summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb17
-rw-r--r--test/-ext-/debug/test_debug.rb2
-rw-r--r--test/-ext-/debug/test_profile_frames.rb67
-rw-r--r--test/-ext-/econv/test_append.rb23
-rw-r--r--test/-ext-/eval/test_eval.rb4
-rw-r--r--test/-ext-/iseq_load/test_iseq_load.rb2
-rw-r--r--test/-ext-/load/test_resolve_symbol.rb27
-rw-r--r--test/-ext-/load/test_stringify_symbols.rb35
-rw-r--r--test/-ext-/marshal/test_internal_ivar.rb2
-rw-r--r--test/-ext-/postponed_job/test_postponed_job.rb72
-rw-r--r--test/-ext-/string/test_capacity.rb8
-rw-r--r--test/-ext-/string/test_chilled.rb19
-rw-r--r--test/-ext-/string/test_cstr.rb6
-rw-r--r--test/-ext-/string/test_fstring.rb20
-rw-r--r--test/-ext-/string/test_set_len.rb29
-rw-r--r--test/-ext-/string/test_too_many_dummy_encodings.rb15
-rw-r--r--test/-ext-/struct/test_data.rb18
-rw-r--r--test/-ext-/symbol/test_type.rb5
-rw-r--r--test/-ext-/test_bug-3571.rb4
-rw-r--r--test/-ext-/test_random.rb26
-rw-r--r--test/-ext-/thread/helper.rb51
-rw-r--r--test/-ext-/thread/test_instrumentation_api.rb274
-rw-r--r--test/-ext-/thread/test_lock_native_thread.rb50
-rw-r--r--test/-ext-/thread_fd/test_thread_fd_close.rb1
-rw-r--r--test/-ext-/tracepoint/test_tracepoint.rb1
-rw-r--r--test/.excludes-prism/TestAssignment.rb1
-rw-r--r--test/.excludes-prism/TestAssignmentGen.rb1
-rw-r--r--test/.excludes-prism/TestCall.rb3
-rw-r--r--test/.excludes-prism/TestIRB/RubyLexTest.rb1
-rw-r--r--test/.excludes-prism/TestISeq.rb3
-rw-r--r--test/.excludes-prism/TestM17N.rb10
-rw-r--r--test/.excludes-prism/TestMixedUnicodeEscape.rb1
-rw-r--r--test/.excludes-prism/TestParse.rb28
-rw-r--r--test/.excludes-prism/TestPatternMatching.rb2
-rw-r--r--test/.excludes-prism/TestRegexp.rb6
-rw-r--r--test/.excludes-prism/TestRequire.rb1
-rw-r--r--test/.excludes-prism/TestRubyLiteral.rb6
-rw-r--r--test/.excludes-prism/TestRubyOptimization.rb1
-rw-r--r--test/.excludes-prism/TestRubyVM.rb1
-rw-r--r--test/.excludes-prism/TestSetTraceFunc.rb2
-rw-r--r--test/.excludes-prism/TestSyntax.rb30
-rw-r--r--test/.excludes-prism/TestUnicodeEscape.rb1
-rw-r--r--test/.excludes/TestArray.rb (renamed from test/excludes/TestArray.rb)0
-rw-r--r--test/.excludes/TestArraySubclass.rb1
-rw-r--r--test/.excludes/TestException.rb (renamed from test/excludes/TestException.rb)0
-rw-r--r--test/.excludes/TestGem.rb (renamed from test/excludes/TestGem.rb)0
-rw-r--r--test/.excludes/TestIO_Console.rb (renamed from test/excludes/TestIO_Console.rb)0
-rw-r--r--test/.excludes/TestISeq.rb (renamed from test/excludes/TestISeq.rb)0
-rw-r--r--test/.excludes/TestThread.rb18
-rw-r--r--test/.excludes/TestThreadQueue.rb (renamed from test/excludes/TestThreadQueue.rb)0
-rw-r--r--test/.excludes/_appveyor/TestArray.rb (renamed from test/excludes/_appveyor/TestArray.rb)0
-rw-r--r--test/base64/test_base64.rb115
-rw-r--r--test/bigdecimal/helper.rb39
-rw-r--r--test/bigdecimal/test_bigdecimal.rb2275
-rw-r--r--test/bigdecimal/test_bigdecimal_util.rb141
-rw-r--r--test/bigdecimal/test_bigmath.rb81
-rw-r--r--test/bigdecimal/test_ractor.rb23
-rw-r--r--test/cgi/test_cgi_cookie.rb85
-rw-r--r--test/cgi/test_cgi_header.rb8
-rw-r--r--test/cgi/test_cgi_util.rb31
-rw-r--r--test/coverage/autostart.rb2
-rw-r--r--test/coverage/main.rb1
-rw-r--r--test/coverage/test_coverage.rb120
-rw-r--r--test/csv/helper.rb42
-rw-r--r--test/csv/interface/test_delegation.rb47
-rw-r--r--test/csv/interface/test_read.rb371
-rw-r--r--test/csv/interface/test_read_write.rb124
-rw-r--r--test/csv/interface/test_write.rb208
-rw-r--r--test/csv/line_endings.gzbin59 -> 0 bytes
-rw-r--r--test/csv/parse/test_column_separator.rb40
-rw-r--r--test/csv/parse/test_convert.rb110
-rw-r--r--test/csv/parse/test_each.rb23
-rw-r--r--test/csv/parse/test_general.rb259
-rw-r--r--test/csv/parse/test_header.rb335
-rw-r--r--test/csv/parse/test_invalid.rb52
-rw-r--r--test/csv/parse/test_liberal_parsing.rb160
-rw-r--r--test/csv/parse/test_quote_char_nil.rb93
-rw-r--r--test/csv/parse/test_rewind.rb40
-rw-r--r--test/csv/parse/test_row_separator.rb16
-rw-r--r--test/csv/parse/test_skip_lines.rb118
-rw-r--r--test/csv/parse/test_strip.rb112
-rw-r--r--test/csv/parse/test_unconverted_fields.rb117
-rw-r--r--test/csv/test_data_converters.rb106
-rw-r--r--test/csv/test_encodings.rb372
-rw-r--r--test/csv/test_features.rb359
-rw-r--r--test/csv/test_row.rb435
-rw-r--r--test/csv/test_table.rb620
-rw-r--r--test/csv/write/test_converters.rb53
-rw-r--r--test/csv/write/test_force_quotes.rb78
-rw-r--r--test/csv/write/test_general.rb246
-rw-r--r--test/csv/write/test_quote_empty.rb70
-rw-r--r--test/date/test_date.rb29
-rw-r--r--test/date/test_date_parse.rb27
-rw-r--r--test/date/test_date_strptime.rb9
-rw-r--r--test/did_you_mean/core_ext/test_name_error_extension.rb4
-rw-r--r--test/did_you_mean/spell_checking/test_method_name_check.rb18
-rw-r--r--test/did_you_mean/spell_checking/test_variable_name_check.rb12
-rw-r--r--test/drb/drbtest.rb394
-rw-r--r--test/drb/ignore_test_drb.rb14
-rw-r--r--test/drb/test_acl.rb207
-rw-r--r--test/drb/test_drb.rb370
-rw-r--r--test/drb/test_drbobject.rb69
-rw-r--r--test/drb/test_drbssl.rb72
-rw-r--r--test/drb/test_drbunix.rb60
-rw-r--r--test/drb/ut_array.rb17
-rw-r--r--test/drb/ut_array_drbssl.rb39
-rw-r--r--test/drb/ut_array_drbunix.rb17
-rw-r--r--test/drb/ut_drb.rb189
-rw-r--r--test/drb/ut_drb_drbssl.rb40
-rw-r--r--test/drb/ut_drb_drbunix.rb18
-rw-r--r--test/drb/ut_eq.rb37
-rw-r--r--test/drb/ut_large.rb62
-rw-r--r--test/drb/ut_port.rb16
-rw-r--r--test/drb/ut_safe1.rb17
-rw-r--r--test/drb/ut_timerholder.rb74
-rw-r--r--test/erb/test_erb.rb30
-rw-r--r--test/erb/test_erb_command.rb18
-rw-r--r--test/error_highlight/test_error_highlight.rb260
-rw-r--r--test/excludes/Psych/TestDateTime.rb4
-rw-r--r--test/excludes/TestThread.rb14
-rw-r--r--test/fiber/scheduler.rb233
-rw-r--r--test/fiber/test_address_resolve.rb4
-rw-r--r--test/fiber/test_enumerator.rb14
-rw-r--r--test/fiber/test_io.rb88
-rw-r--r--test/fiber/test_io_buffer.rb74
-rw-r--r--test/fiber/test_mutex.rb24
-rw-r--r--test/fiber/test_process.rb27
-rw-r--r--test/fiber/test_queue.rb54
-rw-r--r--test/fiber/test_scheduler.rb58
-rw-r--r--test/fiber/test_storage.rb115
-rw-r--r--test/fiber/test_thread.rb22
-rw-r--r--test/fiddle/helper.rb10
-rw-r--r--test/fiddle/test_c_struct_entry.rb8
-rw-r--r--test/fiddle/test_closure.rb123
-rw-r--r--test/fiddle/test_cparser.rb40
-rw-r--r--test/fiddle/test_fiddle.rb41
-rw-r--r--test/fiddle/test_func.rb53
-rw-r--r--test/fiddle/test_function.rb28
-rw-r--r--test/fiddle/test_handle.rb10
-rw-r--r--test/fiddle/test_import.rb23
-rw-r--r--test/fiddle/test_pack.rb37
-rw-r--r--test/fiddle/test_pointer.rb19
-rw-r--r--test/fileutils/test_fileutils.rb77
-rw-r--r--test/io/console/test_io_console.rb57
-rw-r--r--test/io/wait/test_io_wait.rb9
-rw-r--r--test/io/wait/test_io_wait_uncommon.rb1
-rw-r--r--test/io/wait/test_ractor.rb1
-rw-r--r--test/irb/command/test_force_exit.rb63
-rw-r--r--test/irb/command/test_help.rb66
-rw-r--r--test/irb/command/test_show_source.rb397
-rw-r--r--test/irb/helper.rb219
-rw-r--r--test/irb/test_cmd.rb558
-rw-r--r--test/irb/test_color.rb115
-rw-r--r--test/irb/test_color_printer.rb23
-rw-r--r--test/irb/test_command.rb1043
-rw-r--r--test/irb/test_completion.rb345
-rw-r--r--test/irb/test_context.rb461
-rw-r--r--test/irb/test_debugger_integration.rb462
-rw-r--r--test/irb/test_eval_history.rb69
-rw-r--r--test/irb/test_evaluation.rb44
-rw-r--r--test/irb/test_history.rb412
-rw-r--r--test/irb/test_init.rb256
-rw-r--r--test/irb/test_input_method.rb173
-rw-r--r--test/irb/test_irb.rb806
-rw-r--r--test/irb/test_locale.rb118
-rw-r--r--test/irb/test_nesting_parser.rb341
-rw-r--r--test/irb/test_option.rb4
-rw-r--r--test/irb/test_raise_exception.rb74
-rw-r--r--test/irb/test_raise_no_backtrace_exception.rb54
-rw-r--r--test/irb/test_ruby_lex.rb777
-rw-r--r--test/irb/test_tracer.rb90
-rw-r--r--test/irb/test_type_completor.rb88
-rw-r--r--test/irb/test_workspace.rb9
-rw-r--r--test/irb/yamatanooroti/test_rendering.rb699
-rw-r--r--test/json/json_addition_test.rb6
-rw-r--r--test/json/json_common_interface_test.rb34
-rw-r--r--test/json/json_encoding_test.rb9
-rw-r--r--test/json/json_ext_parser_test.rb21
-rw-r--r--test/json/json_fixtures_test.rb2
-rwxr-xr-x[-rw-r--r--]test/json/json_generator_test.rb67
-rw-r--r--test/json/json_generic_object_test.rb4
-rw-r--r--test/json/json_parser_test.rb83
-rw-r--r--test/json/json_string_matching_test.rb2
-rw-r--r--test/json/ractor_test.rb8
-rw-r--r--test/lib/!Nothing_to_test.rb5
-rw-r--r--test/lib/jit_support.rb100
-rw-r--r--test/logger/test_severity.rb32
-rw-r--r--test/mkmf/base.rb8
-rw-r--r--test/mkmf/test_config.rb60
-rw-r--r--test/mkmf/test_configuration.rb39
-rw-r--r--test/mkmf/test_constant.rb8
-rw-r--r--test/mkmf/test_flags.rb6
-rw-r--r--test/mkmf/test_pkg_config.rb4
-rw-r--r--test/monitor/test_monitor.rb2
-rw-r--r--test/net/fixtures/Makefile6
-rw-r--r--test/net/fixtures/cacert.pem44
-rw-r--r--test/net/fixtures/server.crt99
-rw-r--r--test/net/fixtures/server.key55
-rw-r--r--test/net/http/test_http.rb32
-rw-r--r--test/net/http/test_httpheader.rb6
-rw-r--r--test/net/http/test_httpresponse.rb39
-rw-r--r--test/net/http/test_https.rb5
-rw-r--r--test/net/protocol/test_protocol.rb37
-rw-r--r--test/nkf/test_kconv.rb82
-rw-r--r--test/nkf/test_nkf.rb23
-rw-r--r--test/objspace/test_objspace.rb229
-rw-r--r--test/objspace/test_ractor.rb17
-rw-r--r--test/open-uri/test_open-uri.rb43
-rw-r--r--test/open-uri/test_ssl.rb19
-rw-r--r--test/openssl/fixtures/pkey/dh1024.pem5
-rw-r--r--test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem8
-rw-r--r--test/openssl/fixtures/pkey/dsa2048.pem15
-rw-r--r--test/openssl/fixtures/pkey/p256_too_large.pem5
-rw-r--r--test/openssl/fixtures/pkey/p384_invalid.pem6
-rw-r--r--test/openssl/test_asn1.rb22
-rw-r--r--test/openssl/test_bn.rb8
-rw-r--r--test/openssl/test_cipher.rb8
-rw-r--r--test/openssl/test_config.rb12
-rw-r--r--test/openssl/test_digest.rb2
-rw-r--r--test/openssl/test_engine.rb38
-rw-r--r--test/openssl/test_fips.rb40
-rw-r--r--test/openssl/test_hmac.rb9
-rw-r--r--test/openssl/test_ns_spki.rb8
-rw-r--r--test/openssl/test_ocsp.rb2
-rw-r--r--test/openssl/test_ossl.rb13
-rw-r--r--test/openssl/test_pair.rb13
-rw-r--r--test/openssl/test_pkcs12.rb4
-rw-r--r--test/openssl/test_pkey.rb79
-rw-r--r--test/openssl/test_pkey_dh.rb64
-rw-r--r--test/openssl/test_pkey_dsa.rb51
-rw-r--r--test/openssl/test_pkey_ec.rb65
-rw-r--r--test/openssl/test_pkey_rsa.rb25
-rw-r--r--test/openssl/test_provider.rb72
-rw-r--r--test/openssl/test_ssl.rb137
-rw-r--r--test/openssl/test_ssl_session.rb4
-rw-r--r--test/openssl/test_x509cert.rb4
-rw-r--r--test/openssl/test_x509crl.rb20
-rw-r--r--test/openssl/test_x509ext.rb37
-rw-r--r--test/openssl/test_x509req.rb25
-rw-r--r--test/openssl/utils.rb57
-rw-r--r--test/optparse/test_acceptable.rb5
-rw-r--r--test/optparse/test_getopts.rb16
-rw-r--r--test/optparse/test_load.rb141
-rw-r--r--test/optparse/test_optarg.rb16
-rw-r--r--test/optparse/test_optparse.rb103
-rw-r--r--test/optparse/test_placearg.rb20
-rw-r--r--test/optparse/test_reqarg.rb6
-rw-r--r--test/optparse/test_summary.rb23
-rw-r--r--test/ostruct/test_ostruct.rb19
-rw-r--r--test/prism/attribute_write_test.rb60
-rw-r--r--test/prism/bom_test.rb59
-rw-r--r--test/prism/command_line_test.rb111
-rw-r--r--test/prism/comments_test.rb138
-rw-r--r--test/prism/compiler_test.rb31
-rw-r--r--test/prism/constant_path_node_test.rb91
-rw-r--r--test/prism/desugar_compiler_test.rb80
-rw-r--r--test/prism/dispatcher_test.rb46
-rw-r--r--test/prism/encoding_test.rb577
-rw-r--r--test/prism/errors_test.rb2241
-rw-r--r--test/prism/fixtures/alias.txt23
-rw-r--r--test/prism/fixtures/arithmetic.txt13
-rw-r--r--test/prism/fixtures/arrays.txt122
-rw-r--r--test/prism/fixtures/begin_ensure.txt21
-rw-r--r--test/prism/fixtures/begin_rescue.txt79
-rw-r--r--test/prism/fixtures/blocks.txt54
-rw-r--r--test/prism/fixtures/boolean_operators.txt5
-rw-r--r--test/prism/fixtures/booleans.txt3
-rw-r--r--test/prism/fixtures/break.txt25
-rw-r--r--test/prism/fixtures/case.txt55
-rw-r--r--test/prism/fixtures/classes.txt35
-rw-r--r--test/prism/fixtures/command_method_call.txt41
-rw-r--r--test/prism/fixtures/comments.txt24
-rw-r--r--test/prism/fixtures/constants.txt184
-rw-r--r--test/prism/fixtures/dash_heredocs.txt63
-rw-r--r--test/prism/fixtures/defined.txt10
-rw-r--r--test/prism/fixtures/dos_endings.txt20
-rw-r--r--test/prism/fixtures/dstring.txt29
-rw-r--r--test/prism/fixtures/dsym_str.txt2
-rw-r--r--test/prism/fixtures/embdoc_no_newline_at_end.txt2
-rw-r--r--test/prism/fixtures/emoji_method_calls.txt1
-rw-r--r--test/prism/fixtures/endless_methods.txt5
-rw-r--r--test/prism/fixtures/endless_range_in_conditional.txt3
-rw-r--r--test/prism/fixtures/for.txt19
-rw-r--r--test/prism/fixtures/global_variables.txt93
-rw-r--r--test/prism/fixtures/hashes.txt28
-rw-r--r--test/prism/fixtures/heredoc.txt2
-rw-r--r--test/prism/fixtures/heredoc_with_carriage_returns.txt2
-rw-r--r--test/prism/fixtures/heredoc_with_comment.txt3
-rw-r--r--test/prism/fixtures/heredoc_with_escaped_newline_at_start.txt7
-rw-r--r--test/prism/fixtures/heredoc_with_trailing_newline.txt2
-rw-r--r--test/prism/fixtures/heredocs_leading_whitespace.txt29
-rw-r--r--test/prism/fixtures/heredocs_nested.txt22
-rw-r--r--test/prism/fixtures/heredocs_with_ignored_newlines.txt14
-rw-r--r--test/prism/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt4
-rw-r--r--test/prism/fixtures/if.txt42
-rw-r--r--test/prism/fixtures/indented_file_end.txt4
-rw-r--r--test/prism/fixtures/integer_operations.txt63
-rw-r--r--test/prism/fixtures/keyword_method_names.txt29
-rw-r--r--test/prism/fixtures/keywords.txt11
-rw-r--r--test/prism/fixtures/lambda.txt11
-rw-r--r--test/prism/fixtures/method_calls.txt156
-rw-r--r--test/prism/fixtures/methods.txt183
-rw-r--r--test/prism/fixtures/modules.txt18
-rw-r--r--test/prism/fixtures/multi_write.txt4
-rw-r--r--test/prism/fixtures/newline_terminated.txtbin0 -> 212 bytes
-rw-r--r--test/prism/fixtures/next.txt24
-rw-r--r--test/prism/fixtures/nils.txt13
-rw-r--r--test/prism/fixtures/non_alphanumeric_methods.txt105
-rw-r--r--test/prism/fixtures/not.txt37
-rw-r--r--test/prism/fixtures/numbers.txt67
-rw-r--r--test/prism/fixtures/patterns.txt217
-rw-r--r--test/prism/fixtures/procs.txt27
-rw-r--r--test/prism/fixtures/range_begin_open_exclusive.txt1
-rw-r--r--test/prism/fixtures/range_begin_open_inclusive.txt1
-rw-r--r--test/prism/fixtures/range_end_open_exclusive.txt1
-rw-r--r--test/prism/fixtures/range_end_open_inclusive.txt1
-rw-r--r--test/prism/fixtures/ranges.txt49
-rw-r--r--test/prism/fixtures/regex.txt46
-rw-r--r--test/prism/fixtures/regex_char_width.txt3
-rw-r--r--test/prism/fixtures/repeat_parameters.txt38
-rw-r--r--test/prism/fixtures/rescue.txt35
-rw-r--r--test/prism/fixtures/return.txt24
-rw-r--r--test/prism/fixtures/seattlerb/BEGIN.txt1
-rw-r--r--test/prism/fixtures/seattlerb/README.rdoc113
-rw-r--r--test/prism/fixtures/seattlerb/TestRubyParserShared.txt92
-rw-r--r--test/prism/fixtures/seattlerb/__ENCODING__.txt1
-rw-r--r--test/prism/fixtures/seattlerb/alias_gvar_backref.txt1
-rw-r--r--test/prism/fixtures/seattlerb/alias_resword.txt1
-rw-r--r--test/prism/fixtures/seattlerb/and_multi.txt3
-rw-r--r--test/prism/fixtures/seattlerb/aref_args_assocs.txt1
-rw-r--r--test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt1
-rw-r--r--test/prism/fixtures/seattlerb/args_kw_block.txt1
-rw-r--r--test/prism/fixtures/seattlerb/array_line_breaks.txt4
-rw-r--r--test/prism/fixtures/seattlerb/array_lits_trailing_calls.txt3
-rw-r--r--test/prism/fixtures/seattlerb/assoc__bare.txt1
-rw-r--r--test/prism/fixtures/seattlerb/assoc_label.txt1
-rw-r--r--test/prism/fixtures/seattlerb/attr_asgn_colon_id.txt1
-rw-r--r--test/prism/fixtures/seattlerb/attrasgn_array_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt1
-rw-r--r--test/prism/fixtures/seattlerb/attrasgn_primary_dot_constant.txt1
-rw-r--r--test/prism/fixtures/seattlerb/backticks_interpolation_line.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bang_eq.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bdot2.txt3
-rw-r--r--test/prism/fixtures/seattlerb/bdot3.txt3
-rw-r--r--test/prism/fixtures/seattlerb/begin_ensure_no_bodies.txt3
-rw-r--r--test/prism/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt9
-rw-r--r--test/prism/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt9
-rw-r--r--test/prism/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt4
-rw-r--r--test/prism/fixtures/seattlerb/block_arg__bare.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_arg_kwsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_arg_opt_arg_block.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_arg_opt_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_arg_optional.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_arg_scope.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_arg_scope2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_arg_splat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_args_kwargs.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_args_no_kwargs.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_args_opt1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_args_opt2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_args_opt2_2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_args_opt3.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_call_defn_call_block_call.txt4
-rw-r--r--test/prism/fixtures/seattlerb/block_call_dot_op2_brace_block.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_call_dot_op2_cmd_args_do_block.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_call_operation_colon.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_call_operation_dot.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_call_paren_call_block_call.txt2
-rw-r--r--test/prism/fixtures/seattlerb/block_command_operation_colon.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_command_operation_dot.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_decomp_anon_splat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_decomp_arg_splat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_decomp_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_kw.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_kw__required.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_kwarg_lvar.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_kwarg_lvar_multiple.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_opt_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_opt_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_optarg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_paren_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_reg_optarg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_return.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_scope.txt1
-rw-r--r--test/prism/fixtures/seattlerb/block_splat_reg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug169.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug179.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug190.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug191.txt3
-rw-r--r--test/prism/fixtures/seattlerb/bug202.txt2
-rw-r--r--test/prism/fixtures/seattlerb/bug236.txt3
-rw-r--r--test/prism/fixtures/seattlerb/bug290.txt3
-rw-r--r--test/prism/fixtures/seattlerb/bug_187.txt3
-rw-r--r--test/prism/fixtures/seattlerb/bug_215.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_249.txt4
-rw-r--r--test/prism/fixtures/seattlerb/bug_and.txt4
-rw-r--r--test/prism/fixtures/seattlerb/bug_args__19.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_args_masgn.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_args_masgn2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_call_arglist_parens.txt11
-rw-r--r--test/prism/fixtures/seattlerb/bug_case_when_regexp.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_cond_pct.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_hash_args.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_hash_args_trailing_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_hash_interp_array.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_masgn_right.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_not_parens.txt1
-rw-r--r--test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_and.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_arg_assoc.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_arg_assoc_kwsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_arg_kwsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_args_assoc_quoted.txt5
-rw-r--r--test/prism/fixtures/seattlerb/call_args_assoc_trailing_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_args_command.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_array_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_array_block_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_array_lambda_block_call.txt2
-rw-r--r--test/prism/fixtures/seattlerb/call_array_lit_inline_hash.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_assoc.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_assoc_new.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_assoc_new_if_multiline.txt5
-rw-r--r--test/prism/fixtures/seattlerb/call_assoc_trailing_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_bang_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_bang_squiggle.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_begin_call_block_call.txt3
-rw-r--r--test/prism/fixtures/seattlerb/call_block_arg_named.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_carat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_colon2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_colon_parens.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_div.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_dot_parens.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_env.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_eq3.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_gt.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_kwsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_leading_dots.txt3
-rw-r--r--test/prism/fixtures/seattlerb/call_leading_dots_comment.txt4
-rw-r--r--test/prism/fixtures/seattlerb/call_lt.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_lte.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_not.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_pipe.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_rshift.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_self_brackets.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_spaceship.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_stabby_do_end_with_block.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_stabby_with_braces_block.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_star.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_star2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_trailing_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/call_trailing_dots.txt3
-rw-r--r--test/prism/fixtures/seattlerb/call_unary_bang.txt1
-rw-r--r--test/prism/fixtures/seattlerb/case_in.txt111
-rw-r--r--test/prism/fixtures/seattlerb/case_in_31.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_37.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_42.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_42_2.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_47.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_67.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_86.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_86_2.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_array_pat_const.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_array_pat_const2.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_array_pat_paren_assign.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_const.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_else.txt7
-rw-r--r--test/prism/fixtures/seattlerb/case_in_find.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_find_array.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_hash_pat.txt5
-rw-r--r--test/prism/fixtures/seattlerb/case_in_hash_pat_assign.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt4
-rw-r--r--test/prism/fixtures/seattlerb/case_in_hash_pat_paren_true.txt5
-rw-r--r--test/prism/fixtures/seattlerb/case_in_hash_pat_rest.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt3
-rw-r--r--test/prism/fixtures/seattlerb/case_in_if_unless_post_mod.txt6
-rw-r--r--test/prism/fixtures/seattlerb/case_in_multiple.txt6
-rw-r--r--test/prism/fixtures/seattlerb/case_in_or.txt5
-rw-r--r--test/prism/fixtures/seattlerb/class_comments.txt9
-rw-r--r--test/prism/fixtures/seattlerb/cond_unary_minus.txt1
-rw-r--r--test/prism/fixtures/seattlerb/const_2_op_asgn_or2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/const_3_op_asgn_or.txt1
-rw-r--r--test/prism/fixtures/seattlerb/const_op_asgn_and1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/const_op_asgn_and2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/const_op_asgn_or.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defined_eh_parens.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_arg_forward_args.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_args_forward_args.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_comments.txt5
-rw-r--r--test/prism/fixtures/seattlerb/defn_endless_command.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_endless_command_rescue.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_forward_args.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_forward_args__no_parens.txt3
-rw-r--r--test/prism/fixtures/seattlerb/defn_kwarg_env.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_kwarg_kwarg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_kwarg_kwsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_kwarg_lvar.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_kwarg_no_parens.txt2
-rw-r--r--test/prism/fixtures/seattlerb/defn_kwarg_val.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_no_kwargs.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_oneliner.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_oneliner_eq2.txt3
-rw-r--r--test/prism/fixtures/seattlerb/defn_oneliner_noargs.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt13
-rw-r--r--test/prism/fixtures/seattlerb/defn_opt_last_arg.txt2
-rw-r--r--test/prism/fixtures/seattlerb/defn_opt_reg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_opt_splat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_powarg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_reg_opt_reg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_splat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defn_unary_not.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defns_reserved.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defs_comments.txt5
-rw-r--r--test/prism/fixtures/seattlerb/defs_endless_command.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defs_endless_command_rescue.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defs_kwarg.txt2
-rw-r--r--test/prism/fixtures/seattlerb/defs_oneliner.txt1
-rw-r--r--test/prism/fixtures/seattlerb/defs_oneliner_eq2.txt3
-rw-r--r--test/prism/fixtures/seattlerb/defs_oneliner_rescue.txt13
-rw-r--r--test/prism/fixtures/seattlerb/difficult0_.txt4
-rw-r--r--test/prism/fixtures/seattlerb/difficult1_line_numbers.txt13
-rw-r--r--test/prism/fixtures/seattlerb/difficult1_line_numbers2.txt8
-rw-r--r--test/prism/fixtures/seattlerb/difficult2_.txt2
-rw-r--r--test/prism/fixtures/seattlerb/difficult3_.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3_2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3_3.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3_4.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3_5.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3__10.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3__11.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3__12.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3__6.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3__7.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3__8.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult3__9.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult4__leading_dots.txt2
-rw-r--r--test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt2
-rw-r--r--test/prism/fixtures/seattlerb/difficult6_.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult6__7.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult6__8.txt1
-rw-r--r--test/prism/fixtures/seattlerb/difficult7_.txt5
-rw-r--r--test/prism/fixtures/seattlerb/do_bug.txt4
-rw-r--r--test/prism/fixtures/seattlerb/do_lambda.txt1
-rw-r--r--test/prism/fixtures/seattlerb/dot2_nil__26.txt1
-rw-r--r--test/prism/fixtures/seattlerb/dot3_nil__26.txt1
-rw-r--r--test/prism/fixtures/seattlerb/dstr_evstr.txt1
-rw-r--r--test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt1
-rw-r--r--test/prism/fixtures/seattlerb/dstr_lex_state.txt1
-rw-r--r--test/prism/fixtures/seattlerb/dstr_str.txt1
-rw-r--r--test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt1
-rw-r--r--test/prism/fixtures/seattlerb/dsym_to_sym.txt3
-rw-r--r--test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt6
-rw-r--r--test/prism/fixtures/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt3
-rw-r--r--test/prism/fixtures/seattlerb/evstr_evstr.txt1
-rw-r--r--test/prism/fixtures/seattlerb/evstr_str.txt1
-rw-r--r--test/prism/fixtures/seattlerb/expr_not_bang.txt1
-rw-r--r--test/prism/fixtures/seattlerb/f_kw.txt1
-rw-r--r--test/prism/fixtures/seattlerb/f_kw__required.txt1
-rw-r--r--test/prism/fixtures/seattlerb/flip2_env_lvar.txt1
-rw-r--r--test/prism/fixtures/seattlerb/float_with_if_modifier.txt1
-rw-r--r--test/prism/fixtures/seattlerb/heredoc__backslash_dos_format.txt5
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_backslash_nl.txt8
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_bad_hex_escape.txt3
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_bad_oct_escape.txt5
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_comma_arg.txt7
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_lineno.txt7
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_nested.txt7
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly.txt7
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt4
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt7
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly_empty.txt2
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt5
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly_no_indent.txt3
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt6
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt6
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt7
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt4
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_unicode.txt4
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt5
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt5
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt4
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt5
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt5
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt4
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt4
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt3
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt6
-rw-r--r--test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt6
-rw-r--r--test/prism/fixtures/seattlerb/if_elsif.txt1
-rw-r--r--test/prism/fixtures/seattlerb/if_symbol.txt1
-rw-r--r--test/prism/fixtures/seattlerb/in_expr_no_case.txt1
-rw-r--r--test/prism/fixtures/seattlerb/index_0.txt1
-rw-r--r--test/prism/fixtures/seattlerb/index_0_opasgn.txt1
-rw-r--r--test/prism/fixtures/seattlerb/integer_with_if_modifier.txt1
-rw-r--r--test/prism/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt5
-rw-r--r--test/prism/fixtures/seattlerb/interpolated_word_array_line_breaks.txt5
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_10_1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_10_2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_11_1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_11_2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_2__19.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_3.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_4.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_5.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_6.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_7_1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_7_2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_8_1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_8_2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_9_1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_args_9_2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_kwarg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/label_vs_string.txt2
-rw-r--r--test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt7
-rw-r--r--test/prism/fixtures/seattlerb/lasgn_arg_rescue_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/lasgn_command.txt1
-rw-r--r--test/prism/fixtures/seattlerb/lasgn_env.txt1
-rw-r--r--test/prism/fixtures/seattlerb/lasgn_ivar_env.txt1
-rw-r--r--test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/lasgn_middle_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/magic_encoding_comment.txt4
-rw-r--r--test/prism/fixtures/seattlerb/masgn_anon_splat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_arg_ident.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_arg_splat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_colon2.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_colon3.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_double_paren.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_lhs_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_paren.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_splat_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_splat_arg_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_star.txt1
-rw-r--r--test/prism/fixtures/seattlerb/masgn_var_star_var.txt1
-rw-r--r--test/prism/fixtures/seattlerb/messy_op_asgn_lineno.txt1
-rw-r--r--test/prism/fixtures/seattlerb/method_call_assoc_trailing_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/method_call_trailing_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/mlhs_back_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/mlhs_front_anonsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/mlhs_front_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/mlhs_keyword.txt1
-rw-r--r--test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/mlhs_mid_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/mlhs_rescue.txt1
-rw-r--r--test/prism/fixtures/seattlerb/module_comments.txt10
-rw-r--r--test/prism/fixtures/seattlerb/multiline_hash_declaration.txt8
-rw-r--r--test/prism/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt5
-rw-r--r--test/prism/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt5
-rw-r--r--test/prism/fixtures/seattlerb/op_asgn_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/op_asgn_index_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt1
-rw-r--r--test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/parse_def_special_name.txt1
-rw-r--r--test/prism/fixtures/seattlerb/parse_if_not_canonical.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_if_not_noncanonical.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_block.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_block_inline_comment.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt7
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt4
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_call_no_args.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_defn_complex.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_defn_no_parens.txt6
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_defn_no_parens_args.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_dot2.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_dot2_open.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_dot3.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_dot3_open.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_dstr_soft_newline.txt4
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_evstr_after_break.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_hash_lit.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_heredoc.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_heredoc_evstr.txt4
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt7
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_iter_call_no_parens.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_iter_call_parens.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_multiline_str.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_newlines.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_op_asgn.txt4
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_postexe.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_preexe.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_rescue.txt8
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_return.txt6
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_str_with_newline_escape.txt1
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_to_ary.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_line_trailing_newlines.txt2
-rw-r--r--test/prism/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt1
-rw-r--r--test/prism/fixtures/seattlerb/parse_pattern_019.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_pattern_044.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_pattern_051.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_pattern_058.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_pattern_058_2.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_pattern_069.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_pattern_076.txt5
-rw-r--r--test/prism/fixtures/seattlerb/parse_until_not_canonical.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_until_not_noncanonical.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_while_not_canonical.txt3
-rw-r--r--test/prism/fixtures/seattlerb/parse_while_not_noncanonical.txt3
-rw-r--r--test/prism/fixtures/seattlerb/pctW_lineno.txt5
-rw-r--r--test/prism/fixtures/seattlerb/pct_Q_backslash_nl.txt2
-rw-r--r--test/prism/fixtures/seattlerb/pct_nl.txt3
-rw-r--r--test/prism/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt4
-rw-r--r--test/prism/fixtures/seattlerb/pipe_semicolon.txt1
-rw-r--r--test/prism/fixtures/seattlerb/pipe_space.txt1
-rw-r--r--test/prism/fixtures/seattlerb/qWords_space.txt1
-rw-r--r--test/prism/fixtures/seattlerb/qsymbols.txt1
-rw-r--r--test/prism/fixtures/seattlerb/qsymbols_empty.txt1
-rw-r--r--test/prism/fixtures/seattlerb/qsymbols_empty_space.txt1
-rw-r--r--test/prism/fixtures/seattlerb/qsymbols_interp.txt1
-rw-r--r--test/prism/fixtures/seattlerb/quoted_symbol_hash_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/quoted_symbol_keys.txt1
-rw-r--r--test/prism/fixtures/seattlerb/qw_escape.txt1
-rw-r--r--test/prism/fixtures/seattlerb/qw_escape_term.txt1
-rw-r--r--test/prism/fixtures/seattlerb/qwords_empty.txt1
-rw-r--r--test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt1
-rw-r--r--test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt1
-rw-r--r--test/prism/fixtures/seattlerb/regexp.txt9
-rw-r--r--test/prism/fixtures/seattlerb/regexp_esc_C_slash.txt1
-rw-r--r--test/prism/fixtures/seattlerb/regexp_esc_u.txt1
-rw-r--r--test/prism/fixtures/seattlerb/regexp_escape_extended.txt1
-rw-r--r--test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt3
-rw-r--r--test/prism/fixtures/seattlerb/required_kwarg_no_value.txt2
-rw-r--r--test/prism/fixtures/seattlerb/rescue_do_end_ensure_result.txt5
-rw-r--r--test/prism/fixtures/seattlerb/rescue_do_end_no_raise.txt9
-rw-r--r--test/prism/fixtures/seattlerb/rescue_do_end_raised.txt5
-rw-r--r--test/prism/fixtures/seattlerb/rescue_do_end_rescued.txt9
-rw-r--r--test/prism/fixtures/seattlerb/rescue_in_block.txt4
-rw-r--r--test/prism/fixtures/seattlerb/rescue_parens.txt1
-rw-r--r--test/prism/fixtures/seattlerb/return_call_assocs.txt11
-rw-r--r--test/prism/fixtures/seattlerb/rhs_asgn.txt1
-rw-r--r--test/prism/fixtures/seattlerb/ruby21_numbers.txt1
-rw-r--r--test/prism/fixtures/seattlerb/safe_attrasgn.txt1
-rw-r--r--test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt1
-rw-r--r--test/prism/fixtures/seattlerb/safe_call.txt1
-rw-r--r--test/prism/fixtures/seattlerb/safe_call_after_newline.txt2
-rw-r--r--test/prism/fixtures/seattlerb/safe_call_dot_parens.txt1
-rw-r--r--test/prism/fixtures/seattlerb/safe_call_newline.txt2
-rw-r--r--test/prism/fixtures/seattlerb/safe_call_operator.txt1
-rw-r--r--test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt2
-rw-r--r--test/prism/fixtures/seattlerb/safe_calls.txt1
-rw-r--r--test/prism/fixtures/seattlerb/safe_op_asgn.txt1
-rw-r--r--test/prism/fixtures/seattlerb/safe_op_asgn2.txt2
-rw-r--r--test/prism/fixtures/seattlerb/slashy_newlines_within_string.txt7
-rw-r--r--test/prism/fixtures/seattlerb/stabby_arg_no_paren.txt1
-rw-r--r--test/prism/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/stabby_block_iter_call.txt4
-rw-r--r--test/prism/fixtures/seattlerb/stabby_block_iter_call_no_target_with_arg.txt4
-rw-r--r--test/prism/fixtures/seattlerb/stabby_block_kw.txt1
-rw-r--r--test/prism/fixtures/seattlerb/stabby_block_kw__required.txt1
-rw-r--r--test/prism/fixtures/seattlerb/stabby_proc_scope.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_backslashes.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_double_double_escaped_newline.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_double_escaped_newline.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_double_newline.txt2
-rw-r--r--test/prism/fixtures/seattlerb/str_evstr.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_evstr_escape.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_heredoc_interp.txt5
-rw-r--r--test/prism/fixtures/seattlerb/str_interp_ternary_or_label.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_lit_concat_bad_encodings.txt2
-rw-r--r--test/prism/fixtures/seattlerb/str_newline_hash_line_number.txt2
-rw-r--r--test/prism/fixtures/seattlerb/str_pct_Q_nested.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_pct_nested_nested.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_pct_q.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_single_double_escaped_newline.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_single_escaped_newline.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_single_newline.txt2
-rw-r--r--test/prism/fixtures/seattlerb/str_str.txt1
-rw-r--r--test/prism/fixtures/seattlerb/str_str_str.txt1
-rw-r--r--test/prism/fixtures/seattlerb/super_arg.txt1
-rw-r--r--test/prism/fixtures/seattlerb/symbol_empty.txt1
-rw-r--r--test/prism/fixtures/seattlerb/symbol_list.txt1
-rw-r--r--test/prism/fixtures/seattlerb/symbols.txt1
-rw-r--r--test/prism/fixtures/seattlerb/symbols_empty.txt1
-rw-r--r--test/prism/fixtures/seattlerb/symbols_empty_space.txt1
-rw-r--r--test/prism/fixtures/seattlerb/symbols_interp.txt1
-rw-r--r--test/prism/fixtures/seattlerb/thingy.txt3
-rw-r--r--test/prism/fixtures/seattlerb/uminus_float.txt1
-rw-r--r--test/prism/fixtures/seattlerb/unary_minus.txt1
-rw-r--r--test/prism/fixtures/seattlerb/unary_plus.txt1
-rw-r--r--test/prism/fixtures/seattlerb/unary_plus_on_literal.txt1
-rw-r--r--test/prism/fixtures/seattlerb/unary_tilde.txt1
-rw-r--r--test/prism/fixtures/seattlerb/utf8_bom.txt3
-rw-r--r--test/prism/fixtures/seattlerb/when_splat.txt1
-rw-r--r--test/prism/fixtures/seattlerb/words_interp.txt1
-rw-r--r--test/prism/fixtures/single_method_call_with_bang.txt1
-rw-r--r--test/prism/fixtures/single_quote_heredocs.txt3
-rw-r--r--test/prism/fixtures/spanning_heredoc.txt63
-rw-r--r--test/prism/fixtures/spanning_heredoc_newlines.txt23
-rw-r--r--test/prism/fixtures/strings.txt105
-rw-r--r--test/prism/fixtures/super.txt17
-rw-r--r--test/prism/fixtures/symbols.txt93
-rw-r--r--test/prism/fixtures/ternary_operator.txt15
-rw-r--r--test/prism/fixtures/tilde_heredocs.txt97
-rw-r--r--test/prism/fixtures/undef.txt17
-rw-r--r--test/prism/fixtures/unescaping.txt9
-rw-r--r--test/prism/fixtures/unless.txt14
-rw-r--r--test/prism/fixtures/unparser/LICENSE20
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/alias.txt2
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/assignment.txt53
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/block.txt96
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/case.txt37
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/class.txt35
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/def.txt134
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/defined.txt3
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/defs.txt40
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/dstr.txt37
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/empty.txt0
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/empty_begin.txt1
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/flipflop.txt10
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/for.txt12
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/hookexe.txt7
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/if.txt36
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/kwbegin.txt80
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/lambda.txt13
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/literal.txt91
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/module.txt16
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/opasgn.txt24
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/pattern.txt41
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/pragma.txt4
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/range.txt4
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/rescue.txt3
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/send.txt84
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/since/27.txt4
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/since/30.txt4
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/since/31.txt7
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/since/32.txt11
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/singletons.txt4
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/super.txt21
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/unary.txt8
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/undef.txt2
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/variables.txt10
-rw-r--r--test/prism/fixtures/unparser/corpus/literal/while.txt73
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/and.txt8
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/block.txt26
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/def.txt7
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/dstr.txt127
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/kwbegin.txt42
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/literal.txt14
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/opasgn.txt1
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/send.txt6
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/undef.txt2
-rw-r--r--test/prism/fixtures/unparser/corpus/semantic/while.txt25
-rw-r--r--test/prism/fixtures/until.txt13
-rw-r--r--test/prism/fixtures/variables.txt47
-rw-r--r--test/prism/fixtures/while.txt23
-rw-r--r--test/prism/fixtures/whitequark/LICENSE25
-rw-r--r--test/prism/fixtures/whitequark/__ENCODING__.txt1
-rw-r--r--test/prism/fixtures/whitequark/__ENCODING___legacy_.txt1
-rw-r--r--test/prism/fixtures/whitequark/alias.txt1
-rw-r--r--test/prism/fixtures/whitequark/alias_gvar.txt3
-rw-r--r--test/prism/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt1
-rw-r--r--test/prism/fixtures/whitequark/and.txt3
-rw-r--r--test/prism/fixtures/whitequark/and_asgn.txt3
-rw-r--r--test/prism/fixtures/whitequark/and_or_masgn.txt3
-rw-r--r--test/prism/fixtures/whitequark/anonymous_blockarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/arg.txt3
-rw-r--r--test/prism/fixtures/whitequark/arg_duplicate_ignored.txt3
-rw-r--r--test/prism/fixtures/whitequark/arg_label.txt6
-rw-r--r--test/prism/fixtures/whitequark/arg_scope.txt1
-rw-r--r--test/prism/fixtures/whitequark/args.txt63
-rw-r--r--test/prism/fixtures/whitequark/args_args_assocs.txt3
-rw-r--r--test/prism/fixtures/whitequark/args_args_assocs_comma.txt1
-rw-r--r--test/prism/fixtures/whitequark/args_args_comma.txt1
-rw-r--r--test/prism/fixtures/whitequark/args_args_star.txt3
-rw-r--r--test/prism/fixtures/whitequark/args_assocs_comma.txt1
-rw-r--r--test/prism/fixtures/whitequark/args_block_pass.txt1
-rw-r--r--test/prism/fixtures/whitequark/args_cmd.txt1
-rw-r--r--test/prism/fixtures/whitequark/args_star.txt3
-rw-r--r--test/prism/fixtures/whitequark/array_assocs.txt3
-rw-r--r--test/prism/fixtures/whitequark/array_plain.txt1
-rw-r--r--test/prism/fixtures/whitequark/array_splat.txt5
-rw-r--r--test/prism/fixtures/whitequark/array_symbols.txt1
-rw-r--r--test/prism/fixtures/whitequark/array_symbols_empty.txt3
-rw-r--r--test/prism/fixtures/whitequark/array_symbols_interp.txt3
-rw-r--r--test/prism/fixtures/whitequark/array_words.txt1
-rw-r--r--test/prism/fixtures/whitequark/array_words_empty.txt3
-rw-r--r--test/prism/fixtures/whitequark/array_words_interp.txt3
-rw-r--r--test/prism/fixtures/whitequark/asgn_cmd.txt3
-rw-r--r--test/prism/fixtures/whitequark/asgn_mrhs.txt5
-rw-r--r--test/prism/fixtures/whitequark/back_ref.txt1
-rw-r--r--test/prism/fixtures/whitequark/bang.txt1
-rw-r--r--test/prism/fixtures/whitequark/bang_cmd.txt1
-rw-r--r--test/prism/fixtures/whitequark/begin_cmdarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/beginless_erange_after_newline.txt2
-rw-r--r--test/prism/fixtures/whitequark/beginless_irange_after_newline.txt2
-rw-r--r--test/prism/fixtures/whitequark/beginless_range.txt3
-rw-r--r--test/prism/fixtures/whitequark/blockarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/blockargs.txt71
-rw-r--r--test/prism/fixtures/whitequark/bug_435.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_447.txt3
-rw-r--r--test/prism/fixtures/whitequark/bug_452.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_466.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_473.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_480.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_481.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_ascii_8bit_in_literal.txt2
-rw-r--r--test/prism/fixtures/whitequark/bug_cmd_string_lookahead.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_cmdarg.txt5
-rw-r--r--test/prism/fixtures/whitequark/bug_def_no_paren_eql_begin.txt4
-rw-r--r--test/prism/fixtures/whitequark/bug_do_block_in_call_args.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_do_block_in_cmdarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_do_block_in_hash_brace.txt9
-rw-r--r--test/prism/fixtures/whitequark/bug_heredoc_do.txt3
-rw-r--r--test/prism/fixtures/whitequark/bug_interp_single.txt3
-rw-r--r--test/prism/fixtures/whitequark/bug_lambda_leakage.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_regex_verification.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_rescue_empty_else.txt1
-rw-r--r--test/prism/fixtures/whitequark/bug_while_not_parens_do.txt1
-rw-r--r--test/prism/fixtures/whitequark/case_cond.txt1
-rw-r--r--test/prism/fixtures/whitequark/case_cond_else.txt1
-rw-r--r--test/prism/fixtures/whitequark/case_expr.txt1
-rw-r--r--test/prism/fixtures/whitequark/case_expr_else.txt1
-rw-r--r--test/prism/fixtures/whitequark/casgn_scoped.txt1
-rw-r--r--test/prism/fixtures/whitequark/casgn_toplevel.txt1
-rw-r--r--test/prism/fixtures/whitequark/casgn_unscoped.txt1
-rw-r--r--test/prism/fixtures/whitequark/character.txt1
-rw-r--r--test/prism/fixtures/whitequark/class.txt3
-rw-r--r--test/prism/fixtures/whitequark/class_super.txt1
-rw-r--r--test/prism/fixtures/whitequark/class_super_label.txt1
-rw-r--r--test/prism/fixtures/whitequark/comments_before_leading_dot__27.txt19
-rw-r--r--test/prism/fixtures/whitequark/complex.txt7
-rw-r--r--test/prism/fixtures/whitequark/cond_begin.txt1
-rw-r--r--test/prism/fixtures/whitequark/cond_begin_masgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/cond_eflipflop.txt3
-rw-r--r--test/prism/fixtures/whitequark/cond_eflipflop_with_beginless_range.txt1
-rw-r--r--test/prism/fixtures/whitequark/cond_eflipflop_with_endless_range.txt1
-rw-r--r--test/prism/fixtures/whitequark/cond_iflipflop.txt3
-rw-r--r--test/prism/fixtures/whitequark/cond_iflipflop_with_beginless_range.txt1
-rw-r--r--test/prism/fixtures/whitequark/cond_iflipflop_with_endless_range.txt1
-rw-r--r--test/prism/fixtures/whitequark/cond_match_current_line.txt3
-rw-r--r--test/prism/fixtures/whitequark/const_op_asgn.txt9
-rw-r--r--test/prism/fixtures/whitequark/const_scoped.txt1
-rw-r--r--test/prism/fixtures/whitequark/const_toplevel.txt1
-rw-r--r--test/prism/fixtures/whitequark/const_unscoped.txt1
-rw-r--r--test/prism/fixtures/whitequark/cpath.txt3
-rw-r--r--test/prism/fixtures/whitequark/cvar.txt1
-rw-r--r--test/prism/fixtures/whitequark/cvasgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/dedenting_heredoc.txt75
-rw-r--r--test/prism/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt4
-rw-r--r--test/prism/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt4
-rw-r--r--test/prism/fixtures/whitequark/def.txt11
-rw-r--r--test/prism/fixtures/whitequark/defined.txt5
-rw-r--r--test/prism/fixtures/whitequark/defs.txt9
-rw-r--r--test/prism/fixtures/whitequark/empty_stmt.txt1
-rw-r--r--test/prism/fixtures/whitequark/endless_comparison_method.txt11
-rw-r--r--test/prism/fixtures/whitequark/endless_method.txt7
-rw-r--r--test/prism/fixtures/whitequark/endless_method_command_syntax.txt15
-rw-r--r--test/prism/fixtures/whitequark/endless_method_forwarded_args_legacy.txt1
-rw-r--r--test/prism/fixtures/whitequark/endless_method_with_rescue_mod.txt3
-rw-r--r--test/prism/fixtures/whitequark/endless_method_without_args.txt7
-rw-r--r--test/prism/fixtures/whitequark/ensure.txt1
-rw-r--r--test/prism/fixtures/whitequark/ensure_empty.txt1
-rw-r--r--test/prism/fixtures/whitequark/false.txt1
-rw-r--r--test/prism/fixtures/whitequark/float.txt3
-rw-r--r--test/prism/fixtures/whitequark/for.txt3
-rw-r--r--test/prism/fixtures/whitequark/for_mlhs.txt1
-rw-r--r--test/prism/fixtures/whitequark/forward_arg.txt1
-rw-r--r--test/prism/fixtures/whitequark/forward_arg_with_open_args.txt27
-rw-r--r--test/prism/fixtures/whitequark/forward_args_legacy.txt5
-rw-r--r--test/prism/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/forwarded_argument_with_restarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/forwarded_kwrestarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/forwarded_restarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/gvar.txt1
-rw-r--r--test/prism/fixtures/whitequark/gvasgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/hash_empty.txt1
-rw-r--r--test/prism/fixtures/whitequark/hash_hashrocket.txt3
-rw-r--r--test/prism/fixtures/whitequark/hash_kwsplat.txt1
-rw-r--r--test/prism/fixtures/whitequark/hash_label.txt1
-rw-r--r--test/prism/fixtures/whitequark/hash_label_end.txt5
-rw-r--r--test/prism/fixtures/whitequark/hash_pair_value_omission.txt5
-rw-r--r--test/prism/fixtures/whitequark/heredoc.txt14
-rw-r--r--test/prism/fixtures/whitequark/if.txt3
-rw-r--r--test/prism/fixtures/whitequark/if_else.txt3
-rw-r--r--test/prism/fixtures/whitequark/if_elsif.txt1
-rw-r--r--test/prism/fixtures/whitequark/if_masgn__24.txt1
-rw-r--r--test/prism/fixtures/whitequark/if_mod.txt1
-rw-r--r--test/prism/fixtures/whitequark/if_nl_then.txt2
-rw-r--r--test/prism/fixtures/whitequark/int.txt5
-rw-r--r--test/prism/fixtures/whitequark/int___LINE__.txt1
-rw-r--r--test/prism/fixtures/whitequark/interp_digit_var.txt87
-rw-r--r--test/prism/fixtures/whitequark/ivar.txt1
-rw-r--r--test/prism/fixtures/whitequark/ivasgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/keyword_argument_omission.txt1
-rw-r--r--test/prism/fixtures/whitequark/kwarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/kwbegin_compstmt.txt1
-rw-r--r--test/prism/fixtures/whitequark/kwnilarg.txt5
-rw-r--r--test/prism/fixtures/whitequark/kwoptarg.txt1
-rw-r--r--test/prism/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt1
-rw-r--r--test/prism/fixtures/whitequark/kwrestarg_named.txt1
-rw-r--r--test/prism/fixtures/whitequark/kwrestarg_unnamed.txt1
-rw-r--r--test/prism/fixtures/whitequark/lbrace_arg_after_command_args.txt1
-rw-r--r--test/prism/fixtures/whitequark/lparenarg_after_lvar__since_25.txt3
-rw-r--r--test/prism/fixtures/whitequark/lvar.txt1
-rw-r--r--test/prism/fixtures/whitequark/lvar_injecting_match.txt1
-rw-r--r--test/prism/fixtures/whitequark/lvasgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/masgn.txt5
-rw-r--r--test/prism/fixtures/whitequark/masgn_attr.txt5
-rw-r--r--test/prism/fixtures/whitequark/masgn_cmd.txt1
-rw-r--r--test/prism/fixtures/whitequark/masgn_const.txt3
-rw-r--r--test/prism/fixtures/whitequark/masgn_nested.txt3
-rw-r--r--test/prism/fixtures/whitequark/masgn_splat.txt19
-rw-r--r--test/prism/fixtures/whitequark/module.txt1
-rw-r--r--test/prism/fixtures/whitequark/multiple_pattern_matches.txt5
-rw-r--r--test/prism/fixtures/whitequark/newline_in_hash_argument.txt14
-rw-r--r--test/prism/fixtures/whitequark/nil.txt1
-rw-r--r--test/prism/fixtures/whitequark/nil_expression.txt3
-rw-r--r--test/prism/fixtures/whitequark/non_lvar_injecting_match.txt1
-rw-r--r--test/prism/fixtures/whitequark/not.txt5
-rw-r--r--test/prism/fixtures/whitequark/not_cmd.txt1
-rw-r--r--test/prism/fixtures/whitequark/not_masgn__24.txt1
-rw-r--r--test/prism/fixtures/whitequark/nth_ref.txt1
-rw-r--r--test/prism/fixtures/whitequark/numbered_args_after_27.txt7
-rw-r--r--test/prism/fixtures/whitequark/numparam_outside_block.txt9
-rw-r--r--test/prism/fixtures/whitequark/numparam_ruby_bug_19025.txt1
-rw-r--r--test/prism/fixtures/whitequark/op_asgn.txt5
-rw-r--r--test/prism/fixtures/whitequark/op_asgn_cmd.txt7
-rw-r--r--test/prism/fixtures/whitequark/op_asgn_index.txt1
-rw-r--r--test/prism/fixtures/whitequark/op_asgn_index_cmd.txt1
-rw-r--r--test/prism/fixtures/whitequark/optarg.txt3
-rw-r--r--test/prism/fixtures/whitequark/or.txt3
-rw-r--r--test/prism/fixtures/whitequark/or_asgn.txt3
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_272.txt1
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_490.txt5
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_507.txt1
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_518.txt2
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_525.txt1
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_604.txt1
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_640.txt4
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_645.txt1
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_830.txt1
-rw-r--r--test/prism/fixtures/whitequark/parser_bug_989.txt3
-rw-r--r--test/prism/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt3
-rw-r--r--test/prism/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt62
-rw-r--r--test/prism/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt4
-rw-r--r--test/prism/fixtures/whitequark/pattern_matching_blank_else.txt1
-rw-r--r--test/prism/fixtures/whitequark/pattern_matching_else.txt1
-rw-r--r--test/prism/fixtures/whitequark/pattern_matching_single_line.txt3
-rw-r--r--test/prism/fixtures/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt11
-rw-r--r--test/prism/fixtures/whitequark/postexe.txt1
-rw-r--r--test/prism/fixtures/whitequark/preexe.txt1
-rw-r--r--test/prism/fixtures/whitequark/procarg0.txt3
-rw-r--r--test/prism/fixtures/whitequark/range_exclusive.txt1
-rw-r--r--test/prism/fixtures/whitequark/range_inclusive.txt1
-rw-r--r--test/prism/fixtures/whitequark/rational.txt3
-rw-r--r--test/prism/fixtures/whitequark/regex_interp.txt1
-rw-r--r--test/prism/fixtures/whitequark/regex_plain.txt1
-rw-r--r--test/prism/fixtures/whitequark/resbody_list.txt1
-rw-r--r--test/prism/fixtures/whitequark/resbody_list_mrhs.txt1
-rw-r--r--test/prism/fixtures/whitequark/resbody_list_var.txt1
-rw-r--r--test/prism/fixtures/whitequark/resbody_var.txt3
-rw-r--r--test/prism/fixtures/whitequark/rescue.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_else.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_else_ensure.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_ensure.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_in_lambda_block.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_mod.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_mod_asgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_mod_masgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_mod_op_assign.txt1
-rw-r--r--test/prism/fixtures/whitequark/rescue_without_begin_end.txt1
-rw-r--r--test/prism/fixtures/whitequark/restarg_named.txt1
-rw-r--r--test/prism/fixtures/whitequark/restarg_unnamed.txt1
-rw-r--r--test/prism/fixtures/whitequark/return.txt7
-rw-r--r--test/prism/fixtures/whitequark/return_block.txt1
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_10279.txt1
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_10653.txt5
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_11107.txt1
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_11380.txt1
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_11873.txt23
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_11873_a.txt39
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_11873_b.txt1
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_11989.txt3
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_11990.txt3
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_12073.txt3
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_12402.txt27
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_12669.txt7
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_12686.txt1
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_13547.txt1
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_14690.txt1
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_15789.txt3
-rw-r--r--test/prism/fixtures/whitequark/ruby_bug_9669.txt8
-rw-r--r--test/prism/fixtures/whitequark/sclass.txt1
-rw-r--r--test/prism/fixtures/whitequark/self.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_attr_asgn.txt7
-rw-r--r--test/prism/fixtures/whitequark/send_attr_asgn_conditional.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_binary_op.txt41
-rw-r--r--test/prism/fixtures/whitequark/send_block_chain_cmd.txt13
-rw-r--r--test/prism/fixtures/whitequark/send_block_conditional.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_call.txt3
-rw-r--r--test/prism/fixtures/whitequark/send_conditional.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_index.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_index_asgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_index_asgn_legacy.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_index_cmd.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_index_legacy.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_lambda.txt5
-rw-r--r--test/prism/fixtures/whitequark/send_lambda_args.txt3
-rw-r--r--test/prism/fixtures/whitequark/send_lambda_args_noparen.txt3
-rw-r--r--test/prism/fixtures/whitequark/send_lambda_args_shadow.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_lambda_legacy.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_op_asgn_conditional.txt1
-rw-r--r--test/prism/fixtures/whitequark/send_plain.txt5
-rw-r--r--test/prism/fixtures/whitequark/send_plain_cmd.txt5
-rw-r--r--test/prism/fixtures/whitequark/send_self.txt5
-rw-r--r--test/prism/fixtures/whitequark/send_self_block.txt7
-rw-r--r--test/prism/fixtures/whitequark/send_unary_op.txt5
-rw-r--r--test/prism/fixtures/whitequark/slash_newline_in_heredocs.txt13
-rw-r--r--test/prism/fixtures/whitequark/space_args_arg.txt1
-rw-r--r--test/prism/fixtures/whitequark/space_args_arg_block.txt5
-rw-r--r--test/prism/fixtures/whitequark/space_args_arg_call.txt1
-rw-r--r--test/prism/fixtures/whitequark/space_args_arg_newline.txt2
-rw-r--r--test/prism/fixtures/whitequark/space_args_block.txt1
-rw-r--r--test/prism/fixtures/whitequark/space_args_cmd.txt1
-rw-r--r--test/prism/fixtures/whitequark/string___FILE__.txt1
-rw-r--r--test/prism/fixtures/whitequark/string_concat.txt1
-rw-r--r--test/prism/fixtures/whitequark/string_dvar.txt1
-rw-r--r--test/prism/fixtures/whitequark/string_interp.txt1
-rw-r--r--test/prism/fixtures/whitequark/string_plain.txt3
-rw-r--r--test/prism/fixtures/whitequark/super.txt5
-rw-r--r--test/prism/fixtures/whitequark/super_block.txt3
-rw-r--r--test/prism/fixtures/whitequark/symbol_interp.txt1
-rw-r--r--test/prism/fixtures/whitequark/symbol_plain.txt3
-rw-r--r--test/prism/fixtures/whitequark/ternary.txt1
-rw-r--r--test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt1
-rw-r--r--test/prism/fixtures/whitequark/trailing_forward_arg.txt1
-rw-r--r--test/prism/fixtures/whitequark/true.txt1
-rw-r--r--test/prism/fixtures/whitequark/unary_num_pow_precedence.txt5
-rw-r--r--test/prism/fixtures/whitequark/undef.txt1
-rw-r--r--test/prism/fixtures/whitequark/unless.txt3
-rw-r--r--test/prism/fixtures/whitequark/unless_else.txt3
-rw-r--r--test/prism/fixtures/whitequark/unless_mod.txt1
-rw-r--r--test/prism/fixtures/whitequark/until.txt3
-rw-r--r--test/prism/fixtures/whitequark/until_mod.txt1
-rw-r--r--test/prism/fixtures/whitequark/until_post.txt1
-rw-r--r--test/prism/fixtures/whitequark/var_and_asgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/var_op_asgn.txt7
-rw-r--r--test/prism/fixtures/whitequark/var_op_asgn_cmd.txt1
-rw-r--r--test/prism/fixtures/whitequark/var_or_asgn.txt1
-rw-r--r--test/prism/fixtures/whitequark/when_multi.txt1
-rw-r--r--test/prism/fixtures/whitequark/when_splat.txt1
-rw-r--r--test/prism/fixtures/whitequark/when_then.txt1
-rw-r--r--test/prism/fixtures/whitequark/while.txt3
-rw-r--r--test/prism/fixtures/whitequark/while_mod.txt1
-rw-r--r--test/prism/fixtures/whitequark/while_post.txt1
-rw-r--r--test/prism/fixtures/whitequark/xstring_interp.txt1
-rw-r--r--test/prism/fixtures/whitequark/xstring_plain.txt1
-rw-r--r--test/prism/fixtures/whitequark/zsuper.txt1
-rw-r--r--test/prism/fixtures/xstring.txt13
-rw-r--r--test/prism/fixtures/xstring_with_backslash.txt1
-rw-r--r--test/prism/fixtures/yield.txt7
-rw-r--r--test/prism/format_errors_test.rb24
-rw-r--r--test/prism/fuzzer_test.rb67
-rw-r--r--test/prism/heredoc_dedent_test.rb27
-rw-r--r--test/prism/index_write_test.rb89
-rw-r--r--test/prism/integer_parse_test.rb45
-rw-r--r--test/prism/library_symbols_test.rb106
-rw-r--r--test/prism/locals_test.rb58
-rw-r--r--test/prism/location_test.rb947
-rw-r--r--test/prism/magic_comment_test.rb33
-rw-r--r--test/prism/memsize_test.rb17
-rw-r--r--test/prism/newline_test.rb93
-rw-r--r--test/prism/parameters_signature_test.rb93
-rw-r--r--test/prism/parse_comments_test.rb21
-rw-r--r--test/prism/parse_stream_test.rb74
-rw-r--r--test/prism/parse_test.rb371
-rw-r--r--test/prism/parser_test.rb186
-rw-r--r--test/prism/pattern_test.rb132
-rw-r--r--test/prism/regexp_test.rb263
-rw-r--r--test/prism/ripper_test.rb85
-rw-r--r--test/prism/ruby_api_test.rb253
-rw-r--r--test/prism/ruby_parser_test.rb144
-rw-r--r--test/prism/snapshots/alias.txt194
-rw-r--r--test/prism/snapshots/arithmetic.txt255
-rw-r--r--test/prism/snapshots/arrays.txt1837
-rw-r--r--test/prism/snapshots/begin_ensure.txt251
-rw-r--r--test/prism/snapshots/begin_rescue.txt699
-rw-r--r--test/prism/snapshots/blocks.txt774
-rw-r--r--test/prism/snapshots/boolean_operators.txt54
-rw-r--r--test/prism/snapshots/booleans.txt7
-rw-r--r--test/prism/snapshots/break.txt401
-rw-r--r--test/prism/snapshots/case.txt495
-rw-r--r--test/prism/snapshots/classes.txt365
-rw-r--r--test/prism/snapshots/command_method_call.txt755
-rw-r--r--test/prism/snapshots/comments.txt145
-rw-r--r--test/prism/snapshots/constants.txt1242
-rw-r--r--test/prism/snapshots/dash_heredocs.txt260
-rw-r--r--test/prism/snapshots/defined.txt88
-rw-r--r--test/prism/snapshots/dos_endings.txt110
-rw-r--r--test/prism/snapshots/dstring.txt85
-rw-r--r--test/prism/snapshots/dsym_str.txt11
-rw-r--r--test/prism/snapshots/embdoc_no_newline_at_end.txt5
-rw-r--r--test/prism/snapshots/emoji_method_calls.txt31
-rw-r--r--test/prism/snapshots/endless_methods.txt107
-rw-r--r--test/prism/snapshots/endless_range_in_conditional.txt53
-rw-r--r--test/prism/snapshots/for.txt188
-rw-r--r--test/prism/snapshots/global_variables.txt191
-rw-r--r--test/prism/snapshots/hashes.txt384
-rw-r--r--test/prism/snapshots/heredoc.txt11
-rw-r--r--test/prism/snapshots/heredoc_with_carriage_returns.txt11
-rw-r--r--test/prism/snapshots/heredoc_with_comment.txt21
-rw-r--r--test/prism/snapshots/heredoc_with_escaped_newline_at_start.txt67
-rw-r--r--test/prism/snapshots/heredoc_with_trailing_newline.txt11
-rw-r--r--test/prism/snapshots/heredocs_leading_whitespace.txt63
-rw-r--r--test/prism/snapshots/heredocs_nested.txt94
-rw-r--r--test/prism/snapshots/heredocs_with_ignored_newlines.txt70
-rw-r--r--test/prism/snapshots/heredocs_with_ignored_newlines_and_non_empty.txt11
-rw-r--r--test/prism/snapshots/if.txt530
-rw-r--r--test/prism/snapshots/indented_file_end.txt18
-rw-r--r--test/prism/snapshots/integer_operations.txt635
-rw-r--r--test/prism/snapshots/keyword_method_names.txt173
-rw-r--r--test/prism/snapshots/keywords.txt47
-rw-r--r--test/prism/snapshots/lambda.txt202
-rw-r--r--test/prism/snapshots/method_calls.txt2459
-rw-r--r--test/prism/snapshots/methods.txt2053
-rw-r--r--test/prism/snapshots/modules.txt184
-rw-r--r--test/prism/snapshots/multi_write.txt93
-rw-r--r--test/prism/snapshots/newline_terminated.txt107
-rw-r--r--test/prism/snapshots/next.txt329
-rw-r--r--test/prism/snapshots/nils.txt34
-rw-r--r--test/prism/snapshots/non_alphanumeric_methods.txt503
-rw-r--r--test/prism/snapshots/not.txt351
-rw-r--r--test/prism/snapshots/numbers.txt142
-rw-r--r--test/prism/snapshots/patterns.txt4921
-rw-r--r--test/prism/snapshots/procs.txt403
-rw-r--r--test/prism/snapshots/range_begin_open_exclusive.txt13
-rw-r--r--test/prism/snapshots/range_begin_open_inclusive.txt13
-rw-r--r--test/prism/snapshots/range_end_open_exclusive.txt13
-rw-r--r--test/prism/snapshots/range_end_open_inclusive.txt13
-rw-r--r--test/prism/snapshots/ranges.txt533
-rw-r--r--test/prism/snapshots/regex.txt510
-rw-r--r--test/prism/snapshots/regex_char_width.txt50
-rw-r--r--test/prism/snapshots/repeat_parameters.txt473
-rw-r--r--test/prism/snapshots/rescue.txt527
-rw-r--r--test/prism/snapshots/return.txt155
-rw-r--r--test/prism/snapshots/seattlerb/BEGIN.txt15
-rw-r--r--test/prism/snapshots/seattlerb/TestRubyParserShared.txt361
-rw-r--r--test/prism/snapshots/seattlerb/__ENCODING__.txt6
-rw-r--r--test/prism/snapshots/seattlerb/alias_gvar_backref.txt13
-rw-r--r--test/prism/snapshots/seattlerb/alias_resword.txt21
-rw-r--r--test/prism/snapshots/seattlerb/and_multi.txt26
-rw-r--r--test/prism/snapshots/seattlerb/aref_args_assocs.txt23
-rw-r--r--test/prism/snapshots/seattlerb/aref_args_lit_assocs.txt26
-rw-r--r--test/prism/snapshots/seattlerb/args_kw_block.txt39
-rw-r--r--test/prism/snapshots/seattlerb/array_line_breaks.txt25
-rw-r--r--test/prism/snapshots/seattlerb/array_lits_trailing_calls.txt35
-rw-r--r--test/prism/snapshots/seattlerb/assoc__bare.txt31
-rw-r--r--test/prism/snapshots/seattlerb/assoc_label.txt34
-rw-r--r--test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt23
-rw-r--r--test/prism/snapshots/seattlerb/attrasgn_array_arg.txt42
-rw-r--r--test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt83
-rw-r--r--test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt31
-rw-r--r--test/prism/snapshots/seattlerb/backticks_interpolation_line.txt38
-rw-r--r--test/prism/snapshots/seattlerb/bang_eq.txt24
-rw-r--r--test/prism/snapshots/seattlerb/bdot2.txt38
-rw-r--r--test/prism/snapshots/seattlerb/bdot3.txt38
-rw-r--r--test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt16
-rw-r--r--test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt47
-rw-r--r--test/prism/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt27
-rw-r--r--test/prism/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt23
-rw-r--r--test/prism/snapshots/seattlerb/block_arg__bare.txt31
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_kwsplat.txt39
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_opt_arg_block.txt54
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_opt_splat.txt51
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt59
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_optional.txt43
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_scope.txt40
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_scope2.txt43
-rw-r--r--test/prism/snapshots/seattlerb/block_arg_splat_arg.txt45
-rw-r--r--test/prism/snapshots/seattlerb/block_args_kwargs.txt44
-rw-r--r--test/prism/snapshots/seattlerb/block_args_no_kwargs.txt37
-rw-r--r--test/prism/snapshots/seattlerb/block_args_opt1.txt59
-rw-r--r--test/prism/snapshots/seattlerb/block_args_opt2.txt52
-rw-r--r--test/prism/snapshots/seattlerb/block_args_opt2_2.txt71
-rw-r--r--test/prism/snapshots/seattlerb/block_args_opt3.txt79
-rw-r--r--test/prism/snapshots/seattlerb/block_call_defn_call_block_call.txt80
-rw-r--r--test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt100
-rw-r--r--test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt113
-rw-r--r--test/prism/snapshots/seattlerb/block_call_operation_colon.txt54
-rw-r--r--test/prism/snapshots/seattlerb/block_call_operation_dot.txt54
-rw-r--r--test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt60
-rw-r--r--test/prism/snapshots/seattlerb/block_command_operation_colon.txt49
-rw-r--r--test/prism/snapshots/seattlerb/block_command_operation_dot.txt49
-rw-r--r--test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt46
-rw-r--r--test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt46
-rw-r--r--test/prism/snapshots/seattlerb/block_decomp_arg_splat_arg.txt52
-rw-r--r--test/prism/snapshots/seattlerb/block_decomp_splat.txt46
-rw-r--r--test/prism/snapshots/seattlerb/block_kw.txt42
-rw-r--r--test/prism/snapshots/seattlerb/block_kw__required.txt38
-rw-r--r--test/prism/snapshots/seattlerb/block_kwarg_lvar.txt50
-rw-r--r--test/prism/snapshots/seattlerb/block_kwarg_lvar_multiple.txt61
-rw-r--r--test/prism/snapshots/seattlerb/block_opt_arg.txt46
-rw-r--r--test/prism/snapshots/seattlerb/block_opt_splat.txt48
-rw-r--r--test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt56
-rw-r--r--test/prism/snapshots/seattlerb/block_optarg.txt46
-rw-r--r--test/prism/snapshots/seattlerb/block_paren_splat.txt49
-rw-r--r--test/prism/snapshots/seattlerb/block_reg_optarg.txt49
-rw-r--r--test/prism/snapshots/seattlerb/block_return.txt56
-rw-r--r--test/prism/snapshots/seattlerb/block_scope.txt29
-rw-r--r--test/prism/snapshots/seattlerb/block_splat_reg.txt42
-rw-r--r--test/prism/snapshots/seattlerb/bug169.txt28
-rw-r--r--test/prism/snapshots/seattlerb/bug179.txt28
-rw-r--r--test/prism/snapshots/seattlerb/bug190.txt11
-rw-r--r--test/prism/snapshots/seattlerb/bug191.txt87
-rw-r--r--test/prism/snapshots/seattlerb/bug202.txt22
-rw-r--r--test/prism/snapshots/seattlerb/bug236.txt70
-rw-r--r--test/prism/snapshots/seattlerb/bug290.txt24
-rw-r--r--test/prism/snapshots/seattlerb/bug_187.txt59
-rw-r--r--test/prism/snapshots/seattlerb/bug_215.txt14
-rw-r--r--test/prism/snapshots/seattlerb/bug_249.txt86
-rw-r--r--test/prism/snapshots/seattlerb/bug_and.txt21
-rw-r--r--test/prism/snapshots/seattlerb/bug_args__19.txt58
-rw-r--r--test/prism/snapshots/seattlerb/bug_args_masgn.txt49
-rw-r--r--test/prism/snapshots/seattlerb/bug_args_masgn2.txt58
-rw-r--r--test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt55
-rw-r--r--test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt110
-rw-r--r--test/prism/snapshots/seattlerb/bug_case_when_regexp.txt28
-rw-r--r--test/prism/snapshots/seattlerb/bug_comma.txt41
-rw-r--r--test/prism/snapshots/seattlerb/bug_cond_pct.txt22
-rw-r--r--test/prism/snapshots/seattlerb/bug_hash_args.txt38
-rw-r--r--test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt38
-rw-r--r--test/prism/snapshots/seattlerb/bug_hash_interp_array.txt26
-rw-r--r--test/prism/snapshots/seattlerb/bug_masgn_right.txt49
-rw-r--r--test/prism/snapshots/seattlerb/bug_not_parens.txt25
-rw-r--r--test/prism/snapshots/seattlerb/bug_op_asgn_rescue.txt26
-rw-r--r--test/prism/snapshots/seattlerb/call_and.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_assoc.txt34
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt43
-rw-r--r--test/prism/snapshots/seattlerb/call_arg_kwsplat.txt37
-rw-r--r--test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt106
-rw-r--r--test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt34
-rw-r--r--test/prism/snapshots/seattlerb/call_args_command.txt54
-rw-r--r--test/prism/snapshots/seattlerb/call_array_arg.txt38
-rw-r--r--test/prism/snapshots/seattlerb/call_array_block_call.txt40
-rw-r--r--test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt41
-rw-r--r--test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt45
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc.txt31
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_new.txt34
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt58
-rw-r--r--test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt31
-rw-r--r--test/prism/snapshots/seattlerb/call_bang_command_call.txt41
-rw-r--r--test/prism/snapshots/seattlerb/call_bang_squiggle.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_begin_call_block_call.txt53
-rw-r--r--test/prism/snapshots/seattlerb/call_block_arg_named.txt28
-rw-r--r--test/prism/snapshots/seattlerb/call_carat.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_colon2.txt17
-rw-r--r--test/prism/snapshots/seattlerb/call_colon_parens.txt18
-rw-r--r--test/prism/snapshots/seattlerb/call_div.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_dot_parens.txt18
-rw-r--r--test/prism/snapshots/seattlerb/call_env.txt25
-rw-r--r--test/prism/snapshots/seattlerb/call_eq3.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_gt.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_kwsplat.txt27
-rw-r--r--test/prism/snapshots/seattlerb/call_leading_dots.txt35
-rw-r--r--test/prism/snapshots/seattlerb/call_leading_dots_comment.txt35
-rw-r--r--test/prism/snapshots/seattlerb/call_lt.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_lte.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_not.txt18
-rw-r--r--test/prism/snapshots/seattlerb/call_pipe.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_rshift.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_self_brackets.txt22
-rw-r--r--test/prism/snapshots/seattlerb/call_spaceship.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_stabby_do_end_with_block.txt41
-rw-r--r--test/prism/snapshots/seattlerb/call_stabby_with_braces_block.txt41
-rw-r--r--test/prism/snapshots/seattlerb/call_star.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_star2.txt24
-rw-r--r--test/prism/snapshots/seattlerb/call_trailing_comma.txt21
-rw-r--r--test/prism/snapshots/seattlerb/call_trailing_dots.txt35
-rw-r--r--test/prism/snapshots/seattlerb/call_unary_bang.txt18
-rw-r--r--test/prism/snapshots/seattlerb/case_in.txt976
-rw-r--r--test/prism/snapshots/seattlerb/case_in_31.txt49
-rw-r--r--test/prism/snapshots/seattlerb/case_in_37.txt58
-rw-r--r--test/prism/snapshots/seattlerb/case_in_42.txt44
-rw-r--r--test/prism/snapshots/seattlerb/case_in_42_2.txt40
-rw-r--r--test/prism/snapshots/seattlerb/case_in_47.txt52
-rw-r--r--test/prism/snapshots/seattlerb/case_in_67.txt33
-rw-r--r--test/prism/snapshots/seattlerb/case_in_86.txt52
-rw-r--r--test/prism/snapshots/seattlerb/case_in_86_2.txt52
-rw-r--r--test/prism/snapshots/seattlerb/case_in_array_pat_const.txt42
-rw-r--r--test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt48
-rw-r--r--test/prism/snapshots/seattlerb/case_in_array_pat_paren_assign.txt48
-rw-r--r--test/prism/snapshots/seattlerb/case_in_const.txt28
-rw-r--r--test/prism/snapshots/seattlerb/case_in_else.txt40
-rw-r--r--test/prism/snapshots/seattlerb/case_in_find.txt47
-rw-r--r--test/prism/snapshots/seattlerb/case_in_find_array.txt44
-rw-r--r--test/prism/snapshots/seattlerb/case_in_hash_pat.txt68
-rw-r--r--test/prism/snapshots/seattlerb/case_in_hash_pat_assign.txt86
-rw-r--r--test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt51
-rw-r--r--test/prism/snapshots/seattlerb/case_in_hash_pat_paren_true.txt47
-rw-r--r--test/prism/snapshots/seattlerb/case_in_hash_pat_rest.txt55
-rw-r--r--test/prism/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt42
-rw-r--r--test/prism/snapshots/seattlerb/case_in_if_unless_post_mod.txt67
-rw-r--r--test/prism/snapshots/seattlerb/case_in_multiple.txt59
-rw-r--r--test/prism/snapshots/seattlerb/case_in_or.txt38
-rw-r--r--test/prism/snapshots/seattlerb/class_comments.txt31
-rw-r--r--test/prism/snapshots/seattlerb/cond_unary_minus.txt15
-rw-r--r--test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt24
-rw-r--r--test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt18
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_and1.txt19
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_and2.txt18
-rw-r--r--test/prism/snapshots/seattlerb/const_op_asgn_or.txt20
-rw-r--r--test/prism/snapshots/seattlerb/dasgn_icky2.txt61
-rw-r--r--test/prism/snapshots/seattlerb/defined_eh_parens.txt13
-rw-r--r--test/prism/snapshots/seattlerb/defn_arg_asplat_arg.txt37
-rw-r--r--test/prism/snapshots/seattlerb/defn_arg_forward_args.txt49
-rw-r--r--test/prism/snapshots/seattlerb/defn_args_forward_args.txt61
-rw-r--r--test/prism/snapshots/seattlerb/defn_comments.txt18
-rw-r--r--test/prism/snapshots/seattlerb/defn_endless_command.txt36
-rw-r--r--test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt43
-rw-r--r--test/prism/snapshots/seattlerb/defn_forward_args.txt43
-rw-r--r--test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt43
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_env.txt55
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt45
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt39
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt39
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt42
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt34
-rw-r--r--test/prism/snapshots/seattlerb/defn_kwarg_val.txt37
-rw-r--r--test/prism/snapshots/seattlerb/defn_no_kwargs.txt29
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner.txt47
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt47
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt30
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt30
-rw-r--r--test/prism/snapshots/seattlerb/defn_oneliner_rescue.txt158
-rw-r--r--test/prism/snapshots/seattlerb/defn_opt_last_arg.txt33
-rw-r--r--test/prism/snapshots/seattlerb/defn_opt_reg.txt36
-rw-r--r--test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt43
-rw-r--r--test/prism/snapshots/seattlerb/defn_powarg.txt31
-rw-r--r--test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt44
-rw-r--r--test/prism/snapshots/seattlerb/defn_splat_arg.txt34
-rw-r--r--test/prism/snapshots/seattlerb/defn_unary_not.txt21
-rw-r--r--test/prism/snapshots/seattlerb/defns_reserved.txt19
-rw-r--r--test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt60
-rw-r--r--test/prism/snapshots/seattlerb/defs_comments.txt19
-rw-r--r--test/prism/snapshots/seattlerb/defs_endless_command.txt46
-rw-r--r--test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt53
-rw-r--r--test/prism/snapshots/seattlerb/defs_kwarg.txt35
-rw-r--r--test/prism/snapshots/seattlerb/defs_oneliner.txt48
-rw-r--r--test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt48
-rw-r--r--test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt161
-rw-r--r--test/prism/snapshots/seattlerb/difficult0_.txt73
-rw-r--r--test/prism/snapshots/seattlerb/difficult1_line_numbers.txt267
-rw-r--r--test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt78
-rw-r--r--test/prism/snapshots/seattlerb/difficult2_.txt74
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_.txt52
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_2.txt42
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_3.txt47
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_4.txt38
-rw-r--r--test/prism/snapshots/seattlerb/difficult3_5.txt48
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__10.txt52
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__11.txt46
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__12.txt49
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__6.txt55
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__7.txt49
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__8.txt52
-rw-r--r--test/prism/snapshots/seattlerb/difficult3__9.txt49
-rw-r--r--test/prism/snapshots/seattlerb/difficult4__leading_dots.txt25
-rw-r--r--test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt16
-rw-r--r--test/prism/snapshots/seattlerb/difficult6_.txt61
-rw-r--r--test/prism/snapshots/seattlerb/difficult6__7.txt55
-rw-r--r--test/prism/snapshots/seattlerb/difficult6__8.txt55
-rw-r--r--test/prism/snapshots/seattlerb/difficult7_.txt93
-rw-r--r--test/prism/snapshots/seattlerb/do_bug.txt63
-rw-r--r--test/prism/snapshots/seattlerb/do_lambda.txt17
-rw-r--r--test/prism/snapshots/seattlerb/dot2_nil__26.txt20
-rw-r--r--test/prism/snapshots/seattlerb/dot3_nil__26.txt20
-rw-r--r--test/prism/snapshots/seattlerb/dstr_evstr.txt38
-rw-r--r--test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt25
-rw-r--r--test/prism/snapshots/seattlerb/dstr_lex_state.txt35
-rw-r--r--test/prism/snapshots/seattlerb/dstr_str.txt28
-rw-r--r--test/prism/snapshots/seattlerb/dsym_esc_to_sym.txt11
-rw-r--r--test/prism/snapshots/seattlerb/dsym_to_sym.txt37
-rw-r--r--test/prism/snapshots/seattlerb/eq_begin_line_numbers.txt11
-rw-r--r--test/prism/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt50
-rw-r--r--test/prism/snapshots/seattlerb/evstr_evstr.txt42
-rw-r--r--test/prism/snapshots/seattlerb/evstr_str.txt32
-rw-r--r--test/prism/snapshots/seattlerb/expr_not_bang.txt38
-rw-r--r--test/prism/snapshots/seattlerb/f_kw.txt34
-rw-r--r--test/prism/snapshots/seattlerb/f_kw__required.txt30
-rw-r--r--test/prism/snapshots/seattlerb/flip2_env_lvar.txt37
-rw-r--r--test/prism/snapshots/seattlerb/float_with_if_modifier.txt17
-rw-r--r--test/prism/snapshots/seattlerb/heredoc__backslash_dos_format.txt17
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_backslash_nl.txt17
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_bad_hex_escape.txt17
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_bad_oct_escape.txt17
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_comma_arg.txt27
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_lineno.txt26
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_nested.txt42
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly.txt34
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt67
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt34
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_empty.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_interp.txt49
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_no_indent.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_tabs.txt28
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt28
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt34
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_trailing_slash_continued_call.txt21
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_unicode.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes_windows.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns_windows.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt27
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt27
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_not_global_interpolation.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns.txt11
-rw-r--r--test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns_windows.txt11
-rw-r--r--test/prism/snapshots/seattlerb/if_elsif.txt25
-rw-r--r--test/prism/snapshots/seattlerb/if_symbol.txt31
-rw-r--r--test/prism/snapshots/seattlerb/in_expr_no_case.txt17
-rw-r--r--test/prism/snapshots/seattlerb/index_0.txt38
-rw-r--r--test/prism/snapshots/seattlerb/index_0_opasgn.txt36
-rw-r--r--test/prism/snapshots/seattlerb/integer_with_if_modifier.txt18
-rw-r--r--test/prism/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt25
-rw-r--r--test/prism/snapshots/seattlerb/interpolated_word_array_line_breaks.txt25
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_1.txt40
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_10_1.txt51
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_10_2.txt56
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_11_1.txt54
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_11_2.txt59
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_2__19.txt46
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_3.txt52
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_4.txt45
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_5.txt42
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_6.txt49
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_7_1.txt48
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_7_2.txt53
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_8_1.txt51
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_8_2.txt56
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_9_1.txt46
-rw-r--r--test/prism/snapshots/seattlerb/iter_args_9_2.txt51
-rw-r--r--test/prism/snapshots/seattlerb/iter_kwarg.txt42
-rw-r--r--test/prism/snapshots/seattlerb/iter_kwarg_kwsplat.txt47
-rw-r--r--test/prism/snapshots/seattlerb/label_vs_string.txt34
-rw-r--r--test/prism/snapshots/seattlerb/lambda_do_vs_brace.txt95
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_arg_rescue_arg.txt21
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt34
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt34
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_command.txt37
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_env.txt14
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_ivar_env.txt13
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_lasgn_command_call.txt33
-rw-r--r--test/prism/snapshots/seattlerb/lasgn_middle_splat.txt49
-rw-r--r--test/prism/snapshots/seattlerb/magic_encoding_comment.txt46
-rw-r--r--test/prism/snapshots/seattlerb/masgn_anon_splat_arg.txt29
-rw-r--r--test/prism/snapshots/seattlerb/masgn_arg_colon_arg.txt42
-rw-r--r--test/prism/snapshots/seattlerb/masgn_arg_ident.txt42
-rw-r--r--test/prism/snapshots/seattlerb/masgn_arg_splat_arg.txt35
-rw-r--r--test/prism/snapshots/seattlerb/masgn_colon2.txt43
-rw-r--r--test/prism/snapshots/seattlerb/masgn_colon3.txt36
-rw-r--r--test/prism/snapshots/seattlerb/masgn_command_call.txt43
-rw-r--r--test/prism/snapshots/seattlerb/masgn_double_paren.txt35
-rw-r--r--test/prism/snapshots/seattlerb/masgn_lhs_splat.txt33
-rw-r--r--test/prism/snapshots/seattlerb/masgn_paren.txt39
-rw-r--r--test/prism/snapshots/seattlerb/masgn_splat_arg.txt32
-rw-r--r--test/prism/snapshots/seattlerb/masgn_splat_arg_arg.txt35
-rw-r--r--test/prism/snapshots/seattlerb/masgn_star.txt19
-rw-r--r--test/prism/snapshots/seattlerb/masgn_var_star_var.txt32
-rw-r--r--test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt60
-rw-r--r--test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt41
-rw-r--r--test/prism/snapshots/seattlerb/method_call_trailing_comma.txt31
-rw-r--r--test/prism/snapshots/seattlerb/mlhs_back_anonsplat.txt35
-rw-r--r--test/prism/snapshots/seattlerb/mlhs_back_splat.txt38
-rw-r--r--test/prism/snapshots/seattlerb/mlhs_front_anonsplat.txt35
-rw-r--r--test/prism/snapshots/seattlerb/mlhs_front_splat.txt38
-rw-r--r--test/prism/snapshots/seattlerb/mlhs_keyword.txt30
-rw-r--r--test/prism/snapshots/seattlerb/mlhs_mid_anonsplat.txt44
-rw-r--r--test/prism/snapshots/seattlerb/mlhs_mid_splat.txt47
-rw-r--r--test/prism/snapshots/seattlerb/mlhs_rescue.txt36
-rw-r--r--test/prism/snapshots/seattlerb/module_comments.txt29
-rw-r--r--test/prism/snapshots/seattlerb/multiline_hash_declaration.txt95
-rw-r--r--test/prism/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt25
-rw-r--r--test/prism/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt25
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_command_call.txt37
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt32
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_index_command_call.txt53
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt41
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt20
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt40
-rw-r--r--test/prism/snapshots/seattlerb/op_asgn_val_dot_ident_command_call.txt40
-rw-r--r--test/prism/snapshots/seattlerb/parse_def_special_name.txt18
-rw-r--r--test/prism/snapshots/seattlerb/parse_if_not_canonical.txt62
-rw-r--r--test/prism/snapshots/seattlerb/parse_if_not_noncanonical.txt62
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_block.txt30
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_block_inline_comment.txt35
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_block_inline_comment_leading_newlines.txt35
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_block_inline_multiline_comment.txt35
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt20
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_call_ivar_line_break_paren.txt20
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_call_no_args.txt61
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_defn_complex.txt66
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_defn_no_parens.txt31
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_defn_no_parens_args.txt29
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dot2.txt51
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dot2_open.txt38
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dot3.txt51
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dot3_open.txt38
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt21
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_dstr_soft_newline.txt21
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_evstr_after_break.txt37
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_hash_lit.txt22
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_heredoc.txt43
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_heredoc_evstr.txt38
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt22
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt33
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_iter_call_no_parens.txt74
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_iter_call_parens.txt74
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_multiline_str.txt14
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt14
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_newlines.txt6
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_op_asgn.txt32
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_postexe.txt22
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_preexe.txt22
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_rescue.txt62
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_return.txt39
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_str_with_newline_escape.txt25
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_to_ary.txt39
-rw-r--r--test/prism/snapshots/seattlerb/parse_line_trailing_newlines.txt25
-rw-r--r--test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt34
-rw-r--r--test/prism/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt24
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_019.txt33
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_044.txt38
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_051.txt47
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_058.txt73
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_058_2.txt67
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_069.txt48
-rw-r--r--test/prism/snapshots/seattlerb/parse_pattern_076.txt58
-rw-r--r--test/prism/snapshots/seattlerb/parse_until_not_canonical.txt49
-rw-r--r--test/prism/snapshots/seattlerb/parse_until_not_noncanonical.txt49
-rw-r--r--test/prism/snapshots/seattlerb/parse_while_not_canonical.txt49
-rw-r--r--test/prism/snapshots/seattlerb/parse_while_not_noncanonical.txt49
-rw-r--r--test/prism/snapshots/seattlerb/pctW_lineno.txt52
-rw-r--r--test/prism/snapshots/seattlerb/pct_Q_backslash_nl.txt11
-rw-r--r--test/prism/snapshots/seattlerb/pct_nl.txt17
-rw-r--r--test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt51
-rw-r--r--test/prism/snapshots/seattlerb/pipe_semicolon.txt39
-rw-r--r--test/prism/snapshots/seattlerb/pipe_space.txt36
-rw-r--r--test/prism/snapshots/seattlerb/qWords_space.txt10
-rw-r--r--test/prism/snapshots/seattlerb/qsymbols.txt28
-rw-r--r--test/prism/snapshots/seattlerb/qsymbols_empty.txt10
-rw-r--r--test/prism/snapshots/seattlerb/qsymbols_empty_space.txt10
-rw-r--r--test/prism/snapshots/seattlerb/qsymbols_interp.txt57
-rw-r--r--test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt35
-rw-r--r--test/prism/snapshots/seattlerb/quoted_symbol_keys.txt25
-rw-r--r--test/prism/snapshots/seattlerb/qw_escape.txt11
-rw-r--r--test/prism/snapshots/seattlerb/qw_escape_term.txt11
-rw-r--r--test/prism/snapshots/seattlerb/qwords_empty.txt10
-rw-r--r--test/prism/snapshots/seattlerb/read_escape_unicode_curlies.txt11
-rw-r--r--test/prism/snapshots/seattlerb/read_escape_unicode_h4.txt11
-rw-r--r--test/prism/snapshots/seattlerb/regexp.txt35
-rw-r--r--test/prism/snapshots/seattlerb/regexp_esc_C_slash.txt11
-rw-r--r--test/prism/snapshots/seattlerb/regexp_esc_u.txt11
-rw-r--r--test/prism/snapshots/seattlerb/regexp_escape_extended.txt11
-rw-r--r--test/prism/snapshots/seattlerb/regexp_unicode_curlies.txt17
-rw-r--r--test/prism/snapshots/seattlerb/required_kwarg_no_value.txt34
-rw-r--r--test/prism/snapshots/seattlerb/rescue_do_end_ensure_result.txt58
-rw-r--r--test/prism/snapshots/seattlerb/rescue_do_end_no_raise.txt75
-rw-r--r--test/prism/snapshots/seattlerb/rescue_do_end_raised.txt52
-rw-r--r--test/prism/snapshots/seattlerb/rescue_do_end_rescued.txt79
-rw-r--r--test/prism/snapshots/seattlerb/rescue_in_block.txt47
-rw-r--r--test/prism/snapshots/seattlerb/rescue_parens.txt48
-rw-r--r--test/prism/snapshots/seattlerb/return_call_assocs.txt212
-rw-r--r--test/prism/snapshots/seattlerb/rhs_asgn.txt15
-rw-r--r--test/prism/snapshots/seattlerb/ruby21_numbers.txt27
-rw-r--r--test/prism/snapshots/seattlerb/safe_attrasgn.txt31
-rw-r--r--test/prism/snapshots/seattlerb/safe_attrasgn_constant.txt31
-rw-r--r--test/prism/snapshots/seattlerb/safe_call.txt25
-rw-r--r--test/prism/snapshots/seattlerb/safe_call_after_newline.txt25
-rw-r--r--test/prism/snapshots/seattlerb/safe_call_dot_parens.txt25
-rw-r--r--test/prism/snapshots/seattlerb/safe_call_newline.txt25
-rw-r--r--test/prism/snapshots/seattlerb/safe_call_operator.txt31
-rw-r--r--test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt31
-rw-r--r--test/prism/snapshots/seattlerb/safe_calls.txt41
-rw-r--r--test/prism/snapshots/seattlerb/safe_op_asgn.txt41
-rw-r--r--test/prism/snapshots/seattlerb/safe_op_asgn2.txt34
-rw-r--r--test/prism/snapshots/seattlerb/slashy_newlines_within_string.txt57
-rw-r--r--test/prism/snapshots/seattlerb/stabby_arg_no_paren.txt28
-rw-r--r--test/prism/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt50
-rw-r--r--test/prism/snapshots/seattlerb/stabby_block_iter_call.txt58
-rw-r--r--test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt54
-rw-r--r--test/prism/snapshots/seattlerb/stabby_block_kw.txt33
-rw-r--r--test/prism/snapshots/seattlerb/stabby_block_kw__required.txt29
-rw-r--r--test/prism/snapshots/seattlerb/stabby_proc_scope.txt31
-rw-r--r--test/prism/snapshots/seattlerb/str_backslashes.txt24
-rw-r--r--test/prism/snapshots/seattlerb/str_double_double_escaped_newline.txt34
-rw-r--r--test/prism/snapshots/seattlerb/str_double_escaped_newline.txt34
-rw-r--r--test/prism/snapshots/seattlerb/str_double_newline.txt34
-rw-r--r--test/prism/snapshots/seattlerb/str_evstr.txt32
-rw-r--r--test/prism/snapshots/seattlerb/str_evstr_escape.txt38
-rw-r--r--test/prism/snapshots/seattlerb/str_heredoc_interp.txt32
-rw-r--r--test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt105
-rw-r--r--test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt22
-rw-r--r--test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt14
-rw-r--r--test/prism/snapshots/seattlerb/str_pct_Q_nested.txt38
-rw-r--r--test/prism/snapshots/seattlerb/str_pct_nested_nested.txt42
-rw-r--r--test/prism/snapshots/seattlerb/str_pct_q.txt11
-rw-r--r--test/prism/snapshots/seattlerb/str_single_double_escaped_newline.txt34
-rw-r--r--test/prism/snapshots/seattlerb/str_single_escaped_newline.txt34
-rw-r--r--test/prism/snapshots/seattlerb/str_single_newline.txt34
-rw-r--r--test/prism/snapshots/seattlerb/str_str.txt28
-rw-r--r--test/prism/snapshots/seattlerb/str_str_str.txt34
-rw-r--r--test/prism/snapshots/seattlerb/super_arg.txt17
-rw-r--r--test/prism/snapshots/seattlerb/symbol_empty.txt11
-rw-r--r--test/prism/snapshots/seattlerb/symbol_list.txt50
-rw-r--r--test/prism/snapshots/seattlerb/symbols.txt28
-rw-r--r--test/prism/snapshots/seattlerb/symbols_empty.txt10
-rw-r--r--test/prism/snapshots/seattlerb/symbols_empty_space.txt10
-rw-r--r--test/prism/snapshots/seattlerb/symbols_interp.txt28
-rw-r--r--test/prism/snapshots/seattlerb/thingy.txt57
-rw-r--r--test/prism/snapshots/seattlerb/uminus_float.txt7
-rw-r--r--test/prism/snapshots/seattlerb/unary_minus.txt25
-rw-r--r--test/prism/snapshots/seattlerb/unary_plus.txt25
-rw-r--r--test/prism/snapshots/seattlerb/unary_plus_on_literal.txt21
-rw-r--r--test/prism/snapshots/seattlerb/unary_tilde.txt25
-rw-r--r--test/prism/snapshots/seattlerb/utf8_bom.txt21
-rw-r--r--test/prism/snapshots/seattlerb/when_splat.txt39
-rw-r--r--test/prism/snapshots/seattlerb/words_interp.txt30
-rw-r--r--test/prism/snapshots/seattlerb/yield_arg.txt16
-rw-r--r--test/prism/snapshots/seattlerb/yield_call_assocs.txt224
-rw-r--r--test/prism/snapshots/seattlerb/yield_empty_parens.txt10
-rw-r--r--test/prism/snapshots/single_method_call_with_bang.txt15
-rw-r--r--test/prism/snapshots/single_quote_heredocs.txt11
-rw-r--r--test/prism/snapshots/spanning_heredoc.txt413
-rw-r--r--test/prism/snapshots/spanning_heredoc_newlines.txt155
-rw-r--r--test/prism/snapshots/strings.txt534
-rw-r--r--test/prism/snapshots/super.txt132
-rw-r--r--test/prism/snapshots/symbols.txt464
-rw-r--r--test/prism/snapshots/ternary_operator.txt295
-rw-r--r--test/prism/snapshots/tilde_heredocs.txt405
-rw-r--r--test/prism/snapshots/undef.txt117
-rw-r--r--test/prism/snapshots/unescaping.txt34
-rw-r--r--test/prism/snapshots/unless.txt172
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/alias.txt29
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/assignment.txt1080
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/block.txt1402
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/case.txt446
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/class.txt233
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/def.txt1204
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/defined.txt55
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/defs.txt360
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/dstr.txt352
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/empty.txt5
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/empty_begin.txt9
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/flipflop.txt237
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/for.txt171
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/hookexe.txt49
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/if.txt288
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/kwbegin.txt491
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/lambda.txt151
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/literal.txt1198
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/module.txt107
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/opasgn.txt509
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/pattern.txt446
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/pragma.txt20
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/range.txt55
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/rescue.txt101
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/send.txt2190
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/27.txt49
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/30.txt88
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/31.txt90
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/since/32.txt156
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/singletons.txt9
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/super.txt277
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/unary.txt248
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/undef.txt29
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/variables.txt53
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/while.txt704
-rw-r--r--test/prism/snapshots/unparser/corpus/literal/yield.txt56
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/and.txt235
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/block.txt191
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/def.txt90
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/dstr.txt598
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/kwbegin.txt259
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/literal.txt103
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/opasgn.txt69
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/send.txt163
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/undef.txt29
-rw-r--r--test/prism/snapshots/unparser/corpus/semantic/while.txt277
-rw-r--r--test/prism/snapshots/until.txt179
-rw-r--r--test/prism/snapshots/variables.txt408
-rw-r--r--test/prism/snapshots/while.txt469
-rw-r--r--test/prism/snapshots/whitequark/__ENCODING__.txt6
-rw-r--r--test/prism/snapshots/whitequark/__ENCODING___legacy_.txt6
-rw-r--r--test/prism/snapshots/whitequark/alias.txt21
-rw-r--r--test/prism/snapshots/whitequark/alias_gvar.txt21
-rw-r--r--test/prism/snapshots/whitequark/ambiuous_quoted_label_in_ternary_operator.txt60
-rw-r--r--test/prism/snapshots/whitequark/and.txt53
-rw-r--r--test/prism/snapshots/whitequark/and_asgn.txt59
-rw-r--r--test/prism/snapshots/whitequark/and_or_masgn.txt93
-rw-r--r--test/prism/snapshots/whitequark/anonymous_blockarg.txt46
-rw-r--r--test/prism/snapshots/whitequark/arg.txt56
-rw-r--r--test/prism/snapshots/whitequark/arg_duplicate_ignored.txt59
-rw-r--r--test/prism/snapshots/whitequark/arg_label.txt115
-rw-r--r--test/prism/snapshots/whitequark/arg_scope.txt34
-rw-r--r--test/prism/snapshots/whitequark/args.txt1075
-rw-r--r--test/prism/snapshots/whitequark/args_args_assocs.txt96
-rw-r--r--test/prism/snapshots/whitequark/args_args_assocs_comma.txt54
-rw-r--r--test/prism/snapshots/whitequark/args_args_comma.txt38
-rw-r--r--test/prism/snapshots/whitequark/args_args_star.txt90
-rw-r--r--test/prism/snapshots/whitequark/args_assocs.txt195
-rw-r--r--test/prism/snapshots/whitequark/args_assocs_comma.txt44
-rw-r--r--test/prism/snapshots/whitequark/args_assocs_legacy.txt195
-rw-r--r--test/prism/snapshots/whitequark/args_block_pass.txt28
-rw-r--r--test/prism/snapshots/whitequark/args_cmd.txt41
-rw-r--r--test/prism/snapshots/whitequark/args_star.txt70
-rw-r--r--test/prism/snapshots/whitequark/array_assocs.txt44
-rw-r--r--test/prism/snapshots/whitequark/array_plain.txt16
-rw-r--r--test/prism/snapshots/whitequark/array_splat.txt68
-rw-r--r--test/prism/snapshots/whitequark/array_symbols.txt22
-rw-r--r--test/prism/snapshots/whitequark/array_symbols_empty.txt15
-rw-r--r--test/prism/snapshots/whitequark/array_symbols_interp.txt67
-rw-r--r--test/prism/snapshots/whitequark/array_words.txt22
-rw-r--r--test/prism/snapshots/whitequark/array_words_empty.txt15
-rw-r--r--test/prism/snapshots/whitequark/array_words_interp.txt80
-rw-r--r--test/prism/snapshots/whitequark/asgn_cmd.txt55
-rw-r--r--test/prism/snapshots/whitequark/asgn_mrhs.txt87
-rw-r--r--test/prism/snapshots/whitequark/back_ref.txt7
-rw-r--r--test/prism/snapshots/whitequark/bang.txt25
-rw-r--r--test/prism/snapshots/whitequark/bang_cmd.txt38
-rw-r--r--test/prism/snapshots/whitequark/begin_cmdarg.txt51
-rw-r--r--test/prism/snapshots/whitequark/beginless_erange_after_newline.txt23
-rw-r--r--test/prism/snapshots/whitequark/beginless_irange_after_newline.txt23
-rw-r--r--test/prism/snapshots/whitequark/beginless_range.txt21
-rw-r--r--test/prism/snapshots/whitequark/blockarg.txt31
-rw-r--r--test/prism/snapshots/whitequark/blockargs.txt1339
-rw-r--r--test/prism/snapshots/whitequark/bug_435.txt39
-rw-r--r--test/prism/snapshots/whitequark/bug_447.txt56
-rw-r--r--test/prism/snapshots/whitequark/bug_452.txt63
-rw-r--r--test/prism/snapshots/whitequark/bug_466.txt70
-rw-r--r--test/prism/snapshots/whitequark/bug_473.txt34
-rw-r--r--test/prism/snapshots/whitequark/bug_480.txt37
-rw-r--r--test/prism/snapshots/whitequark/bug_481.txt50
-rw-r--r--test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt11
-rw-r--r--test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt30
-rw-r--r--test/prism/snapshots/whitequark/bug_cmdarg.txt106
-rw-r--r--test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt18
-rw-r--r--test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt50
-rw-r--r--test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt40
-rw-r--r--test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt383
-rw-r--r--test/prism/snapshots/whitequark/bug_heredoc_do.txt30
-rw-r--r--test/prism/snapshots/whitequark/bug_interp_single.txt38
-rw-r--r--test/prism/snapshots/whitequark/bug_lambda_leakage.txt38
-rw-r--r--test/prism/snapshots/whitequark/bug_regex_verification.txt11
-rw-r--r--test/prism/snapshots/whitequark/bug_rescue_empty_else.txt25
-rw-r--r--test/prism/snapshots/whitequark/bug_while_not_parens_do.txt28
-rw-r--r--test/prism/snapshots/whitequark/case_cond.txt34
-rw-r--r--test/prism/snapshots/whitequark/case_cond_else.txt46
-rw-r--r--test/prism/snapshots/whitequark/case_expr.txt44
-rw-r--r--test/prism/snapshots/whitequark/case_expr_else.txt60
-rw-r--r--test/prism/snapshots/whitequark/casgn_scoped.txt20
-rw-r--r--test/prism/snapshots/whitequark/casgn_toplevel.txt18
-rw-r--r--test/prism/snapshots/whitequark/casgn_unscoped.txt13
-rw-r--r--test/prism/snapshots/whitequark/character.txt11
-rw-r--r--test/prism/snapshots/whitequark/class.txt27
-rw-r--r--test/prism/snapshots/whitequark/class_super.txt18
-rw-r--r--test/prism/snapshots/whitequark/class_super_label.txt35
-rw-r--r--test/prism/snapshots/whitequark/comments_before_leading_dot__27.txt85
-rw-r--r--test/prism/snapshots/whitequark/complex.txt27
-rw-r--r--test/prism/snapshots/whitequark/cond_begin.txt40
-rw-r--r--test/prism/snapshots/whitequark/cond_begin_masgn.txt52
-rw-r--r--test/prism/snapshots/whitequark/cond_eflipflop.txt78
-rw-r--r--test/prism/snapshots/whitequark/cond_eflipflop_with_beginless_range.txt27
-rw-r--r--test/prism/snapshots/whitequark/cond_eflipflop_with_endless_range.txt27
-rw-r--r--test/prism/snapshots/whitequark/cond_iflipflop.txt78
-rw-r--r--test/prism/snapshots/whitequark/cond_iflipflop_with_beginless_range.txt27
-rw-r--r--test/prism/snapshots/whitequark/cond_iflipflop_with_endless_range.txt27
-rw-r--r--test/prism/snapshots/whitequark/cond_match_current_line.txt34
-rw-r--r--test/prism/snapshots/whitequark/const_op_asgn.txt101
-rw-r--r--test/prism/snapshots/whitequark/const_scoped.txt13
-rw-r--r--test/prism/snapshots/whitequark/const_toplevel.txt11
-rw-r--r--test/prism/snapshots/whitequark/const_unscoped.txt7
-rw-r--r--test/prism/snapshots/whitequark/cpath.txt33
-rw-r--r--test/prism/snapshots/whitequark/cvar.txt7
-rw-r--r--test/prism/snapshots/whitequark/cvasgn.txt13
-rw-r--r--test/prism/snapshots/whitequark/dedenting_heredoc.txt496
-rw-r--r--test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt22
-rw-r--r--test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt22
-rw-r--r--test/prism/snapshots/whitequark/def.txt83
-rw-r--r--test/prism/snapshots/whitequark/defined.txt42
-rw-r--r--test/prism/snapshots/whitequark/defs.txt90
-rw-r--r--test/prism/snapshots/whitequark/empty_stmt.txt5
-rw-r--r--test/prism/snapshots/whitequark/endless_comparison_method.txt221
-rw-r--r--test/prism/snapshots/whitequark/endless_method.txt151
-rw-r--r--test/prism/snapshots/whitequark/endless_method_command_syntax.txt394
-rw-r--r--test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt43
-rw-r--r--test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt56
-rw-r--r--test/prism/snapshots/whitequark/endless_method_without_args.txt89
-rw-r--r--test/prism/snapshots/whitequark/ensure.txt40
-rw-r--r--test/prism/snapshots/whitequark/ensure_empty.txt16
-rw-r--r--test/prism/snapshots/whitequark/false.txt6
-rw-r--r--test/prism/snapshots/whitequark/float.txt9
-rw-r--r--test/prism/snapshots/whitequark/for.txt83
-rw-r--r--test/prism/snapshots/whitequark/for_mlhs.txt56
-rw-r--r--test/prism/snapshots/whitequark/forward_arg.txt43
-rw-r--r--test/prism/snapshots/whitequark/forward_arg_with_open_args.txt404
-rw-r--r--test/prism/snapshots/whitequark/forward_args_legacy.txt99
-rw-r--r--test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt58
-rw-r--r--test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt55
-rw-r--r--test/prism/snapshots/whitequark/forwarded_kwrestarg.txt52
-rw-r--r--test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt63
-rw-r--r--test/prism/snapshots/whitequark/forwarded_restarg.txt49
-rw-r--r--test/prism/snapshots/whitequark/gvar.txt7
-rw-r--r--test/prism/snapshots/whitequark/gvasgn.txt13
-rw-r--r--test/prism/snapshots/whitequark/hash_empty.txt9
-rw-r--r--test/prism/snapshots/whitequark/hash_hashrocket.txt49
-rw-r--r--test/prism/snapshots/whitequark/hash_kwsplat.txt35
-rw-r--r--test/prism/snapshots/whitequark/hash_label.txt22
-rw-r--r--test/prism/snapshots/whitequark/hash_label_end.txt100
-rw-r--r--test/prism/snapshots/whitequark/hash_pair_value_omission.txt97
-rw-r--r--test/prism/snapshots/whitequark/heredoc.txt23
-rw-r--r--test/prism/snapshots/whitequark/if.txt63
-rw-r--r--test/prism/snapshots/whitequark/if_else.txt95
-rw-r--r--test/prism/snapshots/whitequark/if_elsif.txt65
-rw-r--r--test/prism/snapshots/whitequark/if_masgn__24.txt42
-rw-r--r--test/prism/snapshots/whitequark/if_mod.txt34
-rw-r--r--test/prism/snapshots/whitequark/if_nl_then.txt34
-rw-r--r--test/prism/snapshots/whitequark/int.txt14
-rw-r--r--test/prism/snapshots/whitequark/int___LINE__.txt6
-rw-r--r--test/prism/snapshots/whitequark/interp_digit_var.txt273
-rw-r--r--test/prism/snapshots/whitequark/ivar.txt7
-rw-r--r--test/prism/snapshots/whitequark/ivasgn.txt13
-rw-r--r--test/prism/snapshots/whitequark/keyword_argument_omission.txt65
-rw-r--r--test/prism/snapshots/whitequark/kwarg.txt30
-rw-r--r--test/prism/snapshots/whitequark/kwbegin_compstmt.txt34
-rw-r--r--test/prism/snapshots/whitequark/kwnilarg.txt84
-rw-r--r--test/prism/snapshots/whitequark/kwoptarg.txt34
-rw-r--r--test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt58
-rw-r--r--test/prism/snapshots/whitequark/kwrestarg_named.txt31
-rw-r--r--test/prism/snapshots/whitequark/kwrestarg_unnamed.txt31
-rw-r--r--test/prism/snapshots/whitequark/lbrace_arg_after_command_args.txt54
-rw-r--r--test/prism/snapshots/whitequark/lparenarg_after_lvar__since_25.txt67
-rw-r--r--test/prism/snapshots/whitequark/lvar.txt15
-rw-r--r--test/prism/snapshots/whitequark/lvar_injecting_match.txt39
-rw-r--r--test/prism/snapshots/whitequark/lvasgn.txt17
-rw-r--r--test/prism/snapshots/whitequark/masgn.txt83
-rw-r--r--test/prism/snapshots/whitequark/masgn_attr.txt82
-rw-r--r--test/prism/snapshots/whitequark/masgn_cmd.txt35
-rw-r--r--test/prism/snapshots/whitequark/masgn_const.txt46
-rw-r--r--test/prism/snapshots/whitequark/masgn_nested.txt66
-rw-r--r--test/prism/snapshots/whitequark/masgn_splat.txt284
-rw-r--r--test/prism/snapshots/whitequark/module.txt14
-rw-r--r--test/prism/snapshots/whitequark/multiple_pattern_matches.txt173
-rw-r--r--test/prism/snapshots/whitequark/newline_in_hash_argument.txt163
-rw-r--r--test/prism/snapshots/whitequark/nil.txt6
-rw-r--r--test/prism/snapshots/whitequark/nil_expression.txt16
-rw-r--r--test/prism/snapshots/whitequark/non_lvar_injecting_match.txt44
-rw-r--r--test/prism/snapshots/whitequark/not.txt55
-rw-r--r--test/prism/snapshots/whitequark/not_cmd.txt38
-rw-r--r--test/prism/snapshots/whitequark/not_masgn__24.txt45
-rw-r--r--test/prism/snapshots/whitequark/nth_ref.txt7
-rw-r--r--test/prism/snapshots/whitequark/numbered_args_after_27.txt143
-rw-r--r--test/prism/snapshots/whitequark/numparam_outside_block.txt114
-rw-r--r--test/prism/snapshots/whitequark/numparam_ruby_bug_19025.txt49
-rw-r--r--test/prism/snapshots/whitequark/op_asgn.txt74
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_cmd.txt178
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_index.txt38
-rw-r--r--test/prism/snapshots/whitequark/op_asgn_index_cmd.txt58
-rw-r--r--test/prism/snapshots/whitequark/optarg.txt74
-rw-r--r--test/prism/snapshots/whitequark/or.txt53
-rw-r--r--test/prism/snapshots/whitequark/or_asgn.txt59
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_272.txt42
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_490.txt106
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_507.txt36
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_518.txt18
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_525.txt65
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_604.txt57
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_640.txt22
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_645.txt35
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_830.txt11
-rw-r--r--test/prism/snapshots/whitequark/parser_bug_989.txt11
-rw-r--r--test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt20
-rw-r--r--test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt139
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt54
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching_blank_else.txt31
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching_else.txt36
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching_single_line.txt45
-rw-r--r--test/prism/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt249
-rw-r--r--test/prism/snapshots/whitequark/postexe.txt15
-rw-r--r--test/prism/snapshots/whitequark/preexe.txt15
-rw-r--r--test/prism/snapshots/whitequark/procarg0.txt78
-rw-r--r--test/prism/snapshots/whitequark/range_exclusive.txt16
-rw-r--r--test/prism/snapshots/whitequark/range_inclusive.txt16
-rw-r--r--test/prism/snapshots/whitequark/rational.txt14
-rw-r--r--test/prism/snapshots/whitequark/regex_interp.txt38
-rw-r--r--test/prism/snapshots/whitequark/regex_plain.txt11
-rw-r--r--test/prism/snapshots/whitequark/resbody_list.txt45
-rw-r--r--test/prism/snapshots/whitequark/resbody_list_mrhs.txt55
-rw-r--r--test/prism/snapshots/whitequark/resbody_list_var.txt56
-rw-r--r--test/prism/snapshots/whitequark/resbody_var.txt86
-rw-r--r--test/prism/snapshots/whitequark/rescue.txt43
-rw-r--r--test/prism/snapshots/whitequark/rescue_else.txt59
-rw-r--r--test/prism/snapshots/whitequark/rescue_else_ensure.txt75
-rw-r--r--test/prism/snapshots/whitequark/rescue_ensure.txt59
-rw-r--r--test/prism/snapshots/whitequark/rescue_in_lambda_block.txt26
-rw-r--r--test/prism/snapshots/whitequark/rescue_mod.txt29
-rw-r--r--test/prism/snapshots/whitequark/rescue_mod_asgn.txt35
-rw-r--r--test/prism/snapshots/whitequark/rescue_mod_masgn.txt44
-rw-r--r--test/prism/snapshots/whitequark/rescue_mod_op_assign.txt36
-rw-r--r--test/prism/snapshots/whitequark/rescue_without_begin_end.txt59
-rw-r--r--test/prism/snapshots/whitequark/restarg_named.txt31
-rw-r--r--test/prism/snapshots/whitequark/restarg_unnamed.txt31
-rw-r--r--test/prism/snapshots/whitequark/return.txt56
-rw-r--r--test/prism/snapshots/whitequark/return_block.txt40
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_10279.txt32
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_10653.txt173
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11107.txt48
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11380.txt55
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11873.txt767
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11873_a.txt1231
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11873_b.txt98
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11989.txt24
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_11990.txt35
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12073.txt96
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12402.txt567
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12669.txt133
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_12686.txt39
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_13547.txt31
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_14690.txt59
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_15789.txt120
-rw-r--r--test/prism/snapshots/whitequark/ruby_bug_9669.txt58
-rw-r--r--test/prism/snapshots/whitequark/sclass.txt25
-rw-r--r--test/prism/snapshots/whitequark/self.txt6
-rw-r--r--test/prism/snapshots/whitequark/send_attr_asgn.txt106
-rw-r--r--test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt31
-rw-r--r--test/prism/snapshots/whitequark/send_binary_op.txt551
-rw-r--r--test/prism/snapshots/whitequark/send_block_chain_cmd.txt325
-rw-r--r--test/prism/snapshots/whitequark/send_block_conditional.txt31
-rw-r--r--test/prism/snapshots/whitequark/send_call.txt57
-rw-r--r--test/prism/snapshots/whitequark/send_conditional.txt25
-rw-r--r--test/prism/snapshots/whitequark/send_index.txt34
-rw-r--r--test/prism/snapshots/whitequark/send_index_asgn.txt37
-rw-r--r--test/prism/snapshots/whitequark/send_index_asgn_legacy.txt37
-rw-r--r--test/prism/snapshots/whitequark/send_index_cmd.txt51
-rw-r--r--test/prism/snapshots/whitequark/send_index_legacy.txt34
-rw-r--r--test/prism/snapshots/whitequark/send_lambda.txt44
-rw-r--r--test/prism/snapshots/whitequark/send_lambda_args.txt51
-rw-r--r--test/prism/snapshots/whitequark/send_lambda_args_noparen.txt57
-rw-r--r--test/prism/snapshots/whitequark/send_lambda_args_shadow.txt34
-rw-r--r--test/prism/snapshots/whitequark/send_lambda_legacy.txt12
-rw-r--r--test/prism/snapshots/whitequark/send_op_asgn_conditional.txt27
-rw-r--r--test/prism/snapshots/whitequark/send_plain.txt65
-rw-r--r--test/prism/snapshots/whitequark/send_plain_cmd.txt104
-rw-r--r--test/prism/snapshots/whitequark/send_self.txt41
-rw-r--r--test/prism/snapshots/whitequark/send_self_block.txt75
-rw-r--r--test/prism/snapshots/whitequark/send_unary_op.txt65
-rw-r--r--test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt34
-rw-r--r--test/prism/snapshots/whitequark/space_args_arg.txt27
-rw-r--r--test/prism/snapshots/whitequark/space_args_arg_block.txt109
-rw-r--r--test/prism/snapshots/whitequark/space_args_arg_call.txt37
-rw-r--r--test/prism/snapshots/whitequark/space_args_arg_newline.txt27
-rw-r--r--test/prism/snapshots/whitequark/space_args_block.txt28
-rw-r--r--test/prism/snapshots/whitequark/space_args_cmd.txt47
-rw-r--r--test/prism/snapshots/whitequark/string___FILE__.txt8
-rw-r--r--test/prism/snapshots/whitequark/string_concat.txt32
-rw-r--r--test/prism/snapshots/whitequark/string_dvar.txt37
-rw-r--r--test/prism/snapshots/whitequark/string_interp.txt38
-rw-r--r--test/prism/snapshots/whitequark/string_plain.txt17
-rw-r--r--test/prism/snapshots/whitequark/super.txt49
-rw-r--r--test/prism/snapshots/whitequark/super_block.txt48
-rw-r--r--test/prism/snapshots/whitequark/symbol_interp.txt37
-rw-r--r--test/prism/snapshots/whitequark/symbol_plain.txt17
-rw-r--r--test/prism/snapshots/whitequark/ternary.txt36
-rw-r--r--test/prism/snapshots/whitequark/ternary_ambiguous_symbol.txt50
-rw-r--r--test/prism/snapshots/whitequark/trailing_forward_arg.txt55
-rw-r--r--test/prism/snapshots/whitequark/true.txt6
-rw-r--r--test/prism/snapshots/whitequark/unary_num_pow_precedence.txt80
-rw-r--r--test/prism/snapshots/whitequark/undef.txt39
-rw-r--r--test/prism/snapshots/whitequark/unless.txt63
-rw-r--r--test/prism/snapshots/whitequark/unless_else.txt95
-rw-r--r--test/prism/snapshots/whitequark/unless_mod.txt34
-rw-r--r--test/prism/snapshots/whitequark/until.txt61
-rw-r--r--test/prism/snapshots/whitequark/until_mod.txt33
-rw-r--r--test/prism/snapshots/whitequark/until_post.txt42
-rw-r--r--test/prism/snapshots/whitequark/var_and_asgn.txt14
-rw-r--r--test/prism/snapshots/whitequark/var_op_asgn.txt57
-rw-r--r--test/prism/snapshots/whitequark/var_op_asgn_cmd.txt28
-rw-r--r--test/prism/snapshots/whitequark/var_or_asgn.txt14
-rw-r--r--test/prism/snapshots/whitequark/when_multi.txt50
-rw-r--r--test/prism/snapshots/whitequark/when_splat.txt72
-rw-r--r--test/prism/snapshots/whitequark/when_then.txt44
-rw-r--r--test/prism/snapshots/whitequark/while.txt61
-rw-r--r--test/prism/snapshots/whitequark/while_mod.txt33
-rw-r--r--test/prism/snapshots/whitequark/while_post.txt42
-rw-r--r--test/prism/snapshots/whitequark/xstring_interp.txt37
-rw-r--r--test/prism/snapshots/whitequark/xstring_plain.txt11
-rw-r--r--test/prism/snapshots/whitequark/yield.txt51
-rw-r--r--test/prism/snapshots/whitequark/zsuper.txt7
-rw-r--r--test/prism/snapshots/xstring.txt67
-rw-r--r--test/prism/snapshots/xstring_with_backslash.txt11
-rw-r--r--test/prism/snapshots/yield.txt103
-rw-r--r--test/prism/static_inspect_test.rb90
-rw-r--r--test/prism/static_literals_test.rb92
-rw-r--r--test/prism/test_helper.rb126
-rw-r--r--test/prism/unescape_test.rb235
-rw-r--r--test/prism/version_test.rb11
-rw-r--r--test/prism/warnings_test.rb236
-rw-r--r--test/psych/test_coder.rb6
-rw-r--r--test/psych/test_date_time.rb20
-rw-r--r--test/psych/test_encoding.rb11
-rw-r--r--test/psych/test_numeric.rb9
-rw-r--r--test/psych/test_object_references.rb8
-rw-r--r--test/psych/test_parser.rb31
-rw-r--r--test/psych/test_psych.rb33
-rw-r--r--test/psych/test_scalar_scanner.rb2
-rw-r--r--test/psych/test_set.rb7
-rw-r--r--test/psych/test_string.rb12
-rw-r--r--test/psych/test_yaml.rb34
-rw-r--r--test/psych/visitors/test_emitter.rb16
-rw-r--r--test/psych/visitors/test_to_ruby.rb2
-rw-r--r--test/psych/visitors/test_yaml_tree.rb8
-rw-r--r--test/racc/assets/cadenza.y170
-rw-r--r--test/racc/assets/cast.y926
-rw-r--r--test/racc/assets/chk.y126
-rw-r--r--test/racc/assets/conf.y16
-rw-r--r--test/racc/assets/csspool.y729
-rw-r--r--test/racc/assets/digraph.y29
-rw-r--r--test/racc/assets/echk.y118
-rw-r--r--test/racc/assets/edtf.y583
-rw-r--r--test/racc/assets/err.y60
-rw-r--r--test/racc/assets/error_recovery.y35
-rw-r--r--test/racc/assets/expect.y7
-rw-r--r--test/racc/assets/firstline.y4
-rw-r--r--test/racc/assets/huia.y318
-rw-r--r--test/racc/assets/ichk.y102
-rw-r--r--test/racc/assets/ifelse.y14
-rw-r--r--test/racc/assets/intp.y546
-rw-r--r--test/racc/assets/journey.y47
-rw-r--r--test/racc/assets/liquor.y313
-rw-r--r--test/racc/assets/machete.y423
-rw-r--r--test/racc/assets/macruby.y2197
-rw-r--r--test/racc/assets/mailp.y437
-rw-r--r--test/racc/assets/mediacloth.y599
-rw-r--r--test/racc/assets/mof.y649
-rw-r--r--test/racc/assets/namae.y302
-rw-r--r--test/racc/assets/nasl.y626
-rw-r--r--test/racc/assets/newsyn.y25
-rw-r--r--test/racc/assets/noend.y4
-rw-r--r--test/racc/assets/nokogiri-css.y255
-rw-r--r--test/racc/assets/nonass.y41
-rw-r--r--test/racc/assets/normal.y27
-rw-r--r--test/racc/assets/norule.y4
-rw-r--r--test/racc/assets/nullbug1.y25
-rw-r--r--test/racc/assets/nullbug2.y15
-rw-r--r--test/racc/assets/opal.y1807
-rw-r--r--test/racc/assets/opt.y123
-rw-r--r--test/racc/assets/percent.y35
-rw-r--r--test/racc/assets/php_serialization.y98
-rw-r--r--test/racc/assets/recv.y97
-rw-r--r--test/racc/assets/riml.y665
-rw-r--r--test/racc/assets/rrconf.y14
-rw-r--r--test/racc/assets/ruby18.y1943
-rw-r--r--test/racc/assets/ruby19.y2174
-rw-r--r--test/racc/assets/ruby20.y2350
-rw-r--r--test/racc/assets/ruby21.y2359
-rw-r--r--test/racc/assets/ruby22.y2381
-rw-r--r--test/racc/assets/scan.y72
-rw-r--r--test/racc/assets/syntax.y50
-rw-r--r--test/racc/assets/tp_plus.y622
-rw-r--r--test/racc/assets/twowaysql.y278
-rw-r--r--test/racc/assets/unterm.y5
-rw-r--r--test/racc/assets/useless.y12
-rw-r--r--test/racc/assets/yyerr.y46
-rw-r--r--test/racc/bench.y36
-rw-r--r--test/racc/case.rb109
-rw-r--r--test/racc/infini.y8
-rw-r--r--test/racc/regress/README.txt7
-rw-r--r--test/racc/regress/cadenza796
-rw-r--r--test/racc/regress/cast3945
-rw-r--r--test/racc/regress/csspool2314
-rw-r--r--test/racc/regress/edtf1794
-rw-r--r--test/racc/regress/huia1681
-rw-r--r--test/racc/regress/journey222
-rw-r--r--test/racc/regress/liquor885
-rw-r--r--test/racc/regress/machete833
-rw-r--r--test/racc/regress/mediacloth1463
-rw-r--r--test/racc/regress/mof1368
-rw-r--r--test/racc/regress/namae634
-rw-r--r--test/racc/regress/nasl2548
-rw-r--r--test/racc/regress/nokogiri-css836
-rw-r--r--test/racc/regress/opal10107
-rw-r--r--test/racc/regress/php_serialization336
-rw-r--r--test/racc/regress/riml4037
-rw-r--r--test/racc/regress/ruby189945
-rw-r--r--test/racc/regress/ruby2211180
-rw-r--r--test/racc/regress/tp_plus1933
-rw-r--r--test/racc/regress/twowaysql556
-rw-r--r--test/racc/scandata/brace7
-rw-r--r--test/racc/scandata/gvar1
-rw-r--r--test/racc/scandata/normal4
-rw-r--r--test/racc/scandata/percent18
-rw-r--r--test/racc/scandata/slash10
-rw-r--r--test/racc/src.intp34
-rw-r--r--test/racc/start.y20
-rw-r--r--test/racc/test_chk_y.rb52
-rw-r--r--test/racc/test_grammar_file_parser.rb15
-rw-r--r--test/racc/test_racc_command.rb339
-rw-r--r--test/racc/test_scan_y.rb52
-rw-r--r--test/racc/testscanner.rb51
-rw-r--r--test/rdoc/support/test_case.rb4
-rw-r--r--test/rdoc/support/text_formatter_test_case.rb1
-rw-r--r--test/rdoc/test_rdoc_any_method.rb38
-rw-r--r--test/rdoc/test_rdoc_comment.rb9
-rw-r--r--test/rdoc/test_rdoc_context.rb6
-rw-r--r--test/rdoc/test_rdoc_context_section.rb1
-rw-r--r--test/rdoc/test_rdoc_generator_darkfish.rb95
-rw-r--r--test/rdoc/test_rdoc_generator_json_index.rb14
-rw-r--r--test/rdoc/test_rdoc_generator_markup.rb1
-rw-r--r--test/rdoc/test_rdoc_markdown.rb40
-rw-r--r--test/rdoc/test_rdoc_markup.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_attribute_manager.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_attributes.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_document.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_formatter.rb6
-rw-r--r--test/rdoc/test_rdoc_markup_hard_break.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_heading.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_include.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_indented_paragraph.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_paragraph.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_raw.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_to_ansi.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_to_html.rb121
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_crossref.rb12
-rw-r--r--test/rdoc/test_rdoc_markup_to_joined_paragraph.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_to_label.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_to_markdown.rb8
-rw-r--r--test/rdoc/test_rdoc_markup_to_rdoc.rb19
-rw-r--r--test/rdoc/test_rdoc_markup_to_table_of_contents.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_to_tt_only.rb1
-rw-r--r--test/rdoc/test_rdoc_markup_verbatim.rb1
-rw-r--r--test/rdoc/test_rdoc_options.rb54
-rw-r--r--test/rdoc/test_rdoc_parser.rb14
-rw-r--r--test/rdoc/test_rdoc_parser_c.rb44
-rw-r--r--test/rdoc/test_rdoc_parser_changelog.rb1
-rw-r--r--test/rdoc/test_rdoc_parser_markdown.rb1
-rw-r--r--test/rdoc/test_rdoc_parser_rd.rb1
-rw-r--r--test/rdoc/test_rdoc_parser_ruby.rb45
-rw-r--r--test/rdoc/test_rdoc_parser_simple.rb1
-rw-r--r--test/rdoc/test_rdoc_rd.rb1
-rw-r--r--test/rdoc/test_rdoc_rd_block_parser.rb21
-rw-r--r--test/rdoc/test_rdoc_rd_inline.rb1
-rw-r--r--test/rdoc/test_rdoc_rdoc.rb56
-rw-r--r--test/rdoc/test_rdoc_ri_driver.rb17
-rw-r--r--test/rdoc/test_rdoc_ri_paths.rb1
-rw-r--r--test/rdoc/test_rdoc_single_class.rb1
-rw-r--r--test/rdoc/test_rdoc_stats.rb1
-rw-r--r--test/rdoc/test_rdoc_store.rb11
-rw-r--r--test/rdoc/test_rdoc_task.rb9
-rw-r--r--test/rdoc/test_rdoc_token_stream.rb53
-rw-r--r--test/rdoc/xref_data.rb13
-rw-r--r--test/rdoc/xref_test_case.rb1
-rw-r--r--test/readline/helper.rb29
-rw-r--r--test/readline/test_readline.rb950
-rw-r--r--test/readline/test_readline_history.rb292
-rw-r--r--test/reline/helper.rb112
-rw-r--r--test/reline/test_ansi_with_terminfo.rb112
-rw-r--r--test/reline/test_ansi_without_terminfo.rb77
-rw-r--r--test/reline/test_config.rb35
-rw-r--r--test/reline/test_face.rb257
-rw-r--r--test/reline/test_history.rb2
-rw-r--r--test/reline/test_key_actor_emacs.rb1854
-rw-r--r--test/reline/test_key_actor_vi.rb1302
-rw-r--r--test/reline/test_key_stroke.rb26
-rw-r--r--test/reline/test_line_editor.rb155
-rw-r--r--test/reline/test_macro.rb3
-rw-r--r--test/reline/test_reline.rb47
-rw-r--r--test/reline/test_reline_key.rb1
-rw-r--r--test/reline/test_string_processing.rb14
-rw-r--r--test/reline/test_terminfo.rb2
-rw-r--r--test/reline/test_unicode.rb40
-rw-r--r--test/reline/test_within_pipe.rb8
-rwxr-xr-xtest/reline/yamatanooroti/multiline_repl55
-rw-r--r--test/reline/yamatanooroti/termination_checker.rb38
-rw-r--r--test/reline/yamatanooroti/test_rendering.rb514
-rw-r--r--test/resolv/test_dns.rb243
-rw-r--r--test/resolv/test_resource.rb76
-rw-r--r--test/resolv/test_svcb_https.rb231
-rw-r--r--test/rinda/test_rinda.rb912
-rw-r--r--test/rinda/test_tuplebag.rb173
-rw-r--r--test/ripper/assert_parse_files.rb25
-rw-r--r--test/ripper/dummyparser.rb53
-rw-r--r--test/ripper/test_lexer.rb94
-rw-r--r--test/ripper/test_parser_events.rb56
-rw-r--r--test/ripper/test_ripper.rb31
-rw-r--r--test/ripper/test_scanner_events.rb37
-rw-r--r--test/ripper/test_sexp.rb54
-rw-r--r--test/ruby/enc/test_case_comprehensive.rb2
-rw-r--r--test/ruby/enc/test_case_mapping.rb10
-rw-r--r--test/ruby/enc/test_case_options.rb12
-rw-r--r--test/ruby/enc/test_cesu8.rb4
-rw-r--r--test/ruby/enc/test_emoji_breaks.rb5
-rw-r--r--test/ruby/enc/test_grapheme_breaks.rb2
-rw-r--r--test/ruby/enc/test_regex_casefold.rb2
-rw-r--r--test/ruby/rjit/test_assembler.rb368
-rw-r--r--test/ruby/test_allocation.rb656
-rw-r--r--test/ruby/test_argf.rb110
-rw-r--r--test/ruby/test_arity.rb1
-rw-r--r--test/ruby/test_array.rb64
-rw-r--r--test/ruby/test_ast.rb690
-rw-r--r--test/ruby/test_autoload.rb23
-rw-r--r--test/ruby/test_backtrace.rb52
-rw-r--r--test/ruby/test_beginendblock.rb14
-rw-r--r--test/ruby/test_bignum.rb2
-rw-r--r--test/ruby/test_call.rb1221
-rw-r--r--test/ruby/test_class.rb52
-rw-r--r--test/ruby/test_clone.rb7
-rw-r--r--test/ruby/test_comparable.rb10
-rw-r--r--test/ruby/test_compile_prism.rb2671
-rw-r--r--test/ruby/test_complex.rb207
-rw-r--r--test/ruby/test_continuation.rb4
-rw-r--r--test/ruby/test_data.rb283
-rw-r--r--test/ruby/test_default_gems.rb21
-rw-r--r--test/ruby/test_defined.rb26
-rw-r--r--test/ruby/test_dir.rb198
-rw-r--r--test/ruby/test_dir_m17n.rb46
-rw-r--r--test/ruby/test_econv.rb2
-rw-r--r--test/ruby/test_encoding.rb35
-rw-r--r--test/ruby/test_enum.rb14
-rw-r--r--test/ruby/test_enumerator.rb111
-rw-r--r--test/ruby/test_env.rb4
-rw-r--r--test/ruby/test_eval.rb7
-rw-r--r--test/ruby/test_exception.rb208
-rw-r--r--test/ruby/test_fiber.rb18
-rw-r--r--test/ruby/test_file.rb290
-rw-r--r--test/ruby/test_file_exhaustive.rb11
-rw-r--r--test/ruby/test_float.rb20
-rw-r--r--test/ruby/test_gc.rb424
-rw-r--r--test/ruby/test_gc_compact.rb271
-rw-r--r--test/ruby/test_hash.rb794
-rw-r--r--test/ruby/test_integer.rb100
-rw-r--r--test/ruby/test_integer_comb.rb23
-rw-r--r--test/ruby/test_io.rb219
-rw-r--r--test/ruby/test_io_buffer.rb267
-rw-r--r--test/ruby/test_io_m17n.rb104
-rw-r--r--test/ruby/test_io_timeout.rb58
-rw-r--r--test/ruby/test_iseq.rb92
-rw-r--r--test/ruby/test_keyword.rb341
-rw-r--r--test/ruby/test_lambda.rb26
-rw-r--r--test/ruby/test_lazy_enumerator.rb25
-rw-r--r--test/ruby/test_literal.rb22
-rw-r--r--test/ruby/test_m17n.rb72
-rw-r--r--test/ruby/test_marshal.rb20
-rw-r--r--test/ruby/test_math.rb10
-rw-r--r--test/ruby/test_method.rb316
-rw-r--r--test/ruby/test_mjit.rb1307
-rw-r--r--test/ruby/test_mjit_debug.rb17
-rw-r--r--test/ruby/test_module.rb84
-rw-r--r--test/ruby/test_nomethod_error.rb2
-rw-r--r--test/ruby/test_numeric.rb3
-rw-r--r--test/ruby/test_object.rb84
-rw-r--r--test/ruby/test_objectspace.rb5
-rw-r--r--test/ruby/test_optimization.rb88
-rw-r--r--test/ruby/test_pack.rb110
-rw-r--r--test/ruby/test_parse.rb457
-rw-r--r--test/ruby/test_pattern_matching.rb40
-rw-r--r--test/ruby/test_proc.rb83
-rw-r--r--test/ruby/test_process.rb379
-rw-r--r--test/ruby/test_rand.rb8
-rw-r--r--test/ruby/test_random_formatter.rb55
-rw-r--r--test/ruby/test_range.rb343
-rw-r--r--test/ruby/test_rational.rb2
-rw-r--r--test/ruby/test_refinement.rb100
-rw-r--r--test/ruby/test_regexp.rb599
-rw-r--r--test/ruby/test_require.rb76
-rw-r--r--test/ruby/test_require_lib.rb31
-rw-r--r--test/ruby/test_rubyoptions.rb381
-rw-r--r--test/ruby/test_rubyvm.rb2
-rw-r--r--test/ruby/test_rubyvm_mjit.rb108
-rw-r--r--test/ruby/test_settracefunc.rb345
-rw-r--r--test/ruby/test_shapes.rb1040
-rw-r--r--test/ruby/test_signal.rb43
-rw-r--r--test/ruby/test_sprintf.rb17
-rw-r--r--test/ruby/test_stack.rb1
-rw-r--r--test/ruby/test_string.rb761
-rw-r--r--test/ruby/test_string_memory.rb55
-rw-r--r--test/ruby/test_struct.rb22
-rw-r--r--test/ruby/test_super.rb12
-rw-r--r--test/ruby/test_symbol.rb8
-rw-r--r--test/ruby/test_syntax.rb397
-rw-r--r--test/ruby/test_system.rb13
-rw-r--r--test/ruby/test_thread.rb50
-rw-r--r--test/ruby/test_thread_cv.rb6
-rw-r--r--test/ruby/test_thread_queue.rb52
-rw-r--r--test/ruby/test_time.rb133
-rw-r--r--test/ruby/test_time_tz.rb36
-rw-r--r--test/ruby/test_transcode.rb514
-rw-r--r--test/ruby/test_variable.rb130
-rw-r--r--test/ruby/test_vm_dump.rb7
-rw-r--r--test/ruby/test_weakkeymap.rb145
-rw-r--r--test/ruby/test_weakmap.rb91
-rw-r--r--test/ruby/test_whileuntil.rb18
-rw-r--r--test/ruby/test_yjit.rb934
-rw-r--r--test/ruby/test_yjit_exit_locations.rb24
-rw-r--r--test/rubygems/alternate_cert.pem28
-rw-r--r--test/rubygems/alternate_cert_32.pem30
-rw-r--r--test/rubygems/alternate_key.pem50
-rw-r--r--test/rubygems/bad_rake.rb1
-rw-r--r--test/rubygems/bundler_test_gem.rb424
-rw-r--r--test/rubygems/child_cert.pem31
-rw-r--r--test/rubygems/child_cert_32.pem31
-rw-r--r--test/rubygems/child_key.pem50
-rw-r--r--test/rubygems/encrypted_private_key.pem52
-rw-r--r--test/rubygems/expired_cert.pem30
-rw-r--r--test/rubygems/fake_certlib/openssl.rb1
-rw-r--r--test/rubygems/future_cert.pem30
-rw-r--r--test/rubygems/future_cert_32.pem30
-rw-r--r--test/rubygems/good_rake.rb1
-rw-r--r--test/rubygems/grandchild_cert.pem31
-rw-r--r--test/rubygems/grandchild_cert_32.pem31
-rw-r--r--test/rubygems/grandchild_key.pem50
-rw-r--r--test/rubygems/helper.rb388
-rw-r--r--test/rubygems/installer_test_case.rb17
-rw-r--r--test/rubygems/invalid_issuer_cert.pem32
-rw-r--r--test/rubygems/invalid_issuer_cert_32.pem32
-rw-r--r--test/rubygems/invalid_key.pem50
-rw-r--r--test/rubygems/invalid_signer_cert.pem30
-rw-r--r--test/rubygems/invalid_signer_cert_32.pem30
-rw-r--r--test/rubygems/invalidchild_cert.pem31
-rw-r--r--test/rubygems/invalidchild_cert_32.pem31
-rw-r--r--test/rubygems/invalidchild_key.pem50
-rw-r--r--test/rubygems/mock_gem_ui.rb86
-rw-r--r--test/rubygems/multifactor_auth_utilities.rb111
-rw-r--r--test/rubygems/package/tar_test_case.rb68
-rw-r--r--test/rubygems/packages/Bluebie-legs-0.6.2.gembin0 -> 14336 bytes
-rw-r--r--test/rubygems/plugin/exception/rubygems_plugin.rb3
-rw-r--r--test/rubygems/plugin/load/rubygems_plugin.rb1
-rw-r--r--test/rubygems/plugin/scripterror/rubygems_plugin.rb4
-rw-r--r--test/rubygems/plugin/standarderror/rubygems_plugin.rb1
-rw-r--r--test/rubygems/private_key.pem50
-rw-r--r--test/rubygems/public_cert.pem32
-rw-r--r--test/rubygems/public_cert_32.pem30
-rw-r--r--test/rubygems/public_key.pem14
-rw-r--r--test/rubygems/rubygems/commands/crash_command.rb1
-rw-r--r--test/rubygems/rubygems_plugin.rb1
-rw-r--r--test/rubygems/simple_gem.rb3
-rw-r--r--test/rubygems/specifications/bar-0.0.2.gemspec2
-rw-r--r--test/rubygems/specifications/rubyforge-0.0.1.gemspec23
-rw-r--r--test/rubygems/test_bundled_ca.rb9
-rw-r--r--test/rubygems/test_config.rb7
-rw-r--r--test/rubygems/test_deprecate.rb11
-rw-r--r--test/rubygems/test_exit.rb2
-rw-r--r--test/rubygems/test_gem.rb609
-rw-r--r--test/rubygems/test_gem_available_set.rb7
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb8
-rw-r--r--test/rubygems/test_gem_ci_detector.rb44
-rw-r--r--test/rubygems/test_gem_command.rb48
-rw-r--r--test/rubygems/test_gem_command_manager.rb132
-rw-r--r--test/rubygems/test_gem_commands_build_command.rb28
-rw-r--r--test/rubygems/test_gem_commands_cert_command.rb68
-rw-r--r--test/rubygems/test_gem_commands_check_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_cleanup_command.rb19
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb15
-rw-r--r--test/rubygems/test_gem_commands_dependency_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_environment_command.rb50
-rw-r--r--test/rubygems/test_gem_commands_exec_command.rb859
-rw-r--r--test/rubygems/test_gem_commands_fetch_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_generate_index_command.rb80
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb5
-rw-r--r--test/rubygems/test_gem_commands_info_command.rb39
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb138
-rw-r--r--test/rubygems/test_gem_commands_list_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_lock_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_mirror.rb3
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb14
-rw-r--r--test/rubygems/test_gem_commands_outdated_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_owner_command.rb267
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb70
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb210
-rw-r--r--test/rubygems/test_gem_commands_query_command.rb65
-rw-r--r--test/rubygems/test_gem_commands_rebuild_command.rb145
-rw-r--r--test/rubygems/test_gem_commands_search_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_server_command.rb3
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb45
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb129
-rw-r--r--test/rubygems/test_gem_commands_signout_command.rb6
-rw-r--r--test/rubygems/test_gem_commands_sources_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_specification_command.rb31
-rw-r--r--test/rubygems/test_gem_commands_stale_command.rb5
-rw-r--r--test/rubygems/test_gem_commands_uninstall_command.rb76
-rw-r--r--test/rubygems/test_gem_commands_unpack_command.rb9
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb53
-rw-r--r--test/rubygems/test_gem_commands_which_command.rb13
-rw-r--r--test/rubygems/test_gem_commands_yank_command.rb147
-rw-r--r--test/rubygems/test_gem_config_file.rb107
-rw-r--r--test/rubygems/test_gem_console_ui.rb19
-rw-r--r--test/rubygems/test_gem_dependency.rb22
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb214
-rw-r--r--test/rubygems/test_gem_dependency_list.rb13
-rw-r--r--test/rubygems/test_gem_dependency_resolution_error.rb15
-rw-r--r--test/rubygems/test_gem_doctor.rb1
-rw-r--r--test/rubygems/test_gem_ext_builder.rb162
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder.rb87
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock243
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb21
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec8
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock249
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml10
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs27
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb3
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs27
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock84
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml2
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb21
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec2
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs12
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb33
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder_unit.rb27
-rw-r--r--test/rubygems/test_gem_ext_cmake_builder.rb13
-rw-r--r--test/rubygems/test_gem_ext_configure_builder.rb3
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb17
-rw-r--r--test/rubygems/test_gem_ext_rake_builder.rb23
-rw-r--r--test/rubygems/test_gem_gem_runner.rb10
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb213
-rw-r--r--test/rubygems/test_gem_impossible_dependencies_error.rb1
-rw-r--r--test/rubygems/test_gem_indexer.rb361
-rw-r--r--test/rubygems/test_gem_install_update_options.rb26
-rw-r--r--test/rubygems/test_gem_installer.rb375
-rw-r--r--test/rubygems/test_gem_local_remote_options.rb13
-rw-r--r--test/rubygems/test_gem_name_tuple.rb34
-rw-r--r--test/rubygems/test_gem_package.rb315
-rw-r--r--test/rubygems/test_gem_package_old.rb7
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb66
-rw-r--r--test/rubygems/test_gem_package_tar_reader.rb69
-rw-r--r--test/rubygems/test_gem_package_tar_reader_entry.rb218
-rw-r--r--test/rubygems/test_gem_package_tar_writer.rb89
-rw-r--r--test/rubygems/test_gem_package_task.rb5
-rw-r--r--test/rubygems/test_gem_path_support.rb1
-rw-r--r--test/rubygems/test_gem_platform.rb232
-rw-r--r--test/rubygems/test_gem_rdoc.rb5
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb245
-rw-r--r--test/rubygems/test_gem_request.rb121
-rw-r--r--test/rubygems/test_gem_request_connection_pools.rb25
-rw-r--r--test/rubygems/test_gem_request_set.rb59
-rw-r--r--test/rubygems/test_gem_request_set_gem_dependency_api.rb181
-rw-r--r--test/rubygems/test_gem_request_set_lockfile.rb1
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_parser.rb29
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_tokenizer.rb1
-rw-r--r--test/rubygems/test_gem_requirement.rb19
-rw-r--r--test/rubygems/test_gem_resolver.rb154
-rw-r--r--test/rubygems/test_gem_resolver_activation_request.rb15
-rw-r--r--test/rubygems/test_gem_resolver_api_set.rb112
-rw-r--r--test/rubygems/test_gem_resolver_api_specification.rb69
-rw-r--r--test/rubygems/test_gem_resolver_best_set.rb41
-rw-r--r--test/rubygems/test_gem_resolver_composed_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_conflict.rb11
-rw-r--r--test/rubygems/test_gem_resolver_dependency_request.rb25
-rw-r--r--test/rubygems/test_gem_resolver_git_set.rb19
-rw-r--r--test/rubygems/test_gem_resolver_git_specification.rb8
-rw-r--r--test/rubygems/test_gem_resolver_index_set.rb29
-rw-r--r--test/rubygems/test_gem_resolver_index_specification.rb10
-rw-r--r--test/rubygems/test_gem_resolver_installed_specification.rb1
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb23
-rw-r--r--test/rubygems/test_gem_resolver_local_specification.rb1
-rw-r--r--test/rubygems/test_gem_resolver_lock_set.rb7
-rw-r--r--test/rubygems/test_gem_resolver_lock_specification.rb15
-rw-r--r--test/rubygems/test_gem_resolver_requirement_list.rb1
-rw-r--r--test/rubygems/test_gem_resolver_specification.rb3
-rw-r--r--test/rubygems/test_gem_resolver_vendor_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_vendor_specification.rb4
-rw-r--r--test/rubygems/test_gem_safe_marshal.rb404
-rw-r--r--test/rubygems/test_gem_safe_yaml.rb24
-rw-r--r--test/rubygems/test_gem_security.rb71
-rw-r--r--test/rubygems/test_gem_security_policy.rb60
-rw-r--r--test/rubygems/test_gem_security_signer.rb31
-rw-r--r--test/rubygems/test_gem_security_trust_dir.rb19
-rw-r--r--test/rubygems/test_gem_silent_ui.rb4
-rw-r--r--test/rubygems/test_gem_source.rb42
-rw-r--r--test/rubygems/test_gem_source_fetch_problem.rb1
-rw-r--r--test/rubygems/test_gem_source_git.rb39
-rw-r--r--test/rubygems/test_gem_source_installed.rb5
-rw-r--r--test/rubygems/test_gem_source_list.rb5
-rw-r--r--test/rubygems/test_gem_source_local.rb5
-rw-r--r--test/rubygems/test_gem_source_lock.rb11
-rw-r--r--test/rubygems/test_gem_source_specific_file.rb5
-rw-r--r--test/rubygems/test_gem_source_subpath_problem.rb7
-rw-r--r--test/rubygems/test_gem_source_vendor.rb5
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb15
-rw-r--r--test/rubygems/test_gem_specification.rb504
-rw-r--r--test/rubygems/test_gem_stream_ui.rb53
-rw-r--r--test/rubygems/test_gem_stub_specification.rb3
-rw-r--r--test/rubygems/test_gem_text.rb1
-rw-r--r--test/rubygems/test_gem_uninstaller.rb105
-rw-r--r--test/rubygems/test_gem_unsatisfiable_dependency_error.rb1
-rw-r--r--test/rubygems/test_gem_update_suggestion.rb209
-rw-r--r--test/rubygems/test_gem_uri.rb2
-rw-r--r--test/rubygems/test_gem_uri_formatter.rb1
-rw-r--r--test/rubygems/test_gem_util.rb15
-rw-r--r--test/rubygems/test_gem_version.rb11
-rw-r--r--test/rubygems/test_gem_version_option.rb49
-rw-r--r--test/rubygems/test_kernel.rb33
-rw-r--r--test/rubygems/test_project_sanity.rb35
-rw-r--r--test/rubygems/test_remote_fetch_error.rb5
-rw-r--r--test/rubygems/test_require.rb233
-rw-r--r--test/rubygems/test_rubygems.rb12
-rw-r--r--test/rubygems/test_webauthn_listener.rb143
-rw-r--r--test/rubygems/test_webauthn_listener_response.rb93
-rw-r--r--test/rubygems/test_webauthn_poller.rb124
-rw-r--r--test/rubygems/utilities.rb111
-rw-r--r--test/rubygems/wrong_key_cert.pem30
-rw-r--r--test/rubygems/wrong_key_cert_32.pem30
-rw-r--r--test/runner.rb11
-rw-r--r--test/set/fixtures/fake_sorted_set_gem/sorted_set.rb (renamed from test/fixtures/fake_sorted_set_gem/sorted_set.rb)0
-rw-r--r--test/set/test_set.rb892
-rw-r--r--test/set/test_sorted_set.rb (renamed from test/test_sorted_set.rb)0
-rw-r--r--test/socket/test_addrinfo.rb8
-rw-r--r--test/socket/test_nonblock.rb4
-rw-r--r--test/socket/test_socket.rb277
-rw-r--r--test/socket/test_tcp.rb2
-rw-r--r--test/socket/test_unix.rb215
-rw-r--r--test/stringio/test_ractor.rb2
-rw-r--r--test/stringio/test_stringio.rb94
-rw-r--r--test/strscan/test_ractor.rb2
-rw-r--r--test/strscan/test_stringscanner.rb106
-rw-r--r--test/syslog/test_syslog_logger.rb588
-rw-r--r--test/test_abbrev.rb55
-rw-r--r--test/test_extlibs.rb9
-rw-r--r--test/test_forwardable.rb2
-rw-r--r--test/test_getoptlong.rb163
-rw-r--r--test/test_ipaddr.rb87
-rw-r--r--test/test_mutex_m.rb58
-rw-r--r--test/test_observer.rb66
-rw-r--r--test/test_open3.rb10
-rw-r--r--test/test_pp.rb62
-rw-r--r--test/test_rbconfig.rb9
-rw-r--r--test/test_set.rb879
-rw-r--r--test/test_singleton.rb21
-rw-r--r--test/test_syslog.rb193
-rw-r--r--test/test_tempfile.rb27
-rw-r--r--test/test_time.rb9
-rw-r--r--test/test_timeout.rb123
-rw-r--r--test/test_tmpdir.rb34
-rw-r--r--test/test_trick.rb114
-rw-r--r--test/test_unicode_normalize.rb2
-rw-r--r--test/uri/test_common.rb19
-rw-r--r--test/uri/test_ftp.rb10
-rw-r--r--test/uri/test_generic.rb24
-rw-r--r--test/uri/test_http.rb8
-rw-r--r--test/uri/test_ldap.rb14
-rw-r--r--test/uri/test_parser.rb37
-rw-r--r--test/uri/test_ws.rb8
-rw-r--r--test/uri/test_wss.rb8
-rw-r--r--test/win32ole/available_ole.rb14
-rw-r--r--test/win32ole/err_in_callback.rb4
-rw-r--r--test/win32ole/test_err_in_callback.rb4
-rw-r--r--test/win32ole/test_folderitem2_invokeverb.rb2
-rw-r--r--test/win32ole/test_nil2vtempty.rb2
-rw-r--r--test/win32ole/test_propertyputref.rb2
-rw-r--r--test/win32ole/test_thread.rb2
-rw-r--r--test/win32ole/test_win32ole.rb43
-rw-r--r--test/win32ole/test_win32ole_event.rb70
-rw-r--r--test/win32ole/test_win32ole_method.rb48
-rw-r--r--test/win32ole/test_win32ole_method_event.rb10
-rw-r--r--test/win32ole/test_win32ole_param.rb42
-rw-r--r--test/win32ole/test_win32ole_param_event.rb2
-rw-r--r--test/win32ole/test_win32ole_record.rb60
-rw-r--r--test/win32ole/test_win32ole_type.rb67
-rw-r--r--test/win32ole/test_win32ole_type_event.rb4
-rw-r--r--test/win32ole/test_win32ole_typelib.rb66
-rw-r--r--test/win32ole/test_win32ole_variable.rb16
-rw-r--r--test/win32ole/test_win32ole_variant.rb308
-rw-r--r--test/win32ole/test_win32ole_variant_m.rb5
-rw-r--r--test/win32ole/test_win32ole_variant_outarg.rb6
-rw-r--r--test/win32ole/test_word.rb2
-rw-r--r--test/yaml/test_store.rb4
-rw-r--r--test/zlib/test_zlib.rb55
2690 files changed, 141567 insertions, 110773 deletions
diff --git a/test/-ext-/bug_reporter/test_bug_reporter.rb b/test/-ext-/bug_reporter/test_bug_reporter.rb
index 81d2ca4674..76f913c275 100644
--- a/test/-ext-/bug_reporter/test_bug_reporter.rb
+++ b/test/-ext-/bug_reporter/test_bug_reporter.rb
@@ -4,15 +4,10 @@ require 'tmpdir'
require_relative '../../lib/jit_support'
class TestBugReporter < Test::Unit::TestCase
- def yjit_enabled?
- defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
- end
-
def test_bug_reporter_add
- omit if ENV['RUBY_ON_BUG']
-
- description = RUBY_DESCRIPTION
- description = description.sub(/\+MJIT /, '') unless JITSupport.mjit_force_enabled?
+ omit "flaky with RJIT" if JITSupport.rjit_enabled?
+ description = RUBY_DESCRIPTION.sub(/\+PRISM /, '')
+ description = description.sub(/\+RJIT /, '') unless JITSupport.rjit_force_enabled?
expected_stderr = [
:*,
/\[BUG\]\sSegmentation\sfault.*\n/,
@@ -24,9 +19,9 @@ class TestBugReporter < Test::Unit::TestCase
tmpdir = Dir.mktmpdir
no_core = "Process.setrlimit(Process::RLIMIT_CORE, 0); " if defined?(Process.setrlimit) && defined?(Process::RLIMIT_CORE)
- args = ["--disable-gems", "-r-test-/bug_reporter",
- "-C", tmpdir]
- args.push("--yjit") if yjit_enabled? # We want the printed description to match this process's RUBY_DESCRIPTION
+ args = ["-r-test-/bug_reporter", "-C", tmpdir]
+ args.push("--yjit") if JITSupport.yjit_enabled? # We want the printed description to match this process's RUBY_DESCRIPTION
+ args.unshift({"RUBY_ON_BUG" => nil})
stdin = "#{no_core}register_sample_bug_reporter(12345); Process.kill :SEGV, $$"
assert_in_out_err(args, stdin, [], expected_stderr, encoding: "ASCII-8BIT")
ensure
diff --git a/test/-ext-/debug/test_debug.rb b/test/-ext-/debug/test_debug.rb
index 8a351d74fa..b244eb41ea 100644
--- a/test/-ext-/debug/test_debug.rb
+++ b/test/-ext-/debug/test_debug.rb
@@ -29,7 +29,7 @@ class TestDebug < Test::Unit::TestCase
# check same location
assert_equal(loc.path, iseq.path, msg)
assert_equal(loc.absolute_path, iseq.absolute_path, msg)
- assert_equal(loc.label, iseq.label, msg)
+ #assert_equal(loc.label, iseq.label, msg)
assert_operator(loc.lineno, :>=, iseq.first_lineno, msg)
end
diff --git a/test/-ext-/debug/test_profile_frames.rb b/test/-ext-/debug/test_profile_frames.rb
index d6ae953dd2..bd819266df 100644
--- a/test/-ext-/debug/test_profile_frames.rb
+++ b/test/-ext-/debug/test_profile_frames.rb
@@ -14,6 +14,8 @@ class SampleClassForTestProfileFrames
end
class Sample2
+ EVAL_LINE = __LINE__ + 3
+
def baz(block)
instance_eval "def zab(block) block.call end"
[self, zab(block)]
@@ -37,6 +39,20 @@ class SampleClassForTestProfileFrames
end
end
+class SampleClassForTestProfileThreadFrames
+ def initialize(mutex)
+ @mutex = mutex
+ end
+
+ def foo(block)
+ bar(block)
+ end
+
+ def bar(block)
+ block.call
+ end
+end
+
class TestProfileFrames < Test::Unit::TestCase
def test_profile_frames
obj, frames = Fiber.new{
@@ -112,7 +128,7 @@ class TestProfileFrames < Test::Unit::TestCase
"SampleClassForTestProfileFrames#foo",
"TestProfileFrames#test_profile_frames",
]
- paths = [ nil, file=__FILE__, "(eval)", file, file, file, file, file, file, nil ]
+ paths = [ nil, file=__FILE__, "(eval at #{__FILE__}:#{SampleClassForTestProfileFrames::Sample2::EVAL_LINE})", file, file, file, file, file, file, nil ]
absolute_paths = [ "<cfunc>", file, nil, file, file, file, file, file, file, nil ]
assert_equal(labels.size, frames.size)
@@ -137,13 +153,56 @@ class TestProfileFrames < Test::Unit::TestCase
}
end
+ def test_profile_thread_frames
+ mutex = Mutex.new
+ th = Thread.new do
+ mutex.lock
+ Thread.stop
+ SampleClassForTestProfileThreadFrames.new(mutex).foo(lambda { mutex.unlock; loop { sleep(1) } } )
+ end
+
+ # ensure execution has reached SampleClassForTestProfileThreadFrames#bar before running profile_thread_frames
+ loop { break if th.status == "sleep"; sleep 0.1 }
+ th.run
+ mutex.lock # wait until SampleClassForTestProfileThreadFrames#bar has been called
+
+ frames = Bug::Debug.profile_thread_frames(th, 0, 10)
+
+ full_labels = [
+ "Kernel#sleep",
+ "TestProfileFrames#test_profile_thread_frames",
+ "Kernel#loop",
+ "TestProfileFrames#test_profile_thread_frames",
+ "SampleClassForTestProfileThreadFrames#bar",
+ "SampleClassForTestProfileThreadFrames#foo",
+ "TestProfileFrames#test_profile_thread_frames",
+ ]
+
+ frames.each.with_index do |frame, i|
+ assert_equal(full_labels[i], frame)
+ end
+
+ ensure
+ th.kill
+ th.join
+ end
+
+
def test_matches_backtrace_locations_main_thread
assert_equal(Thread.current, Thread.main)
# Keep these in the same line, so the backtraces match exactly
backtrace_locations, profile_frames = [Thread.current.backtrace_locations, Bug::Debug.profile_frames(0, 100)]
- assert_equal(backtrace_locations.size, profile_frames.size)
+ errmsg = "backtrace_locations:\n " + backtrace_locations.map.with_index{|loc, i| "#{i} #{loc}"}.join("\n ")
+ errmsg += "\n\nprofile_frames:\n " + profile_frames.map.with_index{|(path, absolute_path, _, base_label, _, _, _, _, _, full_label, lineno), i|
+ if lineno
+ "#{i} #{absolute_path}:#{lineno} // #{full_label}"
+ else
+ "#{i} #{absolute_path} #{full_label}"
+ end
+ }.join("\n ")
+ assert_equal(backtrace_locations.size, profile_frames.size, errmsg)
# The first entries are not going to match, since one is #backtrace_locations and the other #profile_frames
backtrace_locations.shift
@@ -177,4 +236,8 @@ class TestProfileFrames < Test::Unit::TestCase
a
end;
end
+
+ def test_start
+ assert_equal Bug::Debug.profile_frames(0, 10).tap(&:shift), Bug::Debug.profile_frames(1, 9)
+ end
end
diff --git a/test/-ext-/econv/test_append.rb b/test/-ext-/econv/test_append.rb
new file mode 100644
index 0000000000..f8c1d2add6
--- /dev/null
+++ b/test/-ext-/econv/test_append.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: false
+require 'test/unit'
+require "-test-/econv"
+
+class Test_EConvAppend < Test::Unit::TestCase
+ def test_econv_str_append_valid
+ ec = Bug::EConv.new("utf-8", "cp932")
+ dst = "\u3044".encode("cp932")
+ ret = ec.append("\u3042"*30, dst)
+ assert_same(dst, ret)
+ assert_not_predicate(dst, :ascii_only?)
+ assert_predicate(dst, :valid_encoding?)
+ end
+
+ def test_econv_str_append_broken
+ ec = Bug::EConv.new("utf-8", "cp932")
+ dst = ""
+ ret = ec.append("\u3042"*30, dst)
+ assert_same(dst, ret)
+ assert_not_predicate(dst, :ascii_only?)
+ assert_not_predicate(dst, :valid_encoding?)
+ end
+end
diff --git a/test/-ext-/eval/test_eval.rb b/test/-ext-/eval/test_eval.rb
index 27952996e2..e37d301b2e 100644
--- a/test/-ext-/eval/test_eval.rb
+++ b/test/-ext-/eval/test_eval.rb
@@ -4,9 +4,9 @@ require "-test-/eval"
class EvalTest < Test::Unit::TestCase
def test_rb_eval_string
- a = 1
+ _a = 1
assert_equal [self, 1, __method__], rb_eval_string(%q{
- [self, a, __method__]
+ [self, _a, __method__]
})
end
end
diff --git a/test/-ext-/iseq_load/test_iseq_load.rb b/test/-ext-/iseq_load/test_iseq_load.rb
index 6e5bc8e811..864ce1afbb 100644
--- a/test/-ext-/iseq_load/test_iseq_load.rb
+++ b/test/-ext-/iseq_load/test_iseq_load.rb
@@ -123,6 +123,8 @@ class TestIseqLoad < Test::Unit::TestCase
assert_equal false, test_break_ensure_def_method
omit "failing due to exception entry sp mismatch"
assert_iseq_roundtrip(src)
+ ensure
+ Object.undef_method(:test_break_ensure_def_method) rescue nil
end
def test_kwarg
diff --git a/test/-ext-/load/test_resolve_symbol.rb b/test/-ext-/load/test_resolve_symbol.rb
new file mode 100644
index 0000000000..471d3acebd
--- /dev/null
+++ b/test/-ext-/load/test_resolve_symbol.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+require 'test/unit'
+
+class Test_Load_ResolveSymbol < Test::Unit::TestCase
+ def test_load_resolve_symbol_resolver
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ feature = "Feature #20005"
+ assert_raise(LoadError, "resolve_symbol_target is not loaded") {
+ require '-test-/load/resolve_symbol_resolver'
+ }
+ require '-test-/load/resolve_symbol_target'
+ assert_nothing_raised(LoadError, "#{feature} resolver can be loaded") {
+ require '-test-/load/resolve_symbol_resolver'
+ }
+ assert_not_nil ResolveSymbolResolver
+ assert_equal "from target", ResolveSymbolResolver.any_method
+
+ assert_raise(LoadError, "tries to resolve missing feature name, and it should raise LoadError") {
+ ResolveSymbolResolver.try_resolve_fname
+ }
+ assert_raise(LoadError, "tries to resolve missing symbol name, and it should raise LoadError") {
+ ResolveSymbolResolver.try_resolve_sname
+ }
+ end;
+ end
+end
diff --git a/test/-ext-/load/test_stringify_symbols.rb b/test/-ext-/load/test_stringify_symbols.rb
new file mode 100644
index 0000000000..0d9736b591
--- /dev/null
+++ b/test/-ext-/load/test_stringify_symbols.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+require 'test/unit'
+
+class Test_Load_stringify_symbols < Test::Unit::TestCase
+ def test_load_stringify_symbol_required_extensions
+ require '-test-/load/stringify_symbols'
+ require '-test-/load/stringify_target'
+ r1 = StringifySymbols.stringify_symbol("-test-/load/stringify_target", "stt_any_method")
+ assert_not_nil r1
+ r2 = StringifySymbols.stringify_symbol("-test-/load/stringify_target.so", "stt_any_method")
+ assert_equal r1, r2, "resolved symbols should be equal even with or without .so suffix"
+ end
+
+ def test_load_stringify_symbol_statically_linked
+ require '-test-/load/stringify_symbols'
+ # "complex.so" is actually not a statically linked extension.
+ # But it is registered in $LOADED_FEATURES, so it can be a target of this test.
+ r1 = StringifySymbols.stringify_symbol("complex", "rb_complex_minus")
+ assert_not_nil r1
+ r2 = StringifySymbols.stringify_symbol("complex.so", "rb_complex_minus")
+ assert_equal r1, r2
+ end
+
+ def test_load_stringify_symbol_missing_target
+ require '-test-/load/stringify_symbols'
+ r1 = assert_nothing_raised {
+ StringifySymbols.stringify_symbol("something_missing", "unknown_method")
+ }
+ assert_nil r1
+ r2 = assert_nothing_raised {
+ StringifySymbols.stringify_symbol("complex.so", "unknown_method")
+ }
+ assert_nil r2
+ end
+end
diff --git a/test/-ext-/marshal/test_internal_ivar.rb b/test/-ext-/marshal/test_internal_ivar.rb
index a32138f6e8..faabe14ab2 100644
--- a/test/-ext-/marshal/test_internal_ivar.rb
+++ b/test/-ext-/marshal/test_internal_ivar.rb
@@ -11,7 +11,7 @@ module Bug::Marshal
assert_equal("hello", v.normal)
assert_equal("world", v.internal)
assert_equal("bye", v.encoding_short)
- dump = assert_warn(/instance variable `E' on class \S+ is not dumped/) {
+ dump = assert_warn(/instance variable 'E' on class \S+ is not dumped/) {
::Marshal.dump(v)
}
v = assert_nothing_raised {break ::Marshal.load(dump)}
diff --git a/test/-ext-/postponed_job/test_postponed_job.rb b/test/-ext-/postponed_job/test_postponed_job.rb
index fee0172d11..8c2b3e95d1 100644
--- a/test/-ext-/postponed_job/test_postponed_job.rb
+++ b/test/-ext-/postponed_job/test_postponed_job.rb
@@ -2,34 +2,70 @@
require 'test/unit'
require '-test-/postponed_job'
-module Bug
- def self.postponed_job_call_direct_wrapper(*args)
- postponed_job_call_direct(*args)
+class TestPostponed_job < Test::Unit::TestCase
+ def test_preregister_and_trigger
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ require '-test-/postponed_job'
+ Bug.postponed_job_preregister_and_call_without_sleep(counters = [])
+ # i.e. rb_postponed_job_trigger performs coalescing
+ assert_equal([3], counters)
+
+ # i.e. rb_postponed_job_trigger resets after interrupts are checked
+ Bug.postponed_job_preregister_and_call_with_sleep(counters = [])
+ assert_equal([1, 2, 3], counters)
+ RUBY
end
- def self.postponed_job_register_wrapper(*args)
- postponed_job_register(*args)
+ def test_multiple_preregistration
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ require '-test-/postponed_job'
+ handles = Bug.postponed_job_preregister_multiple_times
+ # i.e. rb_postponed_job_preregister returns the same handle if preregistered multiple times
+ assert_equal [handles[0]], handles.uniq
+ RUBY
end
-end
-class TestPostponed_job < Test::Unit::TestCase
- def test_register
- direct, registered = [], []
+ def test_multiple_preregistration_with_new_data
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ require '-test-/postponed_job'
+ values = Bug.postponed_job_preregister_calls_with_last_argument
+ # i.e. the callback is called with the last argument it was preregistered with
+ assert_equal [3, 4], values
+ RUBY
+ end
- Bug.postponed_job_call_direct_wrapper(direct)
- Bug.postponed_job_register_wrapper(registered)
+ def test_legacy_register
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ require '-test-/postponed_job'
+ direct, registered = [], []
- assert_equal([0], direct)
- assert_equal([3], registered)
+ Bug.postponed_job_call_direct(direct)
+ Bug.postponed_job_register(registered)
- Bug.postponed_job_register_one(ary = [])
- assert_equal [1], ary
+ assert_equal([0], direct)
+ assert_equal([3], registered)
+
+ Bug.postponed_job_register_one(ary = [])
+ assert_equal [1], ary
+ RUBY
+ end
+
+ def test_legacy_register_one_same
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ require '-test-/postponed_job'
+ # Registering the same job three times should result in three of the same handle
+ handles = Bug.postponed_job_register_one_same
+ assert_equal [handles[0]], handles.uniq
+ RUBY
end
if Bug.respond_to?(:postponed_job_register_in_c_thread)
- def test_register_in_c_thread
- assert Bug.postponed_job_register_in_c_thread(ary = [])
- assert_equal [1], ary
+ def test_legacy_register_in_c_thread
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ require '-test-/postponed_job'
+ assert Bug.postponed_job_register_in_c_thread(ary = [])
+ assert_equal [1], ary
+ RUBY
end
end
end
diff --git a/test/-ext-/string/test_capacity.rb b/test/-ext-/string/test_capacity.rb
index 0cb7c00761..2c6c51fdda 100644
--- a/test/-ext-/string/test_capacity.rb
+++ b/test/-ext-/string/test_capacity.rb
@@ -23,7 +23,7 @@ class Test_StringCapacity < Test::Unit::TestCase
def test_s_new_capacity
assert_equal("", String.new(capacity: 1000))
assert_equal(String, String.new(capacity: 1000).class)
- assert_equal(10000, capa(String.new(capacity: 10000)))
+ assert_equal(10_000 - 1, capa(String.new(capacity: 10_000))) # Real capa doesn't account for termlen
assert_equal("", String.new(capacity: -1000))
assert_equal(capa(String.new(capacity: -10000)), capa(String.new(capacity: -1000)))
@@ -66,11 +66,7 @@ class Test_StringCapacity < Test::Unit::TestCase
end
def embed_header_size
- if GC.using_rvargc?
- 2 * RbConfig::SIZEOF['void*'] + RbConfig::SIZEOF['long']
- else
- 2 * RbConfig::SIZEOF['void*']
- end
+ 3 * RbConfig::SIZEOF['void*']
end
def max_embed_len
diff --git a/test/-ext-/string/test_chilled.rb b/test/-ext-/string/test_chilled.rb
new file mode 100644
index 0000000000..dccab61ced
--- /dev/null
+++ b/test/-ext-/string/test_chilled.rb
@@ -0,0 +1,19 @@
+require 'test/unit'
+require '-test-/string'
+
+class Test_String_ChilledString < Test::Unit::TestCase
+ def test_rb_str_chilled_p
+ str = ""
+ assert_equal true, Bug::String.rb_str_chilled_p(str)
+ end
+
+ def test_rb_str_chilled_p_frozen
+ str = "".freeze
+ assert_equal false, Bug::String.rb_str_chilled_p(str)
+ end
+
+ def test_rb_str_chilled_p_mutable
+ str = "".dup
+ assert_equal false, Bug::String.rb_str_chilled_p(str)
+ end
+end
diff --git a/test/-ext-/string/test_cstr.rb b/test/-ext-/string/test_cstr.rb
index d909781700..efc64119dc 100644
--- a/test/-ext-/string/test_cstr.rb
+++ b/test/-ext-/string/test_cstr.rb
@@ -43,7 +43,11 @@ class Test_StringCStr < Test::Unit::TestCase
end
def test_rb_str_new_frozen_embed
- str = Bug::String.cstr_noembed("rbconfig.rb")
+ # "rbconfi" is the smallest "maximum embeddable string". VWA adds
+ # a capacity field, which removes one pointer capacity for embedded objects,
+ # so if VWA is enabled, but there is only one size pool, then the
+ # maximum embeddable capacity on 32 bit machines is 8 bytes.
+ str = Bug::String.cstr_noembed("rbconfi")
str = Bug::String.rb_str_new_frozen(str)
assert_equal true, Bug::String.cstr_embedded?(str)
end
diff --git a/test/-ext-/string/test_fstring.rb b/test/-ext-/string/test_fstring.rb
index 5a3456c566..fcec6be543 100644
--- a/test/-ext-/string/test_fstring.rb
+++ b/test/-ext-/string/test_fstring.rb
@@ -15,19 +15,27 @@ class Test_String_Fstring < Test::Unit::TestCase
def test_rb_enc_interned_str_autoloaded_encoding
assert_separately([], <<~RUBY)
require '-test-/string'
- assert_include(Encoding::Windows_31J.inspect, 'autoload')
- Bug::String.rb_enc_interned_str(Encoding::Windows_31J)
+ assert_include(Encoding::CESU_8.inspect, 'autoload')
+ Bug::String.rb_enc_interned_str(Encoding::CESU_8)
RUBY
end
+ def test_rb_enc_interned_str_null_encoding
+ assert_equal Encoding::ASCII_8BIT, Bug::String.rb_enc_interned_str(nil).encoding
+ end
+
def test_rb_enc_str_new_autoloaded_encoding
assert_separately([], <<~RUBY)
require '-test-/string'
- assert_include(Encoding::Windows_31J.inspect, 'autoload')
- Bug::String.rb_enc_str_new(Encoding::Windows_31J)
+ assert_include(Encoding::CESU_8.inspect, 'autoload')
+ Bug::String.rb_enc_str_new(Encoding::CESU_8)
RUBY
end
+ def test_rb_enc_str_new_null_encoding
+ assert_equal Encoding::ASCII_8BIT, Bug::String.rb_enc_str_new(nil).encoding
+ end
+
def test_instance_variable
str = __method__.to_s * 3
str.instance_variable_set(:@test, 42)
@@ -49,6 +57,10 @@ class Test_String_Fstring < Test::Unit::TestCase
assert_raise(TypeError) {fstr.singleton_class}
end
+ def test_fake_str
+ assert_equal([*"a".."z"].join(""), Bug::String.fstring_fake_str)
+ end
+
class S < String
end
diff --git a/test/-ext-/string/test_set_len.rb b/test/-ext-/string/test_set_len.rb
index 67ba961194..e3eff75d9b 100644
--- a/test/-ext-/string/test_set_len.rb
+++ b/test/-ext-/string/test_set_len.rb
@@ -34,4 +34,33 @@ class Test_StrSetLen < Test::Unit::TestCase
assert_equal 128, Bug::String.capacity(str)
assert_equal 127, str.set_len(127).bytesize, bug12757
end
+
+ def test_coderange_after_append
+ u = -"\u3042"
+ str = Bug::String.new(encoding: Encoding::UTF_8)
+ bsize = u.bytesize
+ str.append(u)
+ assert_equal 0, str.bytesize
+ str.set_len(bsize)
+ assert_equal bsize, str.bytesize
+ assert_predicate str, :valid_encoding?
+ assert_not_predicate str, :ascii_only?
+ assert_equal u, str
+ end
+
+ def test_coderange_after_trunc
+ u = -"\u3042"
+ bsize = u.bytesize
+ str = Bug::String.new(u)
+ str.set_len(bsize - 1)
+ assert_equal bsize - 1, str.bytesize
+ assert_not_predicate str, :valid_encoding?
+ assert_not_predicate str, :ascii_only?
+ str.append(u.byteslice(-1))
+ str.set_len(bsize)
+ assert_equal bsize, str.bytesize
+ assert_predicate str, :valid_encoding?
+ assert_not_predicate str, :ascii_only?
+ assert_equal u, str
+ end
end
diff --git a/test/-ext-/string/test_too_many_dummy_encodings.rb b/test/-ext-/string/test_too_many_dummy_encodings.rb
new file mode 100644
index 0000000000..b96b40db7b
--- /dev/null
+++ b/test/-ext-/string/test_too_many_dummy_encodings.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: false
+require 'test/unit'
+require "-test-/string"
+
+class Test_TooManyDummyEncodings < Test::Unit::TestCase
+ def test_exceed_encoding_table_size
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ require "-test-/string"
+ assert_raise_with_message(EncodingError, /too many encoding/) do
+ 1_000.times{|i| Bug::String.rb_define_dummy_encoding("R_#{i}") } # now 256 entries
+ end
+ end;
+ end
+end
diff --git a/test/-ext-/struct/test_data.rb b/test/-ext-/struct/test_data.rb
new file mode 100644
index 0000000000..8dbc9113a5
--- /dev/null
+++ b/test/-ext-/struct/test_data.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: false
+require 'test/unit'
+require "-test-/struct"
+
+class Bug::Struct::Test_Data < Test::Unit::TestCase
+ def test_data_new_default
+ klass = Bug::Struct.data_new(false)
+ assert_equal Data, klass.superclass
+ assert_equal %i[mem1 mem2], klass.members
+ end
+
+ def test_data_new_superclass
+ superclass = Data.define
+ klass = Bug::Struct.data_new(superclass)
+ assert_equal superclass, klass.superclass
+ assert_equal %i[mem1 mem2], klass.members
+ end
+end
diff --git a/test/-ext-/symbol/test_type.rb b/test/-ext-/symbol/test_type.rb
index fdee692fe4..2b0fbe5b79 100644
--- a/test/-ext-/symbol/test_type.rb
+++ b/test/-ext-/symbol/test_type.rb
@@ -134,5 +134,10 @@ module Test_Symbol
Bug::Symbol.find(cx)
}
end
+
+ def test_const_name_type
+ sym = "\xb5".force_encoding(Encoding::Windows_1253)
+ assert_not_operator Bug::Symbol, :const?, sym, sym.encode(Encoding::UTF_8)
+ end
end
end
diff --git a/test/-ext-/test_bug-3571.rb b/test/-ext-/test_bug-3571.rb
index c75d2e8523..5952ce2a33 100644
--- a/test/-ext-/test_bug-3571.rb
+++ b/test/-ext-/test_bug-3571.rb
@@ -13,8 +13,8 @@ end
SRC
out = [
"start() function is unimplemented on this machine",
- "-:2:in `start'",
- "-:2:in `<main>'",
+ "-:2:in 'Bug.start'",
+ "-:2:in '<main>'",
]
assert_in_out_err(%w"-r-test-/bug_3571", src, [], out, bug3571)
end
diff --git a/test/-ext-/test_random.rb b/test/-ext-/test_random.rb
index 838e5d2f14..e5cebcc871 100644
--- a/test/-ext-/test_random.rb
+++ b/test/-ext-/test_random.rb
@@ -1,11 +1,13 @@
require 'test/unit'
module TestRandomExt
+ def setup
+ super
+ assert_nothing_raised(LoadError) {require '-test-/random'}
+ end
+
class TestLoop < Test::Unit::TestCase
- def setup
- super
- assert_nothing_raised(LoadError) {require '-test-/random'}
- end
+ include TestRandomExt
def test_bytes
rnd = Bug::Random::Loop.new(1)
@@ -24,4 +26,20 @@ module TestRandomExt
assert_equal(1.00, Bug::Random::Loop.new(4<<14).rand)
end
end
+
+ class TestVersionZero < Test::Unit::TestCase
+ include TestRandomExt
+
+ def test_bad_version
+ assert_raise(TypeError) {Bug::Random::VersionZero.new}
+ end
+ end
+
+ class TestVersionMax < Test::Unit::TestCase
+ include TestRandomExt
+
+ def test_bad_version
+ assert_raise(TypeError) {Bug::Random::VersionMax.new}
+ end
+ end
end
diff --git a/test/-ext-/thread/helper.rb b/test/-ext-/thread/helper.rb
new file mode 100644
index 0000000000..3ea2057d15
--- /dev/null
+++ b/test/-ext-/thread/helper.rb
@@ -0,0 +1,51 @@
+module ThreadInstrumentation
+ module TestHelper
+ private
+
+ def record
+ Bug::ThreadInstrumentation.register_callback(!ENV["GVL_DEBUG"])
+ yield
+ ensure
+ timeline = Bug::ThreadInstrumentation.unregister_callback
+ if $!
+ raise
+ else
+ return timeline
+ end
+ end
+
+ def timeline_for(thread, timeline)
+ timeline.select { |t, _| t == thread }.map(&:last)
+ end
+
+ def assert_consistent_timeline(events)
+ refute_predicate events, :empty?
+
+ previous_event = nil
+ events.each do |event|
+ refute_equal :exited, previous_event, "`exited` must be the final event: #{events.inspect}"
+ case event
+ when :started
+ assert_nil previous_event, "`started` must be the first event: #{events.inspect}"
+ when :ready
+ unless previous_event.nil?
+ assert %i(started suspended).include?(previous_event), "`ready` must be preceded by `started` or `suspended`: #{events.inspect}"
+ end
+ when :resumed
+ unless previous_event.nil?
+ assert_equal :ready, previous_event, "`resumed` must be preceded by `ready`: #{events.inspect}"
+ end
+ when :suspended
+ unless previous_event.nil?
+ assert_equal :resumed, previous_event, "`suspended` must be preceded by `resumed`: #{events.inspect}"
+ end
+ when :exited
+ unless previous_event.nil?
+ assert %i(resumed suspended).include?(previous_event), "`exited` must be preceded by `resumed` or `suspended`: #{events.inspect}"
+ end
+ end
+ previous_event = event
+ end
+ end
+ end
+end
diff --git a/test/-ext-/thread/test_instrumentation_api.rb b/test/-ext-/thread/test_instrumentation_api.rb
index dd620e7380..9a3b67fa10 100644
--- a/test/-ext-/thread/test_instrumentation_api.rb
+++ b/test/-ext-/thread/test_instrumentation_api.rb
@@ -1,91 +1,289 @@
# frozen_string_literal: false
require 'envutil'
+require_relative "helper"
class TestThreadInstrumentation < Test::Unit::TestCase
+ include ThreadInstrumentation::TestHelper
+
def setup
pend("No windows support") if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM
require '-test-/thread/instrumentation'
- Thread.list.each do |thread|
- if thread != Thread.current
- thread.kill
- thread.join rescue nil
- end
- end
- assert_equal [Thread.current], Thread.list
-
- Bug::ThreadInstrumentation.reset_counters
- Bug::ThreadInstrumentation::register_callback
+ cleanup_threads
end
def teardown
return if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM
- Bug::ThreadInstrumentation::unregister_callback
+ Bug::ThreadInstrumentation.unregister_callback
+ cleanup_threads
end
THREADS_COUNT = 3
- def test_thread_instrumentation
- threads = threaded_cpu_work
- assert_equal [false] * THREADS_COUNT, threads.map(&:status)
- counters = Bug::ThreadInstrumentation.counters
- assert_join_counters(counters)
- assert_global_join_counters(counters)
+ def test_single_thread_timeline
+ thread = nil
+ full_timeline = record do
+ thread = Thread.new { 1 + 1 }
+ thread.join
+ end
+ assert_equal %i(started ready resumed suspended exited), timeline_for(thread, full_timeline)
+ ensure
+ thread&.kill
+ end
+
+ def test_thread_pass_single_thread
+ full_timeline = record do
+ Thread.pass
+ end
+ assert_equal [], timeline_for(Thread.current, full_timeline)
+ end
+
+ def test_thread_pass_multi_thread
+ thread = Thread.new do
+ cpu_bound_work(0.5)
+ end
+
+ full_timeline = record do
+ Thread.pass
+ end
+
+ assert_equal %i(suspended ready resumed), timeline_for(Thread.current, full_timeline)
+ ensure
+ thread&.kill
+ thread&.join
+ end
+
+ def test_muti_thread_timeline
+ threads = nil
+ full_timeline = record do
+ threads = threaded_cpu_bound_work(1.0)
+ results = threads.map(&:value)
+ results.each do |r|
+ refute_equal false, r
+ end
+ assert_equal [false] * THREADS_COUNT, threads.map(&:status)
+ end
+
+ 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}"
+ end
+
+ timeline = timeline_for(Thread.current, full_timeline)
+ assert_consistent_timeline(timeline)
+ ensure
+ threads&.each(&:kill)
+ end
+
+ def test_join_suspends # Bug #18900
+ thread = other_thread = nil
+ full_timeline = record do
+ other_thread = Thread.new { sleep 0.3 }
+ thread = Thread.new { other_thread.join }
+ thread.join
+ end
+
+ timeline = timeline_for(thread, full_timeline)
+ assert_consistent_timeline(timeline)
+ assert_equal %i(started ready resumed suspended ready resumed suspended exited), timeline
+ ensure
+ other_thread&.kill
+ thread&.kill
end
- def test_join_counters # Bug #18900
- thr = Thread.new { fib(30) }
- Bug::ThreadInstrumentation.reset_counters
- thr.join
- assert_join_counters(Bug::ThreadInstrumentation.local_counters)
+ def test_io_release_gvl
+ r, w = IO.pipe
+ thread = nil
+ full_timeline = record do
+ thread = Thread.new do
+ w.write("Hello\n")
+ end
+ thread.join
+ end
+
+ timeline = timeline_for(thread, full_timeline)
+ assert_consistent_timeline(timeline)
+ assert_equal %i(started ready resumed suspended ready resumed suspended exited), timeline
+ ensure
+ r&.close
+ w&.close
+ end
+
+ def test_queue_releases_gvl
+ queue1 = Queue.new
+ queue2 = Queue.new
+
+ thread = nil
+
+ full_timeline = record do
+ thread = Thread.new do
+ queue1 << true
+ queue2.pop
+ end
+
+ queue1.pop
+ queue2 << true
+ thread.join
+ end
+
+ timeline = timeline_for(thread, full_timeline)
+ assert_consistent_timeline(timeline)
+ assert_equal %i(started ready resumed suspended ready resumed suspended exited), timeline
+ end
+
+ def test_blocking_on_ractor
+ assert_ractor(<<-"RUBY", require_relative: "helper", require: "-test-/thread/instrumentation")
+ include ThreadInstrumentation::TestHelper
+
+ ractor = Ractor.new {
+ Ractor.receive # wait until woke
+ Thread.current
+ }
+
+ # Wait for the main thread to block, then wake the ractor
+ Thread.new do
+ while Thread.main.status != "sleep"
+ Thread.pass
+ end
+ ractor.send true
+ end
+
+ full_timeline = record do
+ ractor.take
+ end
+
+ timeline = timeline_for(Thread.current, full_timeline)
+ assert_consistent_timeline(timeline)
+ assert_equal %i(suspended ready resumed), timeline
+ RUBY
+ end
+
+ def test_sleeping_inside_ractor
+ assert_ractor(<<-"RUBY", require_relative: "helper", require: "-test-/thread/instrumentation")
+ include ThreadInstrumentation::TestHelper
+
+ thread = nil
+
+ full_timeline = record do
+ thread = Ractor.new{
+ sleep 0.1
+ Thread.current
+ }.take
+ sleep 0.1
+ end
+
+ timeline = timeline_for(thread, full_timeline)
+ assert_consistent_timeline(timeline)
+ assert_equal %i(started ready resumed suspended ready resumed suspended exited), timeline
+ RUBY
+ end
+
+ def test_thread_blocked_forever_on_mutex
+ mutex = Mutex.new
+ mutex.lock
+ thread = nil
+
+ full_timeline = record do
+ thread = Thread.new do
+ mutex.lock
+ end
+ 10.times { Thread.pass }
+ sleep 0.1
+ end
+
+ mutex.unlock
+ thread.join
+
+ timeline = timeline_for(thread, full_timeline)
+ assert_consistent_timeline(timeline)
+ assert_equal %i(started ready resumed suspended), timeline
+ end
+
+ def test_thread_blocked_temporarily_on_mutex
+ mutex = Mutex.new
+ mutex.lock
+ thread = nil
+
+ full_timeline = record do
+ thread = Thread.new do
+ mutex.lock
+ end
+ 10.times { Thread.pass }
+ sleep 0.1
+ mutex.unlock
+ 10.times { Thread.pass }
+ sleep 0.1
+ end
+
+ thread.join
+
+ timeline = timeline_for(thread, full_timeline)
+ assert_consistent_timeline(timeline)
+ assert_equal %i(started ready resumed suspended ready resumed suspended exited), timeline
end
def test_thread_instrumentation_fork_safe
skip "No fork()" unless Process.respond_to?(:fork)
- thread_statuses = counters = nil
+ thread_statuses = full_timeline = nil
IO.popen("-") do |read_pipe|
if read_pipe
thread_statuses = Marshal.load(read_pipe)
- counters = Marshal.load(read_pipe)
+ full_timeline = Marshal.load(read_pipe)
else
- Bug::ThreadInstrumentation.reset_counters
- threads = threaded_cpu_work
+ threads = threaded_cpu_bound_work.each(&:join)
Marshal.dump(threads.map(&:status), STDOUT)
- Marshal.dump(Bug::ThreadInstrumentation.counters, STDOUT)
+ full_timeline = Bug::ThreadInstrumentation.unregister_callback.map { |t, e| [t.to_s, e ] }
+ Marshal.dump(full_timeline, STDOUT)
end
end
assert_predicate $?, :success?
assert_equal [false] * THREADS_COUNT, thread_statuses
- assert_join_counters(counters)
- assert_global_join_counters(counters)
+ thread_names = full_timeline.map(&:first).uniq
+ thread_names.each do |thread_name|
+ assert_consistent_timeline(timeline_for(thread_name, full_timeline))
+ end
end
def test_thread_instrumentation_unregister
- Bug::ThreadInstrumentation::unregister_callback
assert Bug::ThreadInstrumentation::register_and_unregister_callbacks
end
private
- def fib(n = 20)
+ def fib(n = 30)
return n if n <= 1
fib(n-1) + fib(n-2)
end
- def threaded_cpu_work(size = 20)
- THREADS_COUNT.times.map { Thread.new { fib(size) } }.each(&:join)
+ def cpu_bound_work(duration)
+ deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + duration
+ i = 0
+ while deadline > Process.clock_gettime(Process::CLOCK_MONOTONIC)
+ fib(25)
+ i += 1
+ end
+ i > 0 ? i : false
end
- def assert_join_counters(counters)
- counters.each_with_index do |c, i|
- assert_operator c, :>, 0, "Call counters[#{i}]: #{counters.inspect}"
+ def threaded_cpu_bound_work(duration = 0.5)
+ THREADS_COUNT.times.map do
+ Thread.new do
+ cpu_bound_work(duration)
+ end
end
end
- def assert_global_join_counters(counters)
- assert_equal THREADS_COUNT, counters.first
+ def cleanup_threads
+ Thread.list.each do |thread|
+ if thread != Thread.current
+ thread.kill
+ thread.join rescue nil
+ end
+ end
+ assert_equal [Thread.current], Thread.list
end
end
diff --git a/test/-ext-/thread/test_lock_native_thread.rb b/test/-ext-/thread/test_lock_native_thread.rb
new file mode 100644
index 0000000000..8a5ba78838
--- /dev/null
+++ b/test/-ext-/thread/test_lock_native_thread.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: false
+
+require 'envutil'
+
+mn_supported_p = -> do
+ out, *_ = EnvUtil.invoke_ruby([{'RUBY_MN_THREADS' => '1'}, '-v'], '', true)
+ return /\+MN/ =~ out
+end
+
+if mn_supported_p.call
+ # test only on MN threads
+else
+ return
+end
+
+class TestThreadLockNativeThread < Test::Unit::TestCase
+ def test_lock_native_thread
+ assert_separately([{'RUBY_MN_THREADS' => '1'}], <<-RUBY)
+ require '-test-/thread/lock_native_thread'
+
+ Thread.new{
+ assert_equal true, Thread.current.lock_native_thread
+ }.join
+
+ # main thread already has DNT
+ assert_equal false, Thread.current.lock_native_thread
+ RUBY
+ end
+
+ def test_lock_native_thread_tls
+ assert_separately([{'RUBY_MN_THREADS' => '1'}], <<-RUBY)
+ require '-test-/thread/lock_native_thread'
+ tn = 10
+ ln = 1_000
+
+ ts = tn.times.map{|i|
+ Thread.new(i){|i|
+ Thread.current.set_tls i
+ assert_equal true, Thread.current.lock_native_thread
+
+ ln.times{
+ assert_equal i, Thread.current.get_tls
+ Thread.pass
+ }
+ }
+ }
+ ts.each(&:join)
+ RUBY
+ end
+end
diff --git a/test/-ext-/thread_fd/test_thread_fd_close.rb b/test/-ext-/thread_fd/test_thread_fd_close.rb
index a53949b93b..1d2ef63635 100644
--- a/test/-ext-/thread_fd/test_thread_fd_close.rb
+++ b/test/-ext-/thread_fd/test_thread_fd_close.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'test/unit'
require '-test-/thread_fd'
-require 'io/wait'
class TestThreadFdClose < Test::Unit::TestCase
diff --git a/test/-ext-/tracepoint/test_tracepoint.rb b/test/-ext-/tracepoint/test_tracepoint.rb
index 9d1679602a..48ffe2605c 100644
--- a/test/-ext-/tracepoint/test_tracepoint.rb
+++ b/test/-ext-/tracepoint/test_tracepoint.rb
@@ -11,6 +11,7 @@ class TestTracepointObj < Test::Unit::TestCase
def test_tracks_objspace_events
result = EnvUtil.suppress_warning {eval(<<-EOS, nil, __FILE__, __LINE__+1)}
+ # frozen_string_literal: false
Bug.tracepoint_track_objspace_events {
99
'abc'
diff --git a/test/.excludes-prism/TestAssignment.rb b/test/.excludes-prism/TestAssignment.rb
new file mode 100644
index 0000000000..23a1b4c5e7
--- /dev/null
+++ b/test/.excludes-prism/TestAssignment.rb
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000000..5f3bb12ef7
--- /dev/null
+++ b/test/.excludes-prism/TestAssignmentGen.rb
@@ -0,0 +1 @@
+exclude(:test_assignment, "https://github.com/ruby/prism/issues/2370")
diff --git a/test/.excludes-prism/TestCall.rb b/test/.excludes-prism/TestCall.rb
new file mode 100644
index 0000000000..969e32ea5a
--- /dev/null
+++ b/test/.excludes-prism/TestCall.rb
@@ -0,0 +1,3 @@
+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/TestIRB/RubyLexTest.rb b/test/.excludes-prism/TestIRB/RubyLexTest.rb
new file mode 100644
index 0000000000..2274ae62cf
--- /dev/null
+++ b/test/.excludes-prism/TestIRB/RubyLexTest.rb
@@ -0,0 +1 @@
+exclude(:test_code_block_open_with_should_continue, "symbol encoding")
diff --git a/test/.excludes-prism/TestISeq.rb b/test/.excludes-prism/TestISeq.rb
new file mode 100644
index 0000000000..3768d8fc05
--- /dev/null
+++ b/test/.excludes-prism/TestISeq.rb
@@ -0,0 +1,3 @@
+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
new file mode 100644
index 0000000000..e9e0623689
--- /dev/null
+++ b/test/.excludes-prism/TestM17N.rb
@@ -0,0 +1,10 @@
+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_mixed_unicode, "unknown")
+exclude(:test_regexp_too_short_multibyte_character, "unknown")
+exclude(:test_regexp_unicode, "unknown")
+exclude(:test_regexp_usascii, "unknown")
+exclude(:test_string_mixed_unicode, "unknown")
diff --git a/test/.excludes-prism/TestMixedUnicodeEscape.rb b/test/.excludes-prism/TestMixedUnicodeEscape.rb
new file mode 100644
index 0000000000..09e3cc168b
--- /dev/null
+++ b/test/.excludes-prism/TestMixedUnicodeEscape.rb
@@ -0,0 +1 @@
+exclude(:test_basic, "unknown")
diff --git a/test/.excludes-prism/TestParse.rb b/test/.excludes-prism/TestParse.rb
new file mode 100644
index 0000000000..83af593b15
--- /dev/null
+++ b/test/.excludes-prism/TestParse.rb
@@ -0,0 +1,28 @@
+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
new file mode 100644
index 0000000000..cfd0c6bed9
--- /dev/null
+++ b/test/.excludes-prism/TestPatternMatching.rb
@@ -0,0 +1,2 @@
+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
new file mode 100644
index 0000000000..68ad1414a9
--- /dev/null
+++ b/test/.excludes-prism/TestRegexp.rb
@@ -0,0 +1,6 @@
+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
new file mode 100644
index 0000000000..a7f66c5d80
--- /dev/null
+++ b/test/.excludes-prism/TestRequire.rb
@@ -0,0 +1 @@
+exclude(:test_require_nonascii_path_shift_jis, "encoding")
diff --git a/test/.excludes-prism/TestRubyLiteral.rb b/test/.excludes-prism/TestRubyLiteral.rb
new file mode 100644
index 0000000000..bf5dbcd36a
--- /dev/null
+++ b/test/.excludes-prism/TestRubyLiteral.rb
@@ -0,0 +1,6 @@
+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_integer, "unknown")
+exclude(:test_string, "https://github.com/ruby/prism/issues/2331")
diff --git a/test/.excludes-prism/TestRubyOptimization.rb b/test/.excludes-prism/TestRubyOptimization.rb
new file mode 100644
index 0000000000..df22ca4f71
--- /dev/null
+++ b/test/.excludes-prism/TestRubyOptimization.rb
@@ -0,0 +1 @@
+exclude(:test_peephole_string_literal_range, "unknown")
diff --git a/test/.excludes-prism/TestRubyVM.rb b/test/.excludes-prism/TestRubyVM.rb
new file mode 100644
index 0000000000..6d4c3ca6fe
--- /dev/null
+++ b/test/.excludes-prism/TestRubyVM.rb
@@ -0,0 +1 @@
+exclude(:test_keep_script_lines, "unknown")
diff --git a/test/.excludes-prism/TestSetTraceFunc.rb b/test/.excludes-prism/TestSetTraceFunc.rb
new file mode 100644
index 0000000000..dd0ea3b219
--- /dev/null
+++ b/test/.excludes-prism/TestSetTraceFunc.rb
@@ -0,0 +1,2 @@
+exclude(:test_return, "unknown")
+exclude(:test_return2, "unknown")
diff --git a/test/.excludes-prism/TestSyntax.rb b/test/.excludes-prism/TestSyntax.rb
new file mode 100644
index 0000000000..f8ae776930
--- /dev/null
+++ b/test/.excludes-prism/TestSyntax.rb
@@ -0,0 +1,30 @@
+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_unassignable, "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")
diff --git a/test/.excludes-prism/TestUnicodeEscape.rb b/test/.excludes-prism/TestUnicodeEscape.rb
new file mode 100644
index 0000000000..add4911bc2
--- /dev/null
+++ b/test/.excludes-prism/TestUnicodeEscape.rb
@@ -0,0 +1 @@
+exclude(:test_fail, "unknown")
diff --git a/test/excludes/TestArray.rb b/test/.excludes/TestArray.rb
index 73da272007..73da272007 100644
--- a/test/excludes/TestArray.rb
+++ b/test/.excludes/TestArray.rb
diff --git a/test/.excludes/TestArraySubclass.rb b/test/.excludes/TestArraySubclass.rb
new file mode 100644
index 0000000000..73da272007
--- /dev/null
+++ b/test/.excludes/TestArraySubclass.rb
@@ -0,0 +1 @@
+exclude(:test_shared_marking, "The target code has already been changed")
diff --git a/test/excludes/TestException.rb b/test/.excludes/TestException.rb
index 38d66d63d2..38d66d63d2 100644
--- a/test/excludes/TestException.rb
+++ b/test/.excludes/TestException.rb
diff --git a/test/excludes/TestGem.rb b/test/.excludes/TestGem.rb
index 042af26eff..042af26eff 100644
--- a/test/excludes/TestGem.rb
+++ b/test/.excludes/TestGem.rb
diff --git a/test/excludes/TestIO_Console.rb b/test/.excludes/TestIO_Console.rb
index caf1935fec..caf1935fec 100644
--- a/test/excludes/TestIO_Console.rb
+++ b/test/.excludes/TestIO_Console.rb
diff --git a/test/excludes/TestISeq.rb b/test/.excludes/TestISeq.rb
index b99181eeaf..b99181eeaf 100644
--- a/test/excludes/TestISeq.rb
+++ b/test/.excludes/TestISeq.rb
diff --git a/test/.excludes/TestThread.rb b/test/.excludes/TestThread.rb
new file mode 100644
index 0000000000..f26ea420a6
--- /dev/null
+++ b/test/.excludes/TestThread.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: false
+exclude(/_stack_size$/, 'often too expensive')
+if /freebsd13/ =~ RUBY_PLATFORM
+ # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220216T143001Z.fail.html.gz
+ #
+ # 1) Error:
+ # TestThread#test_signal_at_join:
+ # Timeout::Error: execution of assert_separately expired timeout (120 sec)
+ # pid 30743 killed by SIGABRT (signal 6) (core dumped)
+ # |
+ #
+ # /usr/home/chkbuild/chkbuild/tmp/build/20220216T143001Z/ruby/test/ruby/test_thread.rb:1390:in `test_signal_at_join'
+ exclude(:test_signal_at_join, 'gets stuck somewhere')
+end
+if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS')
+ # to avoid "`failed to allocate memory (NoMemoryError)" error
+ exclude(:test_thread_interrupt_for_killed_thread, 'TODO')
+end
diff --git a/test/excludes/TestThreadQueue.rb b/test/.excludes/TestThreadQueue.rb
index c8231e372a..c8231e372a 100644
--- a/test/excludes/TestThreadQueue.rb
+++ b/test/.excludes/TestThreadQueue.rb
diff --git a/test/excludes/_appveyor/TestArray.rb b/test/.excludes/_appveyor/TestArray.rb
index 7d03833f07..7d03833f07 100644
--- a/test/excludes/_appveyor/TestArray.rb
+++ b/test/.excludes/_appveyor/TestArray.rb
diff --git a/test/base64/test_base64.rb b/test/base64/test_base64.rb
deleted file mode 100644
index ce716043a8..0000000000
--- a/test/base64/test_base64.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-# coding: US-ASCII
-# frozen_string_literal: true
-require "test/unit"
-require "base64"
-
-class TestBase64 < Test::Unit::TestCase
- def test_sample
- assert_equal("U2VuZCByZWluZm9yY2VtZW50cw==\n", Base64.encode64('Send reinforcements'))
- assert_equal('Send reinforcements', Base64.decode64("U2VuZCByZWluZm9yY2VtZW50cw==\n"))
- assert_equal(
- "Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g\nUnVieQ==\n",
- Base64.encode64("Now is the time for all good coders\nto learn Ruby"))
- assert_equal(
- "Now is the time for all good coders\nto learn Ruby",
- Base64.decode64("Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g\nUnVieQ==\n"))
- assert_equal(
- "VGhpcyBpcyBsaW5lIG9uZQpUaGlzIGlzIGxpbmUgdHdvClRoaXMgaXMgbGlu\nZSB0aHJlZQpBbmQgc28gb24uLi4K\n",
- Base64.encode64("This is line one\nThis is line two\nThis is line three\nAnd so on...\n"))
- assert_equal(
- "This is line one\nThis is line two\nThis is line three\nAnd so on...\n",
- Base64.decode64("VGhpcyBpcyBsaW5lIG9uZQpUaGlzIGlzIGxpbmUgdHdvClRoaXMgaXMgbGluZSB0aHJlZQpBbmQgc28gb24uLi4K"))
- end
-
- def test_encode64
- assert_equal("", Base64.encode64(""))
- assert_equal("AA==\n", Base64.encode64("\0"))
- assert_equal("AAA=\n", Base64.encode64("\0\0"))
- assert_equal("AAAA\n", Base64.encode64("\0\0\0"))
- assert_equal("/w==\n", Base64.encode64("\377"))
- assert_equal("//8=\n", Base64.encode64("\377\377"))
- assert_equal("////\n", Base64.encode64("\377\377\377"))
- assert_equal("/+8=\n", Base64.encode64("\xff\xef"))
- end
-
- def test_decode64
- assert_equal("", Base64.decode64(""))
- assert_equal("\0", Base64.decode64("AA==\n"))
- assert_equal("\0\0", Base64.decode64("AAA=\n"))
- assert_equal("\0\0\0", Base64.decode64("AAAA\n"))
- assert_equal("\377", Base64.decode64("/w==\n"))
- assert_equal("\377\377", Base64.decode64("//8=\n"))
- assert_equal("\377\377\377", Base64.decode64("////\n"))
- assert_equal("\xff\xef", Base64.decode64("/+8=\n"))
- end
-
- def test_strict_encode64
- assert_equal("", Base64.strict_encode64(""))
- assert_equal("AA==", Base64.strict_encode64("\0"))
- assert_equal("AAA=", Base64.strict_encode64("\0\0"))
- assert_equal("AAAA", Base64.strict_encode64("\0\0\0"))
- assert_equal("/w==", Base64.strict_encode64("\377"))
- assert_equal("//8=", Base64.strict_encode64("\377\377"))
- assert_equal("////", Base64.strict_encode64("\377\377\377"))
- assert_equal("/+8=", Base64.strict_encode64("\xff\xef"))
- end
-
- def test_strict_decode64
- assert_equal("", Base64.strict_decode64(""))
- assert_equal("\0", Base64.strict_decode64("AA=="))
- assert_equal("\0\0", Base64.strict_decode64("AAA="))
- assert_equal("\0\0\0", Base64.strict_decode64("AAAA"))
- assert_equal("\377", Base64.strict_decode64("/w=="))
- assert_equal("\377\377", Base64.strict_decode64("//8="))
- assert_equal("\377\377\377", Base64.strict_decode64("////"))
- assert_equal("\xff\xef", Base64.strict_decode64("/+8="))
-
- assert_raise(ArgumentError) { Base64.strict_decode64("^") }
- assert_raise(ArgumentError) { Base64.strict_decode64("A") }
- assert_raise(ArgumentError) { Base64.strict_decode64("A^") }
- assert_raise(ArgumentError) { Base64.strict_decode64("AA") }
- assert_raise(ArgumentError) { Base64.strict_decode64("AA=") }
- assert_raise(ArgumentError) { Base64.strict_decode64("AA===") }
- assert_raise(ArgumentError) { Base64.strict_decode64("AA=x") }
- assert_raise(ArgumentError) { Base64.strict_decode64("AAA") }
- assert_raise(ArgumentError) { Base64.strict_decode64("AAA^") }
- assert_raise(ArgumentError) { Base64.strict_decode64("AB==") }
- assert_raise(ArgumentError) { Base64.strict_decode64("AAB=") }
- end
-
- def test_urlsafe_encode64
- assert_equal("", Base64.urlsafe_encode64(""))
- assert_equal("AA==", Base64.urlsafe_encode64("\0"))
- assert_equal("AAA=", Base64.urlsafe_encode64("\0\0"))
- assert_equal("AAAA", Base64.urlsafe_encode64("\0\0\0"))
- assert_equal("_w==", Base64.urlsafe_encode64("\377"))
- assert_equal("__8=", Base64.urlsafe_encode64("\377\377"))
- assert_equal("____", Base64.urlsafe_encode64("\377\377\377"))
- assert_equal("_-8=", Base64.urlsafe_encode64("\xff\xef"))
- end
-
- def test_urlsafe_encode64_unpadded
- assert_equal("", Base64.urlsafe_encode64("", padding: false))
- assert_equal("AA", Base64.urlsafe_encode64("\0", padding: false))
- assert_equal("AAA", Base64.urlsafe_encode64("\0\0", padding: false))
- assert_equal("AAAA", Base64.urlsafe_encode64("\0\0\0", padding: false))
- end
-
- def test_urlsafe_decode64
- assert_equal("", Base64.urlsafe_decode64(""))
- assert_equal("\0", Base64.urlsafe_decode64("AA=="))
- assert_equal("\0\0", Base64.urlsafe_decode64("AAA="))
- assert_equal("\0\0\0", Base64.urlsafe_decode64("AAAA"))
- assert_equal("\377", Base64.urlsafe_decode64("_w=="))
- assert_equal("\377\377", Base64.urlsafe_decode64("__8="))
- assert_equal("\377\377\377", Base64.urlsafe_decode64("____"))
- assert_equal("\xff\xef", Base64.urlsafe_decode64("_+8="))
- end
-
- def test_urlsafe_decode64_unpadded
- assert_equal("\0", Base64.urlsafe_decode64("AA"))
- assert_equal("\0\0", Base64.urlsafe_decode64("AAA"))
- assert_equal("\0\0\0", Base64.urlsafe_decode64("AAAA"))
- assert_raise(ArgumentError) { Base64.urlsafe_decode64("AA=") }
- end
-end
diff --git a/test/bigdecimal/helper.rb b/test/bigdecimal/helper.rb
deleted file mode 100644
index 46721fb9a8..0000000000
--- a/test/bigdecimal/helper.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: false
-require "test/unit"
-require "bigdecimal"
-require 'rbconfig/sizeof'
-
-module TestBigDecimalBase
- if RbConfig::SIZEOF.key?("int64_t")
- SIZEOF_DECDIG = RbConfig::SIZEOF["int32_t"]
- BASE = 1_000_000_000
- BASE_FIG = 9
- else
- SIZEOF_DECDIG = RbConfig::SIZEOF["int16_t"]
- BASE = 1000
- BASE_FIG = 4
- end
-
- def setup
- @mode = BigDecimal.mode(BigDecimal::EXCEPTION_ALL)
- BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true)
- BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true)
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
- BigDecimal.limit(0)
- end
-
- def teardown
- [BigDecimal::EXCEPTION_INFINITY, BigDecimal::EXCEPTION_NaN,
- BigDecimal::EXCEPTION_UNDERFLOW, BigDecimal::EXCEPTION_OVERFLOW].each do |mode|
- BigDecimal.mode(mode, !(@mode & mode).zero?)
- end
- end
-
- def under_gc_stress
- stress, GC.stress = GC.stress, true
- yield
- ensure
- GC.stress = stress
- end
-end
diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb
deleted file mode 100644
index 0cd85249ad..0000000000
--- a/test/bigdecimal/test_bigdecimal.rb
+++ /dev/null
@@ -1,2275 +0,0 @@
-# frozen_string_literal: false
-require_relative "helper"
-require 'bigdecimal/math'
-
-class TestBigDecimal < Test::Unit::TestCase
- include TestBigDecimalBase
-
- if defined? RbConfig::LIMITS
- LIMITS = RbConfig::LIMITS
- else
- require 'fiddle'
- LONG_MAX = (1 << (Fiddle::SIZEOF_LONG*8 - 1)) - 1
- LONG_MIN = [LONG_MAX + 1].pack("L!").unpack("l!")[0]
- LLONG_MAX = (1 << (Fiddle::SIZEOF_LONG_LONG*8 - 1)) - 1
- LLONG_MIN = [LLONG_MAX + 1].pack("Q!").unpack("q!")[0]
- ULLONG_MAX = (1 << Fiddle::SIZEOF_LONG_LONG*8) - 1
- LIMITS = {
- "LLONG_MIN" => LLONG_MIN,
- "ULLONG_MAX" => ULLONG_MAX,
- "FIXNUM_MIN" => LONG_MIN / 2,
- "FIXNUM_MAX" => LONG_MAX / 2,
- "INT64_MIN" => -9223372036854775808,
- "INT64_MAX" => 9223372036854775807,
- "UINT64_MAX" => 18446744073709551615,
- }.freeze
- end
-
- ROUNDING_MODE_MAP = [
- [ BigDecimal::ROUND_UP, :up],
- [ BigDecimal::ROUND_DOWN, :down],
- [ BigDecimal::ROUND_DOWN, :truncate],
- [ BigDecimal::ROUND_HALF_UP, :half_up],
- [ BigDecimal::ROUND_HALF_UP, :default],
- [ BigDecimal::ROUND_HALF_DOWN, :half_down],
- [ BigDecimal::ROUND_HALF_EVEN, :half_even],
- [ BigDecimal::ROUND_HALF_EVEN, :banker],
- [ BigDecimal::ROUND_CEILING, :ceiling],
- [ BigDecimal::ROUND_CEILING, :ceil],
- [ BigDecimal::ROUND_FLOOR, :floor],
- ]
-
- def assert_nan(x)
- assert(x.nan?, "Expected #{x.inspect} to be NaN")
- end
-
- def assert_positive_infinite(x)
- assert(x.infinite?, "Expected #{x.inspect} to be positive infinite")
- assert_operator(x, :>, 0)
- end
-
- def assert_negative_infinite(x)
- assert(x.infinite?, "Expected #{x.inspect} to be negative infinite")
- assert_operator(x, :<, 0)
- end
-
- def assert_positive_zero(x)
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, x.sign,
- "Expected #{x.inspect} to be positive zero")
- end
-
- def assert_negative_zero(x)
- assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, x.sign,
- "Expected #{x.inspect} to be negative zero")
- end
-
- def test_not_equal
- assert_not_equal BigDecimal("1"), BigDecimal("2")
- end
-
- def test_BigDecimal
- assert_equal(1, BigDecimal("1"))
- assert_equal(1, BigDecimal("1", 1))
- assert_equal(1, BigDecimal(" 1 "))
- assert_equal(111, BigDecimal("1_1_1_"))
- assert_equal(10**(-1), BigDecimal("1E-1"), '#4825')
- assert_equal(1234, BigDecimal(" \t\n\r \r1234 \t\n\r \r"))
-
- assert_raise(ArgumentError) { BigDecimal("1", -1) }
- assert_raise_with_message(ArgumentError, /"1__1_1"/) { BigDecimal("1__1_1") }
- assert_raise_with_message(ArgumentError, /"_1_1_1"/) { BigDecimal("_1_1_1") }
-
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_positive_infinite(BigDecimal("Infinity"))
- assert_positive_infinite(BigDecimal("1E1111111111111111111"))
- assert_positive_infinite(BigDecimal(" \t\n\r \rInfinity \t\n\r \r"))
- assert_negative_infinite(BigDecimal("-Infinity"))
- assert_negative_infinite(BigDecimal(" \t\n\r \r-Infinity \t\n\r \r"))
- assert_nan(BigDecimal("NaN"))
- assert_nan(BigDecimal(" \t\n\r \rNaN \t\n\r \r"))
- end
- end
-
- def test_BigDecimal_bug7522
- bd = BigDecimal("1.12", 1)
- assert_same(bd, BigDecimal(bd))
- assert_same(bd, BigDecimal(bd, exception: false))
- assert_not_same(bd, BigDecimal(bd, 1))
- assert_not_same(bd, BigDecimal(bd, 1, exception: false))
- end
-
- def test_BigDecimal_issue_192
- # https://github.com/ruby/bigdecimal/issues/192
- # https://github.com/rails/rails/pull/42125
- if BASE_FIG == 9
- int = 1_000_000_000_12345_0000
- big = BigDecimal("0.100000000012345e19")
- else # BASE_FIG == 4
- int = 1_0000_12_00
- big = BigDecimal("0.1000012e9")
- end
- assert_equal(BigDecimal(int), big, "[ruby/bigdecimal#192]")
- end
-
- def test_BigDecimal_with_invalid_string
- [
- '', '.', 'e1', 'd1', '.e', '.d', '1.e', '1.d', '.1e', '.1d',
- '2,30', '19,000.0', '-2,30', '-19,000.0', '+2,30', '+19,000.0',
- '2.3,0', '19.000,0', '-2.3,0', '-19.000,0', '+2.3,0', '+19.000,0',
- '2.3.0', '19.000.0', '-2.3.0', '-19.000.0', '+2.3.0', '+19.000.0',
- 'invlaid value', '123 xyz'
- ].each do |invalid_string|
- assert_raise_with_message(ArgumentError, %Q[invalid value for BigDecimal(): "#{invalid_string}"]) do
- BigDecimal(invalid_string)
- end
- end
-
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_raise_with_message(ArgumentError, /"Infinity_"/) { BigDecimal("Infinity_") }
- assert_raise_with_message(ArgumentError, /"\+Infinity_"/) { BigDecimal("+Infinity_") }
- assert_raise_with_message(ArgumentError, /"-Infinity_"/) { BigDecimal("-Infinity_") }
- assert_raise_with_message(ArgumentError, /"NaN_"/) { BigDecimal("NaN_") }
- end
- end
-
- def test_BigDecimal_with_integer
- assert_equal(BigDecimal("0"), BigDecimal(0))
- assert_equal(BigDecimal("1"), BigDecimal(1))
- assert_equal(BigDecimal("-1"), BigDecimal(-1))
- assert_equal(BigDecimal((2**100).to_s), BigDecimal(2**100))
- assert_equal(BigDecimal((-2**100).to_s), BigDecimal(-2**100))
-
- assert_equal(BigDecimal(LIMITS["FIXNUM_MIN"].to_s), BigDecimal(LIMITS["FIXNUM_MIN"]))
-
- assert_equal(BigDecimal(LIMITS["FIXNUM_MAX"].to_s), BigDecimal(LIMITS["FIXNUM_MAX"]))
-
- assert_equal(BigDecimal(LIMITS["INT64_MIN"].to_s), BigDecimal(LIMITS["INT64_MIN"]))
-
- assert_equal(BigDecimal(LIMITS["INT64_MAX"].to_s), BigDecimal(LIMITS["INT64_MAX"]))
-
- assert_equal(BigDecimal(LIMITS["UINT64_MAX"].to_s), BigDecimal(LIMITS["UINT64_MAX"]))
- end
-
- def test_BigDecimal_with_rational
- assert_equal(BigDecimal("0.333333333333333333333"), BigDecimal(1.quo(3), 21))
- assert_equal(BigDecimal("-0.333333333333333333333"), BigDecimal(-1.quo(3), 21))
- assert_raise_with_message(ArgumentError, "can't omit precision for a Rational.") { BigDecimal(42.quo(7)) }
- end
-
- def test_BigDecimal_with_float
- assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4))
- assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4))
- assert_equal(BigDecimal("0.01"), BigDecimal(0.01, Float::DIG + 1))
- assert_raise_with_message(ArgumentError, "can't omit precision for a Float.") { BigDecimal(4.2) }
- assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) }
- assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) }
-
- assert_same(BigDecimal(0.0), BigDecimal(0.0))
- assert_same(BigDecimal(-0.0), BigDecimal(-0.0))
-
- bug9214 = '[ruby-core:58858]'
- assert_equal(BigDecimal(-0.0).sign, -1, bug9214)
-
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_nan(BigDecimal(Float::NAN))
- assert_same(BigDecimal(Float::NAN), BigDecimal(Float::NAN))
- end
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert_positive_infinite(BigDecimal(Float::INFINITY))
- assert_same(BigDecimal(Float::INFINITY), BigDecimal(Float::INFINITY))
- assert_negative_infinite(BigDecimal(-Float::INFINITY))
- assert_same(BigDecimal(-Float::INFINITY), BigDecimal(-Float::INFINITY))
- end
- end
-
- def test_BigDecimal_with_complex
- assert_equal(BigDecimal("1"), BigDecimal(Complex(1, 0)))
- assert_equal(BigDecimal("0.333333333333333333333"), BigDecimal(Complex(1.quo(3), 0), 21))
- assert_equal(BigDecimal("0.1235"), BigDecimal(Complex(0.1234567, 0), 4))
-
- assert_raise_with_message(ArgumentError, "Unable to make a BigDecimal from non-zero imaginary number") { BigDecimal(Complex(1, 1)) }
- end
-
- def test_BigDecimal_with_big_decimal
- assert_equal(BigDecimal(1), BigDecimal(BigDecimal(1)))
- assert_equal(BigDecimal('+0'), BigDecimal(BigDecimal('+0')))
- assert_equal(BigDecimal('-0'), BigDecimal(BigDecimal('-0')))
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_positive_infinite(BigDecimal(BigDecimal('Infinity')))
- assert_negative_infinite(BigDecimal(BigDecimal('-Infinity')))
- assert_nan(BigDecimal(BigDecimal('NaN')))
- end
- end
-
- if RUBY_VERSION < '2.7'
- def test_BigDecimal_with_tainted_string
- Thread.new {
- $SAFE = 1
- BigDecimal('1'.taint)
- }.join
- ensure
- $SAFE = 0
- end
- end
-
- def test_BigDecimal_with_exception_keyword
- assert_raise(ArgumentError) {
- BigDecimal('.', exception: true)
- }
- assert_nothing_raised(ArgumentError) {
- assert_equal(nil, BigDecimal(".", exception: false))
- }
- assert_raise(ArgumentError) {
- BigDecimal("1", -1, exception: true)
- }
- assert_nothing_raised(ArgumentError) {
- assert_equal(nil, BigDecimal("1", -1, exception: false))
- }
- assert_raise(ArgumentError) {
- BigDecimal(42.quo(7), exception: true)
- }
- assert_nothing_raised(ArgumentError) {
- assert_equal(nil, BigDecimal(42.quo(7), exception: false))
- }
- assert_raise(ArgumentError) {
- BigDecimal(4.2, exception: true)
- }
- assert_nothing_raised(ArgumentError) {
- assert_equal(nil, BigDecimal(4.2, exception: false))
- }
- # TODO: support conversion from complex
- # assert_raise(RangeError) {
- # BigDecimal(1i, exception: true)
- # }
- # assert_nothing_raised(RangeError) {
- # assert_equal(nil, BigDecimal(1i, exception: false))
- # }
- assert_raise_with_message(TypeError, "can't convert nil into BigDecimal") {
- BigDecimal(nil, exception: true)
- }
- assert_raise_with_message(TypeError, "can't convert true into BigDecimal") {
- BigDecimal(true, exception: true)
- }
- assert_raise_with_message(TypeError, "can't convert false into BigDecimal") {
- BigDecimal(false, exception: true)
- }
- assert_raise_with_message(TypeError, "can't convert Object into BigDecimal") {
- BigDecimal(Object.new, exception: true)
- }
- assert_nothing_raised(TypeError) {
- assert_equal(nil, BigDecimal(nil, exception: false))
- }
- assert_nothing_raised(TypeError) {
- assert_equal(nil, BigDecimal(:test, exception: false))
- }
- assert_nothing_raised(TypeError) {
- assert_equal(nil, BigDecimal(Object.new, exception: false))
- }
- assert_nothing_raised(TypeError) {
- assert_equal(nil, BigDecimal(Object.new, exception: false))
- }
- # TODO: support to_d
- # assert_nothing_raised(TypeError) {
- # o = Object.new
- # def o.to_d; 3.14; end
- # assert_equal(3.14, BigDecimal(o, exception: false))
- # }
- # assert_nothing_raised(RuntimeError) {
- # o = Object.new
- # def o.to_d; raise; end
- # assert_equal(nil, BigDecimal(o, exception: false))
- # }
- end
-
- def test_s_ver
- assert_raise_with_message(NoMethodError, /undefined method `ver'/) { BigDecimal.ver }
- end
-
- def test_s_allocate
- assert_raise_with_message(TypeError, /allocator undefined for BigDecimal/) { BigDecimal.allocate }
- end
-
- def test_s_new
- assert_raise_with_message(NoMethodError, /undefined method `new'/) { BigDecimal.new("1") }
- end
-
- def test_s_interpret_loosely
- assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1__1_1"))
- assert_equal(BigDecimal('2.5'), BigDecimal.interpret_loosely("2.5"))
- assert_equal(BigDecimal('2.5'), BigDecimal.interpret_loosely("2.5 degrees"))
- assert_equal(BigDecimal('2.5e1'), BigDecimal.interpret_loosely("2.5e1 degrees"))
- assert_equal(BigDecimal('0'), BigDecimal.interpret_loosely("degrees 100.0"))
- assert_equal(BigDecimal('0.125'), BigDecimal.interpret_loosely("0.1_2_5"))
- assert_equal(BigDecimal('0.125'), BigDecimal.interpret_loosely("0.1_2_5__"))
- assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1_.125"))
- assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1._125"))
- assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1__2_5"))
- assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1_e10"))
- assert_equal(BigDecimal('0.1'), BigDecimal.interpret_loosely("0.1e_10"))
- assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("0.1e1__0"))
- assert_equal(BigDecimal('1.2'), BigDecimal.interpret_loosely("1.2.3"))
- assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1."))
- assert_equal(BigDecimal('1'), BigDecimal.interpret_loosely("1e"))
-
- assert_equal(BigDecimal('0.0'), BigDecimal.interpret_loosely("invalid"))
-
- assert(BigDecimal.interpret_loosely("2.5").frozen?)
- end
-
- def _test_mode(type)
- BigDecimal.mode(type, true)
- assert_raise(FloatDomainError) { yield }
-
- BigDecimal.mode(type, false)
- assert_nothing_raised { yield }
- end
-
- def test_mode
- assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::EXCEPTION_ALL, 1) }
- assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 256) }
- assert_raise(ArgumentError) { BigDecimal.mode(BigDecimal::ROUND_MODE, :xyzzy) }
- assert_raise(TypeError) { BigDecimal.mode(0xf000, true) }
-
- begin
- saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
-
- [ BigDecimal::ROUND_UP,
- BigDecimal::ROUND_DOWN,
- BigDecimal::ROUND_HALF_UP,
- BigDecimal::ROUND_HALF_DOWN,
- BigDecimal::ROUND_CEILING,
- BigDecimal::ROUND_FLOOR,
- BigDecimal::ROUND_HALF_EVEN,
- ].each do |mode|
- BigDecimal.mode(BigDecimal::ROUND_MODE, mode)
- assert_equal(mode, BigDecimal.mode(BigDecimal::ROUND_MODE))
- end
- ensure
- BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
- end
-
- BigDecimal.save_rounding_mode do
- ROUNDING_MODE_MAP.each do |const, sym|
- BigDecimal.mode(BigDecimal::ROUND_MODE, sym)
- assert_equal(const, BigDecimal.mode(BigDecimal::ROUND_MODE))
- end
- end
- end
-
- def test_thread_local_mode
- begin
- saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
- Thread.start {
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
- assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE))
- }.join
- assert_equal(BigDecimal::ROUND_UP, BigDecimal.mode(BigDecimal::ROUND_MODE))
- ensure
- BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
- end
- end
-
- def test_save_exception_mode
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- mode = BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW)
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
- end
- assert_equal(mode, BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW))
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
- end
- assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE))
-
- assert_equal(42, BigDecimal.save_exception_mode { 42 })
- end
-
- def test_save_rounding_mode
- saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
- end
- assert_equal(BigDecimal::ROUND_FLOOR, BigDecimal.mode(BigDecimal::ROUND_MODE))
-
- assert_equal(42, BigDecimal.save_rounding_mode { 42 })
- ensure
- BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
- end
-
- def test_save_limit
- begin
- old = BigDecimal.limit
- BigDecimal.limit(100)
- BigDecimal.save_limit do
- BigDecimal.limit(200)
- end
- assert_equal(100, BigDecimal.limit);
- ensure
- BigDecimal.limit(old)
- end
-
- assert_equal(42, BigDecimal.save_limit { 42 })
- end
-
- def test_exception_nan
- _test_mode(BigDecimal::EXCEPTION_NaN) { BigDecimal("NaN") }
- end
-
- def test_exception_infinity
- _test_mode(BigDecimal::EXCEPTION_INFINITY) { BigDecimal("Infinity") }
- end
-
- def test_exception_underflow
- _test_mode(BigDecimal::EXCEPTION_UNDERFLOW) do
- x = BigDecimal("0.1")
- 100.times do
- x *= x
- end
- end
- end
-
- def test_exception_overflow
- _test_mode(BigDecimal::EXCEPTION_OVERFLOW) do
- x = BigDecimal("10")
- 100.times do
- x *= x
- end
- end
- end
-
- def test_exception_zerodivide
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { 1 / BigDecimal("0") }
- _test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { -1 / BigDecimal("0") }
- end
-
- def test_round_up
- n4 = BigDecimal("4") # n4 / 9 = 0.44444...
- n5 = BigDecimal("5") # n5 / 9 = 0.55555...
- n6 = BigDecimal("6") # n6 / 9 = 0.66666...
- m4, m5, m6 = -n4, -n5, -n6
- n2h = BigDecimal("2.5")
- n3h = BigDecimal("3.5")
- m2h, m3h = -n2h, -n3h
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
- assert_operator(n4, :<, n4 / 9 * 9)
- assert_operator(n5, :<, n5 / 9 * 9)
- assert_operator(n6, :<, n6 / 9 * 9)
- assert_operator(m4, :>, m4 / 9 * 9)
- assert_operator(m5, :>, m5 / 9 * 9)
- assert_operator(m6, :>, m6 / 9 * 9)
- assert_equal(3, n2h.round)
- assert_equal(4, n3h.round)
- assert_equal(-3, m2h.round)
- assert_equal(-4, m3h.round)
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
- assert_operator(n4, :>, n4 / 9 * 9)
- assert_operator(n5, :>, n5 / 9 * 9)
- assert_operator(n6, :>, n6 / 9 * 9)
- assert_operator(m4, :<, m4 / 9 * 9)
- assert_operator(m5, :<, m5 / 9 * 9)
- assert_operator(m6, :<, m6 / 9 * 9)
- assert_equal(2, n2h.round)
- assert_equal(3, n3h.round)
- assert_equal(-2, m2h.round)
- assert_equal(-3, m3h.round)
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
- assert_operator(n4, :>, n4 / 9 * 9)
- assert_operator(n5, :<, n5 / 9 * 9)
- assert_operator(n6, :<, n6 / 9 * 9)
- assert_operator(m4, :<, m4 / 9 * 9)
- assert_operator(m5, :>, m5 / 9 * 9)
- assert_operator(m6, :>, m6 / 9 * 9)
- assert_equal(3, n2h.round)
- assert_equal(4, n3h.round)
- assert_equal(-3, m2h.round)
- assert_equal(-4, m3h.round)
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN)
- assert_operator(n4, :>, n4 / 9 * 9)
- assert_operator(n5, :>, n5 / 9 * 9)
- assert_operator(n6, :<, n6 / 9 * 9)
- assert_operator(m4, :<, m4 / 9 * 9)
- assert_operator(m5, :<, m5 / 9 * 9)
- assert_operator(m6, :>, m6 / 9 * 9)
- assert_equal(2, n2h.round)
- assert_equal(3, n3h.round)
- assert_equal(-2, m2h.round)
- assert_equal(-3, m3h.round)
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
- assert_operator(n4, :>, n4 / 9 * 9)
- assert_operator(n5, :<, n5 / 9 * 9)
- assert_operator(n6, :<, n6 / 9 * 9)
- assert_operator(m4, :<, m4 / 9 * 9)
- assert_operator(m5, :>, m5 / 9 * 9)
- assert_operator(m6, :>, m6 / 9 * 9)
- assert_equal(2, n2h.round)
- assert_equal(4, n3h.round)
- assert_equal(-2, m2h.round)
- assert_equal(-4, m3h.round)
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING)
- assert_operator(n4, :<, n4 / 9 * 9)
- assert_operator(n5, :<, n5 / 9 * 9)
- assert_operator(n6, :<, n6 / 9 * 9)
- assert_operator(m4, :<, m4 / 9 * 9)
- assert_operator(m5, :<, m5 / 9 * 9)
- assert_operator(m6, :<, m6 / 9 * 9)
- assert_equal(3, n2h.round)
- assert_equal(4, n3h.round)
- assert_equal(-2, m2h.round)
- assert_equal(-3, m3h.round)
-
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
- assert_operator(n4, :>, n4 / 9 * 9)
- assert_operator(n5, :>, n5 / 9 * 9)
- assert_operator(n6, :>, n6 / 9 * 9)
- assert_operator(m4, :>, m4 / 9 * 9)
- assert_operator(m5, :>, m5 / 9 * 9)
- assert_operator(m6, :>, m6 / 9 * 9)
- assert_equal(2, n2h.round)
- assert_equal(3, n3h.round)
- assert_equal(-3, m2h.round)
- assert_equal(-4, m3h.round)
- end
-
- def test_zero_p
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
-
- assert_equal(true, BigDecimal("0").zero?)
- assert_equal(true, BigDecimal("-0").zero?)
- assert_equal(false, BigDecimal("1").zero?)
- assert_equal(true, BigDecimal("0E200000000000000").zero?)
- assert_equal(false, BigDecimal("Infinity").zero?)
- assert_equal(false, BigDecimal("-Infinity").zero?)
- assert_equal(false, BigDecimal("NaN").zero?)
- end
-
- def test_nonzero_p
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
-
- assert_equal(nil, BigDecimal("0").nonzero?)
- assert_equal(nil, BigDecimal("-0").nonzero?)
- assert_equal(BigDecimal("1"), BigDecimal("1").nonzero?)
- assert_positive_infinite(BigDecimal("Infinity").nonzero?)
- assert_negative_infinite(BigDecimal("-Infinity").nonzero?)
- assert_nan(BigDecimal("NaN").nonzero?)
- end
-
- def test_double_fig
- assert_kind_of(Integer, BigDecimal.double_fig)
- end
-
- def test_cmp
- n1 = BigDecimal("1")
- n2 = BigDecimal("2")
- assert_equal( 0, n1 <=> n1)
- assert_equal( 1, n2 <=> n1)
- assert_equal(-1, n1 <=> n2)
- assert_operator(n1, :==, n1)
- assert_operator(n1, :!=, n2)
- assert_operator(n1, :<, n2)
- assert_operator(n1, :<=, n1)
- assert_operator(n1, :<=, n2)
- assert_operator(n2, :>, n1)
- assert_operator(n2, :>=, n1)
- assert_operator(n1, :>=, n1)
-
- assert_operator(BigDecimal("-0"), :==, BigDecimal("0"))
- assert_operator(BigDecimal("0"), :<, BigDecimal("1"))
- assert_operator(BigDecimal("1"), :>, BigDecimal("0"))
- assert_operator(BigDecimal("1"), :>, BigDecimal("-1"))
- assert_operator(BigDecimal("-1"), :<, BigDecimal("1"))
- assert_operator(BigDecimal((2**100).to_s), :>, BigDecimal("1"))
- assert_operator(BigDecimal("1"), :<, BigDecimal((2**100).to_s))
-
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- inf = BigDecimal("Infinity")
- assert_operator(inf, :>, 1)
- assert_operator(1, :<, inf)
-
- assert_operator(BigDecimal("1E-1"), :==, 10**(-1), '#4825')
- assert_equal(0, BigDecimal("1E-1") <=> 10**(-1), '#4825')
- end
-
- def test_cmp_issue9192
- bug9192 = '[ruby-core:58756] [#9192]'
- operators = { :== => :==, :< => :>, :> => :<, :<= => :>=, :>= => :<= }
- 5.upto(8) do |i|
- s = "706.0#{i}"
- d = BigDecimal(s)
- f = s.to_f
- operators.each do |op, inv|
- assert_equal(d.send(op, f), f.send(inv, d),
- "(BigDecimal(#{s.inspect}) #{op} #{s}) and (#{s} #{inv} BigDecimal(#{s.inspect})) is different #{bug9192}")
- end
- end
- end
-
- def test_cmp_nan
- n1 = BigDecimal("1")
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_equal(nil, BigDecimal("NaN") <=> n1)
- assert_equal(false, BigDecimal("NaN") > n1)
- assert_equal(nil, BigDecimal("NaN") <=> BigDecimal("NaN"))
- assert_equal(false, BigDecimal("NaN") == BigDecimal("NaN"))
- end
-
- def test_cmp_failing_coercion
- n1 = BigDecimal("1")
- assert_equal(nil, n1 <=> nil)
- assert_raise(ArgumentError){n1 > nil}
- end
-
- def test_cmp_coerce
- n1 = BigDecimal("1")
- n2 = BigDecimal("2")
- o1 = Object.new; def o1.coerce(x); [x, BigDecimal("1")]; end
- o2 = Object.new; def o2.coerce(x); [x, BigDecimal("2")]; end
- assert_equal( 0, n1 <=> o1)
- assert_equal( 1, n2 <=> o1)
- assert_equal(-1, n1 <=> o2)
- assert_operator(n1, :==, o1)
- assert_operator(n1, :!=, o2)
- assert_operator(n1, :<, o2)
- assert_operator(n1, :<=, o1)
- assert_operator(n1, :<=, o2)
- assert_operator(n2, :>, o1)
- assert_operator(n2, :>=, o1)
- assert_operator(n1, :>=, 1)
-
- bug10109 = '[ruby-core:64190]'
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert_operator(BigDecimal(0), :<, Float::INFINITY, bug10109)
- assert_operator(Float::INFINITY, :>, BigDecimal(0), bug10109)
- end
-
- def test_cmp_bignum
- assert_operator(BigDecimal((2**100).to_s), :==, 2**100)
- end
-
- def test_cmp_data
- d = Time.now; def d.coerce(x); [x, x]; end
- assert_operator(BigDecimal((2**100).to_s), :==, d)
- end
-
- def test_precs_deprecated
- assert_warn(/BigDecimal#precs is deprecated and will be removed in the future/) do
- Warning[:deprecated] = true if defined?(Warning.[])
- BigDecimal("1").precs
- end
- end
-
- def test_precs
- assert_separately(["-rbigdecimal"], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- $VERBOSE = nil
- a = BigDecimal("1").precs
- assert_instance_of(Array, a)
- assert_equal(2, a.size)
- assert_kind_of(Integer, a[0])
- assert_kind_of(Integer, a[1])
- end;
- end
-
- def test_hash
- a = []
- b = BigDecimal("1")
- 10.times { a << b *= 10 }
- h = {}
- a.each_with_index {|x, i| h[x] = i }
- a.each_with_index do |x, i|
- assert_equal(i, h[x])
- end
- end
-
- def test_marshal
- s = Marshal.dump(BigDecimal("1", 1))
- assert_equal(BigDecimal("1", 1), Marshal.load(s))
-
- # corrupt data
- s = s.gsub(/BigDecimal.*\z/m) {|x| x.gsub(/\d/m, "-") }
- assert_raise(TypeError) { Marshal.load(s) }
- end
-
- def test_finite_infinite_nan
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
-
- x = BigDecimal("0")
- assert_equal(true, x.finite?)
- assert_equal(nil, x.infinite?)
- assert_equal(false, x.nan?)
- y = 1 / x
- assert_equal(false, y.finite?)
- assert_equal(1, y.infinite?)
- assert_equal(false, y.nan?)
- y = -1 / x
- assert_equal(false, y.finite?)
- assert_equal(-1, y.infinite?)
- assert_equal(false, y.nan?)
-
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- y = 0 / x
- assert_equal(false, y.finite?)
- assert_equal(nil, y.infinite?)
- assert_equal(true, y.nan?)
- end
-
- def test_to_i
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
-
- x = BigDecimal("0")
- assert_kind_of(Integer, x.to_i)
- assert_equal(0, x.to_i)
- assert_raise(FloatDomainError){( 1 / x).to_i}
- assert_raise(FloatDomainError){(-1 / x).to_i}
- assert_raise(FloatDomainError) {( 0 / x).to_i}
- x = BigDecimal("1")
- assert_equal(1, x.to_i)
- x = BigDecimal((2**100).to_s)
- assert_equal(2**100, x.to_i)
- end
-
- def test_to_f
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
-
- x = BigDecimal("0")
- assert_instance_of(Float, x.to_f)
- assert_equal(0.0, x.to_f)
- assert_equal( 1.0 / 0.0, ( 1 / x).to_f)
- assert_equal(-1.0 / 0.0, (-1 / x).to_f)
- assert_nan(( 0 / x).to_f)
- x = BigDecimal("1")
- assert_equal(1.0, x.to_f)
- x = BigDecimal((2**100).to_s)
- assert_equal((2**100).to_f, x.to_f)
- x = BigDecimal("1" + "0" * 10000)
- assert_equal(0, BigDecimal("-0").to_f)
-
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
- assert_raise(FloatDomainError) { x.to_f }
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- assert_kind_of(Float, x .to_f)
- assert_kind_of(Float, (-x).to_f)
-
- bug6944 = '[ruby-core:47342]'
-
- BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true)
- x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}"
- assert_raise(FloatDomainError, x) {BigDecimal(x).to_f}
- x = "-#{x}"
- assert_raise(FloatDomainError, x) {BigDecimal(x).to_f}
- x = "1e#{Float::MIN_10_EXP - Float::DIG}"
- assert_nothing_raised(FloatDomainError, x) {
- assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
- }
- x = "-#{x}"
- assert_nothing_raised(FloatDomainError, x) {
- assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
- }
-
- BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, false)
- x = "1e#{Float::MIN_10_EXP - 2*Float::DIG}"
- assert_equal( 0.0, BigDecimal(x).to_f, x)
- x = "-#{x}"
- assert_equal(-0.0, BigDecimal(x).to_f, x)
- x = "1e#{Float::MIN_10_EXP - Float::DIG}"
- assert_nothing_raised(FloatDomainError, x) {
- assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
- }
- x = "-#{x}"
- assert_nothing_raised(FloatDomainError, x) {
- assert_in_delta(0.0, BigDecimal(x).to_f, 10**Float::MIN_10_EXP, bug6944)
- }
-
- assert_equal( 0.0, BigDecimal( '9e-325').to_f)
- assert_equal( 0.0, BigDecimal( '10e-325').to_f)
- assert_equal(-0.0, BigDecimal( '-9e-325').to_f)
- assert_equal(-0.0, BigDecimal('-10e-325').to_f)
- end
-
- def test_to_r
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
-
- x = BigDecimal("0")
- assert_kind_of(Rational, x.to_r)
- assert_equal(0, x.to_r)
- assert_raise(FloatDomainError) {( 1 / x).to_r}
- assert_raise(FloatDomainError) {(-1 / x).to_r}
- assert_raise(FloatDomainError) {( 0 / x).to_r}
-
- assert_equal(1, BigDecimal("1").to_r)
- assert_equal(Rational(3, 2), BigDecimal("1.5").to_r)
- assert_equal((2**100).to_r, BigDecimal((2**100).to_s).to_r)
- end
-
- def test_coerce
- a, b = BigDecimal("1").coerce(1.0)
- assert_instance_of(BigDecimal, a)
- assert_instance_of(BigDecimal, b)
- assert_equal(2, 1 + BigDecimal("1"), '[ruby-core:25697]')
-
- a, b = BigDecimal("1").coerce(1.quo(10))
- assert_equal(BigDecimal("0.1"), a, '[ruby-core:34318]')
-
- a, b = BigDecimal("0.11111").coerce(1.quo(3))
- assert_equal(BigDecimal("0." + "3"*a.precision), a)
-
- assert_nothing_raised(TypeError, '#7176') do
- BigDecimal('1') + Rational(1)
- end
- end
-
- def test_uplus
- x = BigDecimal("1")
- assert_equal(x, x.send(:+@))
- end
-
- def test_neg
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
-
- assert_equal(BigDecimal("-1"), BigDecimal("1").send(:-@))
- assert_equal(BigDecimal("-0"), BigDecimal("0").send(:-@))
- assert_equal(BigDecimal("0"), BigDecimal("-0").send(:-@))
- assert_equal(BigDecimal("-Infinity"), BigDecimal("Infinity").send(:-@))
- assert_equal(BigDecimal("Infinity"), BigDecimal("-Infinity").send(:-@))
- assert_equal(true, BigDecimal("NaN").send(:-@).nan?)
- end
-
- def test_add
- x = BigDecimal("1")
- assert_equal(BigDecimal("2"), x + x)
- assert_equal(1, BigDecimal("0") + 1)
- assert_equal(1, x + 0)
-
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("0") + 0).sign)
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("-0") + 0).sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal("-0") + BigDecimal("-0")).sign)
-
- x = BigDecimal((2**100).to_s)
- assert_equal(BigDecimal((2**100+1).to_s), x + 1)
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- inf = BigDecimal("Infinity")
- neginf = BigDecimal("-Infinity")
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
- assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf + inf }
- assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf + neginf }
- end
-
- def test_sub
- x = BigDecimal("1")
- assert_equal(BigDecimal("0"), x - x)
- assert_equal(-1, BigDecimal("0") - 1)
- assert_equal(1, x - 0)
-
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("0") - 0).sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal("-0") - 0).sign)
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("-0") - BigDecimal("-0")).sign)
-
- x = BigDecimal((2**100).to_s)
- assert_equal(BigDecimal((2**100-1).to_s), x - 1)
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- inf = BigDecimal("Infinity")
- neginf = BigDecimal("-Infinity")
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
- assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf - neginf }
- assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf - inf }
- end
-
- def test_sub_with_float
- assert_kind_of(BigDecimal, BigDecimal("3") - 1.0)
- end
-
- def test_sub_with_rational
- assert_kind_of(BigDecimal, BigDecimal("3") - 1.quo(3))
- end
-
- def test_mult
- x = BigDecimal((2**100).to_s)
- assert_equal(BigDecimal((2**100 * 3).to_s), (x * 3).to_i)
- assert_equal(x, (x * 1).to_i)
- assert_equal(x, (BigDecimal("1") * x).to_i)
- assert_equal(BigDecimal((2**200).to_s), (x * x).to_i)
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- inf = BigDecimal("Infinity")
- neginf = BigDecimal("-Infinity")
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
- assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf * inf }
- assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf * inf }
- end
-
- def test_mult_with_float
- assert_kind_of(BigDecimal, BigDecimal("3") * 1.5)
- assert_equal(BigDecimal("64.4"), BigDecimal(1) * 64.4)
- end
-
- def test_mult_with_rational
- assert_kind_of(BigDecimal, BigDecimal("3") * 1.quo(3))
- end
-
- def test_mult_with_nil
- assert_raise(TypeError) {
- BigDecimal('1.1') * nil
- }
- end
-
- def test_div
- x = BigDecimal((2**100).to_s)
- assert_equal(BigDecimal((2**100 / 3).to_s), (x / 3).to_i)
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal("0") / 1).sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal("-0") / 1).sign)
- assert_equal(2, BigDecimal("2") / 1)
- assert_equal(-2, BigDecimal("2") / -1)
-
- assert_equal(BigDecimal('1486.868686869'),
- (BigDecimal('1472.0') / BigDecimal('0.99')).round(9),
- '[ruby-core:59365] [#9316]')
-
- assert_in_delta(4.124045235,
- (BigDecimal('0.9932') / (700 * BigDecimal('0.344045') / BigDecimal('1000.0'))).round(9, half: :up),
- 10**Float::MIN_10_EXP, '[#9305]')
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert_positive_zero(BigDecimal("1.0") / BigDecimal("Infinity"))
- assert_negative_zero(BigDecimal("-1.0") / BigDecimal("Infinity"))
- assert_negative_zero(BigDecimal("1.0") / BigDecimal("-Infinity"))
- assert_positive_zero(BigDecimal("-1.0") / BigDecimal("-Infinity"))
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
- BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
- assert_raise_with_message(FloatDomainError, "Computation results in 'Infinity'") { BigDecimal("1") / 0 }
- assert_raise_with_message(FloatDomainError, "Computation results in '-Infinity'") { BigDecimal("-1") / 0 }
- end
-
- def test_div_gh220
- x = BigDecimal("1.0")
- y = BigDecimal("3672577333.6608990499165058135986328125")
- c = BigDecimal("0.272288343892592687909520102748926752911779209181321744700032723729015151607289998e-9")
- assert_equal(c, x / y, "[GH-220]")
- end
-
- def test_div_precision
- bug13754 = '[ruby-core:82107] [Bug #13754]'
- a = BigDecimal('101')
- b = BigDecimal('0.9163472602589686')
- c = a/b
- assert(c.precision > b.precision,
- "(101/0.9163472602589686).precision >= (0.9163472602589686).precision #{bug13754}")
- end
-
- def test_div_with_float
- assert_kind_of(BigDecimal, BigDecimal("3") / 1.5)
- assert_equal(BigDecimal("0.5"), BigDecimal(1) / 2.0)
- end
-
- def test_div_with_rational
- assert_kind_of(BigDecimal, BigDecimal("3") / 1.quo(3))
- end
-
- def test_div_with_complex
- q = BigDecimal("3") / 1i
- assert_kind_of(Complex, q)
- end
-
- def test_div_error
- assert_raise(TypeError) { BigDecimal(20) / '2' }
- end
-
- def test_mod
- x = BigDecimal((2**100).to_s)
- assert_equal(1, x % 3)
- assert_equal(2, (-x) % 3)
- assert_equal(-2, x % -3)
- assert_equal(-1, (-x) % -3)
- end
-
- def test_mod_with_float
- assert_kind_of(BigDecimal, BigDecimal("3") % 1.5)
- end
-
- def test_mod_with_rational
- assert_kind_of(BigDecimal, BigDecimal("3") % 1.quo(3))
- end
-
- def test_remainder
- x = BigDecimal((2**100).to_s)
- assert_equal(1, x.remainder(3))
- assert_equal(-1, (-x).remainder(3))
- assert_equal(1, x.remainder(-3))
- assert_equal(-1, (-x).remainder(-3))
- end
-
- def test_remainder_with_float
- assert_kind_of(BigDecimal, BigDecimal("3").remainder(1.5))
- end
-
- def test_remainder_with_rational
- assert_kind_of(BigDecimal, BigDecimal("3").remainder(1.quo(3)))
- end
-
- def test_divmod
- x = BigDecimal((2**100).to_s)
- assert_equal([(x / 3).floor, 1], x.divmod(3))
- assert_equal([(-x / 3).floor, 2], (-x).divmod(3))
-
- assert_equal([0, 0], BigDecimal("0").divmod(2))
-
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_raise(ZeroDivisionError){BigDecimal("0").divmod(0)}
- end
-
- def test_divmod_precision
- a = BigDecimal('2e55')
- b = BigDecimal('1.23456789e10')
- q, r = a.divmod(b)
- assert_equal((a/b).round(0, :down), q)
- assert_equal((a - q*b), r)
-
- b = BigDecimal('-1.23456789e10')
- q, r = a.divmod(b)
- assert_equal((a/b).round(0, :down) - 1, q)
- assert_equal((a - q*b), r)
- end
-
- def test_divmod_error
- assert_raise(TypeError) { BigDecimal(20).divmod('2') }
- end
-
- def test_add_bigdecimal
- x = BigDecimal((2**100).to_s)
- assert_equal(3000000000000000000000000000000, x.add(x, 1))
- assert_equal(2500000000000000000000000000000, x.add(x, 2))
- assert_equal(2540000000000000000000000000000, x.add(x, 3))
- end
-
- def test_sub_bigdecimal
- x = BigDecimal((2**100).to_s)
- assert_equal(1000000000000000000000000000000, x.sub(1, 1))
- assert_equal(1300000000000000000000000000000, x.sub(1, 2))
- assert_equal(1270000000000000000000000000000, x.sub(1, 3))
- end
-
- def test_mult_bigdecimal
- x = BigDecimal((2**100).to_s)
- assert_equal(4000000000000000000000000000000, x.mult(3, 1))
- assert_equal(3800000000000000000000000000000, x.mult(3, 2))
- assert_equal(3800000000000000000000000000000, x.mult(3, 3))
- end
-
- def test_div_bigdecimal
- x = BigDecimal((2**100).to_s)
- assert_equal(422550200076076467165567735125, x.div(3))
- assert_equal(400000000000000000000000000000, x.div(3, 1))
- assert_equal(420000000000000000000000000000, x.div(3, 2))
- assert_equal(423000000000000000000000000000, x.div(3, 3))
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert_equal(0, BigDecimal("0").div(BigDecimal("Infinity")))
- end
- end
-
- def test_div_bigdecimal_with_float_and_precision
- x = BigDecimal(5)
- y = 5.1
- assert_equal(x.div(BigDecimal(y, 0), 8),
- x.div(y, 8))
-
- assert_equal(x.div(BigDecimal(y, 0), 100),
- x.div(y, 100))
- end
-
- def test_quo_without_prec
- x = BigDecimal(5)
- y = BigDecimal(229)
- assert_equal(BigDecimal("0.021834061135371179039301310043668122"), x.quo(y))
- end
-
- def test_quo_with_prec
- begin
- saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
- BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up)
-
- x = BigDecimal(5)
- y = BigDecimal(229)
- assert_equal(BigDecimal("0.021834061135371179039301310043668122"), x.quo(y, 0))
- assert_equal(BigDecimal("0.022"), x.quo(y, 2))
- assert_equal(BigDecimal("0.0218"), x.quo(y, 3))
- assert_equal(BigDecimal("0.0218341"), x.quo(y, 6))
- assert_equal(BigDecimal("0.02183406114"), x.quo(y, 10))
- assert_equal(BigDecimal("0.021834061135371179039301310043668122270742358078603"), x.quo(y, 50))
- ensure
- BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
- end
- end
-
- def test_abs_bigdecimal
- x = BigDecimal((2**100).to_s)
- assert_equal(1267650600228229401496703205376, x.abs)
- x = BigDecimal("-" + (2**100).to_s)
- assert_equal(1267650600228229401496703205376, x.abs)
- x = BigDecimal("0")
- assert_equal(0, x.abs)
- x = BigDecimal("-0")
- assert_equal(0, x.abs)
-
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- x = BigDecimal("Infinity")
- assert_equal(BigDecimal("Infinity"), x.abs)
- x = BigDecimal("-Infinity")
- assert_equal(BigDecimal("Infinity"), x.abs)
-
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- x = BigDecimal("NaN")
- assert_nan(x.abs)
- end
-
- def test_sqrt_bigdecimal
- x = BigDecimal("0.09")
- assert_in_delta(0.3, x.sqrt(1), 0.001)
- x = BigDecimal((2**100).to_s)
- y = BigDecimal("1125899906842624")
- e = y.exponent
- assert_equal(true, (x.sqrt(100) - y).abs < BigDecimal("1E#{e-100}"))
- assert_equal(true, (x.sqrt(200) - y).abs < BigDecimal("1E#{e-200}"))
- assert_equal(true, (x.sqrt(300) - y).abs < BigDecimal("1E#{e-300}"))
- x = BigDecimal("-" + (2**100).to_s)
- assert_raise_with_message(FloatDomainError, "sqrt of negative value") { x.sqrt(1) }
- x = BigDecimal((2**200).to_s)
- assert_equal(2**100, x.sqrt(1))
-
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_raise_with_message(FloatDomainError, "sqrt of 'NaN'(Not a Number)") { BigDecimal("NaN").sqrt(1) }
- assert_raise_with_message(FloatDomainError, "sqrt of negative value") { BigDecimal("-Infinity").sqrt(1) }
-
- assert_equal(0, BigDecimal("0").sqrt(1))
- assert_equal(0, BigDecimal("-0").sqrt(1))
- assert_equal(1, BigDecimal("1").sqrt(1))
- assert_positive_infinite(BigDecimal("Infinity").sqrt(1))
- end
-
- def test_sqrt_5266
- x = BigDecimal('2' + '0'*100)
- assert_equal('0.14142135623730950488016887242096980785696718753769480731',
- x.sqrt(56).to_s(56).split(' ')[0])
- assert_equal('0.1414213562373095048801688724209698078569671875376948073',
- x.sqrt(55).to_s(55).split(' ')[0])
-
- x = BigDecimal('2' + '0'*200)
- assert_equal('0.14142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462',
- x.sqrt(110).to_s(110).split(' ')[0])
- assert_equal('0.1414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572735013846',
- x.sqrt(109).to_s(109).split(' ')[0])
- end
-
- def test_fix
- x = BigDecimal("1.1")
- assert_equal(1, x.fix)
- assert_kind_of(BigDecimal, x.fix)
- end
-
- def test_frac
- x = BigDecimal("1.1")
- assert_equal(0.1, x.frac)
- assert_equal(0.1, BigDecimal("0.1").frac)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_nan(BigDecimal("NaN").frac)
- end
-
- def test_round
- assert_equal(3, BigDecimal("3.14159").round)
- assert_equal(9, BigDecimal("8.7").round)
- assert_equal(3.142, BigDecimal("3.14159").round(3))
- assert_equal(13300.0, BigDecimal("13345.234").round(-2))
-
- x = BigDecimal("111.111")
- assert_equal(111 , x.round)
- assert_equal(111.1 , x.round(1))
- assert_equal(111.11 , x.round(2))
- assert_equal(111.111, x.round(3))
- assert_equal(111.111, x.round(4))
- assert_equal(110 , x.round(-1))
- assert_equal(100 , x.round(-2))
- assert_equal( 0 , x.round(-3))
- assert_equal( 0 , x.round(-4))
-
- x = BigDecimal("2.5")
- assert_equal(3, x.round(0, BigDecimal::ROUND_UP))
- assert_equal(2, x.round(0, BigDecimal::ROUND_DOWN))
- assert_equal(3, x.round(0, BigDecimal::ROUND_HALF_UP))
- assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_DOWN))
- assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_EVEN))
- assert_equal(3, x.round(0, BigDecimal::ROUND_CEILING))
- assert_equal(2, x.round(0, BigDecimal::ROUND_FLOOR))
- assert_raise(ArgumentError) { x.round(0, 256) }
-
- x = BigDecimal("-2.5")
- assert_equal(-3, x.round(0, BigDecimal::ROUND_UP))
- assert_equal(-2, x.round(0, BigDecimal::ROUND_DOWN))
- assert_equal(-3, x.round(0, BigDecimal::ROUND_HALF_UP))
- assert_equal(-2, x.round(0, BigDecimal::ROUND_HALF_DOWN))
- assert_equal(-2, x.round(0, BigDecimal::ROUND_HALF_EVEN))
- assert_equal(-2, x.round(0, BigDecimal::ROUND_CEILING))
- assert_equal(-3, x.round(0, BigDecimal::ROUND_FLOOR))
-
- ROUNDING_MODE_MAP.each do |const, sym|
- assert_equal(x.round(0, const), x.round(0, sym))
- end
-
- bug3803 = '[ruby-core:32136]'
- 15.times do |n|
- x = BigDecimal("5#{'0'*n}1")
- assert_equal(10**(n+2), x.round(-(n+2), BigDecimal::ROUND_HALF_DOWN), bug3803)
- assert_equal(10**(n+2), x.round(-(n+2), BigDecimal::ROUND_HALF_EVEN), bug3803)
- x = BigDecimal("0.5#{'0'*n}1")
- assert_equal(1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803)
- assert_equal(1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803)
- x = BigDecimal("-0.5#{'0'*n}1")
- assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_DOWN), bug3803)
- assert_equal(-1, x.round(0, BigDecimal::ROUND_HALF_EVEN), bug3803)
- end
-
- assert_instance_of(Integer, x.round)
- assert_instance_of(Integer, x.round(0))
- assert_instance_of(Integer, x.round(-1))
- assert_instance_of(BigDecimal, x.round(1))
- end
-
- def test_round_half_even
- assert_equal(BigDecimal('12.0'), BigDecimal('12.5').round(half: :even))
- assert_equal(BigDecimal('14.0'), BigDecimal('13.5').round(half: :even))
-
- assert_equal(BigDecimal('2.2'), BigDecimal('2.15').round(1, half: :even))
- assert_equal(BigDecimal('2.2'), BigDecimal('2.25').round(1, half: :even))
- assert_equal(BigDecimal('2.4'), BigDecimal('2.35').round(1, half: :even))
-
- assert_equal(BigDecimal('-2.2'), BigDecimal('-2.15').round(1, half: :even))
- assert_equal(BigDecimal('-2.2'), BigDecimal('-2.25').round(1, half: :even))
- assert_equal(BigDecimal('-2.4'), BigDecimal('-2.35').round(1, half: :even))
-
- assert_equal(BigDecimal('7.1364'), BigDecimal('7.13645').round(4, half: :even))
- assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :even))
- assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :even))
-
- assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.13645').round(4, half: :even))
- assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :even))
- assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :even))
- end
-
- def test_round_half_up
- assert_equal(BigDecimal('13.0'), BigDecimal('12.5').round(half: :up))
- assert_equal(BigDecimal('14.0'), BigDecimal('13.5').round(half: :up))
-
- assert_equal(BigDecimal('2.2'), BigDecimal('2.15').round(1, half: :up))
- assert_equal(BigDecimal('2.3'), BigDecimal('2.25').round(1, half: :up))
- assert_equal(BigDecimal('2.4'), BigDecimal('2.35').round(1, half: :up))
-
- assert_equal(BigDecimal('-2.2'), BigDecimal('-2.15').round(1, half: :up))
- assert_equal(BigDecimal('-2.3'), BigDecimal('-2.25').round(1, half: :up))
- assert_equal(BigDecimal('-2.4'), BigDecimal('-2.35').round(1, half: :up))
-
- assert_equal(BigDecimal('7.1365'), BigDecimal('7.13645').round(4, half: :up))
- assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :up))
- assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :up))
-
- assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.13645').round(4, half: :up))
- assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :up))
- assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :up))
- end
-
- def test_round_half_down
- assert_equal(BigDecimal('12.0'), BigDecimal('12.5').round(half: :down))
- assert_equal(BigDecimal('13.0'), BigDecimal('13.5').round(half: :down))
-
- assert_equal(BigDecimal('2.1'), BigDecimal('2.15').round(1, half: :down))
- assert_equal(BigDecimal('2.2'), BigDecimal('2.25').round(1, half: :down))
- assert_equal(BigDecimal('2.3'), BigDecimal('2.35').round(1, half: :down))
-
- assert_equal(BigDecimal('-2.1'), BigDecimal('-2.15').round(1, half: :down))
- assert_equal(BigDecimal('-2.2'), BigDecimal('-2.25').round(1, half: :down))
- assert_equal(BigDecimal('-2.3'), BigDecimal('-2.35').round(1, half: :down))
-
- assert_equal(BigDecimal('7.1364'), BigDecimal('7.13645').round(4, half: :down))
- assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :down))
- assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :down))
-
- assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.13645').round(4, half: :down))
- assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :down))
- assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :down))
- end
-
- def test_round_half_nil
- x = BigDecimal("2.5")
-
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
- assert_equal(3, x.round(0, half: nil))
- end
-
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
- assert_equal(2, x.round(0, half: nil))
- end
-
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
- assert_equal(3, x.round(0, half: nil))
- end
-
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN)
- assert_equal(2, x.round(0, half: nil))
- end
-
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
- assert_equal(2, x.round(0, half: nil))
- end
-
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING)
- assert_equal(3, x.round(0, half: nil))
- end
-
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
- assert_equal(2, x.round(0, half: nil))
- end
- end
-
- def test_round_half_invalid_option
- assert_raise_with_message(ArgumentError, "invalid rounding mode: invalid") { BigDecimal('12.5').round(half: :invalid) }
- assert_raise_with_message(ArgumentError, "invalid rounding mode: invalid") { BigDecimal('2.15').round(1, half: :invalid) }
- end
-
- def test_truncate
- assert_equal(3, BigDecimal("3.14159").truncate)
- assert_equal(8, BigDecimal("8.7").truncate)
- assert_equal(3.141, BigDecimal("3.14159").truncate(3))
- assert_equal(13300.0, BigDecimal("13345.234").truncate(-2))
-
- assert_equal(-3, BigDecimal("-3.14159").truncate)
- assert_equal(-8, BigDecimal("-8.7").truncate)
- assert_equal(-3.141, BigDecimal("-3.14159").truncate(3))
- assert_equal(-13300.0, BigDecimal("-13345.234").truncate(-2))
- end
-
- def test_floor
- assert_equal(3, BigDecimal("3.14159").floor)
- assert_equal(-10, BigDecimal("-9.1").floor)
- assert_equal(3.141, BigDecimal("3.14159").floor(3))
- assert_equal(13300.0, BigDecimal("13345.234").floor(-2))
- end
-
- def test_ceil
- assert_equal(4, BigDecimal("3.14159").ceil)
- assert_equal(-9, BigDecimal("-9.1").ceil)
- assert_equal(3.142, BigDecimal("3.14159").ceil(3))
- assert_equal(13400.0, BigDecimal("13345.234").ceil(-2))
- end
-
- def test_to_s
- assert_equal('-123.45678 90123 45678 9', BigDecimal('-123.45678901234567890').to_s('5F'))
- assert_equal('+123.45678901 23456789', BigDecimal('123.45678901234567890').to_s('+8F'))
- assert_equal(' 123.4567890123456789', BigDecimal('123.45678901234567890').to_s(' F'))
- assert_equal('0.1234567890123456789e3', BigDecimal('123.45678901234567890').to_s)
- assert_equal('0.12345 67890 12345 6789e3', BigDecimal('123.45678901234567890').to_s(5))
- end
-
- def test_split
- x = BigDecimal('-123.45678901234567890')
- assert_equal([-1, "1234567890123456789", 10, 3], x.split)
- assert_equal([1, "0", 10, 0], BigDecimal("0").split)
- assert_equal([-1, "0", 10, 0], BigDecimal("-0").split)
-
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_equal([0, "NaN", 10, 0], BigDecimal("NaN").split)
- assert_equal([1, "Infinity", 10, 0], BigDecimal("Infinity").split)
- assert_equal([-1, "Infinity", 10, 0], BigDecimal("-Infinity").split)
- end
-
- def test_exponent
- x = BigDecimal('-123.45678901234567890')
- assert_equal(3, x.exponent)
- end
-
- def test_inspect
- assert_equal("0.123456789012e0", BigDecimal("0.123456789012").inspect)
- assert_equal("0.123456789012e4", BigDecimal("1234.56789012").inspect)
- assert_equal("0.123456789012e-4", BigDecimal("0.0000123456789012").inspect)
- end
-
- def test_power
- assert_nothing_raised(TypeError, '[ruby-core:47632]') do
- 1000.times { BigDecimal('1001.10')**0.75 }
- end
- end
-
- def test_power_with_nil
- assert_raise(TypeError) do
- BigDecimal(3) ** nil
- end
- end
-
- def test_power_of_nan
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_nan(BigDecimal::NAN ** 0)
- assert_nan(BigDecimal::NAN ** 1)
- assert_nan(BigDecimal::NAN ** 42)
- assert_nan(BigDecimal::NAN ** -42)
- assert_nan(BigDecimal::NAN ** 42.0)
- assert_nan(BigDecimal::NAN ** -42.0)
- assert_nan(BigDecimal::NAN ** BigDecimal(42))
- assert_nan(BigDecimal::NAN ** BigDecimal(-42))
- assert_nan(BigDecimal::NAN ** BigDecimal::INFINITY)
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert_nan(BigDecimal::NAN ** (-BigDecimal::INFINITY))
- end
- end
- end
-
- def test_power_with_Bignum
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert_equal(0, BigDecimal(0) ** (2**100))
-
- assert_positive_infinite(BigDecimal(0) ** -(2**100))
- assert_positive_infinite((-BigDecimal(0)) ** -(2**100))
- assert_negative_infinite((-BigDecimal(0)) ** -(2**100 + 1))
-
- assert_equal(1, BigDecimal(1) ** (2**100))
-
- assert_positive_infinite(BigDecimal(3) ** (2**100))
- assert_positive_zero(BigDecimal(3) ** (-2**100))
-
- assert_negative_infinite(BigDecimal(-3) ** (2**100))
- assert_positive_infinite(BigDecimal(-3) ** (2**100 + 1))
- assert_negative_zero(BigDecimal(-3) ** (-2**100))
- assert_positive_zero(BigDecimal(-3) ** (-2**100 - 1))
-
- assert_positive_zero(BigDecimal(0.5, Float::DIG) ** (2**100))
- assert_positive_infinite(BigDecimal(0.5, Float::DIG) ** (-2**100))
-
- assert_negative_zero(BigDecimal(-0.5, Float::DIG) ** (2**100))
- assert_positive_zero(BigDecimal(-0.5, Float::DIG) ** (2**100 - 1))
- assert_negative_infinite(BigDecimal(-0.5, Float::DIG) ** (-2**100))
- assert_positive_infinite(BigDecimal(-0.5, Float::DIG) ** (-2**100 - 1))
- end
- end
-
- def test_power_with_BigDecimal
- assert_nothing_raised do
- assert_in_delta(3 ** 3, BigDecimal(3) ** BigDecimal(3))
- end
- end
-
- def test_power_of_finite_with_zero
- x = BigDecimal(1)
- assert_equal(1, x ** 0)
- assert_equal(1, x ** 0.quo(1))
- assert_equal(1, x ** 0.0)
- assert_equal(1, x ** BigDecimal(0))
-
- x = BigDecimal(42)
- assert_equal(1, x ** 0)
- assert_equal(1, x ** 0.quo(1))
- assert_equal(1, x ** 0.0)
- assert_equal(1, x ** BigDecimal(0))
-
- x = BigDecimal(-42)
- assert_equal(1, x ** 0)
- assert_equal(1, x ** 0.quo(1))
- assert_equal(1, x ** 0.0)
- assert_equal(1, x ** BigDecimal(0))
- end
-
- def test_power_of_three
- x = BigDecimal(3)
- assert_equal(81, x ** 4)
- assert_equal(1.quo(81), x ** -4)
- assert_in_delta(1.0/81, x ** -4)
- end
-
- def test_power_of_zero
- zero = BigDecimal(0)
- assert_equal(0, zero ** 4)
- assert_equal(0, zero ** 4.quo(1))
- assert_equal(0, zero ** 4.0)
- assert_equal(0, zero ** BigDecimal(4))
- assert_equal(1, zero ** 0)
- assert_equal(1, zero ** 0.quo(1))
- assert_equal(1, zero ** 0.0)
- assert_equal(1, zero ** BigDecimal(0))
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- assert_positive_infinite(zero ** -1)
- assert_positive_infinite(zero ** -1.quo(1))
- assert_positive_infinite(zero ** -1.0)
- assert_positive_infinite(zero ** BigDecimal(-1))
-
- m_zero = BigDecimal("-0")
- assert_negative_infinite(m_zero ** -1)
- assert_negative_infinite(m_zero ** -1.quo(1))
- assert_negative_infinite(m_zero ** -1.0)
- assert_negative_infinite(m_zero ** BigDecimal(-1))
- assert_positive_infinite(m_zero ** -2)
- assert_positive_infinite(m_zero ** -2.quo(1))
- assert_positive_infinite(m_zero ** -2.0)
- assert_positive_infinite(m_zero ** BigDecimal(-2))
- end
- end
-
- def test_power_of_positive_infinity
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- assert_positive_infinite(BigDecimal::INFINITY ** 3)
- assert_positive_infinite(BigDecimal::INFINITY ** 3.quo(1))
- assert_positive_infinite(BigDecimal::INFINITY ** 3.0)
- assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(3))
- assert_positive_infinite(BigDecimal::INFINITY ** 2)
- assert_positive_infinite(BigDecimal::INFINITY ** 2.quo(1))
- assert_positive_infinite(BigDecimal::INFINITY ** 2.0)
- assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(2))
- assert_positive_infinite(BigDecimal::INFINITY ** 1)
- assert_positive_infinite(BigDecimal::INFINITY ** 1.quo(1))
- assert_positive_infinite(BigDecimal::INFINITY ** 1.0)
- assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(1))
- assert_equal(1, BigDecimal::INFINITY ** 0)
- assert_equal(1, BigDecimal::INFINITY ** 0.quo(1))
- assert_equal(1, BigDecimal::INFINITY ** 0.0)
- assert_equal(1, BigDecimal::INFINITY ** BigDecimal(0))
- assert_positive_zero(BigDecimal::INFINITY ** -1)
- assert_positive_zero(BigDecimal::INFINITY ** -1.quo(1))
- assert_positive_zero(BigDecimal::INFINITY ** -1.0)
- assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-1))
- assert_positive_zero(BigDecimal::INFINITY ** -2)
- assert_positive_zero(BigDecimal::INFINITY ** -2.0)
- assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-2))
- end
- end
-
- def test_power_of_negative_infinity
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- assert_negative_infinite((-BigDecimal::INFINITY) ** 3)
- assert_negative_infinite((-BigDecimal::INFINITY) ** 3.quo(1))
- assert_negative_infinite((-BigDecimal::INFINITY) ** 3.0)
- assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(3))
- assert_positive_infinite((-BigDecimal::INFINITY) ** 2)
- assert_positive_infinite((-BigDecimal::INFINITY) ** 2.quo(1))
- assert_positive_infinite((-BigDecimal::INFINITY) ** 2.0)
- assert_positive_infinite((-BigDecimal::INFINITY) ** BigDecimal(2))
- assert_negative_infinite((-BigDecimal::INFINITY) ** 1)
- assert_negative_infinite((-BigDecimal::INFINITY) ** 1.quo(1))
- assert_negative_infinite((-BigDecimal::INFINITY) ** 1.0)
- assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(1))
- assert_equal(1, (-BigDecimal::INFINITY) ** 0)
- assert_equal(1, (-BigDecimal::INFINITY) ** 0.quo(1))
- assert_equal(1, (-BigDecimal::INFINITY) ** 0.0)
- assert_equal(1, (-BigDecimal::INFINITY) ** BigDecimal(0))
- assert_negative_zero((-BigDecimal::INFINITY) ** -1)
- assert_negative_zero((-BigDecimal::INFINITY) ** -1.quo(1))
- assert_negative_zero((-BigDecimal::INFINITY) ** -1.0)
- assert_negative_zero((-BigDecimal::INFINITY) ** BigDecimal(-1))
- assert_positive_zero((-BigDecimal::INFINITY) ** -2)
- assert_positive_zero((-BigDecimal::INFINITY) ** -2.quo(1))
- assert_positive_zero((-BigDecimal::INFINITY) ** -2.0)
- assert_positive_zero((-BigDecimal::INFINITY) ** BigDecimal(-2))
- end
- end
-
- def test_power_without_prec
- pi = BigDecimal("3.14159265358979323846264338327950288419716939937511")
- e = BigDecimal("2.71828182845904523536028747135266249775724709369996")
- pow = BigDecimal("0.2245915771836104547342715220454373502758931513399678438732330680117143493477164265678321738086407229773690574073268002736527e2")
- assert_equal(pow, pi.power(e))
-
- n = BigDecimal("2222")
- assert_equal(BigDecimal("0.5171353084572525892492416e12"), (n ** 3.5))
- assert_equal(BigDecimal("0.517135308457252592e12"), (n ** 3.5r))
- assert_equal(BigDecimal("0.517135308457252589249241582e12"), (n ** BigDecimal("3.5",15)))
- end
-
- def test_power_with_prec
- pi = BigDecimal("3.14159265358979323846264338327950288419716939937511")
- e = BigDecimal("2.71828182845904523536028747135266249775724709369996")
- pow = BigDecimal("22.459157718361045473")
- assert_equal(pow, pi.power(e, 20))
-
- b = BigDecimal('1.034482758620689655172413793103448275862068965517241379310344827586206896551724')
- assert_equal(BigDecimal('0.114523E1'), b.power(4, 5), '[Bug #8818] [ruby-core:56802]')
- end
-
- def test_limit
- BigDecimal.save_limit do
- BigDecimal.limit(1)
- x = BigDecimal("3")
- assert_equal(90, x ** 4) # OK? must it be 80?
- # 3 * 3 * 3 * 3 = 10 * 3 * 3 = 30 * 3 = 90 ???
- assert_raise(ArgumentError) { BigDecimal.limit(-1) }
-
- bug7458 = '[ruby-core:50269] [#7458]'
- one = BigDecimal('1')
- epsilon = BigDecimal('0.7E-18')
-
- BigDecimal.limit(0)
- assert_equal(BigDecimal("1.0000000000000000007"), one + epsilon, "limit(0) #{bug7458}")
-
- 1.upto(18) do |lim|
- BigDecimal.limit(lim)
- assert_equal(BigDecimal("1.0"), one + epsilon, "limit(#{lim}) #{bug7458}")
- end
-
- BigDecimal.limit(19)
- assert_equal(BigDecimal("1.000000000000000001"), one + epsilon, "limit(19) #{bug7458}")
-
- BigDecimal.limit(20)
- assert_equal(BigDecimal("1.0000000000000000007"), one + epsilon, "limit(20) #{bug7458}")
- end
- end
-
- def test_sign
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
-
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal("0").sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal("-0").sign)
- assert_equal(BigDecimal::SIGN_POSITIVE_FINITE, BigDecimal("1").sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_FINITE, BigDecimal("-1").sign)
- assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal("1") / 0).sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, (BigDecimal("-1") / 0).sign)
- assert_equal(BigDecimal::SIGN_NaN, (BigDecimal("0") / 0).sign)
- end
-
- def test_inf
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- inf = BigDecimal("Infinity")
-
- assert_equal(inf, inf + inf)
- assert_nan((inf + (-inf)))
- assert_nan((inf - inf))
- assert_equal(inf, inf - (-inf))
- assert_equal(inf, inf * inf)
- assert_nan((inf / inf))
-
- assert_equal(inf, inf + 1)
- assert_equal(inf, inf - 1)
- assert_equal(inf, inf * 1)
- assert_nan((inf * 0))
- assert_equal(inf, inf / 1)
-
- assert_equal(inf, 1 + inf)
- assert_equal(-inf, 1 - inf)
- assert_equal(inf, 1 * inf)
- assert_equal(-inf, -1 * inf)
- assert_nan((0 * inf))
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (1 / inf).sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (-1 / inf).sign)
- end
-
- def assert_equal_us_ascii_string(a, b)
- assert_equal(a, b)
- assert_equal(Encoding::US_ASCII, b.encoding)
- end
-
- def test_to_special_string
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- nan = BigDecimal("NaN")
- assert_equal_us_ascii_string("NaN", nan.to_s)
- inf = BigDecimal("Infinity")
- assert_equal_us_ascii_string("Infinity", inf.to_s)
- assert_equal_us_ascii_string(" Infinity", inf.to_s(" "))
- assert_equal_us_ascii_string("+Infinity", inf.to_s("+"))
- assert_equal_us_ascii_string("-Infinity", (-inf).to_s)
- pzero = BigDecimal("0")
- assert_equal_us_ascii_string("0.0", pzero.to_s)
- assert_equal_us_ascii_string(" 0.0", pzero.to_s(" "))
- assert_equal_us_ascii_string("+0.0", pzero.to_s("+"))
- assert_equal_us_ascii_string("-0.0", (-pzero).to_s)
- end
-
- def test_to_string
- assert_equal_us_ascii_string("0.01", BigDecimal("0.01").to_s("F"))
- s = "0." + "0" * 100 + "1"
- assert_equal_us_ascii_string(s, BigDecimal(s).to_s("F"))
- s = "1" + "0" * 100 + ".0"
- assert_equal_us_ascii_string(s, BigDecimal(s).to_s("F"))
- end
-
- def test_ctov
- assert_equal(0.1, BigDecimal("1E-1"))
- assert_equal(10, BigDecimal("1E+1"))
- assert_equal(1, BigDecimal("+1"))
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
-
- assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, BigDecimal("1E1" + "0" * 10000).sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, BigDecimal("-1E1" + "0" * 10000).sign)
- assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal("1E-1" + "0" * 10000).sign)
- assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal("-1E-1" + "0" * 10000).sign)
- end
-
- def test_split_under_gc_stress
- bug3258 = '[ruby-dev:41213]'
- expect = 10.upto(20).map{|i|[1, "1", 10, i+1].inspect}
- assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, expect, [], bug3258)
- GC.stress = true
- 10.upto(20) do |i|
- p BigDecimal("1"+"0"*i).split
- end
- EOS
- end
-
- def test_coerce_under_gc_stress
- assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
- expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
- b = BigDecimal("1")
- GC.stress = true
- 10.times do
- begin
- b.coerce(:too_long_to_embed_as_string)
- rescue => e
- raise unless e.is_a?(TypeError)
- raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
- end
- end
- EOS
- end
-
- def test_INFINITY
- assert_positive_infinite(BigDecimal::INFINITY)
- end
-
- def test_NAN
- assert_nan(BigDecimal::NAN)
- end
-
- def test_exp_with_zero_precision
- assert_raise(ArgumentError) do
- BigMath.exp(1, 0)
- end
- end
-
- def test_exp_with_negative_precision
- assert_raise(ArgumentError) do
- BigMath.exp(1, -42)
- end
- end
-
- def test_exp_with_complex
- assert_raise(ArgumentError) do
- BigMath.exp(Complex(1, 2), 20)
- end
- end
-
- def test_exp_with_negative
- x = BigDecimal(-1)
- y = BigMath.exp(x, 20)
- assert_equal(y, BigMath.exp(-1, 20))
- assert_equal(BigDecimal(-1), x)
- end
-
- def test_exp_with_negative_infinite
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert_equal(0, BigMath.exp(-BigDecimal::INFINITY, 20))
- end
- end
-
- def test_exp_with_positive_infinite
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert(BigMath.exp(BigDecimal::INFINITY, 20) > 0)
- assert_positive_infinite(BigMath.exp(BigDecimal::INFINITY, 20))
- end
- end
-
- def test_exp_with_nan
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_nan(BigMath.exp(BigDecimal::NAN, 20))
- end
- end
-
- def test_exp_with_1
- assert_in_epsilon(Math::E, BigMath.exp(1, 20))
- end
-
- def test_BigMath_exp
- prec = 20
- assert_in_epsilon(Math.exp(20), BigMath.exp(BigDecimal("20"), prec))
- assert_in_epsilon(Math.exp(40), BigMath.exp(BigDecimal("40"), prec))
- assert_in_epsilon(Math.exp(-20), BigMath.exp(BigDecimal("-20"), prec))
- assert_in_epsilon(Math.exp(-40), BigMath.exp(BigDecimal("-40"), prec))
- end
-
- def test_BigMath_exp_with_float
- prec = 20
- assert_in_epsilon(Math.exp(20), BigMath.exp(20.0, prec))
- assert_in_epsilon(Math.exp(40), BigMath.exp(40.0, prec))
- assert_in_epsilon(Math.exp(-20), BigMath.exp(-20.0, prec))
- assert_in_epsilon(Math.exp(-40), BigMath.exp(-40.0, prec))
- end
-
- def test_BigMath_exp_with_fixnum
- prec = 20
- assert_in_epsilon(Math.exp(20), BigMath.exp(20, prec))
- assert_in_epsilon(Math.exp(40), BigMath.exp(40, prec))
- assert_in_epsilon(Math.exp(-20), BigMath.exp(-20, prec))
- assert_in_epsilon(Math.exp(-40), BigMath.exp(-40, prec))
- end
-
- def test_BigMath_exp_with_rational
- prec = 20
- assert_in_epsilon(Math.exp(20), BigMath.exp(Rational(40,2), prec))
- assert_in_epsilon(Math.exp(40), BigMath.exp(Rational(80,2), prec))
- assert_in_epsilon(Math.exp(-20), BigMath.exp(Rational(-40,2), prec))
- assert_in_epsilon(Math.exp(-40), BigMath.exp(Rational(-80,2), prec))
- end
-
- def test_BigMath_exp_under_gc_stress
- assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
- expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
- 10.times do
- begin
- BigMath.exp(:too_long_to_embed_as_string, 6)
- rescue => e
- raise unless e.is_a?(ArgumentError)
- raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
- end
- end
- EOS
- end
-
- def test_BigMath_log_with_string
- assert_raise(ArgumentError) do
- BigMath.log("foo", 20)
- end
- end
-
- def test_BigMath_log_with_nil
- assert_raise(ArgumentError) do
- BigMath.log(nil, 20)
- end
- end
-
- def test_BigMath_log_with_non_integer_precision
- assert_raise(ArgumentError) do
- BigMath.log(1, 0.5)
- end
- end
-
- def test_BigMath_log_with_nil_precision
- assert_raise(ArgumentError) do
- BigMath.log(1, nil)
- end
- end
-
- def test_BigMath_log_with_complex
- assert_raise(Math::DomainError) do
- BigMath.log(Complex(1, 2), 20)
- end
- end
-
- def test_BigMath_log_with_zero_arg
- assert_raise(Math::DomainError) do
- BigMath.log(0, 20)
- end
- end
-
- def test_BigMath_log_with_negative_arg
- assert_raise(Math::DomainError) do
- BigMath.log(-1, 20)
- end
- end
-
- def test_BigMath_log_with_zero_precision
- assert_raise(ArgumentError) do
- BigMath.log(1, 0)
- end
- end
-
- def test_BigMath_log_with_negative_precision
- assert_raise(ArgumentError) do
- BigMath.log(1, -42)
- end
- end
-
- def test_BigMath_log_with_negative_infinite
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert_raise(Math::DomainError) do
- BigMath.log(-BigDecimal::INFINITY, 20)
- end
- end
- end
-
- def test_BigMath_log_with_positive_infinite
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
- assert(BigMath.log(BigDecimal::INFINITY, 20) > 0)
- assert_positive_infinite(BigMath.log(BigDecimal::INFINITY, 20))
- end
- end
-
- def test_BigMath_log_with_nan
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_nan(BigMath.log(BigDecimal::NAN, 20))
- end
- end
-
- def test_BigMath_log_with_float_nan
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
- assert_nan(BigMath.log(Float::NAN, 20))
- end
- end
-
- def test_BigMath_log_with_1
- assert_in_delta(0.0, BigMath.log(1, 20))
- assert_in_delta(0.0, BigMath.log(1.0, 20))
- assert_in_delta(0.0, BigMath.log(BigDecimal(1), 20))
- end
-
- def test_BigMath_log_with_exp_1
- assert_in_delta(1.0, BigMath.log(BigMath.E(10), 10))
- end
-
- def test_BigMath_log_with_2
- assert_in_delta(Math.log(2), BigMath.log(2, 20))
- assert_in_delta(Math.log(2), BigMath.log(2.0, 20))
- assert_in_delta(Math.log(2), BigMath.log(BigDecimal(2), 20))
- end
-
- def test_BigMath_log_with_square_of_E
- assert_in_delta(2, BigMath.log(BigMath.E(20)**2, 20))
- end
-
- def test_BigMath_log_with_high_precision_case
- e = BigDecimal('2.71828182845904523536028747135266249775724709369996')
- e_3 = e.mult(e, 50).mult(e, 50)
- log_3 = BigMath.log(e_3, 50)
- assert_in_delta(3, log_3, 0.0000000000_0000000000_0000000000_0000000000_0000000001)
- end
-
- def test_BigMath_log_with_42
- assert_in_delta(Math.log(42), BigMath.log(42, 20))
- assert_in_delta(Math.log(42), BigMath.log(42.0, 20))
- assert_in_delta(Math.log(42), BigMath.log(BigDecimal(42), 20))
- end
-
- def test_BigMath_log_with_101
- # this is mainly a performance test (should be very fast, not the 0.3 s)
- assert_in_delta(Math.log(101), BigMath.log(101, 20), 1E-15)
- end
-
- def test_BigMath_log_with_reciprocal_of_42
- assert_in_delta(Math.log(1e-42), BigMath.log(1e-42, 20))
- assert_in_delta(Math.log(1e-42), BigMath.log(BigDecimal("1e-42"), 20))
- end
-
- def test_BigMath_log_under_gc_stress
- assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
- expect = ":too_long_to_embed_as_string can't be coerced into BigDecimal"
- 10.times do
- begin
- BigMath.log(:too_long_to_embed_as_string, 6)
- rescue => e
- raise unless e.is_a?(ArgumentError)
- raise "'\#{expect}' is expected, but '\#{e.message}'" unless e.message == expect
- end
- end
- EOS
- end
-
- def test_frozen_p
- x = BigDecimal(1)
- assert(x.frozen?)
- assert((x + x).frozen?)
- end
-
- def test_clone
- assert_warning(/^$/) do
- x = BigDecimal(0)
- assert_same(x, x.clone)
- end
- end
-
- def test_dup
- assert_warning(/^$/) do
- [1, -1, 2**100, -2**100].each do |i|
- x = BigDecimal(i)
- assert_same(x, x.dup)
- end
- end
- end
-
- def test_new_subclass
- c = Class.new(BigDecimal)
- assert_raise_with_message(NoMethodError, /undefined method `new'/) { c.new(1) }
- end
-
- def test_to_d
- bug6093 = '[ruby-core:42969]'
- code = "exit(BigDecimal('10.0') == 10.0.to_d)"
- assert_ruby_status(%w[-rbigdecimal -rbigdecimal/util -rmathn -], code, bug6093)
- end if RUBY_VERSION < '2.5' # mathn was removed from Ruby 2.5
-
- def test_bug6406
- assert_in_out_err(%w[-rbigdecimal --disable-gems], <<-EOS, [], [])
- Thread.current.keys.to_s
- EOS
- end
-
- def test_precision_only_integer
- assert_equal(0, BigDecimal(0).precision)
- assert_equal(1, BigDecimal(1).precision)
- assert_equal(1, BigDecimal(-1).precision)
- assert_equal(2, BigDecimal(10).precision)
- assert_equal(2, BigDecimal(-10).precision)
- assert_equal(9, BigDecimal(100_000_000).precision)
- assert_equal(9, BigDecimal(-100_000_000).precision)
- assert_equal(12, BigDecimal(100_000_000_000).precision)
- assert_equal(12, BigDecimal(-100_000_000_000).precision)
- assert_equal(21, BigDecimal(100_000_000_000_000_000_000).precision)
- assert_equal(21, BigDecimal(-100_000_000_000_000_000_000).precision)
- assert_equal(103, BigDecimal("111e100").precision)
- assert_equal(103, BigDecimal("-111e100").precision)
- end
-
- def test_precision_only_fraction
- assert_equal(1, BigDecimal("0.1").precision)
- assert_equal(1, BigDecimal("-0.1").precision)
- assert_equal(2, BigDecimal("0.01").precision)
- assert_equal(2, BigDecimal("-0.01").precision)
- assert_equal(2, BigDecimal("0.11").precision)
- assert_equal(2, BigDecimal("-0.11").precision)
- assert_equal(9, BigDecimal("0.000_000_001").precision)
- assert_equal(9, BigDecimal("-0.000_000_001").precision)
- assert_equal(10, BigDecimal("0.000_000_000_1").precision)
- assert_equal(10, BigDecimal("-0.000_000_000_1").precision)
- assert_equal(21, BigDecimal("0.000_000_000_000_000_000_001").precision)
- assert_equal(21, BigDecimal("-0.000_000_000_000_000_000_001").precision)
- assert_equal(100, BigDecimal("111e-100").precision)
- assert_equal(100, BigDecimal("-111e-100").precision)
- end
-
- def test_precision_full
- assert_equal(5, BigDecimal("11111e-2").precision)
- assert_equal(5, BigDecimal("-11111e-2").precision)
- assert_equal(5, BigDecimal("11111e-2").precision)
- assert_equal(5, BigDecimal("-11111e-2").precision)
- assert_equal(21, BigDecimal("100.000_000_000_000_000_001").precision)
- assert_equal(21, BigDecimal("-100.000_000_000_000_000_001").precision)
- end
-
- def test_precision_special
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
-
- assert_equal(0, BigDecimal("Infinity").precision)
- assert_equal(0, BigDecimal("-Infinity").precision)
- assert_equal(0, BigDecimal("NaN").precision)
- end
- end
-
- def test_scale_only_integer
- assert_equal(0, BigDecimal(0).scale)
- assert_equal(0, BigDecimal(1).scale)
- assert_equal(0, BigDecimal(-1).scale)
- assert_equal(0, BigDecimal(10).scale)
- assert_equal(0, BigDecimal(-10).scale)
- assert_equal(0, BigDecimal(100_000_000).scale)
- assert_equal(0, BigDecimal(-100_000_000).scale)
- assert_equal(0, BigDecimal(100_000_000_000).scale)
- assert_equal(0, BigDecimal(-100_000_000_000).scale)
- assert_equal(0, BigDecimal(100_000_000_000_000_000_000).scale)
- assert_equal(0, BigDecimal(-100_000_000_000_000_000_000).scale)
- assert_equal(0, BigDecimal("111e100").scale)
- assert_equal(0, BigDecimal("-111e100").scale)
- end
-
- def test_scale_only_fraction
- assert_equal(1, BigDecimal("0.1").scale)
- assert_equal(1, BigDecimal("-0.1").scale)
- assert_equal(2, BigDecimal("0.01").scale)
- assert_equal(2, BigDecimal("-0.01").scale)
- assert_equal(2, BigDecimal("0.11").scale)
- assert_equal(2, BigDecimal("-0.11").scale)
- assert_equal(21, BigDecimal("0.000_000_000_000_000_000_001").scale)
- assert_equal(21, BigDecimal("-0.000_000_000_000_000_000_001").scale)
- assert_equal(100, BigDecimal("111e-100").scale)
- assert_equal(100, BigDecimal("-111e-100").scale)
- end
-
- def test_scale_full
- assert_equal(1, BigDecimal("0.1").scale)
- assert_equal(1, BigDecimal("-0.1").scale)
- assert_equal(2, BigDecimal("0.01").scale)
- assert_equal(2, BigDecimal("-0.01").scale)
- assert_equal(2, BigDecimal("0.11").scale)
- assert_equal(2, BigDecimal("-0.11").scale)
- assert_equal(2, BigDecimal("11111e-2").scale)
- assert_equal(2, BigDecimal("-11111e-2").scale)
- assert_equal(18, BigDecimal("100.000_000_000_000_000_001").scale)
- assert_equal(18, BigDecimal("-100.000_000_000_000_000_001").scale)
- end
-
- def test_scale_special
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
-
- assert_equal(0, BigDecimal("Infinity").scale)
- assert_equal(0, BigDecimal("-Infinity").scale)
- assert_equal(0, BigDecimal("NaN").scale)
- end
- end
-
- def test_precision_scale
- assert_equal([2, 0], BigDecimal("11.0").precision_scale)
- assert_equal([2, 1], BigDecimal("1.1").precision_scale)
- assert_equal([2, 2], BigDecimal("0.11").precision_scale)
-
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- assert_equal([0, 0], BigDecimal("Infinity").precision_scale)
- end
- end
-
- def test_n_significant_digits_only_integer
- assert_equal(0, BigDecimal(0).n_significant_digits)
- assert_equal(1, BigDecimal(1).n_significant_digits)
- assert_equal(1, BigDecimal(-1).n_significant_digits)
- assert_equal(1, BigDecimal(10).n_significant_digits)
- assert_equal(1, BigDecimal(-10).n_significant_digits)
- assert_equal(3, BigDecimal(101).n_significant_digits)
- assert_equal(3, BigDecimal(-101).n_significant_digits)
- assert_equal(1, BigDecimal(100_000_000_000_000_000_000).n_significant_digits)
- assert_equal(1, BigDecimal(-100_000_000_000_000_000_000).n_significant_digits)
- assert_equal(21, BigDecimal(100_000_000_000_000_000_001).n_significant_digits)
- assert_equal(21, BigDecimal(-100_000_000_000_000_000_001).n_significant_digits)
- assert_equal(3, BigDecimal("111e100").n_significant_digits)
- assert_equal(3, BigDecimal("-111e100").n_significant_digits)
- end
-
- def test_n_significant_digits_only_fraction
- assert_equal(1, BigDecimal("0.1").n_significant_digits)
- assert_equal(1, BigDecimal("-0.1").n_significant_digits)
- assert_equal(1, BigDecimal("0.01").n_significant_digits)
- assert_equal(1, BigDecimal("-0.01").n_significant_digits)
- assert_equal(2, BigDecimal("0.11").n_significant_digits)
- assert_equal(2, BigDecimal("-0.11").n_significant_digits)
- assert_equal(1, BigDecimal("0.000_000_000_000_000_000_001").n_significant_digits)
- assert_equal(1, BigDecimal("-0.000_000_000_000_000_000_001").n_significant_digits)
- assert_equal(3, BigDecimal("111e-100").n_significant_digits)
- assert_equal(3, BigDecimal("-111e-100").n_significant_digits)
- end
-
- def test_n_significant_digits_full
- assert_equal(2, BigDecimal("1.1").n_significant_digits)
- assert_equal(2, BigDecimal("-1.1").n_significant_digits)
- assert_equal(3, BigDecimal("1.01").n_significant_digits)
- assert_equal(3, BigDecimal("-1.01").n_significant_digits)
- assert_equal(5, BigDecimal("11111e-2").n_significant_digits)
- assert_equal(5, BigDecimal("-11111e-2").n_significant_digits)
- assert_equal(21, BigDecimal("100.000_000_000_000_000_001").n_significant_digits)
- assert_equal(21, BigDecimal("-100.000_000_000_000_000_001").n_significant_digits)
- end
-
- def test_n_significant_digits_special
- BigDecimal.save_exception_mode do
- BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
- BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
-
- assert_equal(0, BigDecimal("Infinity").n_significant_digits)
- assert_equal(0, BigDecimal("-Infinity").n_significant_digits)
- assert_equal(0, BigDecimal("NaN").n_significant_digits)
- end
- end
-
- def test_initialize_copy_dup_clone_frozen_error
- bd = BigDecimal(1)
- bd2 = BigDecimal(2)
- err = RUBY_VERSION >= '2.5' ? FrozenError : TypeError
- assert_raise(err) { bd.send(:initialize_copy, bd2) }
- assert_raise(err) { bd.send(:initialize_clone, bd2) }
- assert_raise(err) { bd.send(:initialize_dup, bd2) }
- end
-
- def test_llong_min_gh_200
- # https://github.com/ruby/bigdecimal/issues/199
- # Between LLONG_MIN and -ULLONG_MAX
- assert_equal(BigDecimal(LIMITS["LLONG_MIN"].to_s), BigDecimal(LIMITS["LLONG_MIN"]), "[GH-200]")
-
- minus_ullong_max = -LIMITS["ULLONG_MAX"]
- assert_equal(BigDecimal(minus_ullong_max.to_s), BigDecimal(minus_ullong_max), "[GH-200]")
- end
-
- def assert_no_memory_leak(code, *rest, **opt)
- code = "8.times {20_000.times {begin #{code}; rescue NoMemoryError; end}; GC.start}"
- super(["-rbigdecimal"],
- "b = BigDecimal('10'); b.nil?; " \
- "GC.add_stress_to_class(BigDecimal); "\
- "#{code}", code, *rest, rss: true, limit: 1.1, **opt)
- end
-
- if EnvUtil.gc_stress_to_class?
- def test_no_memory_leak_allocate
- assert_no_memory_leak("BigDecimal.allocate")
- end
-
- def test_no_memory_leak_initialize
- assert_no_memory_leak("BigDecimal()")
- end
-
- def test_no_memory_leak_BigDecimal
- assert_no_memory_leak("BigDecimal('10')")
- assert_no_memory_leak("BigDecimal(b)")
- end
-
- def test_no_memory_leak_create
- assert_no_memory_leak("b + 10")
- end
- end
-end
diff --git a/test/bigdecimal/test_bigdecimal_util.rb b/test/bigdecimal/test_bigdecimal_util.rb
deleted file mode 100644
index 2f27163ebf..0000000000
--- a/test/bigdecimal/test_bigdecimal_util.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-# frozen_string_literal: false
-require_relative "helper"
-require 'bigdecimal/util'
-
-class TestBigDecimalUtil < Test::Unit::TestCase
- include TestBigDecimalBase
-
- def test_BigDecimal_to_d
- x = BigDecimal(1)
- assert_same(x, x.to_d)
- end
-
- def test_Integer_to_d
- assert_equal(BigDecimal(1), 1.to_d)
- assert_equal(BigDecimal(2<<100), (2<<100).to_d)
-
- assert(1.to_d.frozen?)
- end
-
- def test_Float_to_d_without_precision
- delta = 1.0/10**(Float::DIG+1)
- assert_in_delta(BigDecimal(0.5, 0), 0.5.to_d, delta)
- assert_in_delta(BigDecimal(355.0/113.0, 0), (355.0/113.0).to_d, delta)
-
- assert_equal(9.05, 9.05.to_d.to_f)
- assert_equal("9.05", 9.05.to_d.to_s('F'))
-
- assert_equal("65.6", 65.6.to_d.to_s("F"))
-
- assert_equal(Math::PI, Math::PI.to_d.to_f)
-
- bug9214 = '[ruby-core:58858]'
- assert_equal((-0.0).to_d.sign, -1, bug9214)
-
- assert_raise(TypeError) { 0.3.to_d(nil) }
- assert_raise(TypeError) { 0.3.to_d(false) }
-
- assert(1.1.to_d.frozen?)
-
- assert_equal(BigDecimal("999_999.9999"), 999_999.9999.to_d)
- end
-
- def test_Float_to_d_with_precision
- digits = 5
- delta = 1.0/10**(digits)
- assert_in_delta(BigDecimal(0.5, 5), 0.5.to_d(digits), delta)
- assert_in_delta(BigDecimal(355.0/113.0, 5), (355.0/113.0).to_d(digits), delta)
-
- bug9214 = '[ruby-core:58858]'
- assert_equal((-0.0).to_d(digits).sign, -1, bug9214)
-
- assert(1.1.to_d(digits).frozen?)
- end
-
- def test_Float_to_d_bug13331
- assert_equal(64.4.to_d,
- 1.to_d * 64.4,
- "[ruby-core:80234] [Bug #13331]")
-
- assert_equal((2*Math::PI).to_d,
- 2.to_d * Math::PI,
- "[ruby-core:80234] [Bug #13331]")
- end
-
- def test_Float_to_d_issue_192
- # https://github.com/ruby/bigdecimal/issues/192
- # https://github.com/rails/rails/pull/42125
- if BASE_FIG == 9
- flo = 1_000_000_000.12345
- big = BigDecimal("0.100000000012345e10")
- else # BASE_FIG == 4
- flo = 1_0000.12
- big = BigDecimal("0.1000012e5")
- end
- assert_equal(flo.to_d, big, "[ruby/bigdecimal#192]")
- end
-
- def test_Rational_to_d
- digits = 100
- delta = 1.0/10**(digits)
- assert_in_delta(BigDecimal(1.quo(2), digits), 1.quo(2).to_d(digits), delta)
- assert_in_delta(BigDecimal(355.quo(113), digits), 355.quo(113).to_d(digits), delta)
-
- assert(355.quo(113).to_d(digits).frozen?)
- end
-
- def test_Rational_to_d_with_zero_precision
- assert_equal(BigDecimal(355.quo(113), 0), 355.quo(113).to_d(0))
- end
-
- def test_Rational_to_d_with_negative_precision
- assert_raise(ArgumentError) { 355.quo(113).to_d(-42) }
- end
-
- def test_Complex_to_d
- BigDecimal.save_rounding_mode do
- BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
-
- assert_equal(BigDecimal("1"), Complex(1, 0).to_d)
- assert_equal(BigDecimal("0.333333333333333333333"),
- Complex(1.quo(3), 0).to_d(21))
- assert_equal(BigDecimal("0.1234567"), Complex(0.1234567, 0).to_d)
- assert_equal(BigDecimal("0.1235"), Complex(0.1234567, 0).to_d(4))
-
- assert_raise_with_message(ArgumentError, "can't omit precision for a Rational.") { Complex(1.quo(3), 0).to_d }
-
- assert_raise_with_message(ArgumentError, "Unable to make a BigDecimal from non-zero imaginary number") { Complex(1, 1).to_d }
- end
- end
-
- def test_String_to_d
- assert_equal(BigDecimal('1'), "1__1_1".to_d)
- assert_equal(BigDecimal('2.5'), "2.5".to_d)
- assert_equal(BigDecimal('2.5'), "2.5 degrees".to_d)
- assert_equal(BigDecimal('2.5e1'), "2.5e1 degrees".to_d)
- assert_equal(BigDecimal('0'), "degrees 100.0".to_d)
- assert_equal(BigDecimal('0.125'), "0.1_2_5".to_d)
- assert_equal(BigDecimal('0.125'), "0.1_2_5__".to_d)
- assert_equal(BigDecimal('1'), "1_.125".to_d)
- assert_equal(BigDecimal('1'), "1._125".to_d)
- assert_equal(BigDecimal('0.1'), "0.1__2_5".to_d)
- assert_equal(BigDecimal('0.1'), "0.1_e10".to_d)
- assert_equal(BigDecimal('0.1'), "0.1e_10".to_d)
- assert_equal(BigDecimal('1'), "0.1e1__0".to_d)
- assert_equal(BigDecimal('1.2'), "1.2.3".to_d)
- assert_equal(BigDecimal('1'), "1.".to_d)
- assert_equal(BigDecimal('1'), "1e".to_d)
-
- assert("2.5".to_d.frozen?)
- end
-
- def test_invalid_String_to_d
- assert_equal("invalid".to_d, BigDecimal('0.0'))
- end
-
- def test_Nil_to_d
- assert_equal(nil.to_d, BigDecimal('0.0'))
-
- assert(nil.to_d)
- end
-end
diff --git a/test/bigdecimal/test_bigmath.rb b/test/bigdecimal/test_bigmath.rb
deleted file mode 100644
index 5bf1fbf318..0000000000
--- a/test/bigdecimal/test_bigmath.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# frozen_string_literal: false
-require_relative "helper"
-require "bigdecimal/math"
-
-class TestBigMath < Test::Unit::TestCase
- include TestBigDecimalBase
- include BigMath
- N = 20
- PINF = BigDecimal("+Infinity")
- MINF = BigDecimal("-Infinity")
- NAN = BigDecimal("NaN")
-
- def test_const
- assert_in_delta(Math::PI, PI(N))
- assert_in_delta(Math::E, E(N))
- end
-
- def test_sqrt
- assert_in_delta(2**0.5, sqrt(BigDecimal("2"), N))
- assert_equal(10, sqrt(BigDecimal("100"), N))
- assert_equal(0.0, sqrt(BigDecimal("0"), N))
- assert_equal(0.0, sqrt(BigDecimal("-0"), N))
- assert_raise(FloatDomainError) {sqrt(BigDecimal("-1.0"), N)}
- assert_raise(FloatDomainError) {sqrt(NAN, N)}
- assert_raise(FloatDomainError) {sqrt(PINF, N)}
- end
-
- def test_sin
- assert_in_delta(0.0, sin(BigDecimal("0.0"), N))
- assert_in_delta(Math.sqrt(2.0) / 2, sin(PI(N) / 4, N))
- assert_in_delta(1.0, sin(PI(N) / 2, N))
- assert_in_delta(0.0, sin(PI(N) * 2, N))
- assert_in_delta(0.0, sin(PI(N), N))
- assert_in_delta(-1.0, sin(PI(N) / -2, N))
- assert_in_delta(0.0, sin(PI(N) * -2, N))
- assert_in_delta(0.0, sin(-PI(N), N))
- assert_in_delta(0.0, sin(PI(N) * 21, N))
- assert_in_delta(0.0, sin(PI(N) * 30, N))
- assert_in_delta(-1.0, sin(PI(N) * BigDecimal("301.5"), N))
- end
-
- def test_cos
- assert_in_delta(1.0, cos(BigDecimal("0.0"), N))
- assert_in_delta(Math.sqrt(2.0) / 2, cos(PI(N) / 4, N))
- assert_in_delta(0.0, cos(PI(N) / 2, N))
- assert_in_delta(1.0, cos(PI(N) * 2, N))
- assert_in_delta(-1.0, cos(PI(N), N))
- assert_in_delta(0.0, cos(PI(N) / -2, N))
- assert_in_delta(1.0, cos(PI(N) * -2, N))
- assert_in_delta(-1.0, cos(-PI(N), N))
- assert_in_delta(-1.0, cos(PI(N) * 21, N))
- assert_in_delta(1.0, cos(PI(N) * 30, N))
- assert_in_delta(0.0, cos(PI(N) * BigDecimal("301.5"), N))
- end
-
- def test_atan
- assert_equal(0.0, atan(BigDecimal("0.0"), N))
- assert_in_delta(Math::PI/4, atan(BigDecimal("1.0"), N))
- assert_in_delta(Math::PI/6, atan(sqrt(BigDecimal("3.0"), N) / 3, N))
- assert_in_delta(Math::PI/2, atan(PINF, N))
- assert_equal(BigDecimal("0.823840753418636291769355073102514088959345624027952954058347023122539489"),
- atan(BigDecimal("1.08"), 72).round(72), '[ruby-dev:41257]')
- end
-
- def test_log
- assert_equal(0, BigMath.log(BigDecimal("1.0"), 10))
- assert_in_epsilon(Math.log(10)*1000, BigMath.log(BigDecimal("1e1000"), 10))
- assert_raise(Math::DomainError) {BigMath.log(BigDecimal("0"), 10)}
- assert_raise(Math::DomainError) {BigMath.log(BigDecimal("-1"), 10)}
- assert_separately(%w[-rbigdecimal], <<-SRC)
- begin
- x = BigMath.log(BigDecimal("1E19999999999999"), 10)
- rescue FloatDomainError
- else
- unless x.infinite?
- assert_in_epsilon(Math.log(10)*19999999999999, x)
- end
- end
- SRC
- end
-end
diff --git a/test/bigdecimal/test_ractor.rb b/test/bigdecimal/test_ractor.rb
deleted file mode 100644
index 798cc494e1..0000000000
--- a/test/bigdecimal/test_ractor.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-require_relative "helper"
-
-class TestBigDecimalRactor < Test::Unit::TestCase
- include TestBigDecimalBase
-
- def setup
- super
- omit unless defined? Ractor
- end
-
- def test_ractor_shareable
- assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- $VERBOSE = nil
- require "bigdecimal"
- r = Ractor.new BigDecimal(Math::PI, Float::DIG+1) do |pi|
- BigDecimal('2.0')*pi
- end
- assert_equal(2*Math::PI, r.take)
- end;
- end
-end
diff --git a/test/cgi/test_cgi_cookie.rb b/test/cgi/test_cgi_cookie.rb
index 985cc0d7a1..eadae45313 100644
--- a/test/cgi/test_cgi_cookie.rb
+++ b/test/cgi/test_cgi_cookie.rb
@@ -60,6 +60,27 @@ class CGICookieTest < Test::Unit::TestCase
end
+ def test_cgi_cookie_new_with_domain
+ h = {'name'=>'name1', 'value'=>'value1'}
+ cookie = CGI::Cookie.new(h.merge('domain'=>'a.example.com'))
+ assert_equal('a.example.com', cookie.domain)
+
+ cookie = CGI::Cookie.new(h.merge('domain'=>'.example.com'))
+ assert_equal('.example.com', cookie.domain)
+
+ cookie = CGI::Cookie.new(h.merge('domain'=>'1.example.com'))
+ assert_equal('1.example.com', cookie.domain, 'enhanced by RFC 1123')
+
+ assert_raise(ArgumentError) {
+ CGI::Cookie.new(h.merge('domain'=>'-a.example.com'))
+ }
+
+ assert_raise(ArgumentError) {
+ CGI::Cookie.new(h.merge('domain'=>'a-.example.com'))
+ }
+ end
+
+
def test_cgi_cookie_scriptname
cookie = CGI::Cookie.new('name1', 'value1')
assert_equal('', cookie.path)
@@ -118,6 +139,70 @@ class CGICookieTest < Test::Unit::TestCase
end
+ def test_cgi_cookie_domain_injection_into_name
+ name = "a=b; domain=example.com;"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_newline_injection_into_name
+ name = "a=b;\r\nLocation: http://example.com#"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_multibyte_injection_into_name
+ name = "a=b;\u3042"
+ path = "/"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_injection_into_path
+ name = "name"
+ path = "/; samesite=none"
+ domain = "example.jp"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
+
+ def test_cgi_cookie_injection_into_domain
+ name = "name"
+ path = "/"
+ domain = "example.jp; samesite=none"
+ assert_raise(ArgumentError) do
+ CGI::Cookie.new('name' => name,
+ 'value' => "value",
+ 'domain' => domain,
+ 'path' => path)
+ end
+ end
+
instance_methods.each do |method|
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
diff --git a/test/cgi/test_cgi_header.rb b/test/cgi/test_cgi_header.rb
index bab2d0348a..ec2f4deb72 100644
--- a/test/cgi/test_cgi_header.rb
+++ b/test/cgi/test_cgi_header.rb
@@ -176,6 +176,14 @@ class CGIHeaderTest < Test::Unit::TestCase
end
+ def test_cgi_http_header_crlf_injection
+ cgi = CGI.new
+ assert_raise(RuntimeError) { cgi.http_header("text/xhtml\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("type" => "text/xhtml\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("status" => "200 OK\r\nBOO") }
+ assert_raise(RuntimeError) { cgi.http_header("location" => "text/xhtml\r\nBOO") }
+ end
+
instance_methods.each do |method|
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb
index a3be193a13..b0612fc87d 100644
--- a/test/cgi/test_cgi_util.rb
+++ b/test/cgi/test_cgi_util.rb
@@ -74,6 +74,10 @@ class CGIUtilTest < Test::Unit::TestCase
assert_equal('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93'.ascii_only?, CGI.escapeURIComponent(@str1).ascii_only?) if defined?(::Encoding)
end
+ def test_cgi_escape_uri_component
+ assert_equal('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93', CGI.escape_uri_component(@str1))
+ end
+
def test_cgi_escapeURIComponent_with_unreserved_characters
assert_equal("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",
CGI.escapeURIComponent("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"),
@@ -101,6 +105,11 @@ class CGIUtilTest < Test::Unit::TestCase
assert_equal("\u{30E1 30E2 30EA 691C 7D22}", CGI.unescapeURIComponent("\u{30E1 30E2 30EA}%E6%A4%9C%E7%B4%A2"))
end
+ def test_cgi_unescape_uri_component
+ str = CGI.unescape_uri_component('%26%3C%3E%22%20%E3%82%86%E3%82%93%E3%82%86%E3%82%93')
+ assert_equal(@str1, str)
+ end
+
def test_cgi_unescapeURIComponent_preserve_encoding
assert_equal(Encoding::US_ASCII, CGI.unescapeURIComponent("%C0%3C%3C".dup.force_encoding("US-ASCII")).encoding)
assert_equal(Encoding::ASCII_8BIT, CGI.unescapeURIComponent("%C0%3C%3C".dup.force_encoding("ASCII-8BIT")).encoding)
@@ -177,6 +186,22 @@ class CGIUtilTest < Test::Unit::TestCase
assert_equal('&<&amp>&quot&abcdefghijklmn', CGI.unescapeHTML('&&lt;&amp&gt;&quot&abcdefghijklmn'))
end
+ module UnescapeHTMLTests
+ def test_cgi_unescapeHTML_following_known_first_letter
+ assert_equal('&a>&q>&l>&g>', CGI.unescapeHTML('&a&gt;&q&gt;&l&gt;&g&gt;'))
+ end
+
+ def test_cgi_unescapeHTML_following_number_sign
+ assert_equal('&#>&#x>', CGI.unescapeHTML('&#&gt;&#x&gt;'))
+ end
+
+ def test_cgi_unescapeHTML_following_invalid_numeric
+ assert_equal('&#1114112>&#x110000>', CGI.unescapeHTML('&#1114112&gt;&#x110000&gt;'))
+ end
+ end
+
+ include UnescapeHTMLTests
+
Encoding.list.each do |enc|
begin
escaped = "&#39;&amp;&quot;&gt;&lt;".encode(enc)
@@ -262,7 +287,7 @@ class CGIUtilPureRubyTest < Test::Unit::TestCase
remove_method :escapeHTML
alias _unescapeHTML unescapeHTML
remove_method :unescapeHTML
- end
+ end if defined?(CGI::Escape)
end
def teardown
@@ -271,9 +296,11 @@ class CGIUtilPureRubyTest < Test::Unit::TestCase
remove_method :_escapeHTML
alias unescapeHTML _unescapeHTML
remove_method :_unescapeHTML
- end
+ end if defined?(CGI::Escape)
end
+ include CGIUtilTest::UnescapeHTMLTests
+
def test_cgi_escapeHTML_with_invalid_byte_sequence
assert_equal("&lt;\xA4??&gt;", CGI.escapeHTML(%[<\xA4??>]))
end
diff --git a/test/coverage/autostart.rb b/test/coverage/autostart.rb
new file mode 100644
index 0000000000..067fe0a40d
--- /dev/null
+++ b/test/coverage/autostart.rb
@@ -0,0 +1,2 @@
+require 'coverage'
+Coverage.start(:all)
diff --git a/test/coverage/main.rb b/test/coverage/main.rb
new file mode 100644
index 0000000000..74f1e95fa3
--- /dev/null
+++ b/test/coverage/main.rb
@@ -0,0 +1 @@
+puts Coverage.peek_result[__FILE__][:lines]
diff --git a/test/coverage/test_coverage.rb b/test/coverage/test_coverage.rb
index eefe7e7da6..16be47b458 100644
--- a/test/coverage/test_coverage.rb
+++ b/test/coverage/test_coverage.rb
@@ -26,6 +26,13 @@ class TestCoverage < Test::Unit::TestCase
end;
end
+ def test_coverage_in_main_script
+ autostart_path = File.expand_path("autostart.rb", __dir__)
+ main_path = File.expand_path("main.rb", __dir__)
+
+ assert_in_out_err(['-r', autostart_path, main_path], "", ["1"], [])
+ end
+
def test_coverage_running?
assert_in_out_err(%w[-rcoverage], <<-"end;", ["false", "true", "true", "false"], [])
p Coverage.running?
@@ -136,7 +143,7 @@ class TestCoverage < Test::Unit::TestCase
f.puts 'REPEATS = 400'
f.puts 'def add_method(target)'
f.puts ' REPEATS.times do'
- f.puts ' target.class_eval(<<~RUBY, __FILE__, __LINE__ + 1)'
+ f.puts ' target.class_eval(<<~RUBY)'
f.puts ' def foo'
f.puts ' #{"\n" * rand(REPEATS)}'
f.puts ' end'
@@ -147,16 +154,42 @@ class TestCoverage < Test::Unit::TestCase
end
assert_in_out_err(%w[-W0 -rcoverage], <<-"end;", ["[1, 1, 1, 400, nil, nil, nil, nil, nil, nil, nil]"], [], bug13305)
- Coverage.start
+ Coverage.start(:all)
tmp = Dir.pwd
require tmp + '/test.rb'
add_method(Class.new)
- p Coverage.result[tmp + "/test.rb"]
+ p Coverage.result[tmp + "/test.rb"][:lines]
end;
}
}
end
+ def test_eval_coverage
+ assert_in_out_err(%w[-rcoverage], <<-"end;", ["[1, 1, 1, nil, 0, nil]"], [])
+ Coverage.start(eval: true, lines: true)
+
+ eval(<<-RUBY, TOPLEVEL_BINDING, "test.rb")
+ _out = String.new
+ if _out.empty?
+ _out << 'Hello World'
+ else
+ _out << 'Goodbye World'
+ end
+ RUBY
+
+ p Coverage.result["test.rb"][:lines]
+ end;
+ end
+
+ def test_coverage_supported
+ assert Coverage.supported?(:lines)
+ assert Coverage.supported?(:oneshot_lines)
+ assert Coverage.supported?(:branches)
+ assert Coverage.supported?(:methods)
+ assert Coverage.supported?(:eval)
+ refute Coverage.supported?(:all)
+ end
+
def test_nocoverage_optimized_line
assert_ruby_status(%w[], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
@@ -184,19 +217,19 @@ class TestCoverage < Test::Unit::TestCase
def test_coverage_ensure_if_return
result = {
:branches => {
- [:if, 0, 3, 1, 6, 4] => {
- [:then, 1, 3, 6, 3, 6] => 0,
- [:else, 2, 5, 3, 5, 9] => 1,
- },
+ [:if, 0, 3, 2, 6, 5] => {
+ [:then, 1, 3, 7, 3, 7] => 0,
+ [:else, 2, 5, 4, 5, 10] => 1,
+ },
},
}
assert_coverage(<<~"end;", { branches: true }, result)
def flush
ensure
- if $!
- else
- return
- end
+ if $!
+ else
+ return
+ end
end
flush
end;
@@ -815,9 +848,10 @@ class TestCoverage < Test::Unit::TestCase
EOS
end
- cov1 = "[0, 0, nil, nil, 0, 1, nil, nil, 0, 0, nil]"
- cov2 = "[0, 0, nil, nil, 0, 1, nil, nil, 0, 1, nil]"
- assert_in_out_err(%w[-rcoverage], <<-"end;", [cov1, cov2], [])
+ assert_separately(%w[-rcoverage], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ cov1 = [0, 0, nil, nil, 0, 1, nil, nil, 0, 0, nil]
+ cov2 = [0, 0, nil, nil, 0, 1, nil, nil, 0, 1, nil]
Coverage.setup
tmp = Dir.pwd
require tmp + "/test.rb"
@@ -826,15 +860,34 @@ class TestCoverage < Test::Unit::TestCase
bar
Coverage.suspend
baz
- p Coverage.peek_result[tmp + "/test.rb"]
+ assert_equal cov1, Coverage.peek_result[tmp + "/test.rb"]
Coverage.resume
baz
- p Coverage.result[tmp + "/test.rb"]
+ assert_equal cov2, Coverage.result[tmp + "/test.rb"]
end;
- cov1 = "{:lines=>[0, 0, nil, nil, 0, 1, nil, nil, 0, 0, nil], :branches=>{}, :methods=>{[Object, :baz, 9, 12, 11, 15]=>0, [Object, :bar, 5, 12, 7, 15]=>1, [Object, :foo, 1, 12, 3, 15]=>0}}"
- cov2 = "{:lines=>[0, 0, nil, nil, 0, 1, nil, nil, 0, 1, nil], :branches=>{}, :methods=>{[Object, :baz, 9, 12, 11, 15]=>1, [Object, :bar, 5, 12, 7, 15]=>1, [Object, :foo, 1, 12, 3, 15]=>0}}"
- assert_in_out_err(%w[-rcoverage], <<-"end;", [cov1, cov2], [])
+ assert_separately(%w[-rcoverage], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ cov1 = {
+ lines: [0, 0, nil, nil, 0, 1, nil, nil, 0, 0, nil],
+ branches: {},
+ methods: {
+ [Object, :baz, 9, 12, 11, 15]=>0,
+ [Object, :bar, 5, 12, 7, 15]=>1,
+ [Object, :foo, 1, 12, 3, 15]=>0,
+ }
+ }
+
+ cov2 = {
+ lines: [0, 0, nil, nil, 0, 1, nil, nil, 0, 1, nil],
+ branches: {},
+ methods: {
+ [Object, :baz, 9, 12, 11, 15]=>1,
+ [Object, :bar, 5, 12, 7, 15]=>1,
+ [Object, :foo, 1, 12, 3, 15]=>0,
+ }
+ }
+
Coverage.setup(:all)
tmp = Dir.pwd
require tmp + "/test.rb"
@@ -843,15 +896,16 @@ class TestCoverage < Test::Unit::TestCase
bar
Coverage.suspend
baz
- p Coverage.peek_result[tmp + "/test.rb"]
+ assert_equal cov1, Coverage.peek_result[tmp + "/test.rb"]
Coverage.resume
baz
- p Coverage.result[tmp + "/test.rb"]
+ assert_equal cov2, Coverage.result[tmp + "/test.rb"]
end;
- cov1 = "{:oneshot_lines=>[6]}"
- cov2 = "{:oneshot_lines=>[6, 10]}"
- assert_in_out_err(%w[-rcoverage], <<-"end;", [cov1, cov2], [])
+ assert_separately(%w[-rcoverage], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ cov1 = {:oneshot_lines=>[6]}
+ cov2 = {:oneshot_lines=>[6, 10]}
Coverage.setup(oneshot_lines: true)
tmp = Dir.pwd
require tmp + "/test.rb"
@@ -860,10 +914,10 @@ class TestCoverage < Test::Unit::TestCase
bar
Coverage.suspend
baz
- p Coverage.peek_result[tmp + "/test.rb"]
+ assert_equal cov1, Coverage.peek_result[tmp + "/test.rb"]
Coverage.resume
baz
- p Coverage.result[tmp + "/test.rb"]
+ assert_equal cov2, Coverage.result[tmp + "/test.rb"]
end;
}
}
@@ -941,4 +995,18 @@ class TestCoverage < Test::Unit::TestCase
p :NG
end;
end
+
+ def test_tag_break_with_branch_coverage
+ result = {
+ :branches => {
+ [:"&.", 0, 1, 0, 1, 6] => {
+ [:then, 1, 1, 0, 1, 6] => 1,
+ [:else, 2, 1, 0, 1, 6] => 0,
+ },
+ },
+ }
+ assert_coverage(<<~"end;", { branches: true }, result)
+ 1&.tap do break end
+ end;
+ end
end
diff --git a/test/csv/helper.rb b/test/csv/helper.rb
deleted file mode 100644
index 1f9cf96979..0000000000
--- a/test/csv/helper.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-require "tempfile"
-require "test/unit"
-
-require "csv"
-
-require_relative "../lib/with_different_ofs"
-
-module Helper
- def with_chunk_size(chunk_size)
- chunk_size_keep = ENV["CSV_PARSER_SCANNER_TEST_CHUNK_SIZE"]
- begin
- ENV["CSV_PARSER_SCANNER_TEST_CHUNK_SIZE"] = chunk_size
- yield
- ensure
- ENV["CSV_PARSER_SCANNER_TEST_CHUNK_SIZE"] = chunk_size_keep
- end
- end
-
- def with_verbose(verbose)
- original = $VERBOSE
- begin
- $VERBOSE = verbose
- yield
- ensure
- $VERBOSE = original
- end
- end
-
- def with_default_internal(encoding)
- original = Encoding.default_internal
- begin
- with_verbose(false) do
- Encoding.default_internal = encoding
- end
- yield
- ensure
- with_verbose(false) do
- Encoding.default_internal = original
- end
- end
- end
-end
diff --git a/test/csv/interface/test_delegation.rb b/test/csv/interface/test_delegation.rb
deleted file mode 100644
index 349257633b..0000000000
--- a/test/csv/interface/test_delegation.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVInterfaceDelegation < Test::Unit::TestCase
- class TestStringIO < self
- def setup
- @csv = CSV.new("h1,h2")
- end
-
- def test_flock
- assert_raise(NotImplementedError) do
- @csv.flock(File::LOCK_EX)
- end
- end
-
- def test_ioctl
- assert_raise(NotImplementedError) do
- @csv.ioctl(0)
- end
- end
-
- def test_stat
- assert_raise(NotImplementedError) do
- @csv.stat
- end
- end
-
- def test_to_i
- assert_raise(NotImplementedError) do
- @csv.to_i
- end
- end
-
- def test_binmode?
- assert_equal(false, @csv.binmode?)
- end
-
- def test_path
- assert_equal(nil, @csv.path)
- end
-
- def test_to_io
- assert_instance_of(StringIO, @csv.to_io)
- end
- end
-end
diff --git a/test/csv/interface/test_read.rb b/test/csv/interface/test_read.rb
deleted file mode 100644
index d73622d554..0000000000
--- a/test/csv/interface/test_read.rb
+++ /dev/null
@@ -1,371 +0,0 @@
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVInterfaceRead < Test::Unit::TestCase
- extend DifferentOFS
-
- def setup
- super
- @data = ""
- @data << "1\t2\t3\r\n"
- @data << "4\t5\r\n"
- @input = Tempfile.new(["interface-read", ".csv"], binmode: true)
- @input << @data
- @input.rewind
- @rows = [
- ["1", "2", "3"],
- ["4", "5"],
- ]
- end
-
- def teardown
- @input.close(true)
- super
- end
-
- def test_foreach
- rows = []
- CSV.foreach(@input.path, col_sep: "\t", row_sep: "\r\n").each do |row|
- rows << row
- end
- assert_equal(@rows, rows)
- end
-
- if respond_to?(:ractor)
- ractor
- def test_foreach_in_ractor
- ractor = Ractor.new(@input.path) do |path|
- rows = []
- CSV.foreach(path, col_sep: "\t", row_sep: "\r\n").each do |row|
- rows << row
- end
- rows
- end
- rows = [
- ["1", "2", "3"],
- ["4", "5"],
- ]
- assert_equal(rows, ractor.take)
- end
- end
-
- def test_foreach_mode
- rows = []
- CSV.foreach(@input.path, "r", col_sep: "\t", row_sep: "\r\n").each do |row|
- rows << row
- end
- assert_equal(@rows, rows)
- end
-
- def test_foreach_enumurator
- rows = CSV.foreach(@input.path, col_sep: "\t", row_sep: "\r\n").to_a
- assert_equal(@rows, rows)
- end
-
- def test_closed?
- csv = CSV.open(@input.path, "r+", col_sep: "\t", row_sep: "\r\n")
- assert_not_predicate(csv, :closed?)
- csv.close
- assert_predicate(csv, :closed?)
- end
-
- def test_open_auto_close
- csv = nil
- CSV.open(@input.path) do |_csv|
- csv = _csv
- end
- assert_predicate(csv, :closed?)
- end
-
- def test_open_closed
- csv = nil
- CSV.open(@input.path) do |_csv|
- csv = _csv
- csv.close
- end
- assert_predicate(csv, :closed?)
- end
-
- def test_open_block_return_value
- return_value = CSV.open(@input.path) do
- "Return value."
- end
- assert_equal("Return value.", return_value)
- end
-
- def test_open_encoding_valid
- # U+1F600 GRINNING FACE
- # U+1F601 GRINNING FACE WITH SMILING EYES
- File.open(@input.path, "w") do |file|
- file << "\u{1F600},\u{1F601}"
- end
- CSV.open(@input.path, encoding: "utf-8") do |csv|
- assert_equal([["\u{1F600}", "\u{1F601}"]],
- csv.to_a)
- end
- end
-
- def test_open_encoding_invalid
- # U+1F600 GRINNING FACE
- # U+1F601 GRINNING FACE WITH SMILING EYES
- File.open(@input.path, "w") do |file|
- file << "\u{1F600},\u{1F601}"
- end
- CSV.open(@input.path, encoding: "EUC-JP") do |csv|
- error = assert_raise(CSV::MalformedCSVError) do
- csv.shift
- end
- assert_equal("Invalid byte sequence in EUC-JP in line 1.",
- error.message)
- end
- end
-
- def test_open_encoding_nonexistent
- _output, error = capture_output do
- CSV.open(@input.path, encoding: "nonexistent") do
- end
- end
- assert_equal("path:0: warning: Unsupported encoding nonexistent ignored\n",
- error.gsub(/\A.+:\d+: /, "path:0: "))
- end
-
- def test_open_encoding_utf_8_with_bom
- # U+FEFF ZERO WIDTH NO-BREAK SPACE, BOM
- # U+1F600 GRINNING FACE
- # U+1F601 GRINNING FACE WITH SMILING EYES
- File.open(@input.path, "w") do |file|
- file << "\u{FEFF}\u{1F600},\u{1F601}"
- end
- CSV.open(@input.path, encoding: "bom|utf-8") do |csv|
- assert_equal([["\u{1F600}", "\u{1F601}"]],
- csv.to_a)
- end
- end
-
- def test_open_invalid_byte_sequence_in_utf_8
- CSV.open(@input.path, "w", encoding: Encoding::CP932) do |rows|
- error = assert_raise(Encoding::InvalidByteSequenceError) do
- rows << ["\x82\xa0"]
- end
- assert_equal('"\x82" on UTF-8',
- error.message)
- end
- end
-
- def test_open_with_invalid_nil
- CSV.open(@input.path, "w", encoding: Encoding::CP932, invalid: nil) do |rows|
- error = assert_raise(Encoding::InvalidByteSequenceError) do
- rows << ["\x82\xa0"]
- end
- assert_equal('"\x82" on UTF-8',
- error.message)
- end
- end
-
- def test_open_with_invalid_replace
- CSV.open(@input.path, "w", encoding: Encoding::CP932, invalid: :replace) do |rows|
- rows << ["\x82\xa0".force_encoding(Encoding::UTF_8)]
- end
- CSV.open(@input.path, encoding: Encoding::CP932) do |csv|
- assert_equal([["??"]],
- csv.to_a)
- end
- end
-
- def test_open_with_invalid_replace_and_replace_string
- CSV.open(@input.path, "w", encoding: Encoding::CP932, invalid: :replace, replace: "X") do |rows|
- rows << ["\x82\xa0".force_encoding(Encoding::UTF_8)]
- end
- CSV.open(@input.path, encoding: Encoding::CP932) do |csv|
- assert_equal([["XX"]],
- csv.to_a)
- end
- end
-
- def test_open_with_undef_replace
- # U+00B7 Middle Dot
- CSV.open(@input.path, "w", encoding: Encoding::CP932, undef: :replace) do |rows|
- rows << ["\u00B7"]
- end
- CSV.open(@input.path, encoding: Encoding::CP932) do |csv|
- assert_equal([["?"]],
- csv.to_a)
- end
- end
-
- def test_open_with_undef_replace_and_replace_string
- # U+00B7 Middle Dot
- CSV.open(@input.path, "w", encoding: Encoding::CP932, undef: :replace, replace: "X") do |rows|
- rows << ["\u00B7"]
- end
- CSV.open(@input.path, encoding: Encoding::CP932) do |csv|
- assert_equal([["X"]],
- csv.to_a)
- end
- end
-
- def test_parse
- assert_equal(@rows,
- CSV.parse(@data, col_sep: "\t", row_sep: "\r\n"))
- end
-
- def test_parse_block
- rows = []
- CSV.parse(@data, col_sep: "\t", row_sep: "\r\n") do |row|
- rows << row
- end
- assert_equal(@rows, rows)
- end
-
- def test_parse_enumerator
- rows = CSV.parse(@data, col_sep: "\t", row_sep: "\r\n").to_a
- assert_equal(@rows, rows)
- end
-
- def test_parse_headers_only
- table = CSV.parse("a,b,c", headers: true)
- assert_equal([
- ["a", "b", "c"],
- [],
- ],
- [
- table.headers,
- table.each.to_a,
- ])
- end
-
- def test_parse_line
- assert_equal(["1", "2", "3"],
- CSV.parse_line("1;2;3", col_sep: ";"))
- end
-
- def test_parse_line_shortcut
- assert_equal(["1", "2", "3"],
- "1;2;3".parse_csv(col_sep: ";"))
- end
-
- def test_parse_line_empty
- assert_equal(nil, CSV.parse_line("")) # to signal eof
- end
-
- def test_parse_line_empty_line
- assert_equal([], CSV.parse_line("\n1,2,3"))
- end
-
- def test_read
- assert_equal(@rows,
- CSV.read(@input.path, col_sep: "\t", row_sep: "\r\n"))
- end
-
- if respond_to?(:ractor)
- ractor
- def test_read_in_ractor
- ractor = Ractor.new(@input.path) do |path|
- CSV.read(path, col_sep: "\t", row_sep: "\r\n")
- end
- rows = [
- ["1", "2", "3"],
- ["4", "5"],
- ]
- assert_equal(rows, ractor.take)
- end
- end
-
- def test_readlines
- assert_equal(@rows,
- CSV.readlines(@input.path, col_sep: "\t", row_sep: "\r\n"))
- end
-
- def test_open_read
- rows = CSV.open(@input.path, col_sep: "\t", row_sep: "\r\n") do |csv|
- csv.read
- end
- assert_equal(@rows, rows)
- end
-
- def test_open_readlines
- rows = CSV.open(@input.path, col_sep: "\t", row_sep: "\r\n") do |csv|
- csv.readlines
- end
- assert_equal(@rows, rows)
- end
-
- def test_table
- table = CSV.table(@input.path, col_sep: "\t", row_sep: "\r\n")
- assert_equal(CSV::Table.new([
- CSV::Row.new([:"1", :"2", :"3"], [4, 5, nil]),
- ]),
- table)
- end
-
- def test_shift # aliased as gets() and readline()
- CSV.open(@input.path, "rb+", col_sep: "\t", row_sep: "\r\n") do |csv|
- rows = [
- csv.shift,
- csv.shift,
- csv.shift,
- ]
- assert_equal(@rows + [nil],
- rows)
- end
- end
-
- def test_enumerator
- CSV.open(@input.path, col_sep: "\t", row_sep: "\r\n") do |csv|
- assert_equal(@rows, csv.each.to_a)
- end
- end
-
- def test_shift_and_each
- CSV.open(@input.path, col_sep: "\t", row_sep: "\r\n") do |csv|
- rows = []
- rows << csv.shift
- rows.concat(csv.each.to_a)
- assert_equal(@rows, rows)
- end
- end
-
- def test_each_twice
- CSV.open(@input.path, col_sep: "\t", row_sep: "\r\n") do |csv|
- assert_equal([
- @rows,
- [],
- ],
- [
- csv.each.to_a,
- csv.each.to_a,
- ])
- end
- end
-
- def test_eof?
- eofs = []
- CSV.open(@input.path, col_sep: "\t", row_sep: "\r\n") do |csv|
- eofs << csv.eof?
- csv.shift
- eofs << csv.eof?
- csv.shift
- eofs << csv.eof?
- end
- assert_equal([false, false, true],
- eofs)
- end
-
- def test_new_nil
- assert_raise_with_message ArgumentError, "Cannot parse nil as CSV" do
- CSV.new(nil)
- end
- end
-
- def test_options_not_modified
- options = {}.freeze
- CSV.foreach(@input.path, **options)
- CSV.open(@input.path, **options) {}
- CSV.parse("", **options)
- CSV.parse_line("", **options)
- CSV.read(@input.path, **options)
- CSV.readlines(@input.path, **options)
- CSV.table(@input.path, **options)
- end
-end
diff --git a/test/csv/interface/test_read_write.rb b/test/csv/interface/test_read_write.rb
deleted file mode 100644
index c371e9c5fc..0000000000
--- a/test/csv/interface/test_read_write.rb
+++ /dev/null
@@ -1,124 +0,0 @@
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVInterfaceReadWrite < Test::Unit::TestCase
- extend DifferentOFS
-
- def test_filter
- input = <<-CSV.freeze
-1;2;3
-4;5
- CSV
- output = ""
- CSV.filter(input, output,
- in_col_sep: ";",
- out_col_sep: ",",
- converters: :all) do |row|
- row.map! {|n| n * 2}
- row << "Added\r"
- end
- assert_equal(<<-CSV, output)
-2,4,6,"Added\r"
-8,10,"Added\r"
- CSV
- end
-
- def test_filter_headers_true
- input = <<-CSV.freeze
-Name,Value
-foo,0
-bar,1
-baz,2
- CSV
- output = ""
- CSV.filter(input, output, headers: true) do |row|
- row[0] += "X"
- row[1] = row[1].to_i + 1
- end
- assert_equal(<<-CSV, output)
-fooX,1
-barX,2
-bazX,3
- CSV
- end
-
- def test_filter_headers_true_write_headers
- input = <<-CSV.freeze
-Name,Value
-foo,0
-bar,1
-baz,2
- CSV
- output = ""
- CSV.filter(input, output, headers: true, out_write_headers: true) do |row|
- if row.is_a?(Array)
- row[0] += "X"
- row[1] += "Y"
- else
- row[0] += "X"
- row[1] = row[1].to_i + 1
- end
- end
- assert_equal(<<-CSV, output)
-NameX,ValueY
-fooX,1
-barX,2
-bazX,3
- CSV
- end
-
- def test_filter_headers_array_write_headers
- input = <<-CSV.freeze
-foo,0
-bar,1
-baz,2
- CSV
- output = ""
- CSV.filter(input, output,
- headers: ["Name", "Value"],
- out_write_headers: true) do |row|
- row[0] += "X"
- row[1] = row[1].to_i + 1
- end
- assert_equal(<<-CSV, output)
-Name,Value
-fooX,1
-barX,2
-bazX,3
- CSV
- end
-
- def test_instance_same
- data = ""
- assert_equal(CSV.instance(data, col_sep: ";").object_id,
- CSV.instance(data, col_sep: ";").object_id)
- end
-
- def test_instance_append
- output = ""
- CSV.instance(output, col_sep: ";") << ["a", "b", "c"]
- assert_equal(<<-CSV, output)
-a;b;c
- CSV
- CSV.instance(output, col_sep: ";") << [1, 2, 3]
- assert_equal(<<-CSV, output)
-a;b;c
-1;2;3
- CSV
- end
-
- def test_instance_shortcut
- assert_equal(CSV.instance,
- CSV {|csv| csv})
- end
-
- def test_instance_shortcut_with_io
- io = StringIO.new
- from_instance = CSV.instance(io, col_sep: ";") { |csv| csv << ["a", "b", "c"] }
- from_shortcut = CSV(io, col_sep: ";") { |csv| csv << ["e", "f", "g"] }
-
- assert_equal(from_instance, from_shortcut)
- assert_equal(from_instance.string, "a;b;c\ne;f;g\n")
- end
-end
diff --git a/test/csv/interface/test_write.rb b/test/csv/interface/test_write.rb
deleted file mode 100644
index 02c2c5c5ce..0000000000
--- a/test/csv/interface/test_write.rb
+++ /dev/null
@@ -1,208 +0,0 @@
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVInterfaceWrite < Test::Unit::TestCase
- extend DifferentOFS
-
- def setup
- super
- @output = Tempfile.new(["interface-write", ".csv"])
- end
-
- def teardown
- @output.close(true)
- super
- end
-
- def test_generate_default
- csv_text = CSV.generate do |csv|
- csv << [1, 2, 3] << [4, nil, 5]
- end
- assert_equal(<<-CSV, csv_text)
-1,2,3
-4,,5
- CSV
- end
-
- if respond_to?(:ractor)
- ractor
- def test_generate_default_in_ractor
- ractor = Ractor.new do
- CSV.generate do |csv|
- csv << [1, 2, 3] << [4, nil, 5]
- end
- end
- assert_equal(<<-CSV, ractor.take)
-1,2,3
-4,,5
- CSV
- end
- end
-
- def test_generate_append
- csv_text = <<-CSV
-1,2,3
-4,,5
- CSV
- CSV.generate(csv_text) do |csv|
- csv << ["last", %Q{"row"}]
- end
- assert_equal(<<-CSV, csv_text)
-1,2,3
-4,,5
-last,"""row"""
- CSV
- end
-
- def test_generate_no_new_line
- csv_text = CSV.generate("test") do |csv|
- csv << ["row"]
- end
- assert_equal(<<-CSV, csv_text)
-testrow
- CSV
- end
-
- def test_generate_line_col_sep
- line = CSV.generate_line(["1", "2", "3"], col_sep: ";")
- assert_equal(<<-LINE, line)
-1;2;3
- LINE
- end
-
- def test_generate_line_row_sep
- line = CSV.generate_line(["1", "2"], row_sep: nil)
- assert_equal(<<-LINE.chomp, line)
-1,2
- LINE
- end
-
- def test_generate_line_shortcut
- line = ["1", "2", "3"].to_csv(col_sep: ";")
- assert_equal(<<-LINE, line)
-1;2;3
- LINE
- end
-
- def test_headers_detection
- headers = ["a", "b", "c"]
- CSV.open(@output.path, "w", headers: true) do |csv|
- csv << headers
- csv << ["1", "2", "3"]
- assert_equal(headers, csv.headers)
- end
- end
-
- def test_lineno
- CSV.open(@output.path, "w") do |csv|
- n_lines = 20
- n_lines.times do
- csv << ["a", "b", "c"]
- end
- assert_equal(n_lines, csv.lineno)
- end
- end
-
- def test_append_row
- CSV.open(@output.path, "wb") do |csv|
- csv <<
- CSV::Row.new([], ["1", "2", "3"]) <<
- CSV::Row.new([], ["a", "b", "c"])
- end
- assert_equal(<<-CSV, File.read(@output.path, mode: "rb"))
-1,2,3
-a,b,c
- CSV
- end
-
-
- if respond_to?(:ractor)
- ractor
- def test_append_row_in_ractor
- ractor = Ractor.new(@output.path) do |path|
- CSV.open(path, "wb") do |csv|
- csv <<
- CSV::Row.new([], ["1", "2", "3"]) <<
- CSV::Row.new([], ["a", "b", "c"])
- end
- end
- ractor.take
- assert_equal(<<-CSV, File.read(@output.path, mode: "rb"))
-1,2,3
-a,b,c
- CSV
- end
- end
-
- def test_append_hash
- CSV.open(@output.path, "wb", headers: true) do |csv|
- csv << [:a, :b, :c]
- csv << {a: 1, b: 2, c: 3}
- csv << {a: 4, b: 5, c: 6}
- end
- assert_equal(<<-CSV, File.read(@output.path, mode: "rb"))
-a,b,c
-1,2,3
-4,5,6
- CSV
- end
-
- def test_append_hash_headers_array
- CSV.open(@output.path, "wb", headers: [:b, :a, :c]) do |csv|
- csv << {a: 1, b: 2, c: 3}
- csv << {a: 4, b: 5, c: 6}
- end
- assert_equal(<<-CSV, File.read(@output.path, mode: "rb"))
-2,1,3
-5,4,6
- CSV
- end
-
- def test_append_hash_headers_string
- CSV.open(@output.path, "wb", headers: "b|a|c", col_sep: "|") do |csv|
- csv << {"a" => 1, "b" => 2, "c" => 3}
- csv << {"a" => 4, "b" => 5, "c" => 6}
- end
- assert_equal(<<-CSV, File.read(@output.path, mode: "rb"))
-2|1|3
-5|4|6
- CSV
- end
-
- def test_write_headers
- CSV.open(@output.path,
- "wb",
- headers: "b|a|c",
- write_headers: true,
- col_sep: "|" ) do |csv|
- csv << {"a" => 1, "b" => 2, "c" => 3}
- csv << {"a" => 4, "b" => 5, "c" => 6}
- end
- assert_equal(<<-CSV, File.read(@output.path, mode: "rb"))
-b|a|c
-2|1|3
-5|4|6
- CSV
- end
-
- def test_write_headers_empty
- CSV.open(@output.path,
- "wb",
- headers: "b|a|c",
- write_headers: true,
- col_sep: "|" ) do |csv|
- end
- assert_equal(<<-CSV, File.read(@output.path, mode: "rb"))
-b|a|c
- CSV
- end
-
- def test_options_not_modified
- options = {}.freeze
- CSV.generate(**options) {}
- CSV.generate_line([], **options)
- CSV.filter("", "", **options)
- CSV.instance("", **options)
- end
-end
diff --git a/test/csv/line_endings.gz b/test/csv/line_endings.gz
deleted file mode 100644
index 39e1729ee4..0000000000
--- a/test/csv/line_endings.gz
+++ /dev/null
Binary files differ
diff --git a/test/csv/parse/test_column_separator.rb b/test/csv/parse/test_column_separator.rb
deleted file mode 100644
index d6eaa7b6de..0000000000
--- a/test/csv/parse/test_column_separator.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseColumnSeparator < Test::Unit::TestCase
- extend DifferentOFS
-
- def test_comma
- assert_equal([["a", "b", nil, "d"]],
- CSV.parse("a,b,,d", col_sep: ","))
- end
-
- def test_space
- assert_equal([["a", "b", nil, "d"]],
- CSV.parse("a b d", col_sep: " "))
- end
-
- def test_tab
- assert_equal([["a", "b", nil, "d"]],
- CSV.parse("a\tb\t\td", col_sep: "\t"))
- end
-
- def test_multiple_characters_include_sub_separator
- assert_equal([["a b", nil, "d"]],
- CSV.parse("a b d", col_sep: " "))
- end
-
- def test_multiple_characters_leading_empty_fields
- data = <<-CSV
-<=><=>A<=>B<=>C
-1<=>2<=>3
- CSV
- assert_equal([
- [nil, nil, "A", "B", "C"],
- ["1", "2", "3"],
- ],
- CSV.parse(data, col_sep: "<=>"))
- end
-end
diff --git a/test/csv/parse/test_convert.rb b/test/csv/parse/test_convert.rb
deleted file mode 100644
index 21d9f20b28..0000000000
--- a/test/csv/parse/test_convert.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseConvert < Test::Unit::TestCase
- extend DifferentOFS
-
- def setup
- super
- @data = "Numbers,:integer,1,:float,3.015"
- @parser = CSV.new(@data)
-
- @custom = lambda {|field| /\A:(\S.*?)\s*\Z/ =~ field ? $1.to_sym : field}
-
- @time = Time.utc(2018, 12, 30, 6, 41, 29)
- @windows_safe_time_data = @time.strftime("%a %b %d %H:%M:%S %Y")
- end
-
- def test_integer
- @parser.convert(:integer)
- assert_equal(["Numbers", ":integer", 1, ":float", "3.015"],
- @parser.shift)
- end
-
- def test_float
- @parser.convert(:float)
- assert_equal(["Numbers", ":integer", 1.0, ":float", 3.015],
- @parser.shift)
- end
-
- def test_float_integer
- @parser.convert(:float)
- @parser.convert(:integer)
- assert_equal(["Numbers", ":integer", 1.0, ":float", 3.015],
- @parser.shift)
- end
-
- def test_integer_float
- @parser.convert(:integer)
- @parser.convert(:float)
- assert_equal(["Numbers", ":integer", 1, ":float", 3.015],
- @parser.shift)
- end
-
- def test_numeric
- @parser.convert(:numeric)
- assert_equal(["Numbers", ":integer", 1, ":float", 3.015],
- @parser.shift)
- end
-
- def test_all
- @data << ",#{@windows_safe_time_data}"
- @parser = CSV.new(@data)
- @parser.convert(:all)
- assert_equal(["Numbers", ":integer", 1, ":float", 3.015, @time.to_datetime],
- @parser.shift)
- end
-
- def test_custom
- @parser.convert do |field|
- /\A:(\S.*?)\s*\Z/ =~ field ? $1.to_sym : field
- end
- assert_equal(["Numbers", :integer, "1", :float, "3.015"],
- @parser.shift)
- end
-
- def test_builtin_custom
- @parser.convert(:numeric)
- @parser.convert(&@custom)
- assert_equal(["Numbers", :integer, 1, :float, 3.015],
- @parser.shift)
- end
-
- def test_custom_field_info_line
- @parser.convert do |field, info|
- assert_equal(1, info.line)
- info.index == 4 ? Float(field).floor : field
- end
- assert_equal(["Numbers", ":integer", "1", ":float", 3],
- @parser.shift)
- end
-
- def test_custom_field_info_header
- headers = ["one", "two", "three", "four", "five"]
- @parser = CSV.new(@data, headers: headers)
- @parser.convert do |field, info|
- info.header == "three" ? Integer(field) * 100 : field
- end
- assert_equal(CSV::Row.new(headers,
- ["Numbers", ":integer", 100, ":float", "3.015"]),
- @parser.shift)
- end
-
- def test_custom_blank_field
- converter = lambda {|field| field.nil?}
- row = CSV.parse_line('nil,', converters: converter)
- assert_equal([false, true], row)
- end
-
- def test_nil_value
- assert_equal(["nil", "", "a"],
- CSV.parse_line(',"",a', nil_value: "nil"))
- end
-
- def test_empty_value
- assert_equal([nil, "empty", "a"],
- CSV.parse_line(',"",a', empty_value: "empty"))
- end
-end
diff --git a/test/csv/parse/test_each.rb b/test/csv/parse/test_each.rb
deleted file mode 100644
index ce0b71d058..0000000000
--- a/test/csv/parse/test_each.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseEach < Test::Unit::TestCase
- extend DifferentOFS
-
- def test_twice
- data = <<-CSV
-Ruby,2.6.0,script
- CSV
- csv = CSV.new(data)
- assert_equal([
- [["Ruby", "2.6.0", "script"]],
- [],
- ],
- [
- csv.to_a,
- csv.to_a,
- ])
- end
-end
diff --git a/test/csv/parse/test_general.rb b/test/csv/parse/test_general.rb
deleted file mode 100644
index d2b74008eb..0000000000
--- a/test/csv/parse/test_general.rb
+++ /dev/null
@@ -1,259 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require "timeout"
-
-require_relative "../helper"
-
-#
-# Following tests are my interpretation of the
-# {CSV RCF}[http://www.ietf.org/rfc/rfc4180.txt]. I only deviate from that
-# document in one place (intentionally) and that is to make the default row
-# separator <tt>$/</tt>.
-#
-class TestCSVParseGeneral < Test::Unit::TestCase
- extend DifferentOFS
-
- BIG_DATA = "123456789\n" * 512
-
- def test_mastering_regex_example
- ex = %Q{Ten Thousand,10000, 2710 ,,"10,000","It's ""10 Grand"", baby",10K}
- assert_equal( [ "Ten Thousand", "10000", " 2710 ", nil, "10,000",
- "It's \"10 Grand\", baby", "10K" ],
- CSV.parse_line(ex) )
- end
-
- # Old Ruby 1.8 CSV library tests.
- def test_std_lib_csv
- [ ["\t", ["\t"]],
- ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
- ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
- ["\"\"\"\n\",\"\"\"\n\"", ["\"\n", "\"\n"]],
- ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
- ["\"\"", [""]],
- ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
- ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
- ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
- ["foo,\"\",baz", ["foo", "", "baz"]],
- ["\",\"", [","]],
- ["foo", ["foo"]],
- [",,", [nil, nil, nil]],
- [",", [nil, nil]],
- ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
- ["foo,,baz", ["foo", nil, "baz"]],
- ["\"\"\"\r\",\"\"\"\r\"", ["\"\r", "\"\r"]],
- ["\",\",\",\"", [",", ","]],
- ["foo,bar,", ["foo", "bar", nil]],
- [",foo,bar", [nil, "foo", "bar"]],
- ["foo,bar", ["foo", "bar"]],
- [";", [";"]],
- ["\t,\t", ["\t", "\t"]],
- ["foo,\"\r\n\r\",baz", ["foo", "\r\n\r", "baz"]],
- ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
- ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]],
- [";,;", [";", ";"]] ].each do |csv_test|
- assert_equal(csv_test.last, CSV.parse_line(csv_test.first))
- end
-
- [ ["foo,\"\"\"\"\"\",baz", ["foo", "\"\"", "baz"]],
- ["foo,\"\"\"bar\"\"\",baz", ["foo", "\"bar\"", "baz"]],
- ["foo,\"\r\n\",baz", ["foo", "\r\n", "baz"]],
- ["\"\"", [""]],
- ["foo,\"\"\"\",baz", ["foo", "\"", "baz"]],
- ["foo,\"\r.\n\",baz", ["foo", "\r.\n", "baz"]],
- ["foo,\"\r\",baz", ["foo", "\r", "baz"]],
- ["foo,\"\",baz", ["foo", "", "baz"]],
- ["foo", ["foo"]],
- [",,", [nil, nil, nil]],
- [",", [nil, nil]],
- ["foo,\"\n\",baz", ["foo", "\n", "baz"]],
- ["foo,,baz", ["foo", nil, "baz"]],
- ["foo,bar", ["foo", "bar"]],
- ["foo,\"\r\n\n\",baz", ["foo", "\r\n\n", "baz"]],
- ["foo,\"foo,bar\",baz", ["foo", "foo,bar", "baz"]] ].each do |csv_test|
- assert_equal(csv_test.last, CSV.parse_line(csv_test.first))
- end
- end
-
- # From: http://ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-core/6496
- def test_aras_edge_cases
- [ [%Q{a,b}, ["a", "b"]],
- [%Q{a,"""b"""}, ["a", "\"b\""]],
- [%Q{a,"""b"}, ["a", "\"b"]],
- [%Q{a,"b"""}, ["a", "b\""]],
- [%Q{a,"\nb"""}, ["a", "\nb\""]],
- [%Q{a,"""\nb"}, ["a", "\"\nb"]],
- [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
- [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
- [%Q{a,,,}, ["a", nil, nil, nil]],
- [%Q{,}, [nil, nil]],
- [%Q{"",""}, ["", ""]],
- [%Q{""""}, ["\""]],
- [%Q{"""",""}, ["\"",""]],
- [%Q{,""}, [nil,""]],
- [%Q{,"\r"}, [nil,"\r"]],
- [%Q{"\r\n,"}, ["\r\n,"]],
- [%Q{"\r\n,",}, ["\r\n,", nil]] ].each do |edge_case|
- assert_equal(edge_case.last, CSV.parse_line(edge_case.first))
- end
- end
-
- def test_james_edge_cases
- # A read at eof? should return nil.
- assert_equal(nil, CSV.parse_line(""))
- #
- # With Ruby 1.8 CSV it's impossible to tell an empty line from a line
- # containing a single +nil+ field. The old CSV library returns
- # <tt>[nil]</tt> in these cases, but <tt>Array.new</tt> makes more sense to
- # me.
- #
- assert_equal(Array.new, CSV.parse_line("\n1,2,3\n"))
- end
-
- def test_rob_edge_cases
- [ [%Q{"a\nb"}, ["a\nb"]],
- [%Q{"\n\n\n"}, ["\n\n\n"]],
- [%Q{a,"b\n\nc"}, ['a', "b\n\nc"]],
- [%Q{,"\r\n"}, [nil,"\r\n"]],
- [%Q{,"\r\n."}, [nil,"\r\n."]],
- [%Q{"a\na","one newline"}, ["a\na", 'one newline']],
- [%Q{"a\n\na","two newlines"}, ["a\n\na", 'two newlines']],
- [%Q{"a\r\na","one CRLF"}, ["a\r\na", 'one CRLF']],
- [%Q{"a\r\n\r\na","two CRLFs"}, ["a\r\n\r\na", 'two CRLFs']],
- [%Q{with blank,"start\n\nfinish"\n}, ['with blank', "start\n\nfinish"]],
- ].each do |edge_case|
- assert_equal(edge_case.last, CSV.parse_line(edge_case.first))
- end
- end
-
- def test_non_regex_edge_cases
- # An early version of the non-regex parser fails this test
- [ [ "foo,\"foo,bar,baz,foo\",\"foo\"",
- ["foo", "foo,bar,baz,foo", "foo"] ] ].each do |edge_case|
- assert_equal(edge_case.last, CSV.parse_line(edge_case.first))
- end
-
- assert_raise(CSV::MalformedCSVError) do
- CSV.parse_line("1,\"23\"4\"5\", 6")
- end
- end
-
- def test_malformed_csv_cr_first_line
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse_line("1,2\r,3", row_sep: "\n")
- end
- assert_equal("Unquoted fields do not allow new line <\"\\r\"> in line 1.",
- error.message)
- end
-
- def test_malformed_csv_cr_middle_line
- csv = <<-CSV
-line,1,abc
-line,2,"def\nghi"
-
-line,4,some\rjunk
-line,5,jkl
- CSV
-
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse(csv)
- end
- assert_equal("Unquoted fields do not allow new line <\"\\r\"> in line 4.",
- error.message)
- end
-
- def test_malformed_csv_unclosed_quote
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse_line('1,2,"3...')
- end
- assert_equal("Unclosed quoted field in line 1.",
- error.message)
- end
-
- def test_malformed_csv_illegal_quote_middle_line
- csv = <<-CSV
-line,1,abc
-line,2,"def\nghi"
-
-line,4,8'10"
-line,5,jkl
- CSV
-
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse(csv)
- end
- assert_equal("Illegal quoting in line 4.",
- error.message)
- end
-
- def test_the_parse_fails_fast_when_it_can_for_unquoted_fields
- assert_parse_errors_out('valid,fields,bad start"' + BIG_DATA)
- end
-
- def test_the_parse_fails_fast_when_it_can_for_unescaped_quotes
- assert_parse_errors_out('valid,fields,"bad start"unescaped' + BIG_DATA)
- end
-
- def test_field_size_limit_controls_lookahead
- assert_parse_errors_out( 'valid,fields,"' + BIG_DATA + '"',
- field_size_limit: 2048 )
- end
-
- def test_field_size_limit_in_extended_column_not_exceeding
- data = <<~DATA
- "a","b"
- "
- 2
- ",""
- DATA
- assert_nothing_raised(CSV::MalformedCSVError) do
- CSV.parse(data, field_size_limit: 4)
- end
- end
-
- def test_field_size_limit_in_extended_column_exceeding
- data = <<~DATA
- "a","b"
- "
- 2345
- ",""
- DATA
- assert_parse_errors_out(data, field_size_limit: 5)
- end
-
- def test_row_sep_auto_cr
- assert_equal([["a"]], CSV.parse("a\r"))
- end
-
- def test_row_sep_auto_lf
- assert_equal([["a"]], CSV.parse("a\n"))
- end
-
- def test_row_sep_auto_cr_lf
- assert_equal([["a"]], CSV.parse("a\r\n"))
- end
-
- def test_seeked_string_io
- input_with_bom = StringIO.new("\ufeffあ,い,う\r\na,b,c\r\n")
- input_with_bom.read(3)
- assert_equal([
- ["あ", "い", "う"],
- ["a", "b", "c"],
- ],
- CSV.new(input_with_bom).each.to_a)
- end
-
- private
- def assert_parse_errors_out(data, **options)
- assert_raise(CSV::MalformedCSVError) do
- timeout = 0.2
- if defined?(RubyVM::MJIT.enabled?) and RubyVM::MJIT.enabled?
- timeout = 5 # for --jit-wait
- end
- Timeout.timeout(timeout) do
- CSV.parse(data, **options)
- fail("Parse didn't error out")
- end
- end
- end
-end
diff --git a/test/csv/parse/test_header.rb b/test/csv/parse/test_header.rb
deleted file mode 100644
index 481c5107c6..0000000000
--- a/test/csv/parse/test_header.rb
+++ /dev/null
@@ -1,335 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVHeaders < Test::Unit::TestCase
- extend DifferentOFS
-
- def setup
- super
- @data = <<-CSV
-first,second,third
-A,B,C
-1,2,3
- CSV
- end
-
- def test_first_row
- [:first_row, true].each do |setting| # two names for the same setting
- # activate headers
- csv = nil
- assert_nothing_raised(Exception) do
- csv = CSV.parse(@data, headers: setting)
- end
-
- # first data row - skipping headers
- row = csv[0]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([%w{first A}, %w{second B}, %w{third C}], row.to_a)
-
- # second data row
- row = csv[1]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([%w{first 1}, %w{second 2}, %w{third 3}], row.to_a)
-
- # empty
- assert_nil(csv[2])
- end
- end
-
- def test_array_of_headers
- # activate headers
- csv = nil
- assert_nothing_raised(Exception) do
- csv = CSV.parse(@data, headers: [:my, :new, :headers])
- end
-
- # first data row - skipping headers
- row = csv[0]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal( [[:my, "first"], [:new, "second"], [:headers, "third"]],
- row.to_a )
-
- # second data row
- row = csv[1]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([[:my, "A"], [:new, "B"], [:headers, "C"]], row.to_a)
-
- # third data row
- row = csv[2]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([[:my, "1"], [:new, "2"], [:headers, "3"]], row.to_a)
-
- # empty
- assert_nil(csv[3])
-
- # with return and convert
- assert_nothing_raised(Exception) do
- csv = CSV.parse( @data, headers: [:my, :new, :headers],
- return_headers: true,
- header_converters: lambda { |h| h.to_s } )
- end
- row = csv[0]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([["my", :my], ["new", :new], ["headers", :headers]], row.to_a)
- assert_predicate(row, :header_row?)
- assert_not_predicate(row, :field_row?)
- end
-
- def test_csv_header_string
- # activate headers
- csv = nil
- assert_nothing_raised(Exception) do
- csv = CSV.parse(@data, headers: "my,new,headers")
- end
-
- # first data row - skipping headers
- row = csv[0]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([%w{my first}, %w{new second}, %w{headers third}], row.to_a)
-
- # second data row
- row = csv[1]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([%w{my A}, %w{new B}, %w{headers C}], row.to_a)
-
- # third data row
- row = csv[2]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([%w{my 1}, %w{new 2}, %w{headers 3}], row.to_a)
-
- # empty
- assert_nil(csv[3])
-
- # with return and convert
- assert_nothing_raised(Exception) do
- csv = CSV.parse( @data, headers: "my,new,headers",
- return_headers: true,
- header_converters: :symbol )
- end
- row = csv[0]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([[:my, "my"], [:new, "new"], [:headers, "headers"]], row.to_a)
- assert_predicate(row, :header_row?)
- assert_not_predicate(row, :field_row?)
- end
-
- def test_csv_header_string_inherits_separators
- # parse with custom col_sep
- csv = nil
- assert_nothing_raised(Exception) do
- csv = CSV.parse( @data.tr(",", "|"), col_sep: "|",
- headers: "my|new|headers" )
- end
-
- # verify headers were recognized
- row = csv[0]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([%w{my first}, %w{new second}, %w{headers third}], row.to_a)
- end
-
- def test_return_headers
- # activate headers and request they are returned
- csv = nil
- assert_nothing_raised(Exception) do
- csv = CSV.parse(@data, headers: true, return_headers: true)
- end
-
- # header row
- row = csv[0]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal( [%w{first first}, %w{second second}, %w{third third}],
- row.to_a )
- assert_predicate(row, :header_row?)
- assert_not_predicate(row, :field_row?)
-
- # first data row - skipping headers
- row = csv[1]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([%w{first A}, %w{second B}, %w{third C}], row.to_a)
- assert_not_predicate(row, :header_row?)
- assert_predicate(row, :field_row?)
-
- # second data row
- row = csv[2]
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([%w{first 1}, %w{second 2}, %w{third 3}], row.to_a)
- assert_not_predicate(row, :header_row?)
- assert_predicate(row, :field_row?)
-
- # empty
- assert_nil(csv[3])
- end
-
- def test_converters
- # create test data where headers and fields look alike
- data = <<-CSV
-1,2,3
-1,2,3
- CSV
-
- # normal converters do not affect headers
- csv = CSV.parse( data, headers: true,
- return_headers: true,
- converters: :numeric )
- assert_equal([%w{1 1}, %w{2 2}, %w{3 3}], csv[0].to_a)
- assert_equal([["1", 1], ["2", 2], ["3", 3]], csv[1].to_a)
- assert_nil(csv[2])
-
- # header converters do affect headers (only)
- assert_nothing_raised(Exception) do
- csv = CSV.parse( data, headers: true,
- return_headers: true,
- converters: :numeric,
- header_converters: :symbol )
- end
- assert_equal([[:"1", "1"], [:"2", "2"], [:"3", "3"]], csv[0].to_a)
- assert_equal([[:"1", 1], [:"2", 2], [:"3", 3]], csv[1].to_a)
- assert_nil(csv[2])
- end
-
- def test_builtin_downcase_converter
- csv = CSV.parse( "One,TWO Three", headers: true,
- return_headers: true,
- header_converters: :downcase )
- assert_equal(%w{one two\ three}, csv.headers)
- end
-
- def test_builtin_symbol_converter
- # Note that the trailing space is intentional
- csv = CSV.parse( "One,TWO Three ", headers: true,
- return_headers: true,
- header_converters: :symbol )
- assert_equal([:one, :two_three], csv.headers)
- end
-
- def test_builtin_symbol_converter_with_punctuation
- csv = CSV.parse( "One, Two & Three ($)", headers: true,
- return_headers: true,
- header_converters: :symbol )
- assert_equal([:one, :two_three], csv.headers)
- end
-
- def test_builtin_converters_with_blank_header
- csv = CSV.parse( "one,,three", headers: true,
- return_headers: true,
- header_converters: [:downcase, :symbol] )
- assert_equal([:one, nil, :three], csv.headers)
- end
-
- def test_custom_converter
- converter = lambda { |header| header.tr(" ", "_") }
- csv = CSV.parse( "One,TWO Three",
- headers: true,
- return_headers: true,
- header_converters: converter )
- assert_equal(%w{One TWO_Three}, csv.headers)
- end
-
- def test_table_support
- csv = nil
- assert_nothing_raised(Exception) do
- csv = CSV.parse(@data, headers: true)
- end
-
- assert_instance_of(CSV::Table, csv)
- end
-
- def test_skip_blanks
- @data = <<-CSV
-
-
-A,B,C
-
-1,2,3
-
-
-
- CSV
-
- expected = [%w[1 2 3]]
- CSV.parse(@data, headers: true, skip_blanks: true) do |row|
- assert_equal(expected.shift, row.fields)
- end
-
- expected = [%w[A B C], %w[1 2 3]]
- CSV.parse( @data,
- headers: true,
- return_headers: true,
- skip_blanks: true ) do |row|
- assert_equal(expected.shift, row.fields)
- end
- end
-
- def test_headers_reader
- # no headers
- assert_nil(CSV.new(@data).headers)
-
- # headers
- csv = CSV.new(@data, headers: true)
- assert_equal(true, csv.headers) # before headers are read
- csv.shift # set headers
- assert_equal(%w[first second third], csv.headers) # after headers are read
- end
-
- def test_blank_row
- @data += "\n#{@data}" # add a blank row
-
- # ensure that everything returned is a Row object
- CSV.parse(@data, headers: true) do |row|
- assert_instance_of(CSV::Row, row)
- end
- end
-
- def test_nil_row_header
- @data = <<-CSV
-A
-
-1
- CSV
-
- csv = CSV.parse(@data, headers: true)
-
- # ensure nil row creates Row object with headers
- row = csv[0]
- assert_equal([["A"], [nil]],
- [row.headers, row.fields])
- end
-
- def test_parse_empty
- assert_equal(CSV::Table.new([]),
- CSV.parse("", headers: true))
- end
-
- def test_parse_empty_line
- assert_equal(CSV::Table.new([]),
- CSV.parse("\n", headers: true))
- end
-
- def test_specified_empty
- assert_equal(CSV::Table.new([],
- headers: ["header1"]),
- CSV.parse("", headers: ["header1"]))
- end
-
- def test_specified_empty_line
- assert_equal(CSV::Table.new([CSV::Row.new(["header1"], [])],
- headers: ["header1"]),
- CSV.parse("\n", headers: ["header1"]))
- end
-end
diff --git a/test/csv/parse/test_invalid.rb b/test/csv/parse/test_invalid.rb
deleted file mode 100644
index ddb59e2b9a..0000000000
--- a/test/csv/parse/test_invalid.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseInvalid < Test::Unit::TestCase
- def test_no_column_mixed_new_lines
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse("\n" +
- "\r")
- end
- assert_equal("New line must be <\"\\n\"> not <\"\\r\"> in line 2.",
- error.message)
- end
-
- def test_ignore_invalid_line
- csv = CSV.new(<<-CSV, headers: true, return_headers: true)
-head1,head2,head3
-aaa,bbb,ccc
-ddd,ee"e.fff
-ggg,hhh,iii
- CSV
- headers = ["head1", "head2", "head3"]
- assert_equal(CSV::Row.new(headers, headers),
- csv.shift)
- assert_equal(CSV::Row.new(headers, ["aaa", "bbb", "ccc"]),
- csv.shift)
- assert_equal(false, csv.eof?)
- error = assert_raise(CSV::MalformedCSVError) do
- csv.shift
- end
- assert_equal("Illegal quoting in line 3.",
- error.message)
- assert_equal(false, csv.eof?)
- assert_equal(CSV::Row.new(headers, ["ggg", "hhh", "iii"]),
- csv.shift)
- assert_equal(true, csv.eof?)
- end
-
- def test_ignore_invalid_line_cr_lf
- data = <<-CSV
-"1","OK"\r
-"2",""NOT" OK"\r
-"3","OK"\r
-CSV
- csv = CSV.new(data)
-
- assert_equal(['1', 'OK'], csv.shift)
- assert_raise(CSV::MalformedCSVError) { csv.shift }
- assert_equal(['3', 'OK'], csv.shift)
- end
-end
diff --git a/test/csv/parse/test_liberal_parsing.rb b/test/csv/parse/test_liberal_parsing.rb
deleted file mode 100644
index 2f7b34689f..0000000000
--- a/test/csv/parse/test_liberal_parsing.rb
+++ /dev/null
@@ -1,160 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseLiberalParsing < Test::Unit::TestCase
- extend DifferentOFS
-
- def test_middle_quote_start
- input = '"Johnson, Dwayne",Dwayne "The Rock" Johnson'
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse_line(input)
- end
- assert_equal("Illegal quoting in line 1.",
- error.message)
- assert_equal(["Johnson, Dwayne", 'Dwayne "The Rock" Johnson'],
- CSV.parse_line(input, liberal_parsing: true))
- end
-
- def test_middle_quote_end
- input = '"quoted" field'
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse_line(input)
- end
- assert_equal("Any value after quoted field isn't allowed in line 1.",
- error.message)
- assert_equal(['"quoted" field'],
- CSV.parse_line(input, liberal_parsing: true))
- end
-
- def test_quote_after_column_separator
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse_line('is,this "three," or four,fields', liberal_parsing: true)
- end
- assert_equal("Unclosed quoted field in line 1.",
- error.message)
- end
-
- def test_quote_before_column_separator
- assert_equal(["is", 'this "three', ' or four"', "fields"],
- CSV.parse_line('is,this "three, or four",fields',
- liberal_parsing: true))
- end
-
- def test_backslash_quote
- assert_equal([
- "1",
- "\"Hamlet says, \\\"Seems",
- "\\\" madam! Nay it is; I know not \\\"seems.\\\"\"",
- ],
- CSV.parse_line('1,' +
- '"Hamlet says, \"Seems,' +
- '\" madam! Nay it is; I know not \"seems.\""',
- liberal_parsing: true))
- end
-
- def test_space_quote
- input = <<~CSV
- Los Angeles, 34°03'N, 118°15'W
- New York City, 40°42'46"N, 74°00'21"W
- Paris, 48°51'24"N, 2°21'03"E
- CSV
- assert_equal(
- [
- ["Los Angeles", " 34°03'N", " 118°15'W"],
- ["New York City", " 40°42'46\"N", " 74°00'21\"W"],
- ["Paris", " 48°51'24\"N", " 2°21'03\"E"],
- ],
- CSV.parse(input, liberal_parsing: true))
- end
-
- def test_double_quote_outside_quote
- data = %Q{a,""b""}
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse(data)
- end
- assert_equal("Any value after quoted field isn't allowed in line 1.",
- error.message)
- assert_equal([
- [["a", %Q{""b""}]],
- [["a", %Q{"b"}]],
- ],
- [
- CSV.parse(data, liberal_parsing: true),
- CSV.parse(data,
- liberal_parsing: {
- double_quote_outside_quote: true,
- }),
- ])
- end
-
- class TestBackslashQuote < Test::Unit::TestCase
- extend ::DifferentOFS
-
- def test_double_quote_outside_quote
- data = %Q{a,""b""}
- assert_equal([
- [["a", %Q{""b""}]],
- [["a", %Q{"b"}]],
- ],
- [
- CSV.parse(data,
- liberal_parsing: {
- backslash_quote: true
- }),
- CSV.parse(data,
- liberal_parsing: {
- backslash_quote: true,
- double_quote_outside_quote: true
- }),
- ])
- end
-
- def test_unquoted_value
- data = %q{\"\"a\"\"}
- assert_equal([
- [[%q{\"\"a\"\"}]],
- [[%q{""a""}]],
- ],
- [
- CSV.parse(data, liberal_parsing: true),
- CSV.parse(data,
- liberal_parsing: {
- backslash_quote: true
- }),
- ])
- end
-
- def test_unquoted_value_multiple_characters_col_sep
- data = %q{a<\\"b<=>x}
- assert_equal([[%Q{a<"b}, "x"]],
- CSV.parse(data,
- col_sep: "<=>",
- liberal_parsing: {
- backslash_quote: true
- }))
- end
-
- def test_quoted_value
- data = %q{"\"\"a\"\""}
- assert_equal([
- [[%q{"\"\"a\"\""}]],
- [[%q{""a""}]],
- [[%q{""a""}]],
- ],
- [
- CSV.parse(data, liberal_parsing: true),
- CSV.parse(data,
- liberal_parsing: {
- backslash_quote: true
- }),
- CSV.parse(data,
- liberal_parsing: {
- backslash_quote: true,
- double_quote_outside_quote: true
- }),
- ])
- end
- end
-end
diff --git a/test/csv/parse/test_quote_char_nil.rb b/test/csv/parse/test_quote_char_nil.rb
deleted file mode 100644
index fc3b646759..0000000000
--- a/test/csv/parse/test_quote_char_nil.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseQuoteCharNil < Test::Unit::TestCase
- extend DifferentOFS
-
- def test_full
- assert_equal(["a", "b"], CSV.parse_line(%Q{a,b}, quote_char: nil))
- end
-
- def test_end_with_nil
- assert_equal(["a", nil, nil, nil], CSV.parse_line(%Q{a,,,}, quote_char: nil))
- end
-
- def test_nil_nil
- assert_equal([nil, nil], CSV.parse_line(%Q{,}, quote_char: nil))
- end
-
- def test_unquoted_value_multiple_characters_col_sep
- data = %q{a<b<=>x}
- assert_equal([[%Q{a<b}, "x"]], CSV.parse(data, col_sep: "<=>", quote_char: nil))
- end
-
- def test_csv_header_string
- data = <<~DATA
- first,second,third
- A,B,C
- 1,2,3
- DATA
- assert_equal(
- CSV::Table.new([
- CSV::Row.new(["my", "new", "headers"], ["first", "second", "third"]),
- CSV::Row.new(["my", "new", "headers"], ["A", "B", "C"]),
- CSV::Row.new(["my", "new", "headers"], ["1", "2", "3"])
- ]),
- CSV.parse(data, headers: "my,new,headers", quote_char: nil)
- )
- end
-
- def test_comma
- assert_equal([["a", "b", nil, "d"]],
- CSV.parse("a,b,,d", col_sep: ",", quote_char: nil))
- end
-
- def test_space
- assert_equal([["a", "b", nil, "d"]],
- CSV.parse("a b d", col_sep: " ", quote_char: nil))
- end
-
- def encode_array(array, encoding)
- array.collect do |element|
- element ? element.encode(encoding) : element
- end
- end
-
- def test_space_no_ascii
- encoding = Encoding::UTF_16LE
- assert_equal([encode_array(["a", "b", nil, "d"], encoding)],
- CSV.parse("a b d".encode(encoding),
- col_sep: " ".encode(encoding),
- quote_char: nil))
- end
-
- def test_multiple_space
- assert_equal([["a b", nil, "d"]],
- CSV.parse("a b d", col_sep: " ", quote_char: nil))
- end
-
- def test_multiple_characters_leading_empty_fields
- data = <<-CSV
-<=><=>A<=>B<=>C
-1<=>2<=>3
- CSV
- assert_equal([
- [nil, nil, "A", "B", "C"],
- ["1", "2", "3"],
- ],
- CSV.parse(data, col_sep: "<=>", quote_char: nil))
- end
-
- def test_line
- lines = [
- "abc,def\n",
- ]
- csv = CSV.new(lines.join(""), quote_char: nil)
- lines.each do |line|
- csv.shift
- assert_equal(line, csv.line)
- end
- end
-end
diff --git a/test/csv/parse/test_rewind.rb b/test/csv/parse/test_rewind.rb
deleted file mode 100644
index 0aa403b756..0000000000
--- a/test/csv/parse/test_rewind.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseRewind < Test::Unit::TestCase
- extend DifferentOFS
-
- def parse(data, **options)
- csv = CSV.new(data, **options)
- records = csv.to_a
- csv.rewind
- [records, csv.to_a]
- end
-
- def test_default
- data = <<-CSV
-Ruby,2.6.0,script
- CSV
- assert_equal([
- [["Ruby", "2.6.0", "script"]],
- [["Ruby", "2.6.0", "script"]],
- ],
- parse(data))
- end
-
- def test_have_headers
- data = <<-CSV
-Language,Version,Type
-Ruby,2.6.0,script
- CSV
- assert_equal([
- [CSV::Row.new(["Language", "Version", "Type"],
- ["Ruby", "2.6.0", "script"])],
- [CSV::Row.new(["Language", "Version", "Type"],
- ["Ruby", "2.6.0", "script"])],
- ],
- parse(data, headers: true))
- end
-end
diff --git a/test/csv/parse/test_row_separator.rb b/test/csv/parse/test_row_separator.rb
deleted file mode 100644
index eaf6adc910..0000000000
--- a/test/csv/parse/test_row_separator.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseRowSeparator < Test::Unit::TestCase
- extend DifferentOFS
- include Helper
-
- def test_multiple_characters
- with_chunk_size("1") do
- assert_equal([["a"], ["b"]],
- CSV.parse("a\r\nb\r\n", row_sep: "\r\n"))
- end
- end
-end
diff --git a/test/csv/parse/test_skip_lines.rb b/test/csv/parse/test_skip_lines.rb
deleted file mode 100644
index 98d67ae51c..0000000000
--- a/test/csv/parse/test_skip_lines.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseSkipLines < Test::Unit::TestCase
- extend DifferentOFS
- include Helper
-
- def test_default
- csv = CSV.new("a,b,c\n")
- assert_nil(csv.skip_lines)
- end
-
- def test_regexp
- csv = <<-CSV
-1
-#2
- #3
-4
- CSV
- assert_equal([
- ["1"],
- ["4"],
- ],
- CSV.parse(csv, :skip_lines => /\A\s*#/))
- end
-
- def test_regexp_quoted
- csv = <<-CSV
-1
-#2
-"#3"
-4
- CSV
- assert_equal([
- ["1"],
- ["#3"],
- ["4"],
- ],
- CSV.parse(csv, :skip_lines => /\A\s*#/))
- end
-
- def test_string
- csv = <<-CSV
-1
-.2
-3.
-4
- CSV
- assert_equal([
- ["1"],
- ["4"],
- ],
- CSV.parse(csv, :skip_lines => "."))
- end
-
- class RegexStub
- end
-
- def test_not_matchable
- regex_stub = RegexStub.new
- csv = CSV.new("1\n", :skip_lines => regex_stub)
- error = assert_raise(ArgumentError) do
- csv.shift
- end
- assert_equal(":skip_lines has to respond to #match: #{regex_stub.inspect}",
- error.message)
- end
-
- class Matchable
- def initialize(pattern)
- @pattern = pattern
- end
-
- def match(line)
- @pattern.match(line)
- end
- end
-
- def test_matchable
- csv = <<-CSV
-1
-# 2
-3
-# 4
- CSV
- assert_equal([
- ["1"],
- ["3"],
- ],
- CSV.parse(csv, :skip_lines => Matchable.new(/\A#/)))
- end
-
- def test_multibyte_data
- # U+3042 HIRAGANA LETTER A
- # U+3044 HIRAGANA LETTER I
- # U+3046 HIRAGANA LETTER U
- value = "\u3042\u3044\u3046"
- with_chunk_size("5") do
- assert_equal([[value], [value]],
- CSV.parse("#{value}\n#{value}\n",
- :skip_lines => /\A#/))
- end
- end
-
- def test_empty_line_and_liberal_parsing
- assert_equal([["a", "b"]],
- CSV.parse("a,b\n",
- :liberal_parsing => true,
- :skip_lines => /^$/))
- end
-
- def test_crlf
- assert_equal([["a", "b"]],
- CSV.parse("a,b\r\n,\r\n",
- :skip_lines => /^,+$/))
- end
-end
diff --git a/test/csv/parse/test_strip.rb b/test/csv/parse/test_strip.rb
deleted file mode 100644
index c5e35209cc..0000000000
--- a/test/csv/parse/test_strip.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseStrip < Test::Unit::TestCase
- extend DifferentOFS
-
- def test_both
- assert_equal(["a", "b"],
- CSV.parse_line(%Q{ a , b }, strip: true))
- end
-
- def test_left
- assert_equal(["a", "b"],
- CSV.parse_line(%Q{ a, b}, strip: true))
- end
-
- def test_right
- assert_equal(["a", "b"],
- CSV.parse_line(%Q{a ,b }, strip: true))
- end
-
- def test_middle
- assert_equal(["a b"],
- CSV.parse_line(%Q{a b}, strip: true))
- end
-
- def test_quoted
- assert_equal([" a ", " b "],
- CSV.parse_line(%Q{" a "," b "}, strip: true))
- end
-
- def test_liberal_parsing
- assert_equal([" a ", "b", " c ", " d "],
- CSV.parse_line(%Q{" a ", b , " c "," d " },
- strip: true,
- liberal_parsing: true))
- end
-
- def test_string
- assert_equal(["a", " b"],
- CSV.parse_line(%Q{ a , " b" },
- strip: " "))
- end
-
- def test_no_quote
- assert_equal([" a ", " b "],
- CSV.parse_line(%Q{" a ", b },
- strip: %Q{"},
- quote_char: nil))
- end
-
- def test_do_not_strip_cr
- assert_equal([
- ["a", "b "],
- ["a", "b "],
- ],
- CSV.parse(%Q{"a" ,"b " \r} +
- %Q{"a" ,"b " \r},
- strip: true))
- end
-
- def test_do_not_strip_lf
- assert_equal([
- ["a", "b "],
- ["a", "b "],
- ],
- CSV.parse(%Q{"a" ,"b " \n} +
- %Q{"a" ,"b " \n},
- strip: true))
- end
-
- def test_do_not_strip_crlf
- assert_equal([
- ["a", "b "],
- ["a", "b "],
- ],
- CSV.parse(%Q{"a" ,"b " \r\n} +
- %Q{"a" ,"b " \r\n},
- strip: true))
- end
-
- def test_col_sep_incompatible_true
- message = "The provided strip (true) and " \
- "col_sep (\\t) options are incompatible."
- assert_raise_with_message(ArgumentError, message) do
- CSV.parse_line(%Q{"a"\t"b"\n},
- col_sep: "\t",
- strip: true)
- end
- end
-
- def test_col_sep_incompatible_string
- message = "The provided strip (\\t) and " \
- "col_sep (\\t) options are incompatible."
- assert_raise_with_message(ArgumentError, message) do
- CSV.parse_line(%Q{"a"\t"b"\n},
- col_sep: "\t",
- strip: "\t")
- end
- end
-
- def test_col_sep_compatible_string
- assert_equal(
- ["a", "b"],
- CSV.parse_line(%Q{\va\tb\v\n},
- col_sep: "\t",
- strip: "\v")
- )
- end
-end
diff --git a/test/csv/parse/test_unconverted_fields.rb b/test/csv/parse/test_unconverted_fields.rb
deleted file mode 100644
index 437124ebd3..0000000000
--- a/test/csv/parse/test_unconverted_fields.rb
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-class TestCSVParseUnconvertedFields < Test::Unit::TestCase
- extend DifferentOFS
-
- def setup
- super
- @custom = lambda {|field| /\A:(\S.*?)\s*\Z/ =~ field ? $1.to_sym : field}
-
- @headers = ["first", "second", "third"]
- @data = <<-CSV
-first,second,third
-1,2,3
- CSV
- end
-
-
- def test_custom
- row = CSV.parse_line("Numbers,:integer,1,:float,3.015",
- converters: [:numeric, @custom],
- unconverted_fields: true)
- assert_equal([
- ["Numbers", :integer, 1, :float, 3.015],
- ["Numbers", ":integer", "1", ":float", "3.015"],
- ],
- [
- row,
- row.unconverted_fields,
- ])
- end
-
- def test_no_fields
- row = CSV.parse_line("\n",
- converters: [:numeric, @custom],
- unconverted_fields: true)
- assert_equal([
- [],
- [],
- ],
- [
- row,
- row.unconverted_fields,
- ])
- end
-
- def test_parsed_header
- row = CSV.parse_line(@data,
- converters: :numeric,
- unconverted_fields: true,
- headers: :first_row)
- assert_equal([
- CSV::Row.new(@headers,
- [1, 2, 3]),
- ["1", "2", "3"],
- ],
- [
- row,
- row.unconverted_fields,
- ])
- end
-
- def test_return_headers
- row = CSV.parse_line(@data,
- converters: :numeric,
- unconverted_fields: true,
- headers: :first_row,
- return_headers: true)
- assert_equal([
- CSV::Row.new(@headers,
- @headers),
- @headers,
- ],
- [
- row,
- row.unconverted_fields,
- ])
- end
-
- def test_header_converters
- row = CSV.parse_line(@data,
- converters: :numeric,
- unconverted_fields: true,
- headers: :first_row,
- return_headers: true,
- header_converters: :symbol)
- assert_equal([
- CSV::Row.new(@headers.collect(&:to_sym),
- @headers),
- @headers,
- ],
- [
- row,
- row.unconverted_fields,
- ])
- end
-
- def test_specified_headers
- row = CSV.parse_line("\n",
- converters: :numeric,
- unconverted_fields: true,
- headers: %w{my new headers},
- return_headers: true,
- header_converters: :symbol)
- assert_equal([
- CSV::Row.new([:my, :new, :headers],
- ["my", "new", "headers"]),
- [],
- ],
- [
- row,
- row.unconverted_fields,
- ])
- end
-end
diff --git a/test/csv/test_data_converters.rb b/test/csv/test_data_converters.rb
deleted file mode 100644
index 1620e077be..0000000000
--- a/test/csv/test_data_converters.rb
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "helper"
-
-class TestCSVDataConverters < Test::Unit::TestCase
- extend DifferentOFS
-
- def setup
- super
- @win_safe_time_str = Time.now.strftime("%a %b %d %H:%M:%S %Y")
- end
-
- def test_builtin_integer_converter
- # does convert
- [-5, 1, 10000000000].each do |n|
- assert_equal(n, CSV::Converters[:integer][n.to_s])
- end
-
- # does not convert
- (%w{junk 1.0} + [""]).each do |str|
- assert_equal(str, CSV::Converters[:integer][str])
- end
- end
-
- def test_builtin_float_converter
- # does convert
- [-5.1234, 0, 2.3e-11].each do |n|
- assert_equal(n, CSV::Converters[:float][n.to_s])
- end
-
- # does not convert
- (%w{junk 1..0 .015F} + [""]).each do |str|
- assert_equal(str, CSV::Converters[:float][str])
- end
- end
-
- def test_builtin_date_converter
- # does convert
- assert_instance_of(
- Date,
- CSV::Converters[:date][@win_safe_time_str.sub(/\d+:\d+:\d+ /, "")]
- )
-
- # does not convert
- assert_instance_of(String, CSV::Converters[:date]["junk"])
- end
-
- def test_builtin_date_time_converter
- # does convert
- assert_instance_of( DateTime,
- CSV::Converters[:date_time][@win_safe_time_str] )
-
- # does not convert
- assert_instance_of(String, CSV::Converters[:date_time]["junk"])
- end
-
- def test_builtin_date_time_converter_iso8601_date
- iso8601_string = "2018-01-14"
- datetime = DateTime.new(2018, 1, 14)
- assert_equal(datetime,
- CSV::Converters[:date_time][iso8601_string])
- end
-
- def test_builtin_date_time_converter_iso8601_minute
- iso8601_string = "2018-01-14T22:25"
- datetime = DateTime.new(2018, 1, 14, 22, 25)
- assert_equal(datetime,
- CSV::Converters[:date_time][iso8601_string])
- end
-
- def test_builtin_date_time_converter_iso8601_second
- iso8601_string = "2018-01-14T22:25:19"
- datetime = DateTime.new(2018, 1, 14, 22, 25, 19)
- assert_equal(datetime,
- CSV::Converters[:date_time][iso8601_string])
- end
-
- def test_builtin_date_time_converter_iso8601_under_second
- iso8601_string = "2018-01-14T22:25:19.1"
- datetime = DateTime.new(2018, 1, 14, 22, 25, 19.1)
- assert_equal(datetime,
- CSV::Converters[:date_time][iso8601_string])
- end
-
- def test_builtin_date_time_converter_iso8601_under_second_offset
- iso8601_string = "2018-01-14T22:25:19.1+09:00"
- datetime = DateTime.new(2018, 1, 14, 22, 25, 19.1, "+9")
- assert_equal(datetime,
- CSV::Converters[:date_time][iso8601_string])
- end
-
- def test_builtin_date_time_converter_iso8601_offset
- iso8601_string = "2018-01-14T22:25:19+09:00"
- datetime = DateTime.new(2018, 1, 14, 22, 25, 19, "+9")
- assert_equal(datetime,
- CSV::Converters[:date_time][iso8601_string])
- end
-
- def test_builtin_date_time_converter_iso8601_utc
- iso8601_string = "2018-01-14T22:25:19Z"
- datetime = DateTime.new(2018, 1, 14, 22, 25, 19)
- assert_equal(datetime,
- CSV::Converters[:date_time][iso8601_string])
- end
-end
diff --git a/test/csv/test_encodings.rb b/test/csv/test_encodings.rb
deleted file mode 100644
index 8d228c05f3..0000000000
--- a/test/csv/test_encodings.rb
+++ /dev/null
@@ -1,372 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "helper"
-
-class TestCSVEncodings < Test::Unit::TestCase
- extend DifferentOFS
- include Helper
-
- def setup
- super
- require 'tempfile'
- @temp_csv_file = Tempfile.new(%w"test_csv. .csv")
- @temp_csv_path = @temp_csv_file.path
- @temp_csv_file.close
- end
-
- def teardown
- @temp_csv_file.close!
- super
- end
-
- ########################################
- ### Hand Test Some Popular Encodings ###
- ########################################
-
- def test_parses_utf8_encoding
- assert_parses( [ %w[ one two … ],
- %w[ 1 … 3 ],
- %w[ … 5 6 ] ], "UTF-8" )
- end
-
- def test_parses_latin1_encoding
- assert_parses( [ %w[ one two Résumé ],
- %w[ 1 Résumé 3 ],
- %w[ Résumé 5 6 ] ], "ISO-8859-1" )
- end
-
- def test_parses_utf16be_encoding
- assert_parses( [ %w[ one two … ],
- %w[ 1 … 3 ],
- %w[ … 5 6 ] ], "UTF-16BE" )
- end
-
- def test_parses_shift_jis_encoding
- assert_parses( [ %w[ 一 二 三 ],
- %w[ 四 五 六 ],
- %w[ 七 八 九 ] ], "Shift_JIS" )
- end
-
- ###########################################################
- ### Try Simple Reading for All Non-dummy Ruby Encodings ###
- ###########################################################
-
- def test_reading_with_most_encodings
- each_encoding do |encoding|
- begin
- assert_parses( [ %w[ abc def ],
- %w[ ghi jkl ] ], encoding )
- rescue Encoding::ConverterNotFoundError
- fail("Failed to support #{encoding.name}.")
- end
- end
- end
-
- def test_regular_expression_escaping
- each_encoding do |encoding|
- begin
- assert_parses( [ %w[ abc def ],
- %w[ ghi jkl ] ], encoding, col_sep: "|" )
- rescue Encoding::ConverterNotFoundError
- fail("Failed to properly escape #{encoding.name}.")
- end
- end
- end
-
- def test_read_with_default_encoding
- data = "abc"
- default_external = Encoding.default_external
- each_encoding do |encoding|
- File.open(@temp_csv_path, "wb", encoding: encoding) {|f| f << data}
- begin
- no_warnings do
- Encoding.default_external = encoding
- end
- result = CSV.read(@temp_csv_path)[0][0]
- ensure
- no_warnings do
- Encoding.default_external = default_external
- end
- end
- assert_equal(encoding, result.encoding)
- end
- end
-
- #######################################################################
- ### Stress Test ASCII Compatible and Non-ASCII Compatible Encodings ###
- #######################################################################
-
- def test_auto_line_ending_detection
- # arrange data to place a \r at the end of CSV's read ahead point
- encode_for_tests([["a" * 509]], row_sep: "\r\n") do |data|
- assert_equal("\r\n".encode(data.encoding), CSV.new(data).row_sep)
- end
- end
-
- def test_csv_chars_are_transcoded
- encode_for_tests([%w[abc def]]) do |data|
- %w[col_sep row_sep quote_char].each do |csv_char|
- assert_equal( "|".encode(data.encoding),
- CSV.new(data, csv_char.to_sym => "|").send(csv_char) )
- end
- end
- end
-
- def test_parser_works_with_encoded_headers
- encode_for_tests([%w[one two three], %w[1 2 3]]) do |data|
- parsed = CSV.parse(data, headers: true)
- assert_all?(parsed.headers, "Wrong data encoding.") {|h| h.encoding == data.encoding}
- parsed.each do |row|
- assert_all?(row.fields, "Wrong data encoding.") {|f| f.encoding == data.encoding}
- end
- end
- end
-
- def test_built_in_converters_transcode_to_utf_8_then_convert
- encode_for_tests([%w[one two three], %w[1 2 3]]) do |data|
- parsed = CSV.parse(data, converters: :integer)
- assert_all?(parsed[0], "Wrong data encoding.") {|f| f.encoding == data.encoding}
- assert_equal([1, 2, 3], parsed[1])
- end
- end
-
- def test_built_in_header_converters_transcode_to_utf_8_then_convert
- encode_for_tests([%w[one two three], %w[1 2 3]]) do |data|
- parsed = CSV.parse( data, headers: true,
- header_converters: :downcase )
- assert_all?(parsed.headers, "Wrong data encoding.") {|h| h.encoding.name == "UTF-8"}
- assert_all?(parsed[0].fields, "Wrong data encoding.") {|f| f.encoding == data.encoding}
- end
- end
-
- def test_open_allows_you_to_set_encodings
- encode_for_tests([%w[abc def]]) do |data|
- # read and write in encoding
- File.open(@temp_csv_path, "wb:#{data.encoding.name}") { |f| f << data }
- CSV.open(@temp_csv_path, "rb:#{data.encoding.name}") do |csv|
- csv.each do |row|
- assert_all?(row, "Wrong data encoding.") {|f| f.encoding == data.encoding}
- end
- end
-
- # read and write with transcoding
- File.open(@temp_csv_path, "wb:UTF-32BE:#{data.encoding.name}") do |f|
- f << data
- end
- CSV.open(@temp_csv_path, "rb:UTF-32BE:#{data.encoding.name}") do |csv|
- csv.each do |row|
- assert_all?(row, "Wrong data encoding.") {|f| f.encoding == data.encoding}
- end
- end
- end
- end
-
- def test_foreach_allows_you_to_set_encodings
- encode_for_tests([%w[abc def]]) do |data|
- # read and write in encoding
- File.open(@temp_csv_path, "wb", encoding: data.encoding) { |f| f << data }
- CSV.foreach(@temp_csv_path, encoding: data.encoding) do |row|
- row.each {|f| assert_equal(f.encoding, data.encoding)}
- end
-
- # read and write with transcoding
- File.open(@temp_csv_path, "wb:UTF-32BE:#{data.encoding.name}") do |f|
- f << data
- end
- CSV.foreach( @temp_csv_path,
- encoding: "UTF-32BE:#{data.encoding.name}" ) do |row|
- assert_all?(row, "Wrong data encoding.") {|f| f.encoding == data.encoding}
- end
- end
- end
-
- def test_read_allows_you_to_set_encodings
- encode_for_tests([%w[abc def]]) do |data|
- # read and write in encoding
- File.open(@temp_csv_path, "wb:#{data.encoding.name}") { |f| f << data }
- rows = CSV.read(@temp_csv_path, encoding: data.encoding.name)
- assert_all?(rows.flatten, "Wrong data encoding.") {|f| f.encoding == data.encoding}
-
- # read and write with transcoding
- File.open(@temp_csv_path, "wb:UTF-32BE:#{data.encoding.name}") do |f|
- f << data
- end
- rows = CSV.read( @temp_csv_path,
- encoding: "UTF-32BE:#{data.encoding.name}" )
- assert_all?(rows.flatten, "Wrong data encoding.") {|f| f.encoding == data.encoding}
- end
- end
-
- #################################
- ### Write CSV in any Encoding ###
- #################################
-
- def test_can_write_csv_in_any_encoding
- each_encoding do |encoding|
- # test generate_line with encoding hint
- begin
- csv = %w[abc d|ef].map { |f| f.encode(encoding) }.
- to_csv(col_sep: "|", encoding: encoding.name)
- rescue Encoding::ConverterNotFoundError
- next
- end
- assert_equal(encoding, csv.encoding)
-
- # test generate_line with encoding guessing from fields
- csv = %w[abc d|ef].map { |f| f.encode(encoding) }.to_csv(col_sep: "|")
- assert_equal(encoding, csv.encoding)
-
- # writing to files
- data = encode_ary([%w[abc d,ef], %w[123 456 ]], encoding)
- CSV.open(@temp_csv_path, "wb:#{encoding.name}") do |f|
- data.each { |row| f << row }
- end
- assert_equal(data, CSV.read(@temp_csv_path, encoding: encoding.name))
- end
- end
-
- def test_encoding_is_upgraded_during_writing_as_needed
- data = ["foo".force_encoding("US-ASCII"), "\u3042"]
- assert_equal("US-ASCII", data.first.encoding.name)
- assert_equal("UTF-8", data.last.encoding.name)
- assert_equal("UTF-8", data.join('').encoding.name)
- assert_equal("UTF-8", data.to_csv.encoding.name)
- end
-
- def test_encoding_is_upgraded_for_ascii_content_during_writing_as_needed
- data = ["foo".force_encoding("ISO-8859-1"), "\u3042"]
- assert_equal("ISO-8859-1", data.first.encoding.name)
- assert_equal("UTF-8", data.last.encoding.name)
- assert_equal("UTF-8", data.join('').encoding.name)
- assert_equal("UTF-8", data.to_csv.encoding.name)
- end
-
- def test_encoding_is_not_upgraded_for_non_ascii_content_during_writing_as_needed
- data = ["\u00c0".encode("ISO-8859-1"), "\u3042"]
- assert_equal([
- "ISO-8859-1",
- "UTF-8",
- ],
- data.collect {|field| field.encoding.name})
- assert_raise(Encoding::CompatibilityError) do
- data.to_csv
- end
- end
-
- def test_explicit_encoding
- bug9766 = '[ruby-core:62113] [Bug #9766]'
- s = CSV.generate(encoding: "Windows-31J") do |csv|
- csv << ["foo".force_encoding("ISO-8859-1"), "\u3042"]
- end
- assert_equal(["foo,\u3042\n".encode(Encoding::Windows_31J), Encoding::Windows_31J], [s, s.encoding], bug9766)
- end
-
- def test_encoding_with_default_internal
- with_default_internal(Encoding::UTF_8) do
- s = CSV.generate(String.new(encoding: Encoding::Big5), encoding: Encoding::Big5) do |csv|
- csv << ["漢字"]
- end
- assert_equal(["漢字\n".encode(Encoding::Big5), Encoding::Big5], [s, s.encoding])
- end
- end
-
- def test_row_separator_detection_with_invalid_encoding
- csv = CSV.new("invalid,\xF8\r\nvalid,x\r\n".force_encoding("UTF-8"),
- encoding: "UTF-8")
- assert_equal("\r\n", csv.row_sep)
- end
-
- def test_invalid_encoding_row_error
- csv = CSV.new("valid,x\rinvalid,\xF8\r".force_encoding("UTF-8"),
- encoding: "UTF-8", row_sep: "\r")
- error = assert_raise(CSV::MalformedCSVError) do
- csv.shift
- csv.shift
- end
- assert_equal("Invalid byte sequence in UTF-8 in line 2.",
- error.message)
- end
-
- private
-
- def assert_parses(fields, encoding, **options)
- encoding = Encoding.find(encoding) unless encoding.is_a? Encoding
- orig_fields = fields
- fields = encode_ary(fields, encoding)
- data = ary_to_data(fields, **options)
- parsed = CSV.parse(data, **options)
- assert_equal(fields, parsed)
- parsed.flatten.each_with_index do |field, i|
- assert_equal(encoding, field.encoding, "Field[#{i + 1}] was transcoded.")
- end
- File.open(@temp_csv_path, "wb") {|f| f.print(data)}
- CSV.open(@temp_csv_path, "rb:#{encoding}", **options) do |csv|
- csv.each_with_index do |row, i|
- assert_equal(fields[i], row)
- end
- end
- begin
- CSV.open(@temp_csv_path,
- "rb:#{encoding}:#{__ENCODING__}",
- **options) do |csv|
- csv.each_with_index do |row, i|
- assert_equal(orig_fields[i], row)
- end
- end unless encoding == __ENCODING__
- rescue Encoding::ConverterNotFoundError
- end
- options[:encoding] = encoding.name
- CSV.open(@temp_csv_path, **options) do |csv|
- csv.each_with_index do |row, i|
- assert_equal(fields[i], row)
- end
- end
- options.delete(:encoding)
- options[:external_encoding] = encoding.name
- options[:internal_encoding] = __ENCODING__.name
- begin
- CSV.open(@temp_csv_path, **options) do |csv|
- csv.each_with_index do |row, i|
- assert_equal(orig_fields[i], row)
- end
- end unless encoding == __ENCODING__
- rescue Encoding::ConverterNotFoundError
- end
- end
-
- def encode_ary(ary, encoding)
- ary.map { |row| row.map { |field| field.encode(encoding) } }
- end
-
- def ary_to_data(ary, **options)
- encoding = ary.flatten.first.encoding
- quote_char = (options[:quote_char] || '"').encode(encoding)
- col_sep = (options[:col_sep] || ",").encode(encoding)
- row_sep = (options[:row_sep] || "\n").encode(encoding)
- ary.map { |row|
- row.map { |field|
- [quote_char, field.encode(encoding), quote_char].join('')
- }.join(col_sep) + row_sep
- }.join('').encode(encoding)
- end
-
- def encode_for_tests(data, **options)
- yield ary_to_data(encode_ary(data, "UTF-8"), **options)
- yield ary_to_data(encode_ary(data, "UTF-16BE"), **options)
- end
-
- def each_encoding
- Encoding.list.each do |encoding|
- next if encoding.dummy? # skip "dummy" encodings
- yield encoding
- end
- end
-
- def no_warnings
- old_verbose, $VERBOSE = $VERBOSE, nil
- yield
- ensure
- $VERBOSE = old_verbose
- end
-end
diff --git a/test/csv/test_features.rb b/test/csv/test_features.rb
deleted file mode 100644
index d6eb2dc13b..0000000000
--- a/test/csv/test_features.rb
+++ /dev/null
@@ -1,359 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-begin
- require "zlib"
-rescue LoadError
-end
-
-require_relative "helper"
-require "tempfile"
-
-class TestCSVFeatures < Test::Unit::TestCase
- extend DifferentOFS
-
- TEST_CASES = [ [%Q{a,b}, ["a", "b"]],
- [%Q{a,"""b"""}, ["a", "\"b\""]],
- [%Q{a,"""b"}, ["a", "\"b"]],
- [%Q{a,"b"""}, ["a", "b\""]],
- [%Q{a,"\nb"""}, ["a", "\nb\""]],
- [%Q{a,"""\nb"}, ["a", "\"\nb"]],
- [%Q{a,"""\nb\n"""}, ["a", "\"\nb\n\""]],
- [%Q{a,"""\nb\n""",\nc}, ["a", "\"\nb\n\"", nil]],
- [%Q{a,,,}, ["a", nil, nil, nil]],
- [%Q{,}, [nil, nil]],
- [%Q{"",""}, ["", ""]],
- [%Q{""""}, ["\""]],
- [%Q{"""",""}, ["\"",""]],
- [%Q{,""}, [nil,""]],
- [%Q{,"\r"}, [nil,"\r"]],
- [%Q{"\r\n,"}, ["\r\n,"]],
- [%Q{"\r\n,",}, ["\r\n,", nil]] ]
-
- def setup
- super
- @sample_data = <<-CSV
-line,1,abc
-line,2,"def\nghi"
-
-line,4,jkl
- CSV
- @csv = CSV.new(@sample_data)
- end
-
- def test_col_sep
- [";", "\t"].each do |sep|
- TEST_CASES.each do |test_case|
- assert_equal( test_case.last.map { |t| t.tr(",", sep) unless t.nil? },
- CSV.parse_line( test_case.first.tr(",", sep),
- col_sep: sep ) )
- end
- end
- assert_equal([",,,", nil], CSV.parse_line(",,,;", col_sep: ";"))
- end
-
- def test_col_sep_nil
- assert_raise_with_message(ArgumentError,
- ":col_sep must be 1 or more characters: nil") do
- CSV.parse(@sample_data, col_sep: nil)
- end
- end
-
- def test_col_sep_empty
- assert_raise_with_message(ArgumentError,
- ":col_sep must be 1 or more characters: \"\"") do
- CSV.parse(@sample_data, col_sep: "")
- end
- end
-
- def test_row_sep
- error = assert_raise(CSV::MalformedCSVError) do
- CSV.parse_line("1,2,3\n,4,5\r\n", row_sep: "\r\n")
- end
- assert_equal("Unquoted fields do not allow new line <\"\\n\"> in line 1.",
- error.message)
- assert_equal( ["1", "2", "3\n", "4", "5"],
- CSV.parse_line(%Q{1,2,"3\n",4,5\r\n}, row_sep: "\r\n"))
- end
-
- def test_quote_char
- TEST_CASES.each do |test_case|
- assert_equal(test_case.last.map {|t| t.tr('"', "'") unless t.nil?},
- CSV.parse_line(test_case.first.tr('"', "'"),
- quote_char: "'" ))
- end
- end
-
- def test_quote_char_special_regexp_char
- TEST_CASES.each do |test_case|
- assert_equal(test_case.last.map {|t| t.tr('"', "|") unless t.nil?},
- CSV.parse_line(test_case.first.tr('"', "|"),
- quote_char: "|"))
- end
- end
-
- def test_quote_char_special_regexp_char_liberal_parsing
- TEST_CASES.each do |test_case|
- assert_equal(test_case.last.map {|t| t.tr('"', "|") unless t.nil?},
- CSV.parse_line(test_case.first.tr('"', "|"),
- quote_char: "|",
- liberal_parsing: true))
- end
- end
-
- def test_csv_char_readers
- %w[col_sep row_sep quote_char].each do |reader|
- csv = CSV.new("abc,def", reader.to_sym => "|")
- assert_equal("|", csv.send(reader))
- end
- end
-
- def test_row_sep_auto_discovery
- ["\r\n", "\n", "\r"].each do |line_end|
- data = "1,2,3#{line_end}4,5#{line_end}"
- discovered = CSV.new(data).row_sep
- assert_equal(line_end, discovered)
- end
-
- assert_equal("\n", CSV.new("\n\r\n\r").row_sep)
-
- assert_equal($/, CSV.new("").row_sep)
-
- assert_equal($/, CSV.new(STDERR).row_sep)
- end
-
- def test_line
- lines = [
- %Q(\u{3000}abc,def\n),
- %Q(\u{3000}abc,"d\nef"\n),
- %Q(\u{3000}abc,"d\r\nef"\n),
- %Q(\u{3000}abc,"d\ref")
- ]
- csv = CSV.new(lines.join(''))
- lines.each do |line|
- csv.shift
- assert_equal(line, csv.line)
- end
- end
-
- def test_lineno
- assert_equal(5, @sample_data.lines.to_a.size)
-
- 4.times do |line_count|
- assert_equal(line_count, @csv.lineno)
- assert_not_nil(@csv.shift)
- assert_equal(line_count + 1, @csv.lineno)
- end
- assert_nil(@csv.shift)
- end
-
- def test_readline
- test_lineno
-
- @csv.rewind
-
- test_lineno
- end
-
- def test_unknown_options
- assert_raise_with_message(ArgumentError, /unknown keyword/) {
- CSV.new(@sample_data, unknown: :error)
- }
- assert_raise_with_message(ArgumentError, /unknown keyword/) {
- CSV.new(@sample_data, universal_newline: true)
- }
- end
-
- def test_skip_blanks
- assert_equal(4, @csv.to_a.size)
-
- @csv = CSV.new(@sample_data, skip_blanks: true)
-
- count = 0
- @csv.each do |row|
- count += 1
- assert_equal("line", row.first)
- end
- assert_equal(3, count)
- end
-
- def test_csv_behavior_readers
- %w[ unconverted_fields return_headers write_headers
- skip_blanks force_quotes ].each do |behavior|
- assert_not_predicate(CSV.new("abc,def"), "#{behavior}?", "Behavior defaulted to on.")
- csv = CSV.new("abc,def", behavior.to_sym => true)
- assert_predicate(csv, "#{behavior}?", "Behavior change now registered.")
- end
- end
-
- def test_converters_reader
- # no change
- assert_equal( [:integer],
- CSV.new("abc,def", converters: [:integer]).converters )
-
- # just one
- assert_equal( [:integer],
- CSV.new("abc,def", converters: :integer).converters )
-
- # expanded
- assert_equal( [:integer, :float],
- CSV.new("abc,def", converters: :numeric).converters )
-
- # custom
- csv = CSV.new("abc,def", converters: [:integer, lambda { }])
- assert_equal(2, csv.converters.size)
- assert_equal(:integer, csv.converters.first)
- assert_instance_of(Proc, csv.converters.last)
- end
-
- def test_header_converters_reader
- # no change
- hc = :header_converters
- assert_equal([:downcase], CSV.new("abc,def", hc => [:downcase]).send(hc))
-
- # just one
- assert_equal([:downcase], CSV.new("abc,def", hc => :downcase).send(hc))
-
- # custom
- csv = CSV.new("abc,def", hc => [:symbol, lambda { }])
- assert_equal(2, csv.send(hc).size)
- assert_equal(:symbol, csv.send(hc).first)
- assert_instance_of(Proc, csv.send(hc).last)
- end
-
- # reported by Kev Jackson
- def test_failing_to_escape_col_sep
- assert_nothing_raised(Exception) { CSV.new(String.new, col_sep: "|") }
- end
-
- # reported by Chris Roos
- def test_failing_to_reset_headers_in_rewind
- csv = CSV.new("forename,surname", headers: true, return_headers: true)
- csv.each {|row| assert_predicate row, :header_row?}
- csv.rewind
- csv.each {|row| assert_predicate row, :header_row?}
- end
-
- def test_gzip_reader
- zipped = nil
- assert_nothing_raised(NoMethodError) do
- zipped = CSV.new(
- Zlib::GzipReader.open(
- File.join(File.dirname(__FILE__), "line_endings.gz")
- )
- )
- end
- assert_equal("\r\n", zipped.row_sep)
- ensure
- zipped.close
- end if defined?(Zlib::GzipReader)
-
- def test_gzip_writer
- Tempfile.create(%w"temp .gz") {|tempfile|
- tempfile.close
- file = tempfile.path
- zipped = nil
- assert_nothing_raised(NoMethodError) do
- zipped = CSV.new(Zlib::GzipWriter.open(file))
- end
- zipped << %w[one two three]
- zipped << [1, 2, 3]
- zipped.close
-
- assert_include(Zlib::GzipReader.open(file) {|f| f.read},
- $INPUT_RECORD_SEPARATOR, "@row_sep did not default")
- }
- end if defined?(Zlib::GzipWriter)
-
- def test_inspect_is_smart_about_io_types
- str = CSV.new("string,data").inspect
- assert_include(str, "io_type:StringIO", "IO type not detected.")
-
- str = CSV.new($stderr).inspect
- assert_include(str, "io_type:$stderr", "IO type not detected.")
-
- Tempfile.create(%w"temp .csv") {|tempfile|
- tempfile.close
- path = tempfile.path
- File.open(path, "w") { |csv| csv << "one,two,three\n1,2,3\n" }
- str = CSV.open(path) { |csv| csv.inspect }
- assert_include(str, "io_type:File", "IO type not detected.")
- }
- end
-
- def test_inspect_shows_key_attributes
- str = @csv.inspect
- %w[lineno col_sep row_sep quote_char].each do |attr_name|
- assert_match(/\b#{attr_name}:[^\s>]+/, str)
- end
- end
-
- def test_inspect_shows_headers_when_available
- csv = CSV.new("one,two,three\n1,2,3\n", headers: true)
- assert_include(csv.inspect, "headers:true", "Header hint not shown.")
- csv.shift # load headers
- assert_match(/headers:\[[^\]]+\]/, csv.inspect)
- end
-
- def test_inspect_encoding_is_ascii_compatible
- csv = CSV.new("one,two,three\n1,2,3\n".encode("UTF-16BE"))
- assert_send([Encoding, :compatible?,
- Encoding.find("US-ASCII"), csv.inspect.encoding],
- "inspect() was not ASCII compatible.")
- end
-
- def test_version
- assert_not_nil(CSV::VERSION)
- assert_instance_of(String, CSV::VERSION)
- assert_predicate(CSV::VERSION, :frozen?)
- assert_match(/\A\d\.\d\.\d\z/, CSV::VERSION)
- end
-
- def test_table_nil_equality
- assert_nothing_raised(NoMethodError) { CSV.parse("test", headers: true) == nil }
- end
-
- # non-seekable input stream for testing https://github.com/ruby/csv/issues/44
- class DummyIO
- extend Forwardable
- def_delegators :@io, :gets, :read, :pos, :eof? # no seek or rewind!
- def initialize(data)
- @io = StringIO.new(data)
- end
- end
-
- def test_line_separator_autodetection_for_non_seekable_input_lf
- c = CSV.new(DummyIO.new("one,two,three\nfoo,bar,baz\n"))
- assert_equal [["one", "two", "three"], ["foo", "bar", "baz"]], c.each.to_a
- end
-
- def test_line_separator_autodetection_for_non_seekable_input_cr
- c = CSV.new(DummyIO.new("one,two,three\rfoo,bar,baz\r"))
- assert_equal [["one", "two", "three"], ["foo", "bar", "baz"]], c.each.to_a
- end
-
- def test_line_separator_autodetection_for_non_seekable_input_cr_lf
- c = CSV.new(DummyIO.new("one,two,three\r\nfoo,bar,baz\r\n"))
- assert_equal [["one", "two", "three"], ["foo", "bar", "baz"]], c.each.to_a
- end
-
- def test_line_separator_autodetection_for_non_seekable_input_1024_over_lf
- table = (1..10).map { |row| (1..200).map { |col| "row#{row}col#{col}" }.to_a }.to_a
- input = table.map { |line| line.join(",") }.join("\n")
- c = CSV.new(DummyIO.new(input))
- assert_equal table, c.each.to_a
- end
-
- def test_line_separator_autodetection_for_non_seekable_input_1024_over_cr_lf
- table = (1..10).map { |row| (1..200).map { |col| "row#{row}col#{col}" }.to_a }.to_a
- input = table.map { |line| line.join(",") }.join("\r\n")
- c = CSV.new(DummyIO.new(input))
- assert_equal table, c.each.to_a
- end
-
- def test_line_separator_autodetection_for_non_seekable_input_many_cr_only
- # input with lots of CRs (to make sure no bytes are lost due to look-ahead)
- c = CSV.new(DummyIO.new("foo\r" + "\r" * 9999 + "bar\r"))
- assert_equal [["foo"]] + [[]] * 9999 + [["bar"]], c.each.to_a
- end
-end
diff --git a/test/csv/test_row.rb b/test/csv/test_row.rb
deleted file mode 100644
index b717945041..0000000000
--- a/test/csv/test_row.rb
+++ /dev/null
@@ -1,435 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "helper"
-
-class TestCSVRow < Test::Unit::TestCase
- extend DifferentOFS
-
- def setup
- super
- @row = CSV::Row.new(%w{A B C A A}, [1, 2, 3, 4])
- end
-
- def test_initialize
- # basic
- row = CSV::Row.new(%w{A B C}, [1, 2, 3])
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([["A", 1], ["B", 2], ["C", 3]], row.to_a)
-
- # missing headers
- row = CSV::Row.new(%w{A}, [1, 2, 3])
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([["A", 1], [nil, 2], [nil, 3]], row.to_a)
-
- # missing fields
- row = CSV::Row.new(%w{A B C}, [1, 2])
- assert_not_nil(row)
- assert_instance_of(CSV::Row, row)
- assert_equal([["A", 1], ["B", 2], ["C", nil]], row.to_a)
- end
-
- def test_row_type
- # field rows
- row = CSV::Row.new(%w{A B C}, [1, 2, 3]) # implicit
- assert_not_predicate(row, :header_row?)
- assert_predicate(row, :field_row?)
- row = CSV::Row.new(%w{A B C}, [1, 2, 3], false) # explicit
- assert_not_predicate(row, :header_row?)
- assert_predicate(row, :field_row?)
-
- # header row
- row = CSV::Row.new(%w{A B C}, [1, 2, 3], true)
- assert_predicate(row, :header_row?)
- assert_not_predicate(row, :field_row?)
- end
-
- def test_headers
- assert_equal(%w{A B C A A}, @row.headers)
- end
-
- def test_field
- # by name
- assert_equal(2, @row.field("B"))
- assert_equal(2, @row["B"]) # alias
-
- # by index
- assert_equal(3, @row.field(2))
-
- # by range
- assert_equal([2,3], @row.field(1..2))
-
- # missing
- assert_nil(@row.field("Missing"))
- assert_nil(@row.field(10))
-
- # minimum index
- assert_equal(1, @row.field("A"))
- assert_equal(1, @row.field("A", 0))
- assert_equal(4, @row.field("A", 1))
- assert_equal(4, @row.field("A", 2))
- assert_equal(4, @row.field("A", 3))
- assert_equal(nil, @row.field("A", 4))
- assert_equal(nil, @row.field("A", 5))
- end
-
- def test_fetch
- # only by name
- assert_equal(2, @row.fetch('B'))
-
- # missing header raises KeyError
- assert_raise KeyError do
- @row.fetch('foo')
- end
-
- # missing header yields itself to block
- assert_equal 'bar', @row.fetch('foo') { |header|
- header == 'foo' ? 'bar' : false }
-
- # missing header returns the given default value
- assert_equal 'bar', @row.fetch('foo', 'bar')
-
- # more than one vararg raises ArgumentError
- assert_raise ArgumentError do
- @row.fetch('foo', 'bar', 'baz')
- end
- end
-
- def test_has_key?
- assert_equal(true, @row.has_key?('B'))
- assert_equal(false, @row.has_key?('foo'))
-
- # aliases
- assert_equal(true, @row.header?('B'))
- assert_equal(false, @row.header?('foo'))
-
- assert_equal(true, @row.include?('B'))
- assert_equal(false, @row.include?('foo'))
-
- assert_equal(true, @row.member?('B'))
- assert_equal(false, @row.member?('foo'))
-
- assert_equal(true, @row.key?('B'))
- assert_equal(false, @row.key?('foo'))
- end
-
- def test_set_field
- # set field by name
- assert_equal(100, @row["A"] = 100)
-
- # set field by index
- assert_equal(300, @row[3] = 300)
-
- # set field by name and minimum index
- assert_equal([:a, :b, :c], @row["A", 4] = [:a, :b, :c])
-
- # verify the changes
- assert_equal( [ ["A", 100],
- ["B", 2],
- ["C", 3],
- ["A", 300],
- ["A", [:a, :b, :c]] ], @row.to_a )
-
- # assigning an index past the end
- assert_equal("End", @row[10] = "End")
- assert_equal( [ ["A", 100],
- ["B", 2],
- ["C", 3],
- ["A", 300],
- ["A", [:a, :b, :c]],
- [nil, nil],
- [nil, nil],
- [nil, nil],
- [nil, nil],
- [nil, nil],
- [nil, "End"] ], @row.to_a )
-
- # assigning a new field by header
- assert_equal("New", @row[:new] = "New")
- assert_equal( [ ["A", 100],
- ["B", 2],
- ["C", 3],
- ["A", 300],
- ["A", [:a, :b, :c]],
- [nil, nil],
- [nil, nil],
- [nil, nil],
- [nil, nil],
- [nil, nil],
- [nil, "End"],
- [:new, "New"] ], @row.to_a )
- end
-
- def test_append
- # add a value
- assert_equal(@row, @row << "Value")
- assert_equal( [ ["A", 1],
- ["B", 2],
- ["C", 3],
- ["A", 4],
- ["A", nil],
- [nil, "Value"] ], @row.to_a )
-
- # add a pair
- assert_equal(@row, @row << %w{Header Field})
- assert_equal( [ ["A", 1],
- ["B", 2],
- ["C", 3],
- ["A", 4],
- ["A", nil],
- [nil, "Value"],
- %w{Header Field} ], @row.to_a )
-
- # a pair with Hash syntax
- assert_equal(@row, @row << {key: :value})
- assert_equal( [ ["A", 1],
- ["B", 2],
- ["C", 3],
- ["A", 4],
- ["A", nil],
- [nil, "Value"],
- %w{Header Field},
- [:key, :value] ], @row.to_a )
-
- # multiple fields at once
- assert_equal(@row, @row.push(100, 200, [:last, 300]))
- assert_equal( [ ["A", 1],
- ["B", 2],
- ["C", 3],
- ["A", 4],
- ["A", nil],
- [nil, "Value"],
- %w{Header Field},
- [:key, :value],
- [nil, 100],
- [nil, 200],
- [:last, 300] ], @row.to_a )
- end
-
- def test_delete
- # by index
- assert_equal(["B", 2], @row.delete(1))
-
- # by header
- assert_equal(["C", 3], @row.delete("C"))
-
- end
-
- def test_delete_if
- assert_equal(@row, @row.delete_if { |h, f| h == "A" and not f.nil? })
- assert_equal([["B", 2], ["C", 3], ["A", nil]], @row.to_a)
- end
-
- def test_delete_if_without_block
- enum = @row.delete_if
- assert_instance_of(Enumerator, enum)
- assert_equal(@row.size, enum.size)
-
- assert_equal(@row, enum.each { |h, f| h == "A" and not f.nil? })
- assert_equal([["B", 2], ["C", 3], ["A", nil]], @row.to_a)
- end
-
- def test_fields
- # all fields
- assert_equal([1, 2, 3, 4, nil], @row.fields)
-
- # by header
- assert_equal([1, 3], @row.fields("A", "C"))
-
- # by index
- assert_equal([2, 3, nil], @row.fields(1, 2, 10))
-
- # by both
- assert_equal([2, 3, 4], @row.fields("B", "C", 3))
-
- # with minimum indices
- assert_equal([2, 3, 4], @row.fields("B", "C", ["A", 3]))
-
- # by header range
- assert_equal([2, 3], @row.values_at("B".."C"))
- end
-
- def test_index
- # basic usage
- assert_equal(0, @row.index("A"))
- assert_equal(1, @row.index("B"))
- assert_equal(2, @row.index("C"))
- assert_equal(nil, @row.index("Z"))
-
- # with minimum index
- assert_equal(0, @row.index("A"))
- assert_equal(0, @row.index("A", 0))
- assert_equal(3, @row.index("A", 1))
- assert_equal(3, @row.index("A", 2))
- assert_equal(3, @row.index("A", 3))
- assert_equal(4, @row.index("A", 4))
- assert_equal(nil, @row.index("A", 5))
- end
-
- def test_queries
- # fields
- assert(@row.field?(4))
- assert(@row.field?(nil))
- assert(!@row.field?(10))
- end
-
- def test_each
- # array style
- ary = @row.to_a
- @row.each do |pair|
- assert_equal(ary.first.first, pair.first)
- assert_equal(ary.shift.last, pair.last)
- end
-
- # hash style
- ary = @row.to_a
- @row.each do |header, field|
- assert_equal(ary.first.first, header)
- assert_equal(ary.shift.last, field)
- end
-
- # verify that we can chain the call
- assert_equal(@row, @row.each { })
-
- # without block
- ary = @row.to_a
- enum = @row.each
- assert_instance_of(Enumerator, enum)
- assert_equal(@row.size, enum.size)
- enum.each do |pair|
- assert_equal(ary.first.first, pair.first)
- assert_equal(ary.shift.last, pair.last)
- end
- end
-
- def test_each_pair
- assert_equal([
- ["A", 1],
- ["B", 2],
- ["C", 3],
- ["A", 4],
- ["A", nil],
- ],
- @row.each_pair.to_a)
- end
-
- def test_enumerable
- assert_equal( [["A", 1], ["A", 4], ["A", nil]],
- @row.select { |pair| pair.first == "A" } )
-
- assert_equal(10, @row.inject(0) { |sum, (_, n)| sum + (n || 0) })
- end
-
- def test_to_a
- row = CSV::Row.new(%w{A B C}, [1, 2, 3]).to_a
- assert_instance_of(Array, row)
- row.each do |pair|
- assert_instance_of(Array, pair)
- assert_equal(2, pair.size)
- end
- assert_equal([["A", 1], ["B", 2], ["C", 3]], row)
- end
-
- def test_to_hash
- hash = @row.to_hash
- assert_equal({"A" => @row["A"], "B" => @row["B"], "C" => @row["C"]}, hash)
- hash.keys.each_with_index do |string_key, h|
- assert_predicate(string_key, :frozen?)
- assert_same(string_key, @row.headers[h])
- end
- end
-
- def test_to_csv
- # normal conversion
- assert_equal("1,2,3,4,\n", @row.to_csv)
- assert_equal("1,2,3,4,\n", @row.to_s) # alias
-
- # with options
- assert_equal( "1|2|3|4|\r\n",
- @row.to_csv(col_sep: "|", row_sep: "\r\n") )
- end
-
- def test_array_delegation
- assert_not_empty(@row, "Row was empty.")
-
- assert_equal([@row.headers.size, @row.fields.size].max, @row.size)
- end
-
- def test_inspect_shows_header_field_pairs
- str = @row.inspect
- @row.each do |header, field|
- assert_include(str, "#{header.inspect}:#{field.inspect}",
- "Header field pair not found.")
- end
- end
-
- def test_inspect_encoding_is_ascii_compatible
- assert_send([Encoding, :compatible?,
- Encoding.find("US-ASCII"),
- @row.inspect.encoding],
- "inspect() was not ASCII compatible.")
- end
-
- def test_inspect_shows_symbol_headers_as_bare_attributes
- str = CSV::Row.new(@row.headers.map { |h| h.to_sym }, @row.fields).inspect
- @row.each do |header, field|
- assert_include(str, "#{header}:#{field.inspect}",
- "Header field pair not found.")
- end
- end
-
- def test_can_be_compared_with_other_classes
- assert_not_nil(CSV::Row.new([ ], [ ]), "The row was nil")
- end
-
- def test_can_be_compared_when_not_a_row
- r = @row == []
- assert_equal false, r
- end
-
- def test_dig_by_index
- assert_equal(2, @row.dig(1))
-
- assert_nil(@row.dig(100))
- end
-
- def test_dig_by_header
- assert_equal(2, @row.dig("B"))
-
- assert_nil(@row.dig("Missing"))
- end
-
- def test_dig_cell
- row = CSV::Row.new(%w{A}, [["foo", ["bar", ["baz"]]]])
-
- assert_equal("foo", row.dig(0, 0))
- assert_equal("bar", row.dig(0, 1, 0))
-
- assert_equal("foo", row.dig("A", 0))
- assert_equal("bar", row.dig("A", 1, 0))
- end
-
- def test_dig_cell_no_dig
- row = CSV::Row.new(%w{A}, ["foo"])
-
- assert_raise(TypeError) do
- row.dig(0, 0)
- end
- assert_raise(TypeError) do
- row.dig("A", 0)
- end
- end
-
- def test_dup
- row = CSV::Row.new(["A"], ["foo"])
- dupped_row = row.dup
- dupped_row["A"] = "bar"
- assert_equal(["foo", "bar"],
- [row["A"], dupped_row["A"]])
- dupped_row.delete("A")
- assert_equal(["foo", nil],
- [row["A"], dupped_row["A"]])
- end
-end
diff --git a/test/csv/test_table.rb b/test/csv/test_table.rb
deleted file mode 100644
index 968e64eae7..0000000000
--- a/test/csv/test_table.rb
+++ /dev/null
@@ -1,620 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "helper"
-
-class TestCSVTable < Test::Unit::TestCase
- extend DifferentOFS
-
- def setup
- super
- @rows = [ CSV::Row.new(%w{A B C}, [1, 2, 3]),
- CSV::Row.new(%w{A B C}, [4, 5, 6]),
- CSV::Row.new(%w{A B C}, [7, 8, 9]) ]
- @table = CSV::Table.new(@rows)
-
- @header_table = CSV::Table.new(
- [CSV::Row.new(%w{A B C}, %w{A B C}, true)] + @rows
- )
-
- @header_only_table = CSV::Table.new([], headers: %w{A B C})
- end
-
- def test_initialize
- assert_not_nil(@table)
- assert_instance_of(CSV::Table, @table)
- end
-
- def test_modes
- assert_equal(:col_or_row, @table.mode)
-
- # non-destructive changes, intended for one shot calls
- cols = @table.by_col
- assert_equal(:col_or_row, @table.mode)
- assert_equal(:col, cols.mode)
- assert_equal(@table, cols)
-
- rows = @table.by_row
- assert_equal(:col_or_row, @table.mode)
- assert_equal(:row, rows.mode)
- assert_equal(@table, rows)
-
- col_or_row = rows.by_col_or_row
- assert_equal(:row, rows.mode)
- assert_equal(:col_or_row, col_or_row.mode)
- assert_equal(@table, col_or_row)
-
- # destructive mode changing calls
- assert_equal(@table, @table.by_row!)
- assert_equal(:row, @table.mode)
- assert_equal(@table, @table.by_col_or_row!)
- assert_equal(:col_or_row, @table.mode)
- end
-
- def test_headers
- assert_equal(@rows.first.headers, @table.headers)
- end
-
- def test_headers_empty
- t = CSV::Table.new([])
- assert_equal Array.new, t.headers
- end
-
- def test_headers_only
- assert_equal(%w[A B C], @header_only_table.headers)
- end
-
- def test_headers_modified_by_row
- table = CSV::Table.new([], headers: ["A", "B"])
- table << ["a", "b"]
- table.first << {"C" => "c"}
- assert_equal(["A", "B", "C"], table.headers)
- end
-
- def test_index
- ##################
- ### Mixed Mode ###
- ##################
- # by row
- @rows.each_index { |i| assert_equal(@rows[i], @table[i]) }
- assert_equal(nil, @table[100]) # empty row
-
- # by row with Range
- assert_equal([@table[1], @table[2]], @table[1..2])
-
- # by col
- @rows.first.headers.each do |header|
- assert_equal(@rows.map { |row| row[header] }, @table[header])
- end
- assert_equal([nil] * @rows.size, @table["Z"]) # empty col
-
- # by cell, row then col
- assert_equal(2, @table[0][1])
- assert_equal(6, @table[1]["C"])
-
- # by cell, col then row
- assert_equal(5, @table["B"][1])
- assert_equal(9, @table["C"][2])
-
- # with headers (by col)
- assert_equal(["B", 2, 5, 8], @header_table["B"])
-
- ###################
- ### Column Mode ###
- ###################
- @table.by_col!
-
- assert_equal([2, 5, 8], @table[1])
- assert_equal([2, 5, 8], @table["B"])
-
- ################
- ### Row Mode ###
- ################
- @table.by_row!
-
- assert_equal(@rows[1], @table[1])
- assert_raise(TypeError) { @table["B"] }
-
- ############################
- ### One Shot Mode Change ###
- ############################
- assert_equal(@rows[1], @table[1])
- assert_equal([2, 5, 8], @table.by_col[1])
- assert_equal(@rows[1], @table[1])
- end
-
- def test_set_row_or_column
- ##################
- ### Mixed Mode ###
- ##################
- # set row
- @table[2] = [10, 11, 12]
- assert_equal([%w[A B C], [1, 2, 3], [4, 5, 6], [10, 11, 12]], @table.to_a)
-
- @table[3] = CSV::Row.new(%w[A B C], [13, 14, 15])
- assert_equal( [%w[A B C], [1, 2, 3], [4, 5, 6], [10, 11, 12], [13, 14, 15]],
- @table.to_a )
-
- # set col
- @table["Type"] = "data"
- assert_equal( [ %w[A B C Type],
- [1, 2, 3, "data"],
- [4, 5, 6, "data"],
- [10, 11, 12, "data"],
- [13, 14, 15, "data"] ],
- @table.to_a )
-
- @table["Index"] = [1, 2, 3]
- assert_equal( [ %w[A B C Type Index],
- [1, 2, 3, "data", 1],
- [4, 5, 6, "data", 2],
- [10, 11, 12, "data", 3],
- [13, 14, 15, "data", nil] ],
- @table.to_a )
-
- @table["B"] = [100, 200]
- assert_equal( [ %w[A B C Type Index],
- [1, 100, 3, "data", 1],
- [4, 200, 6, "data", 2],
- [10, nil, 12, "data", 3],
- [13, nil, 15, "data", nil] ],
- @table.to_a )
-
- # verify resulting table
- assert_equal(<<-CSV, @table.to_csv)
-A,B,C,Type,Index
-1,100,3,data,1
-4,200,6,data,2
-10,,12,data,3
-13,,15,data,
- CSV
-
- # with headers
- @header_table["Type"] = "data"
- assert_equal(%w[Type data data data], @header_table["Type"])
-
- ###################
- ### Column Mode ###
- ###################
- @table.by_col!
-
- @table[1] = [2, 5, 11, 14]
- assert_equal( [ %w[A B C Type Index],
- [1, 2, 3, "data", 1],
- [4, 5, 6, "data", 2],
- [10, 11, 12, "data", 3],
- [13, 14, 15, "data", nil] ],
- @table.to_a )
-
- @table["Extra"] = "new stuff"
- assert_equal( [ %w[A B C Type Index Extra],
- [1, 2, 3, "data", 1, "new stuff"],
- [4, 5, 6, "data", 2, "new stuff"],
- [10, 11, 12, "data", 3, "new stuff"],
- [13, 14, 15, "data", nil, "new stuff"] ],
- @table.to_a )
-
- ################
- ### Row Mode ###
- ################
- @table.by_row!
-
- @table[1] = (1..6).to_a
- assert_equal( [ %w[A B C Type Index Extra],
- [1, 2, 3, "data", 1, "new stuff"],
- [1, 2, 3, 4, 5, 6],
- [10, 11, 12, "data", 3, "new stuff"],
- [13, 14, 15, "data", nil, "new stuff"] ],
- @table.to_a )
-
- assert_raise(TypeError) { @table["Extra"] = nil }
- end
-
- def test_set_by_col_with_header_row
- r = [ CSV::Row.new(%w{X Y Z}, [97, 98, 99], true) ]
- t = CSV::Table.new(r)
- t.by_col!
- t['A'] = [42]
- assert_equal(['A'], t['A'])
- end
-
- def test_each
- ######################
- ### Mixed/Row Mode ###
- ######################
- i = 0
- @table.each do |row|
- assert_equal(@rows[i], row)
- i += 1
- end
-
- # verify that we can chain the call
- assert_equal(@table, @table.each { })
-
- # without block
- enum = @table.each
- assert_instance_of(Enumerator, enum)
- assert_equal(@table.size, enum.size)
-
- i = 0
- enum.each do |row|
- assert_equal(@rows[i], row)
- i += 1
- end
-
- ###################
- ### Column Mode ###
- ###################
- @table.by_col!
-
- headers = @table.headers
- @table.each do |header, column|
- assert_equal(headers.shift, header)
- assert_equal(@table[header], column)
- end
-
- # without block
- enum = @table.each
- assert_instance_of(Enumerator, enum)
- assert_equal(@table.headers.size, enum.size)
-
- headers = @table.headers
- enum.each do |header, column|
- assert_equal(headers.shift, header)
- assert_equal(@table[header], column)
- end
-
- ############################
- ### One Shot Mode Change ###
- ############################
- @table.by_col_or_row!
-
- @table.each { |row| assert_instance_of(CSV::Row, row) }
- @table.by_col.each { |tuple| assert_instance_of(Array, tuple) }
- @table.each { |row| assert_instance_of(CSV::Row, row) }
- end
-
- def test_each_split
- yielded_values = []
- @table.each do |column1, column2, column3|
- yielded_values << [column1, column2, column3]
- end
- assert_equal(@rows.collect(&:to_a),
- yielded_values)
- end
-
- def test_enumerable
- assert_equal( @rows.values_at(0, 2),
- @table.select { |row| (row["B"] % 2).zero? } )
-
- assert_equal(@rows[1], @table.find { |row| row["C"] > 5 })
- end
-
- def test_to_a
- assert_equal([%w[A B C], [1, 2, 3], [4, 5, 6], [7, 8, 9]], @table.to_a)
-
- # with headers
- assert_equal( [%w[A B C], [1, 2, 3], [4, 5, 6], [7, 8, 9]],
- @header_table.to_a )
- end
-
- def test_to_csv
- csv = <<-CSV
-A,B,C
-1,2,3
-4,5,6
-7,8,9
- CSV
-
- # normal conversion
- assert_equal(csv, @table.to_csv)
- assert_equal(csv, @table.to_s) # alias
-
- # with options
- assert_equal( csv.gsub(",", "|").gsub("\n", "\r\n"),
- @table.to_csv(col_sep: "|", row_sep: "\r\n") )
- assert_equal( csv.lines.to_a[1..-1].join(''),
- @table.to_csv(:write_headers => false) )
-
- # with headers
- assert_equal(csv, @header_table.to_csv)
- end
-
- def test_append
- # verify that we can chain the call
- assert_equal(@table, @table << [10, 11, 12])
-
- # Array append
- assert_equal(CSV::Row.new(%w[A B C], [10, 11, 12]), @table[-1])
-
- # Row append
- assert_equal(@table, @table << CSV::Row.new(%w[A B C], [13, 14, 15]))
- assert_equal(CSV::Row.new(%w[A B C], [13, 14, 15]), @table[-1])
- end
-
- def test_delete_mixed_one
- ##################
- ### Mixed Mode ###
- ##################
- # delete a row
- assert_equal(@rows[1], @table.delete(1))
-
- # delete a col
- assert_equal(@rows.map { |row| row["A"] }, @table.delete("A"))
-
- # verify resulting table
- assert_equal(<<-CSV, @table.to_csv)
-B,C
-2,3
-8,9
- CSV
- end
-
- def test_delete_mixed_multiple
- ##################
- ### Mixed Mode ###
- ##################
- # delete row and col
- second_row = @rows[1]
- a_col = @rows.map { |row| row["A"] }
- a_col_without_second_row = a_col[0..0] + a_col[2..-1]
- assert_equal([
- second_row,
- a_col_without_second_row,
- ],
- @table.delete(1, "A"))
-
- # verify resulting table
- assert_equal(<<-CSV, @table.to_csv)
-B,C
-2,3
-8,9
- CSV
- end
-
- def test_delete_column
- ###################
- ### Column Mode ###
- ###################
- @table.by_col!
-
- assert_equal(@rows.map { |row| row[0] }, @table.delete(0))
- assert_equal(@rows.map { |row| row["C"] }, @table.delete("C"))
-
- # verify resulting table
- assert_equal(<<-CSV, @table.to_csv)
-B
-2
-5
-8
- CSV
- end
-
- def test_delete_row
- ################
- ### Row Mode ###
- ################
- @table.by_row!
-
- assert_equal(@rows[1], @table.delete(1))
- assert_raise(TypeError) { @table.delete("C") }
-
- # verify resulting table
- assert_equal(<<-CSV, @table.to_csv)
-A,B,C
-1,2,3
-7,8,9
- CSV
- end
-
- def test_delete_with_blank_rows
- data = "col1,col2\nra1,ra2\n\nrb1,rb2"
- table = CSV.parse(data, :headers => true)
- assert_equal(["ra2", nil, "rb2"], table.delete("col2"))
- end
-
- def test_delete_if_row
- ######################
- ### Mixed/Row Mode ###
- ######################
- # verify that we can chain the call
- assert_equal(@table, @table.delete_if { |row| (row["B"] % 2).zero? })
-
- # verify resulting table
- assert_equal(<<-CSV, @table.to_csv)
-A,B,C
-4,5,6
- CSV
- end
-
- def test_delete_if_row_without_block
- ######################
- ### Mixed/Row Mode ###
- ######################
- enum = @table.delete_if
- assert_instance_of(Enumerator, enum)
- assert_equal(@table.size, enum.size)
-
- # verify that we can chain the call
- assert_equal(@table, enum.each { |row| (row["B"] % 2).zero? })
-
- # verify resulting table
- assert_equal(<<-CSV, @table.to_csv)
-A,B,C
-4,5,6
- CSV
- end
-
- def test_delete_if_column
- ###################
- ### Column Mode ###
- ###################
- @table.by_col!
-
- assert_equal(@table, @table.delete_if { |h, v| h > "A" })
- assert_equal(<<-CSV, @table.to_csv)
-A
-1
-4
-7
- CSV
- end
-
- def test_delete_if_column_without_block
- ###################
- ### Column Mode ###
- ###################
- @table.by_col!
-
- enum = @table.delete_if
- assert_instance_of(Enumerator, enum)
- assert_equal(@table.headers.size, enum.size)
-
- assert_equal(@table, enum.each { |h, v| h > "A" })
- assert_equal(<<-CSV, @table.to_csv)
-A
-1
-4
-7
- CSV
- end
-
- def test_delete_headers_only
- ###################
- ### Column Mode ###
- ###################
- @header_only_table.by_col!
-
- # delete by index
- assert_equal([], @header_only_table.delete(0))
- assert_equal(%w[B C], @header_only_table.headers)
-
- # delete by header
- assert_equal([], @header_only_table.delete("C"))
- assert_equal(%w[B], @header_only_table.headers)
- end
-
- def test_values_at
- ##################
- ### Mixed Mode ###
- ##################
- # rows
- assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
- assert_equal(@rows.values_at(1..2), @table.values_at(1..2))
-
- # cols
- assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
- assert_equal([[2, 3], [5, 6], [8, 9]], @table.values_at("B".."C"))
-
- ###################
- ### Column Mode ###
- ###################
- @table.by_col!
-
- assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at(0, 2))
- assert_equal([[1, 3], [4, 6], [7, 9]], @table.values_at("A", "C"))
-
- ################
- ### Row Mode ###
- ################
- @table.by_row!
-
- assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
- assert_raise(TypeError) { @table.values_at("A", "C") }
-
- ############################
- ### One Shot Mode Change ###
- ############################
- assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
- assert_equal([[1, 3], [4, 6], [7, 9]], @table.by_col.values_at(0, 2))
- assert_equal(@rows.values_at(0, 2), @table.values_at(0, 2))
- end
-
- def test_array_delegation
- assert_not_empty(@table, "Table was empty.")
-
- assert_equal(@rows.size, @table.size)
- end
-
- def test_inspect_shows_current_mode
- str = @table.inspect
- assert_include(str, "mode:#{@table.mode}", "Mode not shown.")
-
- @table.by_col!
- str = @table.inspect
- assert_include(str, "mode:#{@table.mode}", "Mode not shown.")
- end
-
- def test_inspect_encoding_is_ascii_compatible
- assert_send([Encoding, :compatible?,
- Encoding.find("US-ASCII"),
- @table.inspect.encoding],
- "inspect() was not ASCII compatible." )
- end
-
- def test_dig_mixed
- # by row
- assert_equal(@rows[0], @table.dig(0))
- assert_nil(@table.dig(100)) # empty row
-
- # by col
- assert_equal([2, 5, 8], @table.dig("B"))
- assert_equal([nil] * @rows.size, @table.dig("Z")) # empty col
-
- # by row then col
- assert_equal(2, @table.dig(0, 1))
- assert_equal(6, @table.dig(1, "C"))
-
- # by col then row
- assert_equal(5, @table.dig("B", 1))
- assert_equal(9, @table.dig("C", 2))
- end
-
- def test_dig_by_column
- @table.by_col!
-
- assert_equal([2, 5, 8], @table.dig(1))
- assert_equal([2, 5, 8], @table.dig("B"))
-
- # by col then row
- assert_equal(5, @table.dig("B", 1))
- assert_equal(9, @table.dig("C", 2))
- end
-
- def test_dig_by_row
- @table.by_row!
-
- assert_equal(@rows[1], @table.dig(1))
- assert_raise(TypeError) { @table.dig("B") }
-
- # by row then col
- assert_equal(2, @table.dig(0, 1))
- assert_equal(6, @table.dig(1, "C"))
- end
-
- def test_dig_cell
- table = CSV::Table.new([CSV::Row.new(["A"], [["foo", ["bar", ["baz"]]]])])
-
- # by row, col then cell
- assert_equal("foo", table.dig(0, "A", 0))
- assert_equal(["baz"], table.dig(0, "A", 1, 1))
-
- # by col, row then cell
- assert_equal("foo", table.dig("A", 0, 0))
- assert_equal(["baz"], table.dig("A", 0, 1, 1))
- end
-
- def test_dig_cell_no_dig
- table = CSV::Table.new([CSV::Row.new(["A"], ["foo"])])
-
- # by row, col then cell
- assert_raise(TypeError) do
- table.dig(0, "A", 0)
- end
-
- # by col, row then cell
- assert_raise(TypeError) do
- table.dig("A", 0, 0)
- end
- end
-end
diff --git a/test/csv/write/test_converters.rb b/test/csv/write/test_converters.rb
deleted file mode 100644
index 0e0080b4c5..0000000000
--- a/test/csv/write/test_converters.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-module TestCSVWriteConverters
- def test_one
- assert_equal(%Q[=a,=b,=c\n],
- generate_line(["a", "b", "c"],
- write_converters: ->(value) {"=" + value}))
- end
-
- def test_multiple
- assert_equal(%Q[=a_,=b_,=c_\n],
- generate_line(["a", "b", "c"],
- write_converters: [
- ->(value) {"=" + value},
- ->(value) {value + "_"},
- ]))
- end
-
- def test_nil_value
- assert_equal(%Q[a,NaN,29\n],
- generate_line(["a", nil, 29],
- write_nil_value: "NaN"))
- end
-
- def test_empty_value
- assert_equal(%Q[a,,29\n],
- generate_line(["a", "", 29],
- write_empty_value: nil))
- end
-end
-
-class TestCSVWriteConvertersGenerateLine < Test::Unit::TestCase
- include TestCSVWriteConverters
- extend DifferentOFS
-
- def generate_line(row, **kwargs)
- CSV.generate_line(row, **kwargs)
- end
-end
-
-class TestCSVWriteConvertersGenerate < Test::Unit::TestCase
- include TestCSVWriteConverters
- extend DifferentOFS
-
- def generate_line(row, **kwargs)
- CSV.generate(**kwargs) do |csv|
- csv << row
- end
- end
-end
diff --git a/test/csv/write/test_force_quotes.rb b/test/csv/write/test_force_quotes.rb
deleted file mode 100644
index 622dcb021b..0000000000
--- a/test/csv/write/test_force_quotes.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-module TestCSVWriteForceQuotes
- def test_default
- assert_equal(%Q[1,2,3#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["1", "2", "3"]))
- end
-
- def test_true
- assert_equal(%Q["1","2","3"#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["1", "2", "3"],
- force_quotes: true))
- end
-
- def test_false
- assert_equal(%Q[1,2,3#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["1", "2", "3"],
- force_quotes: false))
- end
-
- def test_field_name
- assert_equal(%Q["1",2,"3"#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["1", "2", "3"],
- headers: ["a", "b", "c"],
- force_quotes: ["a", :c]))
- end
-
- def test_field_name_without_headers
- force_quotes = ["a", "c"]
- error = assert_raise(ArgumentError) do
- generate_line(["1", "2", "3"],
- force_quotes: force_quotes)
- end
- assert_equal(":headers is required when you use field name " +
- "in :force_quotes: " +
- "#{force_quotes.first.inspect}: #{force_quotes.inspect}",
- error.message)
- end
-
- def test_field_index
- assert_equal(%Q["1",2,"3"#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["1", "2", "3"],
- force_quotes: [0, 2]))
- end
-
- def test_field_unknown
- force_quotes = [1.1]
- error = assert_raise(ArgumentError) do
- generate_line(["1", "2", "3"],
- force_quotes: force_quotes)
- end
- assert_equal(":force_quotes element must be field index or field name: " +
- "#{force_quotes.first.inspect}: #{force_quotes.inspect}",
- error.message)
- end
-end
-
-class TestCSVWriteForceQuotesGenerateLine < Test::Unit::TestCase
- include TestCSVWriteForceQuotes
- extend DifferentOFS
-
- def generate_line(row, **kwargs)
- CSV.generate_line(row, **kwargs)
- end
-end
-
-class TestCSVWriteForceQuotesGenerate < Test::Unit::TestCase
- include TestCSVWriteForceQuotes
- extend DifferentOFS
-
- def generate_line(row, **kwargs)
- CSV.generate(**kwargs) do |csv|
- csv << row
- end
- end
-end
diff --git a/test/csv/write/test_general.rb b/test/csv/write/test_general.rb
deleted file mode 100644
index 677119e1ae..0000000000
--- a/test/csv/write/test_general.rb
+++ /dev/null
@@ -1,246 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-module TestCSVWriteGeneral
- include Helper
-
- def test_tab
- assert_equal("\t#{$INPUT_RECORD_SEPARATOR}",
- generate_line(["\t"]))
- end
-
- def test_quote_character
- assert_equal(%Q[foo,"""",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", %Q["], "baz"]))
- end
-
- def test_quote_character_double
- assert_equal(%Q[foo,"""""",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", %Q[""], "baz"]))
- end
-
- def test_quote
- assert_equal(%Q[foo,"""bar""",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", %Q["bar"], "baz"]))
- end
-
- def test_quote_lf
- assert_equal(%Q["""\n","""\n"#{$INPUT_RECORD_SEPARATOR}],
- generate_line([%Q["\n], %Q["\n]]))
- end
-
- def test_quote_cr
- assert_equal(%Q["""\r","""\r"#{$INPUT_RECORD_SEPARATOR}],
- generate_line([%Q["\r], %Q["\r]]))
- end
-
- def test_quote_last
- assert_equal(%Q[foo,"bar"""#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", %Q[bar"]]))
- end
-
- def test_quote_lf_last
- assert_equal(%Q[foo,"\nbar"""#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", %Q[\nbar"]]))
- end
-
- def test_quote_lf_value_lf
- assert_equal(%Q[foo,"""\nbar\n"""#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", %Q["\nbar\n"]]))
- end
-
- def test_quote_lf_value_lf_nil
- assert_equal(%Q[foo,"""\nbar\n""",#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", %Q["\nbar\n"], nil]))
- end
-
- def test_cr
- assert_equal(%Q[foo,"\r",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "\r", "baz"]))
- end
-
- def test_lf
- assert_equal(%Q[foo,"\n",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "\n", "baz"]))
- end
-
- def test_cr_lf
- assert_equal(%Q[foo,"\r\n",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "\r\n", "baz"]))
- end
-
- def test_cr_dot_lf
- assert_equal(%Q[foo,"\r.\n",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "\r.\n", "baz"]))
- end
-
- def test_cr_lf_cr
- assert_equal(%Q[foo,"\r\n\r",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "\r\n\r", "baz"]))
- end
-
- def test_cr_lf_lf
- assert_equal(%Q[foo,"\r\n\n",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "\r\n\n", "baz"]))
- end
-
- def test_cr_lf_comma
- assert_equal(%Q["\r\n,"#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["\r\n,"]))
- end
-
- def test_cr_lf_comma_nil
- assert_equal(%Q["\r\n,",#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["\r\n,", nil]))
- end
-
- def test_comma
- assert_equal(%Q[","#{$INPUT_RECORD_SEPARATOR}],
- generate_line([","]))
- end
-
- def test_comma_double
- assert_equal(%Q[",",","#{$INPUT_RECORD_SEPARATOR}],
- generate_line([",", ","]))
- end
-
- def test_comma_and_value
- assert_equal(%Q[foo,"foo,bar",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "foo,bar", "baz"]))
- end
-
- def test_one_element
- assert_equal(%Q[foo#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo"]))
- end
-
- def test_nil_values_only
- assert_equal(%Q[,,#{$INPUT_RECORD_SEPARATOR}],
- generate_line([nil, nil, nil]))
- end
-
- def test_nil_double_only
- assert_equal(%Q[,#{$INPUT_RECORD_SEPARATOR}],
- generate_line([nil, nil]))
- end
-
- def test_nil_values
- assert_equal(%Q[foo,,,#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", nil, nil, nil]))
- end
-
- def test_nil_value_first
- assert_equal(%Q[,foo,baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line([nil, "foo", "baz"]))
- end
-
- def test_nil_value_middle
- assert_equal(%Q[foo,,baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", nil, "baz"]))
- end
-
- def test_nil_value_last
- assert_equal(%Q[foo,baz,#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "baz", nil]))
- end
-
- def test_nil_empty
- assert_equal(%Q[,""#{$INPUT_RECORD_SEPARATOR}],
- generate_line([nil, ""]))
- end
-
- def test_nil_cr
- assert_equal(%Q[,"\r"#{$INPUT_RECORD_SEPARATOR}],
- generate_line([nil, "\r"]))
- end
-
- def test_values
- assert_equal(%Q[foo,bar#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "bar"]))
- end
-
- def test_semi_colon
- assert_equal(%Q[;#{$INPUT_RECORD_SEPARATOR}],
- generate_line([";"]))
- end
-
- def test_semi_colon_values
- assert_equal(%Q[;,;#{$INPUT_RECORD_SEPARATOR}],
- generate_line([";", ";"]))
- end
-
- def test_tab_values
- assert_equal(%Q[\t,\t#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["\t", "\t"]))
- end
-
- def test_col_sep
- assert_equal(%Q[a;b;;c#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["a", "b", nil, "c"],
- col_sep: ";"))
- assert_equal(%Q[a\tb\t\tc#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["a", "b", nil, "c"],
- col_sep: "\t"))
- end
-
- def test_row_sep
- assert_equal(%Q[a,b,,c\r\n],
- generate_line(["a", "b", nil, "c"],
- row_sep: "\r\n"))
- end
-
- def test_force_quotes
- assert_equal(%Q["1","b","","already ""quoted"""#{$INPUT_RECORD_SEPARATOR}],
- generate_line([1, "b", nil, %Q{already "quoted"}],
- force_quotes: true))
- end
-
- def test_encoding_utf8
- assert_equal(%Q[あ,い,う#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["あ" , "い", "う"]))
- end
-
- def test_encoding_euc_jp
- row = ["あ", "い", "う"].collect {|field| field.encode("EUC-JP")}
- assert_equal(%Q[あ,い,う#{$INPUT_RECORD_SEPARATOR}].encode("EUC-JP"),
- generate_line(row))
- end
-
- def test_encoding_with_default_internal
- with_default_internal(Encoding::UTF_8) do
- row = ["あ", "い", "う"].collect {|field| field.encode("EUC-JP")}
- assert_equal(%Q[あ,い,う#{$INPUT_RECORD_SEPARATOR}].encode("EUC-JP"),
- generate_line(row, encoding: Encoding::EUC_JP))
- end
- end
-
- def test_with_default_internal
- with_default_internal(Encoding::UTF_8) do
- row = ["あ", "い", "う"].collect {|field| field.encode("EUC-JP")}
- assert_equal(%Q[あ,い,う#{$INPUT_RECORD_SEPARATOR}].encode("EUC-JP"),
- generate_line(row))
- end
- end
-end
-
-class TestCSVWriteGeneralGenerateLine < Test::Unit::TestCase
- include TestCSVWriteGeneral
- extend DifferentOFS
-
- def generate_line(row, **kwargs)
- CSV.generate_line(row, **kwargs)
- end
-end
-
-class TestCSVWriteGeneralGenerate < Test::Unit::TestCase
- include TestCSVWriteGeneral
- extend DifferentOFS
-
- def generate_line(row, **kwargs)
- CSV.generate(**kwargs) do |csv|
- csv << row
- end
- end
-end
diff --git a/test/csv/write/test_quote_empty.rb b/test/csv/write/test_quote_empty.rb
deleted file mode 100644
index 70f73dad4a..0000000000
--- a/test/csv/write/test_quote_empty.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-# -*- coding: utf-8 -*-
-# frozen_string_literal: false
-
-require_relative "../helper"
-
-module TestCSVWriteQuoteEmpty
- def test_quote_empty_default
- assert_equal(%Q["""",""#{$INPUT_RECORD_SEPARATOR}],
- generate_line([%Q["], ""]))
- end
-
- def test_quote_empty_false
- assert_equal(%Q["""",#{$INPUT_RECORD_SEPARATOR}],
- generate_line([%Q["], ""],
- quote_empty: false))
- end
-
- def test_empty_default
- assert_equal(%Q[foo,"",baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "", "baz"]))
- end
-
- def test_empty_false
- assert_equal(%Q[foo,,baz#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["foo", "", "baz"],
- quote_empty: false))
- end
-
- def test_empty_only_default
- assert_equal(%Q[""#{$INPUT_RECORD_SEPARATOR}],
- generate_line([""]))
- end
-
- def test_empty_only_false
- assert_equal(%Q[#{$INPUT_RECORD_SEPARATOR}],
- generate_line([""],
- quote_empty: false))
- end
-
- def test_empty_double_default
- assert_equal(%Q["",""#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["", ""]))
- end
-
- def test_empty_double_false
- assert_equal(%Q[,#{$INPUT_RECORD_SEPARATOR}],
- generate_line(["", ""],
- quote_empty: false))
- end
-end
-
-class TestCSVWriteQuoteEmptyGenerateLine < Test::Unit::TestCase
- include TestCSVWriteQuoteEmpty
- extend DifferentOFS
-
- def generate_line(row, **kwargs)
- CSV.generate_line(row, **kwargs)
- end
-end
-
-class TestCSVWriteQuoteEmptyGenerate < Test::Unit::TestCase
- include TestCSVWriteQuoteEmpty
- extend DifferentOFS
-
- def generate_line(row, **kwargs)
- CSV.generate(**kwargs) do |csv|
- csv << row
- end
- end
-end
diff --git a/test/date/test_date.rb b/test/date/test_date.rb
index 6e99bc562c..3f9c893efa 100644
--- a/test/date/test_date.rb
+++ b/test/date/test_date.rb
@@ -175,4 +175,33 @@ class TestDate < Test::Unit::TestCase
assert_equal(-1, -Float::INFINITY <=> Date::Infinity.new)
assert_equal(-1, -Date::Infinity.new <=> Float::INFINITY)
end
+
+ def test_deconstruct_keys
+ d = Date.new(1999,5,23)
+ assert_equal({year: 1999, month: 5, day: 23, wday: 0, yday: 143}, d.deconstruct_keys(nil))
+ assert_equal({year: 1999}, d.deconstruct_keys([:year, :century]))
+ assert_equal(
+ {year: 1999, month: 5, day: 23, wday: 0, yday: 143},
+ d.deconstruct_keys([:year, :month, :day, :wday, :yday])
+ )
+
+ dt = DateTime.new(1999, 5, 23, 4, 20, Rational(1, 10000))
+
+ assert_equal(
+ {year: 1999, month: 5, day: 23, wday: 0, yday: 143,
+ hour: 4, min: 20, sec: 0, sec_fraction: Rational(1, 10000), zone: "+00:00"},
+ dt.deconstruct_keys(nil)
+ )
+
+ assert_equal({year: 1999}, dt.deconstruct_keys([:year, :century]))
+
+ assert_equal(
+ {year: 1999, month: 5, day: 23, wday: 0, yday: 143,
+ hour: 4, min: 20, sec: 0, sec_fraction: Rational(1, 10000), zone: "+00:00"},
+ dt.deconstruct_keys([:year, :month, :day, :wday, :yday, :hour, :min, :sec, :sec_fraction, :zone])
+ )
+
+ dtz = DateTime.parse('3rd Feb 2001 04:05:06+03:30')
+ assert_equal({zone: '+03:30'}, dtz.deconstruct_keys([:zone]))
+ end
end
diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb
index d8dcf6e05e..16362e3bff 100644
--- a/test/date/test_date_parse.rb
+++ b/test/date/test_date_parse.rb
@@ -41,6 +41,7 @@ class TestDateParse < Test::Unit::TestCase
[['Sat Aug 28 02:29:34 Mountain Daylight Time 2000',false],[2000,8,28,2,29,34,'Mountain Daylight Time',-6*3600,6], __LINE__],
[['Sat Aug 28 02:29:34 Mexico Standard Time 2000',false],[2000,8,28,2,29,34,'Mexico Standard Time',-6*3600,6], __LINE__],
[['Sat Aug 28 02:29:34 E. Australia Standard Time 2000',false],[2000,8,28,2,29,34,'E. Australia Standard Time',10*3600,6], __LINE__],
+ [['Sat Aug 28 02:29:34 W. Central Africa Standard Time 2000',false],[2000,8,28,2,29,34,'W. Central Africa Standard Time',1*3600,6], __LINE__],
# part of iso 8601
[['1999-05-23 23:55:21',false],[1999,5,23,23,55,21,nil,nil,nil], __LINE__],
@@ -132,6 +133,7 @@ class TestDateParse < Test::Unit::TestCase
[['19990523235521.123[-9]',false],[1999,5,23,23,55,21,'-9',-(9*3600),nil], __LINE__],
[['19990523235521.123[+9]',false],[1999,5,23,23,55,21,'+9',+(9*3600),nil], __LINE__],
[['19990523235521.123[9]',false],[1999,5,23,23,55,21,'9',+(9*3600),nil], __LINE__],
+ [['19990523235521.123[9 ]',false],[1999,5,23,23,55,21,'9 ',+(9*3600),nil], __LINE__],
[['19990523235521.123[-9.50]',false],[1999,5,23,23,55,21,'-9.50',-(9*3600+30*60),nil], __LINE__],
[['19990523235521.123[+9.50]',false],[1999,5,23,23,55,21,'+9.50',+(9*3600+30*60),nil], __LINE__],
[['19990523235521.123[-5:EST]',false],[1999,5,23,23,55,21,'EST',-5*3600,nil], __LINE__],
@@ -140,6 +142,7 @@ class TestDateParse < Test::Unit::TestCase
[['235521.123',false],[nil,nil,nil,23,55,21,nil,nil,nil], __LINE__],
[['235521.123[-9]',false],[nil,nil,nil,23,55,21,'-9',-9*3600,nil], __LINE__],
[['235521.123[+9]',false],[nil,nil,nil,23,55,21,'+9',+9*3600,nil], __LINE__],
+ [['235521.123[-9 ]',false],[nil,nil,nil,23,55,21,'-9 ',-9*3600,nil], __LINE__],
[['235521.123[-5:EST]',false],[nil,nil,nil,23,55,21,'EST',-5*3600,nil], __LINE__],
[['235521.123[+9:JST]',false],[nil,nil,nil,23,55,21,'JST',+9*3600,nil], __LINE__],
@@ -864,9 +867,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._iso8601(nil)
assert_equal({}, h)
- h = assert_deprecated_warn {Date._iso8601('01-02-03T04:05:06Z'.to_sym)}
- assert_equal([2001, 2, 3, 4, 5, 6, 0],
- h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ assert_raise(TypeError) {Date._iso8601('01-02-03T04:05:06Z'.to_sym)}
end
def test__rfc3339
@@ -886,9 +887,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._rfc3339(nil)
assert_equal({}, h)
- h = assert_deprecated_warn {Date._rfc3339('2001-02-03T04:05:06Z'.to_sym)}
- assert_equal([2001, 2, 3, 4, 5, 6, 0],
- h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ assert_raise(TypeError) {Date._rfc3339('2001-02-03T04:05:06Z'.to_sym)}
end
def test__xmlschema
@@ -975,9 +974,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._xmlschema(nil)
assert_equal({}, h)
- h = assert_deprecated_warn {Date._xmlschema('2001-02-03'.to_sym)}
- assert_equal([2001, 2, 3, nil, nil, nil, nil],
- h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ assert_raise(TypeError) {Date._xmlschema('2001-02-03'.to_sym)}
end
def test__rfc2822
@@ -1014,9 +1011,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._rfc2822(nil)
assert_equal({}, h)
- h = assert_deprecated_warn {Date._rfc2822('Sat, 3 Feb 2001 04:05:06 UT'.to_sym)}
- assert_equal([2001, 2, 3, 4, 5, 6, 0],
- h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ assert_raise(TypeError) {Date._rfc2822('Sat, 3 Feb 2001 04:05:06 UT'.to_sym)}
end
def test__httpdate
@@ -1041,9 +1036,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._httpdate(nil)
assert_equal({}, h)
- h = assert_deprecated_warn {Date._httpdate('Sat, 03 Feb 2001 04:05:06 GMT'.to_sym)}
- assert_equal([2001, 2, 3, 4, 5, 6, 0],
- h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ assert_raise(TypeError) {Date._httpdate('Sat, 03 Feb 2001 04:05:06 GMT'.to_sym)}
end
def test__jisx0301
@@ -1124,9 +1117,7 @@ class TestDateParse < Test::Unit::TestCase
h = Date._jisx0301(nil)
assert_equal({}, h)
- h = assert_deprecated_warn {Date._jisx0301('H13.02.03T04:05:06.07+0100'.to_sym)}
- assert_equal([2001, 2, 3, 4, 5, 6, 3600],
- h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
+ assert_raise(TypeError) {Date._jisx0301('H13.02.03T04:05:06.07+0100'.to_sym)}
end
def test_iso8601
diff --git a/test/date/test_date_strptime.rb b/test/date/test_date_strptime.rb
index fc42ebf7cd..4efe1a47d0 100644
--- a/test/date/test_date_strptime.rb
+++ b/test/date/test_date_strptime.rb
@@ -180,6 +180,10 @@ class TestDateStrptime < Test::Unit::TestCase
[['fri1feb034pm+5', '%a%d%b%y%H%p%Z'], [2003,2,1,16,nil,nil,'+5',5*3600,5]],
[['E. Australia Standard Time', '%Z'], [nil,nil,nil,nil,nil,nil,'E. Australia Standard Time',10*3600,nil], __LINE__],
+
+ # out of range
+ [['+0.9999999999999999999999', '%Z'], [nil,nil,nil,nil,nil,nil,'+0.9999999999999999999999',+1*3600,nil], __LINE__],
+ [['+9999999999999999999999.0', '%Z'], [nil,nil,nil,nil,nil,nil,'+9999999999999999999999.0',nil,nil], __LINE__],
].each do |x, y|
h = Date._strptime(*x)
a = h.values_at(:year,:mon,:mday,:hour,:min,:sec,:zone,:offset,:wday)
@@ -292,6 +296,11 @@ class TestDateStrptime < Test::Unit::TestCase
assert_not_nil(Date._strptime('Januari', '%B'))
assert_nil(Date._strptime('Sundai,', '%A,'))
assert_nil(Date._strptime('Januari,', '%B,'))
+
+ assert_nil(Date._strptime('+24:00', '%Z')[:offset])
+ assert_nil(Date._strptime('+23:60', '%Z')[:offset])
+ assert_nil(Date._strptime('+23:00:60', '%Z')[:offset])
+ assert_nil(Date._strptime('+23:00:60', '%Z')[:offset])
end
def test_strptime
diff --git a/test/did_you_mean/core_ext/test_name_error_extension.rb b/test/did_you_mean/core_ext/test_name_error_extension.rb
index 1fdbd4510f..116c7cd7b9 100644
--- a/test/did_you_mean/core_ext/test_name_error_extension.rb
+++ b/test/did_you_mean/core_ext/test_name_error_extension.rb
@@ -49,7 +49,7 @@ class NameErrorExtensionTest < Test::Unit::TestCase
get_message(error)
- assert_equal "undefined method `sizee' for #<File:test_name_error_extension.rb (closed)>",
- Marshal.load(Marshal.dump(error)).original_message
+ assert_match(/^undefined method [`']sizee' for /,
+ Marshal.load(Marshal.dump(error)).original_message)
end
end
diff --git a/test/did_you_mean/spell_checking/test_method_name_check.rb b/test/did_you_mean/spell_checking/test_method_name_check.rb
index d2e46d58f3..4daaf7cec7 100644
--- a/test/did_you_mean/spell_checking/test_method_name_check.rb
+++ b/test/did_you_mean/spell_checking/test_method_name_check.rb
@@ -4,6 +4,8 @@ class MethodNameCheckTest < Test::Unit::TestCase
include DidYouMean::TestHelper
class User
+ attr_writer :writer
+ attr_reader :reader
def friends; end
def first_name; end
def descendants; end
@@ -144,4 +146,20 @@ class MethodNameCheckTest < Test::Unit::TestCase
assert_correction [], error.corrections
assert_not_match(/Did you mean\? +yield/, get_message(error))
end if RUBY_ENGINE != "jruby"
+
+ # Do not suggest `name=` for `name`
+ def test_does_not_suggest_writer
+ error = assert_raise(NoMethodError) { @user.writer }
+
+ assert_correction [], error.corrections
+ assert_not_match(/Did you mean\? writer=/, get_message(error))
+ end
+
+ # Do not suggest `name` for `name=`
+ def test_does_not_suggest_reader
+ error = assert_raise(NoMethodError) { @user.reader = 1 }
+
+ assert_correction [], error.corrections
+ assert_not_match(/Did you mean\? reader/, get_message(error))
+ end
end
diff --git a/test/did_you_mean/spell_checking/test_variable_name_check.rb b/test/did_you_mean/spell_checking/test_variable_name_check.rb
index 9d8b86eb5b..0350b62660 100644
--- a/test/did_you_mean/spell_checking/test_variable_name_check.rb
+++ b/test/did_you_mean/spell_checking/test_variable_name_check.rb
@@ -137,4 +137,16 @@ class VariableNameCheckTest < Test::Unit::TestCase
error = assert_raise(NameError){ foo }
assert_empty error.corrections
end
+
+ def test_exclude_duplicates_with_same_name
+ error = assert_raise(NameError) do
+ eval(<<~RUBY, binding, __FILE__, __LINE__)
+ bar = 1
+ def bar;end
+ zar
+ RUBY
+ end
+
+ assert_correction [:bar], error.corrections
+ end
end
diff --git a/test/drb/drbtest.rb b/test/drb/drbtest.rb
deleted file mode 100644
index 3c33aedb6f..0000000000
--- a/test/drb/drbtest.rb
+++ /dev/null
@@ -1,394 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'envutil'
-require 'drb/drb'
-require 'drb/extservm'
-require 'timeout'
-
-module DRbTests
-
-class DRbService
- @@ruby = [EnvUtil.rubybin]
- @@ruby << "-d" if $DEBUG
- def self.add_service_command(nm)
- dir = File.dirname(File.expand_path(__FILE__))
- DRb::ExtServManager.command[nm] = @@ruby + ["#{dir}/#{nm}"]
- end
-
- %w(ut_drb.rb ut_array.rb ut_port.rb ut_large.rb ut_safe1.rb ut_eq.rb).each do |nm|
- add_service_command(nm)
- end
-
- def initialize
- @manager = DRb::ExtServManager.new
- start
- @manager.uri = server.uri
- end
-
- def start
- @server = DRb::DRbServer.new('druby://localhost:0', manager, {})
- end
-
- attr_reader :manager
- attr_reader :server
-
- def ext_service(name)
- EnvUtil.timeout(100, RuntimeError) do
- manager.service(name)
- end
- end
-
- def finish
- server.instance_variable_get(:@grp).list.each {|th| th.join }
- server.stop_service
- manager.instance_variable_get(:@queue)&.push(nil)
- manager.instance_variable_get(:@thread)&.join
- DRb::DRbConn.stop_pool
- end
-end
-
-class Onecky
- include DRbUndumped
- def initialize(n)
- @num = n
- end
-
- def to_i
- @num.to_i
- end
-
- def sleep(n)
- Kernel.sleep(n)
- to_i
- end
-end
-
-class FailOnecky < Onecky
- class OneckyError < RuntimeError; end
- def to_i
- raise(OneckyError, @num.to_s)
- end
-end
-
-class XArray < Array
- def initialize(ary)
- ary.each do |x|
- self.push(x)
- end
- end
-end
-
-module DRbBase
- def setup
- @drb_service ||= DRbService.new
- end
-
- def setup_service(service_name)
- @service_name = service_name
- @ext = @drb_service.ext_service(@service_name)
- @there = @ext.front
- end
-
- def teardown
- @ext.stop_service if defined?(@ext) && @ext
- if defined?(@service_name) && @service_name
- @drb_service.manager.unregist(@service_name)
- while (@there&&@there.to_s rescue nil)
- # nop
- end
- signal = /mswin|mingw/ =~ RUBY_PLATFORM ? :KILL : :TERM
- Thread.list.each {|th|
- if th.respond_to?(:pid) && th[:drb_service] == @service_name
- 10.times do
- begin
- Process.kill signal, th.pid
- break
- rescue Errno::ESRCH
- break
- rescue Errno::EPERM # on Windows
- sleep 0.1
- retry
- end
- end
- th.join
- end
- }
- end
- @drb_service.finish
- DRb::DRbConn.stop_pool
- end
-end
-
-module DRbCore
- include DRbBase
-
- def test_00_DRbObject
- ro = DRbObject.new(nil, 'druby://localhost:12345')
- assert_equal('druby://localhost:12345', ro.__drburi)
- assert_equal(nil, ro.__drbref)
-
- ro = DRbObject.new_with_uri('druby://localhost:12345')
- assert_equal('druby://localhost:12345', ro.__drburi)
- assert_equal(nil, ro.__drbref)
-
- ro = DRbObject.new_with_uri('druby://localhost:12345?foobar')
- assert_equal('druby://localhost:12345', ro.__drburi)
- assert_equal(DRb::DRbURIOption.new('foobar'), ro.__drbref)
- end
-
- def test_01
- assert_equal("hello", @there.hello)
- onecky = Onecky.new('3')
- assert_equal(6, @there.sample(onecky, 1, 2))
- ary = @there.to_a
- assert_kind_of(DRb::DRbObject, ary)
-
- assert_respond_to(@there, [:to_a, true])
- assert_respond_to(@there, [:eval, true])
- assert_not_respond_to(@there, [:eval, false])
- assert_not_respond_to(@there, :eval)
- end
-
- def test_01_02_loop
- onecky = Onecky.new('3')
- 50.times do
- assert_equal(6, @there.sample(onecky, 1, 2))
- ary = @there.to_a
- assert_kind_of(DRb::DRbObject, ary)
- end
- end
-
- def test_02_basic_object
- obj = @there.basic_object
- assert_kind_of(DRb::DRbObject, obj)
- assert_equal(1, obj.foo)
- assert_raise(NoMethodError){obj.prot}
- assert_raise(NoMethodError){obj.priv}
- end
-
- def test_02_unknown
- obj = @there.unknown_class
- assert_kind_of(DRb::DRbUnknown, obj)
- assert_equal('DRbTests::Unknown2', obj.name)
-
- obj = @there.unknown_module
- assert_kind_of(DRb::DRbUnknown, obj)
- assert_equal('DRbTests::DRbEx::', obj.name)
-
- assert_raise(DRb::DRbUnknownError) do
- @there.unknown_error
- end
-
- onecky = FailOnecky.new('3')
-
- assert_raise(FailOnecky::OneckyError) do
- @there.sample(onecky, 1, 2)
- end
- end
-
- def test_03
- assert_equal(8, @there.sum(1, 1, 1, 1, 1, 1, 1, 1))
- assert_raise(DRb::DRbConnError) do
- @there.sum(1, 1, 1, 1, 1, 1, 1, 1, 1)
- end
- assert_raise(DRb::DRbConnError) do
- @there.sum('1' * 4096)
- end
- end
-
- def test_04
- assert_respond_to(@there, 'sum')
- assert_not_respond_to(@there, "foobar")
- end
-
- def test_05_eq
- a = @there.to_a[0]
- b = @there.to_a[0]
- assert_not_same(a, b)
- assert_equal(a, b)
- assert_equal(a, @there)
- assert_equal(a.hash, b.hash)
- assert_equal(a.hash, @there.hash)
- assert_operator(a, :eql?, b)
- assert_operator(a, :eql?, @there)
- end
-
- def test_06_timeout
- omit if RUBY_PLATFORM.include?("armv7l-linux")
- omit if RUBY_PLATFORM.include?("sparc-solaris2.10")
- omit if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # expecting a certain delay is difficult for --jit-wait CI
- Timeout.timeout(60) do
- ten = Onecky.new(10)
- assert_raise(Timeout::Error) do
- @there.do_timeout(ten)
- end
- assert_raise(Timeout::Error) do
- @there.do_timeout(ten)
- end
- end
- end
-
- def test_07_private_missing
- e = assert_raise(NoMethodError) {
- @there.method_missing(:eval, 'nil')
- }
- assert_match(/^private method \`eval\'/, e.message)
-
- e = assert_raise(NoMethodError) {
- @there.call_private_method
- }
- assert_match(/^private method \`call_private_method\'/, e.message)
- end
-
- def test_07_protected_missing
- e = assert_raise(NoMethodError) {
- @there.call_protected_method
- }
- assert_match(/^protected method \`call_protected_method\'/, e.message)
- end
-
- def test_07_public_missing
- e = assert_raise(NoMethodError) {
- @there.method_missing(:undefined_method_test)
- }
- assert_match(/^undefined method \`undefined_method_test\'/, e.message)
- end
-
- def test_07_send_missing
- assert_raise(DRb::DRbConnError) do
- @there.method_missing(:__send__, :to_s)
- end
- assert_equal(true, @there.missing)
- end
-
- def test_08_here
- ro = DRbObject.new(nil, DRb.uri)
- assert_kind_of(String, ro.to_s)
-
- ro = DRbObject.new_with_uri(DRb.uri)
- assert_kind_of(String, ro.to_s)
- end
-
- def uri_concat_option(uri, opt)
- "#{uri}?#{opt}"
- end
-
- def test_09_option
- uri = uri_concat_option(@there.__drburi, "foo")
- ro = DRbObject.new_with_uri(uri)
- assert_equal(ro.__drburi, @there.__drburi)
- assert_equal(3, ro.size)
-
- uri = uri_concat_option(@there.__drburi, "")
- ro = DRbObject.new_with_uri(uri)
- assert_equal(ro.__drburi, @there.__drburi)
- assert_equal(DRb::DRbURIOption.new(''), ro.__drbref)
-
- uri = uri_concat_option(@there.__drburi, "hello?world")
- ro = DRbObject.new_with_uri(uri)
- assert_equal(DRb::DRbURIOption.new('hello?world'), ro.__drbref)
-
- uri = uri_concat_option(@there.__drburi, "?hello?world")
- ro = DRbObject.new_with_uri(uri)
- assert_equal(DRb::DRbURIOption.new('?hello?world'), ro.__drbref)
- end
-
- def test_10_yield
- @there.simple_hash.each do |k, v|
- assert_kind_of(String, k)
- assert_kind_of(Symbol, v)
- end
- end
-
- def test_10_yield_undumped
- @there.xarray2_hash.each do |k, v|
- assert_kind_of(String, k)
- assert_kind_of(DRbObject, v)
- end
- end
-
- def test_11_remote_no_method_error
- assert_raise(DRb::DRbRemoteError) do
- @there.remote_no_method_error
- end
- begin
- @there.remote_no_method_error
- rescue
- error = $!
- assert_match(/^undefined method .*\(NoMethodError\)/, error.message)
- assert_equal('NoMethodError', error.reason)
- end
- end
-end
-
-module DRbAry
- include DRbBase
-
- def test_01
- assert_kind_of(DRb::DRbObject, @there)
- end
-
- def test_02_collect
- ary = @there.collect do |x| x + x end
- assert_kind_of(Array, ary)
- assert_equal([2, 4, 'IIIIII', 8, 'fivefive', 12], ary)
- end
-
- def test_03_redo
- ary = []
- count = 0
- @there.each do |x|
- count += 1
- ary.push x
- redo if count == 3
- end
- assert_equal([1, 2, 'III', 'III', 4, 'five', 6], ary)
- end
-
- # retry in block is not supported on ruby 1.9
- #def test_04_retry
- # retried = false
- # ary = []
- # @there.each do |x|
- # ary.push x
- # if x == 4 && !retried
- # retried = true
- # retry
- # end
- # end
- # assert_equal([1, 2, 'III', 4, 1, 2, 'III', 4, 'five', 6], ary)
- #end
-
- def test_05_break
- ary = []
- @there.each do |x|
- ary.push x
- break if x == 4
- end
- assert_equal([1, 2, 'III', 4], ary)
- end
-
- def test_06_next
- ary = []
- @there.each do |x|
- next if String === x
- ary.push x
- end
- assert_equal([1, 2, 4, 6], ary)
- end
-
- class_eval <<EOS
- def test_07_break_18
- ary = []
- result = @there.each do |x|
- ary.push x
- break(:done) if x == 4
- end
- assert_equal([1, 2, 'III', 4], ary)
- assert_equal(:done, result)
- end
-EOS
-
-end
-
-end
diff --git a/test/drb/ignore_test_drb.rb b/test/drb/ignore_test_drb.rb
deleted file mode 100644
index 996a554c0f..0000000000
--- a/test/drb/ignore_test_drb.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: false
-require 'drbtest'
-
-module DRbTests
-
-class TestDRbReusePort < Test::Unit::TestCase
- include DRbAry
-
- def setup
- setup_service 'ut_port.rb'
- end
-end
-
-end
diff --git a/test/drb/test_acl.rb b/test/drb/test_acl.rb
deleted file mode 100644
index ea7b32e76f..0000000000
--- a/test/drb/test_acl.rb
+++ /dev/null
@@ -1,207 +0,0 @@
-# frozen_string_literal: false
-# acltest.rb - ACL unit test
-# Copyright (c) 2000 Masatoshi SEKI
-#
-# acltest.rb is copyrighted free software by Masatoshi SEKI.
-# You can redistribute it and/or modify it under the same terms as Ruby.
-
-require 'test/unit'
-require 'drb/acl'
-
-module DRbTests
-
-class SampleHosts
- def initialize
- list = %w(127.0.0.1 localhost
- 192.168.1.1 x68k.linux.or.jp
- 192.168.1.2 lc630.macos.or.jp
- 192.168.1.3 lib30.win32.or.jp
- 192.168.1.4 ns00.linux.or.jp
- 192.168.1.5 yum.macos.or.jp
- ::ffff:192.168.1.5 ipv6.macos.or.jp
- ::192.168.1.5 too.yumipv6.macos.or.jp
- 192.168.1.254 comstarz.foo.or.jp)
-
- @hostlist = Array.new(list.size / 2)
- @hostlist.each_index do |idx|
- @hostlist[idx] = ["AF_INET", 10000, list[idx * 2 + 1], list[idx * 2]]
- end
-
- @hosts = Hash.new
- @hostlist.each do |h|
- @hosts[h[2].split('.')[0]] = h
- end
- end
- attr_reader(:hostlist, :hosts)
-end
-
-
-class ACLEntryTest < Test::Unit::TestCase
- HOSTS = SampleHosts.new
-
- def setup
- @hostlist = HOSTS.hostlist
- @hosts = HOSTS.hosts
- end
-
- def test_all
- a = ACL::ACLEntry.new("*")
- b = ACL::ACLEntry.new("all")
- @hostlist.each do |h|
- assert_operator(a, :match, h)
- assert_operator(b, :match, h)
- end
- end
-
- def test_ip_v6
- a = ACL::ACLEntry.new('::ffff:192.0.0.0/104')
- assert_not_operator(a, :match, @hosts['localhost'])
- assert_operator(a, :match, @hosts['yum'])
- assert_operator(a, :match, @hosts['ipv6'])
- assert_not_operator(a, :match, @hosts['too'])
- end
-
- def test_ip
- a = ACL::ACLEntry.new('192.0.0.0/8')
- assert_not_operator(a, :match, @hosts['localhost'])
- assert_operator(a, :match, @hosts['yum'])
-
- a = ACL::ACLEntry.new('192.168.1.0/255.255.255.0')
- assert_not_operator(a, :match, @hosts['localhost'])
- assert_operator(a, :match, @hosts['yum'])
- assert_operator(a, :match, @hosts['x68k'])
-
- a = ACL::ACLEntry.new('192.168.1.0/24')
- assert_not_operator(a, :match, @hosts['localhost'])
- assert_operator(a, :match, @hosts['yum'])
- assert_operator(a, :match, @hosts['x68k'])
-
- a = ACL::ACLEntry.new('92.0.0.0/8')
- assert_not_operator(a, :match, @hosts['localhost'])
- assert_not_operator(a, :match, @hosts['yum'])
- assert_not_operator(a, :match, @hosts['x68k'])
-
- a = ACL::ACLEntry.new('127.0.0.0/255.0.0.0')
- assert_operator(a, :match, @hosts['localhost'])
- assert_not_operator(a, :match, @hosts['yum'])
- assert_not_operator(a, :match, @hosts['x68k'])
-
- assert_raise(IPAddr::InvalidPrefixError) {
- ACL::ACLEntry.new('192.168.0.0/33')
- }
- assert_raise(IPAddr::InvalidPrefixError) {
- ACL::ACLEntry.new('192.168.0.0/255.255.0.255')
- }
- end
-
- def test_name
- a = ACL::ACLEntry.new('*.jp')
- assert_not_operator(a, :match, @hosts['localhost'])
- assert_operator(a, :match, @hosts['yum'])
-
- a = ACL::ACLEntry.new('yum.*.jp')
- assert_operator(a, :match, @hosts['yum'])
- assert_not_operator(a, :match, @hosts['lc630'])
-
- a = ACL::ACLEntry.new('*.macos.or.jp')
- assert_operator(a, :match, @hosts['yum'])
- assert_operator(a, :match, @hosts['lc630'])
- assert_not_operator(a, :match, @hosts['lib30'])
- end
-end
-
-class ACLListTest < Test::Unit::TestCase
- HOSTS = SampleHosts.new
-
- def setup
- @hostlist = HOSTS.hostlist
- @hosts = HOSTS.hosts
- end
-
- private
- def build(list)
- acl= ACL::ACLList.new
- list.each do |s|
- acl.add s
- end
- acl
- end
-
- public
- def test_all_1
- a = build(%w(all))
- @hostlist.each do |h|
- assert_operator(a, :match, h)
- end
- end
-
- def test_all_2
- a = build(%w(localhost 127.0.0.0/8 yum.* *))
- @hostlist.each do |h|
- assert_operator(a, :match, h)
- end
- end
-
- def test_1
- a = build(%w(192.168.1.0/255.255.255.252 yum.*.jp))
- assert_operator(a, :match, @hosts['x68k'])
- assert_operator(a, :match, @hosts['lc630'])
- assert_operator(a, :match, @hosts['lib30'])
- assert_not_operator(a, :match, @hosts['ns00'])
- assert_operator(a, :match, @hosts['yum'])
- end
-
- def test_2
- a = build(%w(*.linux.or.jp))
- assert_not_operator(a, :match, @hosts['yum'])
- assert_operator(a, :match, @hosts['x68k'])
- assert_not_operator(a, :match, @hosts['lc630'])
- end
-end
-
-class ACLTest < Test::Unit::TestCase
- HOSTS = SampleHosts.new
-
- def setup
- @hostlist = HOSTS.hostlist
- @hosts = HOSTS.hosts
- end
-
- def test_0
- a = ACL.new
- @hostlist.each do |h|
- assert_operator(a, :allow_addr?, h)
- end
- end
-
- def test_not_0
- a = ACL.new([], ACL::ALLOW_DENY)
- @hostlist.each do |h|
- assert_not_operator(a, :allow_addr?, h)
- end
- end
-
- def test_1
- data = %w(deny all
- allow localhost
- allow x68k.*)
-
- a = ACL.new(data)
- assert_operator(a, :allow_addr?, @hosts['x68k'])
- assert_operator(a, :allow_addr?, @hosts['localhost'])
- assert_not_operator(a, :allow_addr?, @hosts['lc630'])
- end
-
- def test_not_1
- data = %w(deny 192.0.0.0/8
- allow localhost
- allow x68k.*)
-
- a = ACL.new(data, ACL::ALLOW_DENY)
- assert_not_operator(a, :allow_addr?, @hosts['x68k'])
- assert_operator(a, :allow_addr?, @hosts['localhost'])
- assert_not_operator(a, :allow_addr?, @hosts['lc630'])
- end
-end
-
-end
diff --git a/test/drb/test_drb.rb b/test/drb/test_drb.rb
deleted file mode 100644
index 1ee1b265d0..0000000000
--- a/test/drb/test_drb.rb
+++ /dev/null
@@ -1,370 +0,0 @@
-# frozen_string_literal: false
-require_relative 'drbtest'
-
-module DRbTests
-
-class TestDRbCore < Test::Unit::TestCase
- include DRbCore
-
- def setup
- super
- setup_service 'ut_drb.rb'
- end
-end
-
-module DRbYield
- include DRbBase
-
- def test_01_one
- @there.echo_yield_1([]) {|one|
- assert_equal([], one)
- }
-
- @there.echo_yield_1(1) {|one|
- assert_equal(1, one)
- }
-
- @there.echo_yield_1(nil) {|one|
- assert_equal(nil, one)
- }
- end
-
- def test_02_two
- @there.echo_yield_2([], []) {|one, two|
- assert_equal([], one)
- assert_equal([], two)
- }
-
- @there.echo_yield_2(1, 2) {|one, two|
- assert_equal(1, one)
- assert_equal(2, two)
- }
-
- @there.echo_yield_2(3, nil) {|one, two|
- assert_equal(3, one)
- assert_equal(nil, two)
- }
-
- @there.echo_yield_1([:key, :value]) {|one, two|
- assert_equal(:key, one)
- assert_equal(:value, two)
- }
- end
-
- def test_03_many
- @there.echo_yield_0 {|*s|
- assert_equal([], s)
- }
- @there.echo_yield(nil) {|*s|
- assert_equal([nil], s)
- }
- @there.echo_yield(1) {|*s|
- assert_equal([1], s)
- }
- @there.echo_yield(1, 2) {|*s|
- assert_equal([1, 2], s)
- }
- @there.echo_yield(1, 2, 3) {|*s|
- assert_equal([1, 2, 3], s)
- }
- @there.echo_yield([], []) {|*s|
- assert_equal([[], []], s)
- }
- @there.echo_yield([]) {|*s|
- assert_equal([[]], s) # !
- }
- end
-
- def test_04_many_to_one
- @there.echo_yield_0 {|*s|
- assert_equal([], s)
- }
- @there.echo_yield(nil) {|*s|
- assert_equal([nil], s)
- }
- @there.echo_yield(1) {|*s|
- assert_equal([1], s)
- }
- @there.echo_yield(1, 2) {|*s|
- assert_equal([1, 2], s)
- }
- @there.echo_yield(1, 2, 3) {|*s|
- assert_equal([1, 2, 3], s)
- }
- @there.echo_yield([], []) {|*s|
- assert_equal([[], []], s)
- }
- @there.echo_yield([]) {|*s|
- assert_equal([[]], s)
- }
- end
-
- def test_05_array_subclass
- @there.xarray_each {|x| assert_kind_of(XArray, x)}
- @there.xarray_each {|*x| assert_kind_of(XArray, x[0])}
- end
-end
-
-class TestDRbYield < Test::Unit::TestCase
- include DRbYield
-
- def setup
- super
- setup_service 'ut_drb.rb'
- end
-end
-
-class TestDRbRubyYield < Test::Unit::TestCase
- include DRbYield
-
- def setup
- @there = self
- super
- end
-
- def echo_yield(*arg)
- yield(*arg)
- end
-
- def echo_yield_0
- yield
- end
-
- def echo_yield_1(a)
- yield(a)
- end
-
- def echo_yield_2(a, b)
- yield(a, b)
- end
-
- def xarray_each
- xary = [XArray.new([0])]
- xary.each do |x|
- yield(x)
- end
- end
-
-end
-
-class TestDRbRuby18Yield < Test::Unit::TestCase
- include DRbYield
-
- class YieldTest18
- def echo_yield(*arg, &proc)
- proc.call(*arg)
- end
-
- def echo_yield_0(&proc)
- proc.call
- end
-
- def echo_yield_1(a, &proc)
- proc.call(a)
- end
-
- def echo_yield_2(a, b, &proc)
- proc.call(a, b)
- end
-
- def xarray_each(&proc)
- xary = [XArray.new([0])]
- xary.each(&proc)
- end
-
- end
-
- def setup
- @there = YieldTest18.new
- super
- end
-end
-
-class TestDRbAry < Test::Unit::TestCase
- include DRbAry
-
- def setup
- super
- setup_service 'ut_array.rb'
- end
-end
-
-class TestDRbMServer < Test::Unit::TestCase
- include DRbBase
-
- def setup
- super
- setup_service 'ut_drb.rb'
- @server = (1..3).collect do |n|
- DRb::DRbServer.new("druby://localhost:0", Onecky.new(n.to_s))
- end
- end
-
- def teardown
- @server.each do |s|
- s.stop_service
- end
- super
- end
-
- def test_01
- assert_equal(6, @there.sample(@server[0].front, @server[1].front, @server[2].front))
- end
-end
-
-class TestDRbSafe1 < Test::Unit::TestCase
- include DRbAry
- def setup
- super
- setup_service 'ut_safe1.rb'
- end
-end
-
-class TestDRbLarge < Test::Unit::TestCase
- include DRbBase
-
- def setup
- super
- setup_service 'ut_large.rb'
- end
-
- def test_01_large_ary
- ary = [2] * 10240
- assert_equal(10240, @there.size(ary))
- assert_equal(20480, @there.sum(ary))
- assert_equal(2 ** 10240, @there.multiply(ary))
- assert_equal(2, @there.avg(ary))
- assert_equal(2, @there.median(ary))
- end
-
- def test_02_large_ary
- ary = ["Hello, World"] * 10240
- assert_equal(10240, @there.size(ary))
- assert_equal(ary[0..ary.length].inject(:+), @there.sum(ary))
- assert_raise(TypeError) {@there.multiply(ary)}
- assert_raise(TypeError) {@there.avg(ary)}
- assert_raise(TypeError) {@there.median(ary)}
- end
-
- def test_03_large_ary
- ary = [Thread.current] * 10240
- assert_equal(10240, @there.size(ary))
- end
-
- def test_04_many_arg
- assert_raise(DRb::DRbConnError) {
- @there.arg_test(1, 2, 3, 4, 5, 6, 7, 8, 9, 0)
- }
- end
-
- def test_05_too_large_ary
- ary = ["Hello, World"] * 102400
- exception = nil
- begin
- @there.size(ary)
- rescue StandardError
- exception = $!
- end
- assert_kind_of(StandardError, exception)
- end
-
- def test_06_array_operations
- ary = [1,50,3,844,7,45,23]
- assert_equal(7, @there.size(ary))
- assert_equal(973, @there.sum(ary))
- assert_equal(917217000, @there.multiply(ary))
- assert_equal(139.0, @there.avg(ary))
- assert_equal(23.0, @there.median(ary))
-
- ary2 = [1,2,3,4]
- assert_equal(4, @there.size(ary2))
- assert_equal(10, @there.sum(ary2))
- assert_equal(24, @there.multiply(ary2))
- assert_equal(2.5, @there.avg(ary2))
- assert_equal(2.5, @there.median(ary2))
-
- end
-
- def test_07_one_element_array
- ary = [50]
- assert_equal(1, @there.size(ary))
- assert_equal(50, @there.sum(ary))
- assert_equal(50, @there.multiply(ary))
- assert_equal(50.0, @there.avg(ary))
- assert_equal(50.0, @there.median(ary))
- end
-
- def test_08_empty_array
- ary = []
- assert_equal(0, @there.size(ary))
- assert_equal(nil, @there.sum(ary))
- assert_equal(nil, @there.multiply(ary))
- assert_equal(nil, @there.avg(ary))
- assert_equal(nil, @there.median(ary))
- end
-end
-
-class TestBug4409 < Test::Unit::TestCase
- include DRbBase
-
- def setup
- super
- setup_service 'ut_eq.rb'
- end
-
- def test_bug4409
- foo = @there.foo
- assert_operator(@there, :foo?, foo)
- end
-end
-
-class TestDRbAnyToS < Test::Unit::TestCase
- class BO < BasicObject
- end
-
- def test_any_to_s
- server = DRb::DRbServer.new('druby://localhost:0')
- server.singleton_class.send(:public, :any_to_s)
- assert_equal("foo:String", server.any_to_s("foo"))
- assert_match(/\A#<DRbTests::TestDRbAnyToS::BO:0x[0-9a-f]+>\z/, server.any_to_s(BO.new))
- server.stop_service
- server.thread.join
- DRb::DRbConn.stop_pool
- end
-end
-
-class TestDRbTCP < Test::Unit::TestCase
- def test_immediate_close
- server = DRb::DRbServer.new('druby://localhost:0')
- host, port, = DRb::DRbTCPSocket.send(:parse_uri, server.uri)
- socket = TCPSocket.open host, port
- socket.shutdown
- socket.close
- client = DRb::DRbTCPSocket.new(server.uri, socket)
- assert client
- ensure
- client&.close
- socket&.close
- server.stop_service
- server.thread.join
- DRb::DRbConn.stop_pool
- end
-end
-
-class TestBug16634 < Test::Unit::TestCase
- include DRbBase
-
- def setup
- super
- setup_service 'ut_drb.rb'
- end
-
- def test_bug16634
- assert_equal(42, @there.keyword_test1(a: 42))
- assert_equal("default", @there.keyword_test2)
- assert_equal(42, @there.keyword_test2(b: 42))
- assert_equal({:a=>42, :b=>42}, @there.keyword_test3(a: 42, b: 42))
- end
-end
-
-end
diff --git a/test/drb/test_drbobject.rb b/test/drb/test_drbobject.rb
deleted file mode 100644
index 2b0e2061ee..0000000000
--- a/test/drb/test_drbobject.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-require 'test/unit'
-require 'drb'
-require 'drb/timeridconv'
-require 'drb/weakidconv'
-
-module DRbObjectTest
- class Foo
- def initialize
- @foo = 'foo'
- end
- end
-
- def teardown
- DRb.stop_service
- DRb::DRbConn.stop_pool
- end
-
- def drb_eq(obj)
- proxy = DRbObject.new(obj)
- assert_equal(obj, DRb.to_obj(proxy.__drbref))
- end
-
- def test_DRbObject_id_dereference
- drb_eq(Foo.new)
- drb_eq(Foo)
- drb_eq(File)
- drb_eq(Enumerable)
- drb_eq(nil)
- drb_eq(1)
- drb_eq($stdout)
- drb_eq([])
- end
-end
-
-class TestDRbObject < Test::Unit::TestCase
- include DRbObjectTest
-
- def setup
- DRb.start_service
- end
-end
-
-class TestDRbObjectTimerIdConv < Test::Unit::TestCase
- include DRbObjectTest
-
- def setup
- @idconv = DRb::TimerIdConv.new
- DRb.start_service(nil, nil, {:idconv => @idconv})
- end
-
- def teardown
- super
- # stop DRb::TimerIdConv::TimerHolder2#on_gc
- @idconv.instance_eval do
- @holder.instance_eval do
- @expires = nil
- end
- end
- GC.start
- end
-end
-
-class TestDRbObjectWeakIdConv < Test::Unit::TestCase
- include DRbObjectTest
-
- def setup
- DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new})
- end
-end
diff --git a/test/drb/test_drbssl.rb b/test/drb/test_drbssl.rb
deleted file mode 100644
index 0254c7ab50..0000000000
--- a/test/drb/test_drbssl.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-# frozen_string_literal: false
-require_relative 'drbtest'
-
-begin
- require 'drb/ssl'
-rescue LoadError
-end
-
-module DRbTests
-
-if Object.const_defined?("OpenSSL")
-
-
-class DRbSSLService < DRbService
- %w(ut_drb_drbssl.rb ut_array_drbssl.rb).each do |nm|
- add_service_command(nm)
- end
-
- def start
- config = Hash.new
-
- config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
- config[:SSLVerifyCallback] = lambda{ |ok,x509_store|
- true
- }
- begin
- data = open("sample.key"){|io| io.read }
- config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(data)
- data = open("sample.crt"){|io| io.read }
- config[:SSLCertificate] = OpenSSL::X509::Certificate.new(data)
- rescue
- # $stderr.puts "Switching to use self-signed certificate"
- config[:SSLCertName] =
- [ ["C","JP"], ["O","Foo.DRuby.Org"], ["CN", "Sample"] ]
- end
-
- @server = DRb::DRbServer.new('drbssl://localhost:0', manager, config)
- end
-end
-
-class TestDRbSSLCore < Test::Unit::TestCase
- include DRbCore
- def setup
- @drb_service = DRbSSLService.new
- super
- setup_service 'ut_drb_drbssl.rb'
- end
-
- def test_02_unknown
- end
-
- def test_01_02_loop
- end
-
- def test_05_eq
- end
-end
-
-class TestDRbSSLAry < Test::Unit::TestCase
- include DRbAry
- def setup
- LeakChecker.skip if defined?(LeakChecker)
- @drb_service = DRbSSLService.new
- super
- setup_service 'ut_array_drbssl.rb'
- end
-end
-
-
-end
-
-end
diff --git a/test/drb/test_drbunix.rb b/test/drb/test_drbunix.rb
deleted file mode 100644
index 95b3c3ca91..0000000000
--- a/test/drb/test_drbunix.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# frozen_string_literal: false
-require_relative 'drbtest'
-
-begin
- require 'drb/unix'
-rescue LoadError
-end
-
-module DRbTests
-
-if Object.const_defined?("UNIXServer")
-
-
-class DRbUNIXService < DRbService
- %w(ut_drb_drbunix.rb ut_array_drbunix.rb).each do |nm|
- add_service_command(nm)
- end
-
- def start
- @server = DRb::DRbServer.new('drbunix:', manager, {})
- end
-end
-
-class TestDRbUNIXCore < Test::Unit::TestCase
- include DRbCore
- def setup
- @drb_service = DRbUNIXService.new
- super
- setup_service 'ut_drb_drbunix.rb'
- end
-
- def test_02_unknown
- end
-
- def test_01_02_loop
- end
-
- def test_05_eq
- end
-
- def test_bad_uri
- assert_raise(DRb::DRbBadURI) do
- DRb::DRbServer.new("badfile\n""drbunix:")
- end
- end
-end
-
-class TestDRbUNIXAry < Test::Unit::TestCase
- include DRbAry
- def setup
- @drb_service = DRbUNIXService.new
- super
- setup_service 'ut_array_drbunix.rb'
- end
-end
-
-
-end
-
-end
diff --git a/test/drb/ut_array.rb b/test/drb/ut_array.rb
deleted file mode 100644
index d13dda3d8e..0000000000
--- a/test/drb/ut_array.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: false
-require 'drb/drb'
-require 'drb/extserv'
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <uri> <name>" unless it
- it
- end
-
- DRb.start_service('druby://localhost:0', [1, 2, 'III', 4, "five", 6])
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
-
diff --git a/test/drb/ut_array_drbssl.rb b/test/drb/ut_array_drbssl.rb
deleted file mode 100644
index 5938d9ff3d..0000000000
--- a/test/drb/ut_array_drbssl.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: false
-require 'drb/drb'
-require 'drb/extserv'
-require 'drb/ssl'
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <uri> <name>" unless it
- it
- end
-
- module DRbTests
-
- TEST_KEY_DH1024 = OpenSSL::PKey::DH.new <<-_end_of_pem_
------BEGIN DH PARAMETERS-----
-MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0
-pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG
-AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
------END DH PARAMETERS-----
- _end_of_pem_
-
- end
-
- config = Hash.new
- config[:SSLTmpDhCallback] = proc { DRbTests::TEST_KEY_DH1024 }
- config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
- config[:SSLVerifyCallback] = lambda{|ok,x509_store|
- true
- }
- config[:SSLCertName] =
- [ ["C","JP"], ["O","Foo.DRuby.Org"], ["CN", "Sample"] ]
-
- DRb.start_service('drbssl://localhost:0', [1, 2, 'III', 4, "five", 6], config)
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
-
diff --git a/test/drb/ut_array_drbunix.rb b/test/drb/ut_array_drbunix.rb
deleted file mode 100644
index b656cdaddd..0000000000
--- a/test/drb/ut_array_drbunix.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: false
-require 'drb/drb'
-require 'drb/extserv'
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <uri> <name>" unless it
- it
- end
-
- DRb.start_service('drbunix:', [1, 2, 'III', 4, "five", 6])
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
-
diff --git a/test/drb/ut_drb.rb b/test/drb/ut_drb.rb
deleted file mode 100644
index 7c0603b009..0000000000
--- a/test/drb/ut_drb.rb
+++ /dev/null
@@ -1,189 +0,0 @@
-# frozen_string_literal: false
-require 'drb/drb'
-require 'drb/extserv'
-require 'timeout'
-
-module DRbTests
-
-class XArray < Array
- def initialize(ary)
- ary.each do |x|
- self.push(x)
- end
- end
-end
-
-class XArray2 < XArray
- include DRbUndumped
-end
-
-class Unknown2
- def initialize
- @foo = 'unknown2'
- end
-end
-
-class DRbEx
- include DRbUndumped
-
- class FooBar
- def initialize
- @foo = 'bar'
- end
- end
-
- class UError < RuntimeError; end
-
- def initialize
- @xary2_hash = nil
- @hash = nil
- @hello = 'hello'
- end
- attr_reader :hello
-
- def sample(a, b, c)
- a.to_i + b.to_i + c.to_i
- end
-
- def sum(*a)
- s = 0
- a.each do |e|
- s += e.to_i
- end
- s
- end
-
- def do_timeout(n)
- Timeout.timeout(0.1) do
- n.sleep(2)
- end
- end
-
- def unknown_module
- FooBar.new
- end
-
- class BO < ::BasicObject
- def foo; 1 end
- protected def prot; 2; end
- private def priv; 3; end
- end
- def basic_object
- @basic_object = BO.new
- end
-
- def unknown_class
- Unknown2.new
- end
-
- def unknown_error
- raise UError
- end
-
- def remote_no_method_error
- invoke_no_method(self)
- end
-
- def test_yield
- yield
- yield([])
- yield(*[])
- end
-
- def echo_yield(*arg)
- yield(*arg)
- nil
- end
-
- def echo_yield_0
- yield
- nil
- end
-
- def echo_yield_1(one)
- yield(one)
- nil
- end
-
- def echo_yield_2(one, two)
- yield(one, two)
- nil
- end
-
- def xarray_each
- xary = [XArray.new([0])]
- xary.each do |x|
- yield(x)
- end
- nil
- end
-
- def xarray2_hash
- unless @xary2_hash
- @xary2_hash = { "a" => XArray2.new([0]), "b" => XArray2.new([1]) }
- end
- DRbObject.new(@xary2_hash)
- end
-
- def simple_hash
- unless @hash
- @hash = { 'a'=>:a, 'b'=>:b }
- end
- DRbObject.new(@hash)
- end
-
- def [](key)
- key.to_s
- end
-
- def to_a
- [self]
- end
-
- def method_missing(msg, *a, &b)
- if msg == :missing
- return true
- else
- super(msg, *a, &b)
- end
- end
-
- def keyword_test1(a:)
- a
- end
-
- def keyword_test2(b: "default")
- b
- end
-
- def keyword_test3(**opt)
- opt
- end
-
- private
- def call_private_method
- true
- end
-
- protected
- def call_protected_method
- true
- end
-end
-
-end
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <manager-uri> <name>" unless it
- it
- end
-
- DRb::DRbServer.default_argc_limit(8)
- DRb::DRbServer.default_load_limit(4096)
- DRb.start_service('druby://localhost:0', DRbTests::DRbEx.new)
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
diff --git a/test/drb/ut_drb_drbssl.rb b/test/drb/ut_drb_drbssl.rb
deleted file mode 100644
index c8251716d6..0000000000
--- a/test/drb/ut_drb_drbssl.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-# frozen_string_literal: false
-require_relative "ut_drb"
-require 'drb/ssl'
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <manager-uri> <name>" unless it
- it
- end
-
- module DRbTests
-
- TEST_KEY_DH1024 = OpenSSL::PKey::DH.new <<-_end_of_pem_
------BEGIN DH PARAMETERS-----
-MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0
-pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG
-AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
------END DH PARAMETERS-----
- _end_of_pem_
-
- end
-
- config = Hash.new
- config[:SSLTmpDhCallback] = proc { DRbTests::TEST_KEY_DH1024 }
- config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
- config[:SSLVerifyCallback] = lambda{|ok,x509_store|
- true
- }
- config[:SSLCertName] =
- [ ["C","JP"], ["O","Foo.DRuby.Org"], ["CN", "Sample"] ]
-
- DRb::DRbServer.default_argc_limit(8)
- DRb::DRbServer.default_load_limit(4096)
- DRb.start_service('drbssl://localhost:0', DRbTests::DRbEx.new, config)
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
-
diff --git a/test/drb/ut_drb_drbunix.rb b/test/drb/ut_drb_drbunix.rb
deleted file mode 100644
index ecf0920451..0000000000
--- a/test/drb/ut_drb_drbunix.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: false
-require "#{File.dirname(File.expand_path(__FILE__))}/ut_drb"
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <manager-uri> <name>" unless it
- it
- end
-
- DRb::DRbServer.default_argc_limit(8)
- DRb::DRbServer.default_load_limit(4096)
- DRb.start_service('drbunix:', DRbTests::DRbEx.new)
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
-
diff --git a/test/drb/ut_eq.rb b/test/drb/ut_eq.rb
deleted file mode 100644
index 56285a384f..0000000000
--- a/test/drb/ut_eq.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-# frozen_string_literal: false
-require 'drb/drb'
-require 'drb/extserv'
-
-module DRbTests
-
-class Foo
- include DRbUndumped
-end
-
-class Bar
- include DRbUndumped
- def initialize
- @foo = Foo.new
- end
- attr_reader :foo
-
- def foo?(foo)
- @foo == foo
- end
-end
-
-end
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <uri> <name>" unless it
- it
- end
-
- DRb.start_service('druby://localhost:0', DRbTests::Bar.new)
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
-
diff --git a/test/drb/ut_large.rb b/test/drb/ut_large.rb
deleted file mode 100644
index 9376ff119d..0000000000
--- a/test/drb/ut_large.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: false
-require 'drb/drb'
-require 'drb/extserv'
-require 'timeout'
-
-module DRbTests
-
-class DRbLarge
- include DRbUndumped
-
- def size(ary)
- ary.size
- end
-
- def sum(ary)
- ary.inject(:+)
- end
-
- def multiply(ary)
- ary.inject(:*)
- end
-
- def avg(ary)
- return if ary.empty?
- if ary.any? {|n| n.is_a? String}
- raise TypeError
- else
- sum(ary).to_f / ary.count
- end
- end
-
- def median(ary)
- return if ary.empty?
- if ary.any? {|n| n.is_a? String}
- raise TypeError
- else
- avg ary.sort[((ary.length - 1) / 2)..(ary.length / 2)]
- end
- end
-
- def arg_test(*arg)
- # nop
- end
-end
-
-end
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <manager-uri> <name>" unless it
- it
- end
-
- DRb::DRbServer.default_argc_limit(3)
- DRb::DRbServer.default_load_limit(100000)
- DRb.start_service('druby://localhost:0', DRbTests::DRbLarge.new)
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
-
diff --git a/test/drb/ut_port.rb b/test/drb/ut_port.rb
deleted file mode 100644
index d317a307cc..0000000000
--- a/test/drb/ut_port.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: false
-require 'drb/drb'
-require 'drb/extserv'
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <uri> <name>" unless it
- it
- end
-
- DRb.start_service('druby://:8473', [1, 2, 'III', 4, "five", 6])
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
diff --git a/test/drb/ut_safe1.rb b/test/drb/ut_safe1.rb
deleted file mode 100644
index 4b16fa7d6d..0000000000
--- a/test/drb/ut_safe1.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: false
-require 'drb/drb'
-require 'drb/extserv'
-
-if __FILE__ == $0
- def ARGV.shift
- it = super()
- raise "usage: #{$0} <uri> <name>" unless it
- it
- end
-
- DRb.start_service('druby://localhost:0', [1, 2, 'III', 4, "five", 6],
- {:safe_level => 1})
- es = DRb::ExtServ.new(ARGV.shift, ARGV.shift)
- DRb.thread.join
- es.stop_service if es.alive?
-end
diff --git a/test/drb/ut_timerholder.rb b/test/drb/ut_timerholder.rb
deleted file mode 100644
index 1753b30c74..0000000000
--- a/test/drb/ut_timerholder.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'drb/timeridconv'
-
-module DRbTests
-
-class TimerIdConvTest < Test::Unit::TestCase
- def test_usecase_01
- keeping = 0.1
- idconv = DRb::TimerIdConv.new(keeping)
-
- key = idconv.to_id(self)
- assert_equal(key, self.__id__)
- sleep(keeping)
- assert_equal(idconv.to_id(false), false.__id__)
- assert_equal(idconv.to_obj(key), self)
- sleep(keeping)
-
- assert_equal(idconv.to_obj(key), self)
- sleep(keeping)
-
- assert_equal(idconv.to_id(true), true.__id__)
- sleep(keeping)
-
- assert_raise do
- assert_equal(idconv.to_obj(key), self)
- end
-
- assert_raise do
- assert_equal(idconv.to_obj(false.__id__), false)
- end
-
- key = idconv.to_id(self)
- assert_equal(key, self.__id__)
- assert_equal(idconv.to_id(true), true.__id__)
- sleep(keeping)
- GC.start
- sleep(keeping)
- GC.start
- assert_raise do
- assert_equal(idconv.to_obj(key), self)
- end
- end
-
- def test_usecase_02
- keeping = 0.1
- idconv = DRb::TimerIdConv.new(keeping)
-
- key = idconv.to_id(self)
- assert_equal(key, self.__id__)
- sleep(keeping)
- GC.start
- sleep(keeping)
- GC.start
- assert_raise do
- assert_equal(idconv.to_obj(key), self)
- end
- GC.start
-
- key = idconv.to_id(self)
- assert_equal(key, self.__id__)
- sleep(keeping)
- GC.start
- sleep(keeping)
- GC.start
- assert_raise do
- assert_equal(idconv.to_obj(key), self)
- end
- end
-end
-
-
-end
-
diff --git a/test/erb/test_erb.rb b/test/erb/test_erb.rb
index fb5e9b611e..555345a140 100644
--- a/test/erb/test_erb.rb
+++ b/test/erb/test_erb.rb
@@ -73,12 +73,28 @@ class TestERB < Test::Unit::TestCase
assert_equal("", ERB::Util.html_escape(""))
assert_equal("abc", ERB::Util.html_escape("abc"))
assert_equal("&lt;&lt;", ERB::Util.html_escape("<\<"))
+ assert_equal("&#39;&amp;&quot;&gt;&lt;", ERB::Util.html_escape("'&\"><"))
assert_equal("", ERB::Util.html_escape(nil))
assert_equal("123", ERB::Util.html_escape(123))
end
+ def test_html_escape_to_s
+ object = Object.new
+ def object.to_s
+ "object"
+ end
+ assert_equal("object", ERB::Util.html_escape(object))
+ end
+
+ def test_html_escape_extension
+ assert_nil(ERB::Util.method(:html_escape).source_location)
+ end if RUBY_ENGINE == 'ruby'
+
def test_concurrent_default_binding
+ # This test randomly fails with JRuby -- NameError: undefined local variable or method `template2'
+ pend if RUBY_ENGINE == 'jruby'
+
template1 = 'one <%= ERB.new(template2).result %>'
eval 'template2 = "two"', TOPLEVEL_BINDING
@@ -236,6 +252,8 @@ EOS
end
def test_invalid_trim_mode
+ pend if RUBY_ENGINE == 'truffleruby'
+
assert_warning(/#{__FILE__}:#{__LINE__ + 1}/) do
@erb.new("", trim_mode: 'abc-def')
end
@@ -695,6 +713,18 @@ EOS
erb = Marshal.load(Marshal.dump(erb))
assert_raise(ArgumentError) {erb.result}
end
+
+ def test_multi_line_comment_lineno
+ erb = ERB.new(<<~EOS)
+ <%= __LINE__ %>
+ <%#
+ %><%= __LINE__ %>
+ EOS
+ assert_equal <<~EOS, erb.result
+ 1
+ 3
+ EOS
+ end
end
class TestERBCoreWOStrScan < TestERBCore
diff --git a/test/erb/test_erb_command.rb b/test/erb/test_erb_command.rb
index 0baa59ddd5..6bf252c5cd 100644
--- a/test/erb/test_erb_command.rb
+++ b/test/erb/test_erb_command.rb
@@ -4,27 +4,17 @@ require 'test/unit'
class TestErbCommand < Test::Unit::TestCase
def test_var
- assert_in_out_err(["-I#{File.expand_path('../../lib', __dir__)}", "-w",
+ pend if RUBY_ENGINE == 'truffleruby'
+ assert_in_out_err(["-I#{File.expand_path('../../lib', __dir__)}",
File.expand_path("../../libexec/erb", __dir__),
"var=hoge"],
"<%=var%>", ["hoge"])
end
def test_template_file_encoding
- assert_in_out_err(["-I#{File.expand_path('../../lib', __dir__)}", "-w",
+ pend if RUBY_ENGINE == 'truffleruby'
+ assert_in_out_err(["-I#{File.expand_path('../../lib', __dir__)}",
File.expand_path("../../libexec/erb", __dir__)],
"<%=''.encoding.to_s%>", ["UTF-8"])
end
-
- # These interfaces will be removed at Ruby 2.7.
- def test_deprecated_option
- warnings = [
- "warning: -S option of erb command is deprecated. Please do not use this.",
- /\n.+\/libexec\/erb:\d+: warning: Passing safe_level with the 2nd argument of ERB\.new is deprecated\. Do not use it, and specify other arguments as keyword arguments\.\n/,
- ]
- assert_in_out_err(["-I#{File.expand_path('../../lib', __dir__)}", "-w",
- File.expand_path("../../libexec/erb", __dir__),
- "-S", "0"],
- "hoge", ["hoge"], warnings)
- end
end
diff --git a/test/error_highlight/test_error_highlight.rb b/test/error_highlight/test_error_highlight.rb
index c4a998092b..2095970af1 100644
--- a/test/error_highlight/test_error_highlight.rb
+++ b/test/error_highlight/test_error_highlight.rb
@@ -23,21 +23,48 @@ class ErrorHighlightTest < Test::Unit::TestCase
end
end
+ begin
+ method_not_exist
+ rescue NameError
+ if $!.message.include?("`")
+ def preprocess(msg)
+ msg
+ end
+ else
+ def preprocess(msg)
+ msg.sub("`", "'")
+ end
+ end
+ end
+
if Exception.method_defined?(:detailed_message)
def assert_error_message(klass, expected_msg, &blk)
+ omit unless klass < ErrorHighlight::CoreExt
err = assert_raise(klass, &blk)
- assert_equal(expected_msg.chomp, err.detailed_message(highlight: false).sub(/ \((?:NoMethod|Name)Error\)/, ""))
+ assert_equal(preprocess(expected_msg).chomp, err.detailed_message(highlight: false).sub(/ \((?:NoMethod|Name)Error\)/, ""))
end
else
def assert_error_message(klass, expected_msg, &blk)
+ omit unless klass < ErrorHighlight::CoreExt
err = assert_raise(klass, &blk)
- assert_equal(expected_msg.chomp, err.message)
+ assert_equal(preprocess(expected_msg).chomp, err.message)
end
end
+ if begin; 1.time; rescue; $!.message.end_with?("an instance of Integer"); end
+ # new message format
+ NEW_MESSAGE_FORMAT = true
+ NIL_RECV_MESSAGE = "nil"
+ ONE_RECV_MESSAGE = "an instance of Integer"
+ else
+ NEW_MESSAGE_FORMAT = false
+ NIL_RECV_MESSAGE = "nil:NilClass"
+ ONE_RECV_MESSAGE = "1:Integer"
+ end
+
def test_CALL_noarg_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
nil.foo + 1
^^^^
@@ -49,7 +76,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_noarg_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
.foo + 1
^^^^
@@ -62,7 +89,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_noarg_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
foo + 1
^^^
@@ -75,7 +102,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_noarg_4
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
(nil).foo + 1
^^^^
@@ -87,7 +114,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_arg_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
nil.foo (42)
^^^^
@@ -99,7 +126,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_arg_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
.foo (
^^^^
@@ -114,7 +141,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_arg_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
foo (
^^^
@@ -129,7 +156,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_arg_4
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
nil.foo(42)
^^^^
@@ -141,7 +168,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_arg_5
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
.foo(
^^^^
@@ -156,7 +183,7 @@ undefined method `foo' for nil:NilClass
def test_CALL_arg_6
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
foo(
^^^
@@ -171,7 +198,7 @@ undefined method `foo' for nil:NilClass
def test_QCALL_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for 1:Integer
+undefined method `foo' for #{ ONE_RECV_MESSAGE }
1&.foo
^^^^^
@@ -183,7 +210,7 @@ undefined method `foo' for 1:Integer
def test_QCALL_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for 1:Integer
+undefined method `foo' for #{ ONE_RECV_MESSAGE }
1&.foo(42)
^^^^^
@@ -195,7 +222,7 @@ undefined method `foo' for 1:Integer
def test_CALL_aref_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for nil:NilClass
+undefined method `[]' for #{ NIL_RECV_MESSAGE }
nil [ ]
^^^
@@ -207,7 +234,7 @@ undefined method `[]' for nil:NilClass
def test_CALL_aref_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for nil:NilClass
+undefined method `[]' for #{ NIL_RECV_MESSAGE }
nil [0]
^^^
@@ -219,7 +246,7 @@ undefined method `[]' for nil:NilClass
def test_CALL_aref_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for nil:NilClass
+undefined method `[]' for #{ NIL_RECV_MESSAGE }
END
nil [
@@ -230,8 +257,9 @@ undefined method `[]' for nil:NilClass
def test_CALL_aref_4
v = Object.new
+ recv = NEW_MESSAGE_FORMAT ? "an instance of Object" : v.inspect
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for #{ v.inspect }
+undefined method `[]' for #{ recv }
v &.[](0)
^^^^
@@ -243,7 +271,7 @@ undefined method `[]' for #{ v.inspect }
def test_CALL_aref_5
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for nil:NilClass
+undefined method `[]' for #{ NIL_RECV_MESSAGE }
(nil)[ ]
^^^
@@ -255,7 +283,7 @@ undefined method `[]' for nil:NilClass
def test_CALL_aset
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]=' for nil:NilClass
+undefined method `[]=' for #{ NIL_RECV_MESSAGE }
nil.[]=
^^^^
@@ -268,7 +296,7 @@ undefined method `[]=' for nil:NilClass
def test_CALL_op_asgn
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
v += 42
^
@@ -280,7 +308,7 @@ undefined method `+' for nil:NilClass
def test_CALL_special_call_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `call' for nil:NilClass
+undefined method `call' for #{ NIL_RECV_MESSAGE }
END
nil.()
@@ -289,7 +317,7 @@ undefined method `call' for nil:NilClass
def test_CALL_special_call_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `call' for nil:NilClass
+undefined method `call' for #{ NIL_RECV_MESSAGE }
END
nil.(42)
@@ -298,7 +326,7 @@ undefined method `call' for nil:NilClass
def test_CALL_send
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
nil.send(:foo, 42)
^^^^^
@@ -310,7 +338,7 @@ undefined method `foo' for nil:NilClass
def test_ATTRASGN_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]=' for nil:NilClass
+undefined method `[]=' for #{ NIL_RECV_MESSAGE }
nil [ ] = 42
^^^^^
@@ -322,7 +350,7 @@ undefined method `[]=' for nil:NilClass
def test_ATTRASGN_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]=' for nil:NilClass
+undefined method `[]=' for #{ NIL_RECV_MESSAGE }
nil [0] = 42
^^^^^
@@ -334,7 +362,7 @@ undefined method `[]=' for nil:NilClass
def test_ATTRASGN_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo=' for nil:NilClass
+undefined method `foo=' for #{ NIL_RECV_MESSAGE }
nil.foo = 42
^^^^^^
@@ -346,7 +374,7 @@ undefined method `foo=' for nil:NilClass
def test_ATTRASGN_4
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]=' for nil:NilClass
+undefined method `[]=' for #{ NIL_RECV_MESSAGE }
(nil)[0] = 42
^^^^^
@@ -358,7 +386,7 @@ undefined method `[]=' for nil:NilClass
def test_ATTRASGN_5
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo=' for nil:NilClass
+undefined method `foo=' for #{ NIL_RECV_MESSAGE }
(nil).foo = 42
^^^^^^
@@ -370,7 +398,7 @@ undefined method `foo=' for nil:NilClass
def test_OPCALL_binary_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
nil + 42
^
@@ -382,7 +410,7 @@ undefined method `+' for nil:NilClass
def test_OPCALL_binary_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
nil + # comment
^
@@ -395,7 +423,7 @@ undefined method `+' for nil:NilClass
def test_OPCALL_binary_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
(nil) + 42
^
@@ -407,7 +435,7 @@ undefined method `+' for nil:NilClass
def test_OPCALL_unary_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `+@' for nil:NilClass
+undefined method `+@' for #{ NIL_RECV_MESSAGE }
+ nil
^
@@ -419,7 +447,7 @@ undefined method `+@' for nil:NilClass
def test_OPCALL_unary_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `+@' for nil:NilClass
+undefined method `+@' for #{ NIL_RECV_MESSAGE }
+(nil)
^
@@ -431,7 +459,7 @@ undefined method `+@' for nil:NilClass
def test_FCALL_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
nil.instance_eval { foo() }
^^^
@@ -443,7 +471,7 @@ undefined method `foo' for nil:NilClass
def test_FCALL_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
nil.instance_eval { foo(42) }
^^^
@@ -455,7 +483,7 @@ undefined method `foo' for nil:NilClass
def test_VCALL_2
assert_error_message(NameError, <<~END) do
-undefined local variable or method `foo' for nil:NilClass
+undefined local variable or method `foo' for #{ NIL_RECV_MESSAGE }
nil.instance_eval { foo }
^^^
@@ -469,7 +497,7 @@ undefined local variable or method `foo' for nil:NilClass
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for nil:NilClass
+undefined method `[]' for #{ NIL_RECV_MESSAGE }
v [0] += 42
^^^
@@ -483,7 +511,7 @@ undefined method `[]' for nil:NilClass
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for nil:NilClass
+undefined method `[]' for #{ NIL_RECV_MESSAGE }
v [0] += # comment
^^^
@@ -498,7 +526,7 @@ undefined method `[]' for nil:NilClass
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for nil:NilClass
+undefined method `[]' for #{ NIL_RECV_MESSAGE }
END
v [
@@ -512,7 +540,7 @@ undefined method `[]' for nil:NilClass
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `[]' for nil:NilClass
+undefined method `[]' for #{ NIL_RECV_MESSAGE }
(v)[0] += 42
^^^
@@ -527,7 +555,7 @@ undefined method `[]' for nil:NilClass
def v.[](x); nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
v [0] += 42
^
@@ -542,7 +570,7 @@ undefined method `+' for nil:NilClass
def v.[](x); nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
v [0 ] += # comment
^
@@ -558,7 +586,7 @@ undefined method `+' for nil:NilClass
def v.[](x); nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
END
v [
@@ -573,7 +601,7 @@ undefined method `+' for nil:NilClass
def v.[](x); nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
(v)[0] += 42
^
@@ -648,7 +676,7 @@ undefined method `[]=' for #{ v.inspect }
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
v.foo += 42
^^^^
@@ -662,7 +690,7 @@ undefined method `foo' for nil:NilClass
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
v.foo += # comment
^^^^
@@ -677,7 +705,7 @@ undefined method `foo' for nil:NilClass
v = nil
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
(v).foo += 42
^^^^
@@ -692,7 +720,7 @@ undefined method `foo' for nil:NilClass
def v.foo; nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
v.foo += 42
^
@@ -707,7 +735,7 @@ undefined method `+' for nil:NilClass
def v.foo; nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
v.foo += # comment
^
@@ -723,7 +751,7 @@ undefined method `+' for nil:NilClass
def v.foo; nil; end
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
(v).foo += 42
^
@@ -816,6 +844,54 @@ uninitialized constant ErrorHighlightTest::NotDefined
end
end
+ def test_COLON2_3
+ assert_error_message(NameError, <<~END) do
+uninitialized constant ErrorHighlightTest::NotDefined
+
+ ErrorHighlightTest::NotDefined::Foo
+ ^^^^^^^^^^^^
+ END
+
+ ErrorHighlightTest::NotDefined::Foo
+ end
+ end
+
+ def test_COLON2_4
+ assert_error_message(NameError, <<~END) do
+uninitialized constant ErrorHighlightTest::NotDefined
+
+ ::ErrorHighlightTest::NotDefined::Foo
+ ^^^^^^^^^^^^
+ END
+
+ ::ErrorHighlightTest::NotDefined::Foo
+ end
+ end
+
+ if ErrorHighlight.const_get(:Spotter).const_get(:OPT_GETCONSTANT_PATH)
+ def test_COLON2_5
+ # Unfortunately, we cannot identify which `NotDefined` caused the NameError
+ assert_error_message(NameError, <<~END) do
+uninitialized constant ErrorHighlightTest::NotDefined
+ END
+
+ ErrorHighlightTest::NotDefined::NotDefined
+ end
+ end
+ else
+ def test_COLON2_5
+ assert_error_message(NameError, <<~END) do
+uninitialized constant ErrorHighlightTest::NotDefined
+
+ ErrorHighlightTest::NotDefined::NotDefined
+ ^^^^^^^^^^^^
+ END
+
+ ErrorHighlightTest::NotDefined::NotDefined
+ end
+ end
+ end
+
def test_COLON3
assert_error_message(NameError, <<~END) do
uninitialized constant NotDefined
@@ -869,7 +945,7 @@ uninitialized constant ErrorHighlightTest::OP_CDECL_TEST::NotDefined
def test_OP_CDECL_op_1
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
OP_CDECL_TEST::Nil += 1
^
@@ -881,7 +957,7 @@ undefined method `+' for nil:NilClass
def test_OP_CDECL_op_2
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
OP_CDECL_TEST::Nil += # comment
^
@@ -894,7 +970,7 @@ undefined method `+' for nil:NilClass
def test_OP_CDECL_op_3
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for nil:NilClass
+undefined method `+' for #{ NIL_RECV_MESSAGE }
Nil += 1
^
@@ -918,8 +994,9 @@ uninitialized constant NotDefined
end
def test_OP_CDECL_toplevel_2
+ recv = NEW_MESSAGE_FORMAT ? "class ErrorHighlightTest" : "ErrorHighlightTest:Class"
assert_error_message(NoMethodError, <<~END) do
-undefined method `+' for ErrorHighlightTest:Class
+undefined method `+' for #{ recv }
::ErrorHighlightTest += 1
^
@@ -980,18 +1057,16 @@ local variable `foo' is not defined for #{ b.inspect }
def test_multibyte
assert_error_message(NoMethodError, <<~END) do
-undefined method `あいうえお' for nil:NilClass
+undefined method `あいうえお' for #{ NIL_RECV_MESSAGE }
END
nil.あいうえお
end
end
- if false
-
def test_args_CALL_1
assert_error_message(TypeError, <<~END) do
-nil can't be coerced into Integer
+nil can't be coerced into Integer (TypeError)
1.+(nil)
^^^
@@ -1004,7 +1079,7 @@ nil can't be coerced into Integer
def test_args_CALL_2
v = []
assert_error_message(TypeError, <<~END) do
-no implicit conversion from nil to integer
+no implicit conversion from nil to integer (TypeError)
v[nil]
^^^
@@ -1017,7 +1092,7 @@ no implicit conversion from nil to integer
def test_args_ATTRASGN_1
v = []
assert_error_message(ArgumentError, <<~END) do
-wrong number of arguments (given 1, expected 2..3)
+wrong number of arguments (given 1, expected 2..3) (ArgumentError)
v [ ] = 1
^^^^^^
@@ -1030,7 +1105,7 @@ wrong number of arguments (given 1, expected 2..3)
def test_args_ATTRASGN_2
v = []
assert_error_message(TypeError, <<~END) do
-no implicit conversion from nil to integer
+no implicit conversion from nil to integer (TypeError)
v [nil] = 1
^^^^^^^^
@@ -1042,7 +1117,7 @@ no implicit conversion from nil to integer
def test_args_ATTRASGN_3
assert_error_message(TypeError, <<~END) do
-no implicit conversion of String into Integer
+no implicit conversion of String into Integer (TypeError)
$stdin.lineno = "str"
^^^^^
@@ -1054,7 +1129,7 @@ no implicit conversion of String into Integer
def test_args_OPCALL
assert_error_message(TypeError, <<~END) do
-nil can't be coerced into Integer
+nil can't be coerced into Integer (TypeError)
1 + nil
^^^
@@ -1066,7 +1141,7 @@ nil can't be coerced into Integer
def test_args_FCALL_1
assert_error_message(TypeError, <<~END) do
-no implicit conversion of Symbol into String
+no implicit conversion of Symbol into String (TypeError)
"str".instance_eval { gsub("foo", :sym) }
^^^^^^^^^^^
@@ -1078,7 +1153,7 @@ no implicit conversion of Symbol into String
def test_args_FCALL_2
assert_error_message(TypeError, <<~END) do
-no implicit conversion of Symbol into String
+no implicit conversion of Symbol into String (TypeError)
"str".instance_eval { gsub "foo", :sym }
^^^^^^^^^^^
@@ -1092,7 +1167,7 @@ no implicit conversion of Symbol into String
v = []
assert_error_message(TypeError, <<~END) do
-no implicit conversion from nil to integer
+no implicit conversion from nil to integer (TypeError)
v [nil] += 42
^^^^^^^^^^
@@ -1106,7 +1181,7 @@ no implicit conversion from nil to integer
v = []
assert_error_message(ArgumentError, <<~END) do
-wrong number of arguments (given 0, expected 1..2)
+wrong number of arguments (given 0, expected 1..2) (ArgumentError)
v [ ] += 42
^^^^^^^^
@@ -1120,7 +1195,7 @@ wrong number of arguments (given 0, expected 1..2)
v = [1]
assert_error_message(TypeError, <<~END) do
-nil can't be coerced into Integer
+nil can't be coerced into Integer (TypeError)
v [0] += nil
^^^^^^^^^
@@ -1135,7 +1210,7 @@ nil can't be coerced into Integer
def v.foo; 1; end
assert_error_message(TypeError, <<~END) do
-nil can't be coerced into Integer
+nil can't be coerced into Integer (TypeError)
v.foo += nil
^^^
@@ -1145,8 +1220,6 @@ nil can't be coerced into Integer
end
end
- end
-
def test_custom_formatter
custom_formatter = Object.new
def custom_formatter.message_for(spot)
@@ -1156,7 +1229,7 @@ nil can't be coerced into Integer
original_formatter, ErrorHighlight.formatter = ErrorHighlight.formatter, custom_formatter
assert_error_message(NoMethodError, <<~END) do
-undefined method `time' for 1:Integer
+undefined method `time' for #{ ONE_RECV_MESSAGE }
{:first_lineno=>#{ __LINE__ + 3 }, :first_column=>7, :last_lineno=>#{ __LINE__ + 3 }, :last_column=>12, :snippet=>" 1.time {}\\n"}
END
@@ -1174,7 +1247,7 @@ undefined method `time' for 1:Integer
tmp.close
assert_error_message(NoMethodError, <<~END.gsub("_", "\t")) do
-undefined method `time' for 1:Integer
+undefined method `time' for #{ ONE_RECV_MESSAGE }
_ _1.time {}
_ _ ^^^^^
@@ -1191,7 +1264,7 @@ _ _ ^^^^^
tmp.close
assert_error_message(NoMethodError, <<~END) do
-undefined method `time' for 1:Integer
+undefined method `time' for #{ ONE_RECV_MESSAGE }
1.time {}
^^^^^
@@ -1204,7 +1277,7 @@ undefined method `time' for 1:Integer
def test_simulate_funcallv_from_embedded_ruby
assert_error_message(NoMethodError, <<~END) do
-undefined method `foo' for nil:NilClass
+undefined method `foo' for #{ NIL_RECV_MESSAGE }
END
nil.foo + 1
@@ -1219,8 +1292,9 @@ undefined method `foo' for nil:NilClass
tmp << "module Dummy\nend\n"
tmp.close
+ recv = NEW_MESSAGE_FORMAT ? "an instance of String" : '"dummy":String'
assert_error_message(NameError, <<~END) do
- undefined local variable or method `foo' for "dummy":String
+ undefined local variable or method `foo' for #{ recv }
END
"dummy".instance_eval do
@@ -1257,4 +1331,36 @@ undefined method `foo' for nil:NilClass
assert_equal(22, spot[:last_column])
assert_equal(" raise_name_error\n", spot[:snippet])
end
+
+ def test_spot_with_node
+ omit unless RubyVM::AbstractSyntaxTree.respond_to?(:node_id_for_backtrace_location)
+
+ begin
+ raise_name_error
+ rescue NameError => exc
+ end
+
+ bl = exc.backtrace_locations.first
+ expected_spot = ErrorHighlight.spot(exc, backtrace_location: bl)
+ ast = RubyVM::AbstractSyntaxTree.parse_file(__FILE__, keep_script_lines: true)
+ node_id = RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(bl)
+ node = find_node_by_id(ast, node_id)
+ actual_spot = ErrorHighlight.spot(node)
+
+ assert_equal expected_spot, actual_spot
+ end
+
+ private
+
+ def find_node_by_id(node, node_id)
+ return node if node.node_id == node_id
+
+ node.children.each do |child|
+ next unless child.is_a?(RubyVM::AbstractSyntaxTree::Node)
+ found = find_node_by_id(child, node_id)
+ return found if found
+ end
+
+ return false
+ end
end
diff --git a/test/excludes/Psych/TestDateTime.rb b/test/excludes/Psych/TestDateTime.rb
deleted file mode 100644
index 63d99be809..0000000000
--- a/test/excludes/Psych/TestDateTime.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-exclude(:test_new_datetime, <<MSG)
-Undefined behavior of YAML spec, no definitions for pre Gregorian dates.
-https://github.com/yaml/yaml/issues/69
-MSG
diff --git a/test/excludes/TestThread.rb b/test/excludes/TestThread.rb
deleted file mode 100644
index cf7e88427e..0000000000
--- a/test/excludes/TestThread.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: false
-exclude(/_stack_size$/, 'often too expensive')
-if /freebsd13/ =~ RUBY_PLATFORM
- # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220216T143001Z.fail.html.gz
- #
- # 1) Error:
- # TestThread#test_signal_at_join:
- # Timeout::Error: execution of assert_separately expired timeout (120 sec)
- # pid 30743 killed by SIGABRT (signal 6) (core dumped)
- # |
- #
- # /usr/home/chkbuild/chkbuild/tmp/build/20220216T143001Z/ruby/test/ruby/test_thread.rb:1390:in `test_signal_at_join'
- exclude(:test_signal_at_join, 'gets stuck somewhere')
-end
diff --git a/test/fiber/scheduler.rb b/test/fiber/scheduler.rb
index 96b22856d1..3926226ca3 100644
--- a/test/fiber/scheduler.rb
+++ b/test/fiber/scheduler.rb
@@ -1,8 +1,13 @@
# frozen_string_literal: true
# This is an example and simplified scheduler for test purposes.
-# It is not efficient for a large number of file descriptors as it uses IO.select().
-# Production Fiber schedulers should use epoll/kqueue/etc.
+# - It is not efficient for a large number of file descriptors as it uses
+# IO.select().
+# - It does not correctly handle multiple calls to `wait` with the same file
+# descriptor and overlapping events.
+# - Production fiber schedulers should use epoll/kqueue/etc. Consider using the
+# [`io-event`](https://github.com/socketry/io-event) gem instead of this
+# scheduler if you want something simple to build on.
require 'fiber'
require 'socket'
@@ -22,7 +27,9 @@ class Scheduler
Warning[:experimental] = experimental
end
- def initialize
+ def initialize(fiber = Fiber.current)
+ @fiber = fiber
+
@readable = {}
@writable = {}
@waiting = {}
@@ -40,6 +47,10 @@ class Scheduler
attr :writable
attr :waiting
+ def transfer
+ @fiber.transfer
+ end
+
def next_timeout
_fiber, timeout = @waiting.min_by{|key, value| value}
@@ -58,7 +69,7 @@ class Scheduler
# $stderr.puts [__method__, Fiber.current].inspect
while @readable.any? or @writable.any? or @waiting.any? or @blocking.any?
- # Can only handle file descriptors up to 1024...
+ # May only handle file descriptors up to 1024...
readable, writable = IO.select(@readable.keys + [@urgent.first], @writable.keys, [], next_timeout)
# puts "readable: #{readable}" if readable&.any?
@@ -83,7 +94,7 @@ class Scheduler
end
selected.each do |fiber, events|
- fiber.resume(events)
+ fiber.transfer(events)
end
if @waiting.any?
@@ -93,7 +104,7 @@ class Scheduler
waiting.each do |fiber, timeout|
if fiber.alive?
if timeout <= time
- fiber.resume
+ fiber.transfer
else
@waiting[fiber] = timeout
end
@@ -109,16 +120,22 @@ class Scheduler
end
ready.each do |fiber|
- fiber.resume
+ fiber.transfer
end
end
end
end
+ # A fiber scheduler hook, invoked when the scheduler goes out of scope.
def scheduler_close
close(true)
end
+ # If the `scheduler_close` hook does not exist, this method `close` will be
+ # invoked instead when the fiber scheduler goes out of scope. This is legacy
+ # behaviour, you should almost certainly use `scheduler_close`. The reason for
+ # this, is `scheduler_close` is called when the scheduler goes out of scope,
+ # while `close` may be called by the user.
def close(internal = false)
# $stderr.puts [__method__, Fiber.current].inspect
@@ -153,6 +170,7 @@ class Scheduler
Process.clock_gettime(Process::CLOCK_MONOTONIC)
end
+ # This hook is invoked by `Timeout.timeout` and related code.
def timeout_after(duration, klass, message, &block)
fiber = Fiber.current
@@ -171,6 +189,7 @@ class Scheduler
end
end
+ # This hook is invoked by `Process.wait`, `system`, and backticks.
def process_wait(pid, flags)
# $stderr.puts [__method__, pid, flags, Fiber.current].inspect
@@ -180,24 +199,47 @@ class Scheduler
end.value
end
+ # This hook is invoked by `IO#read` and `IO#write` in the case that `io_read`
+ # and `io_write` hooks are not available. This implementation is not
+ # completely general, in the sense that calling `io_wait` multiple times with
+ # the same `io` and `events` will not work, which is okay for tests but not
+ # for real code. Correct fiber schedulers should not have this limitation.
def io_wait(io, events, duration)
# $stderr.puts [__method__, io, events, duration, Fiber.current].inspect
+ fiber = Fiber.current
+
unless (events & IO::READABLE).zero?
- @readable[io] = Fiber.current
+ @readable[io] = fiber
+ readable = true
end
unless (events & IO::WRITABLE).zero?
- @writable[io] = Fiber.current
+ @writable[io] = fiber
+ writable = true
+ end
+
+ if duration
+ @waiting[fiber] = current_time + duration
end
- Fiber.yield
+ @fiber.transfer
ensure
- @readable.delete(io)
- @writable.delete(io)
+ @waiting.delete(fiber) if duration
+ @readable.delete(io) if readable
+ @writable.delete(io) if writable
end
- # Used for Kernel#sleep and Thread::Mutex#sleep
+ # This hook is invoked by `IO.select`. Using a thread ensures that the
+ # operation does not block the fiber scheduler.
+ def io_select(...)
+ # Emulate the operation using a non-blocking thread:
+ Thread.new do
+ IO.select(...)
+ end.value
+ end
+
+ # This hook is invoked by `Kernel#sleep` and `Thread::Mutex#sleep`.
def kernel_sleep(duration = nil)
# $stderr.puts [__method__, duration, Fiber.current].inspect
@@ -206,8 +248,10 @@ class Scheduler
return true
end
- # Used when blocking on synchronization (Thread::Mutex#lock,
- # Thread::Queue#pop, Thread::SizedQueue#push, ...)
+ # This hook is invoked by blocking options such as `Thread::Mutex#lock`,
+ # `Thread::Queue#pop` and `Thread::SizedQueue#push`, which are unblocked by
+ # other threads/fibers. To unblock a blocked fiber, you should call `unblock`
+ # with the same `blocker` and `fiber` arguments.
def block(blocker, timeout = nil)
# $stderr.puts [__method__, blocker, timeout].inspect
@@ -216,7 +260,7 @@ class Scheduler
if timeout
@waiting[fiber] = current_time + timeout
begin
- Fiber.yield
+ @fiber.transfer
ensure
# Remove from @waiting in the case #unblock was called before the timeout expired:
@waiting.delete(fiber)
@@ -224,16 +268,15 @@ class Scheduler
else
@blocking[fiber] = true
begin
- Fiber.yield
+ @fiber.transfer
ensure
@blocking.delete(fiber)
end
end
end
- # Used when synchronization wakes up a previously-blocked fiber
- # (Thread::Mutex#unlock, Thread::Queue#push, ...).
- # This might be called from another thread.
+ # This method is invoked from a thread or fiber to unblock a fiber that is
+ # blocked by `block`. It is expected to be thread safe.
def unblock(blocker, fiber)
# $stderr.puts [__method__, blocker, fiber].inspect
# $stderr.puts blocker.backtrace.inspect
@@ -247,14 +290,20 @@ class Scheduler
io.write_nonblock('.')
end
+ # This hook is invoked by `Fiber.schedule`. Strictly speaking, you should use
+ # it to create scheduled fibers, but it is not required in practice;
+ # `Fiber.new` is usually sufficient.
def fiber(&block)
fiber = Fiber.new(blocking: false, &block)
- fiber.resume
+ fiber.transfer
return fiber
end
+ # This hook is invoked by `Addrinfo.getaddrinfo`. Using a thread ensures that
+ # the operation does not block the fiber scheduler, since `getaddrinfo` is
+ # usually provided by `libc` and is blocking.
def address_resolve(hostname)
Thread.new do
Addrinfo.getaddrinfo(hostname, nil).map(&:ip_address).uniq
@@ -262,85 +311,133 @@ class Scheduler
end
end
+# This scheduler class implements `io_read` and `io_write` hooks which require
+# `IO::Buffer`.
class IOBufferScheduler < Scheduler
- EAGAIN = Errno::EAGAIN::Errno
+ EAGAIN = -Errno::EAGAIN::Errno
- def io_read(io, buffer, length)
- offset = 0
+ def io_read(io, buffer, length, offset)
+ total = 0
+ io.nonblock = true
while true
maximum_size = buffer.size - offset
- result = blocking{io.read_nonblock(maximum_size, exception: false)}
-
- # blocking{pp read: maximum_size, result: result, length: length}
+ result = blocking{buffer.read(io, maximum_size, offset)}
- case result
- when :wait_readable
+ if result > 0
+ total += result
+ offset += result
+ break if total >= length
+ elsif result == 0
+ break
+ elsif result == EAGAIN
if length > 0
self.io_wait(io, IO::READABLE, nil)
else
- return -EAGAIN
+ return result
end
- when :wait_writable
+ elsif result < 0
+ return result
+ end
+ end
+
+ return total
+ end
+
+ def io_write(io, buffer, length, offset)
+ total = 0
+ io.nonblock = true
+
+ while true
+ maximum_size = buffer.size - offset
+ result = blocking{buffer.write(io, maximum_size, offset)}
+
+ if result > 0
+ total += result
+ offset += result
+ break if total >= length
+ elsif result == 0
+ break
+ elsif result == EAGAIN
if length > 0
self.io_wait(io, IO::WRITABLE, nil)
else
- return -EAGAIN
+ return result
end
- else
- break unless result
-
- buffer.set_string(result, offset)
-
- size = result.bytesize
- offset += size
- break if size >= length
- length -= size
+ elsif result < 0
+ return result
end
end
- return offset
+ return total
end
- def io_write(io, buffer, length)
- offset = 0
+ def io_pread(io, buffer, from, length, offset)
+ total = 0
+ io.nonblock = true
while true
maximum_size = buffer.size - offset
+ result = blocking{buffer.pread(io, from, maximum_size, offset)}
- chunk = buffer.get_string(offset, maximum_size)
- result = blocking{io.write_nonblock(chunk, exception: false)}
-
- # blocking{pp write: maximum_size, result: result, length: length}
-
- case result
- when :wait_readable
+ if result > 0
+ total += result
+ offset += result
+ from += result
+ break if total >= length
+ elsif result == 0
+ break
+ elsif result == EAGAIN
if length > 0
self.io_wait(io, IO::READABLE, nil)
else
- return -EAGAIN
+ return result
end
- when :wait_writable
+ elsif result < 0
+ return result
+ end
+ end
+
+ return total
+ end
+
+ def io_pwrite(io, buffer, from, length, offset)
+ total = 0
+ io.nonblock = true
+
+ while true
+ maximum_size = buffer.size - offset
+ result = blocking{buffer.pwrite(io, from, maximum_size, offset)}
+
+ if result > 0
+ total += result
+ offset += result
+ from += result
+ break if total >= length
+ elsif result == 0
+ break
+ elsif result == EAGAIN
if length > 0
self.io_wait(io, IO::WRITABLE, nil)
else
- return -EAGAIN
+ return result
end
- else
- offset += result
- break if result >= length
- length -= result
+ elsif result < 0
+ return result
end
end
- return offset
+ return total
end
def blocking(&block)
- Fiber.new(blocking: true, &block).resume
+ Fiber.blocking(&block)
end
end
+# This scheduler has a broken implementation of `unblock`` in the sense that it
+# raises an exception. This is used to test the behavior of the scheduler when
+# unblock raises an exception.
class BrokenUnblockScheduler < Scheduler
def unblock(blocker, fiber)
super
@@ -349,6 +446,9 @@ class BrokenUnblockScheduler < Scheduler
end
end
+# This scheduler has a broken implementation of `unblock` in the sense that it
+# sleeps. This is used to test the behavior of the scheduler when unblock
+# messes with the internal thread state in an unexpected way.
class SleepingUnblockScheduler < Scheduler
# This method is invoked when the thread is exiting.
def unblock(blocker, fiber)
@@ -358,3 +458,16 @@ class SleepingUnblockScheduler < Scheduler
sleep(0.1)
end
end
+
+# This scheduler has a broken implementation of `kernel_sleep` in the sense that
+# it invokes a blocking sleep which can cause a deadlock in some cases.
+class SleepingBlockingScheduler < Scheduler
+ def kernel_sleep(duration = nil)
+ # Deliberaly sleep in a blocking state which can trigger a deadlock if the implementation is not correct.
+ Fiber.blocking{sleep 0.0001}
+
+ self.block(:sleep, duration)
+
+ return true
+ end
+end
diff --git a/test/fiber/test_address_resolve.rb b/test/fiber/test_address_resolve.rb
index 457221b9b1..09c8db6049 100644
--- a/test/fiber/test_address_resolve.rb
+++ b/test/fiber/test_address_resolve.rb
@@ -179,7 +179,7 @@ class TestAddressResolve < Test::Unit::TestCase
Fiber.set_scheduler scheduler
Fiber.schedule do
- assert_raise(SocketError) {
+ assert_raise(Socket::ResolutionError) {
Addrinfo.getaddrinfo("non-existing-domain.abc", nil)
}
end
@@ -269,7 +269,7 @@ class TestAddressResolve < Test::Unit::TestCase
Fiber.set_scheduler scheduler
Fiber.schedule do
- result = Socket.getnameinfo(["AF_INET", 80, "example.com"], Socket::NI_NUMERICSERV)
+ result = Socket.getnameinfo(["AF_INET", 80, "example.com"], Socket::NI_NUMERICSERV | Socket::NI_NUMERICHOST)
assert_equal(["1.2.3.4", "80"], result)
end
diff --git a/test/fiber/test_enumerator.rb b/test/fiber/test_enumerator.rb
index c635f474db..e9410f925c 100644
--- a/test/fiber/test_enumerator.rb
+++ b/test/fiber/test_enumerator.rb
@@ -10,12 +10,6 @@ class TestFiberEnumerator < Test::Unit::TestCase
i, o = UNIXSocket.pair
- unless i.nonblock? && o.nonblock?
- i.close
- o.close
- omit "I/O is not non-blocking!"
- end
-
message = String.new
thread = Thread.new do
@@ -48,4 +42,12 @@ class TestFiberEnumerator < Test::Unit::TestCase
assert_predicate(i, :closed?)
assert_predicate(o, :closed?)
end
+
+ def enumerator_fiber_is_nonblocking
+ enumerator = Enumerator.new do |yielder|
+ yielder << Fiber.current.blocking?
+ end
+
+ assert_equal(false, enumerator.next)
+ end
end
diff --git a/test/fiber/test_io.rb b/test/fiber/test_io.rb
index 4252641cde..0e3e086d5a 100644
--- a/test/fiber/test_io.rb
+++ b/test/fiber/test_io.rb
@@ -6,14 +6,12 @@ class TestFiberIO < Test::Unit::TestCase
MESSAGE = "Hello World"
def test_read
- omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+ omit unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
-
- unless i.nonblock? && o.nonblock?
- i.close
- o.close
- omit "I/O is not non-blocking!"
+ if RUBY_PLATFORM=~/mswin|mingw/
+ i.nonblock = true
+ o.nonblock = true
end
message = nil
@@ -46,6 +44,10 @@ class TestFiberIO < Test::Unit::TestCase
16.times.map do
Thread.new do
i, o = UNIXSocket.pair
+ if RUBY_PLATFORM=~/mswin|mingw/
+ i.nonblock = true
+ o.nonblock = true
+ end
scheduler = Scheduler.new
Fiber.set_scheduler scheduler
@@ -64,16 +66,11 @@ class TestFiberIO < Test::Unit::TestCase
end
def test_epipe_on_read
- omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+ omit unless defined?(UNIXSocket)
+ omit "nonblock=true isn't properly supported on Windows" if RUBY_PLATFORM=~/mswin|mingw/
i, o = UNIXSocket.pair
- unless i.nonblock? && o.nonblock?
- i.close
- o.close
- omit "I/O is not non-blocking!"
- end
-
error = nil
thread = Thread.new do
@@ -172,4 +169,69 @@ class TestFiberIO < Test::Unit::TestCase
assert_predicate(i, :closed?)
assert_predicate(o, :closed?)
end
+
+ def test_puts_empty
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ i, o = UNIXSocket.pair
+ i.nonblock = false
+ o.nonblock = false
+
+ thread = Thread.new do
+ # This scheduler provides non-blocking `io_read`/`io_write`:
+ scheduler = IOBufferScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ # This was causing a segfault on older Ruby.
+ o.puts ""
+ o.puts nil
+ o.close
+ end
+ end
+
+ thread.join
+
+ message = i.read
+ i.close
+
+ assert_equal $/*2, message
+ end
+
+ def test_io_select
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ UNIXSocket.pair do |r, w|
+ result = nil
+
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ w.write("Hello World")
+ result = IO.select([r], [w])
+ end
+ end
+
+ thread.join
+
+ assert_equal [[r], [w], []], result
+ end
+ end
+
+ def test_backquote
+ result = nil
+
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+ Fiber.schedule do
+ result = `#{EnvUtil.rubybin} -e "sleep 0.1;puts %[ok]"`
+ end
+ end
+ thread.join
+
+ assert_equal "ok\n", result
+ end
end
diff --git a/test/fiber/test_io_buffer.rb b/test/fiber/test_io_buffer.rb
index 48a34c31b6..a08b1ce1a9 100644
--- a/test/fiber/test_io_buffer.rb
+++ b/test/fiber/test_io_buffer.rb
@@ -122,4 +122,78 @@ class TestFiberIOBuffer < Test::Unit::TestCase
i&.close
o&.close
end
+
+ def test_io_buffer_read_write
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ i, o = UNIXSocket.pair
+ source_buffer = IO::Buffer.for("Hello World!")
+ destination_buffer = IO::Buffer.new(source_buffer.size)
+
+ # Test non-scheduler code path:
+ source_buffer.write(o, source_buffer.size)
+ destination_buffer.read(i, source_buffer.size)
+ assert_equal source_buffer, destination_buffer
+
+ # Test scheduler code path:
+ destination_buffer.clear
+
+ thread = Thread.new do
+ scheduler = IOBufferScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ source_buffer.write(o, source_buffer.size)
+ destination_buffer.read(i, source_buffer.size)
+ end
+ end
+
+ thread.join
+
+ assert_equal source_buffer, destination_buffer
+ ensure
+ i&.close
+ o&.close
+ end
+
+ def nonblockable?(io)
+ io.nonblock{}
+ true
+ rescue
+ false
+ end
+
+ def test_io_buffer_pread_pwrite
+ file = Tempfile.new("test_io_buffer_pread_pwrite")
+
+ omit "Non-blocking file IO is not supported" unless nonblockable?(file)
+
+ source_buffer = IO::Buffer.for("Hello World!")
+ destination_buffer = IO::Buffer.new(source_buffer.size)
+
+ # Test non-scheduler code path:
+ source_buffer.pwrite(file, 1, source_buffer.size)
+ destination_buffer.pread(file, 1, source_buffer.size)
+ assert_equal source_buffer, destination_buffer
+
+ # Test scheduler code path:
+ destination_buffer.clear
+ file.truncate(0)
+
+ thread = Thread.new do
+ scheduler = IOBufferScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ source_buffer.pwrite(file, 1, source_buffer.size)
+ destination_buffer.pread(file, 1, source_buffer.size)
+ end
+ end
+
+ thread.join
+
+ assert_equal source_buffer, destination_buffer
+ ensure
+ file&.close!
+ end
end
diff --git a/test/fiber/test_mutex.rb b/test/fiber/test_mutex.rb
index b0655f06a5..2cee2cc235 100644
--- a/test/fiber/test_mutex.rb
+++ b/test/fiber/test_mutex.rb
@@ -194,7 +194,7 @@ class TestFiberMutex < Test::Unit::TestCase
end
def test_mutex_deadlock
- error_pattern = /No live threads left. Deadlock\?/
+ error_pattern = /lock already owned by another fiber/
assert_in_out_err %W[-I#{__dir__} -], <<-RUBY, ['in synchronize'], error_pattern, success: false
require 'scheduler'
@@ -207,7 +207,7 @@ class TestFiberMutex < Test::Unit::TestCase
Fiber.schedule do
mutex.synchronize do
puts 'in synchronize'
- Fiber.yield
+ scheduler.transfer
end
end
@@ -217,4 +217,24 @@ class TestFiberMutex < Test::Unit::TestCase
thread.join
RUBY
end
+
+ def test_mutex_fiber_deadlock_no_scheduler
+ thr = Thread.new do
+ loop do
+ sleep 1
+ end
+ end
+
+ mutex = Mutex.new
+ mutex.synchronize do
+ error = assert_raise ThreadError do
+ Fiber.new do
+ mutex.lock
+ end.resume
+ end
+ assert_includes error.message, "deadlock; lock already owned by another fiber belonging to the same thread"
+ end
+ ensure
+ thr&.kill&.join
+ end
end
diff --git a/test/fiber/test_process.rb b/test/fiber/test_process.rb
index a5990be204..a09b070c0a 100644
--- a/test/fiber/test_process.rb
+++ b/test/fiber/test_process.rb
@@ -3,13 +3,15 @@ require 'test/unit'
require_relative 'scheduler'
class TestFiberProcess < Test::Unit::TestCase
+ TRUE_CMD = RUBY_PLATFORM =~ /mswin|mingw/ ? "exit 0" : "true"
+
def test_process_wait
Thread.new do
scheduler = Scheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
- pid = Process.spawn("true")
+ pid = Process.spawn(TRUE_CMD)
Process.wait(pid)
# TODO test that scheduler was invoked.
@@ -25,7 +27,7 @@ class TestFiberProcess < Test::Unit::TestCase
Fiber.set_scheduler scheduler
Fiber.schedule do
- system("true")
+ system(TRUE_CMD)
# TODO test that scheduler was invoked (currently it's not).
@@ -34,6 +36,27 @@ class TestFiberProcess < Test::Unit::TestCase
end.join
end
+ def test_system_faulty_process_wait
+ Thread.new do
+ scheduler = Scheduler.new
+
+ def scheduler.process_wait(pid, flags)
+ Fiber.blocking{Process.wait(pid, flags)}
+
+ # Don't return `Process::Status` instance.
+ return false
+ end
+
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ assert_raise TypeError do
+ system(TRUE_CMD)
+ end
+ end
+ end.join
+ end
+
def test_fork
omit 'fork not supported' unless Process.respond_to?(:fork)
Thread.new do
diff --git a/test/fiber/test_queue.rb b/test/fiber/test_queue.rb
new file mode 100644
index 0000000000..d78b026f11
--- /dev/null
+++ b/test/fiber/test_queue.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+require 'test/unit'
+require_relative 'scheduler'
+
+class TestFiberQueue < Test::Unit::TestCase
+ def test_pop_with_timeout
+ queue = Thread::Queue.new
+ kill = false
+ result = :unspecified
+
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler(scheduler)
+
+ Fiber.schedule do
+ result = queue.pop(timeout: 0.0001)
+ end
+
+ scheduler.run
+ end
+ until thread.join(2)
+ kill = true
+ thread.kill
+ end
+
+ assert_false(kill, 'Getting stuck due to a possible compiler bug.')
+ assert_nil result
+ end
+
+ def test_pop_with_timeout_and_value
+ queue = Thread::Queue.new
+ queue.push(:something)
+ kill = false
+ result = :unspecified
+
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler(scheduler)
+
+ Fiber.schedule do
+ result = queue.pop(timeout: 0.0001)
+ end
+
+ scheduler.run
+ end
+ until thread.join(2)
+ kill = true
+ thread.kill
+ end
+
+ assert_false(kill, 'Getting stuck due to a possible compiler bug.')
+ assert_equal :something, result
+ end
+end
diff --git a/test/fiber/test_scheduler.rb b/test/fiber/test_scheduler.rb
index 4b1310f0a6..34effad816 100644
--- a/test/fiber/test_scheduler.rb
+++ b/test/fiber/test_scheduler.rb
@@ -27,6 +27,18 @@ class TestFiberScheduler < Test::Unit::TestCase
refute f.blocking?
end
+ def test_fiber_blocking
+ f = Fiber.new(blocking: false) do
+ fiber = Fiber.current
+ refute fiber.blocking?
+ Fiber.blocking do |_fiber|
+ assert_equal fiber, _fiber
+ assert fiber.blocking?
+ end
+ end
+ f.resume
+ end
+
def test_closed_at_thread_exit
scheduler = Scheduler.new
@@ -106,7 +118,7 @@ class TestFiberScheduler < Test::Unit::TestCase
end
def test_autoload
- 100.times do
+ 10.times do
Object.autoload(:TestFiberSchedulerAutoload, File.expand_path("autoload.rb", __dir__))
thread = Thread.new do
@@ -126,4 +138,48 @@ class TestFiberScheduler < Test::Unit::TestCase
Object.send(:remove_const, :TestFiberSchedulerAutoload)
end
end
+
+ def test_deadlock
+ mutex = Thread::Mutex.new
+ condition = Thread::ConditionVariable.new
+ q = 0.0001
+
+ signaller = Thread.new do
+ loop do
+ mutex.synchronize do
+ condition.signal
+ end
+ sleep q
+ end
+ end
+
+ i = 0
+
+ thread = Thread.new do
+ scheduler = SleepingBlockingScheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ 10.times do
+ mutex.synchronize do
+ condition.wait(mutex)
+ sleep q
+ i += 1
+ end
+ end
+ end
+ end
+
+ # Wait for 10 seconds at most... if it doesn't finish, it's deadlocked.
+ thread.join(10)
+
+ # If it's deadlocked, it will never finish, so this will be 0.
+ assert_equal 10, i
+ ensure
+ # Make sure the threads are dead...
+ thread.kill
+ signaller.kill
+ thread.join
+ signaller.join
+ end
end
diff --git a/test/fiber/test_storage.rb b/test/fiber/test_storage.rb
new file mode 100644
index 0000000000..3726decbdb
--- /dev/null
+++ b/test/fiber/test_storage.rb
@@ -0,0 +1,115 @@
+# frozen_string_literal: true
+require 'test/unit'
+
+class TestFiberStorage < Test::Unit::TestCase
+ def test_storage
+ Fiber.new do
+ Fiber[:x] = 10
+ assert_kind_of Hash, Fiber.current.storage
+ assert_predicate Fiber.current.storage, :any?
+ end.resume
+ end
+
+ def test_storage_inherited
+ Fiber.new do
+ Fiber[:foo] = :bar
+
+ Fiber.new do
+ assert_equal :bar, Fiber[:foo]
+ Fiber[:bar] = :baz
+ end.resume
+
+ assert_nil Fiber[:bar]
+ end.resume
+ end
+
+ def test_variable_assignment
+ Fiber.new do
+ Fiber[:foo] = :bar
+ assert_equal :bar, Fiber[:foo]
+ end.resume
+ end
+
+ def test_storage_assignment
+ old, Warning[:experimental] = Warning[:experimental], false
+
+ Fiber.new do
+ Fiber.current.storage = {foo: :bar}
+ assert_equal :bar, Fiber[:foo]
+ end.resume
+ ensure
+ Warning[:experimental] = old
+ end
+
+ def test_storage_only_allow_access_from_same_fiber
+ old, Warning[:experimental] = Warning[:experimental], false
+
+ f = Fiber.new do
+ Fiber[:a] = 1
+ end
+ assert_raise(ArgumentError) { f.storage }
+ assert_raise(ArgumentError) { f.storage = {} }
+ ensure
+ Warning[:experimental] = old
+ end
+
+ def test_inherited_storage
+ Fiber.new(storage: {foo: :bar}) do
+ f = Fiber.new do
+ assert_equal :bar, Fiber[:foo]
+ end
+ f.resume
+ end.resume
+ end
+
+ def test_enumerator_inherited_storage
+ Fiber.new do
+ Fiber[:item] = "Hello World"
+
+ enumerator = Enumerator.new do |out|
+ out << Fiber.current
+ out << Fiber[:item]
+ end
+
+ # The fiber within the enumerator is not equal to the current...
+ assert_not_equal Fiber.current, enumerator.next
+
+ # But it inherited the storage from the current fiber:
+ assert_equal "Hello World", enumerator.next
+ end.resume
+ end
+
+ def test_thread_inherited_storage
+ Fiber.new do
+ Fiber[:x] = 10
+
+ x = Thread.new do
+ Fiber[:y] = 20
+ Fiber[:x]
+ end.value
+
+ assert_equal 10, x
+ assert_equal nil, Fiber[:y]
+ end.resume
+ end
+
+ def test_enumerator_count
+ Fiber.new do
+ Fiber[:count] = 0
+
+ enumerator = Enumerator.new do |y|
+ Fiber[:count] += 1
+ y << Fiber[:count]
+ end
+
+ assert_equal 1, enumerator.next
+ assert_equal 0, Fiber[:count]
+ end.resume
+ end
+
+ def test_storage_assignment_type_error
+ assert_raise(TypeError) do
+ Fiber.new(storage: {Object.new => "bar"}) {}
+ end
+ end
+end
diff --git a/test/fiber/test_thread.rb b/test/fiber/test_thread.rb
index 5c25c43de2..5e3cc6d0e1 100644
--- a/test/fiber/test_thread.rb
+++ b/test/fiber/test_thread.rb
@@ -20,6 +20,28 @@ class TestFiberThread < Test::Unit::TestCase
assert_equal :done, thread.value
end
+ def test_thread_join_timeout
+ sleeper = nil
+
+ thread = Thread.new do
+ scheduler = Scheduler.new
+ Fiber.set_scheduler scheduler
+
+ Fiber.schedule do
+ sleeper = Thread.new{sleep}
+ sleeper.join(0.1)
+ end
+
+ scheduler.run
+ end
+
+ thread.join
+
+ assert_predicate sleeper, :alive?
+ ensure
+ sleeper&.kill&.join
+ end
+
def test_thread_join_implicit
sleeping = false
finished = false
diff --git a/test/fiddle/helper.rb b/test/fiddle/helper.rb
index 0ea3bf57f4..e470f5a276 100644
--- a/test/fiddle/helper.rb
+++ b/test/fiddle/helper.rb
@@ -49,8 +49,14 @@ when /linux/
libm_so = libc_so
else
# glibc
- libc_so = "libc.so.6"
- libm_so = "libm.so.6"
+ case RUBY_PLATFORM
+ when /alpha-linux/, /ia64-linux/
+ libc_so = "libc.so.6.1"
+ libm_so = "libm.so.6.1"
+ else
+ libc_so = "libc.so.6"
+ libm_so = "libm.so.6"
+ end
end
when /mingw/, /mswin/
require "rbconfig"
diff --git a/test/fiddle/test_c_struct_entry.rb b/test/fiddle/test_c_struct_entry.rb
index 9fd16d7101..45de2efe21 100644
--- a/test/fiddle/test_c_struct_entry.rb
+++ b/test/fiddle/test_c_struct_entry.rb
@@ -8,7 +8,7 @@ end
module Fiddle
class TestCStructEntity < TestCase
def test_class_size
- types = [TYPE_DOUBLE, TYPE_CHAR]
+ types = [TYPE_DOUBLE, TYPE_CHAR, TYPE_DOUBLE, TYPE_BOOL]
size = CStructEntity.size types
@@ -20,6 +20,12 @@ module Fiddle
expected = PackInfo.align expected, alignments[1]
expected += PackInfo::SIZE_MAP[TYPE_CHAR]
+ expected = PackInfo.align expected, alignments[2]
+ expected += PackInfo::SIZE_MAP[TYPE_DOUBLE]
+
+ expected = PackInfo.align expected, alignments[3]
+ expected += PackInfo::SIZE_MAP[TYPE_BOOL]
+
expected = PackInfo.align expected, alignments.max
assert_equal expected, size
diff --git a/test/fiddle/test_closure.rb b/test/fiddle/test_closure.rb
index 9e748bf5ee..abb6bdbd32 100644
--- a/test/fiddle/test_closure.rb
+++ b/test/fiddle/test_closure.rb
@@ -6,6 +6,17 @@ end
module Fiddle
class TestClosure < Fiddle::TestCase
+ def teardown
+ super
+ # Ensure freeing all closures.
+ # See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 .
+ not_freed_closures = []
+ ObjectSpace.each_object(Fiddle::Closure) do |closure|
+ not_freed_closures << closure unless closure.freed?
+ end
+ assert_equal([], not_freed_closures)
+ end
+
def test_argument_errors
assert_raise(TypeError) do
Closure.new(TYPE_INT, TYPE_INT)
@@ -21,37 +32,40 @@ module Fiddle
end
def test_type_symbol
- closure = Closure.new(:int, [:void])
- assert_equal([
- TYPE_INT,
- [TYPE_VOID],
- ],
- [
- closure.instance_variable_get(:@ctype),
- closure.instance_variable_get(:@args),
- ])
+ Closure.create(:int, [:void]) do |closure|
+ assert_equal([
+ TYPE_INT,
+ [TYPE_VOID],
+ ],
+ [
+ closure.instance_variable_get(:@ctype),
+ closure.instance_variable_get(:@args),
+ ])
+ end
end
def test_call
- closure = Class.new(Closure) {
+ closure_class = Class.new(Closure) do
def call
10
end
- }.new(TYPE_INT, [])
-
- func = Function.new(closure, [], TYPE_INT)
- assert_equal 10, func.call
+ end
+ closure_class.create(TYPE_INT, []) do |closure|
+ func = Function.new(closure, [], TYPE_INT)
+ assert_equal 10, func.call
+ end
end
def test_returner
- closure = Class.new(Closure) {
+ closure_class = Class.new(Closure) do
def call thing
thing
end
- }.new(TYPE_INT, [TYPE_INT])
-
- func = Function.new(closure, [TYPE_INT], TYPE_INT)
- assert_equal 10, func.call(10)
+ end
+ closure_class.create(TYPE_INT, [TYPE_INT]) do |closure|
+ func = Function.new(closure, [TYPE_INT], TYPE_INT)
+ assert_equal 10, func.call(10)
+ end
end
def test_const_string
@@ -61,25 +75,53 @@ module Fiddle
@return_string
end
end
- closure = closure_class.new(:const_string, [:const_string])
+ closure_class.create(:const_string, [:const_string]) do |closure|
+ func = Function.new(closure, [:const_string], :const_string)
+ assert_equal("Hello! World!", func.call("World!"))
+ end
+ end
- func = Function.new(closure, [:const_string], :const_string)
- assert_equal("Hello! World!", func.call("World!"))
+ def test_bool
+ closure_class = Class.new(Closure) do
+ def call(bool)
+ not bool
+ end
+ end
+ closure_class.create(:bool, [:bool]) do |closure|
+ func = Function.new(closure, [:bool], :bool)
+ assert_equal(false, func.call(true))
+ end
+ end
+
+ def test_free
+ Closure.create(:int, [:void]) do |closure|
+ assert(!closure.freed?)
+ closure.free
+ assert(closure.freed?)
+ closure.free
+ end
end
def test_block_caller
cb = Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |one|
one
end
- func = Function.new(cb, [TYPE_INT], TYPE_INT)
- assert_equal 11, func.call(11)
+ begin
+ func = Function.new(cb, [TYPE_INT], TYPE_INT)
+ assert_equal 11, func.call(11)
+ ensure
+ cb.free
+ end
end
- def test_memsize
+ def test_memsize_ruby_dev_42480
require 'objspace'
- bug = '[ruby-dev:42480]'
n = 10000
- assert_equal(n, n.times {ObjectSpace.memsize_of(Closure.allocate)}, bug)
+ n.times do
+ Closure.create(:int, [:void]) do |closure|
+ ObjectSpace.memsize_of(closure)
+ end
+ end
end
%w[INT SHORT CHAR LONG LONG_LONG].each do |name|
@@ -89,20 +131,21 @@ module Fiddle
define_method("test_conversion_#{n.downcase}") do
arg = nil
- clos = Class.new(Closure) do
+ closure_class = Class.new(Closure) do
define_method(:call) {|x| arg = x}
- end.new(t, [t])
-
- v = ~(~0 << (8*s))
-
- arg = nil
- assert_equal(v, clos.call(v))
- assert_equal(arg, v, n)
-
- arg = nil
- func = Function.new(clos, [t], t)
- assert_equal(v, func.call(v))
- assert_equal(arg, v, n)
+ end
+ closure_class.create(t, [t]) do |closure|
+ v = ~(~0 << (8*s))
+
+ arg = nil
+ assert_equal(v, closure.call(v))
+ assert_equal(arg, v, n)
+
+ arg = nil
+ func = Function.new(closure, [t], t)
+ assert_equal(v, func.call(v))
+ assert_equal(arg, v, n)
+ end
end
end
end
diff --git a/test/fiddle/test_cparser.rb b/test/fiddle/test_cparser.rb
index ae319197a4..f1b67476ba 100644
--- a/test/fiddle/test_cparser.rb
+++ b/test/fiddle/test_cparser.rb
@@ -24,14 +24,32 @@ module Fiddle
assert_equal(TYPE_SHORT, parse_ctype('const short'))
assert_equal(TYPE_SHORT, parse_ctype('short int'))
assert_equal(TYPE_SHORT, parse_ctype('const short int'))
+ assert_equal(TYPE_SHORT, parse_ctype('int short'))
+ assert_equal(TYPE_SHORT, parse_ctype('const int short'))
assert_equal(TYPE_SHORT, parse_ctype('signed short'))
assert_equal(TYPE_SHORT, parse_ctype('const signed short'))
+ assert_equal(TYPE_SHORT, parse_ctype('short signed'))
+ assert_equal(TYPE_SHORT, parse_ctype('const short signed'))
assert_equal(TYPE_SHORT, parse_ctype('signed short int'))
assert_equal(TYPE_SHORT, parse_ctype('const signed short int'))
+ assert_equal(TYPE_SHORT, parse_ctype('signed int short'))
+ assert_equal(TYPE_SHORT, parse_ctype('const signed int short'))
+ assert_equal(TYPE_SHORT, parse_ctype('int signed short'))
+ assert_equal(TYPE_SHORT, parse_ctype('const int signed short'))
+ assert_equal(TYPE_SHORT, parse_ctype('int short signed'))
+ assert_equal(TYPE_SHORT, parse_ctype('const int short signed'))
assert_equal(-TYPE_SHORT, parse_ctype('unsigned short'))
assert_equal(-TYPE_SHORT, parse_ctype('const unsigned short'))
assert_equal(-TYPE_SHORT, parse_ctype('unsigned short int'))
assert_equal(-TYPE_SHORT, parse_ctype('const unsigned short int'))
+ assert_equal(-TYPE_SHORT, parse_ctype('unsigned int short'))
+ assert_equal(-TYPE_SHORT, parse_ctype('const unsigned int short'))
+ assert_equal(-TYPE_SHORT, parse_ctype('short int unsigned'))
+ assert_equal(-TYPE_SHORT, parse_ctype('const short int unsigned'))
+ assert_equal(-TYPE_SHORT, parse_ctype('int unsigned short'))
+ assert_equal(-TYPE_SHORT, parse_ctype('const int unsigned short'))
+ assert_equal(-TYPE_SHORT, parse_ctype('int short unsigned'))
+ assert_equal(-TYPE_SHORT, parse_ctype('const int short unsigned'))
end
def test_int_ctype
@@ -50,14 +68,32 @@ module Fiddle
assert_equal(TYPE_LONG, parse_ctype('const long'))
assert_equal(TYPE_LONG, parse_ctype('long int'))
assert_equal(TYPE_LONG, parse_ctype('const long int'))
+ assert_equal(TYPE_LONG, parse_ctype('int long'))
+ assert_equal(TYPE_LONG, parse_ctype('const int long'))
assert_equal(TYPE_LONG, parse_ctype('signed long'))
assert_equal(TYPE_LONG, parse_ctype('const signed long'))
assert_equal(TYPE_LONG, parse_ctype('signed long int'))
assert_equal(TYPE_LONG, parse_ctype('const signed long int'))
+ assert_equal(TYPE_LONG, parse_ctype('signed int long'))
+ assert_equal(TYPE_LONG, parse_ctype('const signed int long'))
+ assert_equal(TYPE_LONG, parse_ctype('long signed'))
+ assert_equal(TYPE_LONG, parse_ctype('const long signed'))
+ assert_equal(TYPE_LONG, parse_ctype('long int signed'))
+ assert_equal(TYPE_LONG, parse_ctype('const long int signed'))
+ assert_equal(TYPE_LONG, parse_ctype('int long signed'))
+ assert_equal(TYPE_LONG, parse_ctype('const int long signed'))
assert_equal(-TYPE_LONG, parse_ctype('unsigned long'))
assert_equal(-TYPE_LONG, parse_ctype('const unsigned long'))
assert_equal(-TYPE_LONG, parse_ctype('unsigned long int'))
assert_equal(-TYPE_LONG, parse_ctype('const unsigned long int'))
+ assert_equal(-TYPE_LONG, parse_ctype('long int unsigned'))
+ assert_equal(-TYPE_LONG, parse_ctype('const long int unsigned'))
+ assert_equal(-TYPE_LONG, parse_ctype('unsigned int long'))
+ assert_equal(-TYPE_LONG, parse_ctype('const unsigned int long'))
+ assert_equal(-TYPE_LONG, parse_ctype('int unsigned long'))
+ assert_equal(-TYPE_LONG, parse_ctype('const int unsigned long'))
+ assert_equal(-TYPE_LONG, parse_ctype('int long unsigned'))
+ assert_equal(-TYPE_LONG, parse_ctype('const int long unsigned'))
end
def test_size_t_ctype
@@ -85,6 +121,10 @@ module Fiddle
assert_equal(TYPE_UINTPTR_T, parse_ctype("const uintptr_t"))
end
+ def test_bool_ctype
+ assert_equal(TYPE_BOOL, parse_ctype('bool'))
+ end
+
def test_undefined_ctype
assert_raise(DLError) { parse_ctype('DWORD') }
end
diff --git a/test/fiddle/test_fiddle.rb b/test/fiddle/test_fiddle.rb
index 8751d96920..9bddb056c9 100644
--- a/test/fiddle/test_fiddle.rb
+++ b/test/fiddle/test_fiddle.rb
@@ -5,6 +5,13 @@ rescue LoadError
end
class TestFiddle < Fiddle::TestCase
+ def test_nil_true_etc
+ assert_equal Fiddle::Qtrue, Fiddle.dlwrap(true)
+ assert_equal Fiddle::Qfalse, Fiddle.dlwrap(false)
+ assert_equal Fiddle::Qnil, Fiddle.dlwrap(nil)
+ assert Fiddle::Qundef
+ end
+
def test_windows_constant
require 'rbconfig'
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
@@ -14,4 +21,38 @@ class TestFiddle < Fiddle::TestCase
end
end
+ def test_dlopen_linker_script_input_linux
+ omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
+ if Dir.glob("/usr/lib/*/libncurses.so").empty?
+ omit("libncurses.so is needed")
+ end
+ # libncurses.so uses INPUT() on Debian GNU/Linux
+ # $ cat /usr/lib/x86_64-linux-gnu/libncurses.so
+ # INPUT(libncurses.so.6 -ltinfo)
+ handle = Fiddle.dlopen("libncurses.so")
+ begin
+ assert_equal("libncurses.so",
+ File.basename(handle.file_name, ".*"))
+ ensure
+ handle.close
+ end
+ end
+
+ def test_dlopen_linker_script_group_linux
+ omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
+ # libc.so uses GROUP() on Debian GNU/Linux
+ # $ cat /usr/lib/x86_64-linux-gnu/libc.so
+ # /* GNU ld script
+ # Use the shared library, but some functions are only in
+ # the static library, so try that secondarily. */
+ # OUTPUT_FORMAT(elf64-x86-64)
+ # GROUP ( /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )
+ handle = Fiddle.dlopen("libc.so")
+ begin
+ assert_equal("libc.so",
+ File.basename(handle.file_name, ".*"))
+ ensure
+ handle.close
+ end
+ end
end if defined?(Fiddle)
diff --git a/test/fiddle/test_func.rb b/test/fiddle/test_func.rb
index 44893017e8..df79539e76 100644
--- a/test/fiddle/test_func.rb
+++ b/test/fiddle/test_func.rb
@@ -60,25 +60,35 @@ module Fiddle
end
def test_qsort1
- cb = Class.new(Closure) {
+ closure_class = Class.new(Closure) do
def call(x, y)
Pointer.new(x)[0] <=> Pointer.new(y)[0]
end
- }.new(TYPE_INT, [TYPE_VOIDP, TYPE_VOIDP])
+ end
- qsort = Function.new(@libc['qsort'],
- [TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T, TYPE_VOIDP],
- TYPE_VOID)
- buff = "9341"
- qsort.call(buff, buff.size, 1, cb)
- assert_equal("1349", buff)
+ closure_class.create(TYPE_INT, [TYPE_VOIDP, TYPE_VOIDP]) do |callback|
+ qsort = Function.new(@libc['qsort'],
+ [TYPE_VOIDP, TYPE_SIZE_T, TYPE_SIZE_T, TYPE_VOIDP],
+ TYPE_VOID)
+ buff = "9341"
+ qsort.call(buff, buff.size, 1, callback)
+ assert_equal("1349", buff)
- bug4929 = '[ruby-core:37395]'
- buff = "9341"
- under_gc_stress do
- qsort.call(buff, buff.size, 1, cb)
+ bug4929 = '[ruby-core:37395]'
+ buff = "9341"
+ under_gc_stress do
+ qsort.call(buff, buff.size, 1, callback)
+ end
+ assert_equal("1349", buff, bug4929)
+ end
+ ensure
+ # Ensure freeing all closures.
+ # See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 .
+ not_freed_closures = []
+ ObjectSpace.each_object(Fiddle::Closure) do |closure|
+ not_freed_closures << closure unless closure.freed?
end
- assert_equal("1349", buff, bug4929)
+ assert_equal([], not_freed_closures)
end
def test_snprintf
@@ -135,5 +145,22 @@ module Fiddle
assert_equal("string: He, const string: World, uint: 29\n",
output_buffer[0, written])
end
+
+ def test_rb_memory_view_available_p
+ omit "MemoryView is unavailable" unless defined? Fiddle::MemoryView
+ libruby = Fiddle.dlopen(nil)
+ case Fiddle::SIZEOF_VOIDP
+ when Fiddle::SIZEOF_LONG_LONG
+ value_type = -Fiddle::TYPE_LONG_LONG
+ else
+ value_type = -Fiddle::TYPE_LONG
+ end
+ rb_memory_view_available_p =
+ Function.new(libruby["rb_memory_view_available_p"],
+ [value_type],
+ :bool,
+ need_gvl: true)
+ assert_equal(false, rb_memory_view_available_p.call(Fiddle::Qnil))
+ end
end
end if defined?(Fiddle)
diff --git a/test/fiddle/test_function.rb b/test/fiddle/test_function.rb
index 8ac4f60aa3..847df3793a 100644
--- a/test/fiddle/test_function.rb
+++ b/test/fiddle/test_function.rb
@@ -15,6 +15,16 @@ module Fiddle
end
end
+ def teardown
+ # Ensure freeing all closures.
+ # See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 .
+ not_freed_closures = []
+ ObjectSpace.each_object(Fiddle::Closure) do |closure|
+ not_freed_closures << closure unless closure.freed?
+ end
+ assert_equal([], not_freed_closures)
+ end
+
def test_default_abi
func = Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE)
assert_equal Function::DEFAULT, func.abi
@@ -75,18 +85,20 @@ module Fiddle
end
def test_argument_count
- closure = Class.new(Closure) {
+ closure_class = Class.new(Closure) do
def call one
10 + one
end
- }.new(TYPE_INT, [TYPE_INT])
- func = Function.new(closure, [TYPE_INT], TYPE_INT)
-
- assert_raise(ArgumentError) do
- func.call(1,2,3)
end
- assert_raise(ArgumentError) do
- func.call
+ closure_class.create(TYPE_INT, [TYPE_INT]) do |closure|
+ func = Function.new(closure, [TYPE_INT], TYPE_INT)
+
+ assert_raise(ArgumentError) do
+ func.call(1,2,3)
+ end
+ assert_raise(ArgumentError) do
+ func.call
+ end
end
end
diff --git a/test/fiddle/test_handle.rb b/test/fiddle/test_handle.rb
index 7e3ff9d844..412c10e09d 100644
--- a/test/fiddle/test_handle.rb
+++ b/test/fiddle/test_handle.rb
@@ -22,12 +22,14 @@ module Fiddle
def test_static_sym_unknown
assert_raise(DLError) { Fiddle::Handle.sym('fooo') }
assert_raise(DLError) { Fiddle::Handle['fooo'] }
+ refute Fiddle::Handle.sym_defined?('fooo')
end
def test_static_sym
begin
# Linux / Darwin / FreeBSD
refute_nil Fiddle::Handle.sym('dlopen')
+ assert Fiddle::Handle.sym_defined?('dlopen')
assert_equal Fiddle::Handle.sym('dlopen'), Fiddle::Handle['dlopen']
return
rescue
@@ -54,6 +56,7 @@ module Fiddle
handle = Fiddle::Handle.new(LIBC_SO)
assert_raise(DLError) { handle.sym('fooo') }
assert_raise(DLError) { handle['fooo'] }
+ refute handle.sym_defined?('fooo')
end
def test_sym_with_bad_args
@@ -66,6 +69,7 @@ module Fiddle
handle = Handle.new(LIBC_SO)
refute_nil handle.sym('calloc')
refute_nil handle['calloc']
+ assert handle.sym_defined?('calloc')
end
def test_handle_close
@@ -179,12 +183,18 @@ module Fiddle
# it calls _nss_cache_cycle_prevention_function with dlsym(3).
# So our Fiddle::Handle#sym must call dlerror(3) before call dlsym.
# In general uses of dlerror(3) should call it before use it.
+ verbose, $VERBOSE = $VERBOSE, nil
require 'socket'
Socket.gethostbyname("localhost")
Fiddle.dlopen("/lib/libc.so.7").sym('strcpy')
+ ensure
+ $VERBOSE = verbose
end if /freebsd/=~ RUBY_PLATFORM
def test_no_memory_leak
+ # https://github.com/ruby/fiddle/actions/runs/3202406059/jobs/5231356410
+ omit if RUBY_VERSION >= '3.2'
+
if respond_to?(:assert_nothing_leaked_memory)
n_tries = 100_000
assert_nothing_leaked_memory(SIZEOF_VOIDP * (n_tries / 100)) do
diff --git a/test/fiddle/test_import.rb b/test/fiddle/test_import.rb
index afa8df9e00..090ace620d 100644
--- a/test/fiddle/test_import.rb
+++ b/test/fiddle/test_import.rb
@@ -22,7 +22,6 @@ module Fiddle
extern "int fprintf(FILE*, char*)" rescue nil
extern "int gettimeofday(timeval*, timezone*)" rescue nil
- BoundQsortCallback = bind("void *bound_qsort_callback(void*, void*)"){|ptr1,ptr2| ptr1[0] <=> ptr2[0]}
Timeval = struct [
"long tv_sec",
"long tv_usec",
@@ -59,11 +58,6 @@ module Fiddle
]
}
]
-
- CallCallback = bind("void call_callback(void*, void*)"){ | ptr1, ptr2|
- f = Function.new(ptr1.to_i, [TYPE_VOIDP], TYPE_VOID)
- f.call(ptr2)
- }
end
class TestImport < TestCase
@@ -130,11 +124,28 @@ module Fiddle
name = $1.sub(/P\z/,"*").gsub(/_(?!T\z)/, " ").downcase
type_name = name
end
+ type_name = "unsigned #{$1}" if type_name =~ /\Au(long|short|char|int|long long)\z/
+
define_method("test_sizeof_#{name}") do
assert_equal(size, Fiddle::Importer.sizeof(type_name), type)
end
end
+ # Assert that the unsigned constants are equal to the "negative" signed ones
+ # for backwards compatibility
+ def test_unsigned_equals_negative_signed
+ Fiddle.constants.grep(/\ATYPE_(?!VOID|VARIADIC\z)(U.*)/) do |unsigned|
+ assert_equal(-Fiddle.const_get(unsigned.to_s.sub(/U/, '')),
+ Fiddle.const_get(unsigned))
+ end
+ end
+
+ def test_type_constants
+ Fiddle::Types.constants.each do |const|
+ assert_equal Fiddle::Types.const_get(const), Fiddle.const_get("TYPE_#{const}")
+ end
+ end
+
def test_unsigned_result()
d = (2 ** 31) + 1
diff --git a/test/fiddle/test_pack.rb b/test/fiddle/test_pack.rb
new file mode 100644
index 0000000000..ade1dd5040
--- /dev/null
+++ b/test/fiddle/test_pack.rb
@@ -0,0 +1,37 @@
+begin
+ require_relative 'helper'
+ require 'fiddle/pack'
+rescue LoadError
+ return
+end
+
+module Fiddle
+ class TestPack < TestCase
+ def test_pack_map
+ if defined?(TYPE_LONG_LONG)
+ assert_equal [0xffff_ffff_ffff_ffff], [0xffff_ffff_ffff_ffff].pack(PackInfo::PACK_MAP[-TYPE_LONG_LONG]).unpack(PackInfo::PACK_MAP[-TYPE_LONG_LONG])
+ end
+
+ case Fiddle::SIZEOF_VOIDP
+ when 8
+ assert_equal [0xffff_ffff_ffff_ffff], [0xffff_ffff_ffff_ffff].pack(PackInfo::PACK_MAP[TYPE_VOIDP]).unpack(PackInfo::PACK_MAP[TYPE_VOIDP])
+ when 4
+ assert_equal [0xffff_ffff], [0xffff_ffff].pack(PackInfo::PACK_MAP[TYPE_VOIDP]).unpack(PackInfo::PACK_MAP[TYPE_VOIDP])
+ end
+
+ case Fiddle::SIZEOF_LONG
+ when 8
+ assert_equal [0xffff_ffff_ffff_ffff], [0xffff_ffff_ffff_ffff].pack(PackInfo::PACK_MAP[-TYPE_LONG]).unpack(PackInfo::PACK_MAP[-TYPE_LONG])
+ when 4
+ assert_equal [0xffff_ffff], [0xffff_ffff].pack(PackInfo::PACK_MAP[-TYPE_LONG]).unpack(PackInfo::PACK_MAP[-TYPE_LONG])
+ end
+
+ if Fiddle::SIZEOF_INT == 4
+ assert_equal [0xffff_ffff], [0xffff_ffff].pack(PackInfo::PACK_MAP[-TYPE_INT]).unpack(PackInfo::PACK_MAP[-TYPE_INT])
+ end
+
+ assert_equal [0xffff], [0xffff].pack(PackInfo::PACK_MAP[-TYPE_SHORT]).unpack(PackInfo::PACK_MAP[-TYPE_SHORT])
+ assert_equal [0xff], [0xff].pack(PackInfo::PACK_MAP[-TYPE_CHAR]).unpack(PackInfo::PACK_MAP[-TYPE_CHAR])
+ end
+ end
+end
diff --git a/test/fiddle/test_pointer.rb b/test/fiddle/test_pointer.rb
index 7d708ee417..f2c1d285ad 100644
--- a/test/fiddle/test_pointer.rb
+++ b/test/fiddle/test_pointer.rb
@@ -10,6 +10,22 @@ module Fiddle
Fiddle.dlwrap arg
end
+ def test_can_read_write_memory
+ # Allocate some memory
+ address = Fiddle.malloc(Fiddle::SIZEOF_VOIDP)
+
+ bytes_to_write = Fiddle::SIZEOF_VOIDP.times.to_a.pack("C*")
+
+ # Write to the memory
+ Fiddle::Pointer.write(address, bytes_to_write)
+
+ # Read the bytes out again
+ bytes = Fiddle::Pointer.read(address, Fiddle::SIZEOF_VOIDP)
+ assert_equal bytes_to_write, bytes
+ ensure
+ Fiddle.free address
+ end
+
def test_cptr_to_int
null = Fiddle::NULL
assert_equal(null.to_i, null.to_int)
@@ -272,6 +288,9 @@ module Fiddle
end
def test_no_memory_leak
+ # https://github.com/ruby/fiddle/actions/runs/3202406059/jobs/5231356410
+ omit if RUBY_VERSION >= '3.2'
+
if respond_to?(:assert_nothing_leaked_memory)
n_tries = 100_000
assert_nothing_leaked_memory(SIZEOF_VOIDP * (n_tries / 100)) do
diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb
index e1e2a829c3..481f913d0c 100644
--- a/test/fileutils/test_fileutils.rb
+++ b/test/fileutils/test_fileutils.rb
@@ -472,10 +472,14 @@ class TestFileUtils < Test::Unit::TestCase
else
def test_cp_r_socket
pend "Skipping socket test on JRuby" if RUBY_ENGINE == 'jruby'
+
Dir.mkdir('tmp/cpr_src')
UNIXServer.new('tmp/cpr_src/socket').close
cp_r 'tmp/cpr_src', 'tmp/cpr_dest'
assert_equal(true, File.socket?('tmp/cpr_dest/socket'))
+ rescue Errno::EINVAL => error
+ # On some platforms (windows) sockets cannot be copied by FileUtils.
+ omit error.message
end if defined?(UNIXServer)
end
@@ -750,6 +754,24 @@ class TestFileUtils < Test::Unit::TestCase
assert_file_not_exist 'tmp/tmpdir3'
end
+ def test_rm_r_no_permissions
+ check_singleton :rm_rf
+
+ return if /mswin|mingw/ =~ RUBY_PLATFORM
+
+ mkdir 'tmpdatadir'
+ touch 'tmpdatadir/tmpdata'
+ chmod "-x", 'tmpdatadir'
+
+ begin
+ assert_raise Errno::EACCES do
+ rm_r 'tmpdatadir'
+ end
+ ensure
+ chmod "+x", 'tmpdatadir'
+ end
+ end
+
def test_remove_entry_cjk_path
dir = "tmpdir\u3042"
my_rm_rf dir
@@ -980,6 +1002,43 @@ class TestFileUtils < Test::Unit::TestCase
}
end if have_symlink?
+ def test_ln_sr
+ check_singleton :ln_sr
+
+ TARGETS.each do |fname|
+ begin
+ lnfname = 'tmp/lnsdest'
+ ln_sr fname, lnfname
+ assert FileTest.symlink?(lnfname), 'not symlink'
+ assert_equal "../#{fname}", File.readlink(lnfname), fname
+ ensure
+ rm_f lnfname
+ end
+ end
+ mkdir 'data/src'
+ File.write('data/src/xxx', 'ok')
+ File.symlink '../data/src', 'tmp/src'
+ ln_sr 'tmp/src/xxx', 'data'
+ assert File.symlink?('data/xxx')
+ assert_equal 'ok', File.read('data/xxx')
+ end if have_symlink?
+
+ def test_ln_sr_broken_symlink
+ assert_nothing_raised {
+ ln_sr 'tmp/symlink', 'tmp/symlink'
+ }
+ end if have_symlink? and !no_broken_symlink?
+
+ def test_ln_sr_pathname
+ # pathname
+ touch 'tmp/lns_dest'
+ assert_nothing_raised {
+ ln_sr Pathname.new('tmp/lns_dest'), 'tmp/symlink_tmp1'
+ ln_sr 'tmp/lns_dest', Pathname.new('tmp/symlink_tmp2')
+ ln_sr Pathname.new('tmp/lns_dest'), Pathname.new('tmp/symlink_tmp3')
+ }
+ end if have_symlink?
+
def test_mkdir
check_singleton :mkdir
@@ -1098,6 +1157,14 @@ class TestFileUtils < Test::Unit::TestCase
ensure
Dir.rmdir(drive) if drive and File.directory?(drive)
end
+
+ def test_mkdir_p_offline_drive
+ offline_drive = ("A".."Z").to_a.reverse.find {|d| !File.exist?("#{d}:/") }
+
+ assert_raise(Errno::ENOENT) {
+ mkdir_p "#{offline_drive}:/new_dir"
+ }
+ end
end
def test_mkdir_p_file_perm
@@ -1170,6 +1237,14 @@ class TestFileUtils < Test::Unit::TestCase
install Pathname.new('tmp/a'), 'tmp/b'
rm_f 'tmp/a'; touch 'tmp/a'
install Pathname.new('tmp/a'), Pathname.new('tmp/b')
+ my_rm_rf 'tmp/new_dir_end_with_slash'
+ install Pathname.new('tmp/a'), 'tmp/new_dir_end_with_slash/'
+ my_rm_rf 'tmp/new_dir_end_with_slash'
+ my_rm_rf 'tmp/new_dir'
+ install Pathname.new('tmp/a'), 'tmp/new_dir/a'
+ my_rm_rf 'tmp/new_dir'
+ install Pathname.new('tmp/a'), 'tmp/new_dir/new_dir_end_with_slash/'
+ my_rm_rf 'tmp/new_dir'
rm_f 'tmp/a'
touch 'tmp/a'
touch 'tmp/b'
@@ -1790,7 +1865,7 @@ cd -
return if /mswin|mingw/ =~ RUBY_PLATFORM
mkdir 'tmpdatadir'
- chmod 0o700, 'tmpdatadir'
+ chmod 0o000, 'tmpdatadir'
rm_rf 'tmpdatadir'
assert_file_not_exist 'tmpdatadir'
diff --git a/test/io/console/test_io_console.rb b/test/io/console/test_io_console.rb
index b5382555f5..0a113ebd2f 100644
--- a/test/io/console/test_io_console.rb
+++ b/test/io/console/test_io_console.rb
@@ -15,6 +15,7 @@ class TestIO_Console < Test::Unit::TestCase
raise
end
PATHS.uniq!
+ INCLUDE_OPTS = "-I#{PATHS.join(File::PATH_SEPARATOR)}"
# FreeBSD seems to hang on TTOU when running parallel tests
# tested on FreeBSD 11.x.
@@ -36,18 +37,27 @@ class TestIO_Console < Test::Unit::TestCase
trap(:TTOU, @old_ttou) if defined?(@old_ttou) and @old_ttou
end
+ exceptions = %w[ENODEV ENOTTY EBADF ENXIO].map {|e|
+ Errno.const_get(e) if Errno.const_defined?(e)
+ }
+ exceptions.compact!
+ FailedPathExceptions = (exceptions unless exceptions.empty?)
+
def test_failed_path
- exceptions = %w[ENODEV ENOTTY EBADF ENXIO].map {|e|
- Errno.const_get(e) if Errno.const_defined?(e)
- }
- exceptions.compact!
- omit if exceptions.empty?
File.open(IO::NULL) do |f|
- e = assert_raise(*exceptions) do
+ e = assert_raise(*FailedPathExceptions) do
f.echo?
end
assert_include(e.message, IO::NULL)
end
+ end if FailedPathExceptions
+
+ def test_bad_keyword
+ assert_raise_with_message(ArgumentError, /unknown keyword:.*bad/) do
+ File.open(IO::NULL) do |f|
+ f.raw(bad: 0)
+ end
+ end
end
end
@@ -232,7 +242,6 @@ defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
end
def test_getpass
- omit unless IO.method_defined?("getpass")
run_pty("p IO.console.getpass('> ')") do |r, w|
assert_equal("> ", r.readpartial(10))
sleep 0.1
@@ -250,6 +259,15 @@ defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
assert_equal("\r\n", r.gets)
assert_equal("\"asdf\"", r.gets.chomp)
end
+
+ run_pty("$VERBOSE, $/ = nil, '.'; p IO.console.getpass('> ')") do |r, w|
+ assert_equal("> ", r.readpartial(10))
+ sleep 0.1
+ w.print "asdf\n"
+ sleep 0.1
+ assert_equal("\r\n", r.gets)
+ assert_equal("\"asdf\"", r.gets.chomp)
+ end
end
def test_iflush
@@ -357,6 +375,15 @@ defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
end
def test_intr
+ # This test fails randomly on FreeBSD 13
+ # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220304T163001Z.fail.html.gz
+ #
+ # 1) Failure:
+ # TestIO_Console#test_intr [/usr/home/chkbuild/chkbuild/tmp/build/20220304T163001Z/ruby/test/io/console/test_io_console.rb:387]:
+ # <"25"> expected but was
+ # <"-e:12:in `p': \e[1mexecution expired (\e[1;4mTimeout::Error\e[m\e[1m)\e[m">.
+ omit if /freebsd/ =~ RUBY_PLATFORM
+
run_pty("#{<<~"begin;"}\n#{<<~'end;'}") do |r, w, _|
begin;
require 'timeout'
@@ -383,19 +410,12 @@ defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
assert_ctrl("#{cc.ord}", cc, r, w)
assert_ctrl("Interrupt", cc, r, w) unless /linux|solaris/ =~ RUBY_PLATFORM
end
- # This test fails randomly on FreeBSD 13
- # http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220304T163001Z.fail.html.gz
- #
- # 1) Failure:
- # TestIO_Console#test_intr [/usr/home/chkbuild/chkbuild/tmp/build/20220304T163001Z/ruby/test/io/console/test_io_console.rb:387]:
- # <"25"> expected but was
- # <"-e:12:in `p': \e[1mexecution expired (\e[1;4mTimeout::Error\e[m\e[1m)\e[m">.
- if (cc = ctrl["dsusp"]) && /freebsd/ !~ RUBY_PLATFORM
+ if cc = ctrl["dsusp"]
assert_ctrl("#{cc.ord}", cc, r, w)
assert_ctrl("#{cc.ord}", cc, r, w)
assert_ctrl("#{cc.ord}", cc, r, w)
end
- if (cc = ctrl["lnext"]) && /freebsd/ !~ RUBY_PLATFORM
+ if cc = ctrl["lnext"]
assert_ctrl("#{cc.ord}", cc, r, w)
assert_ctrl("#{cc.ord}", cc, r, w)
assert_ctrl("#{cc.ord}", cc, r, w)
@@ -438,7 +458,9 @@ defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
def run_pty(src, n = 1)
pend("PTY.spawn cannot control terminal on JRuby") if RUBY_ENGINE == 'jruby'
- r, w, pid = PTY.spawn(EnvUtil.rubybin, "-I#{TestIO_Console::PATHS.join(File::PATH_SEPARATOR)}", "-rio/console", "-e", src)
+ args = [TestIO_Console::INCLUDE_OPTS, "-rio/console", "-e", src]
+ args.shift if args.first == "-I" # statically linked
+ r, w, pid = PTY.spawn(EnvUtil.rubybin, *args)
rescue RuntimeError
omit $!
else
@@ -530,6 +552,7 @@ defined?(IO.console) and TestIO_Console.class_eval do
t2 = Tempfile.new("noctty_run")
t2.close
cmd = [*NOCTTY[1..-1],
+ TestIO_Console::INCLUDE_OPTS,
'-e', 'open(ARGV[0], "w") {|f|',
'-e', 'STDOUT.reopen(f)',
'-e', 'STDERR.reopen(f)',
diff --git a/test/io/wait/test_io_wait.rb b/test/io/wait/test_io_wait.rb
index fb42b6a700..cbc01f9622 100644
--- a/test/io/wait/test_io_wait.rb
+++ b/test/io/wait/test_io_wait.rb
@@ -3,10 +3,9 @@
require 'test/unit'
require 'timeout'
require 'socket'
-begin
- require 'io/wait'
-rescue LoadError
-end
+
+# For `IO#ready?` and `IO#nread`:
+require 'io/wait'
class TestIOWait < Test::Unit::TestCase
@@ -37,6 +36,7 @@ class TestIOWait < Test::Unit::TestCase
end
def test_ready?
+ omit 'unstable on MinGW' if /mingw/ =~ RUBY_PLATFORM
assert_not_predicate @r, :ready?, "shouldn't ready, but ready"
@w.syswrite "."
sleep 0.1
@@ -50,6 +50,7 @@ class TestIOWait < Test::Unit::TestCase
end
def test_wait
+ omit 'unstable on MinGW' if /mingw/ =~ RUBY_PLATFORM
assert_nil @r.wait(0)
@w.syswrite "."
sleep 0.1
diff --git a/test/io/wait/test_io_wait_uncommon.rb b/test/io/wait/test_io_wait_uncommon.rb
index 7b92e4c758..0f922f4e24 100644
--- a/test/io/wait/test_io_wait_uncommon.rb
+++ b/test/io/wait/test_io_wait_uncommon.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
require 'test/unit'
-require 'io/wait'
# test uncommon device types to check portability problems
# We may optimize IO#wait_*able for non-Linux kernels in the future
diff --git a/test/io/wait/test_ractor.rb b/test/io/wait/test_ractor.rb
index 3742680cf7..800216e610 100644
--- a/test/io/wait/test_ractor.rb
+++ b/test/io/wait/test_ractor.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'test/unit'
require 'rbconfig'
-require 'io/wait'
class TestIOWaitInRactor < Test::Unit::TestCase
def test_ractor
diff --git a/test/irb/command/test_force_exit.rb b/test/irb/command/test_force_exit.rb
new file mode 100644
index 0000000000..9e86c644d6
--- /dev/null
+++ b/test/irb/command/test_force_exit.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: false
+require 'irb'
+
+require_relative "../helper"
+
+module TestIRB
+ class ForceExitTest < IntegrationTestCase
+ def test_forced_exit_finishes_process_immediately
+ write_ruby <<~'ruby'
+ puts "First line"
+ puts "Second line"
+ binding.irb
+ puts "Third line"
+ binding.irb
+ puts "Fourth line"
+ ruby
+
+ output = run_ruby_file do
+ type "123"
+ type "456"
+ type "exit!"
+ end
+
+ assert_match(/First line\r\n/, output)
+ assert_match(/Second line\r\n/, output)
+ assert_match(/irb\(main\):001> 123/, output)
+ assert_match(/irb\(main\):002> 456/, output)
+ refute_match(/Third line\r\n/, output)
+ refute_match(/Fourth line\r\n/, output)
+ end
+
+ def test_forced_exit_in_nested_sessions
+ write_ruby <<~'ruby'
+ def foo
+ binding.irb
+ end
+
+ binding.irb
+ binding.irb
+ ruby
+
+ output = run_ruby_file do
+ type "123"
+ type "foo"
+ type "exit!"
+ end
+
+ assert_match(/irb\(main\):001> 123/, output)
+ end
+
+ def test_forced_exit_out_of_irb_session
+ write_ruby <<~'ruby'
+ at_exit { puts 'un' + 'reachable' }
+ binding.irb
+ exit! # this will call exit! method overrided by command
+ ruby
+ output = run_ruby_file do
+ type "exit"
+ end
+ assert_not_include(output, 'unreachable')
+ end
+ end
+end
diff --git a/test/irb/command/test_help.rb b/test/irb/command/test_help.rb
new file mode 100644
index 0000000000..c82c43a4c5
--- /dev/null
+++ b/test/irb/command/test_help.rb
@@ -0,0 +1,66 @@
+require "tempfile"
+require_relative "../helper"
+
+module TestIRB
+ class HelpTest < IntegrationTestCase
+ def setup
+ super
+
+ write_rc <<~'RUBY'
+ IRB.conf[:USE_PAGER] = false
+ RUBY
+
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+ end
+
+ def test_help
+ out = run_ruby_file do
+ type "help"
+ type "exit"
+ end
+
+ assert_match(/List all available commands/, out)
+ assert_match(/Start the debugger of debug\.gem/, out)
+ end
+
+ def test_command_help
+ out = run_ruby_file do
+ type "help ls"
+ type "exit"
+ end
+
+ assert_match(/Usage: ls \[obj\]/, out)
+ end
+
+ def test_command_help_not_found
+ out = run_ruby_file do
+ type "help foo"
+ type "exit"
+ end
+
+ assert_match(/Can't find command `foo`\. Please check the command name and try again\./, out)
+ end
+
+ def test_show_cmds
+ out = run_ruby_file do
+ type "help"
+ type "exit"
+ end
+
+ assert_match(/List all available commands/, out)
+ assert_match(/Start the debugger of debug\.gem/, out)
+ end
+
+ def test_help_lists_user_aliases
+ out = run_ruby_file do
+ type "help"
+ type "exit"
+ end
+
+ assert_match(/\$\s+Alias for `show_source`/, out)
+ assert_match(/@\s+Alias for `whereami`/, out)
+ end
+ end
+end
diff --git a/test/irb/command/test_show_source.rb b/test/irb/command/test_show_source.rb
new file mode 100644
index 0000000000..d014c78fc4
--- /dev/null
+++ b/test/irb/command/test_show_source.rb
@@ -0,0 +1,397 @@
+# frozen_string_literal: false
+require 'irb'
+
+require_relative "../helper"
+
+module TestIRB
+ class ShowSourceTest < IntegrationTestCase
+ def setup
+ super
+
+ write_rc <<~'RUBY'
+ IRB.conf[:USE_PAGER] = false
+ RUBY
+ end
+
+ def test_show_source
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source IRB.conf"
+ type "exit"
+ end
+
+ assert_match(%r[/irb\/init\.rb], out)
+ end
+
+ def test_show_source_alias
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "$ IRB.conf"
+ type "exit"
+ end
+
+ assert_match(%r[/irb\/init\.rb], out)
+ end
+
+ def test_show_source_with_missing_signature
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source foo"
+ type "exit"
+ end
+
+ assert_match(%r[Couldn't locate a definition for foo], out)
+ end
+
+ def test_show_source_with_missing_constant
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source Foo"
+ type "exit"
+ end
+
+ assert_match(%r[Couldn't locate a definition for Foo], out)
+ end
+
+ def test_show_source_string
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source 'IRB.conf'"
+ type "exit"
+ end
+
+ assert_match(%r[/irb\/init\.rb], out)
+ end
+
+ def test_show_source_method_s
+ write_ruby <<~RUBY
+ class Baz
+ def foo
+ end
+ end
+
+ class Bar < Baz
+ def foo
+ super
+ end
+ end
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source Bar#foo -s"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end\r\n], out)
+ end
+
+ def test_show_source_method_s_with_incorrect_signature
+ write_ruby <<~RUBY
+ class Baz
+ def foo
+ end
+ end
+
+ class Bar < Baz
+ def foo
+ super
+ end
+ end
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source Bar#fooo -s"
+ type "exit"
+ end
+
+ assert_match(%r[Error: Couldn't locate a super definition for Bar#fooo], out)
+ end
+
+ def test_show_source_private_method
+ write_ruby <<~RUBY
+ class Bar
+ private def foo
+ end
+ end
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source Bar#foo"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:2\s+private def foo\r\n end\r\n], out)
+ end
+
+ def test_show_source_private_singleton_method
+ write_ruby <<~RUBY
+ class Bar
+ private def foo
+ end
+ end
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "bar = Bar.new"
+ type "show_source bar.foo"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:2\s+private def foo\r\n end\r\n], out)
+ end
+
+ def test_show_source_method_multiple_s
+ write_ruby <<~RUBY
+ class Baz
+ def foo
+ end
+ end
+
+ class Bar < Baz
+ def foo
+ super
+ end
+ end
+
+ class Bob < Bar
+ def foo
+ super
+ end
+ end
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source Bob#foo -ss"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end\r\n], out)
+ end
+
+ def test_show_source_method_no_instance_method
+ write_ruby <<~RUBY
+ class Baz
+ end
+
+ class Bar < Baz
+ def foo
+ super
+ end
+ end
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source Bar#foo -s"
+ type "exit"
+ end
+
+ assert_match(%r[Error: Couldn't locate a super definition for Bar#foo], out)
+ end
+
+ def test_show_source_method_exceeds_super_chain
+ write_ruby <<~RUBY
+ class Baz
+ def foo
+ end
+ end
+
+ class Bar < Baz
+ def foo
+ super
+ end
+ end
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source Bar#foo -ss"
+ type "exit"
+ end
+
+ assert_match(%r[Error: Couldn't locate a super definition for Bar#foo], out)
+ end
+
+ def test_show_source_method_accidental_characters
+ write_ruby <<~'RUBY'
+ class Baz
+ def foo
+ end
+ end
+
+ class Bar < Baz
+ def foo
+ super
+ end
+ end
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source Bar#foo -sddddd"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end], out)
+ end
+
+ def test_show_source_receiver_super
+ write_ruby <<~RUBY
+ class Baz
+ def foo
+ end
+ end
+
+ class Bar < Baz
+ def foo
+ super
+ end
+ end
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "bar = Bar.new"
+ type "show_source bar.foo -s"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:2\s+def foo\r\n end], out)
+ end
+
+ def test_show_source_with_double_colons
+ write_ruby <<~RUBY
+ class Foo
+ end
+
+ class Foo
+ class Bar
+ end
+ end
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source ::Foo"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:1\s+class Foo\r\nend], out)
+
+ out = run_ruby_file do
+ type "show_source ::Foo::Bar"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:5\s+class Bar\r\n end], out)
+ end
+
+ def test_show_source_keep_script_lines
+ pend unless defined?(RubyVM.keep_script_lines)
+
+ write_ruby <<~RUBY
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "def foo; end"
+ type "show_source foo"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}\(irb\):1\s+def foo; end], out)
+ end
+
+ def test_show_source_unavailable_source
+ write_ruby <<~RUBY
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ type "RubyVM.keep_script_lines = false if defined?(RubyVM.keep_script_lines)"
+ type "def foo; end"
+ type "show_source foo"
+ type "exit"
+ end
+ assert_match(%r[#{@ruby_file.to_path}\(irb\):2\s+Source not available], out)
+ end
+
+ def test_show_source_shows_binary_source
+ write_ruby <<~RUBY
+ # io-console is an indirect dependency of irb
+ require "io/console"
+
+ binding.irb
+ RUBY
+
+ out = run_ruby_file do
+ # IO::ConsoleMode is defined in io-console gem's C extension
+ type "show_source IO::ConsoleMode"
+ type "exit"
+ end
+
+ # A safeguard to make sure the test subject is actually defined
+ refute_match(/NameError/, out)
+ assert_match(%r[Defined in binary file:.+io/console], out)
+ end
+
+ def test_show_source_with_constant_lookup
+ write_ruby <<~RUBY
+ X = 1
+ module M
+ Y = 1
+ Z = 2
+ end
+ class A
+ Z = 1
+ Array = 1
+ class B
+ include M
+ Object.new.instance_eval { binding.irb }
+ end
+ end
+ RUBY
+
+ out = run_ruby_file do
+ type "show_source X"
+ type "show_source Y"
+ type "show_source Z"
+ type "show_source Array"
+ type "exit"
+ end
+
+ assert_match(%r[#{@ruby_file.to_path}:1\s+X = 1], out)
+ assert_match(%r[#{@ruby_file.to_path}:3\s+Y = 1], out)
+ assert_match(%r[#{@ruby_file.to_path}:7\s+Z = 1], out)
+ assert_match(%r[#{@ruby_file.to_path}:8\s+Array = 1], out)
+ end
+ end
+end
diff --git a/test/irb/helper.rb b/test/irb/helper.rb
new file mode 100644
index 0000000000..1614b42adb
--- /dev/null
+++ b/test/irb/helper.rb
@@ -0,0 +1,219 @@
+require "test/unit"
+require "pathname"
+require "rubygems"
+
+begin
+ require_relative "../lib/helper"
+ require_relative "../lib/envutil"
+rescue LoadError # ruby/ruby defines helpers differently
+end
+
+begin
+ require "pty"
+rescue LoadError # some platforms don't support PTY
+end
+
+module IRB
+ class InputMethod; end
+end
+
+module TestIRB
+ RUBY_3_4 = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0.dev")
+ class TestCase < Test::Unit::TestCase
+ class TestInputMethod < ::IRB::InputMethod
+ attr_reader :list, :line_no
+
+ def initialize(list = [])
+ @line_no = 0
+ @list = list
+ end
+
+ def gets
+ @list[@line_no]&.tap {@line_no += 1}
+ end
+
+ def eof?
+ @line_no >= @list.size
+ end
+
+ def encoding
+ Encoding.default_external
+ end
+
+ def reset
+ @line_no = 0
+ end
+ end
+
+ def ruby_core?
+ !Pathname(__dir__).join("../../", "irb.gemspec").exist?
+ end
+
+ def save_encodings
+ @default_encoding = [Encoding.default_external, Encoding.default_internal]
+ @stdio_encodings = [STDIN, STDOUT, STDERR].map {|io| [io.external_encoding, io.internal_encoding] }
+ end
+
+ def restore_encodings
+ EnvUtil.suppress_warning do
+ Encoding.default_external, Encoding.default_internal = *@default_encoding
+ [STDIN, STDOUT, STDERR].zip(@stdio_encodings) do |io, encs|
+ io.set_encoding(*encs)
+ end
+ end
+ end
+
+ def without_rdoc(&block)
+ ::Kernel.send(:alias_method, :irb_original_require, :require)
+
+ ::Kernel.define_method(:require) do |name|
+ raise LoadError, "cannot load such file -- rdoc (test)" if name.match?("rdoc") || name.match?(/^rdoc\/.*/)
+ ::Kernel.send(:irb_original_require, name)
+ end
+
+ yield
+ ensure
+ EnvUtil.suppress_warning {
+ ::Kernel.send(:alias_method, :require, :irb_original_require)
+ ::Kernel.undef_method :irb_original_require
+ }
+ end
+ end
+
+ class IntegrationTestCase < TestCase
+ LIB = File.expand_path("../../lib", __dir__)
+ TIMEOUT_SEC = 3
+
+ def setup
+ @envs = {}
+ @tmpfiles = []
+
+ unless defined?(PTY)
+ omit "Integration tests require PTY."
+ end
+
+ if ruby_core?
+ omit "This test works only under ruby/irb"
+ end
+
+ write_rc <<~RUBY
+ IRB.conf[:USE_PAGER] = false
+ RUBY
+ end
+
+ def teardown
+ @tmpfiles.each do |tmpfile|
+ File.unlink(tmpfile)
+ end
+ end
+
+ def run_ruby_file(&block)
+ cmd = [EnvUtil.rubybin, "-I", LIB, @ruby_file.to_path]
+ tmp_dir = Dir.mktmpdir
+
+ @commands = []
+ lines = []
+
+ yield
+
+ # Test should not depend on user's irbrc file
+ @envs["HOME"] ||= tmp_dir
+ @envs["XDG_CONFIG_HOME"] ||= tmp_dir
+ @envs["IRBRC"] = nil unless @envs.key?("IRBRC")
+
+ PTY.spawn(@envs.merge("TERM" => "dumb"), *cmd) do |read, write, pid|
+ Timeout.timeout(TIMEOUT_SEC) do
+ while line = safe_gets(read)
+ lines << line
+
+ # means the breakpoint is triggered
+ if line.match?(/binding\.irb/)
+ while command = @commands.shift
+ write.puts(command)
+ end
+ end
+ end
+ end
+ ensure
+ read.close
+ write.close
+ kill_safely(pid)
+ end
+
+ lines.join
+ rescue Timeout::Error
+ message = <<~MSG
+ Test timedout.
+
+ #{'=' * 30} OUTPUT #{'=' * 30}
+ #{lines.map { |l| " #{l}" }.join}
+ #{'=' * 27} END OF OUTPUT #{'=' * 27}
+ MSG
+ assert_block(message) { false }
+ ensure
+ FileUtils.remove_entry tmp_dir
+ end
+
+ # read.gets could raise exceptions on some platforms
+ # https://github.com/ruby/ruby/blob/master/ext/pty/pty.c#L721-L728
+ def safe_gets(read)
+ read.gets
+ rescue Errno::EIO
+ nil
+ end
+
+ def kill_safely pid
+ return if wait_pid pid, TIMEOUT_SEC
+
+ Process.kill :TERM, pid
+ return if wait_pid pid, 0.2
+
+ Process.kill :KILL, pid
+ Process.waitpid(pid)
+ rescue Errno::EPERM, Errno::ESRCH
+ end
+
+ def wait_pid pid, sec
+ total_sec = 0.0
+ wait_sec = 0.001 # 1ms
+
+ while total_sec < sec
+ if Process.waitpid(pid, Process::WNOHANG) == pid
+ return true
+ end
+ sleep wait_sec
+ total_sec += wait_sec
+ wait_sec *= 2
+ end
+
+ false
+ rescue Errno::ECHILD
+ true
+ end
+
+ def type(command)
+ @commands << command
+ end
+
+ def write_ruby(program)
+ @ruby_file = Tempfile.create(%w{irb- .rb})
+ @tmpfiles << @ruby_file
+ @ruby_file.write(program)
+ @ruby_file.close
+ end
+
+ def write_rc(content)
+ # Append irbrc content if a tempfile for it already exists
+ if @irbrc
+ @irbrc = File.open(@irbrc, "a")
+ else
+ @irbrc = Tempfile.new('irbrc')
+ @tmpfiles << @irbrc
+ end
+
+ @irbrc.write(content)
+ @irbrc.close
+ @envs['IRBRC'] = @irbrc.path
+ end
+ end
+end
diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb
deleted file mode 100644
index 7b7ab55a64..0000000000
--- a/test/irb/test_cmd.rb
+++ /dev/null
@@ -1,558 +0,0 @@
-# frozen_string_literal: false
-require "test/unit"
-require "irb"
-require "irb/extend-command"
-
-module TestIRB
- class ExtendCommand < Test::Unit::TestCase
- class TestInputMethod < ::IRB::InputMethod
- attr_reader :list, :line_no
-
- def initialize(list = [])
- super("test")
- @line_no = 0
- @list = list
- end
-
- def gets
- @list[@line_no]&.tap {@line_no += 1}
- end
-
- def eof?
- @line_no >= @list.size
- end
-
- def encoding
- Encoding.default_external
- end
-
- def reset
- @line_no = 0
- end
- end
-
- def setup
- @pwd = Dir.pwd
- @tmpdir = File.join(Dir.tmpdir, "test_reline_config_#{$$}")
- begin
- Dir.mkdir(@tmpdir)
- rescue Errno::EEXIST
- FileUtils.rm_rf(@tmpdir)
- Dir.mkdir(@tmpdir)
- end
- Dir.chdir(@tmpdir)
- @home_backup = ENV["HOME"]
- ENV["HOME"] = @tmpdir
- @xdg_config_home_backup = ENV.delete("XDG_CONFIG_HOME")
- @default_encoding = [Encoding.default_external, Encoding.default_internal]
- @stdio_encodings = [STDIN, STDOUT, STDERR].map {|io| [io.external_encoding, io.internal_encoding] }
- IRB.instance_variable_get(:@CONF).clear
- @is_win = (RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/)
- end
-
- def teardown
- ENV["XDG_CONFIG_HOME"] = @xdg_config_home_backup
- ENV["HOME"] = @home_backup
- Dir.chdir(@pwd)
- FileUtils.rm_rf(@tmpdir)
- EnvUtil.suppress_warning {
- Encoding.default_external, Encoding.default_internal = *@default_encoding
- [STDIN, STDOUT, STDERR].zip(@stdio_encodings) do |io, encs|
- io.set_encoding(*encs)
- end
- }
- end
-
- def test_irb_info_multiline
- FileUtils.touch("#{@tmpdir}/.inputrc")
- FileUtils.touch("#{@tmpdir}/.irbrc")
- IRB.setup(__FILE__, argv: [])
- IRB.conf[:USE_MULTILINE] = true
- IRB.conf[:USE_SINGLELINE] = false
- IRB.conf[:VERBOSE] = false
- lang_backup = ENV.delete("LANG")
- lc_all_backup = ENV.delete("LC_ALL")
- workspace = IRB::WorkSpace.new(self)
- irb = IRB::Irb.new(workspace, TestInputMethod.new([]))
- IRB.conf[:MAIN_CONTEXT] = irb.context
- expected = %r{
- Ruby\sversion:\s.+\n
- IRB\sversion:\sirb\s.+\n
- InputMethod:\sAbstract\sInputMethod\n
- \.irbrc\spath:\s.+\n
- RUBY_PLATFORM:\s.+\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- #{@is_win ? 'Code\spage:\s\d+\n' : ''}
- }x
- assert_match expected, irb.context.main.irb_info.to_s
- ensure
- ENV["LANG"] = lang_backup
- ENV["LC_ALL"] = lc_all_backup
- end
-
- def test_irb_info_singleline
- FileUtils.touch("#{@tmpdir}/.inputrc")
- FileUtils.touch("#{@tmpdir}/.irbrc")
- IRB.setup(__FILE__, argv: [])
- IRB.conf[:USE_MULTILINE] = false
- IRB.conf[:USE_SINGLELINE] = true
- IRB.conf[:VERBOSE] = false
- lang_backup = ENV.delete("LANG")
- lc_all_backup = ENV.delete("LC_ALL")
- workspace = IRB::WorkSpace.new(self)
- irb = IRB::Irb.new(workspace, TestInputMethod.new([]))
- IRB.conf[:MAIN_CONTEXT] = irb.context
- expected = %r{
- Ruby\sversion:\s.+\n
- IRB\sversion:\sirb\s.+\n
- InputMethod:\sAbstract\sInputMethod\n
- \.irbrc\spath:\s.+\n
- RUBY_PLATFORM:\s.+\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- #{@is_win ? 'Code\spage:\s\d+\n' : ''}
- }x
- assert_match expected, irb.context.main.irb_info.to_s
- ensure
- ENV["LANG"] = lang_backup
- ENV["LC_ALL"] = lc_all_backup
- end
-
- def test_irb_info_multiline_without_rc_files
- inputrc_backup = ENV["INPUTRC"]
- ENV["INPUTRC"] = "unknown_inpurc"
- ext_backup = IRB::IRBRC_EXT
- IRB.__send__(:remove_const, :IRBRC_EXT)
- IRB.const_set(:IRBRC_EXT, "unknown_ext")
- IRB.setup(__FILE__, argv: [])
- IRB.conf[:USE_MULTILINE] = true
- IRB.conf[:USE_SINGLELINE] = false
- IRB.conf[:VERBOSE] = false
- lang_backup = ENV.delete("LANG")
- lc_all_backup = ENV.delete("LC_ALL")
- workspace = IRB::WorkSpace.new(self)
- irb = IRB::Irb.new(workspace, TestInputMethod.new([]))
- IRB.conf[:MAIN_CONTEXT] = irb.context
- expected = %r{
- Ruby\sversion:\s.+\n
- IRB\sversion:\sirb\s.+\n
- InputMethod:\sAbstract\sInputMethod\n
- RUBY_PLATFORM:\s.+\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- #{@is_win ? 'Code\spage:\s\d+\n' : ''}
- \z
- }x
- assert_match expected, irb.context.main.irb_info.to_s
- ensure
- ENV["INPUTRC"] = inputrc_backup
- IRB.__send__(:remove_const, :IRBRC_EXT)
- IRB.const_set(:IRBRC_EXT, ext_backup)
- ENV["LANG"] = lang_backup
- ENV["LC_ALL"] = lc_all_backup
- end
-
- def test_irb_info_singleline_without_rc_files
- inputrc_backup = ENV["INPUTRC"]
- ENV["INPUTRC"] = "unknown_inpurc"
- ext_backup = IRB::IRBRC_EXT
- IRB.__send__(:remove_const, :IRBRC_EXT)
- IRB.const_set(:IRBRC_EXT, "unknown_ext")
- IRB.setup(__FILE__, argv: [])
- IRB.conf[:USE_MULTILINE] = false
- IRB.conf[:USE_SINGLELINE] = true
- IRB.conf[:VERBOSE] = false
- lang_backup = ENV.delete("LANG")
- lc_all_backup = ENV.delete("LC_ALL")
- workspace = IRB::WorkSpace.new(self)
- irb = IRB::Irb.new(workspace, TestInputMethod.new([]))
- IRB.conf[:MAIN_CONTEXT] = irb.context
- expected = %r{
- Ruby\sversion:\s.+\n
- IRB\sversion:\sirb\s.+\n
- InputMethod:\sAbstract\sInputMethod\n
- RUBY_PLATFORM:\s.+\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- #{@is_win ? 'Code\spage:\s\d+\n' : ''}
- \z
- }x
- assert_match expected, irb.context.main.irb_info.to_s
- ensure
- ENV["INPUTRC"] = inputrc_backup
- IRB.__send__(:remove_const, :IRBRC_EXT)
- IRB.const_set(:IRBRC_EXT, ext_backup)
- ENV["LANG"] = lang_backup
- ENV["LC_ALL"] = lc_all_backup
- end
-
- def test_irb_info_lang
- FileUtils.touch("#{@tmpdir}/.inputrc")
- FileUtils.touch("#{@tmpdir}/.irbrc")
- IRB.setup(__FILE__, argv: [])
- IRB.conf[:USE_MULTILINE] = true
- IRB.conf[:USE_SINGLELINE] = false
- IRB.conf[:VERBOSE] = false
- lang_backup = ENV.delete("LANG")
- lc_all_backup = ENV.delete("LC_ALL")
- ENV["LANG"] = "ja_JP.UTF-8"
- ENV["LC_ALL"] = "en_US.UTF-8"
- workspace = IRB::WorkSpace.new(self)
- irb = IRB::Irb.new(workspace, TestInputMethod.new([]))
- IRB.conf[:MAIN_CONTEXT] = irb.context
- expected = %r{
- Ruby\sversion: .+\n
- IRB\sversion:\sirb .+\n
- InputMethod:\sAbstract\sInputMethod\n
- \.irbrc\spath: .+\n
- RUBY_PLATFORM: .+\n
- LANG\senv:\sja_JP\.UTF-8\n
- LC_ALL\senv:\sen_US\.UTF-8\n
- East\sAsian\sAmbiguous\sWidth:\s\d\n
- }x
- assert_match expected, irb.context.main.irb_info.to_s
- ensure
- ENV["LANG"] = lang_backup
- ENV["LC_ALL"] = lc_all_backup
- end
-
- def test_measure
- IRB.init_config(nil)
- IRB.conf[:PROMPT] = {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> ',
- PROMPT_N: '> '
- }
- }
- IRB.conf[:VERBOSE] = false
- IRB.conf[:PROMPT_MODE] = :DEFAULT
- IRB.conf[:MEASURE] = false
- input = TestInputMethod.new([
- "3\n",
- "measure\n",
- "3\n",
- "measure :off\n",
- "3\n",
- ])
- c = Class.new(Object)
- irb = IRB::Irb.new(IRB::WorkSpace.new(c.new), input)
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/\A=> 3\nTIME is added\.\n=> nil\nprocessing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
- assert_empty(c.class_variables)
- end
-
- def test_measure_enabled_by_rc
- IRB.init_config(nil)
- IRB.conf[:PROMPT] = {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> ',
- PROMPT_N: '> '
- }
- }
- IRB.conf[:VERBOSE] = false
- IRB.conf[:PROMPT_MODE] = :DEFAULT
- IRB.conf[:MEASURE] = true
- input = TestInputMethod.new([
- "3\n",
- "measure :off\n",
- "3\n",
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/\Aprocessing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
- end
-
- def test_measure_enabled_by_rc_with_custom
- IRB.init_config(nil)
- IRB.conf[:PROMPT] = {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> ',
- PROMPT_N: '> '
- }
- }
- IRB.conf[:VERBOSE] = false
- IRB.conf[:PROMPT_MODE] = :DEFAULT
- IRB.conf[:MEASURE] = true
- IRB.conf[:MEASURE_PROC][:CUSTOM] = proc { |line, line_no, &block|
- time = Time.now
- result = block.()
- puts 'custom processing time: %fs' % (Time.now - time) if IRB.conf[:MEASURE]
- result
- }
- input = TestInputMethod.new([
- "3\n",
- "measure :off\n",
- "3\n",
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/\Acustom processing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
- end
-
- def test_measure_with_custom
- IRB.init_config(nil)
- IRB.conf[:PROMPT] = {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> ',
- PROMPT_N: '> '
- }
- }
- IRB.conf[:VERBOSE] = false
- IRB.conf[:PROMPT_MODE] = :DEFAULT
- IRB.conf[:MEASURE] = false
- IRB.conf[:MEASURE_PROC][:CUSTOM] = proc { |line, line_no, &block|
- time = Time.now
- result = block.()
- puts 'custom processing time: %fs' % (Time.now - time) if IRB.conf[:MEASURE]
- result
- }
- input = TestInputMethod.new([
- "3\n",
- "measure\n",
- "3\n",
- "measure :off\n",
- "3\n",
- ])
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/\A=> 3\nCUSTOM is added\.\n=> nil\ncustom processing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
- end
-
- def test_measure_with_proc
- IRB.init_config(nil)
- IRB.conf[:PROMPT] = {
- DEFAULT: {
- PROMPT_I: '> ',
- PROMPT_S: '> ',
- PROMPT_C: '> ',
- PROMPT_N: '> '
- }
- }
- IRB.conf[:VERBOSE] = false
- IRB.conf[:PROMPT_MODE] = :DEFAULT
- IRB.conf[:MEASURE] = false
- input = TestInputMethod.new([
- "3\n",
- "measure { |context, code, line_no, &block|\n",
- " result = block.()\n",
- " puts 'aaa' if IRB.conf[:MEASURE]\n",
- " result\n",
- "}\n",
- "3\n",
- "measure { |context, code, line_no, &block|\n",
- " result = block.()\n",
- " puts 'bbb' if IRB.conf[:MEASURE]\n",
- " result\n",
- "}\n",
- "3\n",
- "measure :off\n",
- "3\n",
- ])
- c = Class.new(Object)
- irb = IRB::Irb.new(IRB::WorkSpace.new(c.new), input)
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/\A=> 3\nBLOCK is added\.\n=> nil\naaa\n=> 3\nBLOCK is added.\naaa\n=> nil\nbbb\n=> 3\n=> nil\n=> 3\n/, out)
- assert_empty(c.class_variables)
- end
-
- def test_irb_source
- IRB.init_config(nil)
- File.write("#{@tmpdir}/a.rb", "a = 'hi'\n")
- input = TestInputMethod.new([
- "a = 'bug17564'\n",
- "a\n",
- "irb_source '#{@tmpdir}/a.rb'\n",
- "a\n",
- ])
- IRB.conf[:VERBOSE] = false
- IRB.conf[:PROMPT_MODE] = :SIMPLE
- irb = IRB::Irb.new(IRB::WorkSpace.new(self), input)
- IRB.conf[:MAIN_CONTEXT] = irb.context
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_pattern_list([
- /=> "bug17564"\n/,
- /=> "bug17564"\n/,
- / => "hi"\n/,
- / => nil\n/,
- /=> "hi"\n/,
- ], out)
- end
-
- def test_irb_load
- IRB.init_config(nil)
- File.write("#{@tmpdir}/a.rb", "a = 'hi'\n")
- input = TestInputMethod.new([
- "a = 'bug17564'\n",
- "a\n",
- "irb_load '#{@tmpdir}/a.rb'\n",
- "a\n",
- ])
- IRB.conf[:VERBOSE] = false
- IRB.conf[:PROMPT_MODE] = :SIMPLE
- irb = IRB::Irb.new(IRB::WorkSpace.new(self), input)
- IRB.conf[:MAIN_CONTEXT] = irb.context
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_pattern_list([
- /=> "bug17564"\n/,
- /=> "bug17564"\n/,
- / => "hi"\n/,
- / => nil\n/,
- /=> "bug17564"\n/,
- ], out)
- end
-
- def test_ls
- input = TestInputMethod.new([
- "class P\n",
- " def m() end\n",
- " def m2() end\n",
- "end\n",
-
- "class C < P\n",
- " def m1() end\n",
- " def m2() end\n",
- "end\n",
-
- "module M\n",
- " def m1() end\n",
- " def m3() end\n",
- "end\n",
-
- "module M2\n",
- " include M\n",
- " def m4() end\n",
- "end\n",
-
- "obj = C.new\n",
- "obj.instance_variable_set(:@a, 1)\n",
- "obj.extend M2\n",
- "def obj.m5() end\n",
- "ls obj\n",
- ])
- IRB.init_config(nil)
- workspace = IRB::WorkSpace.new(self)
- IRB.conf[:VERBOSE] = false
- irb = IRB::Irb.new(workspace, input)
- IRB.conf[:MAIN_CONTEXT] = irb.context
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/^instance variables:\s+@a\n/m, out)
- assert_match(/P#methods:\s+m\n/m, out)
- assert_match(/C#methods:\s+m2\n/m, out)
- assert_match(/M#methods:\s+m1\s+m3\n/m, out)
- assert_match(/M2#methods:\s+m4\n/m, out)
- assert_match(/C.methods:\s+m5\n/m, out)
- end
-
- def test_ls_with_no_singleton_class
- input = TestInputMethod.new([
- "ls 42",
- ])
- IRB.init_config(nil)
- workspace = IRB::WorkSpace.new(self)
- IRB.conf[:VERBOSE] = false
- irb = IRB::Irb.new(workspace, input)
- IRB.conf[:MAIN_CONTEXT] = irb.context
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/Comparable#methods:\s+/, out)
- assert_match(/Numeric#methods:\s+/, out)
- assert_match(/Integer#methods:\s+/, out)
- end
-
- def test_show_source
- input = TestInputMethod.new([
- "show_source 'IRB.conf'\n",
- ])
- IRB.init_config(nil)
- workspace = IRB::WorkSpace.new(self)
- IRB.conf[:VERBOSE] = false
- irb = IRB::Irb.new(workspace, input)
- IRB.conf[:MAIN_CONTEXT] = irb.context
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(%r[/irb\.rb], out)
- end
-
- def test_show_source_end_finder
- pend if RUBY_ENGINE == 'truffleruby'
- eval(code = <<-EOS, binding, __FILE__, __LINE__ + 1)
- def show_source_test_method
- unless true
- end
- end
- EOS
- input = TestInputMethod.new([
- "show_source 'TestIRB::ExtendCommand#show_source_test_method'\n",
- ])
- IRB.init_config(nil)
- workspace = IRB::WorkSpace.new(self)
- IRB.conf[:VERBOSE] = false
- irb = IRB::Irb.new(workspace, input)
- IRB.conf[:MAIN_CONTEXT] = irb.context
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_include(out, code)
- end
-
- def test_whereami
- input = TestInputMethod.new([
- "whereami\n",
- ])
- IRB.init_config(nil)
- workspace = IRB::WorkSpace.new(self)
- IRB.conf[:VERBOSE] = false
- irb = IRB::Irb.new(workspace, input)
- IRB.conf[:MAIN_CONTEXT] = irb.context
- irb.context.return_format = "=> %s\n"
- out, err = capture_output do
- irb.eval_input
- end
- assert_empty err
- assert_match(/^From: .+ @ line \d+ :\n/, out)
- end
- end
-end
diff --git a/test/irb/test_color.rb b/test/irb/test_color.rb
index 6ad64a0ae2..72e036eab7 100644
--- a/test/irb/test_color.rb
+++ b/test/irb/test_color.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: false
-require 'test/unit'
require 'irb/color'
-require 'rubygems'
require 'stringio'
+require_relative "helper"
+
module TestIRB
- class TestColor < Test::Unit::TestCase
+ class ColorTest < TestCase
CLEAR = "\e[0m"
BOLD = "\e[1m"
UNDERLINE = "\e[4m"
@@ -17,6 +17,20 @@ module TestIRB
MAGENTA = "\e[35m"
CYAN = "\e[36m"
+ def setup
+ super
+ if IRB.respond_to?(:conf)
+ @colorize, IRB.conf[:USE_COLORIZE] = IRB.conf[:USE_COLORIZE], true
+ end
+ end
+
+ def teardown
+ if instance_variable_defined?(:@colorize)
+ IRB.conf[:USE_COLORIZE] = @colorize
+ end
+ super
+ end
+
def test_colorize
text = "text"
{
@@ -75,6 +89,7 @@ module TestIRB
":class" => "#{YELLOW}:#{CLEAR}#{YELLOW}class#{CLEAR}",
"[:end, 2]" => "[#{YELLOW}:#{CLEAR}#{YELLOW}end#{CLEAR}, #{BLUE}#{BOLD}2#{CLEAR}]",
"[:>, 3]" => "[#{YELLOW}:#{CLEAR}#{YELLOW}>#{CLEAR}, #{BLUE}#{BOLD}3#{CLEAR}]",
+ "[:`, 4]" => "[#{YELLOW}:#{CLEAR}#{YELLOW}`#{CLEAR}, #{BLUE}#{BOLD}4#{CLEAR}]",
":Hello ? world : nil" => "#{YELLOW}:#{CLEAR}#{YELLOW}Hello#{CLEAR} ? world : #{CYAN}#{BOLD}nil#{CLEAR}",
'raise "foo#{bar}baz"' => "raise #{RED}#{BOLD}\"#{CLEAR}#{RED}foo#{CLEAR}#{RED}\#{#{CLEAR}bar#{RED}}#{CLEAR}#{RED}baz#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}",
'["#{obj.inspect}"]' => "[#{RED}#{BOLD}\"#{CLEAR}#{RED}\#{#{CLEAR}obj.inspect#{RED}}#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}]",
@@ -88,16 +103,16 @@ module TestIRB
"foo(*%W(bar))" => "foo(*#{RED}#{BOLD}%W(#{CLEAR}#{RED}bar#{CLEAR}#{RED}#{BOLD})#{CLEAR})",
"$stdout" => "#{GREEN}#{BOLD}$stdout#{CLEAR}",
"__END__" => "#{GREEN}__END__#{CLEAR}",
+ "foo\n__END__\nbar" => "foo\n#{GREEN}__END__#{CLEAR}\nbar",
+ "foo\n<<A\0\0bar\nA\nbaz" => "foo\n#{RED}<<A#{CLEAR}^@^@bar\n#{RED}A#{CLEAR}\nbaz",
+ "<<A+1\nA" => "#{RED}<<A#{CLEAR}+#{BLUE}#{BOLD}1#{CLEAR}\n#{RED}A#{CLEAR}",
}
- # specific to Ruby 2.7+
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
- tests.merge!({
- "4.5.6" => "#{MAGENTA}#{BOLD}4.5#{CLEAR}#{RED}#{REVERSE}.6#{CLEAR}",
- "\e[0m\n" => "#{RED}#{REVERSE}^[#{CLEAR}[#{BLUE}#{BOLD}0#{CLEAR}#{RED}#{REVERSE}m#{CLEAR}\n",
- "<<EOS\nhere\nEOS" => "#{RED}<<EOS#{CLEAR}\n#{RED}here#{CLEAR}\n#{RED}EOS#{CLEAR}",
- })
- end
+ tests.merge!({
+ "4.5.6" => "#{MAGENTA}#{BOLD}4.5#{CLEAR}#{RED}#{REVERSE}.6#{CLEAR}",
+ "\e[0m\n" => "#{RED}#{REVERSE}^[#{CLEAR}[#{BLUE}#{BOLD}0#{CLEAR}#{RED}#{REVERSE}m#{CLEAR}\n",
+ "<<EOS\nhere\nEOS" => "#{RED}<<EOS#{CLEAR}\n#{RED}here#{CLEAR}\n#{RED}EOS#{CLEAR}",
+ })
# specific to Ruby 3.0+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
@@ -111,12 +126,15 @@ module TestIRB
"class bad; end" => "#{GREEN}class#{CLEAR} #{RED}#{REVERSE}bad#{CLEAR}; #{GREEN}end#{CLEAR}",
"def req(@a) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}@a#{CLEAR}) #{GREEN}end#{CLEAR}",
})
- else
- tests.merge!({
- "[1]]]\u0013" => "[1]]]^S",
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2.0')
+ tests.merge!({
+ "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}true#{CLEAR}#{RED}#{REVERSE})#{CLEAR} #{RED}#{REVERSE}end#{CLEAR}",
})
+ end
+ else
tests.merge!({
- "def req(true) end" => "def req(true) end",
+ "[1]]]\u0013" => "[#{BLUE}#{BOLD}1#{CLEAR}]#{RED}#{REVERSE}]#{CLEAR}]^S",
+ "def req(true) end" => "#{GREEN}def#{CLEAR} #{BLUE}#{BOLD}req#{CLEAR}(#{RED}#{REVERSE}true#{CLEAR}) end",
"nil = 1" => "#{CYAN}#{BOLD}nil#{CLEAR} = #{BLUE}#{BOLD}1#{CLEAR}",
"alias $x $1" => "#{GREEN}alias#{CLEAR} #{GREEN}#{BOLD}$x#{CLEAR} $1",
"class bad; end" => "#{GREEN}class#{CLEAR} bad; #{GREEN}end#{CLEAR}",
@@ -125,31 +143,34 @@ module TestIRB
end
tests.each do |code, result|
- if colorize_code_supported?
- assert_equal_with_term(result, code, complete: true)
- assert_equal_with_term(result, code, complete: false)
+ assert_equal_with_term(result, code, complete: true)
+ assert_equal_with_term(result, code, complete: false)
- assert_equal_with_term(code, code, complete: true, tty: false)
- assert_equal_with_term(code, code, complete: false, tty: false)
+ assert_equal_with_term(code, code, complete: true, tty: false)
+ assert_equal_with_term(code, code, complete: false, tty: false)
- assert_equal_with_term(code, code, complete: true, colorable: false)
+ assert_equal_with_term(code, code, complete: true, colorable: false)
- assert_equal_with_term(code, code, complete: false, colorable: false)
+ assert_equal_with_term(code, code, complete: false, colorable: false)
- assert_equal_with_term(result, code, complete: true, tty: false, colorable: true)
+ assert_equal_with_term(result, code, complete: true, tty: false, colorable: true)
- assert_equal_with_term(result, code, complete: false, tty: false, colorable: true)
- else
- assert_equal_with_term(code, code)
- end
+ assert_equal_with_term(result, code, complete: false, tty: false, colorable: true)
end
end
- def test_colorize_code_complete_true
- unless complete_option_supported?
- pend '`complete: true` is the same as `complete: false` in Ruby 2.6-'
- end
+ def test_colorize_code_with_local_variables
+ code = "a /(b +1)/i"
+ result_without_lvars = "a #{RED}#{BOLD}/#{CLEAR}#{RED}(b +1)#{CLEAR}#{RED}#{BOLD}/i#{CLEAR}"
+ result_with_lvar = "a /(b #{BLUE}#{BOLD}+1#{CLEAR})/i"
+ result_with_lvars = "a /(b +#{BLUE}#{BOLD}1#{CLEAR})/i"
+ assert_equal_with_term(result_without_lvars, code)
+ assert_equal_with_term(result_with_lvar, code, local_variables: ['a'])
+ assert_equal_with_term(result_with_lvars, code, local_variables: ['a', 'b'])
+ end
+
+ def test_colorize_code_complete_true
# `complete: true` behaviors. Warn end-of-file.
{
"'foo' + 'bar" => "#{RED}#{BOLD}'#{CLEAR}#{RED}foo#{CLEAR}#{RED}#{BOLD}'#{CLEAR} + #{RED}#{BOLD}'#{CLEAR}#{RED}#{REVERSE}bar#{CLEAR}",
@@ -171,27 +192,13 @@ module TestIRB
"'foo' + 'bar" => "#{RED}#{BOLD}'#{CLEAR}#{RED}foo#{CLEAR}#{RED}#{BOLD}'#{CLEAR} + #{RED}#{BOLD}'#{CLEAR}#{RED}bar#{CLEAR}",
"('foo" => "(#{RED}#{BOLD}'#{CLEAR}#{RED}foo#{CLEAR}",
}.each do |code, result|
- if colorize_code_supported?
- assert_equal_with_term(result, code, complete: false)
-
- assert_equal_with_term(code, code, complete: false, tty: false)
-
- assert_equal_with_term(code, code, complete: false, colorable: false)
+ assert_equal_with_term(result, code, complete: false)
- assert_equal_with_term(result, code, complete: false, tty: false, colorable: true)
+ assert_equal_with_term(code, code, complete: false, tty: false)
- unless complete_option_supported?
- assert_equal_with_term(result, code, complete: true)
+ assert_equal_with_term(code, code, complete: false, colorable: false)
- assert_equal_with_term(code, code, complete: true, tty: false)
-
- assert_equal_with_term(code, code, complete: true, colorable: false)
-
- assert_equal_with_term(result, code, complete: true, tty: false, colorable: true)
- end
- else
- assert_equal_with_term(code, code)
- end
+ assert_equal_with_term(result, code, complete: false, tty: false, colorable: true)
end
end
@@ -217,16 +224,6 @@ module TestIRB
private
- # `#colorize_code` is supported only for Ruby 2.5+. It just returns the original code in 2.4-.
- def colorize_code_supported?
- Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
- end
-
- # `complete: true` is the same as `complete: false` in Ruby 2.6-
- def complete_option_supported?
- Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
- end
-
def with_term(tty: true)
stdout = $stdout
io = StringIO.new
diff --git a/test/irb/test_color_printer.rb b/test/irb/test_color_printer.rb
index 93ec700146..c2c624d868 100644
--- a/test/irb/test_color_printer.rb
+++ b/test/irb/test_color_printer.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: false
-require 'test/unit'
require 'irb/color_printer'
-require 'rubygems'
require 'stringio'
+require_relative "helper"
+
module TestIRB
- class TestColorPrinter < Test::Unit::TestCase
+ class ColorPrinterTest < TestCase
CLEAR = "\e[0m"
BOLD = "\e[1m"
RED = "\e[31m"
@@ -14,6 +14,10 @@ module TestIRB
CYAN = "\e[36m"
def setup
+ super
+ if IRB.respond_to?(:conf)
+ @colorize, IRB.conf[:USE_COLORIZE] = IRB.conf[:USE_COLORIZE], true
+ end
@get_screen_size = Reline.method(:get_screen_size)
Reline.instance_eval { undef :get_screen_size }
def Reline.get_screen_size
@@ -24,18 +28,19 @@ module TestIRB
def teardown
Reline.instance_eval { undef :get_screen_size }
Reline.define_singleton_method(:get_screen_size, @get_screen_size)
+ if instance_variable_defined?(:@colorize)
+ IRB.conf[:USE_COLORIZE] = @colorize
+ end
+ super
end
IRBTestColorPrinter = Struct.new(:a)
def test_color_printer
- unless ripper_lexer_scan_supported?
- pend 'Ripper::Lexer#scan is supported in Ruby 2.7+'
- end
{
1 => "#{BLUE}#{BOLD}1#{CLEAR}\n",
"a\nb" => %[#{RED}#{BOLD}"#{CLEAR}#{RED}a\\nb#{CLEAR}#{RED}#{BOLD}"#{CLEAR}\n],
- IRBTestColorPrinter.new('test') => "#{GREEN}#<struct TestIRB::TestColorPrinter::IRBTestColorPrinter#{CLEAR} a#{GREEN}=#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{RED}test#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{GREEN}>#{CLEAR}\n",
+ IRBTestColorPrinter.new('test') => "#{GREEN}#<struct TestIRB::ColorPrinterTest::IRBTestColorPrinter#{CLEAR} a#{GREEN}=#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{RED}test#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{GREEN}>#{CLEAR}\n",
Ripper::Lexer.new('1').scan => "[#{GREEN}#<Ripper::Lexer::Elem:#{CLEAR} on_int@1:0 END token: #{RED}#{BOLD}\"#{CLEAR}#{RED}1#{CLEAR}#{RED}#{BOLD}\"#{CLEAR}#{GREEN}>#{CLEAR}]\n",
Class.new{define_method(:pretty_print){|q| q.text("[__FILE__, __LINE__, __ENCODING__]")}}.new => "[#{CYAN}#{BOLD}__FILE__#{CLEAR}, #{CYAN}#{BOLD}__LINE__#{CLEAR}, #{CYAN}#{BOLD}__ENCODING__#{CLEAR}]\n",
}.each do |object, result|
@@ -46,10 +51,6 @@ module TestIRB
private
- def ripper_lexer_scan_supported?
- Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
- end
-
def with_term
stdout = $stdout
io = StringIO.new
diff --git a/test/irb/test_command.rb b/test/irb/test_command.rb
new file mode 100644
index 0000000000..03fdd37855
--- /dev/null
+++ b/test/irb/test_command.rb
@@ -0,0 +1,1043 @@
+# frozen_string_literal: false
+require "irb"
+
+require_relative "helper"
+
+module TestIRB
+ class CommandTestCase < TestCase
+ def setup
+ @pwd = Dir.pwd
+ @tmpdir = File.join(Dir.tmpdir, "test_reline_config_#{$$}")
+ begin
+ Dir.mkdir(@tmpdir)
+ rescue Errno::EEXIST
+ FileUtils.rm_rf(@tmpdir)
+ Dir.mkdir(@tmpdir)
+ end
+ Dir.chdir(@tmpdir)
+ @home_backup = ENV["HOME"]
+ ENV["HOME"] = @tmpdir
+ @xdg_config_home_backup = ENV.delete("XDG_CONFIG_HOME")
+ save_encodings
+ IRB.instance_variable_get(:@CONF).clear
+ IRB.instance_variable_set(:@existing_rc_name_generators, nil)
+ @is_win = (RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/)
+ end
+
+ def teardown
+ ENV["XDG_CONFIG_HOME"] = @xdg_config_home_backup
+ ENV["HOME"] = @home_backup
+ Dir.chdir(@pwd)
+ FileUtils.rm_rf(@tmpdir)
+ restore_encodings
+ end
+
+ def execute_lines(*lines, conf: {}, main: self, irb_path: nil)
+ capture_output do
+ IRB.init_config(nil)
+ IRB.conf[:VERBOSE] = false
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
+ IRB.conf[:USE_PAGER] = false
+ IRB.conf.merge!(conf)
+ input = TestInputMethod.new(lines)
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), input)
+ irb.context.return_format = "=> %s\n"
+ irb.context.irb_path = irb_path if irb_path
+ IRB.conf[:MAIN_CONTEXT] = irb.context
+ irb.eval_input
+ end
+ end
+ end
+
+ class FrozenObjectTest < CommandTestCase
+ def test_calling_command_on_a_frozen_main
+ main = Object.new.freeze
+
+ out, err = execute_lines(
+ "irb_info",
+ main: main
+ )
+ assert_empty(err)
+ assert_match(/RUBY_PLATFORM/, out)
+ end
+ end
+
+ class InfoTest < CommandTestCase
+ def setup
+ super
+ @locals_backup = ENV.delete("LANG"), ENV.delete("LC_ALL")
+ end
+
+ def teardown
+ super
+ ENV["LANG"], ENV["LC_ALL"] = @locals_backup
+ end
+
+ def test_irb_info_multiline
+ FileUtils.touch("#{@tmpdir}/.inputrc")
+ FileUtils.touch("#{@tmpdir}/.irbrc")
+ FileUtils.touch("#{@tmpdir}/_irbrc")
+
+ out, err = execute_lines(
+ "irb_info",
+ conf: { USE_MULTILINE: true, USE_SINGLELINE: false }
+ )
+
+ expected = %r{
+ Ruby\sversion:\s.+\n
+ IRB\sversion:\sirb\s.+\n
+ InputMethod:\sAbstract\sInputMethod\n
+ Completion: .+\n
+ \.irbrc\spaths:.*\.irbrc.*_irbrc\n
+ RUBY_PLATFORM:\s.+\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
+ #{@is_win ? 'Code\spage:\s\d+\n' : ''}
+ }x
+
+ assert_empty err
+ assert_match expected, out
+ end
+
+ def test_irb_info_singleline
+ FileUtils.touch("#{@tmpdir}/.inputrc")
+ FileUtils.touch("#{@tmpdir}/.irbrc")
+
+ out, err = execute_lines(
+ "irb_info",
+ conf: { USE_MULTILINE: false, USE_SINGLELINE: true }
+ )
+
+ expected = %r{
+ Ruby\sversion:\s.+\n
+ IRB\sversion:\sirb\s.+\n
+ InputMethod:\sAbstract\sInputMethod\n
+ Completion: .+\n
+ \.irbrc\spaths:\s.+\n
+ RUBY_PLATFORM:\s.+\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
+ #{@is_win ? 'Code\spage:\s\d+\n' : ''}
+ }x
+
+ assert_empty err
+ assert_match expected, out
+ end
+
+ def test_irb_info_multiline_without_rc_files
+ inputrc_backup = ENV["INPUTRC"]
+ ENV["INPUTRC"] = "unknown_inpurc"
+ ext_backup = IRB::IRBRC_EXT
+ IRB.__send__(:remove_const, :IRBRC_EXT)
+ IRB.const_set(:IRBRC_EXT, "unknown_ext")
+
+ out, err = execute_lines(
+ "irb_info",
+ conf: { USE_MULTILINE: true, USE_SINGLELINE: false }
+ )
+
+ expected = %r{
+ Ruby\sversion:\s.+\n
+ IRB\sversion:\sirb\s.+\n
+ InputMethod:\sAbstract\sInputMethod\n
+ Completion: .+\n
+ RUBY_PLATFORM:\s.+\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
+ #{@is_win ? 'Code\spage:\s\d+\n' : ''}
+ }x
+
+ assert_empty err
+ assert_match expected, out
+ ensure
+ ENV["INPUTRC"] = inputrc_backup
+ IRB.__send__(:remove_const, :IRBRC_EXT)
+ IRB.const_set(:IRBRC_EXT, ext_backup)
+ end
+
+ def test_irb_info_singleline_without_rc_files
+ inputrc_backup = ENV["INPUTRC"]
+ ENV["INPUTRC"] = "unknown_inpurc"
+ ext_backup = IRB::IRBRC_EXT
+ IRB.__send__(:remove_const, :IRBRC_EXT)
+ IRB.const_set(:IRBRC_EXT, "unknown_ext")
+
+ out, err = execute_lines(
+ "irb_info",
+ conf: { USE_MULTILINE: false, USE_SINGLELINE: true }
+ )
+
+ expected = %r{
+ Ruby\sversion:\s.+\n
+ IRB\sversion:\sirb\s.+\n
+ InputMethod:\sAbstract\sInputMethod\n
+ Completion: .+\n
+ RUBY_PLATFORM:\s.+\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
+ #{@is_win ? 'Code\spage:\s\d+\n' : ''}
+ }x
+
+ assert_empty err
+ assert_match expected, out
+ ensure
+ ENV["INPUTRC"] = inputrc_backup
+ IRB.__send__(:remove_const, :IRBRC_EXT)
+ IRB.const_set(:IRBRC_EXT, ext_backup)
+ end
+
+ def test_irb_info_lang
+ FileUtils.touch("#{@tmpdir}/.inputrc")
+ FileUtils.touch("#{@tmpdir}/.irbrc")
+ ENV["LANG"] = "ja_JP.UTF-8"
+ ENV["LC_ALL"] = "en_US.UTF-8"
+
+ out, err = execute_lines(
+ "irb_info",
+ conf: { USE_MULTILINE: true, USE_SINGLELINE: false }
+ )
+
+ expected = %r{
+ Ruby\sversion: .+\n
+ IRB\sversion:\sirb .+\n
+ InputMethod:\sAbstract\sInputMethod\n
+ Completion: .+\n
+ \.irbrc\spaths: .+\n
+ RUBY_PLATFORM: .+\n
+ LANG\senv:\sja_JP\.UTF-8\n
+ LC_ALL\senv:\sen_US\.UTF-8\n
+ East\sAsian\sAmbiguous\sWidth:\s\d\n
+ }x
+
+ assert_empty err
+ assert_match expected, out
+ end
+ end
+
+ class CustomCommandTestCase < CommandTestCase
+ def setup
+ @commands_backup = IRB::Command.commands
+ IRB::ExtendCommandBundle.class_variable_set(:@@command_override_policies, nil)
+ end
+
+ def teardown
+ IRB::ExtendCommandBundle.class_variable_set(:@@command_override_policies, nil)
+ IRB::Command.instance_variable_set(:@commands, @commands_backup)
+ end
+ end
+
+ class CommandArgTest < CustomCommandTestCase
+ class PrintArgCommand < IRB::Command::Base
+ category 'CommandTest'
+ description 'print_command_arg'
+ def execute(arg)
+ puts "arg=#{arg.inspect}"
+ end
+ end
+
+ def test_arg
+ IRB::Command._register_with_aliases(:print_arg, PrintArgCommand, [:pa, IRB::ExtendCommandBundle::OVERRIDE_ALL])
+ out, err = execute_lines("print_arg\n")
+ assert_empty err
+ assert_include(out, 'arg=""')
+
+ out, err = execute_lines("print_arg \n")
+ assert_empty err
+ assert_include(out, 'arg=""')
+
+ out, err = execute_lines("print_arg a r g\n")
+ assert_empty err
+ assert_include(out, 'arg="a r g"')
+
+ out, err = execute_lines("print_arg a r g \n")
+ assert_empty err
+ assert_include(out, 'arg="a r g"')
+
+ out, err = execute_lines("pa a r g \n")
+ assert_empty err
+ assert_include(out, 'arg="a r g"')
+ end
+ end
+
+ class ExtendCommandBundleCompatibilityTest < CustomCommandTestCase
+ class FooBarCommand < IRB::Command::Base
+ category 'FooBarCategory'
+ description 'foobar_description'
+ def execute(_arg)
+ puts "FooBar executed"
+ end
+ end
+
+ def test_def_extend_command
+ IRB::Command._register_with_aliases(:foobar, FooBarCommand, [:fbalias, IRB::ExtendCommandBundle::OVERRIDE_ALL])
+ out, err = execute_lines("foobar\n")
+ assert_empty err
+ assert_include(out, "FooBar executed")
+
+ out, err = execute_lines("fbalias\n")
+ assert_empty err
+ assert_include(out, "FooBar executed")
+
+ out, err = execute_lines("show_cmds\n")
+ assert_include(out, "FooBarCategory")
+ assert_include(out, "foobar_description")
+ end
+ end
+
+ class MeasureTest < CommandTestCase
+ def test_measure
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: false
+ }
+
+ c = Class.new(Object)
+ out, err = execute_lines(
+ "measure\n",
+ "3\n",
+ "measure :off\n",
+ "3\n",
+ "measure :on\n",
+ "3\n",
+ "measure :off\n",
+ "3\n",
+ conf: conf,
+ main: c
+ )
+
+ assert_empty err
+ assert_match(/\A(TIME is added\.\n=> nil\nprocessing time: .+\n=> 3\n=> nil\n=> 3\n){2}/, out)
+ assert_empty(c.class_variables)
+ end
+
+ def test_measure_keeps_previous_value
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: false
+ }
+
+ c = Class.new(Object)
+ out, err = execute_lines(
+ "measure\n",
+ "3\n",
+ "_\n",
+ conf: conf,
+ main: c
+ )
+
+ assert_empty err
+ assert_match(/\ATIME is added\.\n=> nil\nprocessing time: .+\n=> 3\nprocessing time: .+\n=> 3/, out)
+ assert_empty(c.class_variables)
+ end
+
+ def test_measure_enabled_by_rc
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: true
+ }
+
+ out, err = execute_lines(
+ "3\n",
+ "measure :off\n",
+ "3\n",
+ conf: conf,
+ )
+
+ assert_empty err
+ assert_match(/\Aprocessing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
+ end
+
+ def test_measure_enabled_by_rc_with_custom
+ measuring_proc = proc { |line, line_no, &block|
+ time = Time.now
+ result = block.()
+ puts 'custom processing time: %fs' % (Time.now - time) if IRB.conf[:MEASURE]
+ result
+ }
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: true,
+ MEASURE_PROC: { CUSTOM: measuring_proc }
+ }
+
+ out, err = execute_lines(
+ "3\n",
+ "measure :off\n",
+ "3\n",
+ conf: conf,
+ )
+ assert_empty err
+ assert_match(/\Acustom processing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
+ end
+
+ def test_measure_with_custom
+ measuring_proc = proc { |line, line_no, &block|
+ time = Time.now
+ result = block.()
+ puts 'custom processing time: %fs' % (Time.now - time) if IRB.conf[:MEASURE]
+ result
+ }
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: false,
+ MEASURE_PROC: { CUSTOM: measuring_proc }
+ }
+ out, err = execute_lines(
+ "3\n",
+ "measure\n",
+ "3\n",
+ "measure :off\n",
+ "3\n",
+ conf: conf
+ )
+
+ assert_empty err
+ assert_match(/\A=> 3\nCUSTOM is added\.\n=> nil\ncustom processing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
+ end
+
+ def test_measure_toggle
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: false,
+ MEASURE_PROC: {
+ FOO: proc { |&block| puts 'foo'; block.call },
+ BAR: proc { |&block| puts 'bar'; block.call }
+ }
+ }
+ out, err = execute_lines(
+ "measure :foo\n",
+ "1\n",
+ "measure :on, :bar\n",
+ "2\n",
+ "measure :off, :foo\n",
+ "3\n",
+ "measure :off, :bar\n",
+ "4\n",
+ conf: conf
+ )
+
+ assert_empty err
+ assert_match(/\AFOO is added\.\n=> nil\nfoo\n=> 1\nBAR is added\.\n=> nil\nbar\nfoo\n=> 2\n=> nil\nbar\n=> 3\n=> nil\n=> 4\n/, out)
+ end
+
+ def test_measure_with_proc_warning
+ conf = {
+ PROMPT: {
+ DEFAULT: {
+ PROMPT_I: '> ',
+ PROMPT_S: '> ',
+ PROMPT_C: '> '
+ }
+ },
+ PROMPT_MODE: :DEFAULT,
+ MEASURE: false,
+ }
+ c = Class.new(Object)
+ out, err = execute_lines(
+ "3\n",
+ "measure do\n",
+ "3\n",
+ conf: conf,
+ main: c
+ )
+
+ assert_match(/to add custom measure/, err)
+ assert_match(/\A=> 3\n=> nil\n=> 3\n/, out)
+ assert_empty(c.class_variables)
+ end
+ end
+
+ class IrbSourceTest < CommandTestCase
+ def test_irb_source
+ File.write("#{@tmpdir}/a.rb", "a = 'hi'\n")
+ out, err = execute_lines(
+ "a = 'bug17564'\n",
+ "a\n",
+ "irb_source '#{@tmpdir}/a.rb'\n",
+ "a\n",
+ )
+ assert_empty err
+ assert_pattern_list([
+ /=> "bug17564"\n/,
+ /=> "bug17564"\n/,
+ / => "hi"\n/,
+ / => nil\n/,
+ /=> "hi"\n/,
+ ], out)
+ end
+
+ def test_irb_source_without_argument
+ out, err = execute_lines(
+ "irb_source\n",
+ )
+ assert_empty err
+ assert_match(/Please specify the file name./, out)
+ end
+ end
+
+ class IrbLoadTest < CommandTestCase
+ def test_irb_load
+ File.write("#{@tmpdir}/a.rb", "a = 'hi'\n")
+ out, err = execute_lines(
+ "a = 'bug17564'\n",
+ "a\n",
+ "irb_load '#{@tmpdir}/a.rb'\n",
+ "a\n",
+ )
+ assert_empty err
+ assert_pattern_list([
+ /=> "bug17564"\n/,
+ /=> "bug17564"\n/,
+ / => "hi"\n/,
+ / => nil\n/,
+ /=> "bug17564"\n/,
+ ], out)
+ end
+
+ def test_irb_load_without_argument
+ out, err = execute_lines(
+ "irb_load\n",
+ )
+
+ assert_empty err
+ assert_match(/Please specify the file name./, out)
+ end
+ end
+
+ class WorkspaceCommandTestCase < CommandTestCase
+ def setup
+ super
+ # create Foo under the test class's namespace so it doesn't pollute global namespace
+ self.class.class_eval <<~RUBY
+ class Foo; end
+ RUBY
+ end
+ end
+
+ class CwwsTest < WorkspaceCommandTestCase
+ def test_cwws_returns_the_current_workspace_object
+ out, err = execute_lines(
+ "cwws",
+ "self.class"
+ )
+
+ assert_empty err
+ assert_include(out, self.class.name)
+ end
+ end
+
+ class PushwsTest < WorkspaceCommandTestCase
+ def test_pushws_switches_to_new_workspace_and_pushes_the_current_one_to_the_stack
+ out, err = execute_lines(
+ "pushws #{self.class}::Foo.new",
+ "self.class",
+ "popws",
+ "self.class"
+ )
+ assert_empty err
+
+ assert_match(/=> #{self.class}::Foo\n/, out)
+ assert_match(/=> #{self.class}\n$/, out)
+ end
+
+ def test_pushws_extends_the_new_workspace_with_command_bundle
+ out, err = execute_lines(
+ "pushws Object.new",
+ "self.singleton_class.ancestors"
+ )
+ assert_empty err
+ assert_include(out, "IRB::ExtendCommandBundle")
+ end
+
+ def test_pushws_prints_workspace_stack_when_no_arg_is_given
+ out, err = execute_lines(
+ "pushws",
+ )
+ assert_empty err
+ assert_include(out, "[#<TestIRB::PushwsTe...>]")
+ end
+
+ def test_pushws_without_argument_swaps_the_top_two_workspaces
+ out, err = execute_lines(
+ "pushws #{self.class}::Foo.new",
+ "self.class",
+ "pushws",
+ "self.class"
+ )
+ assert_empty err
+ assert_match(/=> #{self.class}::Foo\n/, out)
+ assert_match(/=> #{self.class}\n$/, out)
+ end
+ end
+
+ class WorkspacesTest < WorkspaceCommandTestCase
+ def test_workspaces_returns_the_stack_of_workspaces
+ out, err = execute_lines(
+ "pushws #{self.class}::Foo.new\n",
+ "workspaces",
+ )
+
+ assert_empty err
+ assert_match(/\[#<TestIRB::Workspac...>, #<TestIRB::Workspac...>\]\n/, out)
+ end
+ end
+
+ class PopwsTest < WorkspaceCommandTestCase
+ def test_popws_replaces_the_current_workspace_with_the_previous_one
+ out, err = execute_lines(
+ "pushws Foo.new\n",
+ "popws\n",
+ "cwws\n",
+ "_.class",
+ )
+ assert_empty err
+ assert_include(out, "=> #{self.class}")
+ end
+
+ def test_popws_prints_help_message_if_the_workspace_is_empty
+ out, err = execute_lines(
+ "popws\n",
+ )
+ assert_empty err
+ assert_match(/\[#<TestIRB::PopwsTes...>\]\n/, out)
+ end
+ end
+
+ class ChwsTest < WorkspaceCommandTestCase
+ def test_chws_replaces_the_current_workspace
+ out, err = execute_lines(
+ "chws #{self.class}::Foo.new\n",
+ "cwws\n",
+ "_.class",
+ )
+ assert_empty err
+ assert_include(out, "=> #{self.class}::Foo")
+ end
+
+ def test_chws_does_nothing_when_receiving_no_argument
+ out, err = execute_lines(
+ "chws\n",
+ "cwws\n",
+ "_.class",
+ )
+ assert_empty err
+ assert_include(out, "=> #{self.class}")
+ end
+ end
+
+ class WhereamiTest < CommandTestCase
+ def test_whereami
+ out, err = execute_lines(
+ "whereami\n",
+ )
+ assert_empty err
+ assert_match(/^From: .+ @ line \d+ :\n/, out)
+ end
+
+ def test_whereami_alias
+ out, err = execute_lines(
+ "@\n",
+ )
+ assert_empty err
+ assert_match(/^From: .+ @ line \d+ :\n/, out)
+ end
+ end
+
+ class LsTest < CommandTestCase
+ def test_ls
+ out, err = execute_lines(
+ "class P\n",
+ " def m() end\n",
+ " def m2() end\n",
+ "end\n",
+
+ "class C < P\n",
+ " def m1() end\n",
+ " def m2() end\n",
+ "end\n",
+
+ "module M\n",
+ " def m1() end\n",
+ " def m3() end\n",
+ "end\n",
+
+ "module M2\n",
+ " include M\n",
+ " def m4() end\n",
+ "end\n",
+
+ "obj = C.new\n",
+ "obj.instance_variable_set(:@a, 1)\n",
+ "obj.extend M2\n",
+ "def obj.m5() end\n",
+ "ls obj\n",
+ )
+
+ assert_empty err
+ assert_match(/^instance variables:\s+@a\n/m, out)
+ assert_match(/P#methods:\s+m\n/m, out)
+ assert_match(/C#methods:\s+m2\n/m, out)
+ assert_match(/M#methods:\s+m1\s+m3\n/m, out)
+ assert_match(/M2#methods:\s+m4\n/m, out)
+ assert_match(/C.methods:\s+m5\n/m, out)
+ end
+
+ def test_ls_class
+ out, err = execute_lines(
+ "module M1\n",
+ " def m2; end\n",
+ " def m3; end\n",
+ "end\n",
+
+ "class C1\n",
+ " def m1; end\n",
+ " def m2; end\n",
+ "end\n",
+
+ "class C2 < C1\n",
+ " include M1\n",
+ " def m3; end\n",
+ " def m4; end\n",
+ " def self.m3; end\n",
+ " def self.m5; end\n",
+ "end\n",
+ "ls C2"
+ )
+
+ assert_empty err
+ assert_match(/C2.methods:\s+m3\s+m5\n/, out)
+ assert_match(/C2#methods:\s+m3\s+m4\n.*M1#methods:\s+m2\n.*C1#methods:\s+m1\n/, out)
+ assert_not_match(/Module#methods/, out)
+ assert_not_match(/Class#methods/, out)
+ end
+
+ def test_ls_module
+ out, err = execute_lines(
+ "module M1\n",
+ " def m1; end\n",
+ " def m2; end\n",
+ "end\n",
+
+ "module M2\n",
+ " include M1\n",
+ " def m1; end\n",
+ " def m3; end\n",
+ " def self.m4; end\n",
+ "end\n",
+ "ls M2"
+ )
+
+ assert_empty err
+ assert_match(/M2\.methods:\s+m4\n/, out)
+ assert_match(/M2#methods:\s+m1\s+m3\n.*M1#methods:\s+m2\n/, out)
+ assert_not_match(/Module#methods/, out)
+ end
+
+ def test_ls_instance
+ out, err = execute_lines(
+ "class Foo; def bar; end; end\n",
+ "ls Foo.new"
+ )
+
+ assert_empty err
+ assert_match(/Foo#methods:\s+bar/, out)
+ # don't duplicate
+ assert_not_match(/Foo#methods:\s+bar\n.*Foo#methods/, out)
+ end
+
+ def test_ls_grep
+ out, err = execute_lines("ls 42\n")
+ assert_empty err
+ assert_match(/times/, out)
+ assert_match(/polar/, out)
+
+ [
+ "ls 42, grep: /times/\n",
+ "ls 42 -g times\n",
+ "ls 42 -G times\n",
+ ].each do |line|
+ out, err = execute_lines(line)
+ assert_empty err
+ assert_match(/times/, out)
+ assert_not_match(/polar/, out)
+ end
+ end
+
+ def test_ls_grep_empty
+ out, err = execute_lines("ls\n")
+ assert_empty err
+ assert_match(/assert/, out)
+ assert_match(/refute/, out)
+
+ [
+ "ls grep: /assert/\n",
+ "ls -g assert\n",
+ "ls -G assert\n",
+ ].each do |line|
+ out, err = execute_lines(line)
+ assert_empty err
+ assert_match(/assert/, out)
+ assert_not_match(/refute/, out)
+ end
+ end
+
+ def test_ls_with_no_singleton_class
+ out, err = execute_lines(
+ "ls 42",
+ )
+ assert_empty err
+ assert_match(/Comparable#methods:\s+/, out)
+ assert_match(/Numeric#methods:\s+/, out)
+ assert_match(/Integer#methods:\s+/, out)
+ end
+ end
+
+ class ShowDocTest < CommandTestCase
+ def test_show_doc
+ out, err = execute_lines(
+ "show_doc String#gsub\n",
+ "\n",
+ )
+
+ # the former is what we'd get without document content installed, like on CI
+ # the latter is what we may get locally
+ possible_rdoc_output = [/Nothing known about String#gsub/, /gsub\(pattern\)/]
+ assert_not_include err, "[Deprecation]"
+ assert(possible_rdoc_output.any? { |output| output.match?(out) }, "Expect the `show_doc` command to match one of the possible outputs. Got:\n#{out}")
+ ensure
+ # this is the only way to reset the redefined method without coupling the test with its implementation
+ EnvUtil.suppress_warning { load "irb/command/help.rb" }
+ end
+
+ def test_show_doc_without_rdoc
+ out, err = without_rdoc do
+ execute_lines(
+ "show_doc String#gsub\n",
+ "\n",
+ )
+ end
+
+ # if it fails to require rdoc, it only returns the command object
+ assert_match(/=> nil\n/, out)
+ assert_include(err, "Can't display document because `rdoc` is not installed.\n")
+ ensure
+ # this is the only way to reset the redefined method without coupling the test with its implementation
+ EnvUtil.suppress_warning { load "irb/command/help.rb" }
+ end
+ end
+
+ class EditTest < CommandTestCase
+ def setup
+ @original_visual = ENV["VISUAL"]
+ @original_editor = ENV["EDITOR"]
+ # noop the command so nothing gets executed
+ ENV["VISUAL"] = ": code"
+ ENV["EDITOR"] = ": code2"
+ end
+
+ def teardown
+ ENV["VISUAL"] = @original_visual
+ ENV["EDITOR"] = @original_editor
+ end
+
+ def test_edit_without_arg
+ out, err = execute_lines(
+ "edit",
+ irb_path: __FILE__
+ )
+
+ assert_empty err
+ assert_match("path: #{__FILE__}", out)
+ assert_match("command: ': code'", out)
+ end
+
+ def test_edit_without_arg_and_non_existing_irb_path
+ out, err = execute_lines(
+ "edit",
+ irb_path: '/path/to/file.rb(irb)'
+ )
+
+ assert_empty err
+ assert_match(/Can not find file: \/path\/to\/file\.rb\(irb\)/, out)
+ end
+
+ def test_edit_with_path
+ out, err = execute_lines(
+ "edit #{__FILE__}"
+ )
+
+ assert_empty err
+ assert_match("path: #{__FILE__}", out)
+ assert_match("command: ': code'", out)
+ end
+
+ def test_edit_with_non_existing_path
+ out, err = execute_lines(
+ "edit test_cmd_non_existing_path.rb"
+ )
+
+ assert_empty err
+ assert_match(/Can not find file: test_cmd_non_existing_path\.rb/, out)
+ end
+
+ def test_edit_with_constant
+ out, err = execute_lines(
+ "edit IRB::Irb"
+ )
+
+ assert_empty err
+ assert_match(/path: .*\/lib\/irb\.rb/, out)
+ assert_match("command: ': code'", out)
+ end
+
+ def test_edit_with_class_method
+ out, err = execute_lines(
+ "edit IRB.start"
+ )
+
+ assert_empty err
+ assert_match(/path: .*\/lib\/irb\.rb/, out)
+ assert_match("command: ': code'", out)
+ end
+
+ def test_edit_with_instance_method
+ out, err = execute_lines(
+ "edit IRB::Irb#run"
+ )
+
+ assert_empty err
+ assert_match(/path: .*\/lib\/irb\.rb/, out)
+ assert_match("command: ': code'", out)
+ end
+
+ def test_edit_with_editor_env_var
+ ENV.delete("VISUAL")
+
+ out, err = execute_lines(
+ "edit",
+ irb_path: __FILE__
+ )
+
+ assert_empty err
+ assert_match("path: #{__FILE__}", out)
+ assert_match("command: ': code2'", out)
+ end
+ end
+
+ class HistoryCmdTest < CommandTestCase
+ def teardown
+ TestInputMethod.send(:remove_const, "HISTORY") if defined?(TestInputMethod::HISTORY)
+ super
+ end
+
+ def test_history
+ TestInputMethod.const_set("HISTORY", %w[foo bar baz])
+
+ out, err = without_rdoc do
+ execute_lines("history")
+ end
+
+ assert_include(out, <<~EOF)
+ 2: baz
+ 1: bar
+ 0: foo
+ EOF
+ assert_empty err
+ end
+
+ def test_multiline_history_with_truncation
+ TestInputMethod.const_set("HISTORY", ["foo", "bar", <<~INPUT])
+ [].each do |x|
+ puts x
+ end
+ INPUT
+
+ out, err = without_rdoc do
+ execute_lines("hist")
+ end
+
+ assert_include(out, <<~EOF)
+ 2: [].each do |x|
+ puts x
+ ...
+ 1: bar
+ 0: foo
+ EOF
+ assert_empty err
+ end
+
+ def test_history_grep
+ TestInputMethod.const_set("HISTORY", ["foo", "bar", <<~INPUT])
+ [].each do |x|
+ puts x
+ end
+ INPUT
+
+ out, err = without_rdoc do
+ execute_lines("hist -g each\n")
+ end
+
+ assert_include(out, <<~EOF)
+ 2: [].each do |x|
+ puts x
+ ...
+ EOF
+ assert_empty err
+ end
+
+ end
+
+ class HelperMethodInsallTest < CommandTestCase
+ def test_helper_method_install
+ IRB::ExtendCommandBundle.module_eval do
+ def foobar
+ "test_helper_method_foobar"
+ end
+ end
+
+ out, err = execute_lines("foobar.upcase")
+ assert_empty err
+ assert_include(out, '=> "TEST_HELPER_METHOD_FOOBAR"')
+ ensure
+ IRB::ExtendCommandBundle.remove_method :foobar
+ end
+ end
+end
diff --git a/test/irb/test_completion.rb b/test/irb/test_completion.rb
index 3aa99d74d3..5fe7952b3d 100644
--- a/test/irb/test_completion.rb
+++ b/test/irb/test_completion.rb
@@ -1,122 +1,311 @@
# frozen_string_literal: false
-require "test/unit"
+require "pathname"
require "irb"
+require_relative "helper"
+
module TestIRB
- class TestCompletion < Test::Unit::TestCase
- def test_nonstring_module_name
- begin
- require "irb/completion"
- bug5938 = '[ruby-core:42244]'
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- cmds = bundle_exec + %W[-W0 -rirb -rirb/completion -e IRB.setup(__FILE__)
- -e IRB.conf[:MAIN_CONTEXT]=IRB::Irb.new.context
- -e module\sFoo;def\sself.name;//;end;end
- -e IRB::InputCompletor::CompletionProc.call("[1].first.")
- -- -f --]
- status = assert_in_out_err(cmds, "", //, [], bug5938)
- assert(status.success?, bug5938)
- rescue LoadError
- pend "cannot load irb/completion"
+ class CompletionTest < TestCase
+ def completion_candidates(target, bind)
+ IRB::RegexpCompletor.new.completion_candidates('', target, '', bind: bind)
+ end
+
+ def doc_namespace(target, bind)
+ IRB::RegexpCompletor.new.doc_namespace('', target, '', bind: bind)
+ end
+
+ class CommandCompletionTest < CompletionTest
+ def test_command_completion
+ assert_include(IRB::RegexpCompletor.new.completion_candidates('', 'show_s', '', bind: binding), 'show_source')
+ assert_not_include(IRB::RegexpCompletor.new.completion_candidates(';', 'show_s', '', bind: binding), 'show_source')
end
end
- def test_complete_numeric
- assert_include(IRB::InputCompletor.retrieve_completion_data("1r.positi", bind: binding), "1r.positive?")
- assert_empty(IRB::InputCompletor.retrieve_completion_data("1i.positi", bind: binding))
+ class MethodCompletionTest < CompletionTest
+ def test_complete_string
+ assert_include(completion_candidates("'foo'.up", binding), "'foo'.upcase")
+ # completing 'foo bar'.up
+ assert_include(completion_candidates("bar'.up", binding), "bar'.upcase")
+ assert_equal("String.upcase", doc_namespace("'foo'.upcase", binding))
+ end
+
+ def test_complete_regexp
+ assert_include(completion_candidates("/foo/.ma", binding), "/foo/.match")
+ # completing /foo bar/.ma
+ assert_include(completion_candidates("bar/.ma", binding), "bar/.match")
+ assert_equal("Regexp.match", doc_namespace("/foo/.match", binding))
+ end
+
+ def test_complete_array
+ assert_include(completion_candidates("[].an", binding), "[].any?")
+ assert_equal("Array.any?", doc_namespace("[].any?", binding))
+ end
+
+ def test_complete_hash_and_proc
+ # hash
+ assert_include(completion_candidates("{}.an", binding), "{}.any?")
+ assert_equal(["Hash.any?", "Proc.any?"], doc_namespace("{}.any?", binding))
+
+ # proc
+ assert_include(completion_candidates("{}.bin", binding), "{}.binding")
+ assert_equal(["Hash.binding", "Proc.binding"], doc_namespace("{}.binding", binding))
+ end
+
+ def test_complete_numeric
+ assert_include(completion_candidates("1.positi", binding), "1.positive?")
+ assert_equal("Integer.positive?", doc_namespace("1.positive?", binding))
+
+ assert_include(completion_candidates("1r.positi", binding), "1r.positive?")
+ assert_equal("Rational.positive?", doc_namespace("1r.positive?", binding))
+
+ assert_include(completion_candidates("0xFFFF.positi", binding), "0xFFFF.positive?")
+ assert_equal("Integer.positive?", doc_namespace("0xFFFF.positive?", binding))
+
+ assert_empty(completion_candidates("1i.positi", binding))
+ end
+
+ def test_complete_symbol
+ assert_include(completion_candidates(":foo.to_p", binding), ":foo.to_proc")
+ assert_equal("Symbol.to_proc", doc_namespace(":foo.to_proc", binding))
+ end
+
+ def test_complete_class
+ assert_include(completion_candidates("String.ne", binding), "String.new")
+ assert_equal("String.new", doc_namespace("String.new", binding))
+ end
+ end
+
+ class RequireComepletionTest < CompletionTest
+ def test_complete_require
+ candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'irb", "", bind: binding)
+ %w['irb/init 'irb/ruby-lex].each do |word|
+ assert_include candidates, word
+ end
+ # Test cache
+ candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'irb", "", bind: binding)
+ %w['irb/init 'irb/ruby-lex].each do |word|
+ assert_include candidates, word
+ end
+ # Test string completion not disturbed by require completion
+ candidates = IRB::RegexpCompletor.new.completion_candidates("'string ", "'.", "", bind: binding)
+ assert_include candidates, "'.upcase"
+ end
+
+ def test_complete_require_with_pathname_in_load_path
+ temp_dir = Dir.mktmpdir
+ File.write(File.join(temp_dir, "foo.rb"), "test")
+ test_path = Pathname.new(temp_dir)
+ $LOAD_PATH << test_path
+
+ candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
+ assert_include candidates, "'foo"
+ ensure
+ $LOAD_PATH.pop if test_path
+ FileUtils.remove_entry(temp_dir) if temp_dir
+ end
+
+ def test_complete_require_with_string_convertable_in_load_path
+ temp_dir = Dir.mktmpdir
+ File.write(File.join(temp_dir, "foo.rb"), "test")
+ object = Object.new
+ object.define_singleton_method(:to_s) { temp_dir }
+ $LOAD_PATH << object
+
+ candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
+ assert_include candidates, "'foo"
+ ensure
+ $LOAD_PATH.pop if object
+ FileUtils.remove_entry(temp_dir) if temp_dir
+ end
+
+ def test_complete_require_with_malformed_object_in_load_path
+ object = Object.new
+ def object.to_s; raise; end
+ $LOAD_PATH << object
+
+ assert_nothing_raised do
+ IRB::RegexpCompletor.new.completion_candidates("require ", "'foo", "", bind: binding)
+ end
+ ensure
+ $LOAD_PATH.pop if object
+ end
+
+ def test_complete_require_library_name_first
+ # Test that library name is completed first with subdirectories
+ candidates = IRB::RegexpCompletor.new.completion_candidates("require ", "'irb", "", bind: binding)
+ assert_equal "'irb", candidates.first
+ end
+
+ def test_complete_require_relative
+ candidates = Dir.chdir(__dir__ + "/../..") do
+ IRB::RegexpCompletor.new.completion_candidates("require_relative ", "'lib/irb", "", bind: binding)
+ end
+ %w['lib/irb/init 'lib/irb/ruby-lex].each do |word|
+ assert_include candidates, word
+ end
+ # Test cache
+ candidates = Dir.chdir(__dir__ + "/../..") do
+ IRB::RegexpCompletor.new.completion_candidates("require_relative ", "'lib/irb", "", bind: binding)
+ end
+ %w['lib/irb/init 'lib/irb/ruby-lex].each do |word|
+ assert_include candidates, word
+ end
+ end
+ end
+
+ class VariableCompletionTest < CompletionTest
+ def test_complete_variable
+ # Bug fix issues https://github.com/ruby/irb/issues/368
+ # Variables other than `str_example` and `@str_example` are defined to ensure that irb completion does not cause unintended behavior
+ str_example = ''
+ @str_example = ''
+ private_methods = ''
+ methods = ''
+ global_variables = ''
+ local_variables = ''
+ instance_variables = ''
+
+ # suppress "assigned but unused variable" warning
+ str_example.clear
+ @str_example.clear
+ private_methods.clear
+ methods.clear
+ global_variables.clear
+ local_variables.clear
+ instance_variables.clear
+
+ assert_include(completion_candidates("str_examp", binding), "str_example")
+ assert_equal("String", doc_namespace("str_example", binding))
+ assert_equal("String.to_s", doc_namespace("str_example.to_s", binding))
+
+ assert_include(completion_candidates("@str_examp", binding), "@str_example")
+ assert_equal("String", doc_namespace("@str_example", binding))
+ assert_equal("String.to_s", doc_namespace("@str_example.to_s", binding))
+ end
+
+ def test_complete_sort_variables
+ xzy, xzy_1, xzy2 = '', '', ''
+
+ xzy.clear
+ xzy_1.clear
+ xzy2.clear
+
+ candidates = completion_candidates("xz", binding)
+ assert_equal(%w[xzy xzy2 xzy_1], candidates)
+ end
+ end
+
+ class ConstantCompletionTest < CompletionTest
+ class Foo
+ B3 = 1
+ B1 = 1
+ B2 = 1
+ end
+
+ def test_complete_constants
+ assert_equal(["Foo"], completion_candidates("Fo", binding))
+ assert_equal(["Foo::B1", "Foo::B2", "Foo::B3"], completion_candidates("Foo::B", binding))
+ assert_equal(["Foo::B1.positive?"], completion_candidates("Foo::B1.pos", binding))
+
+ assert_equal(["::Forwardable"], completion_candidates("::Fo", binding))
+ assert_equal("Forwardable", doc_namespace("::Forwardable", binding))
+ end
+ end
+
+ def test_not_completing_empty_string
+ assert_equal([], completion_candidates("", binding))
+ assert_equal([], completion_candidates(" ", binding))
+ assert_equal([], completion_candidates("\t", binding))
+ assert_equal(nil, doc_namespace("", binding))
end
def test_complete_symbol
- %w"UTF-16LE UTF-7".each do |enc|
+ symbols = %w"UTF-16LE UTF-7".map do |enc|
"K".force_encoding(enc).to_sym
rescue
end
- _ = :aiueo
- assert_include(IRB::InputCompletor.retrieve_completion_data(":a", bind: binding), ":aiueo")
- assert_empty(IRB::InputCompletor.retrieve_completion_data(":irb_unknown_symbol_abcdefg", bind: binding))
+ symbols += [:aiueo, :"aiu eo"]
+ candidates = completion_candidates(":a", binding)
+ assert_include(candidates, ":aiueo")
+ assert_not_include(candidates, ":aiu eo")
+ assert_empty(completion_candidates(":irb_unknown_symbol_abcdefg", binding))
+ # Do not complete empty symbol for performance reason
+ assert_empty(completion_candidates(":", binding))
end
def test_complete_invalid_three_colons
- assert_empty(IRB::InputCompletor.retrieve_completion_data(":::A", bind: binding))
- assert_empty(IRB::InputCompletor.retrieve_completion_data(":::", bind: binding))
+ assert_empty(completion_candidates(":::A", binding))
+ assert_empty(completion_candidates(":::", binding))
end
def test_complete_absolute_constants_with_special_characters
- assert_empty(IRB::InputCompletor.retrieve_completion_data("::A:", bind: binding))
- assert_empty(IRB::InputCompletor.retrieve_completion_data("::A.", bind: binding))
- assert_empty(IRB::InputCompletor.retrieve_completion_data("::A(", bind: binding))
- assert_empty(IRB::InputCompletor.retrieve_completion_data("::A)", bind: binding))
- end
-
- def test_complete_symbol_failure
- assert_nil(IRB::InputCompletor::PerfectMatchedProc.(":aiueo", bind: binding))
+ assert_empty(completion_candidates("::A:", binding))
+ assert_empty(completion_candidates("::A.", binding))
+ assert_empty(completion_candidates("::A(", binding))
+ assert_empty(completion_candidates("::A)", binding))
+ assert_empty(completion_candidates("::A[", binding))
end
def test_complete_reserved_words
- candidates = IRB::InputCompletor.retrieve_completion_data("de", bind: binding)
+ candidates = completion_candidates("de", binding)
%w[def defined?].each do |word|
assert_include candidates, word
end
- candidates = IRB::InputCompletor.retrieve_completion_data("__", bind: binding)
+ candidates = completion_candidates("__", binding)
%w[__ENCODING__ __LINE__ __FILE__].each do |word|
assert_include candidates, word
end
end
- def test_complete_predicate?
- candidates = IRB::InputCompletor.retrieve_completion_data("1.posi", bind: binding)
- assert_include candidates, '1.positive?'
+ def test_complete_methods
+ obj = Object.new
+ obj.singleton_class.class_eval {
+ def public_hoge; end
+ private def private_hoge; end
- namespace = IRB::InputCompletor.retrieve_completion_data("1.positive?", bind: binding, doc_namespace: true)
- assert_equal "Integer.positive?", namespace
- end
+ # Support for overriding #methods etc.
+ def methods; end
+ def private_methods; end
+ def global_variables; end
+ def local_variables; end
+ def instance_variables; end
+ }
+ bind = obj.instance_exec { binding }
- def test_complete_require
- candidates = IRB::InputCompletor::CompletionProc.("'irb", "require ", "")
- %w['irb/init 'irb/ruby-lex].each do |word|
- assert_include candidates, word
- end
- # Test cache
- candidates = IRB::InputCompletor::CompletionProc.("'irb", "require ", "")
- %w['irb/init 'irb/ruby-lex].each do |word|
- assert_include candidates, word
- end
+ assert_include(completion_candidates("public_hog", bind), "public_hoge")
+ assert_include(doc_namespace("public_hoge", bind), "public_hoge")
+
+ assert_include(completion_candidates("private_hog", bind), "private_hoge")
+ assert_include(doc_namespace("private_hoge", bind), "private_hoge")
end
+ end
- def test_complete_require_library_name_first
- pend 'Need to use virtual library paths'
- candidates = IRB::InputCompletor::CompletionProc.("'csv", "require ", "")
- assert_equal "'csv", candidates.first
+ class DeprecatedInputCompletorTest < TestCase
+ def setup
+ save_encodings
+ @verbose, $VERBOSE = $VERBOSE, nil
+ IRB.init_config(nil)
+ IRB.conf[:VERBOSE] = false
+ IRB.conf[:MAIN_CONTEXT] = IRB::Context.new(IRB::WorkSpace.new(binding))
end
- def test_complete_require_relative
- candidates = Dir.chdir(__dir__ + "/../..") do
- IRB::InputCompletor::CompletionProc.("'lib/irb", "require_relative ", "")
- end
- %w['lib/irb/init 'lib/irb/ruby-lex].each do |word|
- assert_include candidates, word
- end
- # Test cache
- candidates = Dir.chdir(__dir__ + "/../..") do
- IRB::InputCompletor::CompletionProc.("'lib/irb", "require_relative ", "")
- end
- %w['lib/irb/init 'lib/irb/ruby-lex].each do |word|
- assert_include candidates, word
- end
+ def teardown
+ restore_encodings
+ $VERBOSE = @verbose
end
- def test_complete_variable
- str_example = ''
- str_example.clear # suppress "assigned but unused variable" warning
- assert_include(IRB::InputCompletor.retrieve_completion_data("str_examp", bind: binding), "str_example")
- assert_equal(IRB::InputCompletor.retrieve_completion_data("str_example", bind: binding, doc_namespace: true), "String")
- assert_equal(IRB::InputCompletor.retrieve_completion_data("str_example.to_s", bind: binding, doc_namespace: true), "String.to_s")
+ def test_completion_proc
+ assert_include(IRB::InputCompletor::CompletionProc.call('1.ab'), '1.abs')
+ assert_include(IRB::InputCompletor::CompletionProc.call('1.ab', '', ''), '1.abs')
end
- def test_complete_class_method
- assert_include(IRB::InputCompletor.retrieve_completion_data("String.new", bind: binding), "String.new")
- assert_equal(IRB::InputCompletor.retrieve_completion_data("String.new", bind: binding, doc_namespace: true), "String.new")
+ def test_retrieve_completion_data
+ assert_include(IRB::InputCompletor.retrieve_completion_data('1.ab'), '1.abs')
+ assert_equal(IRB::InputCompletor.retrieve_completion_data('1.abs', doc_namespace: true), 'Integer.abs')
+ bind = eval('a = 1; binding')
+ assert_include(IRB::InputCompletor.retrieve_completion_data('a.ab', bind: bind), 'a.abs')
+ assert_equal(IRB::InputCompletor.retrieve_completion_data('a.abs', bind: bind, doc_namespace: true), 'Integer.abs')
end
end
end
diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb
index b3fc49e7e3..aff4b5b67c 100644
--- a/test/irb/test_context.rb
+++ b/test/irb/test_context.rb
@@ -1,41 +1,16 @@
# frozen_string_literal: false
-require 'test/unit'
require 'tempfile'
require 'irb'
-require 'rubygems' if defined?(Gem)
-module TestIRB
- class TestContext < Test::Unit::TestCase
- class TestInputMethod < ::IRB::InputMethod
- attr_reader :list, :line_no
-
- def initialize(list = [])
- super("test")
- @line_no = 0
- @list = list
- end
-
- def gets
- @list[@line_no]&.tap {@line_no += 1}
- end
-
- def eof?
- @line_no >= @list.size
- end
-
- def encoding
- Encoding.default_external
- end
-
- def reset
- @line_no = 0
- end
- end
+require_relative "helper"
+module TestIRB
+ class ContextTest < TestCase
def setup
IRB.init_config(nil)
IRB.conf[:USE_SINGLELINE] = false
IRB.conf[:VERBOSE] = false
+ IRB.conf[:USE_PAGER] = false
workspace = IRB::WorkSpace.new(Object.new)
@context = IRB::Context.new(nil, workspace, TestInputMethod.new)
@@ -44,53 +19,17 @@ module TestIRB
def Reline.get_screen_size
[36, 80]
end
+ save_encodings
end
def teardown
Reline.instance_eval { undef :get_screen_size }
Reline.define_singleton_method(:get_screen_size, @get_screen_size)
+ restore_encodings
end
- def test_last_value
- assert_nil(@context.last_value)
- assert_nil(@context.evaluate('_', 1))
- obj = Object.new
- @context.set_last_value(obj)
- assert_same(obj, @context.last_value)
- assert_same(obj, @context.evaluate('_', 1))
- end
-
- def test_evaluate_with_exception
- assert_nil(@context.evaluate("$!", 1))
- e = assert_raise_with_message(RuntimeError, 'foo') {
- @context.evaluate("raise 'foo'", 1)
- }
- assert_equal('foo', e.message)
- assert_same(e, @context.evaluate('$!', 1, exception: e))
- e = assert_raise(SyntaxError) {
- @context.evaluate("1,2,3", 1, exception: e)
- }
- assert_match(/\A\(irb\):1:/, e.message)
- assert_not_match(/rescue _\.class/, e.message)
- end
-
- def test_evaluate_with_encoding_error_without_lineno
- pend if RUBY_ENGINE == 'truffleruby'
- assert_raise_with_message(EncodingError, /invalid symbol/) {
- @context.evaluate(%q[{"\xAE": 1}], 1)
- # The backtrace of this invalid encoding hash doesn't contain lineno.
- }
- end
-
- def test_evaluate_with_onigmo_warning
- pend if RUBY_ENGINE == 'truffleruby'
- assert_warning("(irb):1: warning: character class has duplicated range: /[aa]/\n") do
- @context.evaluate('/[aa]/', 1)
- end
- end
def test_eval_input
- pend if RUBY_ENGINE == 'truffleruby'
verbose, $VERBOSE = $VERBOSE, nil
input = TestInputMethod.new([
"raise 'Foo'\n",
@@ -103,17 +42,32 @@ module TestIRB
irb.eval_input
end
assert_empty err
- assert_pattern_list([:*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
- :*, /#<RuntimeError: Foo>\n/,
- :*, /0$/,
- :*, /0$/,
- /\s*/], out)
+
+ expected_output =
+ if RUBY_3_4
+ [
+ :*, /\(irb\):1:in '<main>': Foo \(RuntimeError\)\n/,
+ :*, /#<RuntimeError: Foo>\n/,
+ :*, /0$/,
+ :*, /0$/,
+ /\s*/
+ ]
+ else
+ [
+ :*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
+ :*, /#<RuntimeError: Foo>\n/,
+ :*, /0$/,
+ :*, /0$/,
+ /\s*/
+ ]
+ end
+
+ assert_pattern_list(expected_output, out)
ensure
$VERBOSE = verbose
end
def test_eval_input_raise2x
- pend if RUBY_ENGINE == 'truffleruby'
input = TestInputMethod.new([
"raise 'Foo'\n",
"raise 'Bar'\n",
@@ -124,11 +78,33 @@ module TestIRB
irb.eval_input
end
assert_empty err
- assert_pattern_list([
- :*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
- :*, /\(irb\):2:in `<main>': Bar \(RuntimeError\)\n/,
- :*, /#<RuntimeError: Bar>\n/,
- ], out)
+ expected_output =
+ if RUBY_3_4
+ [
+ :*, /\(irb\):1:in '<main>': Foo \(RuntimeError\)\n/,
+ :*, /\(irb\):2:in '<main>': Bar \(RuntimeError\)\n/,
+ :*, /#<RuntimeError: Bar>\n/,
+ ]
+ else
+ [
+ :*, /\(irb\):1:in `<main>': Foo \(RuntimeError\)\n/,
+ :*, /\(irb\):2:in `<main>': Bar \(RuntimeError\)\n/,
+ :*, /#<RuntimeError: Bar>\n/,
+ ]
+ end
+ assert_pattern_list(expected_output, out)
+ end
+
+ def test_prompt_n_deprecation
+ irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), TestInputMethod.new)
+
+ _, err = capture_output do
+ irb.context.prompt_n = "foo"
+ irb.context.prompt_n
+ end
+
+ assert_include err, "IRB::Context#prompt_n is deprecated"
+ assert_include err, "IRB::Context#prompt_n= is deprecated"
end
def test_output_to_pipe
@@ -154,16 +130,14 @@ module TestIRB
[:marshal, "123", Marshal.dump(123)],
],
failed: [
- [false, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
- [:p, "class Foo; undef inspect ;end; Foo.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
- [true, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
- [:yaml, "BasicObject.new", /\(Object doesn't support #inspect\)\n(=> )?\n/],
- [:marshal, "[Object.new, Class.new]", /\(Object doesn't support #inspect\)\n(=> )?\n/]
+ [false, "BasicObject.new", /#<NoMethodError: undefined method (`|')to_s' for/],
+ [:p, "class Foo; undef inspect ;end; Foo.new", /#<NoMethodError: undefined method (`|')inspect' for/],
+ [:yaml, "BasicObject.new", /#<NoMethodError: undefined method (`|')inspect' for/],
+ [:marshal, "[Object.new, Class.new]", /#<TypeError: can't dump anonymous class #<Class:/]
]
}.each do |scenario, cases|
cases.each do |inspect_mode, input, expected|
define_method "test_#{inspect_mode}_inspect_mode_#{scenario}" do
- pend if RUBY_ENGINE == 'truffleruby'
verbose, $VERBOSE = $VERBOSE, nil
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), TestInputMethod.new([input]))
irb.context.inspect_mode = inspect_mode
@@ -178,51 +152,71 @@ module TestIRB
end
end
- def test_default_config
- assert_equal(true, @context.use_autocomplete?)
+ def test_object_inspection_handles_basic_object
+ verbose, $VERBOSE = $VERBOSE, nil
+ irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), TestInputMethod.new(["BasicObject.new"]))
+ out, err = capture_output do
+ irb.eval_input
+ end
+ assert_empty err
+ assert_not_match(/NoMethodError/, out)
+ assert_match(/#<BasicObject:.*>/, out)
+ ensure
+ $VERBOSE = verbose
end
- def test_assignment_expression
- input = TestInputMethod.new
- irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
- [
- "foo = bar",
- "@foo = bar",
- "$foo = bar",
- "@@foo = bar",
- "::Foo = bar",
- "a::Foo = bar",
- "Foo = bar",
- "foo.bar = 1",
- "foo[1] = bar",
- "foo += bar",
- "foo -= bar",
- "foo ||= bar",
- "foo &&= bar",
- "foo, bar = 1, 2",
- "foo.bar=(1)",
- "foo; foo = bar",
- "foo; foo = bar; ;\n ;",
- "foo\nfoo = bar",
- ].each do |exp|
- assert(
- irb.assignment_expression?(exp),
- "#{exp.inspect}: should be an assignment expression"
- )
+ def test_object_inspection_falls_back_to_kernel_inspect_when_errored
+ verbose, $VERBOSE = $VERBOSE, nil
+ main = Object.new
+ main.singleton_class.module_eval <<~RUBY
+ class Foo
+ def inspect
+ raise "foo"
+ end
+ end
+ RUBY
+
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new(["Foo.new"]))
+ out, err = capture_output do
+ irb.eval_input
end
+ assert_empty err
+ assert_match(/An error occurred when inspecting the object: #<RuntimeError: foo>/, out)
+ assert_match(/Result of Kernel#inspect: #<#<Class:.*>::Foo:/, out)
+ ensure
+ $VERBOSE = verbose
+ end
+
+ def test_object_inspection_prints_useful_info_when_kernel_inspect_also_errored
+ verbose, $VERBOSE = $VERBOSE, nil
+ main = Object.new
+ main.singleton_class.module_eval <<~RUBY
+ class Foo
+ def initialize
+ # Kernel#inspect goes through instance variables with #inspect
+ # So this will cause Kernel#inspect to fail
+ @foo = BasicObject.new
+ end
- [
- "foo",
- "foo.bar",
- "foo[0]",
- "foo = bar; foo",
- "foo = bar\nfoo",
- ].each do |exp|
- refute(
- irb.assignment_expression?(exp),
- "#{exp.inspect}: should not be an assignment expression"
- )
+ def inspect
+ raise "foo"
+ end
+ end
+ RUBY
+
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new(["Foo.new"]))
+ out, err = capture_output do
+ irb.eval_input
end
+ assert_empty err
+ assert_match(/An error occurred when inspecting the object: #<RuntimeError: foo>/, out)
+ assert_match(/An error occurred when running Kernel#inspect: #<NoMethodError: undefined method (`|')inspect' for/, out)
+ ensure
+ $VERBOSE = verbose
+ end
+
+ def test_default_config
+ assert_equal(true, @context.use_autocomplete?)
end
def test_echo_on_assignment
@@ -359,7 +353,7 @@ module TestIRB
end
assert_empty err
assert_equal("=> \n#{value}\n", out)
- irb.context.evaluate('A.remove_method(:inspect)', 0)
+ irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = true
@@ -369,7 +363,7 @@ module TestIRB
end
assert_empty err
assert_equal("=> #{value_first_line[0..(input.winsize.last - 9)]}...\n=> \n#{value}\n", out)
- irb.context.evaluate('A.remove_method(:inspect)', 0)
+ irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = true
@@ -379,7 +373,7 @@ module TestIRB
end
assert_empty err
assert_equal("=> \n#{value}\n=> \n#{value}\n", out)
- irb.context.evaluate('A.remove_method(:inspect)', 0)
+ irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = false
@@ -389,7 +383,7 @@ module TestIRB
end
assert_empty err
assert_equal("", out)
- irb.context.evaluate('A.remove_method(:inspect)', 0)
+ irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = false
@@ -399,7 +393,7 @@ module TestIRB
end
assert_empty err
assert_equal("", out)
- irb.context.evaluate('A.remove_method(:inspect)', 0)
+ irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
input.reset
irb.context.echo = false
@@ -409,7 +403,7 @@ module TestIRB
end
assert_empty err
assert_equal("", out)
- irb.context.evaluate('A.remove_method(:inspect)', 0)
+ irb.context.evaluate_expression('A.remove_method(:inspect)', 0)
end
end
@@ -477,7 +471,6 @@ module TestIRB
def test_default_return_format
IRB.conf[:PROMPT][:MY_PROMPT] = {
:PROMPT_I => "%03n> ",
- :PROMPT_N => "%03n> ",
:PROMPT_S => "%03n> ",
:PROMPT_C => "%03n> "
# without :RETURN
@@ -507,28 +500,35 @@ module TestIRB
irb.eval_input
end
assert_empty err
- if '2.5.0' <= RUBY_VERSION && RUBY_VERSION < '3.0.0' && STDOUT.tty?
- expected = [
- :*, /Traceback \(most recent call last\):\n/,
- :*, /\t 2: from \(irb\):1:in `<main>'\n/,
- :*, /\t 1: from \(irb\):1:in `hoge'\n/,
- :*, /\(irb\):1:in `fuga': unhandled exception\n/,
- ]
- else
- expected = [
- :*, /\(irb\):1:in `fuga': unhandled exception\n/,
- :*, /\tfrom \(irb\):1:in `hoge'\n/,
- :*, /\tfrom \(irb\):1:in `<main>'\n/,
- :*
- ]
- end
- assert_pattern_list(expected, out)
+ expected_output =
+ if RUBY_3_4
+ [
+ :*, /\(irb\):1:in 'fuga': unhandled exception\n/,
+ :*, /\tfrom \(irb\):1:in 'hoge'\n/,
+ :*, /\tfrom \(irb\):1:in '<main>'\n/,
+ :*
+ ]
+ elsif RUBY_VERSION < '3.0.0' && STDOUT.tty?
+ [
+ :*, /Traceback \(most recent call last\):\n/,
+ :*, /\t 2: from \(irb\):1:in `<main>'\n/,
+ :*, /\t 1: from \(irb\):1:in `hoge'\n/,
+ :*, /\(irb\):1:in `fuga': unhandled exception\n/,
+ ]
+ else
+ [
+ :*, /\(irb\):1:in `fuga': unhandled exception\n/,
+ :*, /\tfrom \(irb\):1:in `hoge'\n/,
+ :*, /\tfrom \(irb\):1:in `<main>'\n/,
+ :*
+ ]
+ end
+ assert_pattern_list(expected_output, out)
ensure
$VERBOSE = verbose
end
def test_eval_input_with_invalid_byte_sequence_exception
- pend if RUBY_ENGINE == 'truffleruby'
verbose, $VERBOSE = $VERBOSE, nil
input = TestInputMethod.new([
%Q{def hoge() fuga; end; def fuga() raise "A\\xF3B"; end; hoge\n},
@@ -538,22 +538,31 @@ module TestIRB
irb.eval_input
end
assert_empty err
- if '2.5.0' <= RUBY_VERSION && RUBY_VERSION < '3.0.0' && STDOUT.tty?
- expected = [
- :*, /Traceback \(most recent call last\):\n/,
- :*, /\t 2: from \(irb\):1:in `<main>'\n/,
- :*, /\t 1: from \(irb\):1:in `hoge'\n/,
- :*, /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/,
- ]
- else
- expected = [
- :*, /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/,
- :*, /\tfrom \(irb\):1:in `hoge'\n/,
- :*, /\tfrom \(irb\):1:in `<main>'\n/,
- :*
- ]
- end
- assert_pattern_list(expected, out)
+ expected_output =
+ if RUBY_3_4
+ [
+ :*, /\(irb\):1:in 'fuga': A\\xF3B \(RuntimeError\)\n/,
+ :*, /\tfrom \(irb\):1:in 'hoge'\n/,
+ :*, /\tfrom \(irb\):1:in '<main>'\n/,
+ :*
+ ]
+ elsif RUBY_VERSION < '3.0.0' && STDOUT.tty?
+ [
+ :*, /Traceback \(most recent call last\):\n/,
+ :*, /\t 2: from \(irb\):1:in `<main>'\n/,
+ :*, /\t 1: from \(irb\):1:in `hoge'\n/,
+ :*, /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/,
+ ]
+ else
+ [
+ :*, /\(irb\):1:in `fuga': A\\xF3B \(RuntimeError\)\n/,
+ :*, /\tfrom \(irb\):1:in `hoge'\n/,
+ :*, /\tfrom \(irb\):1:in `<main>'\n/,
+ :*
+ ]
+ end
+
+ assert_pattern_list(expected_output, out)
ensure
$VERBOSE = verbose
end
@@ -575,47 +584,47 @@ module TestIRB
irb.eval_input
end
assert_empty err
- if '2.5.0' <= RUBY_VERSION && RUBY_VERSION < '3.0.0' && STDOUT.tty?
+ if RUBY_VERSION < '3.0.0' && STDOUT.tty?
expected = [
:*, /Traceback \(most recent call last\):\n/,
:*, /\t... \d+ levels...\n/,
- :*, /\t16: from \(irb\):1:in `a4'\n/,
- :*, /\t15: from \(irb\):1:in `a5'\n/,
- :*, /\t14: from \(irb\):1:in `a6'\n/,
- :*, /\t13: from \(irb\):1:in `a7'\n/,
- :*, /\t12: from \(irb\):1:in `a8'\n/,
- :*, /\t11: from \(irb\):1:in `a9'\n/,
- :*, /\t10: from \(irb\):1:in `a10'\n/,
- :*, /\t 9: from \(irb\):1:in `a11'\n/,
- :*, /\t 8: from \(irb\):1:in `a12'\n/,
- :*, /\t 7: from \(irb\):1:in `a13'\n/,
- :*, /\t 6: from \(irb\):1:in `a14'\n/,
- :*, /\t 5: from \(irb\):1:in `a15'\n/,
- :*, /\t 4: from \(irb\):1:in `a16'\n/,
- :*, /\t 3: from \(irb\):1:in `a17'\n/,
- :*, /\t 2: from \(irb\):1:in `a18'\n/,
- :*, /\t 1: from \(irb\):1:in `a19'\n/,
- :*, /\(irb\):1:in `a20': unhandled exception\n/,
+ :*, /\t16: from \(irb\):1:in (`|')a4'\n/,
+ :*, /\t15: from \(irb\):1:in (`|')a5'\n/,
+ :*, /\t14: from \(irb\):1:in (`|')a6'\n/,
+ :*, /\t13: from \(irb\):1:in (`|')a7'\n/,
+ :*, /\t12: from \(irb\):1:in (`|')a8'\n/,
+ :*, /\t11: from \(irb\):1:in (`|')a9'\n/,
+ :*, /\t10: from \(irb\):1:in (`|')a10'\n/,
+ :*, /\t 9: from \(irb\):1:in (`|')a11'\n/,
+ :*, /\t 8: from \(irb\):1:in (`|')a12'\n/,
+ :*, /\t 7: from \(irb\):1:in (`|')a13'\n/,
+ :*, /\t 6: from \(irb\):1:in (`|')a14'\n/,
+ :*, /\t 5: from \(irb\):1:in (`|')a15'\n/,
+ :*, /\t 4: from \(irb\):1:in (`|')a16'\n/,
+ :*, /\t 3: from \(irb\):1:in (`|')a17'\n/,
+ :*, /\t 2: from \(irb\):1:in (`|')a18'\n/,
+ :*, /\t 1: from \(irb\):1:in (`|')a19'\n/,
+ :*, /\(irb\):1:in (`|')a20': unhandled exception\n/,
]
else
expected = [
- :*, /\(irb\):1:in `a20': unhandled exception\n/,
- :*, /\tfrom \(irb\):1:in `a19'\n/,
- :*, /\tfrom \(irb\):1:in `a18'\n/,
- :*, /\tfrom \(irb\):1:in `a17'\n/,
- :*, /\tfrom \(irb\):1:in `a16'\n/,
- :*, /\tfrom \(irb\):1:in `a15'\n/,
- :*, /\tfrom \(irb\):1:in `a14'\n/,
- :*, /\tfrom \(irb\):1:in `a13'\n/,
- :*, /\tfrom \(irb\):1:in `a12'\n/,
- :*, /\tfrom \(irb\):1:in `a11'\n/,
- :*, /\tfrom \(irb\):1:in `a10'\n/,
- :*, /\tfrom \(irb\):1:in `a9'\n/,
- :*, /\tfrom \(irb\):1:in `a8'\n/,
- :*, /\tfrom \(irb\):1:in `a7'\n/,
- :*, /\tfrom \(irb\):1:in `a6'\n/,
- :*, /\tfrom \(irb\):1:in `a5'\n/,
- :*, /\tfrom \(irb\):1:in `a4'\n/,
+ :*, /\(irb\):1:in (`|')a20': unhandled exception\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a19'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a18'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a17'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a16'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a15'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a14'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a13'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a12'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a11'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a10'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a9'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a8'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a7'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a6'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a5'\n/,
+ :*, /\tfrom \(irb\):1:in (`|')a4'\n/,
:*, /\t... \d+ levels...\n/,
]
end
@@ -624,6 +633,35 @@ module TestIRB
$VERBOSE = verbose
end
+ def test_prompt_main_escape
+ main = Struct.new(:to_s).new("main\a\t\r\n")
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
+ assert_equal("irb(main )>", irb.send(:format_prompt, 'irb(%m)>', nil, 1, 1))
+ end
+
+ def test_prompt_main_inspect_escape
+ main = Struct.new(:inspect).new("main\\n\nmain")
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
+ assert_equal("irb(main\\n main)>", irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1))
+ end
+
+ def test_prompt_main_truncate
+ main = Struct.new(:to_s).new("a" * 100)
+ def main.inspect; to_s.inspect; end
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
+ assert_equal('irb(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa...)>', irb.send(:format_prompt, 'irb(%m)>', nil, 1, 1))
+ assert_equal('irb("aaaaaaaaaaaaaaaaaaaaaaaaaaaa...)>', irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1))
+ end
+
+ def test_prompt_main_raise
+ main = Object.new
+ def main.to_s; raise TypeError; end
+ def main.inspect; raise ArgumentError; end
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), TestInputMethod.new)
+ assert_equal("irb(!TypeError)>", irb.send(:format_prompt, 'irb(%m)>', nil, 1, 1))
+ assert_equal("irb(!ArgumentError)>", irb.send(:format_prompt, 'irb(%M)>', nil, 1, 1))
+ end
+
def test_lineno
input = TestInputMethod.new([
"\n",
@@ -645,6 +683,31 @@ module TestIRB
], out)
end
+ def test_irb_path_setter
+ @context.irb_path = __FILE__
+ assert_equal(__FILE__, @context.irb_path)
+ assert_equal("#{__FILE__}(irb)", @context.instance_variable_get(:@eval_path))
+ @context.irb_path = 'file/does/not/exist'
+ assert_equal('file/does/not/exist', @context.irb_path)
+ assert_equal('file/does/not/exist', @context.instance_variable_get(:@eval_path))
+ @context.irb_path = "#{__FILE__}(irb)"
+ assert_equal("#{__FILE__}(irb)", @context.irb_path)
+ assert_equal("#{__FILE__}(irb)", @context.instance_variable_get(:@eval_path))
+ end
+
+ def test_build_completor
+ verbose, $VERBOSE = $VERBOSE, nil
+ original_completor = IRB.conf[:COMPLETOR]
+ IRB.conf[:COMPLETOR] = :regexp
+ assert_equal 'IRB::RegexpCompletor', @context.send(:build_completor).class.name
+ IRB.conf[:COMPLETOR] = :unknown
+ assert_equal 'IRB::RegexpCompletor', @context.send(:build_completor).class.name
+ # :type is tested in test_type_completor.rb
+ ensure
+ $VERBOSE = verbose
+ IRB.conf[:COMPLETOR] = original_completor
+ end
+
private
def without_colorize
diff --git a/test/irb/test_debugger_integration.rb b/test/irb/test_debugger_integration.rb
new file mode 100644
index 0000000000..839a0d43f0
--- /dev/null
+++ b/test/irb/test_debugger_integration.rb
@@ -0,0 +1,462 @@
+# frozen_string_literal: true
+
+require "tempfile"
+require "tmpdir"
+
+require_relative "helper"
+
+module TestIRB
+ class DebuggerIntegrationTest < IntegrationTestCase
+ def setup
+ super
+
+ if RUBY_ENGINE == 'truffleruby'
+ omit "This test runs with ruby/debug, which doesn't work with truffleruby"
+ end
+
+ @envs.merge!("NO_COLOR" => "true", "RUBY_DEBUG_HISTORY_FILE" => '')
+ end
+
+ def test_backtrace
+ write_ruby <<~'RUBY'
+ def foo
+ binding.irb
+ end
+ foo
+ RUBY
+
+ output = run_ruby_file do
+ type "backtrace"
+ type "exit!"
+ end
+
+ assert_match(/irb\(main\):001> backtrace/, output)
+ assert_match(/Object#foo at #{@ruby_file.to_path}/, output)
+ end
+
+ def test_debug
+ write_ruby <<~'ruby'
+ binding.irb
+ puts "hello"
+ ruby
+
+ output = run_ruby_file do
+ type "debug"
+ type "next"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> debug/, output)
+ assert_match(/irb:rdbg\(main\):002> next/, output)
+ assert_match(/=> 2\| puts "hello"/, output)
+ end
+
+ def test_debug_command_only_runs_once
+ write_ruby <<~'ruby'
+ binding.irb
+ ruby
+
+ output = run_ruby_file do
+ type "debug"
+ type "debug"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> debug/, output)
+ assert_match(/irb:rdbg\(main\):002> debug/, output)
+ assert_match(/IRB is already running with a debug session/, output)
+ end
+
+ def test_next
+ write_ruby <<~'ruby'
+ binding.irb
+ puts "hello"
+ ruby
+
+ output = run_ruby_file do
+ type "next"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> next/, output)
+ assert_match(/=> 2\| puts "hello"/, output)
+ end
+
+ def test_break
+ write_ruby <<~'RUBY'
+ binding.irb
+ puts "Hello"
+ RUBY
+
+ output = run_ruby_file do
+ type "break 2"
+ type "continue"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> break/, output)
+ assert_match(/=> 2\| puts "Hello"/, output)
+ end
+
+ def test_delete
+ write_ruby <<~'RUBY'
+ binding.irb
+ puts "Hello"
+ binding.irb
+ puts "World"
+ RUBY
+
+ output = run_ruby_file do
+ type "break 4"
+ type "continue"
+ type "delete 0"
+ type "continue"
+ end
+
+ assert_match(/irb:rdbg\(main\):003> delete/, output)
+ assert_match(/deleted: #0 BP - Line/, output)
+ end
+
+ def test_step
+ write_ruby <<~'RUBY'
+ def foo
+ puts "Hello"
+ end
+ binding.irb
+ foo
+ RUBY
+
+ output = run_ruby_file do
+ type "step"
+ type "step"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> step/, output)
+ assert_match(/=> 5\| foo/, output)
+ assert_match(/=> 2\| puts "Hello"/, output)
+ end
+
+ def test_long_stepping
+ write_ruby <<~'RUBY'
+ class Foo
+ def foo(num)
+ bar(num + 10)
+ end
+
+ def bar(num)
+ num
+ end
+ end
+
+ binding.irb
+ Foo.new.foo(100)
+ RUBY
+
+ output = run_ruby_file do
+ type "step"
+ type "step"
+ type "step"
+ type "step"
+ type "num"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> step/, output)
+ assert_match(/irb:rdbg\(main\):002> step/, output)
+ assert_match(/irb:rdbg\(#<Foo:.*>\):003> step/, output)
+ assert_match(/irb:rdbg\(#<Foo:.*>\):004> step/, output)
+ assert_match(/irb:rdbg\(#<Foo:.*>\):005> num/, output)
+ assert_match(/=> 110/, output)
+ end
+
+ def test_continue
+ write_ruby <<~'RUBY'
+ binding.irb
+ puts "Hello"
+ binding.irb
+ puts "World"
+ RUBY
+
+ output = run_ruby_file do
+ type "continue"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> continue/, output)
+ assert_match(/=> 3: binding.irb/, output)
+ assert_match(/irb:rdbg\(main\):002> continue/, output)
+ end
+
+ def test_finish
+ write_ruby <<~'RUBY'
+ def foo
+ binding.irb
+ puts "Hello"
+ end
+ foo
+ RUBY
+
+ output = run_ruby_file do
+ type "finish"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> finish/, output)
+ assert_match(/=> 4\| end/, output)
+ end
+
+ def test_info
+ write_ruby <<~'RUBY'
+ def foo
+ a = "He" + "llo"
+ binding.irb
+ end
+ foo
+ RUBY
+
+ output = run_ruby_file do
+ type "info"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> info/, output)
+ assert_match(/%self = main/, output)
+ assert_match(/a = "Hello"/, output)
+ end
+
+ def test_catch
+ write_ruby <<~'RUBY'
+ binding.irb
+ 1 / 0
+ RUBY
+
+ output = run_ruby_file do
+ type "catch ZeroDivisionError"
+ type "continue"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> catch/, output)
+ assert_match(/Stop by #0 BP - Catch "ZeroDivisionError"/, output)
+ end
+
+ def test_exit
+ write_ruby <<~'RUBY'
+ binding.irb
+ puts "hello"
+ RUBY
+
+ output = run_ruby_file do
+ type "next"
+ type "exit"
+ end
+
+ assert_match(/irb\(main\):001> next/, output)
+ end
+
+ def test_quit
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "next"
+ type "quit!"
+ end
+
+ assert_match(/irb\(main\):001> next/, output)
+ end
+
+ def test_prompt_line_number_continues
+ write_ruby <<~'ruby'
+ binding.irb
+ puts "Hello"
+ puts "World"
+ ruby
+
+ output = run_ruby_file do
+ type "123"
+ type "456"
+ type "next"
+ type "info"
+ type "next"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):003> next/, output)
+ assert_match(/irb:rdbg\(main\):004> info/, output)
+ assert_match(/irb:rdbg\(main\):005> next/, output)
+ end
+
+ def test_prompt_irb_name_is_kept
+ write_rc <<~RUBY
+ IRB.conf[:IRB_NAME] = "foo"
+ RUBY
+
+ write_ruby <<~'ruby'
+ binding.irb
+ puts "Hello"
+ ruby
+
+ output = run_ruby_file do
+ type "next"
+ type "continue"
+ end
+
+ assert_match(/foo\(main\):001> next/, output)
+ assert_match(/foo:rdbg\(main\):002> continue/, output)
+ end
+
+ def test_irb_commands_are_available_after_moving_around_with_the_debugger
+ write_ruby <<~'ruby'
+ class Foo
+ def bar
+ puts "bar"
+ end
+ end
+
+ binding.irb
+ Foo.new.bar
+ ruby
+
+ output = run_ruby_file do
+ # Due to the way IRB defines its commands, moving into the Foo instance from main is necessary for proper testing.
+ type "next"
+ type "step"
+ type "irb_info"
+ type "continue"
+ end
+
+ assert_include(output, "InputMethod: RelineInputMethod")
+ end
+
+ def test_help_command_is_delegated_to_the_debugger
+ write_ruby <<~'ruby'
+ binding.irb
+ ruby
+
+ output = run_ruby_file do
+ type "debug"
+ type "help"
+ type "continue"
+ end
+
+ assert_include(output, "### Frame control")
+ end
+
+ def test_help_display_different_content_when_debugger_is_enabled
+ write_ruby <<~'ruby'
+ binding.irb
+ ruby
+
+ output = run_ruby_file do
+ type "debug"
+ type "help"
+ type "continue"
+ end
+
+ # IRB's commands should still be listed
+ assert_match(/help\s+List all available commands/, output)
+ # debug gem's commands should be appended at the end
+ assert_match(/Debugging \(from debug\.gem\)\s+### Control flow/, output)
+ end
+
+ def test_input_is_evaluated_in_the_context_of_the_current_thread
+ write_ruby <<~'ruby'
+ current_thread = Thread.current
+ binding.irb
+ ruby
+
+ output = run_ruby_file do
+ type "debug"
+ type '"Threads match: #{current_thread == Thread.current}"'
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> debug/, output)
+ assert_match(/Threads match: true/, output)
+ end
+
+ def test_irb_switches_debugger_interface_if_debug_was_already_activated
+ write_ruby <<~'ruby'
+ require 'debug'
+ class Foo
+ def bar
+ puts "bar"
+ end
+ end
+
+ binding.irb
+ Foo.new.bar
+ ruby
+
+ output = run_ruby_file do
+ # Due to the way IRB defines its commands, moving into the Foo instance from main is necessary for proper testing.
+ type "next"
+ type "step"
+ type 'irb_info'
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> next/, output)
+ assert_include(output, "InputMethod: RelineInputMethod")
+ end
+
+ def test_debugger_cant_be_activated_while_multi_irb_is_active
+ write_ruby <<~'ruby'
+ binding.irb
+ a = 1
+ ruby
+
+ output = run_ruby_file do
+ type "jobs"
+ type "next"
+ type "exit"
+ end
+
+ assert_match(/irb\(main\):001> jobs/, output)
+ assert_include(output, "Can't start the debugger when IRB is running in a multi-IRB session.")
+ end
+
+ def test_multi_irb_commands_are_not_available_after_activating_the_debugger
+ write_ruby <<~'ruby'
+ binding.irb
+ a = 1
+ ruby
+
+ output = run_ruby_file do
+ type "next"
+ type "jobs"
+ type "continue"
+ end
+
+ assert_match(/irb\(main\):001> next/, output)
+ assert_include(output, "Multi-IRB commands are not available when the debugger is enabled.")
+ end
+
+ def test_irb_passes_empty_input_to_debugger_to_repeat_the_last_command
+ write_ruby <<~'ruby'
+ binding.irb
+ puts "foo"
+ puts "bar"
+ puts "baz"
+ ruby
+
+ output = run_ruby_file do
+ type "next"
+ type ""
+ # Test that empty input doesn't repeat expressions
+ type "123"
+ type ""
+ type "next"
+ type ""
+ type ""
+ end
+
+ assert_include(output, "=> 2\| puts \"foo\"")
+ assert_include(output, "=> 3\| puts \"bar\"")
+ assert_include(output, "=> 4\| puts \"baz\"")
+ end
+ end
+end
diff --git a/test/irb/test_eval_history.rb b/test/irb/test_eval_history.rb
new file mode 100644
index 0000000000..54913ceff5
--- /dev/null
+++ b/test/irb/test_eval_history.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+require "irb"
+
+require_relative "helper"
+
+module TestIRB
+ class EvalHistoryTest < TestCase
+ def setup
+ save_encodings
+ IRB.instance_variable_get(:@CONF).clear
+ end
+
+ def teardown
+ restore_encodings
+ end
+
+ def execute_lines(*lines, conf: {}, main: self, irb_path: nil)
+ IRB.init_config(nil)
+ IRB.conf[:VERBOSE] = false
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
+ IRB.conf[:USE_PAGER] = false
+ IRB.conf.merge!(conf)
+ input = TestInputMethod.new(lines)
+ irb = IRB::Irb.new(IRB::WorkSpace.new(main), input)
+ irb.context.return_format = "=> %s\n"
+ irb.context.irb_path = irb_path if irb_path
+ IRB.conf[:MAIN_CONTEXT] = irb.context
+ capture_output do
+ irb.eval_input
+ end
+ end
+
+ def test_eval_history_is_disabled_by_default
+ out, err = execute_lines(
+ "a = 1",
+ "__"
+ )
+
+ assert_empty(err)
+ assert_match(/undefined local variable or method (`|')__'/, out)
+ end
+
+ def test_eval_history_can_be_retrieved_with_double_underscore
+ out, err = execute_lines(
+ "a = 1",
+ "__",
+ conf: { EVAL_HISTORY: 5 }
+ )
+
+ assert_empty(err)
+ assert_match("=> 1\n" + "=> 1 1\n", out)
+ end
+
+ def test_eval_history_respects_given_limit
+ out, err = execute_lines(
+ "'foo'\n",
+ "'bar'\n",
+ "'baz'\n",
+ "'xyz'\n",
+ "__",
+ conf: { EVAL_HISTORY: 4 }
+ )
+
+ assert_empty(err)
+ # Because eval_history injects `__` into the history AND decide to ignore it, we only get <limit> - 1 results
+ assert_match("2 \"bar\"\n" + "3 \"baz\"\n" + "4 \"xyz\"\n", out)
+ end
+ end
+end
diff --git a/test/irb/test_evaluation.rb b/test/irb/test_evaluation.rb
new file mode 100644
index 0000000000..adb69b2067
--- /dev/null
+++ b/test/irb/test_evaluation.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require "tempfile"
+
+require_relative "helper"
+
+module TestIRB
+ class EchoingTest < IntegrationTestCase
+ def test_irb_echos_by_default
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "123123"
+ type "exit"
+ end
+
+ assert_include(output, "=> 123123")
+ end
+
+ def test_irb_doesnt_echo_line_with_semicolon
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "123123;"
+ type "123123 ;"
+ type "123123; "
+ type <<~RUBY
+ if true
+ 123123
+ end;
+ RUBY
+ type "'evaluation ends'"
+ type "exit"
+ end
+
+ assert_include(output, "=> \"evaluation ends\"")
+ assert_not_include(output, "=> 123123")
+ end
+ end
+end
diff --git a/test/irb/test_history.rb b/test/irb/test_history.rb
index 81b7fe8679..63be35fdaa 100644
--- a/test/irb/test_history.rb
+++ b/test/irb/test_history.rb
@@ -1,51 +1,47 @@
# frozen_string_literal: false
-require 'test/unit'
require 'irb'
-require 'irb/ext/save-history'
require 'readline'
+require "tempfile"
+
+require_relative "helper"
+
+return if RUBY_PLATFORM.match?(/solaris|mswin|mingw/i)
module TestIRB
- class TestHistory < Test::Unit::TestCase
+ class HistoryTest < TestCase
def setup
- IRB.conf[:RC_NAME_GENERATOR] = nil
+ @original_verbose, $VERBOSE = $VERBOSE, nil
+ @tmpdir = Dir.mktmpdir("test_irb_history_")
+ @backup_home = ENV["HOME"]
+ @backup_xdg_config_home = ENV.delete("XDG_CONFIG_HOME")
+ @backup_irbrc = ENV.delete("IRBRC")
+ @backup_default_external = Encoding.default_external
+ ENV["HOME"] = @tmpdir
+ IRB.instance_variable_set(:@existing_rc_name_generators, nil)
end
def teardown
- IRB.conf[:RC_NAME_GENERATOR] = nil
+ IRB.instance_variable_set(:@existing_rc_name_generators, nil)
+ ENV["HOME"] = @backup_home
+ ENV["XDG_CONFIG_HOME"] = @backup_xdg_config_home
+ ENV["IRBRC"] = @backup_irbrc
+ Encoding.default_external = @backup_default_external
+ $VERBOSE = @original_verbose
+ FileUtils.rm_rf(@tmpdir)
end
- class TestInputMethod < ::IRB::InputMethod
- HISTORY = Array.new
+ class TestInputMethodWithRelineHistory < TestInputMethod
+ # When IRB.conf[:USE_MULTILINE] is true, IRB::RelineInputMethod uses Reline::History
+ HISTORY = Reline::History.new(Reline.core.config)
include IRB::HistorySavingAbility
+ end
- attr_reader :list, :line_no
-
- def initialize(list = [])
- super("test")
- @line_no = 0
- @list = list
- end
-
- def gets
- @list[@line_no]&.tap {@line_no += 1}
- end
-
- def eof?
- @line_no >= @list.size
- end
-
- def encoding
- Encoding.default_external
- end
-
- def reset
- @line_no = 0
- end
+ class TestInputMethodWithReadlineHistory < TestInputMethod
+ # When IRB.conf[:USE_MULTILINE] is false, IRB::ReadlineInputMethod uses Readline::HISTORY
+ HISTORY = Readline::HISTORY
- def winsize
- [10, 20]
- end
+ include IRB::HistorySavingAbility
end
def test_history_save_1
@@ -127,10 +123,80 @@ module TestIRB
INPUT
end
- def test_history_concurrent_use
+ def test_history_concurrent_use_reline
omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
IRB.conf[:SAVE_HISTORY] = 1
- assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT) do |history_file|
+ history_concurrent_use_for_input_method(TestInputMethodWithRelineHistory)
+ end
+
+ def test_history_concurrent_use_readline
+ omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
+ IRB.conf[:SAVE_HISTORY] = 1
+ history_concurrent_use_for_input_method(TestInputMethodWithReadlineHistory)
+ end
+
+ def test_history_concurrent_use_not_present
+ IRB.conf[:LC_MESSAGES] = IRB::Locale.new
+ IRB.conf[:SAVE_HISTORY] = 1
+ io = TestInputMethodWithRelineHistory.new
+ io.class::HISTORY.clear
+ io.load_history
+ io.class::HISTORY << 'line1'
+ io.class::HISTORY << 'line2'
+
+ history_file = IRB.rc_file("_history")
+ assert_not_send [File, :file?, history_file]
+ File.write(history_file, "line0\n")
+ io.save_history
+ assert_equal(%w"line0 line1 line2", File.read(history_file).split)
+ end
+
+ def test_history_different_encodings
+ IRB.conf[:SAVE_HISTORY] = 2
+ Encoding.default_external = Encoding::US_ASCII
+ locale = IRB::Locale.new("C")
+ assert_history(<<~EXPECTED_HISTORY.encode(Encoding::US_ASCII), <<~INITIAL_HISTORY.encode(Encoding::UTF_8), <<~INPUT, locale: locale)
+ ????
+ exit
+ EXPECTED_HISTORY
+ 😀
+ INITIAL_HISTORY
+ exit
+ INPUT
+ end
+
+ def test_history_does_not_raise_when_history_file_directory_does_not_exist
+ backup_history_file = IRB.conf[:HISTORY_FILE]
+ IRB.conf[:SAVE_HISTORY] = 1
+ IRB.conf[:HISTORY_FILE] = "fake/fake/fake/history_file"
+ io = TestInputMethodWithRelineHistory.new
+
+ assert_warn(/history file does not exist/) do
+ io.save_history
+ end
+
+ # assert_warn reverts $VERBOSE to EnvUtil.original_verbose, which is true in some cases
+ # We want to keep $VERBOSE as nil until teardown is called
+ # TODO: check if this is an assert_warn issue
+ $VERBOSE = nil
+ ensure
+ IRB.conf[:HISTORY_FILE] = backup_history_file
+ end
+
+ def test_no_home_no_history_file_does_not_raise_history_save
+ ENV['HOME'] = nil
+ io = TestInputMethodWithRelineHistory.new
+ assert_nil(IRB.rc_file('_history'))
+ assert_nothing_raised do
+ io.load_history
+ io.save_history
+ end
+ end
+
+ private
+
+ def history_concurrent_use_for_input_method(input_method)
+ assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT, input_method) do |history_file|
exit
5
exit
@@ -143,7 +209,7 @@ module TestIRB
5
exit
INPUT
- assert_history(<<~EXPECTED_HISTORY2, <<~INITIAL_HISTORY2, <<~INPUT2)
+ assert_history(<<~EXPECTED_HISTORY2, <<~INITIAL_HISTORY2, <<~INPUT2, input_method)
exit
EXPECTED_HISTORY2
1
@@ -158,35 +224,31 @@ module TestIRB
end
end
- private
-
- def assert_history(expected_history, initial_irb_history, input)
- backup_verbose, $VERBOSE = $VERBOSE, nil
- backup_home = ENV["HOME"]
- backup_xdg_config_home = ENV.delete("XDG_CONFIG_HOME")
- IRB.conf[:LC_MESSAGES] = IRB::Locale.new
+ def assert_history(expected_history, initial_irb_history, input, input_method = TestInputMethodWithRelineHistory, locale: IRB::Locale.new)
+ IRB.conf[:LC_MESSAGES] = locale
actual_history = nil
- Dir.mktmpdir("test_irb_history_#{$$}") do |tmpdir|
- ENV["HOME"] = tmpdir
- open(IRB.rc_file("_history"), "w") do |f|
- f.write(initial_irb_history)
- end
+ history_file = IRB.rc_file("_history")
+ ENV["HOME"] = @tmpdir
+ File.open(history_file, "w") do |f|
+ f.write(initial_irb_history)
+ end
- io = TestInputMethod.new
+ io = input_method.new
+ io.class::HISTORY.clear
+ io.load_history
+ if block_given?
+ previous_history = []
+ io.class::HISTORY.each { |line| previous_history << line }
+ yield history_file
io.class::HISTORY.clear
- io.load_history
- if block_given?
- history = io.class::HISTORY.dup
- yield IRB.rc_file("_history")
- io.class::HISTORY.replace(history)
- end
- io.class::HISTORY.concat(input.split)
- io.save_history
+ previous_history.each { |line| io.class::HISTORY << line }
+ end
+ input.split.each { |line| io.class::HISTORY << line }
+ io.save_history
- io.load_history
- open(IRB.rc_file("_history"), "r") do |f|
- actual_history = f.read
- end
+ io.load_history
+ File.open(history_file, "r") do |f|
+ actual_history = f.read
end
assert_equal(expected_history, actual_history, <<~MESSAGE)
expected:
@@ -194,10 +256,6 @@ module TestIRB
but actual:
#{actual_history}
MESSAGE
- ensure
- $VERBOSE = backup_verbose
- ENV["HOME"] = backup_home
- ENV["XDG_CONFIG_HOME"] = backup_xdg_config_home
end
def with_temp_stdio
@@ -208,4 +266,226 @@ module TestIRB
end
end
end
-end if not RUBY_PLATFORM.match?(/solaris|mswin|mingw/i)
+
+ class IRBHistoryIntegrationTest < IntegrationTestCase
+ def test_history_saving_with_debug
+ write_history ""
+
+ write_ruby <<~'RUBY'
+ def foo
+ end
+
+ binding.irb
+
+ foo
+ RUBY
+
+ output = run_ruby_file do
+ type "'irb session'"
+ type "next"
+ type "'irb:debug session'"
+ type "step"
+ type "irb_info"
+ type "puts Reline::HISTORY.to_a.to_s"
+ type "q!"
+ end
+
+ assert_include(output, "InputMethod: RelineInputMethod")
+ # check that in-memory history is preserved across sessions
+ assert_include output, %q(
+ ["'irb session'", "next", "'irb:debug session'", "step", "irb_info", "puts Reline::HISTORY.to_a.to_s"]
+ ).strip
+
+ assert_equal <<~HISTORY, @history_file.open.read
+ 'irb session'
+ next
+ 'irb:debug session'
+ step
+ irb_info
+ puts Reline::HISTORY.to_a.to_s
+ q!
+ HISTORY
+ end
+
+ def test_history_saving_with_debug_without_prior_history
+ tmpdir = Dir.mktmpdir("test_irb_history_")
+ # Intentionally not creating the file so we test the reset counter logic
+ history_file = File.join(tmpdir, "irb_history")
+
+ write_rc <<~RUBY
+ IRB.conf[:HISTORY_FILE] = "#{history_file}"
+ RUBY
+
+ write_ruby <<~'RUBY'
+ def foo
+ end
+
+ binding.irb
+
+ foo
+ RUBY
+
+ output = run_ruby_file do
+ type "'irb session'"
+ type "next"
+ type "'irb:debug session'"
+ type "step"
+ type "irb_info"
+ type "puts Reline::HISTORY.to_a.to_s"
+ type "q!"
+ end
+
+ assert_include(output, "InputMethod: RelineInputMethod")
+ # check that in-memory history is preserved across sessions
+ assert_include output, %q(
+ ["'irb session'", "next", "'irb:debug session'", "step", "irb_info", "puts Reline::HISTORY.to_a.to_s"]
+ ).strip
+
+ assert_equal <<~HISTORY, File.read(history_file)
+ 'irb session'
+ next
+ 'irb:debug session'
+ step
+ irb_info
+ puts Reline::HISTORY.to_a.to_s
+ q!
+ HISTORY
+ ensure
+ FileUtils.rm_rf(tmpdir)
+ end
+
+ def test_history_saving_with_nested_sessions
+ write_history ""
+
+ write_ruby <<~'RUBY'
+ def foo
+ binding.irb
+ end
+
+ binding.irb
+ RUBY
+
+ run_ruby_file do
+ type "'outer session'"
+ type "foo"
+ type "'inner session'"
+ type "exit"
+ type "'outer session again'"
+ type "exit"
+ end
+
+ assert_equal <<~HISTORY, @history_file.open.read
+ 'outer session'
+ foo
+ 'inner session'
+ exit
+ 'outer session again'
+ exit
+ HISTORY
+ end
+
+ def test_nested_history_saving_from_inner_session_with_exit!
+ write_history ""
+
+ write_ruby <<~'RUBY'
+ def foo
+ binding.irb
+ end
+
+ binding.irb
+ RUBY
+
+ run_ruby_file do
+ type "'outer session'"
+ type "foo"
+ type "'inner session'"
+ type "exit!"
+ end
+
+ assert_equal <<~HISTORY, @history_file.open.read
+ 'outer session'
+ foo
+ 'inner session'
+ exit!
+ HISTORY
+ end
+
+ def test_nested_history_saving_from_outer_session_with_exit!
+ write_history ""
+
+ write_ruby <<~'RUBY'
+ def foo
+ binding.irb
+ end
+
+ binding.irb
+ RUBY
+
+ run_ruby_file do
+ type "'outer session'"
+ type "foo"
+ type "'inner session'"
+ type "exit"
+ type "'outer session again'"
+ type "exit!"
+ end
+
+ assert_equal <<~HISTORY, @history_file.open.read
+ 'outer session'
+ foo
+ 'inner session'
+ exit
+ 'outer session again'
+ exit!
+ HISTORY
+ end
+
+ def test_history_saving_with_nested_sessions_and_prior_history
+ write_history <<~HISTORY
+ old_history_1
+ old_history_2
+ old_history_3
+ HISTORY
+
+ write_ruby <<~'RUBY'
+ def foo
+ binding.irb
+ end
+
+ binding.irb
+ RUBY
+
+ run_ruby_file do
+ type "'outer session'"
+ type "foo"
+ type "'inner session'"
+ type "exit"
+ type "'outer session again'"
+ type "exit"
+ end
+
+ assert_equal <<~HISTORY, @history_file.open.read
+ old_history_1
+ old_history_2
+ old_history_3
+ 'outer session'
+ foo
+ 'inner session'
+ exit
+ 'outer session again'
+ exit
+ HISTORY
+ end
+
+ private
+
+ def write_history(history)
+ @history_file = Tempfile.new('irb_history')
+ @history_file.write(history)
+ @history_file.close
+ write_rc <<~RUBY
+ IRB.conf[:HISTORY_FILE] = "#{@history_file.path}"
+ RUBY
+ end
+ end
+end
diff --git a/test/irb/test_init.rb b/test/irb/test_init.rb
index d8c7c79263..f11d7398c8 100644
--- a/test/irb/test_init.rb
+++ b/test/irb/test_init.rb
@@ -1,21 +1,28 @@
# frozen_string_literal: false
-require "test/unit"
require "irb"
require "fileutils"
+require_relative "helper"
+
module TestIRB
- class TestInit < Test::Unit::TestCase
+ class InitTest < TestCase
def setup
# IRBRC is for RVM...
@backup_env = %w[HOME XDG_CONFIG_HOME IRBRC].each_with_object({}) do |env, hash|
hash[env] = ENV.delete(env)
end
- ENV["HOME"] = @tmpdir = Dir.mktmpdir("test_irb_init_#{$$}")
+ ENV["HOME"] = @tmpdir = File.realpath(Dir.mktmpdir("test_irb_init_#{$$}"))
+ end
+
+ def reset_rc_name_generators
+ IRB.instance_variable_set(:@existing_rc_name_generators, nil)
end
def teardown
ENV.update(@backup_env)
FileUtils.rm_rf(@tmpdir)
+ IRB.conf.delete(:SCRIPT)
+ reset_rc_name_generators
end
def test_setup_with_argv_preserves_global_argv
@@ -32,39 +39,80 @@ module TestIRB
assert_equal orig, $0
end
- def test_rc_file
+ def test_rc_files
tmpdir = @tmpdir
Dir.chdir(tmpdir) do
- IRB.conf[:RC_NAME_GENERATOR] = nil
- assert_equal(tmpdir+"/.irb#{IRB::IRBRC_EXT}", IRB.rc_file)
- assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
- IRB.conf[:RC_NAME_GENERATOR] = nil
- FileUtils.touch(tmpdir+"/.irb#{IRB::IRBRC_EXT}")
- assert_equal(tmpdir+"/.irb#{IRB::IRBRC_EXT}", IRB.rc_file)
- assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
+ home = ENV['HOME'] = "#{tmpdir}/home"
+ xdg_config_home = ENV['XDG_CONFIG_HOME'] = "#{tmpdir}/xdg"
+ reset_rc_name_generators
+ assert_empty(IRB.irbrc_files)
+ assert_equal("#{home}/.irb_history", IRB.rc_file('_history'))
+ FileUtils.mkdir_p(home)
+ FileUtils.mkdir_p("#{xdg_config_home}/irb")
+ FileUtils.mkdir_p("#{home}/.config/irb")
+ reset_rc_name_generators
+ assert_empty(IRB.irbrc_files)
+ assert_equal("#{xdg_config_home}/irb/irb_history", IRB.rc_file('_history'))
+ home_irbrc = "#{home}/.irbrc"
+ config_irbrc = "#{home}/.config/irb/irbrc"
+ xdg_config_irbrc = "#{xdg_config_home}/irb/irbrc"
+ [home_irbrc, config_irbrc, xdg_config_irbrc].each do |file|
+ FileUtils.touch(file)
+ end
+ current_dir_irbrcs = %w[.irbrc irbrc _irbrc $irbrc].map { |file| "#{tmpdir}/#{file}" }
+ current_dir_irbrcs.each { |file| FileUtils.touch(file) }
+ reset_rc_name_generators
+ assert_equal([xdg_config_irbrc, home_irbrc, *current_dir_irbrcs], IRB.irbrc_files)
+ assert_equal(xdg_config_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
+ ENV['XDG_CONFIG_HOME'] = nil
+ reset_rc_name_generators
+ assert_equal([home_irbrc, config_irbrc, *current_dir_irbrcs], IRB.irbrc_files)
+ assert_equal(home_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
+ ENV['XDG_CONFIG_HOME'] = ''
+ reset_rc_name_generators
+ assert_equal([home_irbrc, config_irbrc] + current_dir_irbrcs, IRB.irbrc_files)
+ assert_equal(home_irbrc.sub(/rc$/, '_history'), IRB.rc_file('_history'))
+ ENV['XDG_CONFIG_HOME'] = xdg_config_home
+ ENV['IRBRC'] = "#{tmpdir}/.irbrc"
+ reset_rc_name_generators
+ assert_equal([ENV['IRBRC'], xdg_config_irbrc, home_irbrc] + (current_dir_irbrcs - [ENV['IRBRC']]), IRB.irbrc_files)
+ assert_equal(ENV['IRBRC'] + '_history', IRB.rc_file('_history'))
+ ENV['IRBRC'] = ENV['HOME'] = ENV['XDG_CONFIG_HOME'] = nil
+ reset_rc_name_generators
+ assert_equal(current_dir_irbrcs, IRB.irbrc_files)
+ assert_nil(IRB.rc_file('_history'))
end
end
- def test_rc_file_in_subdir
+ def test_duplicated_rc_files
tmpdir = @tmpdir
Dir.chdir(tmpdir) do
- FileUtils.mkdir_p("#{tmpdir}/mydir")
- Dir.chdir("#{tmpdir}/mydir") do
- IRB.conf[:RC_NAME_GENERATOR] = nil
- assert_equal(tmpdir+"/.irb#{IRB::IRBRC_EXT}", IRB.rc_file)
- assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
- IRB.conf[:RC_NAME_GENERATOR] = nil
- FileUtils.touch(tmpdir+"/.irb#{IRB::IRBRC_EXT}")
- assert_equal(tmpdir+"/.irb#{IRB::IRBRC_EXT}", IRB.rc_file)
- assert_equal(tmpdir+"/.irb_history", IRB.rc_file("_history"))
+ ENV['XDG_CONFIG_HOME'] = "#{ENV['HOME']}/.config"
+ FileUtils.mkdir_p("#{ENV['XDG_CONFIG_HOME']}/irb")
+ env_irbrc = ENV['IRBRC'] = "#{tmpdir}/_irbrc"
+ xdg_config_irbrc = "#{ENV['XDG_CONFIG_HOME']}/irb/irbrc"
+ home_irbrc = "#{ENV['HOME']}/.irbrc"
+ current_dir_irbrc = "#{tmpdir}/irbrc"
+ [env_irbrc, xdg_config_irbrc, home_irbrc, current_dir_irbrc].each do |file|
+ FileUtils.touch(file)
end
+ reset_rc_name_generators
+ assert_equal([env_irbrc, xdg_config_irbrc, home_irbrc, current_dir_irbrc], IRB.irbrc_files)
end
end
- def test_recovery_sigint
+ def test_sigint_restore_default
pend "This test gets stuck on Solaris for unknown reason; contribution is welcome" if RUBY_PLATFORM =~ /solaris/
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e binding.irb;loop{Process.kill("SIGINT",$$)} -- -f --], "exit\n", //, //)
+ # IRB should restore SIGINT handler
+ status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e Signal.trap("SIGINT","DEFAULT");binding.irb;loop{Process.kill("SIGINT",$$)} -- -f --], "exit\n", //, //)
+ Process.kill("SIGKILL", status.pid) if !status.exited? && !status.stopped? && !status.signaled?
+ end
+
+ def test_sigint_restore_block
+ bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
+ # IRB should restore SIGINT handler
+ status = assert_in_out_err(bundle_exec + %w[-W0 -rirb -e x=false;Signal.trap("SIGINT"){x=true};binding.irb;loop{Process.kill("SIGINT",$$);if(x);break;end} -- -f --], "exit\n", //, //)
Process.kill("SIGKILL", status.pid) if !status.exited? && !status.stopped? && !status.signaled?
end
@@ -79,6 +127,10 @@ module TestIRB
IRB.setup(__FILE__)
refute IRB.conf[:USE_COLORIZE]
+ ENV['NO_COLOR'] = ''
+ IRB.setup(__FILE__)
+ assert IRB.conf[:USE_COLORIZE]
+
ENV['NO_COLOR'] = nil
IRB.setup(__FILE__)
assert IRB.conf[:USE_COLORIZE]
@@ -87,6 +139,124 @@ module TestIRB
IRB.conf[:USE_COLORIZE] = orig_use_colorize
end
+ def test_use_autocomplete_environment_variable
+ orig_use_autocomplete_env = ENV['IRB_USE_AUTOCOMPLETE']
+ orig_use_autocomplete_conf = IRB.conf[:USE_AUTOCOMPLETE]
+
+ ENV['IRB_USE_AUTOCOMPLETE'] = nil
+ IRB.setup(__FILE__)
+ assert IRB.conf[:USE_AUTOCOMPLETE]
+
+ ENV['IRB_USE_AUTOCOMPLETE'] = ''
+ IRB.setup(__FILE__)
+ assert IRB.conf[:USE_AUTOCOMPLETE]
+
+ ENV['IRB_USE_AUTOCOMPLETE'] = 'false'
+ IRB.setup(__FILE__)
+ refute IRB.conf[:USE_AUTOCOMPLETE]
+
+ ENV['IRB_USE_AUTOCOMPLETE'] = 'true'
+ IRB.setup(__FILE__)
+ assert IRB.conf[:USE_AUTOCOMPLETE]
+ ensure
+ ENV["IRB_USE_AUTOCOMPLETE"] = orig_use_autocomplete_env
+ IRB.conf[:USE_AUTOCOMPLETE] = orig_use_autocomplete_conf
+ end
+
+ def test_completor_environment_variable
+ orig_use_autocomplete_env = ENV['IRB_COMPLETOR']
+ orig_use_autocomplete_conf = IRB.conf[:COMPLETOR]
+
+ ENV['IRB_COMPLETOR'] = nil
+ IRB.setup(__FILE__)
+ assert_equal(:regexp, IRB.conf[:COMPLETOR])
+
+ ENV['IRB_COMPLETOR'] = 'regexp'
+ IRB.setup(__FILE__)
+ assert_equal(:regexp, IRB.conf[:COMPLETOR])
+
+ ENV['IRB_COMPLETOR'] = 'type'
+ IRB.setup(__FILE__)
+ assert_equal(:type, IRB.conf[:COMPLETOR])
+
+ ENV['IRB_COMPLETOR'] = 'regexp'
+ IRB.setup(__FILE__, argv: ['--type-completor'])
+ assert_equal :type, IRB.conf[:COMPLETOR]
+
+ ENV['IRB_COMPLETOR'] = 'type'
+ IRB.setup(__FILE__, argv: ['--regexp-completor'])
+ assert_equal :regexp, IRB.conf[:COMPLETOR]
+ ensure
+ ENV['IRB_COMPLETOR'] = orig_use_autocomplete_env
+ IRB.conf[:COMPLETOR] = orig_use_autocomplete_conf
+ end
+
+ def test_completor_setup_with_argv
+ orig_completor_conf = IRB.conf[:COMPLETOR]
+
+ # Default is :regexp
+ IRB.setup(__FILE__, argv: [])
+ assert_equal :regexp, IRB.conf[:COMPLETOR]
+
+ IRB.setup(__FILE__, argv: ['--type-completor'])
+ assert_equal :type, IRB.conf[:COMPLETOR]
+
+ IRB.setup(__FILE__, argv: ['--regexp-completor'])
+ assert_equal :regexp, IRB.conf[:COMPLETOR]
+ ensure
+ IRB.conf[:COMPLETOR] = orig_completor_conf
+ end
+
+ def test_noscript
+ argv = %w[--noscript -- -f]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_nil IRB.conf[:SCRIPT]
+ assert_equal(['-f'], argv)
+
+ argv = %w[--noscript -- a]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_nil IRB.conf[:SCRIPT]
+ assert_equal(['a'], argv)
+
+ argv = %w[--noscript a]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_nil IRB.conf[:SCRIPT]
+ assert_equal(['a'], argv)
+
+ argv = %w[--script --noscript a]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_nil IRB.conf[:SCRIPT]
+ assert_equal(['a'], argv)
+
+ argv = %w[--noscript --script a]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_equal('a', IRB.conf[:SCRIPT])
+ assert_equal([], argv)
+ end
+
+ def test_dash
+ argv = %w[-]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_equal('-', IRB.conf[:SCRIPT])
+ assert_equal([], argv)
+
+ argv = %w[-- -]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_equal('-', IRB.conf[:SCRIPT])
+ assert_equal([], argv)
+
+ argv = %w[-- - -f]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_equal('-', IRB.conf[:SCRIPT])
+ assert_equal(['-f'], argv)
+ end
+
+ def test_option_tracer
+ argv = %w[--tracer]
+ IRB.setup(eval("__FILE__"), argv: argv)
+ assert_equal(true, IRB.conf[:USE_TRACER])
+ end
+
private
def with_argv(argv)
@@ -97,4 +267,44 @@ module TestIRB
ARGV.replace(orig)
end
end
+
+ class InitIntegrationTest < IntegrationTestCase
+ def test_load_error_in_rc_file_is_warned
+ write_rc <<~'IRBRC'
+ require "file_that_does_not_exist"
+ IRBRC
+
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "'foobar'"
+ type "exit"
+ end
+
+ # IRB session should still be started
+ assert_includes output, "foobar"
+ assert_includes output, 'cannot load such file -- file_that_does_not_exist (LoadError)'
+ end
+
+ def test_normal_errors_in_rc_file_is_warned
+ write_rc <<~'IRBRC'
+ raise "I'm an error"
+ IRBRC
+
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "'foobar'"
+ type "exit"
+ end
+
+ # IRB session should still be started
+ assert_includes output, "foobar"
+ assert_includes output, 'I\'m an error (RuntimeError)'
+ end
+ end
end
diff --git a/test/irb/test_input_method.rb b/test/irb/test_input_method.rb
new file mode 100644
index 0000000000..ce317b4b32
--- /dev/null
+++ b/test/irb/test_input_method.rb
@@ -0,0 +1,173 @@
+# frozen_string_literal: false
+
+require "irb"
+require "rdoc"
+require_relative "helper"
+
+module TestIRB
+ class InputMethodTest < TestCase
+ def setup
+ @conf_backup = IRB.conf.dup
+ IRB.conf[:LC_MESSAGES] = IRB::Locale.new
+ save_encodings
+ end
+
+ def teardown
+ IRB.conf.replace(@conf_backup)
+ restore_encodings
+ # Reset Reline configuration overridden by RelineInputMethod.
+ Reline.instance_variable_set(:@core, nil)
+ end
+ end
+
+ class RelineInputMethodTest < InputMethodTest
+ def test_initialization
+ Reline.completion_proc = nil
+ Reline.dig_perfect_match_proc = nil
+ IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
+
+ assert_nil Reline.completion_append_character
+ assert_equal '', Reline.completer_quote_characters
+ assert_equal IRB::InputMethod::BASIC_WORD_BREAK_CHARACTERS, Reline.basic_word_break_characters
+ assert_not_nil Reline.completion_proc
+ assert_not_nil Reline.dig_perfect_match_proc
+ end
+
+ def test_initialization_without_use_autocomplete
+ original_show_doc_proc = Reline.dialog_proc(:show_doc)&.dialog_proc
+ empty_proc = Proc.new {}
+ Reline.add_dialog_proc(:show_doc, empty_proc)
+
+ IRB.conf[:USE_AUTOCOMPLETE] = false
+
+ IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
+
+ refute Reline.autocompletion
+ assert_equal empty_proc, Reline.dialog_proc(:show_doc).dialog_proc
+ ensure
+ Reline.add_dialog_proc(:show_doc, original_show_doc_proc, Reline::DEFAULT_DIALOG_CONTEXT)
+ end
+
+ def test_initialization_with_use_autocomplete
+ original_show_doc_proc = Reline.dialog_proc(:show_doc)&.dialog_proc
+ empty_proc = Proc.new {}
+ Reline.add_dialog_proc(:show_doc, empty_proc)
+
+ IRB.conf[:USE_AUTOCOMPLETE] = true
+
+ IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
+
+ assert Reline.autocompletion
+ assert_not_equal empty_proc, Reline.dialog_proc(:show_doc).dialog_proc
+ ensure
+ Reline.add_dialog_proc(:show_doc, original_show_doc_proc, Reline::DEFAULT_DIALOG_CONTEXT)
+ end
+
+ def test_initialization_with_use_autocomplete_but_without_rdoc
+ original_show_doc_proc = Reline.dialog_proc(:show_doc)&.dialog_proc
+ empty_proc = Proc.new {}
+ Reline.add_dialog_proc(:show_doc, empty_proc)
+
+ IRB.conf[:USE_AUTOCOMPLETE] = true
+
+ without_rdoc do
+ IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
+ end
+
+ assert Reline.autocompletion
+ # doesn't register show_doc dialog
+ assert_equal empty_proc, Reline.dialog_proc(:show_doc).dialog_proc
+ ensure
+ Reline.add_dialog_proc(:show_doc, original_show_doc_proc, Reline::DEFAULT_DIALOG_CONTEXT)
+ end
+ end
+
+ class DisplayDocumentTest < InputMethodTest
+ def setup
+ super
+ @driver = RDoc::RI::Driver.new(use_stdout: true)
+ end
+
+ def display_document(target, bind, driver = nil)
+ input_method = IRB::RelineInputMethod.new(IRB::RegexpCompletor.new)
+ input_method.instance_variable_set(:@rdoc_ri_driver, driver) if driver
+ input_method.instance_variable_set(:@completion_params, ['', target, '', bind])
+ input_method.display_document(target)
+ end
+
+ def test_perfectly_matched_namespace_triggers_document_display
+ omit unless has_rdoc_content?
+
+ out, err = capture_output do
+ display_document("String", binding, @driver)
+ end
+
+ assert_empty(err)
+
+ assert_include(out, " S\bSt\btr\bri\bin\bng\bg")
+ end
+
+ def test_perfectly_matched_multiple_namespaces_triggers_document_display
+ result = nil
+ out, err = capture_output do
+ result = display_document("{}.nil?", binding, @driver)
+ end
+
+ assert_empty(err)
+
+ # check if there're rdoc contents (e.g. CI doesn't generate them)
+ if has_rdoc_content?
+ # if there's rdoc content, we can verify by checking stdout
+ # rdoc generates control characters for formatting method names
+ assert_include(out, "P\bPr\bro\boc\bc.\b.n\bni\bil\bl?\b?") # Proc.nil?
+ assert_include(out, "H\bHa\bas\bsh\bh.\b.n\bni\bil\bl?\b?") # Hash.nil?
+ else
+ # this is a hacky way to verify the rdoc rendering code path because CI doesn't have rdoc content
+ # if there are multiple namespaces to be rendered, PerfectMatchedProc renders the result with a document
+ # which always returns the bytes rendered, even if it's 0
+ assert_equal(0, result)
+ end
+ end
+
+ def test_not_matched_namespace_triggers_nothing
+ result = nil
+ out, err = capture_output do
+ result = display_document("Stri", binding, @driver)
+ end
+
+ assert_empty(err)
+ assert_empty(out)
+ assert_nil(result)
+ end
+
+ def test_perfect_matching_stops_without_rdoc
+ result = nil
+
+ out, err = capture_output do
+ without_rdoc do
+ result = display_document("String", binding)
+ end
+ end
+
+ assert_empty(err)
+ assert_not_match(/from ruby core/, out)
+ assert_nil(result)
+ end
+
+ def test_perfect_matching_handles_nil_namespace
+ out, err = capture_output do
+ # symbol literal has `nil` doc namespace so it's a good test subject
+ assert_nil(display_document(":aiueo", binding, @driver))
+ end
+
+ assert_empty(err)
+ assert_empty(out)
+ end
+
+ private
+
+ def has_rdoc_content?
+ File.exist?(RDoc::RI::Paths::BASE)
+ end
+ end
+end
diff --git a/test/irb/test_irb.rb b/test/irb/test_irb.rb
new file mode 100644
index 0000000000..84b9ee3644
--- /dev/null
+++ b/test/irb/test_irb.rb
@@ -0,0 +1,806 @@
+# frozen_string_literal: true
+require "irb"
+
+require_relative "helper"
+
+module TestIRB
+ class InputTest < IntegrationTestCase
+ def test_symbol_aliases_are_handled_correctly
+ write_ruby <<~'RUBY'
+ class Foo
+ end
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "$ Foo"
+ type "exit!"
+ end
+
+ assert_include output, "From: #{@ruby_file.path}:1"
+ end
+
+ def test_symbol_aliases_are_handled_correctly_with_singleline_mode
+ write_rc <<~RUBY
+ IRB.conf[:USE_SINGLELINE] = true
+ RUBY
+
+ write_ruby <<~'RUBY'
+ class Foo
+ end
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "irb_info"
+ type "$ Foo"
+ type "exit!"
+ end
+
+ # Make sure it's tested in singleline mode
+ assert_include output, "InputMethod: ReadlineInputMethod"
+ assert_include output, "From: #{@ruby_file.path}:1"
+ end
+
+ def test_underscore_stores_last_result
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "1 + 1"
+ type "_ + 10"
+ type "exit!"
+ end
+
+ assert_include output, "=> 12"
+ end
+
+ def test_evaluate_with_encoding_error_without_lineno
+ if RUBY_ENGINE == 'truffleruby'
+ omit "Remove me after https://github.com/ruby/prism/issues/2129 is addressed and adopted in TruffleRuby"
+ end
+
+ if RUBY_VERSION >= "3.4."
+ omit "Now raises SyntaxError"
+ end
+
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type %q[:"\xAE"]
+ type "exit!"
+ end
+
+ assert_include output, 'invalid symbol in encoding UTF-8 :"\xAE"'
+ # EncodingError would be wrapped with ANSI escape sequences, so we assert it separately
+ assert_include output, "EncodingError"
+ end
+
+ def test_evaluate_still_emits_warning
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type %q[def foo; END {}; end]
+ type "exit!"
+ end
+
+ assert_include output, '(irb):1: warning: END in method; use at_exit'
+ end
+
+ def test_symbol_aliases_dont_affect_ruby_syntax
+ write_ruby <<~'RUBY'
+ $foo = "It's a foo"
+ @bar = "It's a bar"
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "$foo"
+ type "@bar"
+ type "exit!"
+ end
+
+ assert_include output, "=> \"It's a foo\""
+ assert_include output, "=> \"It's a bar\""
+ end
+
+ def test_empty_input_echoing_behaviour
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type ""
+ type " "
+ type "exit"
+ end
+
+ assert_not_match(/irb\(main\):001> (\r*\n)?=> nil/, output)
+ assert_match(/irb\(main\):002> (\r*\n)?=> nil/, output)
+ end
+ end
+
+ class IrbIOConfigurationTest < TestCase
+ Row = Struct.new(:content, :current_line_spaces, :new_line_spaces, :indent_level)
+
+ class MockIO_AutoIndent
+ attr_reader :calculated_indent
+
+ def initialize(*params)
+ @params = params
+ end
+
+ def auto_indent(&block)
+ @calculated_indent = block.call(*@params)
+ end
+ end
+
+ class MockIO_DynamicPrompt
+ attr_reader :prompt_list
+
+ def initialize(params, &assertion)
+ @params = params
+ end
+
+ def dynamic_prompt(&block)
+ @prompt_list = block.call(@params)
+ end
+ end
+
+ def setup
+ save_encodings
+ @irb = build_irb
+ end
+
+ def teardown
+ restore_encodings
+ end
+
+ class AutoIndentationTest < IrbIOConfigurationTest
+ def test_auto_indent
+ input_with_correct_indents = [
+ [%q(def each_top_level_statement), 0, 2],
+ [%q( initialize_input), 2, 2],
+ [%q( catch(:TERM_INPUT) do), 2, 4],
+ [%q( loop do), 4, 6],
+ [%q( begin), 6, 8],
+ [%q( prompt), 8, 8],
+ [%q( unless l = lex), 8, 10],
+ [%q( throw :TERM_INPUT if @line == ''), 10, 10],
+ [%q( else), 8, 10],
+ [%q( @line_no += l.count("\n")), 10, 10],
+ [%q( next if l == "\n"), 10, 10],
+ [%q( @line.concat l), 10, 10],
+ [%q( if @code_block_open or @ltype or @continue or @indent > 0), 10, 12],
+ [%q( next), 12, 12],
+ [%q( end), 10, 10],
+ [%q( end), 8, 8],
+ [%q( if @line != "\n"), 8, 10],
+ [%q( @line.force_encoding(@io.encoding)), 10, 10],
+ [%q( yield @line, @exp_line_no), 10, 10],
+ [%q( end), 8, 8],
+ [%q( break if @io.eof?), 8, 8],
+ [%q( @line = ''), 8, 8],
+ [%q( @exp_line_no = @line_no), 8, 8],
+ [%q( ), nil, 8],
+ [%q( @indent = 0), 8, 8],
+ [%q( rescue TerminateLineInput), 6, 8],
+ [%q( initialize_input), 8, 8],
+ [%q( prompt), 8, 8],
+ [%q( end), 6, 6],
+ [%q( end), 4, 4],
+ [%q( end), 2, 2],
+ [%q(end), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_braces_on_their_own_line
+ input_with_correct_indents = [
+ [%q(if true), 0, 2],
+ [%q( [), 2, 4],
+ [%q( ]), 2, 2],
+ [%q(end), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_multiple_braces_in_a_line
+ input_with_correct_indents = [
+ [%q([[[), 0, 6],
+ [%q( ]), 4, 4],
+ [%q( ]), 2, 2],
+ [%q(]), 0, 0],
+ [%q([<<FOO]), 0, 0],
+ [%q(hello), 0, 0],
+ [%q(FOO), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_a_closed_brace_and_not_closed_brace_in_a_line
+ input_with_correct_indents = [
+ [%q(p() {), 0, 2],
+ [%q(}), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_symbols
+ input_with_correct_indents = [
+ [%q(:a), 0, 0],
+ [%q(:A), 0, 0],
+ [%q(:+), 0, 0],
+ [%q(:@@a), 0, 0],
+ [%q(:@a), 0, 0],
+ [%q(:$a), 0, 0],
+ [%q(:def), 0, 0],
+ [%q(:`), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_incomplete_coding_magic_comment
+ input_with_correct_indents = [
+ [%q(#coding:u), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_incomplete_encoding_magic_comment
+ input_with_correct_indents = [
+ [%q(#encoding:u), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_incomplete_emacs_coding_magic_comment
+ input_with_correct_indents = [
+ [%q(# -*- coding: u), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_incomplete_vim_coding_magic_comment
+ input_with_correct_indents = [
+ [%q(# vim:set fileencoding=u), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_mixed_rescue
+ input_with_correct_indents = [
+ [%q(def m), 0, 2],
+ [%q( begin), 2, 4],
+ [%q( begin), 4, 6],
+ [%q( x = a rescue 4), 6, 6],
+ [%q( y = [(a rescue 5)]), 6, 6],
+ [%q( [x, y]), 6, 6],
+ [%q( rescue => e), 4, 6],
+ [%q( raise e rescue 8), 6, 6],
+ [%q( end), 4, 4],
+ [%q( rescue), 2, 4],
+ [%q( raise rescue 11), 4, 4],
+ [%q( end), 2, 2],
+ [%q(rescue => e), 0, 2],
+ [%q( raise e rescue 14), 2, 2],
+ [%q(end), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_oneliner_method_definition
+ input_with_correct_indents = [
+ [%q(class A), 0, 2],
+ [%q( def foo0), 2, 4],
+ [%q( 3), 4, 4],
+ [%q( end), 2, 2],
+ [%q( def foo1()), 2, 4],
+ [%q( 3), 4, 4],
+ [%q( end), 2, 2],
+ [%q( def foo2(a, b)), 2, 4],
+ [%q( a + b), 4, 4],
+ [%q( end), 2, 2],
+ [%q( def foo3 a, b), 2, 4],
+ [%q( a + b), 4, 4],
+ [%q( end), 2, 2],
+ [%q( def bar0() = 3), 2, 2],
+ [%q( def bar1(a) = a), 2, 2],
+ [%q( def bar2(a, b) = a + b), 2, 2],
+ [%q( def bar3() = :s), 2, 2],
+ [%q( def bar4() = Time.now), 2, 2],
+ [%q(end), 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents)
+ end
+
+ def test_tlambda
+ input_with_correct_indents = [
+ [%q(if true), 0, 2, 1],
+ [%q( -> {), 2, 4, 2],
+ [%q( }), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_corresponding_syntax_to_keyword_do_in_class
+ input_with_correct_indents = [
+ [%q(class C), 0, 2, 1],
+ [%q( while method_name do), 2, 4, 2],
+ [%q( 3), 4, 4, 2],
+ [%q( end), 2, 2, 1],
+ [%q( foo do), 2, 4, 2],
+ [%q( 3), 4, 4, 2],
+ [%q( end), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_corresponding_syntax_to_keyword_do
+ input_with_correct_indents = [
+ [%q(while i > 0), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(while true), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(while ->{i > 0}.call), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(while ->{true}.call), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(while i > 0 do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(while true do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(while ->{i > 0}.call do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(while ->{true}.call do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(foo do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(foo true do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(foo ->{true} do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(foo ->{i > 0} do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_corresponding_syntax_to_keyword_for
+ input_with_correct_indents = [
+ [%q(for i in [1]), 0, 2, 1],
+ [%q( puts i), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_corresponding_syntax_to_keyword_for_with_do
+ input_with_correct_indents = [
+ [%q(for i in [1] do), 0, 2, 1],
+ [%q( puts i), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_typing_incomplete_include_interpreted_as_keyword_in
+ input_with_correct_indents = [
+ [%q(module E), 0, 2, 1],
+ [%q(end), 0, 0, 0],
+ [%q(class A), 0, 2, 1],
+ [%q( in), 2, 2, 1] # scenario typing `include E`
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+
+ end
+
+ def test_bracket_corresponding_to_times
+ input_with_correct_indents = [
+ [%q(3.times { |i|), 0, 2, 1],
+ [%q( puts i), 2, 2, 1],
+ [%q(}), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_do_corresponding_to_times
+ input_with_correct_indents = [
+ [%q(3.times do |i|), 0, 2, 1],
+ [%q( puts i), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_bracket_corresponding_to_loop
+ input_with_correct_indents = [
+ ['loop {', 0, 2, 1],
+ [' 3', 2, 2, 1],
+ ['}', 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_do_corresponding_to_loop
+ input_with_correct_indents = [
+ [%q(loop do), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_embdoc_indent
+ input_with_correct_indents = [
+ [%q(=begin), 0, 0, 0],
+ [%q(a), 0, 0, 0],
+ [%q( b), 1, 1, 0],
+ [%q(=end), 0, 0, 0],
+ [%q(if 1), 0, 2, 1],
+ [%q( 2), 2, 2, 1],
+ [%q(=begin), 0, 0, 0],
+ [%q(a), 0, 0, 0],
+ [%q( b), 1, 1, 0],
+ [%q(=end), 0, 2, 1],
+ [%q( 3), 2, 2, 1],
+ [%q(end), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_heredoc_with_indent
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
+ pend 'This test needs Ripper::Lexer#scan to take broken tokens'
+ end
+ input_with_correct_indents = [
+ [%q(<<~Q+<<~R), 0, 2, 1],
+ [%q(a), 2, 2, 1],
+ [%q(a), 2, 2, 1],
+ [%q( b), 2, 2, 1],
+ [%q( b), 2, 2, 1],
+ [%q( Q), 0, 2, 1],
+ [%q( c), 4, 4, 1],
+ [%q( c), 4, 4, 1],
+ [%q( R), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_oneliner_def_in_multiple_lines
+ input_with_correct_indents = [
+ [%q(def a()=[), 0, 2, 1],
+ [%q( 1,), 2, 2, 1],
+ [%q(].), 0, 0, 0],
+ [%q(to_s), 0, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_broken_heredoc
+ input_with_correct_indents = [
+ [%q(def foo), 0, 2, 1],
+ [%q( <<~Q), 2, 4, 2],
+ [%q( Qend), 4, 4, 2],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_pasted_code_keep_base_indent_spaces
+ input_with_correct_indents = [
+ [%q( def foo), 0, 6, 1],
+ [%q( if bar), 6, 10, 2],
+ [%q( [1), 10, 12, 3],
+ [%q( ]+[["a), 10, 14, 4],
+ [%q(b" + `c), 0, 14, 4],
+ [%q(d` + /e), 0, 14, 4],
+ [%q(f/ + :"g), 0, 14, 4],
+ [%q(h".tap do), 0, 16, 5],
+ [%q( 1), 16, 16, 5],
+ [%q( end), 14, 14, 4],
+ [%q( ]), 12, 12, 3],
+ [%q( ]), 10, 10, 2],
+ [%q( end), 8, 6, 1],
+ [%q( end), 4, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_pasted_code_keep_base_indent_spaces_with_heredoc
+ input_with_correct_indents = [
+ [%q( def foo), 0, 6, 1],
+ [%q( if bar), 6, 10, 2],
+ [%q( [1), 10, 12, 3],
+ [%q( ]+[["a), 10, 14, 4],
+ [%q(b" + <<~A + <<-B + <<C), 0, 16, 5],
+ [%q( a#{), 16, 18, 6],
+ [%q( 1), 18, 18, 6],
+ [%q( }), 16, 16, 5],
+ [%q( A), 14, 16, 5],
+ [%q( b#{), 16, 18, 6],
+ [%q( 1), 18, 18, 6],
+ [%q( }), 16, 16, 5],
+ [%q( B), 14, 0, 0],
+ [%q(c#{), 0, 2, 1],
+ [%q(1), 2, 2, 1],
+ [%q(}), 0, 0, 0],
+ [%q(C), 0, 14, 4],
+ [%q( ]), 12, 12, 3],
+ [%q( ]), 10, 10, 2],
+ [%q( end), 8, 6, 1],
+ [%q( end), 4, 0, 0],
+ ]
+
+ assert_rows_with_correct_indents(input_with_correct_indents, assert_indent_level: true)
+ end
+
+ def test_heredoc_keep_indent_spaces
+ (1..4).each do |indent|
+ row = Row.new(' ' * indent, nil, [4, indent].max, 2)
+ lines = ['def foo', ' <<~Q', row.content]
+ assert_row_indenting(lines, row)
+ assert_indent_level(lines, row.indent_level)
+ end
+ end
+
+ private
+
+ def assert_row_indenting(lines, row)
+ actual_current_line_spaces = calculate_indenting(lines, false)
+
+ error_message = <<~MSG
+ Incorrect spaces calculation for line:
+
+ ```
+ > #{lines.last}
+ ```
+
+ All lines:
+
+ ```
+ #{lines.join("\n")}
+ ```
+ MSG
+ assert_equal(row.current_line_spaces, actual_current_line_spaces, error_message)
+
+ error_message = <<~MSG
+ Incorrect spaces calculation for line after the current line:
+
+ ```
+ #{lines.last}
+ >
+ ```
+
+ All lines:
+
+ ```
+ #{lines.join("\n")}
+ ```
+ MSG
+ actual_next_line_spaces = calculate_indenting(lines, true)
+ assert_equal(row.new_line_spaces, actual_next_line_spaces, error_message)
+ end
+
+ def assert_rows_with_correct_indents(rows_with_spaces, assert_indent_level: false)
+ lines = []
+ rows_with_spaces.map do |row|
+ row = Row.new(*row)
+ lines << row.content
+ assert_row_indenting(lines, row)
+
+ if assert_indent_level
+ assert_indent_level(lines, row.indent_level)
+ end
+ end
+ end
+
+ def assert_indent_level(lines, expected)
+ code = lines.map { |l| "#{l}\n" }.join # code should end with "\n"
+ _tokens, opens, _ = @irb.scanner.check_code_state(code, local_variables: [])
+ indent_level = @irb.scanner.calc_indent_level(opens)
+ error_message = "Calculated the wrong number of indent level for:\n #{lines.join("\n")}"
+ assert_equal(expected, indent_level, error_message)
+ end
+
+ def calculate_indenting(lines, add_new_line)
+ lines = lines + [""] if add_new_line
+ last_line_index = lines.length - 1
+ byte_pointer = lines.last.length
+
+ mock_io = MockIO_AutoIndent.new(lines, last_line_index, byte_pointer, add_new_line)
+ @irb.context.auto_indent_mode = true
+ @irb.context.io = mock_io
+ @irb.configure_io
+
+ mock_io.calculated_indent
+ end
+ end
+
+ class DynamicPromptTest < IrbIOConfigurationTest
+ def test_endless_range_at_end_of_line
+ input_with_prompt = [
+ ['001:0: :> ', %q(a = 3..)],
+ ['002:0: :> ', %q()],
+ ]
+
+ assert_dynamic_prompt(input_with_prompt)
+ end
+
+ def test_heredoc_with_embexpr
+ input_with_prompt = [
+ ['001:0:":* ', %q(<<A+%W[#{<<B)],
+ ['002:0:":* ', %q(#{<<C+%W[)],
+ ['003:0:":* ', %q(a)],
+ ['004:2:]:* ', %q(C)],
+ ['005:2:]:* ', %q(a)],
+ ['006:0:":* ', %q(]})],
+ ['007:0:":* ', %q(})],
+ ['008:0:":* ', %q(A)],
+ ['009:2:]:* ', %q(B)],
+ ['010:1:]:* ', %q(})],
+ ['011:0: :> ', %q(])],
+ ['012:0: :> ', %q()],
+ ]
+
+ assert_dynamic_prompt(input_with_prompt)
+ end
+
+ def test_heredoc_prompt_with_quotes
+ input_with_prompt = [
+ ["001:1:':* ", %q(<<~'A')],
+ ["002:1:':* ", %q(#{foobar})],
+ ["003:0: :> ", %q(A)],
+ ["004:1:`:* ", %q(<<~`A`)],
+ ["005:1:`:* ", %q(whoami)],
+ ["006:0: :> ", %q(A)],
+ ['007:1:":* ', %q(<<~"A")],
+ ['008:1:":* ', %q(foobar)],
+ ['009:0: :> ', %q(A)],
+ ]
+
+ assert_dynamic_prompt(input_with_prompt)
+ end
+
+ def test_backtick_method
+ input_with_prompt = [
+ ['001:0: :> ', %q(self.`(arg))],
+ ['002:0: :> ', %q()],
+ ['003:0: :> ', %q(def `(); end)],
+ ['004:0: :> ', %q()],
+ ]
+
+ assert_dynamic_prompt(input_with_prompt)
+ end
+
+ def test_dynamic_prompt
+ input_with_prompt = [
+ ['001:1: :* ', %q(def hoge)],
+ ['002:1: :* ', %q( 3)],
+ ['003:0: :> ', %q(end)],
+ ]
+
+ assert_dynamic_prompt(input_with_prompt)
+ end
+
+ def test_dynamic_prompt_with_double_newline_breaking_code
+ input_with_prompt = [
+ ['001:1: :* ', %q(if true)],
+ ['002:2: :* ', %q(%)],
+ ['003:1: :* ', %q(;end)],
+ ['004:1: :* ', %q(;hello)],
+ ['005:0: :> ', %q(end)],
+ ]
+
+ assert_dynamic_prompt(input_with_prompt)
+ end
+
+ def test_dynamic_prompt_with_multiline_literal
+ input_with_prompt = [
+ ['001:1: :* ', %q(if true)],
+ ['002:2:]:* ', %q( %w[)],
+ ['003:2:]:* ', %q( a)],
+ ['004:1: :* ', %q( ])],
+ ['005:1: :* ', %q( b)],
+ ['006:2:]:* ', %q( %w[)],
+ ['007:2:]:* ', %q( c)],
+ ['008:1: :* ', %q( ])],
+ ['009:0: :> ', %q(end)],
+ ]
+
+ assert_dynamic_prompt(input_with_prompt)
+ end
+
+ def test_dynamic_prompt_with_blank_line
+ input_with_prompt = [
+ ['001:1:]:* ', %q(%w[)],
+ ['002:1:]:* ', %q()],
+ ['003:0: :> ', %q(])],
+ ]
+
+ assert_dynamic_prompt(input_with_prompt)
+ end
+
+ def assert_dynamic_prompt(input_with_prompt)
+ expected_prompt_list, lines = input_with_prompt.transpose
+ def @irb.generate_prompt(opens, continue, line_offset)
+ ltype = @scanner.ltype_from_open_tokens(opens)
+ indent = @scanner.calc_indent_level(opens)
+ continue = opens.any? || continue
+ line_no = @line_no + line_offset
+ '%03d:%01d:%1s:%s ' % [line_no, indent, ltype, continue ? '*' : '>']
+ end
+ io = MockIO_DynamicPrompt.new(lines)
+ @irb.context.io = io
+ @irb.configure_io
+
+ error_message = <<~EOM
+ Expected dynamic prompt:
+ #{expected_prompt_list.join("\n")}
+
+ Actual dynamic prompt:
+ #{io.prompt_list.join("\n")}
+ EOM
+ assert_equal(expected_prompt_list, io.prompt_list, error_message)
+ end
+ end
+
+ private
+
+ def build_binding
+ Object.new.instance_eval { binding }
+ end
+
+ def build_irb
+ IRB.init_config(nil)
+ workspace = IRB::WorkSpace.new(build_binding)
+
+ IRB.conf[:VERBOSE] = false
+ IRB::Irb.new(workspace, TestInputMethod.new)
+ end
+ end
+end
diff --git a/test/irb/test_locale.rb b/test/irb/test_locale.rb
new file mode 100644
index 0000000000..930a38834c
--- /dev/null
+++ b/test/irb/test_locale.rb
@@ -0,0 +1,118 @@
+require "irb"
+require "stringio"
+
+require_relative "helper"
+
+module TestIRB
+ class LocaleTestCase < TestCase
+ def test_initialize_with_en
+ locale = IRB::Locale.new("en_US.UTF-8")
+
+ assert_equal("en", locale.lang)
+ assert_equal("US", locale.territory)
+ assert_equal("UTF-8", locale.encoding.name)
+ assert_equal(nil, locale.modifier)
+ end
+
+ def test_initialize_with_ja
+ locale = IRB::Locale.new("ja_JP.UTF-8")
+
+ assert_equal("ja", locale.lang)
+ assert_equal("JP", locale.territory)
+ assert_equal("UTF-8", locale.encoding.name)
+ assert_equal(nil, locale.modifier)
+ end
+
+ def test_initialize_with_legacy_ja_encoding_ujis
+ original_stderr = $stderr
+ $stderr = StringIO.new
+
+ locale = IRB::Locale.new("ja_JP.ujis")
+
+ assert_equal("ja", locale.lang)
+ assert_equal("JP", locale.territory)
+ assert_equal(Encoding::EUC_JP, locale.encoding)
+ assert_equal(nil, locale.modifier)
+
+ assert_include $stderr.string, "ja_JP.ujis is obsolete. use ja_JP.EUC-JP"
+ ensure
+ $stderr = original_stderr
+ end
+
+ def test_initialize_with_legacy_ja_encoding_euc
+ original_stderr = $stderr
+ $stderr = StringIO.new
+
+ locale = IRB::Locale.new("ja_JP.euc")
+
+ assert_equal("ja", locale.lang)
+ assert_equal("JP", locale.territory)
+ assert_equal(Encoding::EUC_JP, locale.encoding)
+ assert_equal(nil, locale.modifier)
+
+ assert_include $stderr.string, "ja_JP.euc is obsolete. use ja_JP.EUC-JP"
+ ensure
+ $stderr = original_stderr
+ end
+
+ %w(IRB_LANG LC_MESSAGES LC_ALL LANG).each do |env_var|
+ define_method "test_initialize_with_#{env_var.downcase}" do
+ original_values = {
+ "IRB_LANG" => ENV["IRB_LANG"],
+ "LC_MESSAGES" => ENV["LC_MESSAGES"],
+ "LC_ALL" => ENV["LC_ALL"],
+ "LANG" => ENV["LANG"],
+ }
+
+ ENV["IRB_LANG"] = ENV["LC_MESSAGES"] = ENV["LC_ALL"] = ENV["LANG"] = nil
+ ENV[env_var] = "zh_TW.UTF-8"
+
+ locale = IRB::Locale.new
+
+ assert_equal("zh", locale.lang)
+ assert_equal("TW", locale.territory)
+ assert_equal("UTF-8", locale.encoding.name)
+ assert_equal(nil, locale.modifier)
+ ensure
+ original_values.each do |key, value|
+ ENV[key] = value
+ end
+ end
+ end
+
+ def test_load
+ # reset Locale's internal cache
+ IRB::Locale.class_variable_set(:@@loaded, [])
+ # Because error.rb files define the same class, loading them causes method redefinition warnings.
+ original_verbose = $VERBOSE
+ $VERBOSE = nil
+
+ jp_local = IRB::Locale.new("ja_JP.UTF-8")
+ jp_local.load("irb/error.rb")
+ msg = IRB::CantReturnToNormalMode.new.message
+ assert_equal("Normalモードに戻れません.", msg)
+
+ # reset Locale's internal cache
+ IRB::Locale.class_variable_set(:@@loaded, [])
+
+ en_local = IRB::Locale.new("en_US.UTF-8")
+ en_local.load("irb/error.rb")
+ msg = IRB::CantReturnToNormalMode.new.message
+ assert_equal("Can't return to normal mode.", msg)
+ ensure
+ # before turning warnings back on, load the error.rb file again to avoid warnings in other tests
+ IRB::Locale.new.load("irb/error.rb")
+ $VERBOSE = original_verbose
+ end
+
+ def test_find
+ jp_local = IRB::Locale.new("ja_JP.UTF-8")
+ path = jp_local.find("irb/error.rb")
+ assert_include(path, "/lib/irb/lc/ja/error.rb")
+
+ en_local = IRB::Locale.new("en_US.UTF-8")
+ path = en_local.find("irb/error.rb")
+ assert_include(path, "/lib/irb/lc/error.rb")
+ end
+ end
+end
diff --git a/test/irb/test_nesting_parser.rb b/test/irb/test_nesting_parser.rb
new file mode 100644
index 0000000000..2482d40081
--- /dev/null
+++ b/test/irb/test_nesting_parser.rb
@@ -0,0 +1,341 @@
+# frozen_string_literal: false
+require 'irb'
+
+require_relative "helper"
+
+module TestIRB
+ class NestingParserTest < TestCase
+ def setup
+ save_encodings
+ end
+
+ def teardown
+ restore_encodings
+ end
+
+ def parse_by_line(code)
+ IRB::NestingParser.parse_by_line(IRB::RubyLex.ripper_lex_without_warning(code))
+ end
+
+ def test_open_tokens
+ code = <<~'EOS'
+ class A
+ def f
+ if true
+ tap do
+ {
+ x: "
+ #{p(1, 2, 3
+ EOS
+ opens = IRB::NestingParser.open_tokens(IRB::RubyLex.ripper_lex_without_warning(code))
+ assert_equal(%w[class def if do { " #{ (], opens.map(&:tok))
+ end
+
+ def test_parse_by_line
+ code = <<~EOS
+ (((((1+2
+ ).to_s())).tap do (((
+ EOS
+ _tokens, prev_opens, next_opens, min_depth = parse_by_line(code).last
+ assert_equal(%w[( ( ( ( (], prev_opens.map(&:tok))
+ assert_equal(%w[( ( do ( ( (], next_opens.map(&:tok))
+ assert_equal(2, min_depth)
+ end
+
+ def test_ruby_syntax
+ code = <<~'EOS'
+ class A
+ 1 if 2
+ 1 while 2
+ 1 until 2
+ 1 unless 2
+ 1 rescue 2
+ begin; rescue; ensure; end
+ tap do; rescue; ensure; end
+ class B; end
+ module C; end
+ def f; end
+ def `; end
+ def f() = 1
+ %(); %w[]; %q(); %r{}; %i[]
+ "#{1}"; ''; /#{1}/; `#{1}`
+ :sym; :"sym"; :+; :`; :if
+ [1, 2, 3]
+ { x: 1, y: 2 }
+ (a, (*b, c), d), e = 1, 2, 3
+ ->(a){}; ->(a) do end
+ -> a = -> b = :do do end do end
+ if 1; elsif 2; else; end
+ unless 1; end
+ while 1; end
+ until 1; end
+ for i in j; end
+ case 1; when 2; end
+ puts(1, 2, 3)
+ loop{|i|}
+ loop do |i| end
+ end
+ EOS
+ line_results = parse_by_line(code)
+ assert_equal(code.lines.size, line_results.size)
+ class_open, *inner_line_results, class_close = line_results
+ assert_equal(['class'], class_open[2].map(&:tok))
+ inner_line_results.each {|result| assert_equal(['class'], result[2].map(&:tok)) }
+ assert_equal([], class_close[2].map(&:tok))
+ end
+
+ def test_multiline_string
+ code = <<~EOS
+ "
+ aaa
+ bbb
+ "
+ <<A
+ aaa
+ bbb
+ A
+ EOS
+ line_results = parse_by_line(code)
+ assert_equal(code.lines.size, line_results.size)
+ string_content_line, string_opens = line_results[1]
+ assert_equal("\naaa\nbbb\n", string_content_line.first.first.tok)
+ assert_equal("aaa\n", string_content_line.first.last)
+ assert_equal(['"'], string_opens.map(&:tok))
+ heredoc_content_line, heredoc_opens = line_results[6]
+ assert_equal("aaa\nbbb\n", heredoc_content_line.first.first.tok)
+ assert_equal("bbb\n", heredoc_content_line.first.last)
+ assert_equal(['<<A'], heredoc_opens.map(&:tok))
+ _line, _prev_opens, next_opens, _min_depth = line_results.last
+ assert_equal([], next_opens)
+ end
+
+ def test_backslash_continued_nested_symbol
+ code = <<~'EOS'
+ x = <<A, :\
+ heredoc #{
+ here
+ }
+ A
+ =begin
+ embdoc
+ =end
+ # comment
+
+ if # this is symbol :if
+ while
+ EOS
+ line_results = parse_by_line(code)
+ assert_equal(%w[: <<A #{], line_results[2][2].map(&:tok))
+ assert_equal(%w[while], line_results.last[2].map(&:tok))
+ end
+
+ def test_oneliner_def
+ code = <<~EOC
+ if true
+ # normal oneliner def
+ def f = 1
+ def f() = 1
+ def f(*) = 1
+ # keyword, backtick, op
+ def * = 1
+ def ` = 1
+ def if = 1
+ def *() = 1
+ def `() = 1
+ def if() = 1
+ # oneliner def with receiver
+ def a.* = 1
+ def $a.* = 1
+ def @a.` = 1
+ def A.` = 1
+ def ((a;b;c)).*() = 1
+ def ((a;b;c)).if() = 1
+ def ((a;b;c)).end() = 1
+ # multiline oneliner def
+ def f =
+ 1
+ def f()
+ =
+ 1
+ # oneliner def with comment and embdoc
+ def # comment
+ =begin
+ embdoc
+ =end
+ ((a;b;c))
+ . # comment
+ =begin
+ embdoc
+ =end
+ f (*) # comment
+ =begin
+ embdoc
+ =end
+ =
+ 1
+ # nested oneliner def
+ def f(x = def f() = 1) = def f() = 1
+ EOC
+ _tokens, _prev_opens, next_opens, min_depth = parse_by_line(code).last
+ assert_equal(['if'], next_opens.map(&:tok))
+ assert_equal(1, min_depth)
+ end
+
+ def test_heredoc_embexpr
+ code = <<~'EOS'
+ <<A+<<B+<<C+(<<D+(<<E)
+ #{
+ <<~F+"#{<<~G}
+ #{
+ here
+ }
+ F
+ G
+ "
+ }
+ A
+ B
+ C
+ D
+ E
+ )
+ EOS
+ line_results = parse_by_line(code)
+ last_opens = line_results.last[-2]
+ assert_equal([], last_opens)
+ _tokens, _prev_opens, next_opens, _min_depth = line_results[4]
+ assert_equal(%w[( <<E <<D <<C <<B <<A #{ " <<~G <<~F #{], next_opens.map(&:tok))
+ end
+
+ def test_for_in
+ code = <<~EOS
+ for i in j
+ here
+ end
+ for i in j do
+ here
+ end
+ for i in
+ j do
+ here
+ end
+ for
+ # comment
+ i in j do
+ here
+ end
+ for (a;b;c).d in (a;b;c) do
+ here
+ end
+ for i in :in + :do do
+ here
+ end
+ for i in -> do end do
+ here
+ end
+ EOS
+ line_results = parse_by_line(code).select { |tokens,| tokens.map(&:last).include?('here') }
+ assert_equal(7, line_results.size)
+ line_results.each do |_tokens, _prev_opens, next_opens, _min_depth|
+ assert_equal(['for'], next_opens.map(&:tok))
+ end
+ end
+
+ def test_while_until
+ base_code = <<~'EOS'
+ while_or_until true
+ here
+ end
+ while_or_until a < c
+ here
+ end
+ while_or_until true do
+ here
+ end
+ while_or_until
+ # comment
+ (a + b) <
+ # comment
+ c do
+ here
+ end
+ while_or_until :\
+ do do
+ here
+ end
+ while_or_until def do; end == :do do
+ here
+ end
+ while_or_until -> do end do
+ here
+ end
+ EOS
+ %w[while until].each do |keyword|
+ code = base_code.gsub('while_or_until', keyword)
+ line_results = parse_by_line(code).select { |tokens,| tokens.map(&:last).include?('here') }
+ assert_equal(7, line_results.size)
+ line_results.each do |_tokens, _prev_opens, next_opens, _min_depth|
+ assert_equal([keyword], next_opens.map(&:tok) )
+ end
+ end
+ end
+
+ def test_undef_alias
+ codes = [
+ 'undef foo',
+ 'alias foo bar',
+ 'undef !',
+ 'alias + -',
+ 'alias $a $b',
+ 'undef do',
+ 'alias do do',
+ 'undef :do',
+ 'alias :do :do',
+ 'undef :"#{alias do do}"',
+ 'alias :"#{undef do}" do',
+ 'alias do :"#{undef do}"'
+ ]
+ code_with_comment = <<~EOS
+ undef #
+ #
+ do #
+ alias #
+ #
+ do #
+ #
+ do #
+ EOS
+ code_with_heredoc = <<~EOS
+ <<~A; alias
+ A
+ :"#{<<~A}"
+ A
+ do
+ EOS
+ [*codes, code_with_comment, code_with_heredoc].each do |code|
+ opens = IRB::NestingParser.open_tokens(IRB::RubyLex.ripper_lex_without_warning('(' + code + "\nif"))
+ assert_equal(%w[( if], opens.map(&:tok))
+ end
+ end
+
+ def test_case_in
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
+ pend 'This test requires ruby version that supports case-in syntax'
+ end
+ code = <<~EOS
+ case 1
+ in 1
+ here
+ in
+ 2
+ here
+ end
+ EOS
+ line_results = parse_by_line(code).select { |tokens,| tokens.map(&:last).include?('here') }
+ assert_equal(2, line_results.size)
+ line_results.each do |_tokens, _prev_opens, next_opens, _min_depth|
+ assert_equal(['in'], next_opens.map(&:tok))
+ end
+ end
+ end
+end
diff --git a/test/irb/test_option.rb b/test/irb/test_option.rb
index aa634c02a2..fec31f384f 100644
--- a/test/irb/test_option.rb
+++ b/test/irb/test_option.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: false
-require 'test/unit'
+require_relative "helper"
module TestIRB
- class TestOption < Test::Unit::TestCase
+ class OptionTest < TestCase
def test_end_of_option
bug4117 = '[ruby-core:33574]'
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
diff --git a/test/irb/test_raise_exception.rb b/test/irb/test_raise_exception.rb
new file mode 100644
index 0000000000..44a5ae87e1
--- /dev/null
+++ b/test/irb/test_raise_exception.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: false
+require "tmpdir"
+
+require_relative "helper"
+
+module TestIRB
+ class RaiseExceptionTest < TestCase
+ def test_raise_exception_with_nil_backtrace
+ bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
+ assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, /#<Exception: foo>/, [])
+ raise Exception.new("foo").tap {|e| def e.backtrace; nil; end }
+IRB
+ end
+
+ def test_raise_exception_with_message_exception
+ bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
+ expected = /#<Exception: foo>\nbacktraces are hidden because bar was raised when processing them/
+ assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, expected, [])
+ e = Exception.new("foo")
+ def e.message; raise 'bar'; end
+ raise e
+IRB
+ end
+
+ def test_raise_exception_with_message_inspect_exception
+ bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
+ expected = /Uninspectable exception occurred/
+ assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, expected, [])
+ e = Exception.new("foo")
+ def e.message; raise; end
+ def e.inspect; raise; end
+ raise e
+IRB
+ end
+
+ def test_raise_exception_with_invalid_byte_sequence
+ pend if RUBY_ENGINE == 'truffleruby' || /mswin|mingw/ =~ RUBY_PLATFORM
+ bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
+ assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<~IRB, /A\\xF3B \(StandardError\)/, [])
+ raise StandardError, "A\\xf3B"
+ IRB
+ end
+
+ def test_raise_exception_with_different_encoding_containing_invalid_byte_sequence
+ backup_home = ENV["HOME"]
+ Dir.mktmpdir("test_irb_raise_no_backtrace_exception_#{$$}") do |tmpdir|
+ ENV["HOME"] = tmpdir
+
+ bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
+ File.open("#{tmpdir}/euc.rb", 'w') do |f|
+ f.write(<<~EOF)
+ # encoding: euc-jp
+
+ def raise_euc_with_invalid_byte_sequence
+ raise "\xA4\xA2\\xFF"
+ end
+ EOF
+ end
+ env = {}
+ %w(LC_MESSAGES LC_ALL LC_CTYPE LANG).each {|n| env[n] = "ja_JP.UTF-8" }
+ # TruffleRuby warns when the locale does not exist
+ env['TRUFFLERUBYOPT'] = "#{ENV['TRUFFLERUBYOPT']} --log.level=SEVERE" if RUBY_ENGINE == 'truffleruby'
+ args = [env] + bundle_exec + %W[-rirb -C #{tmpdir} -W0 -e IRB.start(__FILE__) -- -f --]
+ error = /raise_euc_with_invalid_byte_sequence': あ\\xFF \(RuntimeError\)/
+ assert_in_out_err(args, <<~IRB, error, [], encoding: "UTF-8")
+ require_relative 'euc'
+ raise_euc_with_invalid_byte_sequence
+ IRB
+ end
+ ensure
+ ENV["HOME"] = backup_home
+ end
+ end
+end
diff --git a/test/irb/test_raise_no_backtrace_exception.rb b/test/irb/test_raise_no_backtrace_exception.rb
deleted file mode 100644
index 530adc0cbf..0000000000
--- a/test/irb/test_raise_no_backtrace_exception.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-
-module TestIRB
- class TestRaiseNoBacktraceException < Test::Unit::TestCase
- def test_raise_exception
- pend if RUBY_ENGINE == 'truffleruby'
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<-IRB, /Exception: foo/, [])
- e = Exception.new("foo")
- puts e.inspect
- def e.backtrace; nil; end
- raise e
-IRB
- end
-
- def test_raise_exception_with_invalid_byte_sequence
- pend if RUBY_ENGINE == 'truffleruby' || /mswin|mingw/ =~ RUBY_PLATFORM
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- assert_in_out_err(bundle_exec + %w[-rirb -W0 -e IRB.start(__FILE__) -- -f --], <<~IRB, /A\\xF3B \(StandardError\)/, [])
- raise StandardError, "A\\xf3B"
- IRB
- end
-
- def test_raise_exception_with_different_encoding_containing_invalid_byte_sequence
- pend if RUBY_ENGINE == 'truffleruby'
- backup_home = ENV["HOME"]
- Dir.mktmpdir("test_irb_raise_no_backtrace_exception_#{$$}") do |tmpdir|
- ENV["HOME"] = tmpdir
-
- bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
- File.open("#{tmpdir}/euc.rb", 'w') do |f|
- f.write(<<~EOF)
- # encoding: euc-jp
-
- def raise_euc_with_invalid_byte_sequence
- raise "\xA4\xA2\\xFF"
- end
- EOF
- end
- env = {}
- %w(LC_MESSAGES LC_ALL LC_CTYPE LANG).each {|n| env[n] = "ja_JP.UTF-8" }
- args = [env] + bundle_exec + %W[-rirb -C #{tmpdir} -W0 -e IRB.start(__FILE__) -- -f --]
- error = /`raise_euc_with_invalid_byte_sequence': あ\\xFF \(RuntimeError\)/
- assert_in_out_err(args, <<~IRB, error, [], encoding: "UTF-8")
- require_relative 'euc'
- raise_euc_with_invalid_byte_sequence
- IRB
- end
- ensure
- ENV["HOME"] = backup_home
- end
- end
-end
diff --git a/test/irb/test_ruby_lex.rb b/test/irb/test_ruby_lex.rb
index 47435d675e..4e406a8ce0 100644
--- a/test/irb/test_ruby_lex.rb
+++ b/test/irb/test_ruby_lex.rb
@@ -1,601 +1,89 @@
-$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
-require 'irb/ruby-lex'
-require 'test/unit'
-require 'ostruct'
+# frozen_string_literal: true
+require "irb"
-module TestIRB
- class TestRubyLex < Test::Unit::TestCase
- Row = Struct.new(:content, :current_line_spaces, :new_line_spaces, :nesting_level)
-
- class MockIO_AutoIndent
- def initialize(params, &assertion)
- @params = params
- @assertion = assertion
- end
-
- def auto_indent(&block)
- result = block.call(*@params)
- @assertion.call(result)
- end
- end
-
- def assert_indenting(lines, correct_space_count, add_new_line)
- lines = lines + [""] if add_new_line
- last_line_index = lines.length - 1
- byte_pointer = lines.last.length
-
- ruby_lex = RubyLex.new()
- io = MockIO_AutoIndent.new([lines, last_line_index, byte_pointer, add_new_line]) do |auto_indent|
- error_message = "Calculated the wrong number of spaces for:\n #{lines.join("\n")}"
- assert_equal(correct_space_count, auto_indent, error_message)
- end
- ruby_lex.set_input(io)
- context = OpenStruct.new(auto_indent_mode: true)
- ruby_lex.set_auto_indent(context)
- end
-
- def assert_nesting_level(lines, expected)
- ruby_lex = RubyLex.new()
- io = proc{ lines.join("\n") }
- ruby_lex.set_input(io, io)
- ruby_lex.lex
- error_message = "Calculated the wrong number of nesting level for:\n #{lines.join("\n")}"
- assert_equal(expected, ruby_lex.instance_variable_get(:@indent), error_message)
- end
-
- def test_auto_indent
- input_with_correct_indents = [
- Row.new(%q(def each_top_level_statement), nil, 2),
- Row.new(%q( initialize_input), nil, 2),
- Row.new(%q( catch(:TERM_INPUT) do), nil, 4),
- Row.new(%q( loop do), nil, 6),
- Row.new(%q( begin), nil, 8),
- Row.new(%q( prompt), nil, 8),
- Row.new(%q( unless l = lex), nil, 10),
- Row.new(%q( throw :TERM_INPUT if @line == ''), nil, 10),
- Row.new(%q( else), 8, 10),
- Row.new(%q( @line_no += l.count("\n")), nil, 10),
- Row.new(%q( next if l == "\n"), nil, 10),
- Row.new(%q( @line.concat l), nil, 10),
- Row.new(%q( if @code_block_open or @ltype or @continue or @indent > 0), nil, 12),
- Row.new(%q( next), nil, 12),
- Row.new(%q( end), 10, 10),
- Row.new(%q( end), 8, 8),
- Row.new(%q( if @line != "\n"), nil, 10),
- Row.new(%q( @line.force_encoding(@io.encoding)), nil, 10),
- Row.new(%q( yield @line, @exp_line_no), nil, 10),
- Row.new(%q( end), 8, 8),
- Row.new(%q( break if @io.eof?), nil, 8),
- Row.new(%q( @line = ''), nil, 8),
- Row.new(%q( @exp_line_no = @line_no), nil, 8),
- Row.new(%q( ), nil, 8),
- Row.new(%q( @indent = 0), nil, 8),
- Row.new(%q( rescue TerminateLineInput), 6, 8),
- Row.new(%q( initialize_input), nil, 8),
- Row.new(%q( prompt), nil, 8),
- Row.new(%q( end), 6, 6),
- Row.new(%q( end), 4, 4),
- Row.new(%q( end), 2, 2),
- Row.new(%q(end), 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_braces_on_their_own_line
- input_with_correct_indents = [
- Row.new(%q(if true), nil, 2),
- Row.new(%q( [), nil, 4),
- Row.new(%q( ]), 2, 2),
- Row.new(%q(end), 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_multiple_braces_in_a_line
- input_with_correct_indents = [
- Row.new(%q([[[), nil, 6),
- Row.new(%q( ]), 4, 4),
- Row.new(%q( ]), 2, 2),
- Row.new(%q(]), 0, 0),
- Row.new(%q([<<FOO]), 0, 0),
- Row.new(%q(hello), 0, 0),
- Row.new(%q(FOO), nil, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_a_closed_brace_and_not_closed_brace_in_a_line
- input_with_correct_indents = [
- Row.new(%q(p() {), nil, 2),
- Row.new(%q(}), 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_symbols
- input_with_correct_indents = [
- Row.new(%q(:a), nil, 0),
- Row.new(%q(:A), nil, 0),
- Row.new(%q(:+), nil, 0),
- Row.new(%q(:@@a), nil, 0),
- Row.new(%q(:@a), nil, 0),
- Row.new(%q(:$a), nil, 0),
- Row.new(%q(:def), nil, 0),
- Row.new(%q(:`), nil, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_endless_range_at_end_of_line
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.6.0')
- pend 'Endless range is available in 2.6.0 or later'
- end
- input_with_prompt = [
- PromptRow.new('001:0: :> ', %q(a = 3..)),
- PromptRow.new('002:0: :* ', %q()),
- ]
-
- lines = input_with_prompt.map(&:content)
- expected_prompt_list = input_with_prompt.map(&:prompt)
- assert_dynamic_prompt(lines, expected_prompt_list)
- end
-
- def test_incomplete_coding_magic_comment
- input_with_correct_indents = [
- Row.new(%q(#coding:u), nil, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_incomplete_encoding_magic_comment
- input_with_correct_indents = [
- Row.new(%q(#encoding:u), nil, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_incomplete_emacs_coding_magic_comment
- input_with_correct_indents = [
- Row.new(%q(# -*- coding: u), nil, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_incomplete_vim_coding_magic_comment
- input_with_correct_indents = [
- Row.new(%q(# vim:set fileencoding=u), nil, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_mixed_rescue
- input_with_correct_indents = [
- Row.new(%q(def m), nil, 2),
- Row.new(%q( begin), nil, 4),
- Row.new(%q( begin), nil, 6),
- Row.new(%q( x = a rescue 4), nil, 6),
- Row.new(%q( y = [(a rescue 5)]), nil, 6),
- Row.new(%q( [x, y]), nil, 6),
- Row.new(%q( rescue => e), 4, 6),
- Row.new(%q( raise e rescue 8), nil, 6),
- Row.new(%q( end), 4, 4),
- Row.new(%q( rescue), 2, 4),
- Row.new(%q( raise rescue 11), nil, 4),
- Row.new(%q( end), 2, 2),
- Row.new(%q(rescue => e), 0, 2),
- Row.new(%q( raise e rescue 14), nil, 2),
- Row.new(%q(end), 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_oneliner_method_definition
- input_with_correct_indents = [
- Row.new(%q(class A), nil, 2),
- Row.new(%q( def foo0), nil, 4),
- Row.new(%q( 3), nil, 4),
- Row.new(%q( end), 2, 2),
- Row.new(%q( def foo1()), nil, 4),
- Row.new(%q( 3), nil, 4),
- Row.new(%q( end), 2, 2),
- Row.new(%q( def foo2(a, b)), nil, 4),
- Row.new(%q( a + b), nil, 4),
- Row.new(%q( end), 2, 2),
- Row.new(%q( def foo3 a, b), nil, 4),
- Row.new(%q( a + b), nil, 4),
- Row.new(%q( end), 2, 2),
- Row.new(%q( def bar0() = 3), nil, 2),
- Row.new(%q( def bar1(a) = a), nil, 2),
- Row.new(%q( def bar2(a, b) = a + b), nil, 2),
- Row.new(%q( def bar3() = :s), nil, 2),
- Row.new(%q( def bar4() = Time.now), nil, 2),
- Row.new(%q(end), 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- end
- end
-
- def test_tlambda
- input_with_correct_indents = [
- Row.new(%q(if true), nil, 2, 1),
- Row.new(%q( -> {), nil, 4, 2),
- Row.new(%q( }), 2, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
- end
-
- def test_corresponding_syntax_to_keyword_do_in_class
- input_with_correct_indents = [
- Row.new(%q(class C), nil, 2, 1),
- Row.new(%q( while method_name do), nil, 4, 2),
- Row.new(%q( 3), nil, 4, 2),
- Row.new(%q( end), 2, 2, 1),
- Row.new(%q( foo do), nil, 4, 2),
- Row.new(%q( 3), nil, 4, 2),
- Row.new(%q( end), 2, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
- end
-
- def test_corresponding_syntax_to_keyword_do
- input_with_correct_indents = [
- Row.new(%q(while i > 0), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(while true), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(while ->{i > 0}.call), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(while ->{true}.call), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(while i > 0 do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(while true do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(while ->{i > 0}.call do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(while ->{true}.call do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(foo do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(foo true do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(foo ->{true} do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(foo ->{i > 0} do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
- end
-
- def test_corresponding_syntax_to_keyword_for
- input_with_correct_indents = [
- Row.new(%q(for i in [1]), nil, 2, 1),
- Row.new(%q( puts i), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- ]
+require_relative "helper"
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
+module TestIRB
+ class RubyLexTest < TestCase
+ def setup
+ save_encodings
end
- def test_corresponding_syntax_to_keyword_for_with_do
- input_with_correct_indents = [
- Row.new(%q(for i in [1] do), nil, 2, 1),
- Row.new(%q( puts i), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
+ def teardown
+ restore_encodings
end
- def test_corresponding_syntax_to_keyword_in
- input_with_correct_indents = [
- Row.new(%q(module E), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- Row.new(%q(class A), nil, 2, 1),
- Row.new(%q( in), nil, 4, 1)
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
+ def test_interpolate_token_with_heredoc_and_unclosed_embexpr
+ code = <<~'EOC'
+ ①+<<A-②
+ #{③*<<B/④
+ #{⑤&<<C|⑥
+ EOC
+ ripper_tokens = Ripper.tokenize(code)
+ rubylex_tokens = IRB::RubyLex.ripper_lex_without_warning(code)
+ # Assert no missing part
+ assert_equal(code, rubylex_tokens.map(&:tok).join)
+ # Assert ripper tokens are not removed
+ ripper_tokens.each do |tok|
+ assert(rubylex_tokens.any? { |t| t.tok == tok && t.tok != :on_ignored_by_ripper })
end
- end
-
- def test_bracket_corresponding_to_times
- input_with_correct_indents = [
- Row.new(%q(3.times { |i|), nil, 2, 1),
- Row.new(%q( puts i), nil, 2, 1),
- Row.new(%q(}), 0, 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
+ # Assert interpolated token position
+ rubylex_tokens.each do |t|
+ row, col = t.pos
+ assert_equal t.tok, code.lines[row - 1].byteslice(col, t.tok.bytesize)
end
end
- def test_do_corresponding_to_times
- input_with_correct_indents = [
- Row.new(%q(3.times do |i|), nil, 2, 1),
- #Row.new(%q( puts i), nil, 2, 1),
- #Row.new(%q(end), 0, 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
+ def test_local_variables_dependent_code
+ lines = ["a /1#/ do", "2"]
+ assert_indent_level(lines, 1)
+ assert_code_block_open(lines, true)
+ assert_indent_level(lines, 0, local_variables: ['a'])
+ assert_code_block_open(lines, false, local_variables: ['a'])
end
- def test_bracket_corresponding_to_loop
- input_with_correct_indents = [
- Row.new(%q(loop {), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(}), 0, 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
+ def test_literal_ends_with_space
+ assert_code_block_open(['% a'], true)
+ assert_code_block_open(['% a '], false)
end
- def test_do_corresponding_to_loop
- input_with_correct_indents = [
- Row.new(%q(loop do), nil, 2, 1),
- Row.new(%q( 3), nil, 2, 1),
- Row.new(%q(end), 0, 0, 0),
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
+ def test_literal_ends_with_newline
+ assert_code_block_open(['%'], true)
+ assert_code_block_open(['%', ''], false)
end
- def test_heredoc_with_indent
- input_with_correct_indents = [
- Row.new(%q(<<~Q), 0, 0, 0),
- Row.new(%q({), 0, 0, 0),
- Row.new(%q( #), 2, 0, 0),
- Row.new(%q(}), 0, 0, 0)
- ]
-
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
+ def test_should_continue
+ assert_should_continue(['a'], false)
+ assert_should_continue(['/a/'], false)
+ assert_should_continue(['a;'], false)
+ assert_should_continue(['<<A', 'A'], false)
+ assert_should_continue(['a...'], false)
+ assert_should_continue(['a\\'], true)
+ assert_should_continue(['a.'], true)
+ assert_should_continue(['a+'], true)
+ assert_should_continue(['a; #comment', '', '=begin', 'embdoc', '=end', ''], false)
+ assert_should_continue(['a+ #comment', '', '=begin', 'embdoc', '=end', ''], true)
end
- def test_oneliner_def_in_multiple_lines
- input_with_correct_indents = [
- Row.new(%q(def a()=[), nil, 4, 2),
- Row.new(%q( 1,), nil, 4, 1),
- Row.new(%q(].), 0, 0, 0),
- Row.new(%q(to_s), nil, 0, 0),
- ]
+ def test_code_block_open_with_should_continue
+ # syntax ok
+ assert_code_block_open(['a'], false) # continue: false
+ assert_code_block_open(['a\\'], true) # continue: true
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
- end
+ # recoverable syntax error code is not terminated
+ assert_code_block_open(['a+'], true)
- def test_broken_heredoc
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
- pend 'This test needs Ripper::Lexer#scan to take broken tokens'
- end
- input_with_correct_indents = [
- Row.new(%q(def foo), nil, 2, 1),
- Row.new(%q( <<~Q), 2, 2, 1),
- Row.new(%q( Qend), 2, 2, 1),
- ]
+ # unrecoverable syntax error code is terminated
+ assert_code_block_open(['.; a+'], false)
- lines = []
- input_with_correct_indents.each do |row|
- lines << row.content
- assert_indenting(lines, row.current_line_spaces, false)
- assert_indenting(lines, row.new_line_spaces, true)
- assert_nesting_level(lines, row.nesting_level)
- end
- end
-
- PromptRow = Struct.new(:prompt, :content)
-
- class MockIO_DynamicPrompt
- def initialize(params, &assertion)
- @params = params
- @assertion = assertion
- end
-
- def dynamic_prompt(&block)
- result = block.call(@params)
- @assertion.call(result)
- end
- end
-
- def assert_dynamic_prompt(lines, expected_prompt_list)
- pend if RUBY_ENGINE == 'truffleruby'
- ruby_lex = RubyLex.new()
- io = MockIO_DynamicPrompt.new(lines) do |prompt_list|
- error_message = <<~EOM
- Expected dynamic prompt:
- #{expected_prompt_list.join("\n")}
-
- Actual dynamic prompt:
- #{prompt_list.join("\n")}
- EOM
- assert_equal(expected_prompt_list, prompt_list, error_message)
- end
- ruby_lex.set_prompt do |ltype, indent, continue, line_no|
- '%03d:%01d:%1s:%s ' % [line_no, indent, ltype, continue ? '*' : '>']
- end
- ruby_lex.set_input(io)
- end
-
- def test_dyanmic_prompt
- input_with_prompt = [
- PromptRow.new('001:1: :* ', %q(def hoge)),
- PromptRow.new('002:1: :* ', %q( 3)),
- PromptRow.new('003:0: :> ', %q(end)),
- ]
-
- lines = input_with_prompt.map(&:content)
- expected_prompt_list = input_with_prompt.map(&:prompt)
- assert_dynamic_prompt(lines, expected_prompt_list)
- end
-
- def test_dyanmic_prompt_with_blank_line
- input_with_prompt = [
- PromptRow.new('001:0:]:* ', %q(%w[)),
- PromptRow.new('002:0:]:* ', %q()),
- PromptRow.new('003:0: :> ', %q(])),
- ]
-
- lines = input_with_prompt.map(&:content)
- expected_prompt_list = input_with_prompt.map(&:prompt)
- assert_dynamic_prompt(lines, expected_prompt_list)
+ # other syntax error that failed to determine if it is recoverable or not
+ assert_code_block_open(['@; a'], false)
+ assert_code_block_open(['@; a+'], true)
+ assert_code_block_open(['@; (a'], true)
end
def test_broken_percent_literal
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
- pend 'This test needs Ripper::Lexer#scan to take broken tokens'
- end
-
- tokens = RubyLex.ripper_lex_without_warning('%wwww')
+ tokens = IRB::RubyLex.ripper_lex_without_warning('%wwww')
pos_to_index = {}
tokens.each_with_index { |t, i|
assert_nil(pos_to_index[t.pos], "There is already another token in the position of #{t.inspect}.")
@@ -604,11 +92,7 @@ module TestIRB
end
def test_broken_percent_literal_in_method
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
- pend 'This test needs Ripper::Lexer#scan to take broken tokens'
- end
-
- tokens = RubyLex.ripper_lex_without_warning(<<~EOC.chomp)
+ tokens = IRB::RubyLex.ripper_lex_without_warning(<<~EOC.chomp)
def foo
%wwww
end
@@ -619,5 +103,140 @@ module TestIRB
pos_to_index[t.pos] = i
}
end
+
+ def test_unterminated_code
+ ['do', '<<A'].each do |code|
+ tokens = IRB::RubyLex.ripper_lex_without_warning(code)
+ assert_equal(code, tokens.map(&:tok).join, "Cannot reconstruct code from tokens")
+ error_tokens = tokens.map(&:event).grep(/error/)
+ assert_empty(error_tokens, 'Error tokens must be ignored if there is corresponding non-error token')
+ end
+ end
+
+ def test_unterminated_heredoc_string_literal
+ ['<<A;<<B', "<<A;<<B\n", "%W[\#{<<A;<<B", "%W[\#{<<A;<<B\n"].each do |code|
+ tokens = IRB::RubyLex.ripper_lex_without_warning(code)
+ string_literal = IRB::NestingParser.open_tokens(tokens).last
+ assert_equal('<<A', string_literal&.tok)
+ end
+ end
+
+ def test_indent_level_with_heredoc_and_embdoc
+ reference_code = <<~EOC.chomp
+ if true
+ hello
+ p(
+ )
+ EOC
+ code_with_heredoc = <<~EOC.chomp
+ if true
+ <<~A
+ A
+ p(
+ )
+ EOC
+ code_with_embdoc = <<~EOC.chomp
+ if true
+ =begin
+ =end
+ p(
+ )
+ EOC
+ expected = 1
+ assert_indent_level(reference_code.lines, expected)
+ assert_indent_level(code_with_heredoc.lines, expected)
+ assert_indent_level(code_with_embdoc.lines, expected)
+ end
+
+ def test_assignment_expression
+ ruby_lex = IRB::RubyLex.new
+
+ [
+ "foo = bar",
+ "@foo = bar",
+ "$foo = bar",
+ "@@foo = bar",
+ "::Foo = bar",
+ "a::Foo = bar",
+ "Foo = bar",
+ "foo.bar = 1",
+ "foo[1] = bar",
+ "foo += bar",
+ "foo -= bar",
+ "foo ||= bar",
+ "foo &&= bar",
+ "foo, bar = 1, 2",
+ "foo.bar=(1)",
+ "foo; foo = bar",
+ "foo; foo = bar; ;\n ;",
+ "foo\nfoo = bar",
+ ].each do |exp|
+ assert(
+ ruby_lex.assignment_expression?(exp, local_variables: []),
+ "#{exp.inspect}: should be an assignment expression"
+ )
+ end
+
+ [
+ "foo",
+ "foo.bar",
+ "foo[0]",
+ "foo = bar; foo",
+ "foo = bar\nfoo",
+ ].each do |exp|
+ refute(
+ ruby_lex.assignment_expression?(exp, local_variables: []),
+ "#{exp.inspect}: should not be an assignment expression"
+ )
+ end
+ end
+
+ def test_assignment_expression_with_local_variable
+ ruby_lex = IRB::RubyLex.new
+ code = "a /1;x=1#/"
+ refute(ruby_lex.assignment_expression?(code, local_variables: []), "#{code}: should not be an assignment expression")
+ assert(ruby_lex.assignment_expression?(code, local_variables: [:a]), "#{code}: should be an assignment expression")
+ refute(ruby_lex.assignment_expression?("", local_variables: [:a]), "empty code should not be an assignment expression")
+ end
+
+ def test_initialising_the_old_top_level_ruby_lex
+ assert_in_out_err(["--disable-gems", "-W:deprecated"], <<~RUBY, [], /warning: constant ::RubyLex is deprecated/)
+ require "irb"
+ ::RubyLex.new(nil)
+ RUBY
+ end
+
+ private
+
+ def assert_indent_level(lines, expected, local_variables: [])
+ indent_level, _continue, _code_block_open = check_state(lines, local_variables: local_variables)
+ error_message = "Calculated the wrong number of indent level for:\n #{lines.join("\n")}"
+ assert_equal(expected, indent_level, error_message)
+ end
+
+ def assert_should_continue(lines, expected, local_variables: [])
+ _indent_level, continue, _code_block_open = check_state(lines, local_variables: local_variables)
+ error_message = "Wrong result of should_continue for:\n #{lines.join("\n")}"
+ assert_equal(expected, continue, error_message)
+ end
+
+ def assert_code_block_open(lines, expected, local_variables: [])
+ if RUBY_ENGINE == 'truffleruby'
+ omit "Remove me after https://github.com/ruby/prism/issues/2129 is addressed and adopted in TruffleRuby"
+ end
+
+ _indent_level, _continue, code_block_open = check_state(lines, local_variables: local_variables)
+ error_message = "Wrong result of code_block_open for:\n #{lines.join("\n")}"
+ assert_equal(expected, code_block_open, error_message)
+ end
+
+ def check_state(lines, local_variables: [])
+ code = lines.map { |l| "#{l}\n" }.join # code should end with "\n"
+ ruby_lex = IRB::RubyLex.new
+ tokens, opens, terminated = ruby_lex.check_code_state(code, local_variables: local_variables)
+ indent_level = ruby_lex.calc_indent_level(opens)
+ continue = ruby_lex.should_continue?(tokens)
+ [indent_level, continue, !terminated]
+ end
end
end
diff --git a/test/irb/test_tracer.rb b/test/irb/test_tracer.rb
new file mode 100644
index 0000000000..540f8be131
--- /dev/null
+++ b/test/irb/test_tracer.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: false
+require 'tempfile'
+require 'irb'
+
+require_relative "helper"
+
+module TestIRB
+ class ContextWithTracerIntegrationTest < IntegrationTestCase
+ def setup
+ super
+
+ omit "Tracer gem is not available when running on TruffleRuby" if RUBY_ENGINE == "truffleruby"
+
+ @envs.merge!("NO_COLOR" => "true")
+ end
+
+ def example_ruby_file
+ <<~'RUBY'
+ class Foo
+ def self.foo
+ 100
+ end
+ end
+
+ def bar(obj)
+ obj.foo
+ end
+
+ binding.irb
+ RUBY
+ end
+
+ def test_use_tracer_enabled_when_gem_is_unavailable
+ write_rc <<~RUBY
+ # Simulate the absence of the tracer gem
+ ::Kernel.send(:alias_method, :irb_original_require, :require)
+
+ ::Kernel.define_method(:require) do |name|
+ raise LoadError, "cannot load such file -- tracer (test)" if name.match?("tracer")
+ ::Kernel.send(:irb_original_require, name)
+ end
+
+ IRB.conf[:USE_TRACER] = true
+ RUBY
+
+ write_ruby example_ruby_file
+
+ output = run_ruby_file do
+ type "bar(Foo)"
+ type "exit"
+ end
+
+ assert_include(output, "Tracer extension of IRB is enabled but tracer gem wasn't found.")
+ end
+
+ def test_use_tracer_enabled_when_gem_is_available
+ write_rc <<~RUBY
+ IRB.conf[:USE_TRACER] = true
+ RUBY
+
+ write_ruby example_ruby_file
+
+ output = run_ruby_file do
+ type "bar(Foo)"
+ type "exit"
+ end
+
+ assert_include(output, "Object#bar at")
+ assert_include(output, "Foo.foo at")
+ assert_include(output, "Foo.foo #=> 100")
+ assert_include(output, "Object#bar #=> 100")
+
+ # Test that the tracer output does not include IRB's own files
+ assert_not_include(output, "irb/workspace.rb")
+ end
+
+ def test_use_tracer_is_disabled_by_default
+ write_ruby example_ruby_file
+
+ output = run_ruby_file do
+ type "bar(Foo)"
+ type "exit"
+ end
+
+ assert_not_include(output, "#depth:")
+ assert_not_include(output, "Foo.foo")
+ end
+
+ end
+end
diff --git a/test/irb/test_type_completor.rb b/test/irb/test_type_completor.rb
new file mode 100644
index 0000000000..5ed8988b34
--- /dev/null
+++ b/test/irb/test_type_completor.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+# Run test only when Ruby >= 3.0 and repl_type_completor is available
+return unless RUBY_VERSION >= '3.0.0'
+return if RUBY_ENGINE == 'truffleruby' # needs endless method definition
+begin
+ require 'repl_type_completor'
+rescue LoadError
+ return
+end
+
+require 'irb'
+require 'tempfile'
+require_relative './helper'
+
+module TestIRB
+ class TypeCompletorTest < TestCase
+ DummyContext = Struct.new(:irb_path)
+
+ def setup
+ ReplTypeCompletor.load_rbs unless ReplTypeCompletor.rbs_loaded?
+ context = DummyContext.new('(irb)')
+ @completor = IRB::TypeCompletor.new(context)
+ end
+
+ def empty_binding
+ binding
+ end
+
+ def assert_completion(preposing, target, binding: empty_binding, include: nil, exclude: nil)
+ raise ArgumentError if include.nil? && exclude.nil?
+ candidates = @completor.completion_candidates(preposing, target, '', bind: binding)
+ assert ([*include] - candidates).empty?, "Expected #{candidates} to include #{include}" if include
+ assert (candidates & [*exclude]).empty?, "Expected #{candidates} not to include #{exclude}" if exclude
+ end
+
+ def assert_doc_namespace(preposing, target, namespace, binding: empty_binding)
+ @completor.completion_candidates(preposing, target, '', bind: binding)
+ assert_equal namespace, @completor.doc_namespace(preposing, target, '', bind: binding)
+ end
+
+ def test_type_completion
+ bind = eval('num = 1; binding')
+ assert_completion('num.times.map(&:', 'ab', binding: bind, include: 'abs')
+ assert_doc_namespace('num.chr.', 'upcase', 'String#upcase', binding: bind)
+ end
+
+ def test_inspect
+ assert_match(/\AReplTypeCompletor.*\z/, @completor.inspect)
+ end
+
+ def test_empty_completion
+ candidates = @completor.completion_candidates('(', ')', '', bind: binding)
+ assert_equal [], candidates
+ assert_doc_namespace('(', ')', nil)
+ end
+
+ def test_command_completion
+ assert_include(@completor.completion_candidates('', 'show_s', '', bind: binding), 'show_source')
+ assert_not_include(@completor.completion_candidates(';', 'show_s', '', bind: binding), 'show_source')
+ end
+ end
+
+ class TypeCompletorIntegrationTest < IntegrationTestCase
+ def test_type_completor
+ write_rc <<~RUBY
+ IRB.conf[:COMPLETOR] = :type
+ RUBY
+
+ write_ruby <<~'RUBY'
+ binding.irb
+ RUBY
+
+ output = run_ruby_file do
+ type "irb_info"
+ type "sleep 0.01 until ReplTypeCompletor.rbs_loaded?"
+ type "completor = IRB.CurrentContext.io.instance_variable_get(:@completor);"
+ type "n = 10"
+ type "puts completor.completion_candidates 'a = n.abs;', 'a.b', '', bind: binding"
+ type "puts completor.doc_namespace 'a = n.chr;', 'a.encoding', '', bind: binding"
+ type "exit!"
+ end
+ assert_match(/Completion: Autocomplete, ReplTypeCompletor/, output)
+ assert_match(/a\.bit_length/, output)
+ assert_match(/String#encoding/, output)
+ end
+ end
+end
diff --git a/test/irb/test_workspace.rb b/test/irb/test_workspace.rb
index 1a1dc1f49b..199ce95a37 100644
--- a/test/irb/test_workspace.rb
+++ b/test/irb/test_workspace.rb
@@ -1,13 +1,13 @@
# frozen_string_literal: false
-require 'test/unit'
require 'tempfile'
-require 'rubygems'
require 'irb'
require 'irb/workspace'
require 'irb/color'
+require_relative "helper"
+
module TestIRB
- class TestWorkSpace < Test::Unit::TestCase
+ class WorkSpaceTest < TestCase
def test_code_around_binding
IRB.conf[:USE_COLORIZE] = false
Tempfile.create('irb') do |f|
@@ -82,7 +82,6 @@ module TestIRB
def test_toplevel_binding_local_variables
- pend if RUBY_ENGINE == 'truffleruby'
bug17623 = '[ruby-core:102468]'
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []
top_srcdir = "#{__dir__}/../.."
@@ -91,7 +90,7 @@ module TestIRB
irb_path = "#{top_srcdir}/#{dir}/irb"
File.exist?(irb_path)
end or omit 'irb command not found'
- assert_in_out_err(bundle_exec + ['-W0', "-C#{top_srcdir}", '-e', <<~RUBY , '--', '-f', '--'], 'binding.local_variables', /\[:_\]/, [], bug17623)
+ assert_in_out_err(bundle_exec + ['-W0', "-C#{top_srcdir}", '-e', <<~RUBY, '--', '-f', '--'], 'binding.local_variables', /\[:_\]/, [], bug17623)
version = 'xyz' # typical rubygems loading file
load('#{irb_path}')
RUBY
diff --git a/test/irb/yamatanooroti/test_rendering.rb b/test/irb/yamatanooroti/test_rendering.rb
index 7ed98b11c1..44e07a3a12 100644
--- a/test/irb/yamatanooroti/test_rendering.rb
+++ b/test/irb/yamatanooroti/test_rendering.rb
@@ -2,227 +2,516 @@ require 'irb'
begin
require 'yamatanooroti'
+rescue LoadError, NameError
+ # On Ruby repository, this test suite doesn't run because Ruby repo doesn't
+ # have the yamatanooroti gem.
+ return
+end
- class IRB::TestRendering < Yamatanooroti::TestCase
- def setup
- @pwd = Dir.pwd
- suffix = '%010d' % Random.rand(0..65535)
- @tmpdir = File.join(File.expand_path(Dir.tmpdir), "test_irb_#{$$}_#{suffix}")
- begin
- Dir.mkdir(@tmpdir)
- rescue Errno::EEXIST
- FileUtils.rm_rf(@tmpdir)
- Dir.mkdir(@tmpdir)
- end
- @irbrc_backup = ENV['IRBRC']
- @irbrc_file = ENV['IRBRC'] = File.join(@tmpdir, 'temporaty_irbrc')
- File.unlink(@irbrc_file) if File.exist?(@irbrc_file)
- end
-
- def teardown
+class IRB::RenderingTest < Yamatanooroti::TestCase
+ def setup
+ @original_term = ENV['TERM']
+ @home_backup = ENV['HOME']
+ @xdg_config_home_backup = ENV['XDG_CONFIG_HOME']
+ ENV['TERM'] = "xterm-256color"
+ @pwd = Dir.pwd
+ suffix = '%010d' % Random.rand(0..65535)
+ @tmpdir = File.join(File.expand_path(Dir.tmpdir), "test_irb_#{$$}_#{suffix}")
+ begin
+ Dir.mkdir(@tmpdir)
+ rescue Errno::EEXIST
FileUtils.rm_rf(@tmpdir)
- ENV['IRBRC'] = @irbrc_backup
- ENV.delete('RELINE_TEST_PROMPT') if ENV['RELINE_TEST_PROMPT']
+ Dir.mkdir(@tmpdir)
end
+ @irbrc_backup = ENV['IRBRC']
+ @irbrc_file = ENV['IRBRC'] = File.join(@tmpdir, 'temporaty_irbrc')
+ File.unlink(@irbrc_file) if File.exist?(@irbrc_file)
+ ENV['HOME'] = File.join(@tmpdir, 'home')
+ ENV['XDG_CONFIG_HOME'] = File.join(@tmpdir, 'xdg_config_home')
+ end
- def test_launch
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write(<<~EOC)
- 'Hello, World!'
- EOC
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001:0> 'Hello, World!'
- => "Hello, World!"
- irb(main):002:0>
- EOC
- end
+ def teardown
+ FileUtils.rm_rf(@tmpdir)
+ ENV['IRBRC'] = @irbrc_backup
+ ENV['TERM'] = @original_term
+ ENV['HOME'] = @home_backup
+ ENV['XDG_CONFIG_HOME'] = @xdg_config_home_backup
+ end
- def test_multiline_paste
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write(<<~EOC)
- class A
- def inspect; '#<A>'; end
- def a; self; end
- def b; true; end
- end
-
- a = A.new
-
- a
- .a
- .b
- EOC
- close
- assert_screen(<<~EOC)
- start IRB
- irb(main):001:1* class A
- irb(main):002:1* def inspect; '#<A>'; end
- irb(main):003:1* def a; self; end
- irb(main):004:1* def b; true; end
- irb(main):005:0> end
- => :b
- irb(main):006:0>
- irb(main):007:0> a = A.new
- => #<A>
- irb(main):008:0>
- irb(main):009:0> a
- irb(main):010:0> .a
- irb(main):011:0> .b
- => true
- irb(main):012:0>
- EOC
- end
+ def test_launch
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write(<<~EOC)
+ 'Hello, World!'
+ EOC
+ close
+ assert_screen(<<~EOC)
+ start IRB
+ irb(main):001> 'Hello, World!'
+ => "Hello, World!"
+ irb(main):002>
+ EOC
+ end
- def test_evaluate_each_toplevel_statement_by_multiline_paste
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write(<<~EOC)
- class A
- def inspect; '#<A>'; end
- def b; self; end
- def c; true; end
- end
-
- a = A.new
-
- a
- .b
- # aaa
- .c
-
- (a)
- &.b()
-
-
- class A def b; self; end; def c; true; end; end;
- a = A.new
- a
- .b
- # aaa
- .c
- (a)
- &.b()
- EOC
- close
+ def test_configuration_file_is_skipped_with_dash_f
+ write_irbrc <<~'LINES'
+ puts '.irbrc file should be ignored when -f is used'
+ LINES
+ start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb -f}, startup_message: '')
+ write(<<~EOC)
+ 'Hello, World!'
+ EOC
+ close
+ assert_screen(<<~EOC)
+ irb(main):001> 'Hello, World!'
+ => "Hello, World!"
+ irb(main):002>
+ EOC
+ end
+
+ def test_configuration_file_is_skipped_with_dash_f_for_nested_sessions
+ write_irbrc <<~'LINES'
+ puts '.irbrc file should be ignored when -f is used'
+ LINES
+ start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb -f}, startup_message: '')
+ write(<<~EOC)
+ 'Hello, World!'
+ binding.irb
+ exit!
+ EOC
+ close
+ assert_screen(<<~EOC)
+ irb(main):001> 'Hello, World!'
+ => "Hello, World!"
+ irb(main):002> binding.irb
+ irb(main):003> exit!
+ irb(main):001>
+ EOC
+ end
+
+ def test_nomultiline
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb --nomultiline}, startup_message: 'start IRB')
+ write(<<~EOC)
+ if true
+ if false
+ a = "hello
+ world"
+ puts a
+ end
+ end
+ EOC
+ close
+ assert_screen(<<~EOC)
+ start IRB
+ irb(main):001> if true
+ irb(main):002* if false
+ irb(main):003* a = "hello
+ irb(main):004" world"
+ irb(main):005* puts a
+ irb(main):006* end
+ irb(main):007* end
+ => nil
+ irb(main):008>
+ EOC
+ end
+
+ def test_multiline_paste
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(25, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write(<<~EOC)
+ class A
+ def inspect; '#<A>'; end
+ def a; self; end
+ def b; true; end
+ end
+
+ a = A.new
+
+ a
+ .a
+ .b
+ .itself
+ EOC
+ close
+ assert_screen(<<~EOC)
+ start IRB
+ irb(main):001* class A
+ irb(main):002* def inspect; '#<A>'; end
+ irb(main):003* def a; self; end
+ irb(main):004* def b; true; end
+ irb(main):005> end
+ => :b
+ irb(main):006>
+ irb(main):007> a = A.new
+ => #<A>
+ irb(main):008>
+ irb(main):009> a
+ irb(main):010> .a
+ irb(main):011> .b
+ irb(main):012> .itself
+ => true
+ irb(main):013>
+ EOC
+ end
+
+ def test_evaluate_each_toplevel_statement_by_multiline_paste
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write(<<~EOC)
+ class A
+ def inspect; '#<A>'; end
+ def b; self; end
+ def c; true; end
+ end
+
+ a = A.new
+
+ a
+ .b
+ # aaa
+ .c
+
+ (a)
+ &.b()
+
+ class A def b; self; end; def c; true; end; end;
+ a = A.new
+ a
+ .b
+ # aaa
+ .c
+ (a)
+ &.b()
+ .itself
+ EOC
+ close
+ assert_screen(<<~EOC)
+ start IRB
+ irb(main):001* class A
+ irb(main):002* def inspect; '#<A>'; end
+ irb(main):003* def b; self; end
+ irb(main):004* def c; true; end
+ irb(main):005> end
+ => :c
+ irb(main):006>
+ irb(main):007> a = A.new
+ => #<A>
+ irb(main):008>
+ irb(main):009> a
+ irb(main):010> .b
+ irb(main):011> # aaa
+ irb(main):012> .c
+ => true
+ irb(main):013>
+ irb(main):014> (a)
+ irb(main):015> &.b()
+ => #<A>
+ irb(main):016>
+ irb(main):017> class A def b; self; end; def c; true; end; end;
+ irb(main):018> a = A.new
+ => #<A>
+ irb(main):019> a
+ irb(main):020> .b
+ irb(main):021> # aaa
+ irb(main):022> .c
+ => true
+ irb(main):023> (a)
+ irb(main):024> &.b()
+ irb(main):025> .itself
+ => #<A>
+ irb(main):026>
+ EOC
+ end
+
+ def test_symbol_with_backtick
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write(<<~EOC)
+ :`
+ EOC
+ close
+ assert_screen(<<~EOC)
+ start IRB
+ irb(main):001> :`
+ => :`
+ irb(main):002>
+ EOC
+ end
+
+ def test_autocomplete_with_multiple_doc_namespaces
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(3, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("{}.__id_")
+ write("\C-i")
+ sleep 0.2
+ close
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ assert_match(/start\ IRB\nirb\(main\):001> {}\.__id__\n }\.__id__(?:Press )?/, screen)
+ end
+
+ def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_right
+ rdoc_dir = File.join(@tmpdir, 'rdoc')
+ system("bundle exec rdoc -r -o #{rdoc_dir}")
+ write_irbrc <<~LINES
+ IRB.conf[:EXTRA_DOC_DIRS] = ['#{rdoc_dir}']
+ IRB.conf[:PROMPT][:MY_PROMPT] = {
+ :PROMPT_I => "%03n> ",
+ :PROMPT_S => "%03n> ",
+ :PROMPT_C => "%03n> "
+ }
+ IRB.conf[:PROMPT_MODE] = :MY_PROMPT
+ puts 'start IRB'
+ LINES
+ start_terminal(4, 19, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("IR")
+ write("\C-i")
+ sleep 0.2
+ close
+
+ # This is because on macOS we display different shortcut for displaying the full doc
+ # 'O' is for 'Option' and 'A' is for 'Alt'
+ if RUBY_PLATFORM =~ /darwin/
assert_screen(<<~EOC)
start IRB
- irb(main):001:1* class A
- irb(main):002:1* def inspect; '#<A>'; end
- irb(main):003:1* def b; self; end
- irb(main):004:1* def c; true; end
- irb(main):005:0> end
- => :c
- irb(main):006:0>
- irb(main):007:0> a = A.new
- => #<A>
- irb(main):008:0>
- irb(main):009:0> a
- irb(main):010:0> .b
- irb(main):011:0> # aaa
- irb(main):012:0> .c
- => true
- irb(main):013:0>
- irb(main):014:0> (a)
- irb(main):015:0> &.b()
- => #<A>
- irb(main):016:0>
- irb(main):017:0>
- irb(main):018:0> class A def b; self; end; def c; true; end; end;
- => :c
- irb(main):019:0> a = A.new
- => #<A>
- irb(main):020:0> a
- irb(main):021:0> .b
- irb(main):022:0> # aaa
- irb(main):023:0> .c
- => true
- irb(main):024:0> (a)
- irb(main):025:0> &.b()
- => #<A>
- irb(main):026:0>
- EOC
- end
-
- def test_symbol_with_backtick
- write_irbrc <<~'LINES'
- puts 'start IRB'
- LINES
- start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write(<<~EOC)
- :`
+ 001> IRB
+ IRBPress Opti
+ IRB
EOC
- close
+ else
assert_screen(<<~EOC)
start IRB
- irb(main):001:0> :`
- => :`
- irb(main):002:0>
+ 001> IRB
+ IRBPress Alt+
+ IRB
EOC
end
+ end
- def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_right
- pend "Needs a dummy document to show doc"
- write_irbrc <<~'LINES'
- IRB.conf[:PROMPT][:MY_PROMPT] = {
- :PROMPT_I => "%03n> ",
- :PROMPT_N => "%03n> ",
- :PROMPT_S => "%03n> ",
- :PROMPT_C => "%03n> "
- }
- IRB.conf[:PROMPT_MODE] = :MY_PROMPT
- puts 'start IRB'
- LINES
- start_terminal(4, 19, %W{ruby -I/home/aycabta/ruby/reline/lib -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("Str\C-i")
- close
- assert_screen(<<~EOC)
- 001> String
- StringPress A
- StructString
- of byte
- EOC
- end
+ def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_left
+ rdoc_dir = File.join(@tmpdir, 'rdoc')
+ system("bundle exec rdoc -r -o #{rdoc_dir}")
+ write_irbrc <<~LINES
+ IRB.conf[:EXTRA_DOC_DIRS] = ['#{rdoc_dir}']
+ IRB.conf[:PROMPT][:MY_PROMPT] = {
+ :PROMPT_I => "%03n> ",
+ :PROMPT_S => "%03n> ",
+ :PROMPT_C => "%03n> "
+ }
+ IRB.conf[:PROMPT_MODE] = :MY_PROMPT
+ puts 'start IRB'
+ LINES
+ start_terminal(4, 12, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("IR")
+ write("\C-i")
+ sleep 0.2
+ close
+ assert_screen(<<~EOC)
+ start IRB
+ 001> IRB
+ PressIRB
+ IRB
+ EOC
+ end
- def test_autocomplete_with_showdoc_in_gaps_on_narrow_screen_left
- pend "Needs a dummy document to show doc"
- write_irbrc <<~'LINES'
- IRB.conf[:PROMPT][:MY_PROMPT] = {
- :PROMPT_I => "%03n> ",
- :PROMPT_N => "%03n> ",
- :PROMPT_S => "%03n> ",
- :PROMPT_C => "%03n> "
- }
- IRB.conf[:PROMPT_MODE] = :MY_PROMPT
- puts 'start IRB'
- LINES
- start_terminal(4, 12, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
- write("Str\C-i")
- close
- assert_screen(<<~EOC)
- 001> String
- PressString
- StrinStruct
- of by
- EOC
- end
+ def test_assignment_expression_truncate
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ # Assignment expression code that turns into non-assignment expression after evaluation
+ code = "a /'/i if false; a=1; x=1000.times.to_a#'.size"
+ write(code + "\n")
+ close
+ assert_screen(<<~EOC)
+ start IRB
+ irb(main):001> #{code}
+ =>
+ [0,
+ ...
+ irb(main):002>
+ EOC
+ end
- private def write_irbrc(content)
- File.open(@irbrc_file, 'w') do |f|
- f.write content
- end
+ def test_ctrl_c_is_handled
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ # Assignment expression code that turns into non-assignment expression after evaluation
+ write("\C-c")
+ close
+ assert_screen(<<~EOC)
+ start IRB
+ irb(main):001>
+ ^C
+ irb(main):001>
+ EOC
+ end
+
+ def test_show_cmds_with_pager_can_quit_with_ctrl_c
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ LINES
+ start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("help\n")
+ write("G") # move to the end of the screen
+ write("\C-c") # quit pager
+ write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
+ close
+
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ # IRB::Abort should be rescued
+ assert_not_match(/IRB::Abort/, screen)
+ # IRB should resume
+ assert_match(/foobar/, screen)
+ end
+
+ def test_pager_page_content_pages_output_when_it_does_not_fit_in_the_screen_because_of_total_length
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ require "irb/pager"
+ LINES
+ start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("IRB::Pager.page_content('a' * (80 * 8))\n")
+ write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
+ close
+
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ assert_match(/a{80}/, screen)
+ # because pager is invoked, foobar will not be evaluated
+ assert_not_match(/foobar/, screen)
+ end
+
+ def test_pager_page_content_pages_output_when_it_does_not_fit_in_the_screen_because_of_screen_height
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ require "irb/pager"
+ LINES
+ start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("IRB::Pager.page_content('a\n' * 8)\n")
+ write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
+ close
+
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ assert_match(/(a\n){8}/, screen)
+ # because pager is invoked, foobar will not be evaluated
+ assert_not_match(/foobar/, screen)
+ end
+
+ def test_pager_page_content_doesnt_page_output_when_it_fits_in_the_screen
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ require "irb/pager"
+ LINES
+ start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("IRB::Pager.page_content('a' * (80 * 7))\n")
+ write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
+ close
+
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ assert_match(/a{80}/, screen)
+ # because pager is not invoked, foobar will be evaluated
+ assert_match(/foobar/, screen)
+ end
+
+ def test_long_evaluation_output_is_paged
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ require "irb/pager"
+ LINES
+ start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("'a' * 80 * 11\n")
+ write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
+ close
+
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ assert_match(/(a{80}\n){8}/, screen)
+ # because pager is invoked, foobar will not be evaluated
+ assert_not_match(/foobar/, screen)
+ end
+
+ def test_long_evaluation_output_is_preserved_after_paging
+ write_irbrc <<~'LINES'
+ puts 'start IRB'
+ require "irb/pager"
+ LINES
+ start_terminal(10, 80, %W{ruby -I#{@pwd}/lib #{@pwd}/exe/irb}, startup_message: 'start IRB')
+ write("'a' * 80 * 11\n")
+ write("q") # quit pager
+ write("'foo' + 'bar'\n") # eval something to make sure IRB resumes
+ close
+
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ # confirm pager has exited
+ assert_match(/foobar/, screen)
+ # confirm output is preserved
+ assert_match(/(a{80}\n){6}/, screen)
+ end
+
+ def test_debug_integration_hints_debugger_commands
+ write_irbrc <<~'LINES'
+ IRB.conf[:USE_COLORIZE] = false
+ LINES
+ script = Tempfile.create(["debug", ".rb"])
+ script.write <<~RUBY
+ puts 'start IRB'
+ binding.irb
+ RUBY
+ script.close
+ start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{script.to_path}}, startup_message: 'start IRB')
+ write("debug\n")
+ write("pp 1\n")
+ write("pp 1")
+ close
+
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ # submitted input shouldn't contain hint
+ assert_include(screen, "irb:rdbg(main):002> pp 1\n")
+ # unsubmitted input should contain hint
+ assert_include(screen, "irb:rdbg(main):003> pp 1 # debug command\n")
+ ensure
+ File.unlink(script) if script
+ end
+
+ def test_debug_integration_doesnt_hint_non_debugger_commands
+ write_irbrc <<~'LINES'
+ IRB.conf[:USE_COLORIZE] = false
+ LINES
+ script = Tempfile.create(["debug", ".rb"])
+ script.write <<~RUBY
+ puts 'start IRB'
+ binding.irb
+ RUBY
+ script.close
+ start_terminal(40, 80, %W{ruby -I#{@pwd}/lib #{script.to_path}}, startup_message: 'start IRB')
+ write("debug\n")
+ write("foo")
+ close
+
+ screen = result.join("\n").sub(/\n*\z/, "\n")
+ assert_include(screen, "irb:rdbg(main):002> foo\n")
+ ensure
+ File.unlink(script) if script
+ end
+
+ private
+
+ def write_irbrc(content)
+ File.open(@irbrc_file, 'w') do |f|
+ f.write content
end
end
-rescue LoadError, NameError
- # On Ruby repository, this test suit doesn't run because Ruby repo doesn't
- # have the yamatanooroti gem.
end
diff --git a/test/json/json_addition_test.rb b/test/json/json_addition_test.rb
index 614c735567..3a7a58176a 100644
--- a/test/json/json_addition_test.rb
+++ b/test/json/json_addition_test.rb
@@ -1,5 +1,5 @@
#frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
require 'json/add/core'
require 'json/add/complex'
require 'json/add/rational'
@@ -183,14 +183,14 @@ class JSONAdditionTest < Test::Unit::TestCase
def test_bigdecimal
assert_equal BigDecimal('3.141', 23), JSON(JSON(BigDecimal('3.141', 23)), :create_additions => true)
assert_equal BigDecimal('3.141', 666), JSON(JSON(BigDecimal('3.141', 666)), :create_additions => true)
- end
+ end if defined?(::BigDecimal)
def test_ostruct
o = OpenStruct.new
# XXX this won't work; o.foo = { :bar => true }
o.foo = { 'bar' => true }
assert_equal o, parse(JSON(o), :create_additions => true)
- end
+ end if defined?(::OpenStruct)
def test_set
s = Set.new([:a, :b, :c, :a])
diff --git a/test/json/json_common_interface_test.rb b/test/json/json_common_interface_test.rb
index 9148b78c8b..c16f6ceaaf 100644
--- a/test/json/json_common_interface_test.rb
+++ b/test/json/json_common_interface_test.rb
@@ -1,5 +1,5 @@
#frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
require 'stringio'
require 'tempfile'
@@ -99,18 +99,26 @@ class JSONCommonInterfaceTest < Test::Unit::TestCase
def test_dump
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
- assert_equal too_deep, dump(eval(too_deep))
- assert_kind_of String, Marshal.dump(eval(too_deep))
- assert_raise(ArgumentError) { dump(eval(too_deep), 100) }
- assert_raise(ArgumentError) { Marshal.dump(eval(too_deep), 100) }
- assert_equal too_deep, dump(eval(too_deep), 101)
- assert_kind_of String, Marshal.dump(eval(too_deep), 101)
- output = StringIO.new
- dump(eval(too_deep), output)
- assert_equal too_deep, output.string
- output = StringIO.new
- dump(eval(too_deep), output, 101)
- assert_equal too_deep, output.string
+ obj = eval(too_deep)
+ assert_equal too_deep, dump(obj)
+ assert_kind_of String, Marshal.dump(obj)
+ assert_raise(ArgumentError) { dump(obj, 100) }
+ assert_raise(ArgumentError) { Marshal.dump(obj, 100) }
+ assert_equal too_deep, dump(obj, 101)
+ assert_kind_of String, Marshal.dump(obj, 101)
+
+ assert_equal too_deep, JSON.dump(obj, StringIO.new, 101, strict: false).string
+ assert_equal too_deep, dump(obj, StringIO.new, 101, strict: false).string
+ assert_raise(JSON::GeneratorError) { JSON.dump(Object.new, StringIO.new, 101, strict: true).string }
+ assert_raise(JSON::GeneratorError) { dump(Object.new, StringIO.new, 101, strict: true).string }
+
+ assert_equal too_deep, dump(obj, nil, nil, strict: false)
+ assert_equal too_deep, dump(obj, nil, 101, strict: false)
+ assert_equal too_deep, dump(obj, StringIO.new, nil, strict: false).string
+ assert_equal too_deep, dump(obj, nil, strict: false)
+ assert_equal too_deep, dump(obj, 101, strict: false)
+ assert_equal too_deep, dump(obj, StringIO.new, strict: false).string
+ assert_equal too_deep, dump(obj, strict: false)
end
def test_dump_should_modify_defaults
diff --git a/test/json/json_encoding_test.rb b/test/json/json_encoding_test.rb
index cc7b71553a..be87f3c3d6 100644
--- a/test/json/json_encoding_test.rb
+++ b/test/json/json_encoding_test.rb
@@ -1,6 +1,5 @@
-# encoding: utf-8
-#frozen_string_literal: false
-require 'test_helper'
+# frozen_string_literal: false
+require_relative 'test_helper'
class JSONEncodingTest < Test::Unit::TestCase
include JSON
@@ -86,9 +85,7 @@ class JSONEncodingTest < Test::Unit::TestCase
def test_chars
(0..0x7f).each do |i|
json = '["\u%04x"]' % i
- if RUBY_VERSION >= "1.9."
- i = i.chr
- end
+ i = i.chr
assert_equal i, parse(json).first[0]
if i == ?\b
generated = generate(["" << i])
diff --git a/test/json/json_ext_parser_test.rb b/test/json/json_ext_parser_test.rb
index c5a030ea8a..f49f88b596 100644
--- a/test/json/json_ext_parser_test.rb
+++ b/test/json/json_ext_parser_test.rb
@@ -1,8 +1,10 @@
#frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
class JSONExtParserTest < Test::Unit::TestCase
if defined?(JSON::Ext::Parser)
+ include JSON
+
def test_allocate
parser = JSON::Ext::Parser.new("{}")
assert_raise(TypeError, '[ruby-core:35079]') do
@@ -11,5 +13,22 @@ class JSONExtParserTest < Test::Unit::TestCase
parser = JSON::Ext::Parser.allocate
assert_raise(TypeError, '[ruby-core:35079]') { parser.source }
end
+
+ def test_error_messages
+ ex = assert_raise(ParserError) { parse('Infinity') }
+ assert_equal "unexpected token at 'Infinity'", ex.message
+
+ unless RUBY_PLATFORM =~ /java/
+ ex = assert_raise(ParserError) { parse('-Infinity') }
+ assert_equal "unexpected token at '-Infinity'", ex.message
+ end
+
+ ex = assert_raise(ParserError) { parse('NaN') }
+ assert_equal "unexpected token at 'NaN'", ex.message
+ end
+
+ def parse(json)
+ JSON::Ext::Parser.new(json).parse
+ end
end
end
diff --git a/test/json/json_fixtures_test.rb b/test/json/json_fixtures_test.rb
index 845abb4867..acc8749965 100644
--- a/test/json/json_fixtures_test.rb
+++ b/test/json/json_fixtures_test.rb
@@ -1,5 +1,5 @@
#frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
class JSONFixturesTest < Test::Unit::TestCase
def setup
diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb
index f31b6b290e..526bb8c1fe 100644..100755
--- a/test/json/json_generator_test.rb
+++ b/test/json/json_generator_test.rb
@@ -1,8 +1,7 @@
#!/usr/bin/env ruby
-# encoding: utf-8
# frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
class JSONGeneratorTest < Test::Unit::TestCase
include JSON
@@ -62,6 +61,14 @@ EOT
assert_equal '666', generate(666)
end
+ def test_dump_unenclosed_hash
+ assert_equal '{"a":1,"b":2}', dump(a: 1, b: 2)
+ end
+
+ def test_dump_strict
+ assert_equal '{}', dump({}, strict: true)
+ end
+
def test_generate_pretty
json = pretty_generate({})
assert_equal(<<'EOT'.chomp, json)
@@ -149,7 +156,8 @@ EOT
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
- :escape_slash => false,
+ :script_safe => false,
+ :strict => false,
:indent => " ",
:max_nesting => 100,
:object_nl => "\n",
@@ -166,7 +174,8 @@ EOT
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
- :escape_slash => false,
+ :script_safe => false,
+ :strict => false,
:indent => "",
:max_nesting => 100,
:object_nl => "",
@@ -183,7 +192,8 @@ EOT
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
- :escape_slash => false,
+ :script_safe => false,
+ :strict => false,
:indent => "",
:max_nesting => 0,
:object_nl => "",
@@ -233,7 +243,7 @@ EOT
def test_gc
if respond_to?(:assert_in_out_err) && !(RUBY_PLATFORM =~ /java/)
- assert_in_out_err(%w[-rjson --disable-gems], <<-EOS, [], [])
+ assert_in_out_err(%w[-rjson], <<-EOS, [], [])
bignum_too_long_to_embed_as_string = 1234567890123456789012345
expect = bignum_too_long_to_embed_as_string.to_s
GC.stress = true
@@ -336,7 +346,13 @@ EOT
def test_json_generate
assert_raise JSON::GeneratorError do
- assert_equal true, generate(["\xea"])
+ generate(["\xea"])
+ end
+ end
+
+ def test_json_generate_unsupported_types
+ assert_raise JSON::GeneratorError do
+ generate(Object.new, strict: true)
end
end
@@ -370,6 +386,18 @@ EOT
#
data = [ '/' ]
json = '["\/"]'
+ assert_equal json, generate(data, :script_safe => true)
+ #
+ data = [ "\u2028\u2029" ]
+ json = '["\u2028\u2029"]'
+ assert_equal json, generate(data, :script_safe => true)
+ #
+ data = [ "ABC \u2028 DEF \u2029 GHI" ]
+ json = '["ABC \u2028 DEF \u2029 GHI"]'
+ assert_equal json, generate(data, :script_safe => true)
+ #
+ data = [ "/\u2028\u2029" ]
+ json = '["\/\u2028\u2029"]'
assert_equal json, generate(data, :escape_slash => true)
#
data = ['"']
@@ -391,6 +419,31 @@ EOT
end
end
+ if defined?(JSON::Ext::Generator) and RUBY_PLATFORM != "java"
+ def test_string_ext_included_calls_super
+ included = false
+
+ Module.send(:alias_method, :included_orig, :included)
+ Module.send(:remove_method, :included)
+ Module.send(:define_method, :included) do |base|
+ included_orig(base)
+ included = true
+ end
+
+ Class.new(String) do
+ include JSON::Ext::Generator::GeneratorMethods::String
+ end
+
+ assert included
+ ensure
+ if Module.private_method_defined?(:included_orig)
+ Module.send(:remove_method, :included) if Module.method_defined?(:included)
+ Module.send(:alias_method, :included, :included_orig)
+ Module.send(:remove_method, :included_orig)
+ end
+ end
+ end
+
if defined?(Encoding)
def test_nonutf8_encoding
assert_equal("\"5\u{b0}\"", "5\xb0".force_encoding("iso-8859-1").to_json)
diff --git a/test/json/json_generic_object_test.rb b/test/json/json_generic_object_test.rb
index 82742dcd63..d6d7e30816 100644
--- a/test/json/json_generic_object_test.rb
+++ b/test/json/json_generic_object_test.rb
@@ -1,5 +1,5 @@
#frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
class JSONGenericObjectTest < Test::Unit::TestCase
include JSON
@@ -79,4 +79,4 @@ class JSONGenericObjectTest < Test::Unit::TestCase
ensure
JSON::GenericObject.json_creatable = false
end
-end
+end if defined?(JSON::GenericObject)
diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb
index 146ff7c047..49c7c8565d 100644
--- a/test/json/json_parser_test.rb
+++ b/test/json/json_parser_test.rb
@@ -1,10 +1,16 @@
# encoding: utf-8
# frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
require 'stringio'
require 'tempfile'
-require 'ostruct'
-require 'bigdecimal'
+begin
+ require 'ostruct'
+rescue LoadError
+end
+begin
+ require 'bigdecimal'
+rescue LoadError
+end
class JSONParserTest < Test::Unit::TestCase
include JSON
@@ -21,6 +27,9 @@ class JSONParserTest < Test::Unit::TestCase
end if defined?(Encoding::UTF_16)
def test_error_message_encoding
+ # https://github.com/flori/json/actions/runs/6478148162/job/17589572890
+ pend if RUBY_ENGINE == 'truffleruby'
+
bug10705 = '[ruby-core:67386] [Bug #10705]'
json = ".\"\xE2\x88\x9A\"".force_encoding(Encoding::UTF_8)
e = assert_raise(JSON::ParserError) {
@@ -113,7 +122,7 @@ class JSONParserTest < Test::Unit::TestCase
def test_parse_bigdecimals
assert_equal(BigDecimal, JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"].class)
assert_equal(BigDecimal("0.901234567890123456789E1"),JSON.parse('{"foo": 9.01234567890123456789}', decimal_class: BigDecimal)["foo"] )
- end
+ end if defined?(::BigDecimal)
def test_parse_string_mixed_unicode
assert_equal(["éé"], JSON.parse("[\"\\u00e9é\"]"))
@@ -406,21 +415,6 @@ EOT
end
end
- class SubOpenStruct < OpenStruct
- def [](k)
- __send__(k)
- end
-
- def []=(k, v)
- @item_set = true
- __send__("#{k}=", v)
- end
-
- def item_set?
- @item_set
- end
- end
-
def test_parse_object_custom_hash_derived_class
res = parse('{"foo":"bar"}', :object_class => SubHash)
assert_equal({"foo" => "bar"}, res)
@@ -428,24 +422,41 @@ EOT
assert res.item_set?
end
- def test_parse_object_custom_non_hash_derived_class
- res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
- assert_equal "bar", res.foo
- assert_equal(SubOpenStruct, res.class)
- assert res.item_set?
- end
+ if defined?(::OpenStruct)
+ class SubOpenStruct < OpenStruct
+ def [](k)
+ __send__(k)
+ end
- def test_parse_generic_object
- res = parse(
- '{"foo":"bar", "baz":{}}',
- :object_class => JSON::GenericObject
- )
- assert_equal(JSON::GenericObject, res.class)
- assert_equal "bar", res.foo
- assert_equal "bar", res["foo"]
- assert_equal "bar", res[:foo]
- assert_equal "bar", res.to_hash[:foo]
- assert_equal(JSON::GenericObject, res.baz.class)
+ def []=(k, v)
+ @item_set = true
+ __send__("#{k}=", v)
+ end
+
+ def item_set?
+ @item_set
+ end
+ end
+
+ def test_parse_object_custom_non_hash_derived_class
+ res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
+ assert_equal "bar", res.foo
+ assert_equal(SubOpenStruct, res.class)
+ assert res.item_set?
+ end
+
+ def test_parse_generic_object
+ res = parse(
+ '{"foo":"bar", "baz":{}}',
+ :object_class => JSON::GenericObject
+ )
+ assert_equal(JSON::GenericObject, res.class)
+ assert_equal "bar", res.foo
+ assert_equal "bar", res["foo"]
+ assert_equal "bar", res[:foo]
+ assert_equal "bar", res.to_hash[:foo]
+ assert_equal(JSON::GenericObject, res.baz.class)
+ end
end
def test_generate_core_subclasses_with_new_to_json
diff --git a/test/json/json_string_matching_test.rb b/test/json/json_string_matching_test.rb
index 5d55dc31b0..b9cf904aaa 100644
--- a/test/json/json_string_matching_test.rb
+++ b/test/json/json_string_matching_test.rb
@@ -1,5 +1,5 @@
#frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
require 'time'
class JSONStringMatchingTest < Test::Unit::TestCase
diff --git a/test/json/ractor_test.rb b/test/json/ractor_test.rb
index 71105e55ec..ba9bf7a7f6 100644
--- a/test/json/ractor_test.rb
+++ b/test/json/ractor_test.rb
@@ -1,7 +1,11 @@
-# encoding: utf-8
# frozen_string_literal: false
-require 'test_helper'
+require_relative 'test_helper'
+
+begin
+ require_relative './lib/helper'
+rescue LoadError
+end
class JSONInRactorTest < Test::Unit::TestCase
def test_generate
diff --git a/test/lib/!Nothing_to_test.rb b/test/lib/!Nothing_to_test.rb
new file mode 100644
index 0000000000..c1f4c439d3
--- /dev/null
+++ b/test/lib/!Nothing_to_test.rb
@@ -0,0 +1,5 @@
+### Empty test file for chkbuild ###
+
+# If chkbuild fails with `test-all`, each child file/directory is
+# executed individually, but test-unit fails if there are no test
+# files in the specified directory.
diff --git a/test/lib/jit_support.rb b/test/lib/jit_support.rb
index e607df4cab..cf3baaaeb7 100644
--- a/test/lib/jit_support.rb
+++ b/test/lib/jit_support.rb
@@ -1,103 +1,33 @@
require 'rbconfig'
module JITSupport
- JIT_TIMEOUT = 600 # 10min for each...
- JIT_SUCCESS_PREFIX = 'JIT success \(\d+\.\dms\)'
- JIT_RECOMPILE_PREFIX = 'JIT recompile'
- JIT_COMPACTION_PREFIX = 'JIT compaction \(\d+\.\dms\)'
- UNSUPPORTED_COMPILERS = [
- %r[\A.*/bin/intel64/icc\b],
- %r[\A/opt/developerstudio\d+\.\d+/bin/cc\z],
- ]
- # debian-riscv64: "gcc: internal compiler error: Segmentation fault signal terminated program cc1" https://rubyci.org/logs/rubyci.s3.amazonaws.com/debian-riscv64/ruby-master/log/20200420T083601Z.fail.html.gz
- # freebsd12: cc1 internal failure https://rubyci.org/logs/rubyci.s3.amazonaws.com/freebsd12/ruby-master/log/20200306T103003Z.fail.html.gz
- # rhel8: one or more PCH files were found, but they were invalid https://rubyci.org/logs/rubyci.s3.amazonaws.com/rhel8/ruby-master/log/20200306T153003Z.fail.html.gz
- # centos8: ditto https://rubyci.org/logs/rubyci.s3.amazonaws.com/centos8/ruby-master/log/20200512T003004Z.fail.html.gz
- PENDING_RUBYCI_NICKNAMES = %w[
- debian-riscv64
- freebsd12
- rhel8
- centos8
- ]
-
module_function
- # Run Ruby script with --mjit-wait (Synchronous JIT compilation).
- # Returns [stdout, stderr]
- def eval_with_jit(env = nil, script, **opts)
- stdout, stderr = nil, nil
- # retry 3 times while cc1 error happens.
- 3.times do |i|
- stdout, stderr, status = eval_with_jit_without_retry(env, script, **opts)
- assert_equal(true, status.success?, "Failed to run script with JIT:\n#{code_block(script)}\nstdout:\n#{code_block(stdout)}\nstderr:\n#{code_block(stderr)}")
- break unless retried_stderr?(stderr)
- end
- [stdout, stderr]
- end
-
- def eval_with_jit_without_retry(env = nil, script, verbose: 0, min_calls: 5, save_temps: false, max_cache: 1000, wait: true, timeout: JIT_TIMEOUT)
- args = [
- '--disable-gems', "--mjit-verbose=#{verbose}",
- "--mjit-min-calls=#{min_calls}", "--mjit-max-cache=#{max_cache}",
- ]
- args << '--disable-yjit'
- args << '--mjit-wait' if wait
- args << '--mjit-save-temps' if save_temps
- args << '--mjit-debug' if defined?(@mjit_debug) && @mjit_debug
- args << '-e' << script
- base_env = { 'MJIT_SEARCH_BUILD_DIR' => 'true' } # workaround to skip requiring `make install` for `make test-all`
- if preloadenv = RbConfig::CONFIG['PRELOADENV'] and !preloadenv.empty?
- so = "mjit_build_dir.#{RbConfig::CONFIG['SOEXT']}"
- base_env[preloadenv] = File.realpath(so) rescue nil
- end
- args.unshift(env ? base_env.merge!(env) : base_env)
- EnvUtil.invoke_ruby(args,
- '', true, true, timeout: timeout,
- )
- end
-
- def supported?
- return @supported if defined?(@supported)
- @supported = RbConfig::CONFIG["MJIT_SUPPORT"] != 'no' && UNSUPPORTED_COMPILERS.all? do |regexp|
- !regexp.match?(RbConfig::CONFIG['MJIT_CC'])
- end && !appveyor_pdb_corrupted? && !PENDING_RUBYCI_NICKNAMES.include?(ENV['RUBYCI_NICKNAME'])
- end
def yjit_supported?
- # e.g. x86_64-linux, x64-mswin64_140, x64-mingw32, x64-mingw-ucrt
- RUBY_PLATFORM.match?(/^(x86_64|x64)-/)
+ return @yjit_supported if defined?(@yjit_supported)
+ # nil in mswin
+ @yjit_supported = ![nil, 'no'].include?(RbConfig::CONFIG['YJIT_SUPPORT'])
end
- # AppVeyor's Visual Studio 2013 / 2015 are known to spuriously generate broken pch / pdb, like:
- # error C2859: c:\projects\ruby\x64-mswin_120\include\ruby-2.8.0\x64-mswin64_120\rb_mjit_header-2.8.0.pdb
- # is not the pdb file that was used when this precompiled header was created, recreate the precompiled header.
- # https://ci.appveyor.com/project/ruby/ruby/builds/32159878/job/l2p38snw8yxxpp8h
- #
- # Until we figure out why, this allows us to skip testing JIT when it happens.
- def appveyor_pdb_corrupted?
- return false unless ENV.key?('APPVEYOR')
- stdout, _stderr, _status = eval_with_jit_without_retry('proc {}.call', verbose: 2, min_calls: 1)
- stdout.include?('.pdb is not the pdb file that was used when this precompiled header was created, recreate the precompiled header.')
+ def yjit_enabled?
+ defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
end
- def remove_mjit_logs(stderr)
- if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # utility for -DFORCE_MJIT_ENABLE
- stderr.gsub(/^MJIT warning: Skipped to compile unsupported instruction: \w+\n/m, '')
- else
- stderr
- end
+ def yjit_force_enabled?
+ "#{RbConfig::CONFIG['CFLAGS']} #{RbConfig::CONFIG['CPPFLAGS']}".match?(/(\A|\s)-D ?YJIT_FORCE_ENABLE\b/)
end
- def code_block(code)
- %Q["""\n#{code}\n"""\n\n]
+ def rjit_supported?
+ return @rjit_supported if defined?(@rjit_supported)
+ # nil in mswin
+ @rjit_supported = ![nil, 'no'].include?(RbConfig::CONFIG['RJIT_SUPPORT'])
end
- # We're retrying cc1 not found error on gcc, which should be solved in the future but ignored for now.
- def retried_stderr?(stderr)
- RbConfig::CONFIG['CC'].start_with?('gcc') &&
- stderr.include?("error trying to exec 'cc1': execvp: No such file or directory")
+ def rjit_enabled?
+ defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
end
- def mjit_force_enabled?
- "#{RbConfig::CONFIG['CFLAGS']} #{RbConfig::CONFIG['CPPFLAGS']}".match?(/(\A|\s)-D ?MJIT_FORCE_ENABLE\b/)
+ def rjit_force_enabled?
+ "#{RbConfig::CONFIG['CFLAGS']} #{RbConfig::CONFIG['CPPFLAGS']}".match?(/(\A|\s)-D ?RJIT_FORCE_ENABLE\b/)
end
end
diff --git a/test/logger/test_severity.rb b/test/logger/test_severity.rb
index dad63472a6..e1069c8262 100644
--- a/test/logger/test_severity.rb
+++ b/test/logger/test_severity.rb
@@ -3,6 +3,8 @@
require 'logger'
class TestLoggerSeverity < Test::Unit::TestCase
+ include Logger::Severity
+
def test_enum
logger_levels = Logger.constants
levels = ["WARN", "UNKNOWN", "INFO", "FATAL", "DEBUG", "ERROR"]
@@ -23,4 +25,34 @@ class TestLoggerSeverity < Test::Unit::TestCase
assert(logger.level) == Logger::Severity.const_get(level)
end
end
+
+ def test_thread_local_level
+ logger = Logger.new(nil)
+ logger.level = INFO # default level
+ other = Logger.new(nil)
+ other.level = ERROR # default level
+
+ assert_equal(other.level, ERROR)
+ logger.with_level(:WARN) do
+ assert_equal(other.level, ERROR)
+ assert_equal(logger.level, WARN)
+
+ logger.with_level(DEBUG) do # verify reentrancy
+ assert_equal(logger.level, DEBUG)
+
+ Thread.new do
+ assert_equal(logger.level, INFO)
+ logger.with_level(:WARN) do
+ assert_equal(other.level, ERROR)
+ assert_equal(logger.level, WARN)
+ end
+ assert_equal(logger.level, INFO)
+ end.join
+
+ assert_equal(logger.level, DEBUG)
+ end
+ assert_equal(logger.level, WARN)
+ end
+ assert_equal(logger.level, INFO)
+ end
end
diff --git a/test/mkmf/base.rb b/test/mkmf/base.rb
index e097c396d6..7df07c16a6 100644
--- a/test/mkmf/base.rb
+++ b/test/mkmf/base.rb
@@ -106,6 +106,7 @@ class TestMkmf < Test::Unit::TestCase
end
def teardown
+ return if @omitted
rbconfig0 = @rbconfig
mkconfig0 = @mkconfig
RbConfig.module_eval {
@@ -146,7 +147,10 @@ class TestMkmf < Test::Unit::TestCase
include Base
- def assert_separately(args, src, *rest, **options)
- super(args + ["-r#{__FILE__}"], "extend TestMkmf::Base; setup\nEND{teardown}\n#{src}", *rest, **options)
+ def assert_separately(args, extra_args, src, *rest, **options)
+ super(args + ["-r#{__FILE__}"] + %w[- --] + extra_args,
+ "extend TestMkmf::Base; setup\nEND{teardown}\n#{src}",
+ *rest,
+ **options)
end
end
diff --git a/test/mkmf/test_config.rb b/test/mkmf/test_config.rb
index 3878db1964..0d2cb3751c 100644
--- a/test/mkmf/test_config.rb
+++ b/test/mkmf/test_config.rb
@@ -1,15 +1,57 @@
# frozen_string_literal: false
-$extmk = true
+require_relative 'base'
+require 'tempfile'
-require 'test/unit'
-require 'mkmf'
-
-class TestMkmfConfig < Test::Unit::TestCase
+class TestMkmfConfig < TestMkmf
def test_dir_config
bug8074 = '[Bug #8074]'
- lib = RbConfig.expand(RbConfig::MAKEFILE_CONFIG["libdir"], "exec_prefix"=>"")
- assert_separately %w[-rmkmf - -- --with-foo-dir=/test/foo], %{
- assert_equal(%w[/test/foo/include /test/foo#{lib}], dir_config("foo"), #{bug8074.dump})
- }
+ lib = RbConfig.expand(RbConfig::MAKEFILE_CONFIG["libdir"], "exec_prefix"=>"/test/foo")
+ assert_separately([], %w[--with-foo-dir=/test/foo], <<-"end;")
+ assert_equal(%w[/test/foo/include #{lib}], dir_config("foo"), #{bug8074.dump})
+ end;
+ end
+
+ def test_with_config_with_arg_and_value
+ assert_separately([], %w[--with-foo=bar], <<-'end;')
+ assert_equal("bar", with_config("foo"))
+ end;
+ end
+
+ def test_with_config_with_arg_and_no_value
+ assert_separately([], %w[--with-foo], <<-'end;')
+ assert_equal(true, with_config("foo"))
+ end;
+ end
+
+ def test_with_config_without_arg
+ assert_separately([], %w[--without-foo], <<-'end;')
+ assert_equal(false, with_config("foo"))
+ end;
+ end
+
+ def test_with_target_rbconfig
+ Tempfile.create(%w"rbconfig .rb", ".") do |tmp|
+ tmp.puts <<~'end;'
+ module RbConfig
+ CONFIG = {}
+ MAKEFILE_CONFIG = {}
+
+ def self.fire_update!(key, value); end
+ def self.expand(val, config = CONFIG); val; end
+ end;
+ ::RbConfig::CONFIG.each do |k, v|
+ tmp.puts " CONFIG[#{k.dump}] = #{v.dump}"
+ end
+ ::RbConfig::MAKEFILE_CONFIG.each do |k, v|
+ tmp.puts " MAKEFILE_CONFIG[#{k.dump}] = #{v.dump}"
+ end
+ tmp.puts " CONFIG['testing-only'] = 'ok'"
+ tmp.puts "end"
+ tmp.close
+ assert_separately([], ["--target-rbconfig=#{tmp.path}"], <<-'end;')
+ assert_equal("ok", MakeMakefile::RbConfig::CONFIG["testing-only"])
+ assert_not_equal(::RbConfig, MakeMakefile::RbConfig)
+ end;
+ end
end
end
diff --git a/test/mkmf/test_configuration.rb b/test/mkmf/test_configuration.rb
new file mode 100644
index 0000000000..0261f78a01
--- /dev/null
+++ b/test/mkmf/test_configuration.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: false
+require_relative 'base'
+
+class TestMkmfConfiguration < TestMkmf
+ def test_verbose_with_rbconfig_verbose_disabled
+ makefile = mkmf do
+ self.class::CONFIG['MKMF_VERBOSE'] = "0"
+ init_mkmf(self.class::CONFIG)
+ configuration '.'
+ end
+ verbose = makefile.grep(/^V =/).first[/^V = (.)$/, 1]
+
+ assert_equal "0", verbose
+ end
+
+ def test_verbose_with_rbconfig_verbose_enabled
+ makefile = mkmf do
+ self.class::CONFIG['MKMF_VERBOSE'] = "1"
+ init_mkmf(self.class::CONFIG)
+ configuration '.'
+ end
+ verbose = makefile.grep(/^V =/).first[/^V = (.)$/, 1]
+
+ assert_equal "1", verbose
+ end
+
+ def test_verbose_with_arg
+ assert_separately([], %w[--with-verbose], <<-'end;')
+ makefile = mkmf do
+ self.class::CONFIG['MKMF_VERBOSE'] = "0"
+ init_mkmf(self.class::CONFIG)
+ configuration '.'
+ end
+ verbose = makefile.grep(/^V =/).first[/^V = (.)$/, 1]
+
+ assert_equal "1", verbose
+ end;
+ end
+end
diff --git a/test/mkmf/test_constant.rb b/test/mkmf/test_constant.rb
index f6834c7f28..f22b82ff95 100644
--- a/test/mkmf/test_constant.rb
+++ b/test/mkmf/test_constant.rb
@@ -2,6 +2,14 @@
require_relative 'base'
class TestMkmfTryConstant < TestMkmf
+ def setup
+ if ENV.key?('APPVEYOR')
+ @omitted = true
+ omit 'This test fails too often on AppVeyor'
+ end
+ super
+ end
+
def test_simple
assert_equal( 0, mkmf {try_constant("0")}, MKMFLOG)
assert_equal( 1, mkmf {try_constant("1")}, MKMFLOG)
diff --git a/test/mkmf/test_flags.rb b/test/mkmf/test_flags.rb
index aedf06b610..6fde46adec 100644
--- a/test/mkmf/test_flags.rb
+++ b/test/mkmf/test_flags.rb
@@ -33,21 +33,21 @@ class TestMkmfFlags < TestMkmf
end
def test_try_ldflag_invalid_opt
- assert_separately([], <<-'end;') #do
+ assert_separately([], [], <<-'end;') #do
assert(!try_ldflags("nosuch.c"), TestMkmf::MKMFLOG)
assert(have_devel?, TestMkmf::MKMFLOG)
end;
end
def test_try_cflag_invalid_opt
- assert_separately([], <<-'end;', timeout: 30) #do
+ assert_separately([], [], <<-'end;', timeout: 30) #do
assert(!try_cflags("nosuch.c"), TestMkmf::MKMFLOG)
assert(have_devel?, TestMkmf::MKMFLOG)
end;
end
def test_try_cppflag_invalid_opt
- assert_separately([], <<-'end;') #do
+ assert_separately([], [], <<-'end;') #do
assert(!try_cppflags("nosuch.c"), TestMkmf::MKMFLOG)
assert(have_devel?, TestMkmf::MKMFLOG)
end;
diff --git a/test/mkmf/test_pkg_config.rb b/test/mkmf/test_pkg_config.rb
index 72efb4ba81..f6a960c7d9 100644
--- a/test/mkmf/test_pkg_config.rb
+++ b/test/mkmf/test_pkg_config.rb
@@ -3,7 +3,7 @@ require_relative 'base'
require 'shellwords'
class TestMkmfPkgConfig < TestMkmf
- PKG_CONFIG = find_executable0("pkg-config")
+ PKG_CONFIG = config_string("PKG_CONFIG") {|path| find_executable0(path)}
def setup
super
@@ -26,7 +26,7 @@ class TestMkmfPkgConfig < TestMkmf
Cflags: -I${includedir}/cflags-I --cflags-other
EOF
- @pkg_config_path, ENV["PKG_CONFIG_PATH"] = ENV["PKG_CONFIG_PATH"], File.join(Dir.pwd, "fixtures")
+ @pkg_config_path, ENV["PKG_CONFIG_PATH"] = ENV["PKG_CONFIG_PATH"], @fixtures_dir
end
end
diff --git a/test/monitor/test_monitor.rb b/test/monitor/test_monitor.rb
index 8ff6d006df..4c55afca6c 100644
--- a/test/monitor/test_monitor.rb
+++ b/test/monitor/test_monitor.rb
@@ -300,6 +300,8 @@ class TestMonitor < Test::Unit::TestCase
result4 = cond.wait
assert_equal(true, result4)
assert_equal("bar", c)
+ ensure
+ queue3.enq(nil)
end
end
assert_join_threads([th, th2])
diff --git a/test/net/fixtures/Makefile b/test/net/fixtures/Makefile
index b2bc9c7368..88c232e3b6 100644
--- a/test/net/fixtures/Makefile
+++ b/test/net/fixtures/Makefile
@@ -5,11 +5,11 @@ regen_certs:
make server.crt
cacert.pem: server.key
- openssl req -new -x509 -days 1825 -key server.key -out cacert.pem -text -subj "/C=JP/ST=Shimane/L=Matz-e city/O=Ruby Core Team/CN=Ruby Test CA/emailAddress=security@ruby-lang.org"
+ openssl req -new -x509 -days 3650 -key server.key -out cacert.pem -subj "/C=JP/ST=Shimane/L=Matz-e city/O=Ruby Core Team/CN=Ruby Test CA/emailAddress=security@ruby-lang.org"
server.csr:
- openssl req -new -key server.key -out server.csr -text -subj "/C=JP/ST=Shimane/O=Ruby Core Team/OU=Ruby Test/CN=localhost"
+ openssl req -new -key server.key -out server.csr -subj "/C=JP/ST=Shimane/O=Ruby Core Team/OU=Ruby Test/CN=localhost"
server.crt: server.csr cacert.pem
- openssl x509 -days 1825 -CA cacert.pem -CAkey server.key -set_serial 00 -in server.csr -req -text -out server.crt
+ openssl x509 -days 3650 -CA cacert.pem -CAkey server.key -set_serial 00 -in server.csr -req -out server.crt
rm server.csr
diff --git a/test/net/fixtures/cacert.pem b/test/net/fixtures/cacert.pem
index f623bd62ed..24c83f1c65 100644
--- a/test/net/fixtures/cacert.pem
+++ b/test/net/fixtures/cacert.pem
@@ -1,24 +1,24 @@
-----BEGIN CERTIFICATE-----
-MIID7TCCAtWgAwIBAgIJAIltvxrFAuSnMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
-VQQGEwJKUDEQMA4GA1UECAwHU2hpbWFuZTEUMBIGA1UEBwwLTWF0ei1lIGNpdHkx
-FzAVBgNVBAoMDlJ1YnkgQ29yZSBUZWFtMRUwEwYDVQQDDAxSdWJ5IFRlc3QgQ0Ex
-JTAjBgkqhkiG9w0BCQEWFnNlY3VyaXR5QHJ1YnktbGFuZy5vcmcwHhcNMTkwMTAy
-MDI1ODI4WhcNMjQwMTAxMDI1ODI4WjCBjDELMAkGA1UEBhMCSlAxEDAOBgNVBAgM
-B1NoaW1hbmUxFDASBgNVBAcMC01hdHotZSBjaXR5MRcwFQYDVQQKDA5SdWJ5IENv
-cmUgVGVhbTEVMBMGA1UEAwwMUnVieSBUZXN0IENBMSUwIwYJKoZIhvcNAQkBFhZz
-ZWN1cml0eUBydWJ5LWxhbmcub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAznlbjRVhz1NlutHVrhcGnK8W0qug2ujKXv1njSC4U6nJF6py7I9EeehV
-SaKePyv+I9z3K1LnfUHOtUbdwdKC77yN66A6q2aqzu5q09/NSykcZGOIF0GuItYI
-3nvW3IqBddff2ffsyR+9pBjfb5AIPP08WowF9q4s1eGULwZc4w2B8PFhtxYANd7d
-BvGLXFlcufv9tDtzyRi4t7eqxCRJkZQIZNZ6DHHIJrNxejOILfHLarI12yk8VK6L
-2LG4WgGqyeePiRyd1o1MbuiAFYqAwpXNUbRKg5NaZGwBHZk8UZ+uFKt1QMBURO5R
-WFy1c349jbWszTqFyL4Lnbg9HhAowQIDAQABo1AwTjAdBgNVHQ4EFgQU9tEiKdU9
-I9derQyc5nWPnc34nVMwHwYDVR0jBBgwFoAU9tEiKdU9I9derQyc5nWPnc34nVMw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAxj7F/u3C3fgq24N7hGRA
-of7ClFQxGmo/IGT0AISzW3HiVYiFaikKhbO1NwD9aBpD8Zwe62sCqMh8jGV/b0+q
-aOORnWYNy2R6r9FkASAglmdF6xn3bhgGD5ls4pCvcG9FynGnGc24g6MrjFNrBYUS
-2iIZsg36i0IJswo/Dy6HLphCms2BMCD3DeWtfjePUiTmQHJo6HsQIKP/u4N4Fvee
-uMBInei2M4VU74fLXbmKl1F9AEX7JDP3BKSZG19Ch5pnUo4uXM1uNTGsi07P4Y0s
-K44+SKBC0bYEFbDK0eQWMrX3kIhkPxyIWhxdq9/NqPYjShuSEAhA6CSpmRg0pqc+
-mA==
+MIID+zCCAuOgAwIBAgIUGMvHl3EhtKPKcgc3NQSAYfFuC+8wDQYJKoZIhvcNAQEL
+BQAwgYwxCzAJBgNVBAYTAkpQMRAwDgYDVQQIDAdTaGltYW5lMRQwEgYDVQQHDAtN
+YXR6LWUgY2l0eTEXMBUGA1UECgwOUnVieSBDb3JlIFRlYW0xFTATBgNVBAMMDFJ1
+YnkgVGVzdCBDQTElMCMGCSqGSIb3DQEJARYWc2VjdXJpdHlAcnVieS1sYW5nLm9y
+ZzAeFw0yNDAxMDExMTQ3MjNaFw0zMzEyMjkxMTQ3MjNaMIGMMQswCQYDVQQGEwJK
+UDEQMA4GA1UECAwHU2hpbWFuZTEUMBIGA1UEBwwLTWF0ei1lIGNpdHkxFzAVBgNV
+BAoMDlJ1YnkgQ29yZSBUZWFtMRUwEwYDVQQDDAxSdWJ5IFRlc3QgQ0ExJTAjBgkq
+hkiG9w0BCQEWFnNlY3VyaXR5QHJ1YnktbGFuZy5vcmcwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCw+egZQ6eumJKq3hfKfED4dE/tL4FI5sjqont9ABVI
++1GSqyi1bFBgsRjM0THllIdMbKmJtWwnKW8J+5OgNN8y6Xxv8JmM/Y5vQt2lis0f
+qXmG8UTz0VTWdlAXXmhUs6lSADvAaIe4RVrCsZ97L3ZQTryY7JRVcbB4khUN3Gp0
+yg+801SXzoFTTa+UGIRLE66jH51aa5VXu99hnv1OiH8tQrjdi8mH6uG/icq4XuIe
+NWMF32wHqIOOPvQcWV3M5D2vxJEj702Ku6k9OQXkAo17qRSEonWW4HtLbtmS8He1
+JNPc/n3dVUm+fM6NoDXPoLP7j55G9zKyqGtGAWXAj1MTAgMBAAGjUzBRMB0GA1Ud
+DgQWBBSJGVleDvFp9cu9R+E0/OKYzGkwkTAfBgNVHSMEGDAWgBSJGVleDvFp9cu9
+R+E0/OKYzGkwkTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBl
+8GLB8skAWlkSw/FwbUmEV3zyqu+p7PNP5YIYoZs0D74e7yVulGQ6PKMZH5hrZmHo
+orFSQU+VUUirG8nDGj7Rzce8WeWBxsaDGC8CE2dq6nC6LuUwtbdMnBrH0LRWAz48
+jGFF3jHtVz8VsGfoZTZCjukWqNXvU6hETT9GsfU+PZqbqcTVRPH52+XgYayKdIbD
+r97RM4X3+aXBHcUW0b76eyyi65RR/Xtvn8ioZt2AdX7T2tZzJyXJN3Hupp77s6Ui
+AZR35SToHCZeTZD12YBvLBdaTPLZN7O/Q/aAO9ZiJaZ7SbFOjz813B2hxXab4Fob
+2uJX6eMWTVxYK5D4M9lm
-----END CERTIFICATE-----
diff --git a/test/net/fixtures/server.crt b/test/net/fixtures/server.crt
index 5ca78a6d14..5d2923795d 100644
--- a/test/net/fixtures/server.crt
+++ b/test/net/fixtures/server.crt
@@ -1,82 +1,21 @@
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number: 2 (0x2)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=JP, ST=Shimane, L=Matz-e city, O=Ruby Core Team, CN=Ruby Test CA/emailAddress=security@ruby-lang.org
- Validity
- Not Before: Jan 2 03:27:13 2019 GMT
- Not After : Jan 1 03:27:13 2024 GMT
- Subject: C=JP, ST=Shimane, O=Ruby Core Team, OU=Ruby Test, CN=localhost
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:e8:da:9c:01:2e:2b:10:ec:49:cd:5e:07:13:07:
- 9c:70:9e:c6:74:bc:13:c2:e1:6f:c6:82:fd:e3:48:
- e0:2c:a5:68:c7:9e:42:de:60:54:65:e6:6a:14:57:
- 7a:30:d0:cc:b5:b6:d9:c3:d2:df:c9:25:97:54:67:
- cf:f6:be:5e:cb:8b:ee:03:c5:e1:e2:f9:e7:f7:d1:
- 0c:47:f0:b8:da:33:5a:ad:41:ad:e7:b5:a2:7b:b7:
- bf:30:da:60:f8:e3:54:a2:bc:3a:fd:1b:74:d9:dc:
- 74:42:e9:29:be:df:ac:b4:4f:eb:32:f4:06:f1:e1:
- 8c:4b:a8:8b:fb:29:e7:b1:bf:1d:01:ee:73:0f:f9:
- 40:dc:d5:15:79:d9:c6:73:d0:c0:dd:cb:e4:da:19:
- 47:80:c6:14:04:72:fd:9a:7c:8f:11:82:76:49:04:
- 79:cc:f2:5c:31:22:95:13:3e:5d:40:a6:4d:e0:a3:
- 02:26:7d:52:3b:bb:ed:65:a1:0f:ed:6b:b0:3c:d4:
- de:61:15:5e:d3:dd:68:09:9f:4a:57:a5:c2:a9:6d:
- 86:92:c5:f4:a4:d4:b7:13:3b:52:63:24:05:e2:cc:
- e3:8a:3c:d4:35:34:2b:10:bb:58:72:e7:e1:8d:1d:
- 74:8c:61:16:20:3d:d0:1c:4e:8f:6e:fd:fe:64:10:
- 4f:41
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:FALSE
- Netscape Comment:
- OpenSSL Generated Certificate
- X509v3 Subject Key Identifier:
- ED:28:C2:7E:AB:4B:C8:E8:FE:55:6D:66:95:31:1C:2D:60:F9:02:36
- X509v3 Authority Key Identifier:
- keyid:F6:D1:22:29:D5:3D:23:D7:5E:AD:0C:9C:E6:75:8F:9D:CD:F8:9D:53
-
- Signature Algorithm: sha256WithRSAEncryption
- 1d:b8:c5:8b:72:41:20:65:ad:27:6f:15:63:06:26:12:8d:9c:
- ad:ca:f4:db:97:b4:90:cb:ff:35:94:bb:2a:a7:a1:ab:1e:35:
- 2d:a5:3f:c9:24:b0:1a:58:89:75:3e:81:0a:2c:4f:98:f9:51:
- fb:c0:a3:09:d0:0a:9b:e7:a2:b7:c3:60:40:c8:f4:6d:b2:6a:
- 56:12:17:4c:00:24:31:df:9c:60:ae:b1:68:54:a9:e6:b5:4a:
- 04:e6:92:05:86:d9:5a:dc:96:30:a5:58:de:14:99:0f:e5:15:
- 89:3e:9b:eb:80:e3:bd:83:c3:ea:33:35:4b:3e:2f:d3:0d:64:
- 93:67:7f:8d:f5:3f:0c:27:bc:37:5a:cc:d6:47:16:af:5a:62:
- d2:da:51:f8:74:06:6b:24:ad:28:68:08:98:37:7d:ed:0e:ab:
- 1e:82:61:05:d0:ba:75:a0:ab:21:b0:9a:fd:2b:54:86:1d:0d:
- 1f:c2:d4:77:1f:72:26:5e:ad:8a:9f:09:36:6d:44:be:74:c2:
- 5a:3e:ff:5c:9d:75:d6:38:7b:c5:39:f9:44:6e:a1:d1:8e:ff:
- 63:db:c4:bb:c6:91:92:ca:5c:60:9b:1d:eb:0a:de:08:ee:bf:
- da:76:03:65:62:29:8b:f8:7f:c7:86:73:1e:f6:1f:2d:89:69:
- fd:be:bd:6e
-----BEGIN CERTIFICATE-----
-MIID4zCCAsugAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCSlAx
-EDAOBgNVBAgMB1NoaW1hbmUxFDASBgNVBAcMC01hdHotZSBjaXR5MRcwFQYDVQQK
-DA5SdWJ5IENvcmUgVGVhbTEVMBMGA1UEAwwMUnVieSBUZXN0IENBMSUwIwYJKoZI
-hvcNAQkBFhZzZWN1cml0eUBydWJ5LWxhbmcub3JnMB4XDTE5MDEwMjAzMjcxM1oX
-DTI0MDEwMTAzMjcxM1owYDELMAkGA1UEBhMCSlAxEDAOBgNVBAgMB1NoaW1hbmUx
-FzAVBgNVBAoMDlJ1YnkgQ29yZSBUZWFtMRIwEAYDVQQLDAlSdWJ5IFRlc3QxEjAQ
-BgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AOjanAEuKxDsSc1eBxMHnHCexnS8E8Lhb8aC/eNI4CylaMeeQt5gVGXmahRXejDQ
-zLW22cPS38kll1Rnz/a+XsuL7gPF4eL55/fRDEfwuNozWq1Bree1onu3vzDaYPjj
-VKK8Ov0bdNncdELpKb7frLRP6zL0BvHhjEuoi/sp57G/HQHucw/5QNzVFXnZxnPQ
-wN3L5NoZR4DGFARy/Zp8jxGCdkkEeczyXDEilRM+XUCmTeCjAiZ9Uju77WWhD+1r
-sDzU3mEVXtPdaAmfSlelwqlthpLF9KTUtxM7UmMkBeLM44o81DU0KxC7WHLn4Y0d
-dIxhFiA90BxOj279/mQQT0ECAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhC
-AQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFO0o
-wn6rS8jo/lVtZpUxHC1g+QI2MB8GA1UdIwQYMBaAFPbRIinVPSPXXq0MnOZ1j53N
-+J1TMA0GCSqGSIb3DQEBCwUAA4IBAQAduMWLckEgZa0nbxVjBiYSjZytyvTbl7SQ
-y/81lLsqp6GrHjUtpT/JJLAaWIl1PoEKLE+Y+VH7wKMJ0Aqb56K3w2BAyPRtsmpW
-EhdMACQx35xgrrFoVKnmtUoE5pIFhtla3JYwpVjeFJkP5RWJPpvrgOO9g8PqMzVL
-Pi/TDWSTZ3+N9T8MJ7w3WszWRxavWmLS2lH4dAZrJK0oaAiYN33tDqsegmEF0Lp1
-oKshsJr9K1SGHQ0fwtR3H3ImXq2Knwk2bUS+dMJaPv9cnXXWOHvFOflEbqHRjv9j
-28S7xpGSylxgmx3rCt4I7r/adgNlYimL+H/HhnMe9h8tiWn9vr1u
+MIIDYTCCAkkCAQAwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAkpQMRAwDgYD
+VQQIDAdTaGltYW5lMRQwEgYDVQQHDAtNYXR6LWUgY2l0eTEXMBUGA1UECgwOUnVi
+eSBDb3JlIFRlYW0xFTATBgNVBAMMDFJ1YnkgVGVzdCBDQTElMCMGCSqGSIb3DQEJ
+ARYWc2VjdXJpdHlAcnVieS1sYW5nLm9yZzAeFw0yNDAxMDExMTQ3MjNaFw0zMzEy
+MjkxMTQ3MjNaMGAxCzAJBgNVBAYTAkpQMRAwDgYDVQQIDAdTaGltYW5lMRcwFQYD
+VQQKDA5SdWJ5IENvcmUgVGVhbTESMBAGA1UECwwJUnVieSBUZXN0MRIwEAYDVQQD
+DAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCw+egZ
+Q6eumJKq3hfKfED4dE/tL4FI5sjqont9ABVI+1GSqyi1bFBgsRjM0THllIdMbKmJ
+tWwnKW8J+5OgNN8y6Xxv8JmM/Y5vQt2lis0fqXmG8UTz0VTWdlAXXmhUs6lSADvA
+aIe4RVrCsZ97L3ZQTryY7JRVcbB4khUN3Gp0yg+801SXzoFTTa+UGIRLE66jH51a
+a5VXu99hnv1OiH8tQrjdi8mH6uG/icq4XuIeNWMF32wHqIOOPvQcWV3M5D2vxJEj
+702Ku6k9OQXkAo17qRSEonWW4HtLbtmS8He1JNPc/n3dVUm+fM6NoDXPoLP7j55G
+9zKyqGtGAWXAj1MTAgMBAAEwDQYJKoZIhvcNAQELBQADggEBACtGNdj5TEtnJBYp
+M+LhBeU3oNteldfycEm993gJp6ghWZFg23oX8fVmyEeJr/3Ca9bAgDqg0t9a0npN
+oWKEY6wVKqcHgu3gSvThF5c9KhGbeDDmlTSVVNQmXWX0K2d4lS2cwZHH8mCm2mrY
+PDqlEkSc7k4qSiqigdS8i80Yk+lDXWsm8CjsiC93qaRM7DnS0WPQR0c16S95oM6G
+VklFKUSDAuFjw9aVWA/nahOucjn0w5fVW6lyIlkBslC1ChlaDgJmvhz+Ol3iMsE0
+kAmFNu2KKPVrpMWaBID49QwQTDyhetNLaVVFM88iUdA9JDoVMEuP1mm39JqyzHTu
+uBrdP4Q=
-----END CERTIFICATE-----
diff --git a/test/net/fixtures/server.key b/test/net/fixtures/server.key
index 7f2380e71e..6a83d5bcf4 100644
--- a/test/net/fixtures/server.key
+++ b/test/net/fixtures/server.key
@@ -1,28 +1,27 @@
------BEGIN PRIVATE KEY-----
-MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDo2pwBLisQ7EnN
-XgcTB5xwnsZ0vBPC4W/Ggv3jSOAspWjHnkLeYFRl5moUV3ow0My1ttnD0t/JJZdU
-Z8/2vl7Li+4DxeHi+ef30QxH8LjaM1qtQa3ntaJ7t78w2mD441SivDr9G3TZ3HRC
-6Sm+36y0T+sy9Abx4YxLqIv7Keexvx0B7nMP+UDc1RV52cZz0MDdy+TaGUeAxhQE
-cv2afI8RgnZJBHnM8lwxIpUTPl1Apk3gowImfVI7u+1loQ/ta7A81N5hFV7T3WgJ
-n0pXpcKpbYaSxfSk1LcTO1JjJAXizOOKPNQ1NCsQu1hy5+GNHXSMYRYgPdAcTo9u
-/f5kEE9BAgMBAAECggEBAOHkwhc7DLh8IhTDNSW26oMu5OP2WU1jmiYAigDmf+OQ
-DBgrZj+JQBci8qINQxL8XLukSZn5hvQCLc7Kbyu1/wyEEUFDxSGGwwzclodr9kho
-LX2LDASPZrOSzD2+fPi2wTKmXKuS6Uc44OjQfZkYMNkz9r4Vkm8xGgOD3VipjIYX
-QXlhhdqkXZcNABsihCV52GKkDFSVm8jv95YJc5xhoYCy/3a4/qPdF0aT2R7oYUej
-hKrxVDskyooe8Zg/JTydZNV5GQEDmW01/K3r6XGT26oPi1AqMU1gtv/jkW56CRQQ
-1got8smnqM+AV7Slf9R6DauIPdQJ2S8wsr/o8ISBsOECgYEA9YrqEP2gAYSGFXRt
-liw0WI2Ant8BqXS6yvq1jLo/qWhLw/ph4Di73OQ2mpycVTpgfGr2wFPQR1XJ+0Fd
-U+Ir/C3Q7FK4VIGHK7B0zNvZr5tEjlFfeRezo2JMVw5YWeSagIFcSwK+KqCTH9qc
-pw/Eb8nB/4XNcpTZu7Fg0Wc+ooUCgYEA8sVaicn1Wxkpb45a4qfrA6wOr5xdJ4cC
-A5qs7vjX2OdPIQOmoQhdI7bCWFXZzF33wA4YCws6j5wRaySLIJqdms8Gl9QnODy1
-ZlA5gwKToBC/jqPmWAXSKb8EH7cHilaxU9OKnQ7CfwlGLHqjMtjrhR7KHlt3CVRs
-oRmvsjZVXI0CgYAmPedslAO6mMhFSSfULrhMXmV82OCqYrrA6EEkVNGbcdnzAOkD
-gfKIWabDd8bFY10po4Mguy0CHzNhBXIioWQWV5BlbhC1YKMLw+S9DzSdLAKGY9gJ
-xQ4+UQ3wtRQ/k+IYR413RUsW2oFvgZ3KSyNeAb9MK6uuv84VdG/OzVSs/QKBgQDn
-kap//l2EbObiWyaERunckdVcW0lcN+KK75J/TGwPoOwQsLvTpPe65kxRGGrtDsEQ
-uCDk/+v3KkZPLgdrrTAih9FhJ+PVN8tMcb+6IM4SA4fFFr/UPJEwct0LJ3oQ0grJ
-y+HPWFHb/Uurh7t99/4H98uR02sjQh1wOeEmm78mzQKBgQDm+LzGH0se6CXQ6cdZ
-g1JRZeXkDEsrW3hfAsW62xJQmXcWxBoblP9OamMY+A06rM5og3JbDk5Zm6JsOaA8
-wS2gw4ilp46jors4eQey8ux7kB9LzdBoDBBElnsbjLO8oBNZlVcYXg+6BOl/CUi7
-2whRF0FEjKA8ehrNhAq+VFfFNw==
------END PRIVATE KEY-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAsPnoGUOnrpiSqt4XynxA+HRP7S+BSObI6qJ7fQAVSPtRkqso
+tWxQYLEYzNEx5ZSHTGypibVsJylvCfuToDTfMul8b/CZjP2Ob0LdpYrNH6l5hvFE
+89FU1nZQF15oVLOpUgA7wGiHuEVawrGfey92UE68mOyUVXGweJIVDdxqdMoPvNNU
+l86BU02vlBiESxOuox+dWmuVV7vfYZ79Toh/LUK43YvJh+rhv4nKuF7iHjVjBd9s
+B6iDjj70HFldzOQ9r8SRI+9NirupPTkF5AKNe6kUhKJ1luB7S27ZkvB3tSTT3P59
+3VVJvnzOjaA1z6Cz+4+eRvcysqhrRgFlwI9TEwIDAQABAoIBAEEYiyDP29vCzx/+
+dS3LqnI5BjUuJhXUnc6AWX/PCgVAO+8A+gZRgvct7PtZb0sM6P9ZcLrweomlGezI
+FrL0/6xQaa8bBr/ve/a8155OgcjFo6fZEw3Dz7ra5fbSiPmu4/b/kvrg+Br1l77J
+aun6uUAs1f5B9wW+vbR7tzbT/mxaUeDiBzKpe15GwcvbJtdIVMa2YErtRjc1/5B2
+BGVXyvlJv0SIlcIEMsHgnAFOp1ZgQ08aDzvilLq8XVMOahAhP1O2A3X8hKdXPyrx
+IVWE9bS9ptTo+eF6eNl+d7htpKGEZHUxinoQpWEBTv+iOoHsVunkEJ3vjLP3lyI/
+fY0NQ1ECgYEA3RBXAjgvIys2gfU3keImF8e/TprLge1I2vbWmV2j6rZCg5r/AS0u
+pii5CvJ5/T5vfJPNgPBy8B/yRDs+6PJO1GmnlhOkG9JAIPkv0RBZvR0PMBtbp6nT
+Y3yo1lwamBVBfY6rc0sLTzosZh2aGoLzrHNMQFMGaauORzBFpY5lU50CgYEAzPHl
+u5DI6Xgep1vr8QvCUuEesCOgJg8Yh1UqVoY/SmQh6MYAv1I9bLGwrb3WW/7kqIoD
+fj0aQV5buVZI2loMomtU9KY5SFIsPV+JuUpy7/+VE01ZQM5FdY8wiYCQiVZYju9X
+Wz5LxMNoz+gT7pwlLCsC4N+R8aoBk404aF1gum8CgYAJ7VTq7Zj4TFV7Soa/T1eE
+k9y8a+kdoYk3BASpCHJ29M5R2KEA7YV9wrBklHTz8VzSTFTbKHEQ5W5csAhoL5Fo
+qoHzFFi3Qx7MHESQb9qHyolHEMNx6QdsHUn7rlEnaTTyrXh3ifQtD6C0yTmFXUIS
+CW9wKApOrnyKJ9nI0HcuZQKBgQCMtoV6e9VGX4AEfpuHvAAnMYQFgeBiYTkBKltQ
+XwozhH63uMMomUmtSG87Sz1TmrXadjAhy8gsG6I0pWaN7QgBuFnzQ/HOkwTm+qKw
+AsrZt4zeXNwsH7QXHEJCFnCmqw9QzEoZTrNtHJHpNboBuVnYcoueZEJrP8OnUG3r
+UjmopwKBgAqB2KYYMUqAOvYcBnEfLDmyZv9BTVNHbR2lKkMYqv5LlvDaBxVfilE0
+2riO4p6BaAdvzXjKeRrGNEKoHNBpOSfYCOM16NjL8hIZB1CaV3WbT5oY+jp7Mzd5
+7d56RZOE+ERK2uz/7JX9VSsM/LbH9pJibd4e8mikDS9ntciqOH/3
+-----END RSA PRIVATE KEY-----
diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb
index e9471273f4..f0f1bc2d8f 100644
--- a/test/net/http/test_http.rb
+++ b/test/net/http/test_http.rb
@@ -126,10 +126,10 @@ class TestNetHTTP < Test::Unit::TestCase
def test_proxy_address_no_proxy
TestNetHTTPUtils.clean_http_proxy_env do
- http = Net::HTTP.new 'hostname.example', nil, 'proxy.example', nil, nil, nil, 'example'
+ http = Net::HTTP.new 'hostname.example', nil, 'proxy.com', nil, nil, nil, 'example'
assert_nil http.proxy_address
- http = Net::HTTP.new '10.224.1.1', nil, 'proxy.example', nil, nil, nil, 'example,10.224.0.0/22'
+ http = Net::HTTP.new '10.224.1.1', nil, 'proxy.com', nil, nil, nil, 'example,10.224.0.0/22'
assert_nil http.proxy_address
end
end
@@ -178,13 +178,8 @@ class TestNetHTTP < Test::Unit::TestCase
http = Net::HTTP.new 'hostname.example'
assert_equal true, http.proxy?
- if Net::HTTP::ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE
- assert_equal 'foo', http.proxy_user
- assert_equal 'bar', http.proxy_pass
- else
- assert_nil http.proxy_user
- assert_nil http.proxy_pass
- end
+ assert_equal 'foo', http.proxy_user
+ assert_equal 'bar', http.proxy_pass
end
end
@@ -195,13 +190,8 @@ class TestNetHTTP < Test::Unit::TestCase
http = Net::HTTP.new 'hostname.example'
assert_equal true, http.proxy?
- if Net::HTTP::ENVIRONMENT_VARIABLE_IS_MULTIUSER_SAFE
- assert_equal "Y\\X", http.proxy_user
- assert_equal "R%S] ?X", http.proxy_pass
- else
- assert_nil http.proxy_user
- assert_nil http.proxy_pass
- end
+ assert_equal "Y\\X", http.proxy_user
+ assert_equal "R%S] ?X", http.proxy_pass
end
end
@@ -1244,6 +1234,16 @@ class TestNetHTTPKeepAlive < Test::Unit::TestCase
}
end
+ def test_http_retry_failed_with_block
+ start {|http|
+ http.max_retries = 10
+ called = 0
+ assert_raise(Errno::ECONNRESET){ http.get('/'){called += 1; raise Errno::ECONNRESET} }
+ assert_equal 1, called
+ }
+ @log_tester = nil
+ end
+
def test_keep_alive_server_close
def @server.run(sock)
sock.close
diff --git a/test/net/http/test_httpheader.rb b/test/net/http/test_httpheader.rb
index b1ca9e8225..69563168db 100644
--- a/test/net/http/test_httpheader.rb
+++ b/test/net/http/test_httpheader.rb
@@ -28,7 +28,11 @@ class HTTPHeaderTest < Test::Unit::TestCase
assert_raise(NoMethodError){ @c.initialize_http_header("foo"=>[]) }
assert_raise(ArgumentError){ @c.initialize_http_header("foo"=>"a\nb") }
assert_raise(ArgumentError){ @c.initialize_http_header("foo"=>"a\rb") }
- assert_raise(ArgumentError){ @c.initialize_http_header("foo"=>"a\xff") }
+ end
+
+ def test_initialize_with_broken_coderange
+ error = RUBY_VERSION >= "3.2" ? Encoding::CompatibilityError : ArgumentError
+ assert_raise(error){ @c.initialize_http_header("foo"=>"a\xff") }
end
def test_initialize_with_symbol
diff --git a/test/net/http/test_httpresponse.rb b/test/net/http/test_httpresponse.rb
index 394b4c5bfa..01281063cd 100644
--- a/test/net/http/test_httpresponse.rb
+++ b/test/net/http/test_httpresponse.rb
@@ -312,8 +312,8 @@ EOS
end
def test_read_body_block_mod
- # http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/3019353
- if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ # http://ci.rvm.jp/results/trunk-rjit-wait@silicon-docker/3019353
+ if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
omit 'too unstable with --jit-wait, and extending read_timeout did not help it'
end
IO.pipe do |r, w|
@@ -589,6 +589,41 @@ EOS
assert_equal 'hello', body
end
+ def test_read_body_receiving_no_body
+ io = dummy_io(<<EOS)
+HTTP/1.1 204 OK
+Connection: close
+
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+ res.body_encoding = 'utf-8'
+
+ body = 'something to override'
+
+ res.reading_body io, true do
+ body = res.read_body
+ end
+
+ assert_equal nil, body
+ assert_equal nil, res.body
+ end
+
+ def test_read_body_outside_of_reading_body
+ io = dummy_io(<<EOS)
+HTTP/1.1 200 OK
+Connection: close
+Content-Length: 0
+
+EOS
+
+ res = Net::HTTPResponse.read_new(io)
+
+ assert_raise IOError do
+ res.read_body
+ end
+ end
+
def test_uri_equals
uri = URI 'http://example'
diff --git a/test/net/http/test_https.rb b/test/net/http/test_https.rb
index 72a69af1a5..6b3171d265 100644
--- a/test/net/http/test_https.rb
+++ b/test/net/http/test_https.rb
@@ -148,7 +148,7 @@ class TestNetHTTPS < Test::Unit::TestCase
# support session resuse. Limiting the version to the TLSv1.2 stack allows
# this test to continue to work on LibreSSL 3.2+. LibreSSL may eventually
# support session reuse, but there are no current plans to do so.
- http.ssl_version = :TLSv1
+ http.ssl_version = :TLSv1_2
end
http.start
@@ -167,6 +167,7 @@ class TestNetHTTPS < Test::Unit::TestCase
def test_session_reuse_but_expire
# FIXME: The new_session_cb is known broken for clients in OpenSSL 1.1.0h.
omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 1.1.0h')
+ omit if OpenSSL::OPENSSL_LIBRARY_VERSION.include?('OpenSSL 3.2.')
http = Net::HTTP.new(HOST, config("port"))
http.use_ssl = true
@@ -181,7 +182,7 @@ class TestNetHTTPS < Test::Unit::TestCase
http.get("/")
socket = http.instance_variable_get(:@socket).io
- assert_equal false, socket.session_reused?
+ assert_equal false, socket.session_reused?, "NOTE: OpenSSL library version is #{OpenSSL::OPENSSL_LIBRARY_VERSION}"
http.finish
end
diff --git a/test/net/protocol/test_protocol.rb b/test/net/protocol/test_protocol.rb
index d3dc2ccf4c..2f42fa3236 100644
--- a/test/net/protocol/test_protocol.rb
+++ b/test/net/protocol/test_protocol.rb
@@ -57,6 +57,14 @@ class TestProtocol < Test::Unit::TestCase
mockio
end
+ def test_readuntil
+ assert_output("", "") do
+ sio = StringIO.new("12345".dup)
+ io = Net::BufferedIO.new(sio)
+ assert_equal "12345", io.readuntil("5")
+ end
+ end
+
def test_write0_multibyte
mockio = create_mockio(max: 1)
io = Net::BufferedIO.new(mockio)
@@ -119,4 +127,33 @@ class TestProtocol < Test::Unit::TestCase
io.write_timeout = 0.1
assert_raise(Net::WriteTimeout){ io.write("a"*50,"a"*50,"a") }
end
+
+ class FakeReadPartialIO
+ def initialize(chunks)
+ @chunks = chunks.map(&:dup)
+ end
+
+ def read_nonblock(size, buf = nil, exception: false)
+ if buf
+ buf.replace(@chunks.shift)
+ buf
+ else
+ @chunks.shift
+ end
+ end
+ end
+
+ def test_shareable_buffer_leak # https://github.com/ruby/net-protocol/pull/19
+ expected_chunks = [
+ "aaaaa",
+ "bbbbb",
+ ]
+ fake_io = FakeReadPartialIO.new(expected_chunks)
+ io = Net::BufferedIO.new(fake_io)
+ actual_chunks = []
+ reader = Net::ReadAdapter.new(-> (chunk) { actual_chunks << chunk })
+ io.read(5, reader)
+ io.read(5, reader)
+ assert_equal expected_chunks, actual_chunks
+ end
end
diff --git a/test/nkf/test_kconv.rb b/test/nkf/test_kconv.rb
deleted file mode 100644
index 3968cc47dc..0000000000
--- a/test/nkf/test_kconv.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'kconv'
-
-class TestKconv < Test::Unit::TestCase
- def setup
- @euc_str = "\
-\xa5\xaa\xa5\xd6\xa5\xb8\xa5\xa7\xa5\xaf\xa5\xc8\xbb\xd8\xb8\xfe\
-\xa5\xd7\xa5\xed\xa5\xb0\xa5\xe9\xa5\xdf\xa5\xf3\xa5\xb0\xb8\xc0\xb8\xec\
-\x52\x75\x62\x79".force_encoding('EUC-JP')
- @utf8_str = "\
-\xe3\x82\xaa\xe3\x83\x96\xe3\x82\xb8\xe3\x82\xa7\
-\xe3\x82\xaf\xe3\x83\x88\xe6\x8c\x87\xe5\x90\x91\
-\xe3\x83\x97\xe3\x83\xad\xe3\x82\xb0\xe3\x83\xa9\xe3\x83\x9f\
-\xe3\x83\xb3\xe3\x82\xb0\xe8\xa8\x80\xe8\xaa\x9e\
-\x52\x75\x62\x79".force_encoding('UTF-8')
- @sjis_str = "\
-\x83\x49\x83\x75\x83\x57\x83\x46\x83\x4e\x83\x67\x8e\x77\x8c\xfc\
-\x83\x76\x83\x8d\x83\x4f\x83\x89\x83\x7e\x83\x93\x83\x4f\x8c\xbe\x8c\xea\
-\x52\x75\x62\x79".force_encoding('Shift_JIS')
- @jis_str = "\
-\x1b\x24\x42\x25\x2a\x25\x56\x25\x38\x25\x27\x25\x2f\x25\x48\x3b\x58\x38\x7e\
-\x25\x57\x25\x6d\x25\x30\x25\x69\x25\x5f\x25\x73\x25\x30\x38\x40\x38\x6c\x1b\x28\x42\
-\x52\x75\x62\x79".force_encoding('ISO-2022-JP')
- end
-
-
- def test_eucjp
- assert(@euc_str.iseuc)
- assert_equal(::Kconv::EUC, Kconv.guess(@euc_str))
- assert_equal(@euc_str, @euc_str.toeuc)
- assert_equal(@euc_str, @sjis_str.toeuc)
- assert_equal(@euc_str, @utf8_str.toeuc)
- assert_equal(@euc_str, @jis_str.toeuc)
- assert_equal(@euc_str, @euc_str.kconv(::NKF::EUC))
- assert_equal(@euc_str, @sjis_str.kconv(::NKF::EUC))
- assert_equal(@euc_str, @utf8_str.kconv(::NKF::EUC))
- assert_equal(@euc_str, @jis_str.kconv(::NKF::EUC))
- end
- def test_shiftjis
- assert(@sjis_str.issjis)
- assert_equal(::Kconv::SJIS, Kconv.guess(@sjis_str))
- assert_equal(@sjis_str, @euc_str.tosjis)
- assert_equal(@sjis_str, @sjis_str.tosjis)
- assert_equal(@sjis_str, @utf8_str.tosjis)
- assert_equal(@sjis_str, @jis_str.tosjis)
- assert_equal(@sjis_str, @euc_str.kconv(::NKF::SJIS))
- assert_equal(@sjis_str, @sjis_str.kconv(::NKF::SJIS))
- assert_equal(@sjis_str, @utf8_str.kconv(::NKF::SJIS))
- assert_equal(@sjis_str, @jis_str.kconv(::NKF::SJIS))
- end
- def test_utf8
- assert(@utf8_str.isutf8)
- assert_equal(::Kconv::UTF8, Kconv.guess(@utf8_str))
- assert_equal(@utf8_str, @euc_str.toutf8)
- assert_equal(@utf8_str, @sjis_str.toutf8)
- assert_equal(@utf8_str, @utf8_str.toutf8)
- assert_equal(@utf8_str, @jis_str.toutf8)
- assert_equal(@utf8_str, @euc_str.kconv(::NKF::UTF8))
- assert_equal(@utf8_str, @sjis_str.kconv(::NKF::UTF8))
- assert_equal(@utf8_str, @utf8_str.kconv(::NKF::UTF8))
- assert_equal(@utf8_str, @jis_str.kconv(::NKF::UTF8))
- end
- def test_jis
- assert_equal(::Kconv::JIS, Kconv.guess(@jis_str))
- assert_equal(@jis_str, @euc_str.tojis)
- assert_equal(@jis_str, @sjis_str.tojis)
- assert_equal(@jis_str, @utf8_str.tojis)
- assert_equal(@jis_str, @jis_str.tojis)
- assert_equal(@jis_str, @euc_str.kconv(::NKF::JIS))
- assert_equal(@jis_str, @sjis_str.kconv(::NKF::JIS))
- assert_equal(@jis_str, @utf8_str.kconv(::NKF::JIS))
- assert_equal(@jis_str, @jis_str.kconv(::NKF::JIS))
- end
- def test_kconv
- str = "\xc2\xa1"
- %w/UTF-8 EUC-JP/.each do |enc|
- s = str.dup.force_encoding(enc)
- assert_equal(s, s.kconv(enc))
- end
- end
-end
diff --git a/test/nkf/test_nkf.rb b/test/nkf/test_nkf.rb
deleted file mode 100644
index eb51bf8e7d..0000000000
--- a/test/nkf/test_nkf.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'nkf'
-
-class TestNKF < Test::Unit::TestCase
- EUC_STR = "\xa5\xaa\xa5\xd6\xa5\xb8\xa5\xa7\xa5\xaf\xa5\xc8\xbb\xd8\xb8\xfe\
-\xa5\xb9\xa5\xaf\xa5\xea\xa5\xd7\xa5\xc8\xb8\xc0\xb8\xec\
-Ruby"
-
- def test_guess
- str_euc = EUC_STR
- str_jis = NKF.nkf('-j', str_euc)
- assert_equal(::NKF::JIS, NKF.guess(str_jis))
- assert_equal(::NKF::EUC, NKF.guess(str_euc))
- end
-
- def test_ruby_dev_36909
- assert_nothing_raised do
- 100.times { NKF.nkf("--oc=eucJP-nkf", "foo") }
- end
- end
-
-end
diff --git a/test/objspace/test_objspace.rb b/test/objspace/test_objspace.rb
index 3b90319858..b798b897b4 100644
--- a/test/objspace/test_objspace.rb
+++ b/test/objspace/test_objspace.rb
@@ -141,6 +141,7 @@ class TestObjSpace < Test::Unit::TestCase
end
def test_reachable_objects_during_iteration
+ omit 'flaky on Visual Studio with: [BUG] Unnormalized Fixnum value' if /mswin/ =~ RUBY_PLATFORM
opts = %w[--disable-gem --disable=frozen-string-literal -robjspace]
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
begin;
@@ -216,6 +217,28 @@ class TestObjSpace < Test::Unit::TestCase
assert_equal(c3, ObjectSpace.allocation_generation(o3))
assert_equal(self.class.name, ObjectSpace.allocation_class_path(o3))
assert_equal(__method__, ObjectSpace.allocation_method_id(o3))
+
+ # [Bug #19456]
+ o4 =
+ # This line intentionally left blank
+ # This line intentionally left blank
+ 1.0 / 0.0; line4 = __LINE__; _c4 = GC.count
+ assert_equal(__FILE__, ObjectSpace.allocation_sourcefile(o4))
+ assert_equal(line4, ObjectSpace.allocation_sourceline(o4))
+
+ # The line number should be based on newarray instead of getinstancevariable.
+ line5 = __LINE__; o5 = [ # newarray (leaf)
+ @ivar, # getinstancevariable (not leaf)
+ ]
+ assert_equal(__FILE__, ObjectSpace.allocation_sourcefile(o5))
+ assert_equal(line5, ObjectSpace.allocation_sourceline(o5))
+
+ # [Bug #19482]
+ EnvUtil.under_gc_stress do
+ 100.times do
+ Class.new
+ end
+ end
}
end
@@ -266,18 +289,55 @@ class TestObjSpace < Test::Unit::TestCase
end
def test_dump_flags
+ # Ensure that the fstring is promoted to old generation
+ 4.times { GC.start }
info = ObjectSpace.dump("foo".freeze)
assert_match(/"wb_protected":true, "old":true/, info)
assert_match(/"fstring":true/, info)
JSON.parse(info) if defined?(JSON)
end
+ if defined?(RubyVM::Shape)
+ class TooComplex; end
+
+ def test_dump_too_complex_shape
+ omit "flaky test"
+
+ RubyVM::Shape::SHAPE_MAX_VARIATIONS.times do
+ TooComplex.new.instance_variable_set(:"@a#{_1}", 1)
+ end
+
+ tc = TooComplex.new
+ info = ObjectSpace.dump(tc)
+ assert_not_match(/"too_complex_shape"/, info)
+ tc.instance_variable_set(:@new_ivar, 1)
+ info = ObjectSpace.dump(tc)
+ assert_match(/"too_complex_shape":true/, info)
+ if defined?(JSON)
+ assert_true(JSON.parse(info)["too_complex_shape"])
+ end
+ end
+ end
+
+ class NotTooComplex ; end
+
+ def test_dump_not_too_complex_shape
+ tc = NotTooComplex.new
+ tc.instance_variable_set(:@new_ivar, 1)
+ info = ObjectSpace.dump(tc)
+
+ assert_not_match(/"too_complex_shape"/, info)
+ if defined?(JSON)
+ assert_nil(JSON.parse(info)["too_complex_shape"])
+ end
+ end
+
def test_dump_to_default
line = nil
info = nil
ObjectSpace.trace_object_allocations do
line = __LINE__ + 1
- str = "hello world"
+ str = "hello w"
info = ObjectSpace.dump(str)
end
assert_dump_object(info, line)
@@ -289,7 +349,7 @@ class TestObjSpace < Test::Unit::TestCase
th = Thread.start {r.read}
ObjectSpace.trace_object_allocations do
line = __LINE__ + 1
- str = "hello world"
+ str = "hello w"
ObjectSpace.dump(str, output: w)
end
w.close
@@ -301,7 +361,7 @@ class TestObjSpace < Test::Unit::TestCase
def assert_dump_object(info, line)
loc = caller_locations(1, 1)[0]
assert_match(/"type":"STRING"/, info)
- assert_match(/"embedded":true, "bytesize":11, "value":"hello world", "encoding":"UTF-8"/, info)
+ assert_match(/"embedded":true, "bytesize":7, "value":"hello w", "encoding":"UTF-8"/, info)
assert_match(/"file":"#{Regexp.escape __FILE__}", "line":#{line}/, info)
assert_match(/"method":"#{loc.base_label}"/, info)
JSON.parse(info) if defined?(JSON)
@@ -329,6 +389,22 @@ class TestObjSpace < Test::Unit::TestCase
assert_not_include(info, '"embedded":true')
end
+ def test_dump_object
+ klass = Class.new
+
+ # Empty object
+ info = ObjectSpace.dump(klass.new)
+ assert_include(info, '"embedded":true')
+ assert_include(info, '"ivars":0')
+
+ # Non-embed object
+ obj = klass.new
+ 5.times { |i| obj.instance_variable_set("@ivar#{i}", 0) }
+ info = ObjectSpace.dump(obj)
+ assert_not_include(info, '"embedded":true')
+ assert_include(info, '"ivars":5')
+ end
+
def test_dump_control_char
assert_include(ObjectSpace.dump("\x0f"), '"value":"\u000f"')
assert_include(ObjectSpace.dump("\C-?"), '"value":"\u007f"')
@@ -414,7 +490,7 @@ class TestObjSpace < Test::Unit::TestCase
@obj1 = Object.new
GC.start
@obj2 = Object.new
- ObjectSpace.dump_all(output: :stdout, since: gc_gen)
+ ObjectSpace.dump_all(output: :stdout, since: gc_gen, shapes: false)
end
p dump_my_heap_please
@@ -422,7 +498,7 @@ class TestObjSpace < Test::Unit::TestCase
assert_equal 'nil', output.pop
since = output.shift.to_i
assert_operator output.size, :>, 0
- generations = output.map { |l| JSON.parse(l)["generation"] }.uniq.sort
+ generations = output.map { |l| JSON.parse(l) }.map { |o| o["generation"] }.uniq.sort
assert_equal [since, since + 1], generations
end
end
@@ -479,16 +555,38 @@ class TestObjSpace < Test::Unit::TestCase
output.each { |l|
obj = JSON.parse(l)
next if obj["type"] == "ROOT"
+ next if obj["type"] == "SHAPE"
- assert(obj["slot_size"] != nil)
- assert(obj["slot_size"] % GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] == 0)
+ assert_not_nil obj["slot_size"]
+ assert_equal 0, obj["slot_size"] % GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]
}
end
end
+ def test_dump_callinfo_includes_mid
+ assert_in_out_err(%w[-robjspace --disable-gems], "#{<<-"begin;"}\n#{<<-'end;'}") do |output, error|
+ begin;
+ class Foo
+ def foo
+ super(bar: 123) # should not crash on 0 mid
+ end
+
+ def bar
+ baz(bar: 123) # mid: baz
+ end
+ end
+
+ ObjectSpace.dump_all(output: $stdout)
+ end;
+ assert_empty error
+ assert(output.count > 1)
+ assert_includes output.grep(/"imemo_type":"callinfo"/).join("\n"), '"mid":"baz"'
+ end
+ end
+
def test_dump_string_coderange
assert_includes ObjectSpace.dump("TEST STRING"), '"coderange":"7bit"'
- unknown = "TEST STRING".dup.force_encoding(Encoding::BINARY)
+ unknown = "TEST STRING".dup.force_encoding(Encoding::UTF_16BE)
2.times do # ensure that dumping the string doesn't mutate it
assert_includes ObjectSpace.dump(unknown), '"coderange":"unknown"'
end
@@ -549,17 +647,34 @@ class TestObjSpace < Test::Unit::TestCase
#
# This test makes assertions on the assignment to `str`, so we look for
# the second appearance of /TEST STRING/ in the output
- test_string_in_dump_all = output.grep(/TEST STRING/)
- assert_equal(test_string_in_dump_all.size, 2)
+ test_string_in_dump_all = output.grep(/TEST2/)
- entry_hash = JSON.parse(test_string_in_dump_all[1])
+ begin
+ assert_equal(2, test_string_in_dump_all.size, "number of strings")
+ rescue Test::Unit::AssertionFailedError => e
+ STDERR.puts e.inspect
+ STDERR.puts test_string_in_dump_all
+ if test_string_in_dump_all.size == 3
+ STDERR.puts "This test is skipped because it seems hard to fix."
+ else
+ raise
+ end
+ end
+
+ strs = test_string_in_dump_all.reject do |s|
+ s.include?("fstring")
+ end
+
+ assert_equal(1, strs.length)
- assert_equal(entry_hash["bytesize"], 11)
- assert_equal(entry_hash["value"], "TEST STRING")
- assert_equal(entry_hash["encoding"], "UTF-8")
- assert_equal(entry_hash["file"], "-")
- assert_equal(entry_hash["line"], 4)
- assert_equal(entry_hash["method"], "dump_my_heap_please")
+ entry_hash = JSON.parse(strs[0])
+
+ assert_equal(5, entry_hash["bytesize"], "bytesize is wrong")
+ assert_equal("TEST2", entry_hash["value"], "value is wrong")
+ assert_equal("UTF-8", entry_hash["encoding"], "encoding is wrong")
+ assert_equal("-", entry_hash["file"], "file is wrong")
+ assert_equal(5, entry_hash["line"], "line is wrong")
+ assert_equal("dump_my_heap_please", entry_hash["method"], "method is wrong")
assert_not_nil(entry_hash["generation"])
end
@@ -567,11 +682,12 @@ class TestObjSpace < Test::Unit::TestCase
opts = %w[--disable-gem --disable=frozen-string-literal -robjspace]
assert_in_out_err(opts, "#{<<-"begin;"}#{<<-'end;'}") do |output, error|
+ # frozen_string_literal: false
begin;
def dump_my_heap_please
ObjectSpace.trace_object_allocations_start
GC.start
- str = "TEST STRING".force_encoding("UTF-8")
+ str = "TEST2".force_encoding("UTF-8")
ObjectSpace.dump_all(output: :stdout)
end
@@ -583,10 +699,11 @@ class TestObjSpace < Test::Unit::TestCase
assert_in_out_err(%w[-robjspace], "#{<<-"begin;"}#{<<-'end;'}") do |(output), (error)|
begin;
+ # frozen_string_literal: false
def dump_my_heap_please
ObjectSpace.trace_object_allocations_start
GC.start
- (str = "TEST STRING").force_encoding("UTF-8")
+ (str = "TEST2").force_encoding("UTF-8")
ObjectSpace.dump_all().path
end
@@ -713,6 +830,7 @@ class TestObjSpace < Test::Unit::TestCase
def test_objspace_trace
assert_in_out_err(%w[-robjspace/trace], "#{<<-"begin;"}\n#{<<-'end;'}") do |out, err|
begin;
+ # frozen_string_literal: false
a = "foo"
b = "b" + "a" + "r"
c = 42
@@ -720,12 +838,71 @@ class TestObjSpace < Test::Unit::TestCase
end;
assert_equal ["objspace/trace is enabled"], err
assert_equal 3, out.size
- assert_equal '"foo" @ -:2', out[0]
- assert_equal '"bar" @ -:3', out[1]
+ assert_equal '"foo" @ -:3', out[0]
+ assert_equal '"bar" @ -:4', out[1]
assert_equal '42', out[2]
end
end
+ def load_allocation_path_helper method, to_binary: false
+
+ Tempfile.create(["test_ruby_load_allocation_path", ".rb"]) do |t|
+ path = t.path
+ str = "#{Time.now.to_f.to_s}_#{rand.to_s}"
+ t.puts script = <<~RUBY
+ # frozen-string-literal: true
+ return if Time.now.to_i > 0
+ $gv = 'rnd-#{str}' # unreachable, but the string literal was written
+ RUBY
+
+ t.close
+
+ if to_binary
+ bin = RubyVM::InstructionSequence.compile_file(t.path).to_binary
+ bt = Tempfile.new(['test_ruby_load_allocation_path', '.yarb'], mode: File::Constants::WRONLY)
+ bt.write bin
+ bt.close
+
+ path = bt.path
+ end
+
+ assert_separately(%w[-robjspace -rtempfile], <<~RUBY)
+ GC.disable
+ path = "#{path}"
+ ObjectSpace.trace_object_allocations do
+ #{method}
+ end
+
+ n = 0
+ dump = ObjectSpace.dump_all(output: :string)
+ dump.each_line do |line|
+ if /"value":"rnd-#{str}"/ =~ line && /"frozen":true/ =~ line
+ assert Regexp.new('"file":"' + "#{path}") =~ line
+ assert Regexp.new('"line":') !~ line
+ n += 1
+ end
+ rescue ArgumentError
+ end
+
+ assert_equal(1, n)
+ RUBY
+ ensure
+ bt.unlink if bt
+ end
+ end
+
+ def test_load_allocation_path_load
+ load_allocation_path_helper 'load(path)'
+ end
+
+ def test_load_allocation_path_compile_file
+ load_allocation_path_helper 'RubyVM::InstructionSequence.compile_file(path)'
+ end
+
+ def test_load_allocation_path_load_from_binary
+ # load_allocation_path_helper 'iseq = RubyVM::InstructionSequence.load_from_binary(File.binread(path))', to_binary: true
+ end
+
def test_utf8_method_names
name = "utf8_❨╯°□°❩╯︵┻━┻"
obj = ObjectSpace.trace_object_allocations do
@@ -735,6 +912,16 @@ class TestObjSpace < Test::Unit::TestCase
assert_equal name, JSON.parse(dump)["method"], dump
end
+ def test_dump_shapes
+ json = ObjectSpace.dump_shapes(output: :string)
+ json.each_line do |line|
+ assert_include(line, '"type":"SHAPE"')
+ end
+
+ assert_empty ObjectSpace.dump_shapes(output: :string, since: RubyVM.stat(:next_shape_id))
+ assert_equal 2, ObjectSpace.dump_shapes(output: :string, since: RubyVM.stat(:next_shape_id) - 2).lines.size
+ end
+
private
def utf8_❨╯°□°❩╯︵┻━┻
diff --git a/test/objspace/test_ractor.rb b/test/objspace/test_ractor.rb
new file mode 100644
index 0000000000..b7008ea731
--- /dev/null
+++ b/test/objspace/test_ractor.rb
@@ -0,0 +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
+
+ r.take
+ r.take
+ end
+ RUBY
+ end
+end
diff --git a/test/open-uri/test_open-uri.rb b/test/open-uri/test_open-uri.rb
index 72ebcdb0da..30e3b5c9c1 100644
--- a/test/open-uri/test_open-uri.rb
+++ b/test/open-uri/test_open-uri.rb
@@ -172,6 +172,19 @@ class TestOpenURI < Test::Unit::TestCase
assert_raise(ArgumentError) { URI.open("http://127.0.0.1/", :invalid_option=>true) {} }
end
+ def test_pass_keywords
+ begin
+ f = URI.open(File::NULL, mode: 0666)
+ assert_kind_of File, f
+ ensure
+ f&.close
+ end
+
+ o = Object.new
+ def o.open(foo: ) foo end
+ assert_equal 1, URI.open(o, foo: 1)
+ end
+
def test_mode
with_http {|srv, dr, url|
srv.mount_proc("/mode", lambda { |req, res| res.body = "mode" } )
@@ -545,6 +558,25 @@ class TestOpenURI < Test::Unit::TestCase
}
end
+ def test_max_redirects_success
+ with_http {|srv, dr, url|
+ srv.mount_proc("/r1/") {|req, res| res.status = 301; res["location"] = "#{url}/r2"; res.body = "r1" }
+ srv.mount_proc("/r2/") {|req, res| res.status = 301; res["location"] = "#{url}/r3"; res.body = "r2" }
+ srv.mount_proc("/r3/") {|req, res| res.body = "r3" }
+ URI.open("#{url}/r1/", max_redirects: 2) { |f| assert_equal("r3", f.read) }
+ }
+ end
+
+ def test_max_redirects_too_many
+ with_http {|srv, dr, url|
+ srv.mount_proc("/r1/") {|req, res| res.status = 301; res["location"] = "#{url}/r2"; res.body = "r1" }
+ srv.mount_proc("/r2/") {|req, res| res.status = 301; res["location"] = "#{url}/r3"; res.body = "r2" }
+ srv.mount_proc("/r3/") {|req, res| res.body = "r3" }
+ exc = assert_raise(OpenURI::TooManyRedirects) { URI.open("#{url}/r1/", max_redirects: 1) {} }
+ assert_equal("Too many redirects", exc.message)
+ }
+ end
+
def test_userinfo
assert_raise(ArgumentError) { URI.open("http://user:pass@127.0.0.1/") {} }
end
@@ -902,5 +934,14 @@ class TestOpenURI < Test::Unit::TestCase
}
end
-end
+ def test_meta_init_doesnt_bump_global_constant_state
+ omit "RubyVM.stat not defined" unless defined? RubyVM.stat
+ omit unless RubyVM.stat.has_key?(:global_constant_state)
+
+ OpenURI::Meta.init(Object.new) # prewarm
+ before = RubyVM.stat(:global_constant_state)
+ OpenURI::Meta.init(Object.new)
+ assert_equal 0, RubyVM.stat(:global_constant_state) - before
+ end
+end
diff --git a/test/open-uri/test_ssl.rb b/test/open-uri/test_ssl.rb
index 4f645d83b9..3f94cab40f 100644
--- a/test/open-uri/test_ssl.rb
+++ b/test/open-uri/test_ssl.rb
@@ -107,6 +107,25 @@ class TestOpenURISSL
}
end
+ def test_ssl_min_version
+ with_https {|srv, dr, url|
+ setup_validation(srv, dr)
+ URI.open("#{url}/data", :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE, :ssl_min_version => :TLS1_2) {|f|
+ assert_equal("200", f.status[0])
+ assert_equal("ddd", f.read)
+ }
+ }
+ end
+
+ def test_bad_ssl_version
+ with_https(nil) {|srv, dr, url|
+ setup_validation(srv, dr)
+ assert_raise(ArgumentError) {
+ URI.open("#{url}/data", :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE, :ssl_min_version => :TLS_no_such_version) {}
+ }
+ }
+ end
+
def with_https_proxy(proxy_log_tester=lambda {|proxy_log, proxy_access_log| assert_equal([], proxy_log) })
proxy_log = []
proxy_logger = WEBrick::Log.new(proxy_log, WEBrick::BasicLog::WARN)
diff --git a/test/openssl/fixtures/pkey/dh1024.pem b/test/openssl/fixtures/pkey/dh1024.pem
deleted file mode 100644
index f99c757f21..0000000000
--- a/test/openssl/fixtures/pkey/dh1024.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN DH PARAMETERS-----
-MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0
-pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG
-AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
------END DH PARAMETERS-----
diff --git a/test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem b/test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem
new file mode 100644
index 0000000000..9b182b7201
--- /dev/null
+++ b/test/openssl/fixtures/pkey/dh2048_ffdhe2048.pem
@@ -0,0 +1,8 @@
+-----BEGIN DH PARAMETERS-----
+MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
+87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
+YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
+7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
+ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
+-----END DH PARAMETERS-----
diff --git a/test/openssl/fixtures/pkey/dsa2048.pem b/test/openssl/fixtures/pkey/dsa2048.pem
new file mode 100644
index 0000000000..3f22b22b58
--- /dev/null
+++ b/test/openssl/fixtures/pkey/dsa2048.pem
@@ -0,0 +1,15 @@
+-----BEGIN PRIVATE KEY-----
+MIICXgIBADCCAjYGByqGSM44BAEwggIpAoIBAQDXZhJ/dQoWkQELzjzlx8FtIp96
+voCYe5NY0H8j0jz7GyHpXt41+MteqkZK3/Ah+cNR9uG8iEYArAZ71LcWotfee2Gz
+xdxozr9bRt0POYhO2YIsfMpBrEskPsDH2g/2nFV8l4OJgxU2qZUrF4PN5ha+Mu6u
+sVtN8hjvAvnbf4Pxn0b8NN9f4PJncroUa8acv5WsV85E1RW7NYCefggU4LytYIHg
+euRF9eY9gVCX5MkUgW2xODHIYJhwk/+5lJxG7qUsSahD/nPHO/yoWgdVHq2DkdTq
+KYXkAxx2PJcTBOHTglhE6mgCbEKp8vcfElnBWyCT6QykclZiPXXD2JV829J/Ah0A
+vYa+/G/gUZiomyejVje6UsGoCc+vInxmovOL8QKCAQEAhnKEigYPw6u8JY7v5iGo
+Ylz8qiMFYmaJCwevf3KCjWeEXuNO4OrKdfzkQl1tPuGLioYFfP1A2yGosjdUdLEB
+0JqnzlKxUp+G6RfBj+WYzbgc5hr7t0M+reAJh09/hDzqfxjcgiHstq7mpRXBP8Y7
+iu27s7TRYJNSAYRvWcXNSBEUym3mHBBbZn7VszYooSrn60/iZ8I+VY1UF/fgqhbj
+JfaaZNQCDO9K3Vb3rsXoYd8+bOZIen9uHB+pNjMqhpl4waysqrlpGFeeqdxivH6S
+vkrHLs6/eWVMnS08RdcryoCrI3Bm8mMBKQglDwKLnWLfzG565qEhslzyCd/l9k9a
+cwQfAh0Ao8/g72fSFmo04FizM7DZJSIPqDLjfZu9hLvUFA==
+-----END PRIVATE KEY-----
diff --git a/test/openssl/fixtures/pkey/p256_too_large.pem b/test/openssl/fixtures/pkey/p256_too_large.pem
new file mode 100644
index 0000000000..a73ac37f87
--- /dev/null
+++ b/test/openssl/fixtures/pkey/p256_too_large.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIP+TT0V8Fndsnacji9tyf6hmhHywcOWTee9XkiBeJoVloAoGCCqGSM49
+AwEHoUQDQgAEBkhhJIU/2/YdPSlY2I1k25xjK4trr5OXSgXvBC21PtY0HQ7lor7A
+jzT0giJITqmcd81fwGw5+96zLcdxTF1hVQ==
+-----END EC PRIVATE KEY-----
diff --git a/test/openssl/fixtures/pkey/p384_invalid.pem b/test/openssl/fixtures/pkey/p384_invalid.pem
new file mode 100644
index 0000000000..d5cdc9a3af
--- /dev/null
+++ b/test/openssl/fixtures/pkey/p384_invalid.pem
@@ -0,0 +1,6 @@
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDDA1Tm0m7YhkfeVpFuarAJYVlHp2tQj+1fOBiLa10t9E8TiQO/hVfxB
+vGaVEQwOheWgBwYFK4EEACKhZANiAASyGqmryZGqdpsq5gEDIfNvgC3AwSJxiBCL
+XKHBTFRp+tCezLDOK/6V8KK/vVGBJlGFW6/I7ahyXprxS7xs7hPA9iz5YiuqXlu+
+lbrIpZOz7b73hyQQCkvbBO/Avg+hPAk=
+-----END EC PRIVATE KEY-----
diff --git a/test/openssl/test_asn1.rb b/test/openssl/test_asn1.rb
index 0fd7971585..7b1722e5df 100644
--- a/test/openssl/test_asn1.rb
+++ b/test/openssl/test_asn1.rb
@@ -14,7 +14,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
["keyUsage","keyCertSign, cRLSign",true],
["subjectKeyIdentifier","hash",false],
]
- dgst = OpenSSL::Digest.new('SHA1')
+ dgst = OpenSSL::Digest.new('SHA256')
cert = OpenSSL::TestUtils.issue_cert(
subj, key, s, exts, nil, nil, digest: dgst, not_before: now, not_after: now+3600)
@@ -42,7 +42,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
assert_equal(OpenSSL::ASN1::Sequence, sig.class)
assert_equal(2, sig.value.size)
assert_equal(OpenSSL::ASN1::ObjectId, sig.value[0].class)
- assert_equal("1.2.840.113549.1.1.5", sig.value[0].oid)
+ assert_equal("1.2.840.113549.1.1.11", sig.value[0].oid)
assert_equal(OpenSSL::ASN1::Null, sig.value[1].class)
dn = tbs_cert.value[3] # issuer
@@ -189,7 +189,7 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
assert_equal(OpenSSL::ASN1::Null, pkey.value[0].value[1].class)
assert_equal(OpenSSL::ASN1::BitString, sig_val.class)
- cululated_sig = key.sign(OpenSSL::Digest.new('SHA1'), tbs_cert.to_der)
+ cululated_sig = key.sign(OpenSSL::Digest.new('SHA256'), tbs_cert.to_der)
assert_equal(cululated_sig, sig_val.value)
end
@@ -323,14 +323,9 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("3.0".b).to_der }
assert_raise(OpenSSL::ASN1::ASN1Error) { OpenSSL::ASN1::ObjectId.new("0.40".b).to_der }
- begin
- oid = (0...100).to_a.join(".").b
- obj = OpenSSL::ASN1::ObjectId.new(oid)
- assert_equal oid, obj.oid
- rescue OpenSSL::ASN1::ASN1Error
- pend "OBJ_obj2txt() not working (LibreSSL?)" if $!.message =~ /OBJ_obj2txt/
- raise
- end
+ oid = (0...100).to_a.join(".").b
+ obj = OpenSSL::ASN1::ObjectId.new(oid)
+ assert_equal oid, obj.oid
aki = [
OpenSSL::ASN1::ObjectId.new("authorityKeyIdentifier"),
@@ -404,9 +399,6 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
def test_utctime
encode_decode_test B(%w{ 17 0D }) + "160908234339Z".b,
OpenSSL::ASN1::UTCTime.new(Time.utc(2016, 9, 8, 23, 43, 39))
- # Seconds is omitted
- decode_test B(%w{ 17 0B }) + "1609082343Z".b,
- OpenSSL::ASN1::UTCTime.new(Time.utc(2016, 9, 8, 23, 43, 0))
begin
# possible range of UTCTime is 1969-2068 currently
encode_decode_test B(%w{ 17 0D }) + "690908234339Z".b,
@@ -432,8 +424,6 @@ class OpenSSL::TestASN1 < OpenSSL::TestCase
OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 29))
encode_decode_test B(%w{ 18 0F }) + "99990908234339Z".b,
OpenSSL::ASN1::GeneralizedTime.new(Time.utc(9999, 9, 8, 23, 43, 39))
- decode_test B(%w{ 18 0D }) + "201612081934Z".b,
- OpenSSL::ASN1::GeneralizedTime.new(Time.utc(2016, 12, 8, 19, 34, 0))
# not implemented
# decode_test B(%w{ 18 13 }) + "20161208193439+0930".b,
# OpenSSL::ASN1::GeneralizedTime.new(Time.new(2016, 12, 8, 19, 34, 39, "+09:30"))
diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index 346602dada..ea88ff06ce 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -174,6 +174,14 @@ class OpenSSL::TestBN < OpenSSL::TestCase
assert_equal(0, 59.to_bn.mod_sqr(59))
end
+ def test_mod_sqrt
+ assert_equal(4, 4.to_bn.mod_sqrt(5).mod_sqr(5))
+ # One of 189484 or 326277 is returned as a square root of 2 (mod 515761).
+ assert_equal(2, 2.to_bn.mod_sqrt(515761).mod_sqr(515761))
+ assert_equal(0, 5.to_bn.mod_sqrt(5))
+ assert_raise(OpenSSL::BNError) { 3.to_bn.mod_sqrt(5) }
+ end
+
def test_mod_inverse
assert_equal(2, 3.to_bn.mod_inverse(5))
assert_raise(OpenSSL::BNError) { 3.to_bn.mod_inverse(6) }
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb
index b5fdf0b3d1..8faa570648 100644
--- a/test/openssl/test_cipher.rb
+++ b/test/openssl/test_cipher.rb
@@ -108,12 +108,6 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_not_equal s1, s2
end
- def test_empty_data
- cipher = OpenSSL::Cipher.new("DES-EDE3-CBC").encrypt
- cipher.random_key
- assert_raise(ArgumentError) { cipher.update("") }
- end
-
def test_initialize
cipher = OpenSSL::Cipher.new("DES-EDE3-CBC")
assert_raise(RuntimeError) { cipher.__send__(:initialize, "DES-EDE3-CBC") }
@@ -211,7 +205,7 @@ class OpenSSL::TestCipher < OpenSSL::TestCase
assert_raise(OpenSSL::Cipher::CipherError) { cipher.update(ct2) }
end if has_cipher?("aes-128-ccm") &&
OpenSSL::Cipher.new("aes-128-ccm").authenticated? &&
- OpenSSL::OPENSSL_VERSION_NUMBER >= 0x1010103f # version >= 1.1.1c
+ openssl?(1, 1, 1, 0x03, 0xf) # version >= 1.1.1c
def test_aes_gcm
# GCM spec Appendix B Test Case 4
diff --git a/test/openssl/test_config.rb b/test/openssl/test_config.rb
index 24a215a486..6dbb9c6138 100644
--- a/test/openssl/test_config.rb
+++ b/test/openssl/test_config.rb
@@ -91,22 +91,19 @@ __EOC__
assert_equal('123baz456bar798', c['dollar']['qux'])
assert_equal('123baz456bar798.123baz456bar798', c['dollar']['quxx'])
- excn = assert_raise(OpenSSL::ConfigError) do
+ assert_raise_with_message(OpenSSL::ConfigError, /error in line 1: variable has no value/) do
OpenSSL::Config.parse("foo = $bar")
end
- assert_equal("error in line 1: variable has no value", excn.message)
- excn = assert_raise(OpenSSL::ConfigError) do
+ assert_raise_with_message(OpenSSL::ConfigError, /error in line 1: no close brace/) do
OpenSSL::Config.parse("foo = $(bar")
end
- assert_equal("error in line 1: no close brace", excn.message)
- excn = assert_raise(OpenSSL::ConfigError) do
+ assert_raise_with_message(OpenSSL::ConfigError, /error in line 1: missing equal sign/) do
OpenSSL::Config.parse("f o =b ar # no space in key")
end
- assert_equal("error in line 1: missing equal sign", excn.message)
- excn = assert_raise(OpenSSL::ConfigError) do
+ assert_raise_with_message(OpenSSL::ConfigError, /error in line 7: missing close square bracket/) do
OpenSSL::Config.parse(<<__EOC__)
# comment 1 # comments
@@ -117,7 +114,6 @@ __EOC__
[third # section not terminated
__EOC__
end
- assert_equal("error in line 7: missing close square bracket", excn.message)
end
def test_s_parse_include
diff --git a/test/openssl/test_digest.rb b/test/openssl/test_digest.rb
index 84c128c12f..b0b5b9bed1 100644
--- a/test/openssl/test_digest.rb
+++ b/test/openssl/test_digest.rb
@@ -67,7 +67,7 @@ class OpenSSL::TestDigest < OpenSSL::TestCase
end
def encode16(str)
- str.unpack("H*").first
+ str.unpack1("H*")
end
def test_sha2
diff --git a/test/openssl/test_engine.rb b/test/openssl/test_engine.rb
index 1ede6ed086..b6025f915b 100644
--- a/test/openssl/test_engine.rb
+++ b/test/openssl/test_engine.rb
@@ -26,7 +26,7 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
with_openssl <<-'end;'
orig = OpenSSL::Engine.engines
pend "'openssl' is already loaded" if orig.any? { |e| e.id == "openssl" }
- engine = get_engine
+ engine = OpenSSL::Engine.by_id("openssl")
assert_not_nil(engine)
assert_equal(1, OpenSSL::Engine.engines.size - orig.size)
end;
@@ -34,7 +34,7 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
def test_openssl_engine_id_name_inspect
with_openssl <<-'end;'
- engine = get_engine
+ engine = OpenSSL::Engine.by_id("openssl")
assert_equal("openssl", engine.id)
assert_not_nil(engine.name)
assert_not_nil(engine.inspect)
@@ -43,7 +43,7 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
def test_openssl_engine_digest_sha1
with_openssl <<-'end;'
- engine = get_engine
+ engine = OpenSSL::Engine.by_id("openssl")
digest = engine.digest("SHA1")
assert_not_nil(digest)
data = "test"
@@ -59,12 +59,21 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
end
with_openssl(<<-'end;', ignore_stderr: true)
- engine = get_engine
+ engine = OpenSSL::Engine.by_id("openssl")
algo = "RC4"
data = "a" * 1000
key = OpenSSL::Random.random_bytes(16)
- encrypted = crypt_data(data, key, :encrypt) { engine.cipher(algo) }
- decrypted = crypt_data(encrypted, key, :decrypt) { OpenSSL::Cipher.new(algo) }
+
+ cipher = engine.cipher(algo)
+ cipher.encrypt
+ cipher.key = key
+ encrypted = cipher.update(data) + cipher.final
+
+ cipher = OpenSSL::Cipher.new(algo)
+ cipher.decrypt
+ cipher.key = key
+ decrypted = cipher.update(encrypted) + cipher.final
+
assert_equal(data, decrypted)
end;
end
@@ -73,25 +82,10 @@ class OpenSSL::TestEngine < OpenSSL::TestCase
# this is required because OpenSSL::Engine methods change global state
def with_openssl(code, **opts)
- assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;", **opts)
- require #{__FILE__.dump}
- include OpenSSL::TestEngine::Utils
+ assert_separately(["-ropenssl"], <<~"end;", **opts)
#{code}
end;
end
-
- module Utils
- def get_engine
- OpenSSL::Engine.by_id("openssl")
- end
-
- def crypt_data(data, key, mode)
- cipher = yield
- cipher.send mode
- cipher.key = key
- cipher.update(data) + cipher.final
- end
- end
end
end
diff --git a/test/openssl/test_fips.rb b/test/openssl/test_fips.rb
index 8cd474f9a3..4a3dd43a41 100644
--- a/test/openssl/test_fips.rb
+++ b/test/openssl/test_fips.rb
@@ -4,22 +4,46 @@ require_relative 'utils'
if defined?(OpenSSL)
class OpenSSL::TestFIPS < OpenSSL::TestCase
+ def test_fips_mode_get_is_true_on_fips_mode_enabled
+ unless ENV["TEST_RUBY_OPENSSL_FIPS_ENABLED"]
+ omit "Only for FIPS mode environment"
+ end
+
+ assert_separately(["-ropenssl"], <<~"end;")
+ assert OpenSSL.fips_mode == true, ".fips_mode should return true on FIPS mode enabled"
+ end;
+ end
+
+ def test_fips_mode_get_is_false_on_fips_mode_disabled
+ if ENV["TEST_RUBY_OPENSSL_FIPS_ENABLED"]
+ omit "Only for non-FIPS mode environment"
+ end
+
+ assert_separately(["-ropenssl"], <<~"end;")
+ message = ".fips_mode should return false on FIPS mode disabled. " \
+ "If you run the test on FIPS mode, please set " \
+ "TEST_RUBY_OPENSSL_FIPS_ENABLED=true"
+ assert OpenSSL.fips_mode == false, message
+ end;
+ end
+
def test_fips_mode_is_reentrant
- OpenSSL.fips_mode = false
- OpenSSL.fips_mode = false
+ assert_separately(["-ropenssl"], <<~"end;")
+ OpenSSL.fips_mode = false
+ OpenSSL.fips_mode = false
+ end;
end
- def test_fips_mode_get
- return unless OpenSSL::OPENSSL_FIPS
- assert_separately([{ "OSSL_MDEBUG" => nil }, "-ropenssl"], <<~"end;")
- require #{__FILE__.dump}
+ def test_fips_mode_get_with_fips_mode_set
+ omit('OpenSSL is not FIPS-capable') unless OpenSSL::OPENSSL_FIPS
+ assert_separately(["-ropenssl"], <<~"end;")
begin
OpenSSL.fips_mode = true
- assert OpenSSL.fips_mode == true, ".fips_mode returns true when .fips_mode=true"
+ assert OpenSSL.fips_mode == true, ".fips_mode should return true when .fips_mode=true"
OpenSSL.fips_mode = false
- assert OpenSSL.fips_mode == false, ".fips_mode returns false when .fips_mode=false"
+ assert OpenSSL.fips_mode == false, ".fips_mode should return false when .fips_mode=false"
rescue OpenSSL::OpenSSLError
pend "Could not set FIPS mode (OpenSSL::OpenSSLError: \#$!); skipping"
end
diff --git a/test/openssl/test_hmac.rb b/test/openssl/test_hmac.rb
index 47cb3718df..3cb707448a 100644
--- a/test/openssl/test_hmac.rb
+++ b/test/openssl/test_hmac.rb
@@ -21,7 +21,6 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase
end
def test_dup
- pend "HMAC#initialize_copy is currently broken on OpenSSL 3.0.0" if openssl?(3, 0, 0)
h1 = OpenSSL::HMAC.new("KEY", "MD5")
h1.update("DATA")
h = h1.dup
@@ -63,6 +62,14 @@ class OpenSSL::TestHMAC < OpenSSL::TestCase
b64digest = OpenSSL::HMAC.base64digest("MD5", key, "Hi There")
assert_equal "kpRyejY4uxwT9I74FYv8nQ==", b64digest
end
+
+ def test_zero_length_key
+ # Empty string as the key
+ hexdigest = OpenSSL::HMAC.hexdigest("SHA256", "\0"*32, "test")
+ assert_equal "43b0cef99265f9e34c10ea9d3501926d27b39f57c6d674561d8ba236e7a819fb", hexdigest
+ hexdigest = OpenSSL::HMAC.hexdigest("SHA256", "", "test")
+ assert_equal "43b0cef99265f9e34c10ea9d3501926d27b39f57c6d674561d8ba236e7a819fb", hexdigest
+ end
end
end
diff --git a/test/openssl/test_ns_spki.rb b/test/openssl/test_ns_spki.rb
index ed3be86e2c..d76fc9e5cf 100644
--- a/test/openssl/test_ns_spki.rb
+++ b/test/openssl/test_ns_spki.rb
@@ -22,7 +22,7 @@ class OpenSSL::TestNSSPI < OpenSSL::TestCase
spki = OpenSSL::Netscape::SPKI.new
spki.challenge = "RandomString"
spki.public_key = key1.public_key
- spki.sign(key1, OpenSSL::Digest.new('SHA1'))
+ spki.sign(key1, OpenSSL::Digest.new('SHA256'))
assert(spki.verify(spki.public_key))
assert(spki.verify(key1.public_key))
assert(!spki.verify(key2.public_key))
@@ -38,13 +38,13 @@ class OpenSSL::TestNSSPI < OpenSSL::TestCase
def test_decode_data
spki = OpenSSL::Netscape::SPKI.new(@b64)
assert_equal(@b64, spki.to_pem)
- assert_equal(@b64.unpack("m").first, spki.to_der)
+ assert_equal(@b64.unpack1("m"), spki.to_der)
assert_equal("MozillaIsMyFriend", spki.challenge)
assert_equal(OpenSSL::PKey::RSA, spki.public_key.class)
- spki = OpenSSL::Netscape::SPKI.new(@b64.unpack("m").first)
+ spki = OpenSSL::Netscape::SPKI.new(@b64.unpack1("m"))
assert_equal(@b64, spki.to_pem)
- assert_equal(@b64.unpack("m").first, spki.to_der)
+ assert_equal(@b64.unpack1("m"), spki.to_der)
assert_equal("MozillaIsMyFriend", spki.challenge)
assert_equal(OpenSSL::PKey::RSA, spki.public_key.class)
end
diff --git a/test/openssl/test_ocsp.rb b/test/openssl/test_ocsp.rb
index 85f133752c..cf96fc22e5 100644
--- a/test/openssl/test_ocsp.rb
+++ b/test/openssl/test_ocsp.rb
@@ -228,7 +228,7 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
assert_equal OpenSSL::OCSP::V_CERTSTATUS_REVOKED, single.cert_status
assert_equal OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, single.revocation_reason
assert_equal now - 400, single.revocation_time
- assert_in_delta (now - 301), single.this_update, 1
+ assert_in_delta (now - 300), single.this_update, 1
assert_equal nil, single.next_update
assert_equal [], single.extensions
diff --git a/test/openssl/test_ossl.rb b/test/openssl/test_ossl.rb
index e1d86bd40b..979669a003 100644
--- a/test/openssl/test_ossl.rb
+++ b/test/openssl/test_ossl.rb
@@ -60,6 +60,19 @@ class OpenSSL::OSSL < OpenSSL::SSLTestCase
assert_operator(a_b_time, :<, a_c_time * 10, "fixed_length_secure_compare timing test failed")
assert_operator(a_c_time, :<, a_b_time * 10, "fixed_length_secure_compare timing test failed")
end
+
+ def test_error_data
+ # X509V3_EXT_nconf_nid() called from OpenSSL::X509::ExtensionFactory#create_ext is a function
+ # that uses ERR_raise_data() to append additional information about the error.
+ #
+ # The generated message should look like:
+ # "subjectAltName = IP:not.a.valid.ip.address: bad ip address (value=not.a.valid.ip.address)"
+ # "subjectAltName = IP:not.a.valid.ip.address: error in extension (name=subjectAltName, value=IP:not.a.valid.ip.address)"
+ ef = OpenSSL::X509::ExtensionFactory.new
+ assert_raise_with_message(OpenSSL::X509::ExtensionError, /value=(IP:)?not.a.valid.ip.address\)/) {
+ ef.create_ext("subjectAltName", "IP:not.a.valid.ip.address")
+ }
+ end
end
end
diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb
index 4249b4afb7..b616883925 100644
--- a/test/openssl/test_pair.rb
+++ b/test/openssl/test_pair.rb
@@ -2,7 +2,7 @@
require_relative 'utils'
require_relative 'ut_eof'
-if defined?(OpenSSL)
+if defined?(OpenSSL::SSL)
module OpenSSL::SSLPairM
def setup
@@ -115,6 +115,17 @@ module OpenSSL::TestPairM
}
end
+ def test_gets_chomp
+ ssl_pair {|s1, s2|
+ s1 << "line1\r\nline2\r\nline3\r\n"
+ s1.close
+
+ assert_equal("line1", s2.gets("\r\n", chomp: true))
+ assert_equal("line2\r\n", s2.gets("\r\n", chomp: false))
+ assert_equal("line3", s2.gets(chomp: true))
+ }
+ end
+
def test_gets_eof_limit
ssl_pair {|s1, s2|
s1.write("hello")
diff --git a/test/openssl/test_pkcs12.rb b/test/openssl/test_pkcs12.rb
index ec676743bc..e6b91b52af 100644
--- a/test/openssl/test_pkcs12.rb
+++ b/test/openssl/test_pkcs12.rb
@@ -181,7 +181,7 @@ module OpenSSL
def test_new_with_no_keys
# generated with:
# openssl pkcs12 -certpbe PBE-SHA1-3DES -in <@mycert> -nokeys -export
- str = <<~EOF.unpack("m").first
+ str = <<~EOF.unpack1("m")
MIIGJAIBAzCCBeoGCSqGSIb3DQEHAaCCBdsEggXXMIIF0zCCBc8GCSqGSIb3
DQEHBqCCBcAwggW8AgEAMIIFtQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQMw
DgQIjv5c3OHvnBgCAggAgIIFiMJa8Z/w7errRvCQPXh9dGQz3eJaFq3S2gXD
@@ -230,7 +230,7 @@ AA==
def test_new_with_no_certs
# generated with:
# openssl pkcs12 -inkey fixtures/openssl/pkey/rsa-1.pem -nocerts -export
- str = <<~EOF.unpack("m").first
+ str = <<~EOF.unpack1("m")
MIIJ7wIBAzCCCbUGCSqGSIb3DQEHAaCCCaYEggmiMIIJnjCCCZoGCSqGSIb3
DQEHAaCCCYsEggmHMIIJgzCCCX8GCyqGSIb3DQEMCgECoIIJbjCCCWowHAYK
KoZIhvcNAQwBAzAOBAjX5nN8jyRKwQICCAAEgglIBIRLHfiY1mNHpl3FdX6+
diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb
index 544340e378..aee0546f63 100644
--- a/test/openssl/test_pkey.rb
+++ b/test/openssl/test_pkey.rb
@@ -40,6 +40,11 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
}
# Parameter generation callback is called
+ if openssl?(3, 0, 0, 0) && !openssl?(3, 0, 0, 6)
+ # Errors in BN_GENCB were not properly handled. This special pend is to
+ # suppress failures on Ubuntu 22.04, which uses OpenSSL 3.0.2.
+ pend "unstable test on OpenSSL 3.0.[0-5]"
+ end
cb_called = []
assert_raise(RuntimeError) {
OpenSSL::PKey.generate_parameters("DSA") { |*args|
@@ -77,6 +82,9 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
end
def test_ed25519
+ # Ed25519 is not FIPS-approved.
+ omit_on_fips
+
# Test vector from RFC 8032 Section 7.1 TEST 2
priv_pem = <<~EOF
-----BEGIN PRIVATE KEY-----
@@ -91,9 +99,11 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
begin
priv = OpenSSL::PKey.read(priv_pem)
pub = OpenSSL::PKey.read(pub_pem)
- rescue OpenSSL::PKey::PKeyError
+ rescue OpenSSL::PKey::PKeyError => e
# OpenSSL < 1.1.1
- pend "Ed25519 is not implemented"
+ pend "Ed25519 is not implemented" unless openssl?(1, 1, 1)
+
+ raise e
end
assert_instance_of OpenSSL::PKey::PKey, priv
assert_instance_of OpenSSL::PKey::PKey, pub
@@ -101,6 +111,19 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
assert_equal pub_pem, priv.public_to_pem
assert_equal pub_pem, pub.public_to_pem
+ begin
+ assert_equal "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb",
+ priv.raw_private_key.unpack1("H*")
+ assert_equal OpenSSL::PKey.new_raw_private_key("ED25519", priv.raw_private_key).private_to_pem,
+ priv.private_to_pem
+ assert_equal "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c",
+ priv.raw_public_key.unpack1("H*")
+ assert_equal OpenSSL::PKey.new_raw_public_key("ED25519", priv.raw_public_key).public_to_pem,
+ pub.public_to_pem
+ rescue NoMethodError
+ pend "running OpenSSL version does not have raw public key support"
+ end
+
sig = [<<~EOF.gsub(/[^0-9a-f]/, "")].pack("H*")
92a009a9f0d4cab8720e820b5f642540
a2b27b5416503f8fb3762223ebdb69da
@@ -121,6 +144,32 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
assert_raise(OpenSSL::PKey::PKeyError) { priv.derive(pub) }
end
+ def test_ed25519_not_approved_on_fips
+ omit_on_non_fips
+ # Ed25519 is technically allowed in the OpenSSL 3.0 code as a kind of bug.
+ # So, we need to omit OpenSSL 3.0.
+ #
+ # See OpenSSL providers/fips/fipsprov.c PROV_NAMES_ED25519 entries with
+ # FIPS_DEFAULT_PROPERTIES on openssl-3.0 branch and
+ # FIPS_UNAPPROVED_PROPERTIES on openssl-3.1 branch.
+ #
+ # See also
+ # https://github.com/openssl/openssl/issues/20758#issuecomment-1639658102
+ # for details.
+ unless openssl?(3, 1, 0, 0)
+ omit 'Ed25519 is allowed in the OpenSSL 3.0 FIPS code as a kind of bug'
+ end
+
+ priv_pem = <<~EOF
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIEzNCJso/5banbbDRuwRTg9bijGfNaumJNqM9u1PuKb7
+ -----END PRIVATE KEY-----
+ EOF
+ assert_raise(OpenSSL::PKey::PKeyError) do
+ OpenSSL::PKey.read(priv_pem)
+ end
+ end
+
def test_x25519
# Test vector from RFC 7748 Section 6.1
alice_pem = <<~EOF
@@ -145,6 +194,32 @@ class OpenSSL::TestPKey < OpenSSL::PKeyTestCase
assert_equal alice_pem, alice.private_to_pem
assert_equal bob_pem, bob.public_to_pem
assert_equal [shared_secret].pack("H*"), alice.derive(bob)
+ begin
+ alice_private = OpenSSL::PKey.new_raw_private_key("X25519", alice.raw_private_key)
+ bob_public = OpenSSL::PKey.new_raw_public_key("X25519", bob.raw_public_key)
+ alice_private_raw = alice.raw_private_key.unpack1("H*")
+ bob_public_raw = bob.raw_public_key.unpack1("H*")
+ rescue NoMethodError
+ # OpenSSL < 1.1.1
+ pend "running OpenSSL version does not have raw public key support"
+ end
+ assert_equal alice_private.private_to_pem,
+ alice.private_to_pem
+ assert_equal bob_public.public_to_pem,
+ bob.public_to_pem
+ assert_equal "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a",
+ alice_private_raw
+ assert_equal "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f",
+ bob_public_raw
+ end
+
+ def raw_initialize
+ pend "Ed25519 is not implemented" unless openssl?(1, 1, 1) # >= v1.1.1
+
+ assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_private_key("foo123", "xxx") }
+ assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_private_key("ED25519", "xxx") }
+ assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_public_key("foo123", "xxx") }
+ assert_raise(OpenSSL::PKey::PKeyError) { OpenSSL::PKey.new_raw_public_key("ED25519", "xxx") }
end
def test_compare?
diff --git a/test/openssl/test_pkey_dh.rb b/test/openssl/test_pkey_dh.rb
index 161af1897b..d32ffaf6b1 100644
--- a/test/openssl/test_pkey_dh.rb
+++ b/test/openssl/test_pkey_dh.rb
@@ -18,15 +18,26 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
assert_key(dh)
end if ENV["OSSL_TEST_ALL"]
- def test_new_break
+ def test_new_break_on_non_fips
+ omit_on_fips
+
assert_nil(OpenSSL::PKey::DH.new(NEW_KEYLEN) { break })
assert_raise(RuntimeError) do
OpenSSL::PKey::DH.new(NEW_KEYLEN) { raise }
end
end
+ def test_new_break_on_fips
+ omit_on_non_fips
+
+ # The block argument is not executed in FIPS case.
+ # See https://github.com/ruby/openssl/issues/692 for details.
+ assert(OpenSSL::PKey::DH.new(NEW_KEYLEN) { break })
+ assert(OpenSSL::PKey::DH.new(NEW_KEYLEN) { raise })
+ end
+
def test_derive_key
- params = Fixtures.pkey("dh1024")
+ params = Fixtures.pkey("dh2048_ffdhe2048")
dh1 = OpenSSL::PKey.generate_key(params)
dh2 = OpenSSL::PKey.generate_key(params)
dh1_pub = OpenSSL::PKey.read(dh1.public_to_der)
@@ -44,34 +55,38 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_DHparams
- dh1024 = Fixtures.pkey("dh1024")
- dh1024params = dh1024.public_key
+ dh = Fixtures.pkey("dh2048_ffdhe2048")
+ dh_params = dh.public_key
asn1 = OpenSSL::ASN1::Sequence([
- OpenSSL::ASN1::Integer(dh1024.p),
- OpenSSL::ASN1::Integer(dh1024.g)
+ OpenSSL::ASN1::Integer(dh.p),
+ OpenSSL::ASN1::Integer(dh.g)
])
key = OpenSSL::PKey::DH.new(asn1.to_der)
- assert_same_dh dh1024params, key
+ assert_same_dh dh_params, key
pem = <<~EOF
-----BEGIN DH PARAMETERS-----
- MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0
- pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG
- AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC
+ MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+ +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
+ 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
+ YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
+ 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
+ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----
EOF
+
key = OpenSSL::PKey::DH.new(pem)
- assert_same_dh dh1024params, key
+ assert_same_dh dh_params, key
key = OpenSSL::PKey.read(pem)
- assert_same_dh dh1024params, key
+ assert_same_dh dh_params, key
- assert_equal asn1.to_der, dh1024.to_der
- assert_equal pem, dh1024.export
+ assert_equal asn1.to_der, dh.to_der
+ assert_equal pem, dh.export
end
def test_public_key
- dh = Fixtures.pkey("dh1024")
+ dh = Fixtures.pkey("dh2048_ffdhe2048")
public_key = dh.public_key
assert_no_key(public_key) #implies public_key.public? is false!
assert_equal(dh.to_der, public_key.to_der)
@@ -80,7 +95,8 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
def test_generate_key
# Deprecated in v3.0.0; incompatible with OpenSSL 3.0
- dh = Fixtures.pkey("dh1024").public_key # creates a copy with params only
+ # Creates a copy with params only
+ dh = Fixtures.pkey("dh2048_ffdhe2048").public_key
assert_no_key(dh)
dh.generate_key!
assert_key(dh)
@@ -91,7 +107,15 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end if !openssl?(3, 0, 0)
def test_params_ok?
- dh0 = Fixtures.pkey("dh1024")
+ # Skip the tests in old OpenSSL version 1.1.1c or early versions before
+ # applying the following commits in OpenSSL 1.1.1d to make `DH_check`
+ # function pass the RFC 7919 FFDHE group texts.
+ # https://github.com/openssl/openssl/pull/9435
+ unless openssl?(1, 1, 1, 4)
+ pend 'DH check for RFC 7919 FFDHE group texts is not implemented'
+ end
+
+ dh0 = Fixtures.pkey("dh2048_ffdhe2048")
dh1 = OpenSSL::PKey::DH.new(OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(dh0.p),
@@ -108,7 +132,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
def test_dup
# Parameters only
- dh1 = Fixtures.pkey("dh1024")
+ dh1 = Fixtures.pkey("dh2048_ffdhe2048")
dh2 = dh1.dup
assert_equal dh1.to_der, dh2.to_der
assert_not_equal nil, dh1.p
@@ -125,7 +149,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
# With a key pair
- dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh1024"))
+ dh3 = OpenSSL::PKey.generate_key(Fixtures.pkey("dh2048_ffdhe2048"))
dh4 = dh3.dup
assert_equal dh3.to_der, dh4.to_der
assert_equal dh1.to_der, dh4.to_der # encodes parameters only
@@ -136,7 +160,7 @@ class OpenSSL::TestPKeyDH < OpenSSL::PKeyTestCase
end
def test_marshal
- dh = Fixtures.pkey("dh1024")
+ dh = Fixtures.pkey("dh2048_ffdhe2048")
deserialized = Marshal.load(Marshal.dump(dh))
assert_equal dh.to_der, deserialized.to_der
diff --git a/test/openssl/test_pkey_dsa.rb b/test/openssl/test_pkey_dsa.rb
index 726b7dbf7e..4c93f2869d 100644
--- a/test/openssl/test_pkey_dsa.rb
+++ b/test/openssl/test_pkey_dsa.rb
@@ -28,28 +28,55 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
end
end
+ def test_generate
+ # DSA.generate used to call DSA_generate_parameters_ex(), which adjusts the
+ # size of q according to the size of p
+ key2048 = OpenSSL::PKey::DSA.generate(2048)
+ assert_equal 2048, key2048.p.num_bits
+ assert_equal 256, key2048.q.num_bits
+
+ if ENV["OSSL_TEST_ALL"] == "1" # slow
+ key3072 = OpenSSL::PKey::DSA.generate(3072)
+ assert_equal 3072, key3072.p.num_bits
+ assert_equal 256, key3072.q.num_bits
+ end
+ end
+
+ def test_generate_on_non_fips
+ # DSA with 1024 bits is invalid on FIPS 186-4.
+ # https://github.com/openssl/openssl/commit/49ed5ba8f62875074f04417189147fd3dda072ab
+ omit_on_fips
+
+ key1024 = OpenSSL::PKey::DSA.generate(1024)
+ assert_predicate key1024, :private?
+ assert_equal 1024, key1024.p.num_bits
+ assert_equal 160, key1024.q.num_bits
+ end
+
def test_sign_verify
- dsa512 = Fixtures.pkey("dsa512")
+ # The DSA valid size is 2048 or 3072 on FIPS.
+ # https://github.com/openssl/openssl/blob/7649b5548e5c0352b91d9d3ed695e42a2ac1e99c/providers/common/securitycheck.c#L185-L188
+ dsa = Fixtures.pkey("dsa2048")
data = "Sign me!"
if defined?(OpenSSL::Digest::DSS1)
- signature = dsa512.sign(OpenSSL::Digest.new('DSS1'), data)
- assert_equal true, dsa512.verify(OpenSSL::Digest.new('DSS1'), signature, data)
+ signature = dsa.sign(OpenSSL::Digest.new('DSS1'), data)
+ assert_equal true, dsa.verify(OpenSSL::Digest.new('DSS1'), signature, data)
end
- signature = dsa512.sign("SHA1", data)
- assert_equal true, dsa512.verify("SHA1", signature, data)
+ signature = dsa.sign("SHA256", data)
+ assert_equal true, dsa.verify("SHA256", signature, data)
- signature0 = (<<~'end;').unpack("m")[0]
- MCwCFH5h40plgU5Fh0Z4wvEEpz0eE9SnAhRPbkRB8ggsN/vsSEYMXvJwjGg/
- 6g==
+ signature0 = (<<~'end;').unpack1("m")
+ MD4CHQC0zmRkVOAHJTm28fS5PVUv+4LtBeNaKqr/yfmVAh0AsTcLqofWHoW8X5oWu8AOvngOcFVZ
+ cLTvhY3XNw==
end;
- assert_equal true, dsa512.verify("SHA256", signature0, data)
+ assert_equal true, dsa.verify("SHA256", signature0, data)
signature1 = signature0.succ
- assert_equal false, dsa512.verify("SHA256", signature1, data)
+ assert_equal false, dsa.verify("SHA256", signature1, data)
end
def test_sign_verify_raw
- key = Fixtures.pkey("dsa512")
+ key = Fixtures.pkey("dsa2048")
data = 'Sign me!'
digest = OpenSSL::Digest.digest('SHA1', data)
@@ -108,6 +135,8 @@ class OpenSSL::TestPKeyDSA < OpenSSL::PKeyTestCase
end
def test_DSAPrivateKey_encrypted
+ omit_on_fips
+
# key = abcdef
dsa512 = Fixtures.pkey("dsa512")
pem = <<~EOF
diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb
index ffe5a94e5b..2cb8e287ab 100644
--- a/test/openssl/test_pkey_ec.rb
+++ b/test/openssl/test_pkey_ec.rb
@@ -5,20 +5,6 @@ if defined?(OpenSSL)
class OpenSSL::TestEC < OpenSSL::PKeyTestCase
def test_ec_key
- builtin_curves = OpenSSL::PKey::EC.builtin_curves
- assert_not_empty builtin_curves
-
- builtin_curves.each do |curve_name, comment|
- # Oakley curves and X25519 are not suitable for signing and causes
- # FIPS-selftest failure on some environment, so skip for now.
- next if ["Oakley", "X25519"].any? { |n| curve_name.start_with?(n) }
-
- key = OpenSSL::PKey::EC.generate(curve_name)
- assert_predicate key, :private?
- assert_predicate key, :public?
- assert_nothing_raised { key.check_key }
- end
-
key1 = OpenSSL::PKey::EC.generate("prime256v1")
# PKey is immutable in OpenSSL >= 3.0; constructing an empty EC object is
@@ -49,6 +35,17 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
end
end
+ def test_builtin_curves
+ builtin_curves = OpenSSL::PKey::EC.builtin_curves
+ assert_not_empty builtin_curves
+ assert_equal 2, builtin_curves[0].size
+ assert_kind_of String, builtin_curves[0][0]
+ assert_kind_of String, builtin_curves[0][1]
+
+ builtin_curve_names = builtin_curves.map { |name, comment| name }
+ assert_include builtin_curve_names, "prime256v1"
+ end
+
def test_generate
assert_raise(OpenSSL::PKey::ECError) { OpenSSL::PKey::EC.generate("non-existent") }
g = OpenSSL::PKey::EC::Group.new("prime256v1")
@@ -61,8 +58,10 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
def test_generate_key
ec = OpenSSL::PKey::EC.new("prime256v1")
assert_equal false, ec.private?
+ assert_raise(OpenSSL::PKey::ECError) { ec.to_der }
ec.generate_key!
assert_equal true, ec.private?
+ assert_nothing_raised { ec.to_der }
end if !openssl?(3, 0, 0)
def test_marshal
@@ -88,6 +87,13 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
assert_equal(true, key2.public?)
assert_equal(true, key2.check_key)
+ # Behavior of EVP_PKEY_public_check changes between OpenSSL 1.1.1 and 3.0
+ key4 = Fixtures.pkey("p256_too_large")
+ assert_raise(OpenSSL::PKey::ECError) { key4.check_key }
+
+ key5 = Fixtures.pkey("p384_invalid")
+ assert_raise(OpenSSL::PKey::ECError) { key5.check_key }
+
# EC#private_key= is deprecated in 3.0 and won't work on OpenSSL 3.0
if !openssl?(3, 0, 0)
key2.private_key += 1
@@ -98,10 +104,10 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
def test_sign_verify
p256 = Fixtures.pkey("p256")
data = "Sign me!"
- signature = p256.sign("SHA1", data)
- assert_equal true, p256.verify("SHA1", signature, data)
+ signature = p256.sign("SHA256", data)
+ assert_equal true, p256.verify("SHA256", signature, data)
- signature0 = (<<~'end;').unpack("m")[0]
+ signature0 = (<<~'end;').unpack1("m")
MEQCIEOTY/hD7eI8a0qlzxkIt8LLZ8uwiaSfVbjX2dPAvN11AiAQdCYx56Fq
QdBp1B4sxJoA8jvODMMklMyBKVmudboA6A==
end;
@@ -199,7 +205,32 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase
assert_equal pem, p256.export
end
+ def test_ECPrivateKey_with_parameters
+ p256 = Fixtures.pkey("p256")
+
+ # The format used by "openssl ecparam -name prime256v1 -genkey -outform PEM"
+ #
+ # "EC PARAMETERS" block should be ignored if it is followed by an
+ # "EC PRIVATE KEY" block
+ in_pem = <<~EOF
+ -----BEGIN EC PARAMETERS-----
+ BggqhkjOPQMBBw==
+ -----END EC PARAMETERS-----
+ -----BEGIN EC PRIVATE KEY-----
+ MHcCAQEEIID49FDqcf1O1eO8saTgG70UbXQw9Fqwseliit2aWhH1oAoGCCqGSM49
+ AwEHoUQDQgAEFglk2c+oVUIKQ64eZG9bhLNPWB7lSZ/ArK41eGy5wAzU/0G51Xtt
+ CeBUl+MahZtn9fO1JKdF4qJmS39dXnpENg==
+ -----END EC PRIVATE KEY-----
+ EOF
+
+ key = OpenSSL::PKey::EC.new(in_pem)
+ assert_same_ec p256, key
+ assert_equal p256.to_der, key.to_der
+ end
+
def test_ECPrivateKey_encrypted
+ omit_on_fips
+
p256 = Fixtures.pkey("p256")
# key = abcdef
pem = <<~EOF
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index 4bb39ed4a6..61c55c60b2 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -80,10 +80,10 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
def test_sign_verify
rsa1024 = Fixtures.pkey("rsa1024")
data = "Sign me!"
- signature = rsa1024.sign("SHA1", data)
- assert_equal true, rsa1024.verify("SHA1", signature, data)
+ signature = rsa1024.sign("SHA256", data)
+ assert_equal true, rsa1024.verify("SHA256", signature, data)
- signature0 = (<<~'end;').unpack("m")[0]
+ signature0 = (<<~'end;').unpack1("m")
oLCgbprPvfhM4pjFQiDTFeWI9Sk+Og7Nh9TmIZ/xSxf2CGXQrptlwo7NQ28+
WA6YQo8jPH4hSuyWIM4Gz4qRYiYRkl5TDMUYob94zm8Si1HxEiS9354tzvqS
zS8MLW2BtNPuTubMxTItHGTnOzo9sUg0LAHVFt8kHG2NfKAw/gQ=
@@ -108,15 +108,20 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
salt_length: 20, mgf1_hash: "SHA1")
# Defaults to PKCS #1 v1.5 padding => verification failure
assert_equal false, key.verify("SHA256", sig_pss, data)
+
+ # option type check
+ assert_raise_with_message(TypeError, /expected Hash/) {
+ key.sign("SHA256", data, ["x"])
+ }
end
def test_sign_verify_raw
key = Fixtures.pkey("rsa-1")
data = "Sign me!"
- hash = OpenSSL::Digest.digest("SHA1", data)
- signature = key.sign_raw("SHA1", hash)
- assert_equal true, key.verify_raw("SHA1", signature, hash)
- assert_equal true, key.verify("SHA1", signature, data)
+ hash = OpenSSL::Digest.digest("SHA256", data)
+ signature = key.sign_raw("SHA256", hash)
+ assert_equal true, key.verify_raw("SHA256", signature, hash)
+ assert_equal true, key.verify("SHA256", signature, data)
# Too long data
assert_raise(OpenSSL::PKey::PKeyError) {
@@ -129,9 +134,9 @@ class OpenSSL::TestPKeyRSA < OpenSSL::PKeyTestCase
"rsa_pss_saltlen" => 20,
"rsa_mgf1_md" => "SHA256"
}
- sig_pss = key.sign_raw("SHA1", hash, pssopts)
- assert_equal true, key.verify("SHA1", sig_pss, data, pssopts)
- assert_equal true, key.verify_raw("SHA1", sig_pss, hash, pssopts)
+ sig_pss = key.sign_raw("SHA256", hash, pssopts)
+ assert_equal true, key.verify("SHA256", sig_pss, data, pssopts)
+ assert_equal true, key.verify_raw("SHA256", sig_pss, hash, pssopts)
end
def test_sign_verify_raw_legacy
diff --git a/test/openssl/test_provider.rb b/test/openssl/test_provider.rb
new file mode 100644
index 0000000000..b0ffae9ce7
--- /dev/null
+++ b/test/openssl/test_provider.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+require_relative 'utils'
+if defined?(OpenSSL) && defined?(OpenSSL::Provider) && !OpenSSL.fips_mode
+
+class OpenSSL::TestProvider < OpenSSL::TestCase
+ def test_openssl_provider_name_inspect
+ with_openssl <<-'end;'
+ provider = OpenSSL::Provider.load("default")
+ assert_equal("default", provider.name)
+ assert_not_nil(provider.inspect)
+ end;
+ end
+
+ def test_openssl_provider_names
+ with_openssl <<-'end;'
+ base_provider = OpenSSL::Provider.load("base")
+ assert_equal(2, OpenSSL::Provider.provider_names.size)
+ assert_includes(OpenSSL::Provider.provider_names, "base")
+
+ assert_equal(true, base_provider.unload)
+ assert_equal(1, OpenSSL::Provider.provider_names.size)
+ assert_not_includes(OpenSSL::Provider.provider_names, "base")
+ end;
+ end
+
+ def test_unloaded_openssl_provider
+ with_openssl <<-'end;'
+ default_provider = OpenSSL::Provider.load("default")
+ assert_equal(true, default_provider.unload)
+ assert_raise(OpenSSL::Provider::ProviderError) { default_provider.name }
+ assert_raise(OpenSSL::Provider::ProviderError) { default_provider.unload }
+ end;
+ end
+
+ def test_openssl_legacy_provider
+ with_openssl(<<-'end;')
+ begin
+ OpenSSL::Provider.load("legacy")
+ rescue OpenSSL::Provider::ProviderError
+ omit "Only for OpenSSL with legacy provider"
+ end
+
+ algo = "RC4"
+ data = "a" * 1000
+ key = OpenSSL::Random.random_bytes(16)
+
+ # default provider does not support RC4
+ cipher = OpenSSL::Cipher.new(algo)
+ cipher.encrypt
+ cipher.key = key
+ encrypted = cipher.update(data) + cipher.final
+
+ other_cipher = OpenSSL::Cipher.new(algo)
+ other_cipher.decrypt
+ other_cipher.key = key
+ decrypted = other_cipher.update(encrypted) + other_cipher.final
+
+ assert_equal(data, decrypted)
+ end;
+ end
+
+ private
+
+ # this is required because OpenSSL::Provider methods change global state
+ def with_openssl(code, **opts)
+ assert_separately(["-ropenssl"], <<~"end;", **opts)
+ #{code}
+ end;
+ end
+end
+
+end
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 5679ae77d7..66d63a981d 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require_relative "utils"
-if defined?(OpenSSL)
+if defined?(OpenSSL::SSL)
class OpenSSL::TestSSL < OpenSSL::SSLTestCase
def test_bad_socket
@@ -193,6 +193,24 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
end
+ def test_read_with_timeout
+ omit "does not support timeout" unless IO.method_defined?(:timeout)
+
+ start_server do |port|
+ server_connect(port) do |ssl|
+ str = +("x" * 100 + "\n")
+ ssl.syswrite(str)
+ assert_equal(str, ssl.sysread(str.bytesize))
+
+ ssl.timeout = 1
+ assert_raise(IO::TimeoutError) {ssl.read(1)}
+
+ ssl.syswrite(str)
+ assert_equal(str, ssl.sysread(str.bytesize))
+ end
+ end
+ end
+
def test_getbyte
start_server { |port|
server_connect(port) { |ssl|
@@ -481,6 +499,40 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
}
end
+ def test_ca_file
+ start_server(ignore_listener_error: true) { |port|
+ # X509_STORE is shared; setting ca_file to SSLContext affects store
+ store = OpenSSL::X509::Store.new
+ assert_equal false, store.verify(@svr_cert)
+
+ ctx = Tempfile.create("ca_cert.pem") { |f|
+ f.puts(@ca_cert.to_pem)
+ f.close
+
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ ctx.cert_store = store
+ ctx.ca_file = f.path
+ ctx.setup
+ ctx
+ }
+ assert_nothing_raised {
+ server_connect(port, ctx) { |ssl| ssl.puts("abc"); ssl.gets }
+ }
+ assert_equal true, store.verify(@svr_cert)
+ }
+ end
+
+ def test_ca_file_not_found
+ path = Tempfile.create("ca_cert.pem") { |f| f.path }
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.ca_file = path
+ # OpenSSL >= 1.1.0: /no certificate or crl found/
+ assert_raise(OpenSSL::SSL::SSLError) {
+ ctx.setup
+ }
+ end
+
def test_finished_messages
server_finished = nil
server_peer_finished = nil
@@ -639,7 +691,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
assert_equal(true, OpenSSL::SSL.verify_wildcard("xn--qdk4b9b", "xn--qdk4b9b"))
end
- # Comments in this test is excerpted from http://tools.ietf.org/html/rfc6125#page-27
+ # Comments in this test is excerpted from https://www.rfc-editor.org/rfc/rfc6125#page-27
def test_post_connection_check_wildcard_san
# case-insensitive ASCII comparison
# RFC 6125, section 6.4.1
@@ -804,6 +856,54 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
end
+ def test_keylog_cb
+ pend "Keylog callback is not supported" if !openssl?(1, 1, 1) || libressl?
+
+ prefix = 'CLIENT_RANDOM'
+ context = OpenSSL::SSL::SSLContext.new
+ context.min_version = context.max_version = OpenSSL::SSL::TLS1_2_VERSION
+
+ cb_called = false
+ context.keylog_cb = proc do |_sock, line|
+ cb_called = true
+ assert_equal(prefix, line.split.first)
+ end
+
+ start_server do |port|
+ server_connect(port, context) do |ssl|
+ ssl.puts "abc"
+ assert_equal("abc\n", ssl.gets)
+ assert_equal(true, cb_called)
+ end
+ end
+
+ if tls13_supported?
+ prefixes = [
+ 'SERVER_HANDSHAKE_TRAFFIC_SECRET',
+ 'EXPORTER_SECRET',
+ 'SERVER_TRAFFIC_SECRET_0',
+ 'CLIENT_HANDSHAKE_TRAFFIC_SECRET',
+ 'CLIENT_TRAFFIC_SECRET_0',
+ ]
+ context = OpenSSL::SSL::SSLContext.new
+ context.min_version = context.max_version = OpenSSL::SSL::TLS1_3_VERSION
+ cb_called = false
+ context.keylog_cb = proc do |_sock, line|
+ cb_called = true
+ assert_not_nil(prefixes.delete(line.split.first))
+ end
+
+ start_server do |port|
+ server_connect(port, context) do |ssl|
+ ssl.puts "abc"
+ assert_equal("abc\n", ssl.gets)
+ assert_equal(true, cb_called)
+ end
+ assert_equal(0, prefixes.size)
+ end
+ end
+ end
+
def test_tlsext_hostname
fooctx = OpenSSL::SSL::SSLContext.new
fooctx.cert = @cli_cert
@@ -1331,9 +1431,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_npn_protocol_selection_ary
- pend "NPN is not supported" unless \
- OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
- pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
+ return unless OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
advertised = ["http/1.1", "spdy/2"]
ctx_proc = proc { |ctx| ctx.npn_protocols = advertised }
@@ -1351,9 +1449,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_npn_protocol_selection_enum
- pend "NPN is not supported" unless \
- OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
- pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
+ return unless OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
advertised = Object.new
def advertised.each
@@ -1375,9 +1471,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_npn_protocol_selection_cancel
- pend "NPN is not supported" unless \
- OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
- pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
+ return unless OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["http/1.1"] }
start_server_version(:TLSv1_2, ctx_proc) { |port|
@@ -1388,9 +1482,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_npn_advertised_protocol_too_long
- pend "NPN is not supported" unless \
- OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
- pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
+ return unless OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["a" * 256] }
start_server_version(:TLSv1_2, ctx_proc) { |port|
@@ -1401,9 +1493,7 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
def test_npn_selected_protocol_too_long
- pend "NPN is not supported" unless \
- OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
- pend "LibreSSL 2.6 has broken NPN functions" if libressl?(2, 6, 1)
+ return unless OpenSSL::SSL::SSLContext.method_defined?(:npn_select_cb)
ctx_proc = Proc.new { |ctx| ctx.npn_protocols = ["http/1.1"] }
start_server_version(:TLSv1_2, ctx_proc) { |port|
@@ -1817,6 +1907,19 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
sock2.close
end
+ def test_export_keying_material
+ start_server do |port|
+ cli_ctx = OpenSSL::SSL::SSLContext.new
+ server_connect(port, cli_ctx) do |ssl|
+ assert_instance_of(String, ssl.export_keying_material('ttls keying material', 64))
+ assert_operator(64, :==, ssl.export_keying_material('ttls keying material', 64).b.length)
+ assert_operator(8, :==, ssl.export_keying_material('ttls keying material', 8).b.length)
+ assert_operator(5, :==, ssl.export_keying_material('test', 5, 'context').b.length)
+ ssl.puts "abc"; ssl.gets # workaround to make tests work on windows
+ end
+ end
+ end
+
private
def start_server_version(version, ctx_proc = nil,
diff --git a/test/openssl/test_ssl_session.rb b/test/openssl/test_ssl_session.rb
index b72b10d3b5..89cf672a7b 100644
--- a/test/openssl/test_ssl_session.rb
+++ b/test/openssl/test_ssl_session.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require_relative "utils"
-if defined?(OpenSSL)
+if defined?(OpenSSL::SSL)
class OpenSSL::TestSSLSession < OpenSSL::SSLTestCase
def test_session
@@ -22,7 +22,7 @@ class OpenSSL::TestSSLSession < OpenSSL::SSLTestCase
assert_match(/\A-----BEGIN SSL SESSION PARAMETERS-----/, pem)
assert_match(/-----END SSL SESSION PARAMETERS-----\Z/, pem)
pem.gsub!(/-----(BEGIN|END) SSL SESSION PARAMETERS-----/, '').gsub!(/[\r\n]+/m, '')
- assert_equal(session.to_der, pem.unpack('m*')[0])
+ assert_equal(session.to_der, pem.unpack1('m'))
assert_not_nil(session.to_text)
}
end
diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb
index d696b98c0a..64805504de 100644
--- a/test/openssl/test_x509cert.rb
+++ b/test/openssl/test_x509cert.rb
@@ -173,13 +173,14 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
end
def test_sign_and_verify_rsa_sha1
- cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil, digest: "sha1")
+ cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil, digest: "SHA1")
assert_equal(false, cert.verify(@rsa1024))
assert_equal(true, cert.verify(@rsa2048))
assert_equal(false, certificate_error_returns_false { cert.verify(@dsa256) })
assert_equal(false, certificate_error_returns_false { cert.verify(@dsa512) })
cert.serial = 2
assert_equal(false, cert.verify(@rsa2048))
+ rescue OpenSSL::X509::CertificateError # RHEL 9 disables SHA1
end
def test_sign_and_verify_rsa_md5
@@ -229,6 +230,7 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
# SHA1 is allowed from OpenSSL 1.0.0 (0.9.8 requires DSS1)
cert = issue_cert(@ca, @dsa256, 1, [], nil, nil, digest: "sha1")
assert_equal("dsaWithSHA1", cert.signature_algorithm)
+ rescue OpenSSL::X509::CertificateError # RHEL 9 disables SHA1
end
def test_check_private_key
diff --git a/test/openssl/test_x509crl.rb b/test/openssl/test_x509crl.rb
index bcdb0a697c..146ee07309 100644
--- a/test/openssl/test_x509crl.rb
+++ b/test/openssl/test_x509crl.rb
@@ -20,7 +20,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
crl = issue_crl([], 1, now, now+1600, [],
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
assert_equal(1, crl.version)
assert_equal(cert.issuer.to_der, crl.issuer.to_der)
assert_equal(now, crl.last_update)
@@ -57,7 +57,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
]
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
revoked = crl.revoked
assert_equal(5, revoked.size)
assert_equal(1, revoked[0].serial)
@@ -98,7 +98,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
revoke_info = (1..1000).collect{|i| [i, now, 0] }
crl = issue_crl(revoke_info, 1, Time.now, Time.now+1600, [],
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
revoked = crl.revoked
assert_equal(1000, revoked.size)
assert_equal(1, revoked[0].serial)
@@ -124,7 +124,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
cert = issue_cert(@ca, @rsa2048, 1, cert_exts, nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, crl_exts,
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
exts = crl.extensions
assert_equal(3, exts.size)
assert_equal("1", exts[0].value)
@@ -160,24 +160,24 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
assert_equal(false, exts[2].critical?)
no_ext_crl = issue_crl([], 1, Time.now, Time.now+1600, [],
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
assert_equal nil, no_ext_crl.authority_key_identifier
end
def test_crlnumber
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
assert_match(1.to_s, crl.extensions[0].value)
assert_match(/X509v3 CRL Number:\s+#{1}/m, crl.to_text)
crl = issue_crl([], 2**32, Time.now, Time.now+1600, [],
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
assert_match((2**32).to_s, crl.extensions[0].value)
assert_match(/X509v3 CRL Number:\s+#{2**32}/m, crl.to_text)
crl = issue_crl([], 2**100, Time.now, Time.now+1600, [],
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
assert_match(/X509v3 CRL Number:\s+#{2**100}/m, crl.to_text)
assert_match((2**100).to_s, crl.extensions[0].value)
end
@@ -185,7 +185,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
def test_sign_and_verify
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
- cert, @rsa2048, OpenSSL::Digest.new('SHA1'))
+ cert, @rsa2048, OpenSSL::Digest.new('SHA256'))
assert_equal(false, crl.verify(@rsa1024))
assert_equal(true, crl.verify(@rsa2048))
assert_equal(false, crl_error_returns_false { crl.verify(@dsa256) })
@@ -195,7 +195,7 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
cert = issue_cert(@ca, @dsa512, 1, [], nil, nil)
crl = issue_crl([], 1, Time.now, Time.now+1600, [],
- cert, @dsa512, OpenSSL::Digest.new('SHA1'))
+ cert, @dsa512, OpenSSL::Digest.new('SHA256'))
assert_equal(false, crl_error_returns_false { crl.verify(@rsa1024) })
assert_equal(false, crl_error_returns_false { crl.verify(@rsa2048) })
assert_equal(false, crl.verify(@dsa256))
diff --git a/test/openssl/test_x509ext.rb b/test/openssl/test_x509ext.rb
index 7ad010d1ed..59a41ed736 100644
--- a/test/openssl/test_x509ext.rb
+++ b/test/openssl/test_x509ext.rb
@@ -50,24 +50,41 @@ class OpenSSL::TestX509Extension < OpenSSL::TestCase
cdp = ef.create_extension("crlDistributionPoints", "@crlDistPts")
assert_equal(false, cdp.critical?)
assert_equal("crlDistributionPoints", cdp.oid)
- assert_match(%{URI:http://www\.example\.com/crl}, cdp.value)
- assert_match(
- %r{URI:ldap://ldap\.example\.com/cn=ca\?certificateRevocationList;binary},
- cdp.value)
+ assert_include(cdp.value, "URI:http://www.example.com/crl")
+ assert_include(cdp.value,
+ "URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary")
cdp = ef.create_extension("crlDistributionPoints", "critical, @crlDistPts")
assert_equal(true, cdp.critical?)
assert_equal("crlDistributionPoints", cdp.oid)
- assert_match(%{URI:http://www.example.com/crl}, cdp.value)
- assert_match(
- %r{URI:ldap://ldap.example.com/cn=ca\?certificateRevocationList;binary},
- cdp.value)
+ assert_include(cdp.value, "URI:http://www.example.com/crl")
+ assert_include(cdp.value,
+ "URI:ldap://ldap.example.com/cn=ca?certificateRevocationList;binary")
cp = ef.create_extension("certificatePolicies", "@certPolicies")
assert_equal(false, cp.critical?)
assert_equal("certificatePolicies", cp.oid)
- assert_match(%r{2.23.140.1.2.1}, cp.value)
- assert_match(%r{http://cps.example.com}, cp.value)
+ assert_include(cp.value, "2.23.140.1.2.1")
+ assert_include(cp.value, "http://cps.example.com")
+ end
+
+ def test_factory_create_extension_sn_ln
+ ef = OpenSSL::X509::ExtensionFactory.new
+ bc_sn = ef.create_extension("basicConstraints", "critical, CA:TRUE, pathlen:2")
+ bc_ln = ef.create_extension("X509v3 Basic Constraints", "critical, CA:TRUE, pathlen:2")
+ assert_equal(@basic_constraints.to_der, bc_sn.to_der)
+ assert_equal(@basic_constraints.to_der, bc_ln.to_der)
+ end
+
+ def test_factory_create_extension_oid
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ef.config = OpenSSL::Config.parse(<<~_end_of_cnf_)
+ [basic_constraints]
+ cA = BOOLEAN:TRUE
+ pathLenConstraint = INTEGER:2
+ _end_of_cnf_
+ bc_oid = ef.create_extension("2.5.29.19", "ASN1:SEQUENCE:basic_constraints", true)
+ assert_equal(@basic_constraints.to_der, bc_oid.to_der)
end
def test_dup
diff --git a/test/openssl/test_x509req.rb b/test/openssl/test_x509req.rb
index ee9c678fbb..ff17c41163 100644
--- a/test/openssl/test_x509req.rb
+++ b/test/openssl/test_x509req.rb
@@ -23,31 +23,31 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
end
def test_public_key
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1'))
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(@rsa1024.public_key.to_der, req.public_key.to_der)
- req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA1'))
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA256'))
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(@dsa512.public_key.to_der, req.public_key.to_der)
end
def test_version
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1'))
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
assert_equal(0, req.version)
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(0, req.version)
- req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest.new('SHA1'))
+ req = issue_csr(1, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
assert_equal(1, req.version)
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(1, req.version)
end
def test_subject
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1'))
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
assert_equal(@dn.to_der, req.subject.to_der)
req = OpenSSL::X509::Request.new(req.to_der)
assert_equal(@dn.to_der, req.subject.to_der)
@@ -78,9 +78,9 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
OpenSSL::X509::Attribute.new("msExtReq", attrval),
]
- req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1'))
+ req0 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
attrs.each{|attr| req0.add_attribute(attr) }
- req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1'))
+ req1 = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
req1.attributes = attrs
assert_equal(req0.to_der, req1.to_der)
@@ -108,6 +108,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
assert_equal(false, request_error_returns_false { req.verify(@dsa512) })
req.version = 1
assert_equal(false, req.verify(@rsa1024))
+ rescue OpenSSL::X509::RequestError # RHEL 9 disables SHA1
end
def test_sign_and_verify_rsa_md5
@@ -122,7 +123,7 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
end
def test_sign_and_verify_dsa
- req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA1'))
+ req = issue_csr(0, @dn, @dsa512, OpenSSL::Digest.new('SHA256'))
assert_equal(false, request_error_returns_false { req.verify(@rsa1024) })
assert_equal(false, request_error_returns_false { req.verify(@rsa2048) })
assert_equal(false, req.verify(@dsa256))
@@ -137,14 +138,14 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
end
def test_dup
- req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA1'))
+ req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest.new('SHA256'))
assert_equal(req.to_der, req.dup.to_der)
end
def test_eq
- req1 = issue_csr(0, @dn, @rsa1024, "sha1")
- req2 = issue_csr(0, @dn, @rsa1024, "sha1")
- req3 = issue_csr(0, @dn, @rsa1024, "sha256")
+ req1 = issue_csr(0, @dn, @rsa1024, "sha256")
+ req2 = issue_csr(0, @dn, @rsa1024, "sha256")
+ req3 = issue_csr(0, @dn, @rsa1024, "sha512")
assert_equal false, req1 == 12345
assert_equal true, req1 == req2
diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb
index 4ebcb9837b..f6c84eef67 100644
--- a/test/openssl/utils.rb
+++ b/test/openssl/utils.rb
@@ -1,38 +1,13 @@
# frozen_string_literal: true
begin
require "openssl"
-
- # Disable FIPS mode for tests for installations
- # where FIPS mode would be enabled by default.
- # Has no effect on all other installations.
- OpenSSL.fips_mode=false
rescue LoadError
end
-# Compile OpenSSL with crypto-mdebug and run this test suite with OSSL_MDEBUG=1
-# environment variable to enable memory leak check.
-if ENV["OSSL_MDEBUG"] == "1"
- if OpenSSL.respond_to?(:print_mem_leaks)
- OpenSSL.mem_check_start
-
- END {
- GC.start
- case OpenSSL.print_mem_leaks
- when nil
- warn "mdebug: check what is printed"
- when true
- raise "mdebug: memory leaks detected"
- end
- }
- else
- warn "OSSL_MDEBUG=1 is specified but OpenSSL is not built with crypto-mdebug"
- end
-end
-
require "test/unit"
+require "core_assertions"
require "tempfile"
require "socket"
-require "envutil"
if defined?(OpenSSL)
@@ -131,11 +106,12 @@ module OpenSSL::TestUtils
end
end
- def openssl?(major = nil, minor = nil, fix = nil, patch = 0)
+ def openssl?(major = nil, minor = nil, fix = nil, patch = 0, status = 0)
return false if OpenSSL::OPENSSL_VERSION.include?("LibreSSL")
return true unless major
OpenSSL::OPENSSL_VERSION_NUMBER >=
- major * 0x10000000 + minor * 0x100000 + fix * 0x1000 + patch * 0x10
+ major * 0x10000000 + minor * 0x100000 + fix * 0x1000 + patch * 0x10 +
+ status * 0x1
end
def libressl?(major = nil, minor = nil, fix = nil)
@@ -148,6 +124,7 @@ end
class OpenSSL::TestCase < Test::Unit::TestCase
include OpenSSL::TestUtils
extend OpenSSL::TestUtils
+ include Test::Unit::CoreAssertions
def setup
if ENV["OSSL_GC_STRESS"] == "1"
@@ -162,6 +139,30 @@ class OpenSSL::TestCase < Test::Unit::TestCase
# OpenSSL error stack must be empty
assert_equal([], OpenSSL.errors)
end
+
+ # Omit the tests in FIPS.
+ #
+ # For example, the password based encryption used in the PEM format uses MD5
+ # for deriving the encryption key from the password, and MD5 is not
+ # FIPS-approved.
+ #
+ # See https://github.com/openssl/openssl/discussions/21830#discussioncomment-6865636
+ # for details.
+ def omit_on_fips
+ return unless OpenSSL.fips_mode
+
+ omit <<~MESSAGE
+ Only for OpenSSL non-FIPS with the following possible reasons:
+ * A testing logic is non-FIPS specific.
+ * An encryption used in the test is not FIPS-approved.
+ MESSAGE
+ end
+
+ def omit_on_non_fips
+ return if OpenSSL.fips_mode
+
+ omit "Only for OpenSSL FIPS"
+ end
end
class OpenSSL::SSLTestCase < OpenSSL::TestCase
diff --git a/test/optparse/test_acceptable.rb b/test/optparse/test_acceptable.rb
index 12f5322726..c7ea2152fc 100644
--- a/test/optparse/test_acceptable.rb
+++ b/test/optparse/test_acceptable.rb
@@ -8,6 +8,7 @@ class TestOptionParserAcceptable < TestOptionParser
@opt.def_option("--integer VAL", Integer) { |v| @integer = v }
@opt.def_option("--float VAL", Float) { |v| @float = v }
@opt.def_option("--numeric VAL", Numeric) { |v| @numeric = v }
+ @opt.def_option("--array VAL", Array) { |v| @array = v }
@opt.def_option("--decimal-integer VAL",
OptionParser::DecimalInteger) { |i| @decimal_integer = i }
@@ -195,4 +196,8 @@ class TestOptionParserAcceptable < TestOptionParser
end
end
+ def test_array
+ assert_equal(%w"", no_error {@opt.parse!(%w"--array a,b,c")})
+ assert_equal(%w"a b c", @array)
+ end
end
diff --git a/test/optparse/test_getopts.rb b/test/optparse/test_getopts.rb
index 7d9160f7af..4a0ae284e7 100644
--- a/test/optparse/test_getopts.rb
+++ b/test/optparse/test_getopts.rb
@@ -11,23 +11,39 @@ class TestOptionParserGetopts < Test::Unit::TestCase
o = @opt.getopts(%w[-a], "ab")
assert_equal(true, o['a'])
assert_equal(false, o['b'])
+
+ o = @opt.getopts(%w[-a], "ab", symbolize_names: true)
+ assert_equal(true, o[:a])
+ assert_equal(false, o[:b])
end
def test_short_arg
o = @opt.getopts(%w[-a1], "a:b:")
assert_equal("1", o['a'])
assert_equal(nil, o['b'])
+
+ o = @opt.getopts(%w[-a1], "a:b:", symbolize_names: true)
+ assert_equal("1", o[:a])
+ assert_equal(nil, o[:b])
end
def test_long_noarg
o = @opt.getopts(%w[--foo], "", "foo", "bar")
assert_equal(true, o['foo'])
assert_equal(false, o['bar'])
+
+ o = @opt.getopts(%w[--foo], "", "foo", "bar", symbolize_names: true)
+ assert_equal(true, o[:foo])
+ assert_equal(false, o[:bar])
end
def test_long_arg
o = @opt.getopts(%w[--bar ZOT], "", "foo:FOO", "bar:BAR")
assert_equal("FOO", o['foo'])
assert_equal("ZOT", o['bar'])
+
+ o = @opt.getopts(%w[--bar ZOT], "", "foo:FOO", "bar:BAR", symbolize_names: true)
+ assert_equal("FOO", o[:foo])
+ assert_equal("ZOT", o[:bar])
end
end
diff --git a/test/optparse/test_load.rb b/test/optparse/test_load.rb
new file mode 100644
index 0000000000..0ebe855682
--- /dev/null
+++ b/test/optparse/test_load.rb
@@ -0,0 +1,141 @@
+# frozen_string_literal: false
+require 'test/unit'
+require 'optparse'
+require 'tmpdir'
+
+class TestOptionParserLoad < Test::Unit::TestCase
+ def setup
+ @tmpdir = Dir.mktmpdir("optparse_test-")
+ @basename = File.basename($0, '.*')
+ @envs = %w[HOME XDG_CONFIG_HOME XDG_CONFIG_DIRS].each_with_object({}) do |v, h|
+ h[v] = ENV.delete(v)
+ end
+ end
+
+ def teardown
+ ENV.update(@envs)
+ FileUtils.rm_rf(@tmpdir)
+ end
+
+ def new_parser
+ @result = nil
+ OptionParser.new do |opt|
+ opt.on("--test=arg") {|v| @result = v}
+ end
+ end
+
+ def assert_load(result)
+ assert new_parser.load
+ assert_equal(result, @result)
+ assert new_parser.load(into: into = {})
+ assert_equal({test: result}, into)
+ end
+
+ def setup_options(env, dir, suffix = nil)
+ optdir = File.join(@tmpdir, dir)
+ FileUtils.mkdir_p(optdir)
+ file = File.join(optdir, [@basename, suffix].join(""))
+ File.write(file, "--test=#{dir}")
+ ENV.update(env)
+ if block_given?
+ begin
+ yield dir, optdir
+ ensure
+ File.unlink(file)
+ Dir.rmdir(optdir) rescue nil
+ end
+ else
+ return dir, optdir
+ end
+ end
+
+ def setup_options_home(&block)
+ setup_options({'HOME'=>@tmpdir}, ".options", &block)
+ end
+
+ def setup_options_xdg_config_home(&block)
+ setup_options({'XDG_CONFIG_HOME'=>@tmpdir+"/xdg"}, "xdg", ".options", &block)
+ end
+
+ def setup_options_home_config(&block)
+ setup_options({'HOME'=>@tmpdir}, ".config", ".options", &block)
+ end
+
+ def setup_options_xdg_config_dirs(&block)
+ setup_options({'XDG_CONFIG_DIRS'=>@tmpdir+"/xdgconf"}, "xdgconf", ".options", &block)
+ end
+
+ def setup_options_home_config_settings(&block)
+ setup_options({'HOME'=>@tmpdir}, "config/settings", ".options", &block)
+ end
+
+ def test_load_home_options
+ result, = setup_options_home
+ assert_load(result)
+
+ setup_options_xdg_config_home do
+ assert_load(result)
+ end
+
+ setup_options_home_config do
+ assert_load(result)
+ end
+
+ setup_options_xdg_config_dirs do
+ assert_load(result)
+ end
+
+ setup_options_home_config_settings do
+ assert_load(result)
+ end
+ end
+
+ def test_load_xdg_config_home
+ result, = setup_options_xdg_config_home
+ assert_load(result)
+
+ setup_options_home_config do
+ assert_load(result)
+ end
+
+ setup_options_xdg_config_dirs do
+ assert_load(result)
+ end
+
+ setup_options_home_config_settings do
+ assert_load(result)
+ end
+ end
+
+ def test_load_home_config
+ result, = setup_options_home_config
+ assert_load(result)
+
+ setup_options_xdg_config_dirs do
+ assert_load(result)
+ end
+
+ setup_options_home_config_settings do
+ assert_load(result)
+ end
+ end
+
+ def test_load_xdg_config_dirs
+ result, = setup_options_xdg_config_dirs
+ assert_load(result)
+
+ setup_options_home_config_settings do
+ assert_load(result)
+ end
+ end
+
+ def test_load_home_config_settings
+ result, = setup_options_home_config_settings
+ assert_load(result)
+ end
+
+ def test_load_nothing
+ assert !new_parser.load
+ assert_nil @result
+ end
+end
diff --git a/test/optparse/test_optarg.rb b/test/optparse/test_optarg.rb
index 81127a8a37..f94460527f 100644
--- a/test/optparse/test_optarg.rb
+++ b/test/optparse/test_optarg.rb
@@ -9,6 +9,8 @@ class TestOptionParserOptArg < TestOptionParser
@opt.def_option("--regexp[=REGEXP]", Regexp) {|x| @reopt = x}
@opt.def_option "--with_underscore[=VAL]" do |x| @flag = x end
@opt.def_option "--with-hyphen[=VAL]" do |x| @flag = x end
+ @opt.def_option("--fallback[=VAL]") do |x = "fallback"| @flag = x end
+ @opt.def_option("--lambda[=VAL]", &->(x) {@flag = x})
@reopt = nil
end
@@ -57,4 +59,18 @@ class TestOptionParserOptArg < TestOptionParser
assert_equal(%w"", no_error {@opt.parse!(%w"--with_hyphen=foo4")})
assert_equal("foo4", @flag)
end
+
+ def test_default_argument
+ assert_equal(%w"", no_error {@opt.parse!(%w"--fallback=val1")})
+ assert_equal("val1", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--fallback")})
+ assert_equal("fallback", @flag)
+ end
+
+ def test_lambda
+ assert_equal(%w"", no_error {@opt.parse!(%w"--lambda=lambda1")})
+ assert_equal("lambda1", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--lambda")})
+ assert_equal(nil, @flag)
+ end
end
diff --git a/test/optparse/test_optparse.rb b/test/optparse/test_optparse.rb
index 5f5ea183b0..8d09e0f28b 100644
--- a/test/optparse/test_optparse.rb
+++ b/test/optparse/test_optparse.rb
@@ -63,6 +63,9 @@ class TestOptionParser < Test::Unit::TestCase
assert_equal(/foo/i, @reopt)
assert_equal(%w"", no_error {@opt.parse!(%w"--regexp=/foo/n")})
assert_equal(/foo/n, @reopt)
+ assert_equal(%w"", no_error {@opt.parse!(%W"--regexp=/\u{3042}/s")})
+ assert_equal(Encoding::Windows_31J, @reopt.encoding)
+ assert_equal("\x82\xa0".force_encoding(Encoding::Windows_31J), @reopt.source)
end
def test_into
@@ -70,10 +73,17 @@ class TestOptionParser < Test::Unit::TestCase
@opt.def_option "-p", "--port=PORT", "port", Integer
@opt.def_option "-v", "--verbose" do @verbose = true end
@opt.def_option "-q", "--quiet" do @quiet = true end
+ @opt.def_option "-o", "--option [OPT]" do |opt| @option = opt end
result = {}
@opt.parse %w(--host localhost --port 8000 -v), into: result
assert_equal({host: "localhost", port: 8000, verbose: true}, result)
assert_equal(true, @verbose)
+ result = {}
+ @opt.parse %w(--option -q), into: result
+ assert_equal({quiet: true, option: nil}, result)
+ result = {}
+ @opt.parse %w(--option OPTION -v), into: result
+ assert_equal({verbose: true, option: "OPTION"}, result)
end
def test_require_exact
@@ -85,9 +95,9 @@ class TestOptionParser < Test::Unit::TestCase
end
@opt.require_exact = true
- %w(--zrs -F -Ffoo).each do |arg|
+ [%w(--zrs foo), %w(--zrs=foo), %w(-F foo), %w(-Ffoo)].each do |args|
result = {}
- @opt.parse([arg, 'foo'], into: result)
+ @opt.parse(args, into: result)
assert_equal({zrs: 'foo'}, result)
end
@@ -96,6 +106,55 @@ class TestOptionParser < Test::Unit::TestCase
assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-zrs foo))}
assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-zr foo))}
assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-z foo))}
+
+ @opt.def_option('-f', '--[no-]foo', 'foo') {|arg| @foo = arg}
+ @opt.parse(%w[-f])
+ assert_equal(true, @foo)
+ @opt.parse(%w[--foo])
+ assert_equal(true, @foo)
+ @opt.parse(%w[--no-foo])
+ assert_equal(false, @foo)
+ end
+
+ def test_exact_option
+ @opt.def_option('-F', '--zrs=IRS', 'zrs')
+ %w(--zrs --zr --z -zfoo -z -F -Ffoo).each do |arg|
+ result = {}
+ @opt.parse([arg, 'foo'], into: result)
+ assert_equal({zrs: 'foo'}, result)
+ end
+
+ [%w(--zrs foo), %w(--zrs=foo), %w(-F foo), %w(-Ffoo)].each do |args|
+ result = {}
+ @opt.parse(args, into: result, exact: true)
+ assert_equal({zrs: 'foo'}, result)
+ end
+
+ assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(--zr foo), exact: true)}
+ assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(--z foo), exact: true)}
+ assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-zrs foo), exact: true)}
+ assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-zr foo), exact: true)}
+ assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-z foo), exact: true)}
+
+ @opt.def_option('-f', '--[no-]foo', 'foo') {|arg| @foo = arg}
+ @opt.parse(%w[-f], exact: true)
+ assert_equal(true, @foo)
+ @opt.parse(%w[--foo], exact: true)
+ assert_equal(true, @foo)
+ @opt.parse(%w[--no-foo], exact: true)
+ assert_equal(false, @foo)
+ end
+
+ def test_raise_unknown
+ @opt.def_option('--my-foo [ARG]') {|arg| @foo = arg}
+ assert @opt.raise_unknown
+
+ @opt.raise_unknown = false
+ assert_equal(%w[--my-bar], @opt.parse(%w[--my-foo --my-bar]))
+ assert_nil(@foo)
+
+ assert_equal(%w[--my-bar], @opt.parse(%w[--my-foo x --my-bar]))
+ assert_equal("x", @foo)
end
def test_nonopt_pattern
@@ -105,4 +164,44 @@ class TestOptionParser < Test::Unit::TestCase
e = assert_raise(OptionParser::InvalidOption) {@opt.parse(%w(-t))}
assert_equal(["-t"], e.args)
end
+
+ def test_help_pager
+ require 'tmpdir'
+ Dir.mktmpdir do |dir|
+ File.open(File.join(dir, "options.rb"), "w") do |f|
+ f.puts "#{<<~"begin;"}\n#{<<~'end;'}"
+ begin;
+ stdout = STDOUT.dup
+ def stdout.tty?; true; end
+ Object.__send__(:remove_const, :STDOUT)
+ STDOUT = stdout
+ ARGV.options do |opt|
+ end;
+ 100.times {|i| f.puts " opt.on('--opt-#{i}') {}"}
+ f.puts "#{<<~"begin;"}\n#{<<~'end;'}"
+ begin;
+ opt.parse!
+ end
+ end;
+ end
+
+ optparse = $".find {|path| path.end_with?("/optparse.rb")}
+ args = ["-r#{optparse}", "options.rb", "--help"]
+ cmd = File.join(dir, "pager.cmd")
+ if RbConfig::CONFIG["EXECUTABLE_EXTS"]&.include?(".cmd")
+ command = "@echo off"
+ else # if File.executable?("/bin/sh")
+ # TruffleRuby just calls `posix_spawnp` and no fallback to `/bin/sh`.
+ command = "#!/bin/sh\n"
+ end
+
+ [
+ [{"RUBY_PAGER"=>cmd, "PAGER"=>"echo ng"}, "Executing RUBY_PAGER"],
+ [{"RUBY_PAGER"=>nil, "PAGER"=>cmd}, "Executing PAGER"],
+ ].each do |env, expected|
+ File.write(cmd, "#{command}\n" "echo #{expected}\n", perm: 0o700)
+ assert_in_out_err([env, *args], "", [expected], chdir: dir)
+ end
+ end
+ end
end
diff --git a/test/optparse/test_placearg.rb b/test/optparse/test_placearg.rb
index ed0e4d3e6c..a8a11e676b 100644
--- a/test/optparse/test_placearg.rb
+++ b/test/optparse/test_placearg.rb
@@ -13,6 +13,8 @@ class TestOptionParserPlaceArg < TestOptionParser
@reopt = nil
@opt.def_option "--with_underscore=VAL" do |x| @flag = x end
@opt.def_option "--with-hyphen=VAL" do |x| @flag = x end
+ @opt.def_option("--fallback [VAL]") do |x = "fallback"| @flag = x end
+ @opt.def_option("--lambda [VAL]", &->(x) {@flag = x})
end
def test_short
@@ -73,4 +75,22 @@ class TestOptionParserPlaceArg < TestOptionParser
assert_equal(%w"te.rb", no_error('[ruby-dev:38333]') {@opt.parse!(%w"-T1 te.rb")})
assert_equal(1, @topt)
end
+
+ def test_default_argument
+ assert_equal(%w"", no_error {@opt.parse!(%w"--fallback=val1")})
+ assert_equal("val1", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--fallback val2")})
+ assert_equal("val2", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--fallback")})
+ assert_equal("fallback", @flag)
+ end
+
+ def test_lambda
+ assert_equal(%w"", no_error {@opt.parse!(%w"--lambda=lambda1")})
+ assert_equal("lambda1", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--lambda lambda2")})
+ assert_equal("lambda2", @flag)
+ assert_equal(%w"", no_error {@opt.parse!(%w"--lambda")})
+ assert_equal(nil, @flag)
+ end
end
diff --git a/test/optparse/test_reqarg.rb b/test/optparse/test_reqarg.rb
index d5686d13aa..31d4fef417 100644
--- a/test/optparse/test_reqarg.rb
+++ b/test/optparse/test_reqarg.rb
@@ -6,6 +6,7 @@ module TestOptionParserReqArg
super
@opt.def_option "--with_underscore=VAL" do |x| @flag = x end
@opt.def_option "--with-hyphen=VAL" do |x| @flag = x end
+ @opt.def_option("--lambda=VAL", &->(x) {@flag = x})
end
class Def1 < TestOptionParser
@@ -81,6 +82,11 @@ module TestOptionParserReqArg
assert_equal("foo4", @flag)
end
+ def test_lambda
+ assert_equal(%w"", no_error {@opt.parse!(%w"--lambda=lambda1")})
+ assert_equal("lambda1", @flag)
+ end
+
class TestOptionParser::WithPattern < TestOptionParser
def test_pattern
pat = num = nil
diff --git a/test/optparse/test_summary.rb b/test/optparse/test_summary.rb
index 6b36ce3c76..b5dcb3524e 100644
--- a/test/optparse/test_summary.rb
+++ b/test/optparse/test_summary.rb
@@ -55,4 +55,27 @@ class TestOptionParserSummaryTest < TestOptionParser
o.release = "rel"
assert_equal "foo 0.1 (rel)", o.ver
end
+
+ # https://github.com/ruby/optparse/issues/37
+ def test_very_long_without_short
+ o = OptionParser.new do |opts|
+ # This causes TypeError
+ opts.on('', '--long-long-option-param-without-short', "Error desc") { options[:long_long_option_param_without_short] = true }
+ opts.on('', '--long-option-param', "Long desc") { options[:long_option_param_without_short] = true }
+ opts.on('-a', '--long-long-option-param-with-short', "Normal description") { options[:long_long_option_param_with_short] = true }
+
+ opts.on('', '--long-long-option-param-without-short-but-with-desc', 'Description of the long long param') { options[:long_long_option_param_without_short_but_with_desc] = true }
+ end
+
+ s = o.summarize
+
+ assert_match(/^\s*--long-long-option-param-without-short$/, s[0])
+ assert_match(/^\s*Error desc$/, s[1])
+ assert_match(/^\s*--long-option-param\s+Long desc$/, s[2])
+ assert_match(/^\s*-a\s+Normal description$/, s[3])
+ assert_match(/^\s*--long-long-option-param-with-short$/, s[4])
+
+ assert_match(/^\s*--long-long-option-param-without-short-but-with-desc$/, s[5])
+ assert_match(/^\s*Description of the long long param$/, s[6])
+ end
end
diff --git a/test/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb
index 256db7a0c7..19bb606145 100644
--- a/test/ostruct/test_ostruct.rb
+++ b/test/ostruct/test_ostruct.rb
@@ -412,4 +412,23 @@ class TC_OpenStruct < Test::Unit::TestCase
assert_equal('my-class', os.class)
assert_equal(OpenStruct, os.class!)
end
+
+ has_performance_warnings = begin
+ Warning[:performance]
+ true
+ rescue NoMethodError, ArgumentError
+ false
+ end
+
+ if has_performance_warnings
+ def test_performance_warning
+ assert_in_out_err(
+ %w(-Ilib -rostruct -w -W:performance -e) + ['OpenStruct.new(a: 1)'],
+ "",
+ [],
+ ["-e:1: warning: OpenStruct use is discouraged for performance reasons"],
+ success: true,
+ )
+ end
+ end
end
diff --git a/test/prism/attribute_write_test.rb b/test/prism/attribute_write_test.rb
new file mode 100644
index 0000000000..bd83d72da3
--- /dev/null
+++ b/test/prism/attribute_write_test.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class AttributeWriteTest < TestCase
+ module Target
+ def self.value
+ 2
+ end
+
+ def self.value=(value)
+ 2
+ end
+
+ def self.[]=(index, value)
+ 2
+ end
+ end
+
+ def test_named_call_with_operator
+ assert_attribute_write("Target.value = 1")
+ end
+
+ def test_named_call_without_operator
+ assert_attribute_write("Target.value=(1)")
+ end
+
+ def test_indexed_call_with_operator
+ assert_attribute_write("Target[0] = 1")
+ end
+
+ def test_indexed_call_without_operator
+ refute_attribute_write("Target.[]=(0, 1)")
+ end
+
+ def test_comparison_operators
+ refute_attribute_write("Target.value == 1")
+ refute_attribute_write("Target.value === 1")
+ end
+
+ private
+
+ def parse(source)
+ Prism.parse(source).value.statements.body.first
+ end
+
+ def assert_attribute_write(source)
+ call = parse(source)
+ assert(call.attribute_write?)
+ assert_equal(1, eval(source))
+ end
+
+ def refute_attribute_write(source)
+ call = parse(source)
+ refute(call.attribute_write?)
+ refute_equal(1, eval(source))
+ end
+ end
+end
diff --git a/test/prism/bom_test.rb b/test/prism/bom_test.rb
new file mode 100644
index 0000000000..1525caf458
--- /dev/null
+++ b/test/prism/bom_test.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+# Don't bother checking this on these engines, this is such a specific Ripper
+# test.
+return if RUBY_ENGINE == "jruby" || RUBY_ENGINE == "truffleruby"
+
+require_relative "test_helper"
+
+module Prism
+ class BOMTest < TestCase
+ def test_ident
+ assert_bom("foo")
+ end
+
+ def test_back_reference
+ assert_bom("$+")
+ end
+
+ def test_instance_variable
+ assert_bom("@foo")
+ end
+
+ def test_class_variable
+ assert_bom("@@foo")
+ end
+
+ def test_global_variable
+ assert_bom("$foo")
+ end
+
+ def test_numbered_reference
+ assert_bom("$1")
+ end
+
+ def test_percents
+ assert_bom("%i[]")
+ assert_bom("%r[]")
+ assert_bom("%s[]")
+ assert_bom("%q{}")
+ assert_bom("%w[]")
+ assert_bom("%x[]")
+ assert_bom("%I[]")
+ assert_bom("%W[]")
+ assert_bom("%Q{}")
+ end
+
+ def test_string
+ assert_bom("\"\"")
+ assert_bom("''")
+ end
+
+ private
+
+ def assert_bom(source)
+ bommed = "\xEF\xBB\xBF#{source}"
+ assert_equal Prism.lex_ripper(bommed), Prism.lex_compat(bommed).value
+ end
+ end
+end
diff --git a/test/prism/command_line_test.rb b/test/prism/command_line_test.rb
new file mode 100644
index 0000000000..4b04c36f3a
--- /dev/null
+++ b/test/prism/command_line_test.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class CommandLineTest < TestCase
+ def test_command_line_p
+ program = Prism.parse("1", command_line: "p").value
+ statements = program.statements.body
+
+ assert_equal 2, statements.length
+ assert_kind_of CallNode, statements.last
+ assert_equal :print, statements.last.name
+ end
+
+ def test_command_line_n
+ program = Prism.parse("1", command_line: "n").value
+ statements = program.statements.body
+
+ assert_equal 1, statements.length
+ assert_kind_of WhileNode, statements.first
+
+ predicate = statements.first.predicate
+ assert_kind_of CallNode, predicate
+ assert_equal :gets, predicate.name
+
+ arguments = predicate.arguments.arguments
+ assert_equal 1, arguments.length
+ assert_equal :$/, arguments.first.name
+ end
+
+ def test_command_line_a
+ program = Prism.parse("1", command_line: "na").value
+ statements = program.statements.body
+
+ assert_equal 1, statements.length
+ assert_kind_of WhileNode, statements.first
+
+ statement = statements.first.statements.body.first
+ assert_kind_of GlobalVariableWriteNode, statement
+ assert_equal :$F, statement.name
+ end
+
+ def test_command_line_l
+ program = Prism.parse("1", command_line: "nl").value
+ statements = program.statements.body
+
+ assert_equal 1, statements.length
+ assert_kind_of WhileNode, statements.first
+
+ predicate = statements.first.predicate
+ assert_kind_of CallNode, predicate
+ assert_equal :gets, predicate.name
+
+ arguments = predicate.arguments.arguments
+ assert_equal 2, arguments.length
+ assert_equal :$/, arguments.first.name
+ assert_equal "chomp", arguments.last.elements.first.key.unescaped
+ end
+
+ def test_command_line_e
+ result = Prism.parse("1 if 2..3")
+ assert_equal 2, result.warnings.length
+
+ result = Prism.parse("1 if 2..3", command_line: "e")
+ assert_equal 0, result.warnings.length
+ end
+
+ def test_command_line_x_implicit
+ result = Prism.parse(<<~RUBY)
+ #!/bin/bash
+ exit 1
+
+ #!/usr/bin/env ruby
+ 1
+ RUBY
+
+ assert_kind_of IntegerNode, result.value.statements.body.first
+ end
+
+ def test_command_line_x_explicit
+ result = Prism.parse(<<~RUBY, command_line: "x")
+ exit 1
+
+ #!/usr/bin/env ruby
+ 1
+ RUBY
+
+ assert_kind_of IntegerNode, result.value.statements.body.first
+ end
+
+ def test_command_line_x_implicit_fail
+ result = Prism.parse(<<~RUBY)
+ #!/bin/bash
+ exit 1
+ RUBY
+
+ assert_equal 1, result.errors.length
+ assert_equal :load, result.errors.first.level
+ end
+
+ def test_command_line_x_explicit_fail
+ result = Prism.parse(<<~RUBY, command_line: "x")
+ exit 1
+ RUBY
+
+ assert_equal 1, result.errors.length
+ assert_equal :load, result.errors.first.level
+ end
+ end
+end
diff --git a/test/prism/comments_test.rb b/test/prism/comments_test.rb
new file mode 100644
index 0000000000..b99c00268c
--- /dev/null
+++ b/test/prism/comments_test.rb
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class CommentsTest < TestCase
+ def test_comment_inline
+ source = "# comment"
+ assert_equal [0], Debug.newlines(source)
+
+ assert_comment(
+ source,
+ InlineComment,
+ start_offset: 0,
+ end_offset: 9,
+ start_line: 1,
+ end_line: 1,
+ start_column: 0,
+ end_column: 9
+ )
+ end
+
+ def test_comment_inline_def
+ source = <<~RUBY
+ def foo
+ # a comment
+ end
+ RUBY
+
+ assert_comment(
+ source,
+ InlineComment,
+ start_offset: 10,
+ end_offset: 21,
+ start_line: 2,
+ end_line: 2,
+ start_column: 2,
+ end_column: 13
+ )
+ end
+
+ def test___END__
+ result = Prism.parse(<<~RUBY)
+ __END__
+ comment
+ RUBY
+
+ data_loc = result.data_loc
+ assert_equal 0, data_loc.start_offset
+ assert_equal 16, data_loc.end_offset
+ end
+
+ def test___END__crlf
+ result = Prism.parse("__END__\r\ncomment\r\n")
+
+ data_loc = result.data_loc
+ assert_equal 0, data_loc.start_offset
+ assert_equal 18, data_loc.end_offset
+ end
+
+ def test_comment_embedded_document
+ source = <<~RUBY
+ =begin
+ comment
+ =end
+ RUBY
+
+ assert_comment(
+ source,
+ EmbDocComment,
+ start_offset: 0,
+ end_offset: 20,
+ start_line: 1,
+ end_line: 4,
+ start_column: 0,
+ end_column: 0
+ )
+ end
+
+ def test_comment_embedded_document_with_content_on_same_line
+ source = <<~RUBY
+ =begin other stuff
+ =end
+ RUBY
+
+ assert_comment(
+ source,
+ EmbDocComment,
+ start_offset: 0,
+ end_offset: 24,
+ start_line: 1,
+ end_line: 3,
+ start_column: 0,
+ end_column: 0
+ )
+ end
+
+ def test_attaching_comments
+ source = <<~RUBY
+ # Foo class
+ class Foo
+ # bar method
+ def bar
+ # baz invocation
+ baz
+ end # bar end
+ end # Foo end
+ RUBY
+
+ result = Prism.parse(source)
+ result.attach_comments!
+ tree = result.value
+ class_node = tree.statements.body.first
+ method_node = class_node.body.body.first
+ call_node = method_node.body.body.first
+
+ assert_equal("# Foo class\n# Foo end", class_node.location.comments.map { |c| c.location.slice }.join("\n"))
+ assert_equal("# bar method\n# bar end", method_node.location.comments.map { |c| c.location.slice }.join("\n"))
+ assert_equal("# baz invocation", call_node.location.comments.map { |c| c.location.slice }.join("\n"))
+ end
+
+ private
+
+ def assert_comment(source, type, start_offset:, end_offset:, start_line:, end_line:, start_column:, end_column:)
+ result = Prism.parse(source)
+ assert result.errors.empty?, result.errors.map(&:message).join("\n")
+ assert_kind_of type, result.comments.first
+
+ location = result.comments.first.location
+ assert_equal start_offset, location.start_offset, -> { "Expected start_offset to be #{start_offset}" }
+ assert_equal end_offset, location.end_offset, -> { "Expected end_offset to be #{end_offset}" }
+ assert_equal start_line, location.start_line, -> { "Expected start_line to be #{start_line}" }
+ assert_equal end_line, location.end_line, -> { "Expected end_line to be #{end_line}" }
+ assert_equal start_column, location.start_column, -> { "Expected start_column to be #{start_column}" }
+ assert_equal end_column, location.end_column, -> { "Expected end_column to be #{end_column}" }
+ end
+ end
+end
diff --git a/test/prism/compiler_test.rb b/test/prism/compiler_test.rb
new file mode 100644
index 0000000000..9a326eb8d6
--- /dev/null
+++ b/test/prism/compiler_test.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+# typed: ignore
+
+require_relative "test_helper"
+
+module Prism
+ class CompilerTest < TestCase
+ class SExpressions < Prism::Compiler
+ def visit_arguments_node(node)
+ [:arguments, super]
+ end
+
+ def visit_call_node(node)
+ [:call, super]
+ end
+
+ def visit_integer_node(node)
+ [:integer]
+ end
+
+ def visit_program_node(node)
+ [:program, super]
+ end
+ end
+
+ def test_compiler
+ expected = [:program, [[[:call, [[:integer], [:arguments, [[:integer]]]]]]]]
+ assert_equal expected, Prism.parse("1 + 2").value.accept(SExpressions.new)
+ end
+ end
+end
diff --git a/test/prism/constant_path_node_test.rb b/test/prism/constant_path_node_test.rb
new file mode 100644
index 0000000000..dffb55c0ff
--- /dev/null
+++ b/test/prism/constant_path_node_test.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class ConstantPathNodeTest < TestCase
+ def test_full_name_for_constant_path
+ source = <<~RUBY
+ Foo:: # comment
+ Bar::Baz::
+ Qux
+ RUBY
+
+ constant_path = Prism.parse(source).value.statements.body.first
+ assert_equal("Foo::Bar::Baz::Qux", constant_path.full_name)
+ end
+
+ def test_full_name_for_constant_path_with_self
+ source = <<~RUBY
+ self:: # comment
+ Bar::Baz::
+ Qux
+ RUBY
+
+ constant_path = Prism.parse(source).value.statements.body.first
+ assert_raise(ConstantPathNode::DynamicPartsInConstantPathError) do
+ constant_path.full_name
+ end
+ end
+
+ def test_full_name_for_constant_path_with_variable
+ source = <<~RUBY
+ foo:: # comment
+ Bar::Baz::
+ Qux
+ RUBY
+
+ constant_path = Prism.parse(source).value.statements.body.first
+
+ assert_raise(ConstantPathNode::DynamicPartsInConstantPathError) do
+ constant_path.full_name
+ end
+ end
+
+ def test_full_name_for_constant_path_target
+ source = <<~RUBY
+ Foo:: # comment
+ Bar::Baz::
+ Qux, Something = [1, 2]
+ RUBY
+
+ node = Prism.parse(source).value.statements.body.first
+ assert_equal("Foo::Bar::Baz::Qux", node.lefts.first.full_name)
+ end
+
+ def test_full_name_for_constant_path_with_stovetop_start
+ source = <<~RUBY
+ ::Foo:: # comment
+ Bar::Baz::
+ Qux, Something = [1, 2]
+ RUBY
+
+ node = Prism.parse(source).value.statements.body.first
+ assert_equal("::Foo::Bar::Baz::Qux", node.lefts.first.full_name)
+ end
+
+ def test_full_name_for_constant_path_target_with_non_constant_parent
+ source = <<~RUBY
+ self::Foo, Bar = [1, 2]
+ RUBY
+
+ constant_target = Prism.parse(source).value.statements.body.first
+ dynamic, static = constant_target.lefts
+
+ assert_raise(ConstantPathNode::DynamicPartsInConstantPathError) do
+ dynamic.full_name
+ end
+
+ assert_equal("Bar", static.full_name)
+ end
+
+ def test_full_name_for_constant_read_node
+ source = <<~RUBY
+ Bar
+ RUBY
+
+ constant = Prism.parse(source).value.statements.body.first
+ assert_equal("Bar", constant.full_name)
+ end
+ end
+end
diff --git a/test/prism/desugar_compiler_test.rb b/test/prism/desugar_compiler_test.rb
new file mode 100644
index 0000000000..1a1d580d2d
--- /dev/null
+++ b/test/prism/desugar_compiler_test.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class DesugarCompilerTest < TestCase
+ def test_and_write
+ assert_desugars("(AndNode (ClassVariableReadNode) (ClassVariableWriteNode (CallNode)))", "@@foo &&= bar")
+ assert_not_desugared("Foo::Bar &&= baz", "Desugaring would execute Foo twice or need temporary variables")
+ assert_desugars("(AndNode (ConstantReadNode) (ConstantWriteNode (CallNode)))", "Foo &&= bar")
+ assert_desugars("(AndNode (GlobalVariableReadNode) (GlobalVariableWriteNode (CallNode)))", "$foo &&= bar")
+ assert_desugars("(AndNode (InstanceVariableReadNode) (InstanceVariableWriteNode (CallNode)))", "@foo &&= bar")
+ assert_desugars("(AndNode (LocalVariableReadNode) (LocalVariableWriteNode (CallNode)))", "foo &&= bar")
+ assert_desugars("(AndNode (LocalVariableReadNode) (LocalVariableWriteNode (CallNode)))", "foo = 1; foo &&= bar")
+ end
+
+ def test_or_write
+ assert_desugars("(IfNode (DefinedNode (ClassVariableReadNode)) (StatementsNode (ClassVariableReadNode)) (ElseNode (StatementsNode (ClassVariableWriteNode (CallNode)))))", "@@foo ||= bar")
+ assert_not_desugared("Foo::Bar ||= baz", "Desugaring would execute Foo twice or need temporary variables")
+ assert_desugars("(IfNode (DefinedNode (ConstantReadNode)) (StatementsNode (ConstantReadNode)) (ElseNode (StatementsNode (ConstantWriteNode (CallNode)))))", "Foo ||= bar")
+ assert_desugars("(IfNode (DefinedNode (GlobalVariableReadNode)) (StatementsNode (GlobalVariableReadNode)) (ElseNode (StatementsNode (GlobalVariableWriteNode (CallNode)))))", "$foo ||= bar")
+ assert_desugars("(OrNode (InstanceVariableReadNode) (InstanceVariableWriteNode (CallNode)))", "@foo ||= bar")
+ assert_desugars("(OrNode (LocalVariableReadNode) (LocalVariableWriteNode (CallNode)))", "foo ||= bar")
+ assert_desugars("(OrNode (LocalVariableReadNode) (LocalVariableWriteNode (CallNode)))", "foo = 1; foo ||= bar")
+ end
+
+ def test_operator_write
+ assert_desugars("(ClassVariableWriteNode (CallNode (ClassVariableReadNode) (ArgumentsNode (CallNode))))", "@@foo += bar")
+ assert_not_desugared("Foo::Bar += baz", "Desugaring would execute Foo twice or need temporary variables")
+ assert_desugars("(ConstantWriteNode (CallNode (ConstantReadNode) (ArgumentsNode (CallNode))))", "Foo += bar")
+ assert_desugars("(GlobalVariableWriteNode (CallNode (GlobalVariableReadNode) (ArgumentsNode (CallNode))))", "$foo += bar")
+ assert_desugars("(InstanceVariableWriteNode (CallNode (InstanceVariableReadNode) (ArgumentsNode (CallNode))))", "@foo += bar")
+ assert_desugars("(LocalVariableWriteNode (CallNode (LocalVariableReadNode) (ArgumentsNode (CallNode))))", "foo += bar")
+ assert_desugars("(LocalVariableWriteNode (CallNode (LocalVariableReadNode) (ArgumentsNode (CallNode))))", "foo = 1; foo += bar")
+ end
+
+ private
+
+ def ast_inspect(node)
+ parts = [node.class.name.split("::").last]
+
+ node.deconstruct_keys(nil).each do |_, value|
+ case value
+ when Node
+ parts << ast_inspect(value)
+ when Array
+ parts.concat(value.map { |element| ast_inspect(element) })
+ end
+ end
+
+ "(#{parts.join(" ")})"
+ end
+
+ # Ensure every node is only present once in the AST.
+ # If the same node is present twice it would most likely indicate it is executed twice, which is invalid semantically.
+ # This also acts as a sanity check that Node#child_nodes returns only nodes or nil (which caught a couple bugs).
+ def ensure_every_node_once_in_ast(node, all_nodes = {}.compare_by_identity)
+ if all_nodes.include?(node)
+ raise "#{node.inspect} is present multiple times in the desugared AST and likely executed multiple times"
+ else
+ all_nodes[node] = true
+ end
+ node.child_nodes.each do |child|
+ ensure_every_node_once_in_ast(child, all_nodes) unless child.nil?
+ end
+ end
+
+ def assert_desugars(expected, source)
+ ast = Prism.parse(source).value.accept(DesugarCompiler.new)
+ assert_equal expected, ast_inspect(ast.statements.body.last)
+
+ ensure_every_node_once_in_ast(ast)
+ end
+
+ def assert_not_desugared(source, reason)
+ ast = Prism.parse(source).value
+ assert_equal_nodes(ast, ast.accept(DesugarCompiler.new))
+ end
+ end
+end
diff --git a/test/prism/dispatcher_test.rb b/test/prism/dispatcher_test.rb
new file mode 100644
index 0000000000..0d8a6d35e9
--- /dev/null
+++ b/test/prism/dispatcher_test.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class DispatcherTest < TestCase
+ class TestListener
+ attr_reader :events_received
+
+ def initialize
+ @events_received = []
+ end
+
+ def on_call_node_enter(node)
+ events_received << :on_call_node_enter
+ end
+
+ def on_call_node_leave(node)
+ events_received << :on_call_node_leave
+ end
+
+ def on_integer_node_enter(node)
+ events_received << :on_integer_node_enter
+ end
+ end
+
+ def test_dispatching_events
+ listener = TestListener.new
+ dispatcher = Dispatcher.new
+ dispatcher.register(listener, :on_call_node_enter, :on_call_node_leave, :on_integer_node_enter)
+
+ root = Prism.parse(<<~RUBY).value
+ def foo
+ something(1, 2, 3)
+ end
+ RUBY
+
+ dispatcher.dispatch(root)
+ assert_equal([:on_call_node_enter, :on_integer_node_enter, :on_integer_node_enter, :on_integer_node_enter, :on_call_node_leave], listener.events_received)
+
+ listener.events_received.clear
+ dispatcher.dispatch_once(root.statements.body.first.body.body.first)
+ assert_equal([:on_call_node_enter, :on_call_node_leave], listener.events_received)
+ end
+ end
+end
diff --git a/test/prism/encoding_test.rb b/test/prism/encoding_test.rb
new file mode 100644
index 0000000000..2aee473ddf
--- /dev/null
+++ b/test/prism/encoding_test.rb
@@ -0,0 +1,577 @@
+# frozen_string_literal: true
+
+return if RUBY_ENGINE != "ruby"
+
+require_relative "test_helper"
+
+module Prism
+ class EncodingTest < TestCase
+ codepoints_1byte = 0...0x100
+ encodings = {
+ Encoding::ASCII_8BIT => codepoints_1byte,
+ Encoding::US_ASCII => codepoints_1byte
+ }
+
+ if !ENV["PRISM_BUILD_MINIMAL"]
+ encodings[Encoding::Windows_1253] = codepoints_1byte
+ end
+
+ # By default we don't test every codepoint in these encodings because it
+ # takes a very long time.
+ if ENV["PRISM_TEST_ALL_ENCODINGS"]
+ codepoints_2bytes = 0...0x10000
+ codepoints_unicode = (0...0x110000)
+
+ codepoints_eucjp = [
+ *(0...0x10000),
+ *(0...0x10000).map { |bytes| bytes | 0x8F0000 }
+ ]
+
+ codepoints_emacs_mule = [
+ *(0...0x80),
+ *((0x81...0x90).flat_map { |byte1| (0x90...0x100).map { |byte2| byte1 << 8 | byte2 } }),
+ *((0x90...0x9C).flat_map { |byte1| (0xA0...0x100).flat_map { |byte2| (0xA0...0x100).flat_map { |byte3| byte1 << 16 | byte2 << 8 | byte3 } } }),
+ *((0xF0...0xF5).flat_map { |byte2| (0xA0...0x100).flat_map { |byte3| (0xA0...0x100).flat_map { |byte4| 0x9C << 24 | byte3 << 16 | byte3 << 8 | byte4 } } }),
+ ]
+
+ codepoints_gb18030 = [
+ *(0...0x80),
+ *((0x81..0xFE).flat_map { |byte1| (0x40...0x100).map { |byte2| byte1 << 8 | byte2 } }),
+ *((0x81..0xFE).flat_map { |byte1| (0x30...0x40).flat_map { |byte2| (0x81..0xFE).flat_map { |byte3| (0x2F...0x41).map { |byte4| byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4 } } } }),
+ ]
+
+ codepoints_euc_tw = [
+ *(0..0x7F),
+ *(0xA1..0xFF).flat_map { |byte1| (0xA1..0xFF).map { |byte2| (byte1 << 8) | byte2 } },
+ *(0xA1..0xB0).flat_map { |byte2| (0xA1..0xFF).flat_map { |byte3| (0xA1..0xFF).flat_map { |byte4| 0x8E << 24 | byte2 << 16 | byte3 << 8 | byte4 } } }
+ ]
+
+ encodings.merge!(
+ Encoding::CP850 => codepoints_1byte,
+ Encoding::CP852 => codepoints_1byte,
+ Encoding::CP855 => codepoints_1byte,
+ Encoding::GB1988 => codepoints_1byte,
+ Encoding::IBM437 => codepoints_1byte,
+ Encoding::IBM720 => codepoints_1byte,
+ Encoding::IBM737 => codepoints_1byte,
+ Encoding::IBM775 => codepoints_1byte,
+ Encoding::IBM852 => codepoints_1byte,
+ Encoding::IBM855 => codepoints_1byte,
+ Encoding::IBM857 => codepoints_1byte,
+ Encoding::IBM860 => codepoints_1byte,
+ Encoding::IBM861 => codepoints_1byte,
+ Encoding::IBM862 => codepoints_1byte,
+ Encoding::IBM863 => codepoints_1byte,
+ Encoding::IBM864 => codepoints_1byte,
+ Encoding::IBM865 => codepoints_1byte,
+ Encoding::IBM866 => codepoints_1byte,
+ Encoding::IBM869 => codepoints_1byte,
+ Encoding::ISO_8859_1 => codepoints_1byte,
+ Encoding::ISO_8859_2 => codepoints_1byte,
+ Encoding::ISO_8859_3 => codepoints_1byte,
+ Encoding::ISO_8859_4 => codepoints_1byte,
+ Encoding::ISO_8859_5 => codepoints_1byte,
+ Encoding::ISO_8859_6 => codepoints_1byte,
+ Encoding::ISO_8859_7 => codepoints_1byte,
+ Encoding::ISO_8859_8 => codepoints_1byte,
+ Encoding::ISO_8859_9 => codepoints_1byte,
+ Encoding::ISO_8859_10 => codepoints_1byte,
+ Encoding::ISO_8859_11 => codepoints_1byte,
+ Encoding::ISO_8859_13 => codepoints_1byte,
+ Encoding::ISO_8859_14 => codepoints_1byte,
+ Encoding::ISO_8859_15 => codepoints_1byte,
+ Encoding::ISO_8859_16 => codepoints_1byte,
+ Encoding::KOI8_R => codepoints_1byte,
+ Encoding::KOI8_U => codepoints_1byte,
+ Encoding::MACCENTEURO => codepoints_1byte,
+ Encoding::MACCROATIAN => codepoints_1byte,
+ Encoding::MACCYRILLIC => codepoints_1byte,
+ Encoding::MACGREEK => codepoints_1byte,
+ Encoding::MACICELAND => codepoints_1byte,
+ Encoding::MACROMAN => codepoints_1byte,
+ Encoding::MACROMANIA => codepoints_1byte,
+ Encoding::MACTHAI => codepoints_1byte,
+ Encoding::MACTURKISH => codepoints_1byte,
+ Encoding::MACUKRAINE => codepoints_1byte,
+ Encoding::TIS_620 => codepoints_1byte,
+ Encoding::Windows_1250 => codepoints_1byte,
+ Encoding::Windows_1251 => codepoints_1byte,
+ Encoding::Windows_1252 => codepoints_1byte,
+ Encoding::Windows_1254 => codepoints_1byte,
+ Encoding::Windows_1255 => codepoints_1byte,
+ Encoding::Windows_1256 => codepoints_1byte,
+ Encoding::Windows_1257 => codepoints_1byte,
+ Encoding::Windows_1258 => codepoints_1byte,
+ Encoding::Windows_874 => codepoints_1byte,
+ Encoding::Big5 => codepoints_2bytes,
+ Encoding::Big5_HKSCS => codepoints_2bytes,
+ Encoding::Big5_UAO => codepoints_2bytes,
+ Encoding::CP949 => codepoints_2bytes,
+ Encoding::CP950 => codepoints_2bytes,
+ Encoding::CP951 => codepoints_2bytes,
+ Encoding::EUC_KR => codepoints_2bytes,
+ Encoding::GBK => codepoints_2bytes,
+ Encoding::GB12345 => codepoints_2bytes,
+ Encoding::GB2312 => codepoints_2bytes,
+ Encoding::MACJAPANESE => codepoints_2bytes,
+ Encoding::Shift_JIS => codepoints_2bytes,
+ Encoding::SJIS_DoCoMo => codepoints_2bytes,
+ Encoding::SJIS_KDDI => codepoints_2bytes,
+ Encoding::SJIS_SoftBank => codepoints_2bytes,
+ Encoding::Windows_31J => codepoints_2bytes,
+ Encoding::UTF_8 => codepoints_unicode,
+ Encoding::UTF8_MAC => codepoints_unicode,
+ Encoding::UTF8_DoCoMo => codepoints_unicode,
+ Encoding::UTF8_KDDI => codepoints_unicode,
+ Encoding::UTF8_SoftBank => codepoints_unicode,
+ Encoding::CESU_8 => codepoints_unicode,
+ Encoding::CP51932 => codepoints_eucjp,
+ Encoding::EUC_JP => codepoints_eucjp,
+ Encoding::EUCJP_MS => codepoints_eucjp,
+ Encoding::EUC_JIS_2004 => codepoints_eucjp,
+ Encoding::EMACS_MULE => codepoints_emacs_mule,
+ Encoding::STATELESS_ISO_2022_JP => codepoints_emacs_mule,
+ Encoding::STATELESS_ISO_2022_JP_KDDI => codepoints_emacs_mule,
+ Encoding::GB18030 => codepoints_gb18030,
+ Encoding::EUC_TW => codepoints_euc_tw
+ )
+ end
+
+ # These test that we're correctly parsing codepoints for each alias of each
+ # encoding that prism supports.
+ encodings.each do |encoding, range|
+ (encoding.names - %w[external internal filesystem locale]).each do |name|
+ define_method(:"test_encoding_#{name}") do
+ assert_encoding(encoding, name, range)
+ end
+ end
+ end
+
+ # These test that we're correctly setting the flags on strings for each
+ # encoding that prism supports.
+ escapes = ["\\x00", "\\x7F", "\\x80", "\\xFF", "\\u{00}", "\\u{7F}", "\\u{80}", "\\M-\\C-?"]
+ escapes = escapes.concat(escapes.product(escapes).map(&:join))
+ symbols = [:a, :ą, :+]
+ regexps = [/a/, /ą/, //]
+
+ encodings.each_key do |encoding|
+ define_method(:"test_encoding_flags_#{encoding.name}") do
+ assert_encoding_flags(encoding, escapes)
+ end
+
+ define_method(:"test_symbol_encoding_flags_#{encoding.name}") do
+ assert_symbol_encoding_flags(encoding, symbols)
+ end
+
+ define_method(:"test_symbol_character_escape_encoding_flags_#{encoding.name}") do
+ assert_symbol_character_escape_encoding_flags(encoding, escapes)
+ end
+
+ define_method(:"test_regular_expression_encoding_flags_#{encoding.name}") do
+ assert_regular_expression_encoding_flags(encoding, regexps.map(&:inspect))
+ end
+
+ define_method(:"test_regular_expression_escape_encoding_flags_#{encoding.name}") do
+ assert_regular_expression_encoding_flags(encoding, escapes.map { |e| "/#{e}/" })
+ end
+ end
+
+ encoding_modifiers = { ascii_8bit: "n", utf_8: "u", euc_jp: "e", windows_31j: "s" }
+ regexp_sources = ["abc", "garçon", "\\x80", "gar\\xC3\\xA7on", "gar\\u{E7}on", "abc\\u{FFFFFF}", "\\x80\\u{80}" ]
+
+ encoding_modifiers.each_value do |modifier|
+ encodings.each_key do |encoding|
+ define_method(:"test_regular_expression_encoding_modifiers_/#{modifier}_#{encoding.name}") do
+ assert_regular_expression_encoding_flags(
+ encoding,
+ regexp_sources.product(encoding_modifiers.values).map { |r, modifier| "/#{r}/#{modifier}" }
+ )
+ end
+ end
+ end
+
+ def test_coding
+ result = Prism.parse("# coding: utf-8\n'string'")
+ actual = result.value.statements.body.first.unescaped.encoding
+ assert_equal Encoding.find("utf-8"), actual
+ end
+
+ def test_coding_with_whitespace
+ result = Prism.parse("# coding \t \r \v : \t \v \r ascii-8bit \n'string'")
+ actual = result.value.statements.body.first.unescaped.encoding
+ assert_equal Encoding.find("ascii-8bit"), actual
+ end
+
+ def test_emacs_style
+ result = Prism.parse("# -*- coding: utf-8 -*-\n'string'")
+ actual = result.value.statements.body.first.unescaped.encoding
+ assert_equal Encoding.find("utf-8"), actual
+ end
+
+ def test_utf_8_variations
+ %w[
+ utf-8-unix
+ utf-8-dos
+ utf-8-mac
+ utf-8-*
+ ].each do |encoding|
+ result = Prism.parse("# coding: #{encoding}\n'string'")
+ actual = result.value.statements.body.first.unescaped.encoding
+ assert_equal Encoding.find("utf-8"), actual
+ end
+ end
+
+ def test_first_lexed_token
+ encoding = Prism.lex("# encoding: ascii-8bit").value[0][0].value.encoding
+ assert_equal Encoding.find("ascii-8bit"), encoding
+ end
+
+ if !ENV["PRISM_BUILD_MINIMAL"]
+ # This test may be a little confusing. Basically when we use our strpbrk,
+ # it takes into account the encoding of the file.
+ def test_strpbrk_multibyte
+ result = Prism.parse(<<~RUBY)
+ # encoding: Shift_JIS
+ %w[\x81\x5c]
+ RUBY
+
+ assert(result.errors.empty?)
+ assert_equal(
+ (+"\x81\x5c").force_encoding(Encoding::Shift_JIS),
+ result.value.statements.body.first.elements.first.unescaped
+ )
+ end
+
+ def test_slice_encoding
+ slice = Prism.parse("# encoding: Shift_JIS\nア").value.slice
+ assert_equal (+"ア").force_encoding(Encoding::SHIFT_JIS), slice
+ assert_equal Encoding::SHIFT_JIS, slice.encoding
+ end
+
+ def test_multibyte_escapes
+ [
+ ["'", "'"],
+ ["\"", "\""],
+ ["`", "`"],
+ ["/", "/"],
+ ["<<'HERE'\n", "\nHERE"],
+ ["<<-HERE\n", "\nHERE"]
+ ].each do |opening, closing|
+ assert Prism.parse_success?("# encoding: shift_jis\n'\\\x82\xA0'\n")
+ end
+ end
+ end
+
+ private
+
+ class ConstantContext < BasicObject
+ def self.const_missing(const)
+ const
+ end
+ end
+
+ def constant_context
+ ConstantContext.new
+ end
+
+ class IdentifierContext < BasicObject
+ def method_missing(name, *)
+ name
+ end
+ end
+
+ def identifier_context
+ IdentifierContext.new
+ end
+
+ def assert_encoding_constant(name, character)
+ source = "# encoding: #{name}\n#{character}"
+ expected = constant_context.instance_eval(source)
+
+ result = Prism.parse(source)
+ assert result.success?
+
+ actual = result.value.statements.body.last
+ assert_kind_of ConstantReadNode, actual
+ assert_equal expected, actual.name
+ end
+
+ def assert_encoding_identifier(name, character)
+ source = "# encoding: #{name}\n#{character}"
+ expected = identifier_context.instance_eval(source)
+
+ result = Prism.parse(source)
+ assert result.success?
+
+ actual = result.value.statements.body.last
+ assert_kind_of CallNode, actual
+ assert_equal expected, actual.name
+ end
+
+ # Check that we can properly parse every codepoint in the given encoding.
+ def assert_encoding(encoding, name, range)
+ # I'm not entirely sure, but I believe these codepoints are incorrect in
+ # their parsing in CRuby. They all report as matching `[[:lower:]]` but
+ # then they are parsed as constants. This is because CRuby determines if
+ # an identifier is a constant or not by case folding it down to lowercase
+ # and checking if there is a difference. And even though they report
+ # themselves as lowercase, their case fold is different. I have reported
+ # this bug upstream.
+ case encoding
+ when Encoding::UTF_8, Encoding::UTF_8_MAC, Encoding::UTF8_DoCoMo, Encoding::UTF8_KDDI, Encoding::UTF8_SoftBank, Encoding::CESU_8
+ range = range.to_a - [
+ 0x01c5, 0x01c8, 0x01cb, 0x01f2, 0x1f88, 0x1f89, 0x1f8a, 0x1f8b,
+ 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b,
+ 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa8, 0x1fa9, 0x1faa, 0x1fab,
+ 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fbc, 0x1fcc, 0x1ffc,
+ ]
+ when Encoding::Windows_1253
+ range = range.to_a - [0xb5]
+ end
+
+ range.each do |codepoint|
+ character = codepoint.chr(encoding)
+
+ if character.match?(/[[:alpha:]]/)
+ if character.match?(/[[:upper:]]/)
+ assert_encoding_constant(name, character)
+ else
+ assert_encoding_identifier(name, character)
+ end
+ elsif character.match?(/[[:alnum:]]/)
+ assert_encoding_identifier(name, "_#{character}")
+ else
+ next if ["/", "{"].include?(character)
+
+ source = "# encoding: #{name}\n/(?##{character})/\n"
+ assert Prism.parse(source).success?, "Expected #{source.inspect} to parse successfully."
+ end
+ rescue RangeError
+ source = "# encoding: #{name}\n\\x#{codepoint.to_s(16)}"
+ refute Prism.parse(source).success?
+ end
+ end
+
+ def assert_encoding_flags(encoding, escapes)
+ escapes.each do |escaped|
+ source = "# encoding: #{encoding.name}\n\"#{escaped}\""
+
+ expected =
+ begin
+ eval(source).encoding
+ rescue SyntaxError => error
+ if error.message.include?("UTF-8 mixed within")
+ error.message[/: (.+?)\n/, 1]
+ else
+ raise
+ end
+ end
+
+ actual =
+ Prism.parse(source).then do |result|
+ if result.success?
+ string = result.value.statements.body.first
+
+ if string.forced_utf8_encoding?
+ Encoding::UTF_8
+ elsif string.forced_binary_encoding?
+ Encoding::ASCII_8BIT
+ else
+ encoding
+ end
+ else
+ error = result.errors.first
+
+ if error.message.include?("mixed")
+ error.message
+ else
+ raise error.message
+ end
+ end
+ end
+
+ assert_equal expected, actual
+ end
+ end
+
+ # Test Symbol literals without any interpolation or escape sequences.
+ def assert_symbol_encoding_flags(encoding, symbols)
+ symbols.each do |symbol|
+ source = "# encoding: #{encoding.name}\n#{symbol.inspect}"
+
+ expected =
+ begin
+ eval(source).encoding
+ rescue SyntaxError => error
+ unless error.message.include?("invalid multibyte char")
+ raise
+ end
+ end
+
+ actual =
+ Prism.parse(source).then do |result|
+ if result.success?
+ symbol = result.value.statements.body.first
+
+ if symbol.forced_utf8_encoding?
+ Encoding::UTF_8
+ elsif symbol.forced_binary_encoding?
+ Encoding::ASCII_8BIT
+ elsif symbol.forced_us_ascii_encoding?
+ Encoding::US_ASCII
+ else
+ encoding
+ end
+ else
+ error = result.errors.last
+
+ unless error.message.include?("invalid symbol")
+ raise error.message
+ end
+ end
+ end
+
+ assert_equal expected, actual
+ end
+ end
+
+ def assert_symbol_character_escape_encoding_flags(encoding, escapes)
+ escapes.each do |escaped|
+ source = "# encoding: #{encoding.name}\n:\"#{escaped}\""
+
+ expected =
+ begin
+ eval(source).encoding
+ rescue SyntaxError => error
+ if error.message.include?("UTF-8 mixed within")
+ error.message[/: (.+?)\n/, 1]
+ else
+ raise
+ end
+ end
+
+ actual =
+ Prism.parse(source).then do |result|
+ if result.success?
+ symbol = result.value.statements.body.first
+
+ if symbol.forced_utf8_encoding?
+ Encoding::UTF_8
+ elsif symbol.forced_binary_encoding?
+ Encoding::ASCII_8BIT
+ elsif symbol.forced_us_ascii_encoding?
+ Encoding::US_ASCII
+ else
+ encoding
+ end
+ else
+ error = result.errors.first
+
+ if error.message.include?("mixed")
+ error.message
+ else
+ raise error.message
+ end
+ end
+ end
+
+ assert_equal expected, actual
+ end
+ end
+
+ def assert_regular_expression_encoding_flags(encoding, regexps)
+ regexps.each do |regexp|
+ regexp_modifier_used = regexp.end_with?("/u") || regexp.end_with?("/e") || regexp.end_with?("/s") || regexp.end_with?("/n")
+ source = "# encoding: #{encoding.name}\n#{regexp}"
+
+ encoding_errors = ["invalid multibyte char", "escaped non ASCII character in UTF-8 regexp", "differs from source encoding"]
+ skipped_errors = ["invalid multibyte escape", "incompatible character encoding", "UTF-8 character in non UTF-8 regexp", "invalid Unicode range", "invalid Unicode list"]
+
+ # TODO (nirvdrum 21-Feb-2024): Prism currently does not handle Regexp validation unless modifiers are used. So, skip processing those errors for now: https://github.com/ruby/prism/issues/2104
+ unless regexp_modifier_used
+ skipped_errors += encoding_errors
+ encoding_errors.clear
+ end
+
+ expected =
+ begin
+ eval(source).encoding
+ rescue SyntaxError => error
+ if encoding_errors.find { |e| error.message.include?(e) }
+ error.message.split("\n").map { |m| m[/: (.+?)$/, 1] }
+ elsif skipped_errors.find { |e| error.message.include?(e) }
+ next
+ else
+ raise
+ end
+ end
+
+ actual =
+ Prism.parse(source).then do |result|
+ if result.success?
+ regexp = result.value.statements.body.first
+
+ actual_encoding = if regexp.forced_utf8_encoding?
+ Encoding::UTF_8
+ elsif regexp.forced_binary_encoding?
+ Encoding::ASCII_8BIT
+ elsif regexp.forced_us_ascii_encoding?
+ Encoding::US_ASCII
+ elsif regexp.ascii_8bit?
+ Encoding::ASCII_8BIT
+ elsif regexp.utf_8?
+ Encoding::UTF_8
+ elsif regexp.euc_jp?
+ Encoding::EUC_JP
+ elsif regexp.windows_31j?
+ Encoding::Windows_31J
+ else
+ encoding
+ end
+
+ if regexp.utf_8? && actual_encoding != Encoding::UTF_8
+ raise "expected regexp encoding to be UTF-8 due to '/u' modifier, but got #{actual_encoding.name}"
+ elsif regexp.ascii_8bit? && (actual_encoding != Encoding::ASCII_8BIT && actual_encoding != Encoding::US_ASCII)
+ raise "expected regexp encoding to be ASCII-8BIT or US-ASCII due to '/n' modifier, but got #{actual_encoding.name}"
+ elsif regexp.euc_jp? && actual_encoding != Encoding::EUC_JP
+ raise "expected regexp encoding to be EUC-JP due to '/e' modifier, but got #{actual_encoding.name}"
+ elsif regexp.windows_31j? && actual_encoding != Encoding::Windows_31J
+ raise "expected regexp encoding to be Windows-31J due to '/s' modifier, but got #{actual_encoding.name}"
+ end
+
+ if regexp.utf_8? && regexp.forced_utf8_encoding?
+ raise "the forced_utf8 flag should not be set when the UTF-8 modifier (/u) is used"
+ elsif regexp.ascii_8bit? && regexp.forced_binary_encoding?
+ raise "the forced_ascii_8bit flag should not be set when the UTF-8 modifier (/u) is used"
+ end
+
+ actual_encoding
+ else
+ errors = result.errors.map(&:message)
+
+ if errors.last&.include?("UTF-8 mixed within")
+ nil
+ else
+ errors
+ end
+ end
+ end
+
+ # TODO (nirvdrum 22-Feb-2024): Remove this workaround once Prism better maps CRuby's error messages.
+ # This class of error message is tricky. The part not being compared is a representation of the regexp.
+ # Depending on the source encoding and any encoding modifiers being used, CRuby alters how the regexp is represented.
+ # Sometimes it's an MBC string. Other times it uses hexadecimal character escapes. And in other cases it uses
+ # the long-form Unicode escape sequences. This short-circuit checks that the error message is mostly correct.
+ if expected.is_a?(Array) && actual.is_a?(Array)
+ if expected.last.start_with?("/.../n has a non escaped non ASCII character in non ASCII-8BIT script:") &&
+ actual.last.start_with?("/.../n has a non escaped non ASCII character in non ASCII-8BIT script:")
+ expected.last.clear
+ actual.last.clear
+ end
+ end
+
+ assert_equal expected, actual
+ end
+ end
+ end
+end
diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb
new file mode 100644
index 0000000000..679f6ed0a2
--- /dev/null
+++ b/test/prism/errors_test.rb
@@ -0,0 +1,2241 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class ErrorsTest < TestCase
+ include DSL
+
+ def test_constant_path_with_invalid_token_after
+ assert_error_messages "A::$b", [
+ "expected a constant after the `::` operator",
+ "unexpected global variable, expecting end-of-input"
+ ]
+ end
+
+ def test_module_name_recoverable
+ expected = ModuleNode(
+ [],
+ Location(),
+ ConstantReadNode(:Parent),
+ StatementsNode(
+ [ModuleNode([], Location(), MissingNode(), nil, Location(), :"")]
+ ),
+ Location(),
+ :Parent
+ )
+
+ assert_errors expected, "module Parent module end", [
+ ["unexpected constant path after `module`; class/module name must be CONSTANT", 14..20],
+ ["unexpected 'end', assuming it is closing the parent module definition", 21..24]
+ ]
+ end
+
+ def test_for_loops_index_missing
+ expected = ForNode(
+ MissingNode(),
+ expression("1..10"),
+ StatementsNode([expression("i")]),
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "for in 1..10\ni\nend", [
+ ["expected an index after `for`", 0..3]
+ ]
+ end
+
+ def test_for_loops_only_end
+ expected = ForNode(
+ MissingNode(),
+ MissingNode(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "for end", [
+ ["expected an index after `for`", 0..3],
+ ["expected an `in` after the index in a `for` statement", 3..3],
+ ["expected a collection after the `in` in a `for` statement", 3..3]
+ ]
+ end
+
+ def test_pre_execution_missing_brace
+ expected = PreExecutionNode(
+ StatementsNode([expression("1")]),
+ Location(),
+ Location(),
+ Location()
+ )
+
+ assert_errors expected, "BEGIN 1 }", [
+ ["expected a `{` after `BEGIN`", 5..5]
+ ]
+ end
+
+ def test_pre_execution_context
+ expected = PreExecutionNode(
+ StatementsNode([
+ CallNode(
+ 0,
+ expression("1"),
+ nil,
+ :+,
+ Location(),
+ nil,
+ ArgumentsNode(0, [MissingNode()]),
+ nil,
+ nil
+ )
+ ]),
+ Location(),
+ Location(),
+ Location()
+ )
+
+ assert_errors expected, "BEGIN { 1 + }", [
+ ["expected an expression after the operator", 10..11],
+ ["unexpected '}', assuming it is closing the parent 'BEGIN' block", 12..13]
+ ]
+ end
+
+ def test_unterminated_embdoc
+ message = "embedded document meets end of file"
+ assert_error_messages "=begin", [message]
+ assert_error_messages "=begin\n", [message]
+
+ refute_error_messages "=begin\n=end"
+ refute_error_messages "=begin\n=end\0"
+ refute_error_messages "=begin\n=end\C-d"
+ refute_error_messages "=begin\n=end\C-z"
+ end
+
+ def test_unterminated_i_list
+ assert_errors expression("%i["), "%i[", [
+ ["expected a closing delimiter for the `%i` list", 0..3]
+ ]
+ end
+
+ def test_unterminated_w_list
+ assert_errors expression("%w["), "%w[", [
+ ["expected a closing delimiter for the `%w` list", 0..3]
+ ]
+ end
+
+ def test_unterminated_W_list
+ assert_errors expression("%W["), "%W[", [
+ ["expected a closing delimiter for the `%W` list", 0..3]
+ ]
+ end
+
+ def test_unterminated_regular_expression
+ assert_errors expression("/hello"), "/hello", [
+ ["expected a closing delimiter for the regular expression", 0..1]
+ ]
+ end
+
+ def test_unterminated_regular_expression_with_heredoc
+ source = "<<-END + /b\nEND\n"
+
+ assert_errors expression(source), source, [
+ ["expected a closing delimiter for the regular expression", 9..10]
+ ]
+ end
+
+ def test_unterminated_xstring
+ assert_errors expression("`hello"), "`hello", [
+ ["expected a closing delimiter for the `%x` or backtick string", 0..1]
+ ]
+ end
+
+ def test_unterminated_interpolated_string
+ expr = expression('"hello')
+ assert_errors expr, '"hello', [
+ ["unterminated string meets end of file", 6..6]
+ ]
+ assert_equal expr.unescaped, "hello"
+ assert_equal expr.closing, ""
+ end
+
+ def test_unterminated_string
+ expr = expression("'hello")
+ assert_errors expr, "'hello", [
+ ["unterminated string meets end of file", 0..1]
+ ]
+ assert_equal expr.unescaped, "hello"
+ assert_equal expr.closing, ""
+ end
+
+ def test_unterminated_empty_string
+ expr = expression('"')
+ assert_errors expr, '"', [
+ ["unterminated string meets end of file", 1..1]
+ ]
+ assert_equal expr.unescaped, ""
+ assert_equal expr.closing, ""
+ end
+
+ def test_incomplete_instance_var_string
+ assert_errors expression('%@#@@#'), '%@#@@#', [
+ ["'@' without identifiers is not allowed as an instance variable name", 4..5],
+ ["unexpected instance variable, expecting end-of-input", 4..5]
+ ]
+ end
+
+ def test_unterminated_s_symbol
+ assert_errors expression("%s[abc"), "%s[abc", [
+ ["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],
+ ["expected a matching `)`", 6..6]
+ ]
+ end
+
+ def test_missing_terminator_in_parentheses
+ assert_error_messages "(0 0)", [
+ "unexpected integer, expecting end-of-input"
+ ]
+ end
+
+ 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]
+ ]
+ end
+
+ def test_unterminated_interpolated_symbol
+ assert_error_messages ":\"#", [
+ "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],
+ ]
+ end
+
+ def test_1_2_3
+ assert_errors expression("(1, 2, 3)"), "(1, 2, 3)", [
+ ["unexpected ',', expecting end-of-input", 2..3],
+ ["unexpected ',', ignoring it", 2..3],
+ ["expected a matching `)`", 2..2],
+ ["unexpected ',', expecting end-of-input", 2..3],
+ ["unexpected ',', ignoring it", 2..3],
+ ["unexpected ',', expecting end-of-input", 5..6],
+ ["unexpected ',', ignoring it", 5..6],
+ ["unexpected ')', expecting end-of-input", 8..9],
+ ["unexpected ')', ignoring it", 8..9]
+ ]
+ end
+
+ def test_return_1_2_3
+ assert_error_messages "return(1, 2, 3)", [
+ "unexpected ',', expecting end-of-input",
+ "unexpected ',', ignoring it",
+ "expected a matching `)`",
+ "unexpected ')', expecting end-of-input",
+ "unexpected ')', ignoring it"
+ ]
+ end
+
+ def test_return_1
+ assert_errors expression("return 1,;"), "return 1,;", [
+ ["expected an argument", 8..9]
+ ]
+ end
+
+ def test_next_1_2_3
+ assert_errors expression("next(1, 2, 3)"), "next(1, 2, 3)", [
+ ["unexpected ',', expecting end-of-input", 6..7],
+ ["unexpected ',', ignoring it", 6..7],
+ ["expected a matching `)`", 6..6],
+ ["Invalid next", 0..12],
+ ["unexpected ')', expecting end-of-input", 12..13],
+ ["unexpected ')', ignoring it", 12..13]
+ ]
+ end
+
+ def test_next_1
+ assert_errors expression("next 1,;"), "next 1,;", [
+ ["expected an argument", 6..7],
+ ["Invalid next", 0..7]
+ ]
+ end
+
+ def test_break_1_2_3
+ assert_errors expression("break(1, 2, 3)"), "break(1, 2, 3)", [
+ ["unexpected ',', expecting end-of-input", 7..8],
+ ["unexpected ',', ignoring it", 7..8],
+ ["expected a matching `)`", 7..7],
+ ["Invalid break", 0..13],
+ ["unexpected ')', expecting end-of-input", 13..14],
+ ["unexpected ')', ignoring it", 13..14]
+ ]
+ end
+
+ def test_break_1
+ assert_errors expression("break 1,;"), "break 1,;", [
+ ["expected an argument", 7..8],
+ ["Invalid break", 0..8]
+ ]
+ end
+
+ def test_argument_forwarding_when_parent_is_not_forwarding
+ assert_errors expression('def a(x, y, z); b(...); end'), 'def a(x, y, z); b(...); end', [
+ ["unexpected ... when the parent method is not forwarding", 18..21]
+ ]
+ end
+
+ def test_argument_forwarding_only_effects_its_own_internals
+ assert_errors expression('def a(...); b(...); end; def c(x, y, z); b(...); end'),
+ 'def a(...); b(...); end; def c(x, y, z); b(...); end', [
+ ["unexpected ... when the parent method is not forwarding", 43..46]
+ ]
+ end
+
+ def test_top_level_constant_with_downcased_identifier
+ assert_error_messages "::foo", [
+ "expected a constant after the `::` operator",
+ "unexpected local variable or method, expecting end-of-input"
+ ]
+ end
+
+ def test_top_level_constant_starting_with_downcased_identifier
+ assert_error_messages "::foo::A", [
+ "expected a constant after the `::` operator",
+ "unexpected local variable or method, expecting end-of-input"
+ ]
+ end
+
+ def test_aliasing_global_variable_with_non_global_variable
+ assert_errors expression("alias $a b"), "alias $a b", [
+ ["invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", 9..10]
+ ]
+ end
+
+ def test_aliasing_non_global_variable_with_global_variable
+ assert_errors expression("alias a $b"), "alias a $b", [
+ ["invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", 8..10]
+ ]
+ end
+
+ def test_aliasing_global_variable_with_global_number_variable
+ assert_errors expression("alias $a $1"), "alias $a $1", [
+ ["invalid argument being passed to `alias`; can't make alias for the number variables", 9..11]
+ ]
+ end
+
+ def test_def_with_expression_receiver_and_no_identifier
+ assert_errors expression("def (a); end"), "def (a); end", [
+ ["expected a `.` or `::` after the receiver in a method definition", 7..7],
+ ["unexpected ';'; expected a method name", 7..8]
+ ]
+ end
+
+ def test_def_with_multiple_statements_receiver
+ assert_errors expression("def (\na\nb\n).c; end"), "def (\na\nb\n).c; end", [
+ ["expected a matching `)`", 8..8],
+ ["expected a `.` or `::` after the receiver in a method definition", 8..8],
+ ["expected a delimiter to close the parameters", 9..9],
+ ["unexpected ')', ignoring it", 10..11],
+ ["unexpected '.', ignoring it", 11..12]
+ ]
+ end
+
+ def test_def_with_empty_expression_receiver
+ assert_errors expression("def ().a; end"), "def ().a; end", [
+ ["expected a receiver for the method definition", 4..5]
+ ]
+ end
+
+ def test_block_beginning_with_brace_and_ending_with_end
+ 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",
+ "expected a block beginning with `{` to end with `}`"
+ ]
+ end
+
+ def test_double_splat_followed_by_splat_argument
+ expected = CallNode(
+ CallNodeFlags::IGNORE_VISIBILITY,
+ nil,
+ nil,
+ :a,
+ Location(),
+ Location(),
+ ArgumentsNode(1, [
+ KeywordHashNode(0, [AssocSplatNode(expression("kwargs"), Location())]),
+ SplatNode(Location(), expression("args"))
+ ]),
+ Location(),
+ nil
+ )
+
+ assert_errors expected, "a(**kwargs, *args)", [
+ ["unexpected `*` splat argument after a `**` keyword splat argument", 12..17]
+ ]
+ end
+
+ def test_arguments_after_block
+ expected = CallNode(
+ CallNodeFlags::IGNORE_VISIBILITY,
+ nil,
+ nil,
+ :a,
+ Location(),
+ Location(),
+ ArgumentsNode(0, [expression("foo")]),
+ Location(),
+ BlockArgumentNode(expression("block"), Location())
+ )
+
+ assert_errors expected, "a(&block, foo)", [
+ ["unexpected argument after a block argument", 10..13]
+ ]
+ end
+
+ def test_arguments_binding_power_for_and
+ assert_error_messages "foo(*bar and baz)", [
+ "unexpected 'and'; expected a `)` to close the arguments",
+ "unexpected ')', expecting end-of-input",
+ "unexpected ')', ignoring it"
+ ]
+ end
+
+ def test_splat_argument_after_keyword_argument
+ expected = CallNode(
+ CallNodeFlags::IGNORE_VISIBILITY,
+ nil,
+ nil,
+ :a,
+ Location(),
+ Location(),
+ ArgumentsNode(0, [
+ KeywordHashNode(1, [
+ AssocNode(
+ SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, nil, Location(), Location(), "foo"),
+ expression("bar"),
+ nil
+ )
+ ]),
+ SplatNode(Location(), expression("args"))
+ ]),
+ Location(),
+ nil
+ )
+
+ assert_errors expected, "a(foo: bar, *args)", [
+ ["unexpected `*` splat argument after a `**` keyword splat argument", 12..17]
+ ]
+ end
+
+ def test_module_definition_in_method_body
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ nil,
+ StatementsNode([ModuleNode([], Location(), ConstantReadNode(:A), nil, Location(), :A)]),
+ [],
+ Location(),
+ nil,
+ nil,
+ nil,
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo;module A;end;end", [
+ ["unexpected module definition in method body", 8..14]
+ ]
+ end
+
+ def test_module_definition_in_method_body_within_block
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ nil,
+ StatementsNode(
+ [CallNode(
+ CallNodeFlags::IGNORE_VISIBILITY,
+ nil,
+ nil,
+ :bar,
+ Location(),
+ nil,
+ nil,
+ nil,
+ BlockNode(
+ [],
+ nil,
+ StatementsNode([ModuleNode([], Location(), ConstantReadNode(:Foo), nil, Location(), :Foo)]),
+ Location(),
+ Location()
+ )
+ )]
+ ),
+ [],
+ Location(),
+ nil,
+ nil,
+ nil,
+ nil,
+ Location()
+ )
+
+ assert_errors expected, <<~RUBY, [["unexpected module definition in method body", 21..27]]
+ def foo
+ bar do
+ module Foo;end
+ end
+ end
+ RUBY
+ end
+
+ def test_module_definition_in_method_defs
+ source = <<~RUBY
+ def foo(bar = module A;end);end
+ def foo;rescue;module A;end;end
+ def foo;ensure;module A;end;end
+ RUBY
+ message = "unexpected module definition in method body"
+ assert_errors expression(source), source, [
+ [message, 14..20],
+ [message, 47..53],
+ [message, 79..85],
+ ]
+ end
+
+ def test_class_definition_in_method_body
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ nil,
+ StatementsNode(
+ [ClassNode(
+ [],
+ Location(),
+ ConstantReadNode(:A),
+ nil,
+ nil,
+ nil,
+ Location(),
+ :A
+ )]
+ ),
+ [],
+ Location(),
+ nil,
+ nil,
+ nil,
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo;class A;end;end", [
+ ["unexpected class definition in method body", 8..13]
+ ]
+ end
+
+ def test_class_definition_in_method_defs
+ source = <<~RUBY
+ def foo(bar = class A;end);end
+ def foo;rescue;class A;end;end
+ def foo;ensure;class A;end;end
+ RUBY
+ message = "unexpected class definition in method body"
+ assert_errors expression(source), source, [
+ [message, 14..19],
+ [message, 46..51],
+ [message, 77..82],
+ ]
+ end
+
+ def test_bad_arguments
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode([
+ RequiredParameterNode(0, :A),
+ RequiredParameterNode(0, :@a),
+ RequiredParameterNode(0, :$A),
+ RequiredParameterNode(0, :@@a),
+ ], [], nil, [], [], nil, nil),
+ nil,
+ [:A, :@a, :$A, :@@a],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(A, @a, $A, @@a);end", [
+ ["invalid formal argument; formal argument cannot be a constant", 8..9],
+ ["invalid formal argument; formal argument cannot be an instance variable", 11..13],
+ ["invalid formal argument; formal argument cannot be a global variable", 15..17],
+ ["invalid formal argument; formal argument cannot be a class variable", 19..22],
+ ]
+ end
+
+ if RUBY_VERSION >= "3.0"
+ def test_cannot_assign_to_a_reserved_numbered_parameter
+ expected = BeginNode(
+ Location(),
+ StatementsNode([
+ LocalVariableWriteNode(:_1, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_2, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_3, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_4, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_5, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_6, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_7, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_8, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_9, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location()),
+ LocalVariableWriteNode(:_10, 0, Location(), SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"), Location())
+ ]),
+ nil,
+ nil,
+ nil,
+ Location()
+ )
+ source = <<~RUBY
+ begin
+ _1=:a;_2=:a;_3=:a;_4=:a;_5=:a
+ _6=:a;_7=:a;_8=:a;_9=:a;_10=:a
+ end
+ RUBY
+ assert_errors expected, source, [
+ ["_1 is reserved for numbered parameters", 8..10],
+ ["_2 is reserved for numbered parameters", 14..16],
+ ["_3 is reserved for numbered parameters", 20..22],
+ ["_4 is reserved for numbered parameters", 26..28],
+ ["_5 is reserved for numbered parameters", 32..34],
+ ["_6 is reserved for numbered parameters", 40..42],
+ ["_7 is reserved for numbered parameters", 46..48],
+ ["_8 is reserved for numbered parameters", 52..54],
+ ["_9 is reserved for numbered parameters", 58..60],
+ ]
+ end
+ end
+
+ def test_do_not_allow_trailing_commas_in_method_parameters
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [RequiredParameterNode(0, :a), RequiredParameterNode(0, :b), RequiredParameterNode(0, :c)],
+ [],
+ nil,
+ [],
+ [],
+ nil,
+ nil
+ ),
+ nil,
+ [:a, :b, :c],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(a,b,c,);end", [
+ ["unexpected `,` in parameters", 13..14]
+ ]
+ end
+
+ def test_do_not_allow_trailing_commas_in_lambda_parameters
+ expected = LambdaNode(
+ [:a, :b],
+ Location(),
+ Location(),
+ Location(),
+ BlockParametersNode(
+ ParametersNode([RequiredParameterNode(0, :a), RequiredParameterNode(0, :b)], [], nil, [], [], nil, nil),
+ [],
+ Location(),
+ Location()
+ ),
+ nil
+ )
+ assert_errors expected, "-> (a, b, ) {}", [
+ ["unexpected `,` in parameters", 8..9]
+ ]
+ end
+
+ def test_do_not_allow_multiple_codepoints_in_a_single_character_literal
+ 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]
+ ]
+ end
+
+ def test_invalid_hex_escape
+ assert_errors expression('"\\xx"'), '"\\xx"', [
+ ["invalid hexadecimal escape sequence", 1..3],
+ ]
+ end
+
+ def test_do_not_allow_more_than_6_hexadecimal_digits_in_u_Unicode_character_notation
+ expected = StringNode(0, Location(), Location(), Location(), "\u0001")
+
+ assert_errors expected, '"\u{0000001}"', [
+ ["invalid Unicode escape sequence; maximum length is 6 digits", 4..11],
+ ]
+ end
+
+ def test_do_not_allow_characters_other_than_0_9_a_f_and_A_F_in_u_Unicode_character_notation
+ expected = StringNode(0, Location(), Location(), Location(), "\u0000z}")
+
+ assert_errors expected, '"\u{000z}"', [
+ ["invalid Unicode escape sequence", 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],
+ ]
+ end
+
+ def test_method_parameters_after_block
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [],
+ [],
+ nil,
+ [RequiredParameterNode(0, :a)],
+ [],
+ nil,
+ BlockParameterNode(0, :block, Location(), Location())
+ ),
+ nil,
+ [:block, :a],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+ assert_errors expected, "def foo(&block, a)\nend", [
+ ["unexpected parameter order", 16..17]
+ ]
+ end
+
+ def test_method_with_arguments_after_anonymous_block
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode([], [], nil, [RequiredParameterNode(0, :a)], [], nil, BlockParameterNode(0, nil, nil, Location())),
+ nil,
+ [:a],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(&, a)\nend", [
+ ["unexpected parameter order", 11..12]
+ ]
+ end
+
+ def test_method_parameters_after_arguments_forwarding
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [],
+ [],
+ nil,
+ [RequiredParameterNode(0, :a)],
+ [],
+ ForwardingParameterNode(),
+ nil
+ ),
+ nil,
+ [:a],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+ assert_errors expected, "def foo(..., a)\nend", [
+ ["unexpected parameter order", 13..14]
+ ]
+ end
+
+ def test_keywords_parameters_before_required_parameters
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [],
+ [],
+ nil,
+ [RequiredParameterNode(0, :a)],
+ [RequiredKeywordParameterNode(0, :b, Location())],
+ nil,
+ nil
+ ),
+ nil,
+ [:b, :a],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+ assert_errors expected, "def foo(b:, a)\nend", [
+ ["unexpected parameter order", 12..13]
+ ]
+ end
+
+ def test_rest_keywords_parameters_before_required_parameters
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [],
+ [],
+ nil,
+ [],
+ [RequiredKeywordParameterNode(0, :b, Location())],
+ KeywordRestParameterNode(0, :rest, Location(), Location()),
+ nil
+ ),
+ nil,
+ [:rest, :b],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(**rest, b:)\nend", [
+ ["unexpected parameter order", 16..18]
+ ]
+ end
+
+ def test_double_arguments_forwarding
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil),
+ nil,
+ [],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(..., ...)\nend", [
+ ["unexpected parameter order", 13..16]
+ ]
+ end
+
+ def test_multiple_error_in_parameters_order
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [],
+ [],
+ nil,
+ [RequiredParameterNode(0, :a)],
+ [RequiredKeywordParameterNode(0, :b, Location())],
+ KeywordRestParameterNode(0, :args, Location(), Location()),
+ nil
+ ),
+ nil,
+ [:args, :a, :b],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(**args, a, b:)\nend", [
+ ["unexpected parameter order", 16..17],
+ ["unexpected parameter order", 19..21]
+ ]
+ end
+
+ def test_switching_to_optional_arguments_twice
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [],
+ [],
+ nil,
+ [RequiredParameterNode(0, :a)],
+ [RequiredKeywordParameterNode(0, :b, Location())],
+ KeywordRestParameterNode(0, :args, Location(), Location()),
+ nil
+ ),
+ nil,
+ [:args, :a, :b],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location(),
+ )
+
+ assert_errors expected, "def foo(**args, a, b:)\nend", [
+ ["unexpected parameter order", 16..17],
+ ["unexpected parameter order", 19..21]
+ ]
+ end
+
+ def test_switching_to_named_arguments_twice
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [],
+ [],
+ nil,
+ [RequiredParameterNode(0, :a)],
+ [RequiredKeywordParameterNode(0, :b, Location())],
+ KeywordRestParameterNode(0, :args, Location(), Location()),
+ nil
+ ),
+ nil,
+ [:args, :a, :b],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location(),
+ )
+
+ assert_errors expected, "def foo(**args, a, b:)\nend", [
+ ["unexpected parameter order", 16..17],
+ ["unexpected parameter order", 19..21]
+ ]
+ end
+
+ def test_returning_to_optional_parameters_multiple_times
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode(
+ [RequiredParameterNode(0, :a)],
+ [
+ OptionalParameterNode(0, :b, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL, 1)),
+ OptionalParameterNode(0, :d, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL, 2))
+ ],
+ nil,
+ [RequiredParameterNode(0, :c), RequiredParameterNode(0, :e)],
+ [],
+ nil,
+ nil
+ ),
+ nil,
+ [:a, :b, :c, :d, :e],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location(),
+ )
+
+ assert_errors expected, "def foo(a, b = 1, c, d = 2, e)\nend", [
+ ["unexpected parameter order", 23..24]
+ ]
+ end
+
+ def test_case_without_when_clauses_errors_on_else_clause
+ expected = CaseMatchNode(
+ SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"),
+ [],
+ ElseNode(Location(), nil, Location()),
+ Location(),
+ Location()
+ )
+
+ assert_errors expected, "case :a\nelse\nend", [
+ ["expected a `when` or `in` clause after `case`", 0..4]
+ ]
+ end
+
+ def test_case_without_clauses
+ expected = CaseNode(
+ SymbolNode(SymbolFlags::FORCED_US_ASCII_ENCODING, Location(), Location(), nil, "a"),
+ [],
+ nil,
+ Location(),
+ Location()
+ )
+
+ assert_errors expected, "case :a\nend", [
+ ["expected a `when` or `in` clause after `case`", 0..4]
+ ]
+ end
+
+ def test_setter_method_cannot_be_defined_in_an_endless_method_definition
+ expected = DefNode(
+ :a=,
+ Location(),
+ nil,
+ nil,
+ StatementsNode([IntegerNode(IntegerBaseFlags::DECIMAL, 42)]),
+ [],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ Location(),
+ nil
+ )
+
+ assert_errors expected, "def a=() = 42", [
+ ["invalid method name; a setter method cannot be defined in an endless method definition", 4..6]
+ ]
+ end
+
+ def test_do_not_allow_forward_arguments_in_lambda_literals
+ expected = LambdaNode(
+ [],
+ Location(),
+ Location(),
+ Location(),
+ BlockParametersNode(ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil), [], Location(), Location()),
+ nil
+ )
+
+ assert_errors expected, "->(...) {}", [
+ ["unexpected ... when the parent method is not forwarding", 3..6]
+ ]
+ end
+
+ def test_do_not_allow_forward_arguments_in_blocks
+ expected = CallNode(
+ CallNodeFlags::IGNORE_VISIBILITY,
+ nil,
+ nil,
+ :a,
+ Location(),
+ nil,
+ nil,
+ nil,
+ BlockNode(
+ [],
+ BlockParametersNode(ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil), [], Location(), Location()),
+ nil,
+ Location(),
+ Location()
+ )
+ )
+
+ assert_errors expected, "a {|...|}", [
+ ["unexpected ... when the parent method is not forwarding", 4..7]
+ ]
+ end
+
+ def test_dont_allow_return_inside_class_body
+ expected = ClassNode(
+ [],
+ Location(),
+ ConstantReadNode(:A),
+ nil,
+ nil,
+ StatementsNode([ReturnNode(Location(), nil)]),
+ Location(),
+ :A
+ )
+
+ assert_errors expected, "class A; return; end", [
+ ["Invalid return in class/module body", 9..15]
+ ]
+ end
+
+ def test_dont_allow_return_inside_module_body
+ expected = ModuleNode(
+ [],
+ Location(),
+ ConstantReadNode(:A),
+ StatementsNode([ReturnNode(Location(), nil)]),
+ Location(),
+ :A
+ )
+
+ assert_errors expected, "module A; return; end", [
+ ["Invalid return in class/module body", 10..16]
+ ]
+ end
+
+ def test_dont_allow_setting_to_back_and_nth_reference
+ expected = BeginNode(
+ Location(),
+ StatementsNode([
+ GlobalVariableWriteNode(:$+, Location(), NilNode(), Location()),
+ GlobalVariableWriteNode(:$1466, Location(), NilNode(), Location())
+ ]),
+ nil,
+ nil,
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "begin\n$+ = nil\n$1466 = nil\nend", [
+ ["Can't set variable $+", 6..8],
+ ["Can't set variable $1466", 15..20]
+ ]
+ end
+
+ def test_duplicated_parameter_names
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode([RequiredParameterNode(0, :a), RequiredParameterNode(0, :b), RequiredParameterNode(ParameterFlags::REPEATED_PARAMETER, :a)], [], nil, [], [], nil, nil),
+ nil,
+ [:a, :b],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(a,b,a);end", [
+ ["duplicated argument name", 12..13]
+ ]
+
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode([RequiredParameterNode(0, :a), RequiredParameterNode(0, :b)], [], RestParameterNode(ParameterFlags::REPEATED_PARAMETER, :a, Location(), Location()), [], [], nil, nil),
+ nil,
+ [:a, :b],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(a,b,*a);end", [
+ ["duplicated argument name", 13..14]
+ ]
+
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode([RequiredParameterNode(0, :a), RequiredParameterNode(0, :b)], [], nil, [], [], KeywordRestParameterNode(ParameterFlags::REPEATED_PARAMETER, :a, Location(), Location()), nil),
+ nil,
+ [:a, :b],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(a,b,**a);end", [
+ ["duplicated argument name", 14..15]
+ ]
+
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode([RequiredParameterNode(0, :a), RequiredParameterNode(0, :b)], [], nil, [], [], nil, BlockParameterNode(ParameterFlags::REPEATED_PARAMETER, :a, Location(), Location())),
+ nil,
+ [:a, :b],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(a,b,&a);end", [
+ ["duplicated argument name", 13..14]
+ ]
+
+ expected = DefNode(
+ :foo,
+ Location(),
+ nil,
+ ParametersNode([], [OptionalParameterNode(0, :a, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL, 1))], RestParameterNode(0, :c, Location(), Location()), [RequiredParameterNode(0, :b)], [], nil, nil),
+ nil,
+ [:a, :b, :c],
+ Location(),
+ nil,
+ Location(),
+ Location(),
+ nil,
+ Location()
+ )
+
+ assert_errors expected, "def foo(a = 1,b,*c);end", [["unexpected parameter `*`", 16..17]]
+ end
+
+ def test_content_after_unterminated_heredoc
+ receiver = StringNode(0, Location(), Location(), Location(), "")
+ 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]
+ ]
+ end
+
+ def test_invalid_message_name
+ result = Prism.parse("+.@foo,+=foo")
+ assert_equal :"", result.value.statements.body.first.write_name
+ end
+
+ def test_invalid_operator_write_fcall
+ source = "foo! += 1"
+ assert_errors expression(source), source, [
+ ["unexpected write target", 0..4]
+ ]
+ end
+
+ def test_invalid_operator_write_dot
+ source = "foo.+= 1"
+ assert_errors expression(source), source, [
+ ["unexpected write target", 5..6]
+ ]
+ end
+
+ def test_unterminated_global_variable
+ message = "'$' without identifiers is not allowed as a global variable name"
+
+ assert_errors expression("$"), "$", [[message, 0..1]]
+ assert_errors expression("$ "), "$ ", [[message, 0..1]]
+ end
+
+ def test_invalid_global_variable_write
+ assert_errors expression("$',"), "$',", [
+ ["Can't set variable $'", 0..2],
+ ["unexpected write target", 0..2]
+ ]
+ end
+
+ def test_invalid_multi_target
+ error_messages = ["unexpected write target"]
+
+ assert_error_messages "foo,", error_messages
+ assert_error_messages "foo = 1; foo,", error_messages
+ assert_error_messages "foo.bar,", error_messages
+ assert_error_messages "*foo,", error_messages
+ assert_error_messages "@foo,", error_messages
+ assert_error_messages "@@foo,", error_messages
+ assert_error_messages "$foo,", error_messages
+ assert_error_messages "$1,", ["Can't set variable $1", *error_messages]
+ assert_error_messages "$+,", ["Can't set variable $+", *error_messages]
+ assert_error_messages "Foo,", error_messages
+ assert_error_messages "::Foo,", error_messages
+ assert_error_messages "Foo::Foo,", error_messages
+ assert_error_messages "Foo::foo,", error_messages
+ assert_error_messages "foo[foo],", error_messages
+ assert_error_messages "(foo, bar)", error_messages
+ assert_error_messages "foo((foo, bar))", error_messages
+ assert_error_messages "foo((*))", error_messages
+ assert_error_messages "foo(((foo, bar), *))", error_messages
+ assert_error_messages "(foo, bar) + 1", error_messages
+ assert_error_messages "(foo, bar) in baz", error_messages
+ end
+
+ def test_call_with_block_and_write
+ source = "foo {} &&= 1"
+ assert_errors expression(source), source, [
+ ["unexpected write target", 0..6],
+ ["unexpected operator after a call with a block", 7..10]
+ ]
+ end
+
+ def test_call_with_block_or_write
+ source = "foo {} ||= 1"
+ assert_errors expression(source), source, [
+ ["unexpected write target", 0..6],
+ ["unexpected operator after a call with a block", 7..10]
+ ]
+ end
+
+ def test_call_with_block_operator_write
+ source = "foo {} += 1"
+ assert_errors expression(source), source, [
+ ["unexpected write target", 0..6],
+ ["unexpected operator after a call with a block", 7..9]
+ ]
+ end
+
+ def test_index_call_with_block_and_write
+ source = "foo[1] {} &&= 1"
+ assert_errors expression(source), source, [
+ ["unexpected write target", 0..9],
+ ["unexpected operator after a call with arguments", 10..13],
+ ["unexpected operator after a call with a block", 10..13]
+ ]
+ end
+
+ def test_index_call_with_block_or_write
+ source = "foo[1] {} ||= 1"
+ assert_errors expression(source), source, [
+ ["unexpected write target", 0..9],
+ ["unexpected operator after a call with arguments", 10..13],
+ ["unexpected operator after a call with a block", 10..13]
+ ]
+ end
+
+ def test_index_call_with_block_operator_write
+ source = "foo[1] {} += 1"
+ assert_errors expression(source), source, [
+ ["unexpected write target", 0..9],
+ ["unexpected operator after a call with arguments", 10..12],
+ ["unexpected operator after a call with a block", 10..12]
+ ]
+ end
+
+ 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]
+ ]
+ end
+
+ def test_targeting_numbered_parameter
+ assert_errors expression("-> { _1, = 0 }"), "-> { _1, = 0 }", [
+ ["_1 is reserved for numbered parameters", 5..7]
+ ]
+ end
+
+ def test_defining_numbered_parameter
+ error_messages = ["_1 is reserved for numbered parameters"]
+
+ assert_error_messages "def _1; end", error_messages
+ assert_error_messages "def self._1; end", error_messages
+ end
+ end
+
+ def test_double_scope_numbered_parameters
+ source = "-> { _1 + -> { _2 } }"
+ errors = [["numbered parameter is already used in outer scope", 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
+ assert_error_messages "01__1", error_messages
+ assert_error_messages "0d1__1", error_messages
+ assert_error_messages "0x1__1", error_messages
+
+ assert_error_messages "1_1_", error_messages
+ assert_error_messages "0b1_1_", error_messages
+ assert_error_messages "0o1_1_", error_messages
+ assert_error_messages "01_1_", error_messages
+ assert_error_messages "0d1_1_", error_messages
+ assert_error_messages "0x1_1_", error_messages
+ end
+
+ def test_alnum_delimiters
+ error_messages = ["invalid `%` token"]
+
+ assert_error_messages "%qXfooX", error_messages
+ assert_error_messages "%QXfooX", error_messages
+ assert_error_messages "%wXfooX", error_messages
+ assert_error_messages "%WxfooX", error_messages
+ assert_error_messages "%iXfooX", error_messages
+ assert_error_messages "%IXfooX", error_messages
+ assert_error_messages "%xXfooX", error_messages
+ assert_error_messages "%rXfooX", error_messages
+ assert_error_messages "%sXfooX", error_messages
+ end
+
+ def test_begin_at_toplevel
+ source = "def foo; BEGIN {}; end"
+ assert_errors expression(source), source, [
+ ["BEGIN is permitted only at toplevel", 9..14],
+ ]
+ end
+
+ if RUBY_VERSION >= "3.0"
+ def test_numbered_parameters_in_block_arguments
+ source = "foo { |_1| }"
+ assert_errors expression(source), source, [
+ ["_1 is reserved for numbered parameters", 7..9],
+ ]
+ end
+ end
+
+ def test_conditional_predicate_closed
+ source = "if 0 0; elsif 0 0; end\nunless 0 0; end"
+ assert_errors expression(source), source, [
+ ["expected `then` or `;` or '\\n" + "'", 5..6],
+ ["expected `then` or `;` or '\\n" + "'", 16..17],
+ ["expected `then` or `;` or '\\n" + "'", 32..33],
+ ]
+ end
+
+ def test_parameter_name_ending_with_bang_or_question_mark
+ source = "def foo(x!,y?); end"
+ errors = [
+ ["unexpected name for a parameter", 8..10],
+ ["unexpected name for a parameter", 11..13]
+ ]
+ assert_errors expression(source), source, errors
+ end
+
+ def test_class_name
+ source = "class 0.X end"
+ assert_errors expression(source), source, [
+ ["unexpected constant path after `class`; class/module name must be CONSTANT", 6..9],
+ ]
+ end
+
+ def test_loop_conditional_is_closed
+ source = "while 0 0; foo; end; until 0 0; foo; end"
+ assert_errors expression(source), source, [
+ ["expected a predicate expression for the `while` statement", 7..7],
+ ["expected a predicate expression for the `until` statement", 28..28],
+ ]
+ end
+
+ def test_forwarding_arg_after_keyword_rest
+ source = "def f(**,...);end"
+ assert_errors expression(source), source, [
+ ["unexpected `...` in parameters", 9..12],
+ ]
+ end
+
+ def test_semicolon_after_inheritance_operator
+ source = "class Foo < Bar end"
+ assert_errors expression(source), source, [
+ ["unexpected `end`, expecting ';' or '\\n'", 15..15],
+ ]
+ end
+
+ def test_shadow_args_in_lambda
+ source = "->a;b{}"
+
+ 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],
+ ["expected a lambda block beginning with `do` to end with `end`", 7..7]
+ ]
+ end
+
+ def test_shadow_args_in_block
+ source = "tap{|a;a|}"
+ assert_errors expression(source), source, [
+ ["duplicated argument name", 7..8],
+ ]
+ end
+
+ def test_repeated_parameter_name_in_destructured_params
+ source = "def f(a, (b, (a))); end"
+
+ assert_errors expression(source), source, [
+ ["duplicated argument name", 14..15],
+ ]
+ end
+
+ def test_assign_to_numbered_parameter
+ source = <<~RUBY
+ a in _1
+ a => _1
+ 1 => a, _1
+ 1 in a, _1
+ /(?<_1>)/ =~ a
+ RUBY
+
+ message = "_1 is reserved for numbered parameters"
+ assert_errors expression(source), source, [
+ [message, 5..7],
+ [message, 13..15],
+ [message, 24..26],
+ [message, 35..37],
+ [message, 42..44]
+ ]
+ end
+
+ def test_symbol_in_keyword_parameter
+ source = "def foo(x:'y':); end"
+ assert_errors expression(source), source, [
+ ["unexpected label terminator, expected a string literal terminator", 12..14]
+ ]
+ end
+
+ def test_symbol_in_hash
+ source = "{x:'y':}"
+ assert_errors expression(source), source, [
+ ["unexpected label terminator, expected a string literal terminator", 5..7]
+ ]
+ end
+
+ def test_while_endless_method
+ source = "while def f = g do end"
+
+ 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],
+ ["expected an `end` to close the `while` statement", 22..22]
+ ]
+ end
+
+ def test_match_plus
+ source = <<~RUBY
+ a in b + c
+ a => b + c
+ RUBY
+
+ assert_errors expression(source), source, [
+ ["unexpected '+', expecting end-of-input", 7..8],
+ ["unexpected '+', ignoring it", 7..8],
+ ["unexpected '+', expecting end-of-input", 18..19],
+ ["unexpected '+', ignoring it", 18..19]
+ ]
+ end
+
+ def test_rational_number_with_exponential_portion
+ source = '1e1r; 1e1ri'
+
+ assert_errors expression(source), source, [
+ ["unexpected local variable or method, expecting end-of-input", 3..4],
+ ["unexpected local variable or method, expecting end-of-input", 9..11]
+ ]
+ end
+
+ def test_check_value_expression
+ source = <<~RUBY
+ 1 => ^(return)
+ while true
+ 1 => ^(break)
+ 1 => ^(next)
+ 1 => ^(redo)
+ 1 => ^(retry)
+ 1 => ^(2 => a)
+ end
+ 1 => ^(if 1; (return) else (return) end)
+ 1 => ^(unless 1; (return) else (return) end)
+ RUBY
+
+ message = "unexpected void value expression"
+ assert_errors expression(source), source, [
+ [message, 7..13],
+ [message, 35..40],
+ [message, 51..55],
+ [message, 66..70],
+ ["Invalid retry without rescue", 81..86],
+ [message, 81..86],
+ [message, 97..103],
+ [message, 123..129],
+ [message, 168..174],
+ ]
+ end
+
+ def test_void_value_expression_in_statement
+ source = <<~RUBY
+ if (return)
+ end
+ unless (return)
+ end
+ while (return)
+ end
+ until (return)
+ end
+ case (return)
+ when 1
+ end
+ class A < (return)
+ end
+ class << (return)
+ end
+ for x in (return)
+ end
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 4..10],
+ [message, 24..30],
+ [message, 43..49],
+ [message, 62..68],
+ [message, 80..86],
+ [message, 110..116],
+ [message, 132..138],
+ [message, 154..160],
+ ]
+ end
+
+ def test_void_value_expression_in_def
+ source = <<~RUBY
+ def (return).x
+ end
+ def x(a = return)
+ end
+ def x(a: return)
+ end
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 5..11],
+ [message, 29..35],
+ [message, 50..56],
+ ]
+ end
+
+ def test_void_value_expression_in_assignment
+ source = <<~RUBY
+ a = return
+ a = 1, return
+ a, b = return, 1
+ a, b = 1, *return
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 4..10],
+ [message, 18..24],
+ [message, 32..38],
+ [message, 53..59],
+ ]
+ end
+
+ def test_void_value_expression_in_modifier
+ source = <<~RUBY
+ 1 if (return)
+ 1 unless (return)
+ 1 while (return)
+ 1 until (return)
+ (return) => a
+ (return) in a
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 6..12],
+ [message, 24..30],
+ [message, 41..47],
+ [message, 58..64],
+ [message, 67..73],
+ [message, 81..87]
+ ]
+ end
+
+ def test_void_value_expression_in_expression
+ source = <<~RUBY
+ (return) ? 1 : 1
+ (return)..1
+ 1..(return)
+ (return)...1
+ 1...(return)
+ (..(return))
+ (...(return))
+ ((return)..)
+ ((return)...)
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 1..7],
+ [message, 18..24],
+ [message, 33..39],
+ [message, 42..48],
+ [message, 59..65],
+ [message, 71..77],
+ [message, 85..91],
+ [message, 96..102],
+ [message, 109..115]
+ ]
+ end
+
+ def test_void_value_expression_in_array
+ source = <<~RUBY
+ [return]
+ [1, return]
+ [ return => 1 ]
+ [ 1 => return ]
+ [ a: return ]
+ [ *return ]
+ [ **return ]
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 1..7],
+ [message, 13..19],
+ [message, 23..29],
+ [message, 44..50],
+ [message, 58..64],
+ [message, 70..76],
+ [message, 83..89],
+ ]
+ end
+
+ def test_void_value_expression_in_hash
+ source = <<~RUBY
+ { return => 1 }
+ { 1 => return }
+ { a: return }
+ { **return }
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 2..8],
+ [message, 23..29],
+ [message, 37..43],
+ [message, 50..56],
+ ]
+ end
+
+ def test_void_value_expression_in_call
+ source = <<~RUBY
+ (return).foo
+ (return).(1)
+ (return)[1]
+ (return)[1] = 2
+ (return)::foo
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 1..7],
+ [message, 14..20],
+ [message, 27..33],
+ [message, 39..45],
+ [message, 55..61],
+ ]
+ end
+
+ def test_void_value_expression_in_constant_path
+ source = <<~RUBY
+ (return)::A
+ class (return)::A; end
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 1..7],
+ [message, 19..25],
+ ]
+ end
+
+ def test_void_value_expression_in_arguments
+ source = <<~RUBY
+ foo(return)
+ foo(1, return)
+ foo(*return)
+ foo(**return)
+ foo(&return)
+ foo(return => 1)
+ foo(:a => return)
+ foo(a: return)
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 4..10],
+ [message, 19..25],
+ [message, 32..38],
+ [message, 46..52],
+ [message, 59..65],
+ [message, 71..77],
+ [message, 94..100],
+ [message, 109..115],
+ ]
+ end
+
+ def test_void_value_expression_in_unary_call
+ source = <<~RUBY
+ +(return)
+ not return
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 2..8],
+ [message, 14..20],
+ ]
+ end
+
+ def test_void_value_expression_in_binary_call
+ source = <<~RUBY
+ 1 + (return)
+ (return) + 1
+ 1 and (return)
+ (return) and 1
+ 1 or (return)
+ (return) or 1
+ RUBY
+
+ message = 'unexpected void value expression'
+ assert_errors expression(source), source, [
+ [message, 5..11],
+ [message, 14..20],
+ [message, 42..48],
+ [message, 71..77],
+ ]
+ end
+
+ def test_trailing_comma_in_calls
+ assert_errors expression("foo 1,"), "foo 1,", [
+ ["expected an argument", 5..6]
+ ]
+ end
+
+ def test_argument_after_ellipsis
+ source = 'def foo(...); foo(..., 1); end'
+ assert_errors expression(source), source, [
+ ['unexpected argument after `...`', 23..24]
+ ]
+ end
+
+ def test_ellipsis_in_no_paren_call
+ source = 'def foo(...); foo 1, ...; end'
+ assert_errors expression(source), source, [
+ ['unexpected `...` in an non-parenthesized call', 21..24]
+ ]
+ end
+
+ def test_non_assoc_range
+ source = '1....2'
+
+ assert_errors expression(source), source, [
+ ["unexpected '.', expecting end-of-input", 4..5],
+ ["unexpected '.', ignoring it", 4..5]
+ ]
+ end
+
+ def test_upcase_end_in_def
+ assert_warning_messages "def foo; END { }; end", [
+ "END in method; use at_exit"
+ ]
+ end
+
+ def test_warnings_verbosity
+ warning = Prism.parse("def foo; END { }; end").warnings[0]
+ assert_equal "END in method; use at_exit", warning.message
+ assert_equal :default, warning.level
+
+ warning = Prism.parse("foo /regexp/").warnings[0]
+ assert_equal "ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator", warning.message
+ assert_equal :verbose, warning.level
+ end
+
+ def test_statement_operators
+ source = <<~RUBY
+ alias x y + 1
+ alias x y.z
+ BEGIN { bar } + 1
+ BEGIN { bar }.z
+ END { bar } + 1
+ END { bar }.z
+ undef x + 1
+ undef x.z
+ RUBY
+
+ assert_errors expression(source), source, [
+ ["unexpected '+', expecting end-of-input", 10..11],
+ ["unexpected '+', ignoring it", 10..11],
+ ["unexpected '.', expecting end-of-input", 23..24],
+ ["unexpected '.', ignoring it", 23..24],
+ ["unexpected '+', expecting end-of-input", 40..41],
+ ["unexpected '+', ignoring it", 40..41],
+ ["unexpected '.', expecting end-of-input", 57..58],
+ ["unexpected '.', ignoring it", 57..58],
+ ["unexpected '+', expecting end-of-input", 72..73],
+ ["unexpected '+', ignoring it", 72..73],
+ ["unexpected '.', expecting end-of-input", 87..88],
+ ["unexpected '.', ignoring it", 87..88],
+ ["unexpected '+', expecting end-of-input", 98..99],
+ ["unexpected '+', ignoring it", 98..99],
+ ["unexpected '.', expecting end-of-input", 109..110],
+ ["unexpected '.', ignoring it", 109..110]
+ ]
+ end
+
+ def test_statement_at_non_statement
+ source = <<~RUBY
+ foo(alias x y)
+ foo(BEGIN { bar })
+ foo(END { bar })
+ foo(undef x)
+ RUBY
+ assert_errors expression(source), source, [
+ ['unexpected an `alias` at a non-statement position', 4..9],
+ ['unexpected a `BEGIN` at a non-statement position', 19..24],
+ ['unexpected an `END` at a non-statement position', 38..41],
+ ['unexpected an `undef` at a non-statement position', 55..60],
+ ]
+ end
+
+ def test_binary_range_with_left_unary_range
+ source = <<~RUBY
+ ..1..
+ ...1..
+ 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]
+ ]
+ end
+
+ def test_circular_param
+ source = <<~RUBY
+ def foo(bar = bar) = 42
+ def foo(bar: bar) = 42
+ proc { |foo = foo| }
+ proc { |foo: foo| }
+ RUBY
+
+ assert_errors expression(source), source, [
+ ["circular argument reference - bar", 8..11],
+ ["circular argument reference - bar", 32..35],
+ ["circular argument reference - foo", 55..58],
+ ["circular argument reference - foo", 76..79]
+ ]
+
+ refute_error_messages("def foo(bar: bar = 1); end")
+ end
+
+ def test_command_calls
+ sources = <<~RUBY.lines
+ [a b]
+ {a: b c}
+ ...a b
+ if ...a b; end
+ a b, c d
+ a(b, c d)
+ a(*b c)
+ a(**b c)
+ a(&b c)
+ +a b
+ a + b c
+ a && b c
+ a =~ b c
+ a = b, c d
+ a = *b c
+ a, b = c = d f
+ a ? b c : d e
+ defined? a b
+ ! ! a b
+ def f a = b c; end
+ def f(a = b c); end
+ a = b rescue c d
+ def a = b rescue c d
+ ->a=b c{}
+ ->(a=b c){}
+ case; when a b; end
+ case; in a if a b; end
+ case; in a unless a b; end
+ begin; rescue a b; end
+ begin; rescue a b => c; end
+ RUBY
+
+ sources.each do |source|
+ refute_valid_syntax(source)
+ assert_false(Prism.parse(source).success?)
+ end
+ end
+
+ def test_range_and_bin_op
+ sources = <<~RUBY.lines
+ 1..2..3
+ 1..2..
+ 1.. || 2
+ 1.. & 2
+ 1.. * 2
+ 1.. / 2
+ 1.. % 2
+ 1.. ** 2
+ RUBY
+
+ sources.each do |source|
+ refute_valid_syntax(source)
+ assert_false(Prism.parse(source).success?)
+ end
+ end
+
+ def test_command_call_in
+ source = <<~RUBY
+ foo 1 in a
+ a = foo 2 in b
+ RUBY
+
+ assert_errors expression(source), source, [
+ ["unexpected `in` keyword in arguments", 9..10],
+ ["unexpected local variable or method, expecting end-of-input", 9..10],
+ ["unexpected `in` keyword in arguments", 24..25],
+ ["unexpected local variable or method, expecting end-of-input", 24..25]
+ ]
+ end
+
+ def test_constant_assignment_in_method
+ source = 'def foo();A=1;end'
+ assert_errors expression(source), source, [
+ ['dynamic constant assignment', 10..13]
+ ]
+ end
+
+ def test_non_assoc_equality
+ source = <<~RUBY
+ 1 == 2 == 3
+ 1 != 2 != 3
+ 1 === 2 === 3
+ 1 =~ 2 =~ 3
+ 1 !~ 2 !~ 3
+ 1 <=> 2 <=> 3
+ RUBY
+
+ assert_errors expression(source), source, [
+ ["unexpected '==', expecting end-of-input", 7..9],
+ ["unexpected '==', ignoring it", 7..9],
+ ["unexpected '!=', expecting end-of-input", 19..21],
+ ["unexpected '!=', ignoring it", 19..21],
+ ["unexpected '===', expecting end-of-input", 32..35],
+ ["unexpected '===', ignoring it", 32..35],
+ ["unexpected '=~', expecting end-of-input", 45..47],
+ ["unexpected '=~', ignoring it", 45..47],
+ ["unexpected '!~', expecting end-of-input", 57..59],
+ ["unexpected '!~', ignoring it", 57..59],
+ ["unexpected '<=>', expecting end-of-input", 70..73],
+ ["unexpected '<=>', ignoring it", 70..73]
+ ]
+ end
+
+ def test_block_arg_and_block
+ source = 'foo(&1) { }'
+ assert_errors expression(source), source, [
+ ["both block arg and actual block given; only one block is allowed", 8..11]
+ ]
+ end
+
+ 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]
+ ]
+ end
+
+ def test_it_with_ordinary_parameter
+ source = "proc { || it }"
+ errors = [["`it` is not allowed when an ordinary parameter is defined", 10..12]]
+
+ assert_errors expression(source), source, errors, check_valid_syntax: RUBY_VERSION >= "3.4.0"
+ end
+
+ def test_regular_expression_with_unknown_regexp_options
+ source = "/foo/AZaz"
+ errors = [["unknown regexp options: AZaz", 4..9]]
+
+ assert_errors expression(source), source, errors
+ end
+
+ def test_interpolated_regular_expression_with_unknown_regexp_options
+ source = "/\#{foo}/AZaz"
+ errors = [["unknown regexp options: AZaz", 7..12]]
+
+ assert_errors expression(source), source, errors
+ end
+
+ def test_singleton_method_for_literals
+ source = <<~'RUBY'
+ def (1).g; end
+ def ((a; 1)).foo; end
+ def ((return; 1)).bar; end
+ def (((1))).foo; end
+ def (__FILE__).foo; end
+ def (__ENCODING__).foo; end
+ def (__LINE__).foo; end
+ def ("foo").foo; end
+ def (3.14).foo; end
+ def (3.14i).foo; end
+ def (:foo).foo; end
+ def (:'foo').foo; end
+ def (:'f{o}').foo; end
+ def ('foo').foo; end
+ def ("foo").foo; end
+ def ("#{fo}o").foo; end
+ def (/foo/).foo; end
+ def (/f#{oo}/).foo; end
+ def ([1]).foo; end
+ RUBY
+ errors = [
+ ["cannot define singleton method for literals", 5..6],
+ ["cannot define singleton method for literals", 24..25],
+ ["cannot define singleton method for literals", 51..52],
+ ["cannot define singleton method for literals", 71..72],
+ ["cannot define singleton method for literals", 90..98],
+ ["cannot define singleton method for literals", 114..126],
+ ["cannot define singleton method for literals", 142..150],
+ ["cannot define singleton method for literals", 166..171],
+ ["cannot define singleton method for literals", 187..191],
+ ["cannot define singleton method for literals", 207..212],
+ ["cannot define singleton method for literals", 228..232],
+ ["cannot define singleton method for literals", 248..254],
+ ["cannot define singleton method for literals", 270..277],
+ ["cannot define singleton method for literals", 293..298],
+ ["cannot define singleton method for literals", 314..319],
+ ["cannot define singleton method for literals", 335..343],
+ ["cannot define singleton method for literals", 359..364],
+ ["cannot define singleton method for literals", 380..388],
+ ["cannot define singleton method for literals", 404..407]
+ ]
+ assert_errors expression(source), source, errors
+ end
+
+ def test_assignment_to_literal_in_conditionals
+ source = <<~RUBY
+ if (a = 2); end
+ if ($a = 2); end
+ if (@a = 2); end
+ if (@@a = 2); end
+ if a elsif b = 2; end
+ unless (a = 2); end
+ unless ($a = 2); end
+ unless (@a = 2); end
+ unless (@@a = 2); end
+ while (a = 2); end
+ while ($a = 2); end
+ while (@a = 2); end
+ while (@@a = 2); end
+ until (a = 2); end
+ until ($a = 2); end
+ until (@a = 2); end
+ until (@@a = 2); end
+ foo if a = 2
+ foo if (a, b = 2)
+ (@foo = 1) ? a : b
+ !(a = 2)
+ not a = 2
+ RUBY
+ assert_warning_messages source, [
+ "found '= literal' in conditional, should be =="
+ ] * source.lines.count
+ end
+
+ def test_duplicate_pattern_capture
+ source = <<~RUBY
+ case (); in [a, a]; end
+ case (); in [a, *a]; end
+ case (); in {a: a, b: a}; end
+ case (); in {a: a, **a}; end
+ case (); in [a, {a:}]; end
+ case (); in [a, {a: {a: {a: [a]}}}]; end
+ case (); in a => a; end
+ case (); in [A => a, {a: b => a}]; end
+ RUBY
+
+ assert_error_messages source, Array.new(source.lines.length, "duplicated variable name")
+ refute_error_messages "case (); in [_a, _a]; end"
+ end
+
+ def test_duplicate_pattern_hash_key
+ assert_error_messages "case (); in {a:, a:}; end", ["duplicated key name", "duplicated variable name"]
+ assert_error_messages "case (); in {a:1, a:2}; end", ["duplicated key name"]
+ refute_error_messages "case (); in [{a:1}, {a:2}]; end"
+ end
+
+ def test_unexpected_block
+ assert_error_messages "def foo = yield(&:+)", ["block argument should not be given"]
+ end
+
+ private
+
+ def assert_errors(expected, source, errors, check_valid_syntax: true)
+ refute_valid_syntax(source) if check_valid_syntax
+
+ result = Prism.parse(source)
+ node = result.value.statements.body.last
+
+ assert_equal_nodes(expected, node, compare_location: false)
+ assert_equal(errors, result.errors.map { |e| [e.message, e.location.start_offset..e.location.end_offset] })
+ end
+
+ def assert_error_messages(source, errors)
+ refute_valid_syntax(source)
+ result = Prism.parse(source)
+ assert_equal(errors, result.errors.map(&:message))
+ end
+
+ def refute_error_messages(source)
+ assert_valid_syntax(source)
+ assert Prism.parse_success?(source), "Expected #{source.inspect} to parse successfully"
+ end
+
+ def assert_warning_messages(source, warnings)
+ result = Prism.parse(source)
+ assert_equal(warnings, result.warnings.map(&:message))
+ end
+
+ def expression(source)
+ Prism.parse(source).value.statements.body.last
+ end
+ end
+end
diff --git a/test/prism/fixtures/alias.txt b/test/prism/fixtures/alias.txt
new file mode 100644
index 0000000000..376dacd7cc
--- /dev/null
+++ b/test/prism/fixtures/alias.txt
@@ -0,0 +1,23 @@
+alias :foo :bar
+
+alias %s[abc] %s[def]
+
+alias :'abc' :'def'
+
+alias :"abc#{1}" :'def'
+
+alias $a $'
+
+alias foo bar
+
+alias $foo $bar
+
+alias foo if
+
+alias foo <=>
+
+alias :== :eql?
+
+alias A B
+
+alias :A :B
diff --git a/test/prism/fixtures/arithmetic.txt b/test/prism/fixtures/arithmetic.txt
new file mode 100644
index 0000000000..b1e1267b95
--- /dev/null
+++ b/test/prism/fixtures/arithmetic.txt
@@ -0,0 +1,13 @@
+foo !bar
+
+-foo*bar
+
++foo**bar
+
+foo ~bar
+
+foo << bar << baz
+
+-1**2
+
+-1.zero?
diff --git a/test/prism/fixtures/arrays.txt b/test/prism/fixtures/arrays.txt
new file mode 100644
index 0000000000..2897189518
--- /dev/null
+++ b/test/prism/fixtures/arrays.txt
@@ -0,0 +1,122 @@
+[*a]
+
+foo[bar, baz] = 1, 2, 3
+
+[a: [:b, :c]]
+
+
+
+[:a, :b,
+:c,1,
+
+
+
+:d,
+]
+
+
+[:a, :b,
+:c,1,
+
+
+
+:d
+
+
+]
+
+[foo => bar]
+
+foo[bar][baz] = qux
+
+foo[bar][baz]
+
+[
+]
+
+foo[bar, baz]
+
+foo[bar, baz] = qux
+
+foo[0], bar[0] = 1, 2
+
+foo[bar[baz] = qux]
+
+foo[bar]
+
+foo[bar] = baz
+
+[**{}]
+
+[**kw]
+
+[1, **kw]
+
+[1, **kw, **{}, **kw]
+
+[
+ foo => bar,
+]
+
+
+%i#one two three#
+
+%w#one two three#
+
+%x#one two three#
+
+
+%i@one two three@
+
+%w@one two three@
+
+%x@one two three@
+
+
+%i{one two three}
+
+%w{one two three}
+
+%x{one two three}
+
+%w[\C:]
+
+foo[] += 1
+
+foo[] ||= 1
+
+foo[] &&= 1
+
+foo.foo[] += 1
+
+foo.foo[] ||= 1
+
+foo.foo[] &&= 1
+
+foo[bar] += 1
+
+foo[bar] ||= 1
+
+foo[bar] &&= 1
+
+foo.foo[bar] += 1
+
+foo.foo[bar] ||= 1
+
+foo.foo[bar] &&= 1
+
+def f(*); a[*]; end
+
+def f(*); a[1, *]; end
+
+def f(*); a[*] = 1; end
+
+def f(*); a[1, *] = 1; end
+
+def f(*); a[*] += 1; end
+
+def f(*); a[1, *] &&= 1; end
+
+def f(*); rescue => a[*]; end
+
+def f(*); rescue => a[1, *]; end
diff --git a/test/prism/fixtures/begin_ensure.txt b/test/prism/fixtures/begin_ensure.txt
new file mode 100644
index 0000000000..6cfb627453
--- /dev/null
+++ b/test/prism/fixtures/begin_ensure.txt
@@ -0,0 +1,21 @@
+begin
+a
+ensure
+b
+end
+
+begin; a; ensure; b; end
+
+begin a
+ ensure b
+ end
+
+begin a; ensure b; end
+
+begin begin:s.l begin ensure Module.new do
+ begin
+ break
+ ensure Module.new do
+ end
+ end
+end end end end
diff --git a/test/prism/fixtures/begin_rescue.txt b/test/prism/fixtures/begin_rescue.txt
new file mode 100644
index 0000000000..0a56fbef9f
--- /dev/null
+++ b/test/prism/fixtures/begin_rescue.txt
@@ -0,0 +1,79 @@
+begin; a; rescue; b; else; c; end
+
+begin; a; rescue; b; else; c; ensure; d; end
+
+begin
+a
+end
+
+begin; a; end
+
+begin a
+ end
+
+begin a; end
+
+begin
+a
+rescue
+b
+rescue
+c
+rescue
+d
+end
+
+begin
+ a
+rescue Exception => ex
+ b
+rescue AnotherException, OneMoreException => ex
+ c
+end
+
+begin
+ a
+rescue Exception => ex
+ b
+ensure
+ b
+end
+
+%!abc!
+
+begin
+a
+rescue
+b
+end
+
+begin;a;rescue;b;end
+
+begin
+a;rescue
+b;end
+
+begin
+a
+rescue Exception
+b
+end
+
+begin
+a
+rescue Exception, CustomException
+b
+end
+
+begin
+ a
+rescue Exception, CustomException => ex
+ b
+end
+
+begin
+ a
+rescue Exception => ex
+ b
+end
+
diff --git a/test/prism/fixtures/blocks.txt b/test/prism/fixtures/blocks.txt
new file mode 100644
index 0000000000..e33d95c150
--- /dev/null
+++ b/test/prism/fixtures/blocks.txt
@@ -0,0 +1,54 @@
+foo[bar] { baz }
+
+foo[bar] do
+baz
+end
+
+x.reduce(0) { |x, memo| memo += x }
+
+foo do end
+
+foo bar, (baz do end)
+
+foo bar do end
+
+foo bar baz do end
+
+foo do |a = b[1]|
+end
+
+foo do
+rescue
+end
+
+foo do
+ bar do
+ baz do
+ end
+ end
+end
+
+foo[bar] { baz }
+
+foo { |x, y = 2, z:| x }
+
+foo { |x| }
+
+fork = 1
+fork do |a|
+end
+
+fork { |a| }
+
+C do
+end
+
+C {}
+
+foo lambda { |
+ a: 1,
+ b: 2
+ |
+}
+
+foo do |bar,| end
diff --git a/test/prism/fixtures/boolean_operators.txt b/test/prism/fixtures/boolean_operators.txt
new file mode 100644
index 0000000000..dd0b9c9f01
--- /dev/null
+++ b/test/prism/fixtures/boolean_operators.txt
@@ -0,0 +1,5 @@
+a &&= b
+
+a += b
+
+a ||= b
diff --git a/test/prism/fixtures/booleans.txt b/test/prism/fixtures/booleans.txt
new file mode 100644
index 0000000000..d9417254b6
--- /dev/null
+++ b/test/prism/fixtures/booleans.txt
@@ -0,0 +1,3 @@
+false
+
+true
diff --git a/test/prism/fixtures/break.txt b/test/prism/fixtures/break.txt
new file mode 100644
index 0000000000..82fa45bdb4
--- /dev/null
+++ b/test/prism/fixtures/break.txt
@@ -0,0 +1,25 @@
+tap { break }
+
+tap { break (1), (2), (3) }
+
+tap { break 1 }
+
+tap { break 1, 2,
+3 }
+
+tap { break 1, 2, 3 }
+
+tap { break [1, 2, 3] }
+
+tap { break(
+ 1
+ 2
+) }
+
+tap { break() }
+
+tap { break(1) }
+
+foo { break 42 } == 42
+
+foo { |a| break } == 42
diff --git a/test/prism/fixtures/case.txt b/test/prism/fixtures/case.txt
new file mode 100644
index 0000000000..733e1e54d2
--- /dev/null
+++ b/test/prism/fixtures/case.txt
@@ -0,0 +1,55 @@
+case :hi
+when :hi
+end
+
+case true; when true; puts :hi; when false; puts :bye; end
+
+case; when *foo; end
+
+case :hi
+when :hi
+else
+:b
+end
+
+case this; when FooBar, BazBonk; end
+
+case
+when foo == bar
+end
+
+case
+when a
+else
+ # empty
+end
+
+case type;
+ ;when :b;
+ ; else;
+ end
+
+case ;;;;;;;; when 1; end
+
+case 1 in 2
+when 3
+end
+
+case 1 in 2; when 3; end
+
+case 1 in 2
+in 3
+end
+
+case 1 in 2; in 3; end
+
+case a
+in b if c and d
+ e
+end
+
+1.then do
+ case 1
+ in ^_1
+ end
+end
diff --git a/test/prism/fixtures/classes.txt b/test/prism/fixtures/classes.txt
new file mode 100644
index 0000000000..056cb00e82
--- /dev/null
+++ b/test/prism/fixtures/classes.txt
@@ -0,0 +1,35 @@
+class A a = 1 end
+
+class A; ensure; end
+
+class A; rescue; else; ensure; end
+
+class A < B
+a = 1
+end
+
+class << not foo
+end
+
+class A; class << self; ensure; end; end
+
+class A; class << self; rescue; else; ensure; end; end
+
+class << foo.bar
+end
+
+class << foo.bar;end
+
+class << self
+end
+
+class << self;end
+
+class << self
+1 + 2
+end
+
+class << self;1 + 2;end
+
+class A < B[1]
+end
diff --git a/test/prism/fixtures/command_method_call.txt b/test/prism/fixtures/command_method_call.txt
new file mode 100644
index 0000000000..182b87948b
--- /dev/null
+++ b/test/prism/fixtures/command_method_call.txt
@@ -0,0 +1,41 @@
+foo 1
+
+foo bar 1
+
+foo 1 if bar 2
+
+foo 1 unless bar 2
+
+foo 1 while bar 2
+
+foo 1 until bar 2
+
+foo 1 rescue bar 2
+
+foo[bar 1]
+
+foo 1 and bar 2
+
+foo 1 or bar 2
+
+not foo 1
+
+foo = bar = baz 1
+
+def foo = bar 1
+
+1.foo 2
+
+1.foo.bar 2
+
+1.foo[2].bar 3
+
+1.foo(2).bar 3
+
+1.foo(&2).bar 3
+
+!foo 1 and !bar 2
+
+!foo 1 or !bar 2
+
+not !foo 1
diff --git a/test/prism/fixtures/comments.txt b/test/prism/fixtures/comments.txt
new file mode 100644
index 0000000000..9bd853e927
--- /dev/null
+++ b/test/prism/fixtures/comments.txt
@@ -0,0 +1,24 @@
+a
+ # Comment
+b
+
+c # Comment
+d
+
+e
+# Comment
+ .f
+
+g
+ # Comment
+.h
+
+i # Comment
+.j
+
+k # Comment
+ .l
+
+m
+ # Comment
+ &.n
diff --git a/test/prism/fixtures/constants.txt b/test/prism/fixtures/constants.txt
new file mode 100644
index 0000000000..d86f8d3402
--- /dev/null
+++ b/test/prism/fixtures/constants.txt
@@ -0,0 +1,184 @@
+A::B
+
+A::B::C
+
+a::B
+
+A::B = 1
+
+A = 1
+
+ABC
+
+Foo 1
+
+Foo *bar
+
+Foo **bar
+
+Foo &bar
+
+Foo::Bar *baz
+
+Foo::Bar **baz
+
+Foo::Bar &baz
+
+::A::foo
+
+::A = 1
+
+::A::B = 1
+
+::A::B
+
+::A
+
+A::false
+
+A::B::true
+
+A::&
+
+A::`
+
+A::!
+
+A::!=
+
+A::^
+
+A::==
+
+A::===
+
+A::=~
+
+A::>
+
+A::>=
+
+A::>>
+
+A::<<
+
+A::\
+#
+C
+
+A::alias
+
+A::and
+
+A::begin
+
+A::BEGIN
+
+A::break
+
+A::class
+
+A::def
+
+A::defined
+
+A::do
+
+A::else
+
+A::elsif
+
+A::end
+
+A::END
+
+A::ensure
+
+A::false
+
+A::for
+
+A::if
+
+A::in
+
+A::next
+
+A::nil
+
+A::not
+
+A::or
+
+A::redo
+
+A::rescue
+
+A::retry
+
+A::return
+
+A::self
+
+A::super
+
+A::then
+
+A::true
+
+A::undef
+
+A::unless
+
+A::until
+
+A::when
+
+A::while
+
+A::yield
+
+A::__ENCODING__
+
+A::__FILE__
+
+A::__LINE__
+
+A::<
+
+A::<=>
+
+A::<<
+
+A::-
+
+A::%
+
+A::%i
+
+A::%w
+
+A::%x
+
+A::%I
+
+A::%W
+
+A::|
+
+A::+
+
+A::/
+
+A::*
+
+A::**
+
+A::~
+
+A::_::
+C
+
+A::_..
+
+A::__END__
diff --git a/test/prism/fixtures/dash_heredocs.txt b/test/prism/fixtures/dash_heredocs.txt
new file mode 100644
index 0000000000..3e663fae63
--- /dev/null
+++ b/test/prism/fixtures/dash_heredocs.txt
@@ -0,0 +1,63 @@
+<<-EOF
+ a
+EOF
+
+<<-FIRST + <<-SECOND
+ a
+FIRST
+ b
+SECOND
+
+<<-`EOF`
+ a
+#{b}
+EOF
+
+<<-EOF #comment
+ a
+EOF
+
+<<-EOF
+ a
+ b
+ EOF
+
+<<-"EOF"
+ a
+#{b}
+EOF
+
+<<-EOF
+ a
+#{b}
+EOF
+
+%#abc#
+
+<<-EOF
+ a
+ b
+EOF
+
+<<-''
+
+
+<<-'EOF'
+ a #{1}
+EOF
+
+<<-A + <<-B
+ a
+A
+ b
+ #{2
+ }
+B
+
+<<-A + <<-B
+ a
+A
+ b
+ #{
+ 2}
+B
diff --git a/test/prism/fixtures/defined.txt b/test/prism/fixtures/defined.txt
new file mode 100644
index 0000000000..247fa94e3a
--- /dev/null
+++ b/test/prism/fixtures/defined.txt
@@ -0,0 +1,10 @@
+defined? 1 and defined? 2
+
+defined?(x %= 2)
+
+defined?(foo and bar)
+
+defined? 1
+
+defined?("foo"
+)
diff --git a/test/prism/fixtures/dos_endings.txt b/test/prism/fixtures/dos_endings.txt
new file mode 100644
index 0000000000..c105522fa1
--- /dev/null
+++ b/test/prism/fixtures/dos_endings.txt
@@ -0,0 +1,20 @@
+puts "hi"\
+ "there"
+
+%I{a\
+b}
+
+<<-E
+ 1 \
+ 2
+ 3
+E
+
+x = %
+
+
+
+a = foo(<<~EOF.chop)
+
+ baz
+ EOF
diff --git a/test/prism/fixtures/dstring.txt b/test/prism/fixtures/dstring.txt
new file mode 100644
index 0000000000..085e0c6852
--- /dev/null
+++ b/test/prism/fixtures/dstring.txt
@@ -0,0 +1,29 @@
+"foo
+ bar"
+
+"foo
+ #{bar}"
+
+"fo
+o" "ba
+r"
+
+"
+foo\
+"
+
+"
+foo\\
+"
+
+"
+foo\\\
+"
+
+"
+foo\\\\
+"
+
+"
+foo\\\\\
+"
diff --git a/test/prism/fixtures/dsym_str.txt b/test/prism/fixtures/dsym_str.txt
new file mode 100644
index 0000000000..ee68dde88d
--- /dev/null
+++ b/test/prism/fixtures/dsym_str.txt
@@ -0,0 +1,2 @@
+:"foo
+ bar"
diff --git a/test/prism/fixtures/embdoc_no_newline_at_end.txt b/test/prism/fixtures/embdoc_no_newline_at_end.txt
new file mode 100644
index 0000000000..7dc2e32d73
--- /dev/null
+++ b/test/prism/fixtures/embdoc_no_newline_at_end.txt
@@ -0,0 +1,2 @@
+=begin
+=end \ No newline at end of file
diff --git a/test/prism/fixtures/emoji_method_calls.txt b/test/prism/fixtures/emoji_method_calls.txt
new file mode 100644
index 0000000000..96d0daba33
--- /dev/null
+++ b/test/prism/fixtures/emoji_method_calls.txt
@@ -0,0 +1 @@
+foo.🌊 = 1
diff --git a/test/prism/fixtures/endless_methods.txt b/test/prism/fixtures/endless_methods.txt
new file mode 100644
index 0000000000..8c2f2a30cc
--- /dev/null
+++ b/test/prism/fixtures/endless_methods.txt
@@ -0,0 +1,5 @@
+def foo = 1
+
+def bar = A ""
+
+def method = 1 + 2 + 3
diff --git a/test/prism/fixtures/endless_range_in_conditional.txt b/test/prism/fixtures/endless_range_in_conditional.txt
new file mode 100644
index 0000000000..6048008584
--- /dev/null
+++ b/test/prism/fixtures/endless_range_in_conditional.txt
@@ -0,0 +1,3 @@
+if 1..2 ; end
+if ..1 ; end
+if 1.. ; end
diff --git a/test/prism/fixtures/for.txt b/test/prism/fixtures/for.txt
new file mode 100644
index 0000000000..b6eb2cb24f
--- /dev/null
+++ b/test/prism/fixtures/for.txt
@@ -0,0 +1,19 @@
+for i in 1..10
+i
+end
+
+for i in 1..10; i; end
+
+for i,j in 1..10
+i
+end
+
+for i,j,k in 1..10
+i
+end
+
+for i in 1..10 do
+i
+end
+
+for i in 1..10; i; end
diff --git a/test/prism/fixtures/global_variables.txt b/test/prism/fixtures/global_variables.txt
new file mode 100644
index 0000000000..3dc52722a0
--- /dev/null
+++ b/test/prism/fixtures/global_variables.txt
@@ -0,0 +1,93 @@
+$global_variable
+
+$_
+
+$-w
+
+$LOAD_PATH
+
+$stdin
+
+$stdout
+
+$stderr
+
+$!
+
+$?
+
+$~
+
+$&
+
+$`
+
+$'
+
+$+
+
+$:
+
+$;
+
+$,
+
+$DEBUG
+
+$FILENAME
+
+$0
+
+$-0
+
+$LOADED_FEATURES
+
+$VERBOSE
+
+$-K
+
+:$global_variable
+
+:$_
+
+:$-w
+
+:$LOAD_PATH
+
+:$stdin
+
+:$stdout
+
+:$stderr
+
+:$!
+
+:$?
+
+:$~
+
+:$&
+
+:$`
+
+:$'
+
+:$+
+
+:$:
+
+:$;
+
+:$DEBUG
+
+:$FILENAME
+
+:$0
+
+:$-0
+
+:$LOADED_FEATURES
+
+:$VERBOSE
+
+:$-K
diff --git a/test/prism/fixtures/hashes.txt b/test/prism/fixtures/hashes.txt
new file mode 100644
index 0000000000..0afb8db496
--- /dev/null
+++ b/test/prism/fixtures/hashes.txt
@@ -0,0 +1,28 @@
+{}
+
+{
+}
+
+{ a => b, c => d }
+
+{ a => b, **c }
+
+{
+ a: b,
+ c: d
+
+
+
+ }
+
+{ a: b, c: d, **e, f: g }
+
+{ "a": !b? }
+
+a = 1
+tap do
+ b = 1
+ { a:, b:, c:, D: }
+end
+
+{ a: -1 }
diff --git a/test/prism/fixtures/heredoc.txt b/test/prism/fixtures/heredoc.txt
new file mode 100644
index 0000000000..f94fd912df
--- /dev/null
+++ b/test/prism/fixtures/heredoc.txt
@@ -0,0 +1,2 @@
+<<TEXT
+TEXT
diff --git a/test/prism/fixtures/heredoc_with_carriage_returns.txt b/test/prism/fixtures/heredoc_with_carriage_returns.txt
new file mode 100644
index 0000000000..32a2d87b24
--- /dev/null
+++ b/test/prism/fixtures/heredoc_with_carriage_returns.txt
@@ -0,0 +1,2 @@
+<<TEXT
+TEXT
diff --git a/test/prism/fixtures/heredoc_with_comment.txt b/test/prism/fixtures/heredoc_with_comment.txt
new file mode 100644
index 0000000000..8e7b7275bd
--- /dev/null
+++ b/test/prism/fixtures/heredoc_with_comment.txt
@@ -0,0 +1,3 @@
+<<-TARGET.chomp # the heredoc end token doesn't always precede the comment
+ content makes for an obvious error
+TARGET \ No newline at end of file
diff --git a/test/prism/fixtures/heredoc_with_escaped_newline_at_start.txt b/test/prism/fixtures/heredoc_with_escaped_newline_at_start.txt
new file mode 100644
index 0000000000..81f314e0b3
--- /dev/null
+++ b/test/prism/fixtures/heredoc_with_escaped_newline_at_start.txt
@@ -0,0 +1,7 @@
+<<-TARGET.gsub /^\s{/, ''\
+TARGET
+
+
+<<-TARGET.gsub /^\s{/, ''\
+TARGET
+
diff --git a/test/prism/fixtures/heredoc_with_trailing_newline.txt b/test/prism/fixtures/heredoc_with_trailing_newline.txt
new file mode 100644
index 0000000000..13771bf3ac
--- /dev/null
+++ b/test/prism/fixtures/heredoc_with_trailing_newline.txt
@@ -0,0 +1,2 @@
+<<-END
+END \ No newline at end of file
diff --git a/test/prism/fixtures/heredocs_leading_whitespace.txt b/test/prism/fixtures/heredocs_leading_whitespace.txt
new file mode 100644
index 0000000000..660ecb4543
--- /dev/null
+++ b/test/prism/fixtures/heredocs_leading_whitespace.txt
@@ -0,0 +1,29 @@
+<<-' FOO'
+a
+b
+ FOO
+
+<<-" FOO"
+a
+b
+ FOO
+
+<<-` FOO`
+a
+b
+ FOO
+
+<<-' FOO'
+a
+b
+ FOO
+
+<<~' FOO'
+a
+b
+ FOO
+
+<<~' FOO'
+a
+b
+ FOO
diff --git a/test/prism/fixtures/heredocs_nested.txt b/test/prism/fixtures/heredocs_nested.txt
new file mode 100644
index 0000000000..0802378278
--- /dev/null
+++ b/test/prism/fixtures/heredocs_nested.txt
@@ -0,0 +1,22 @@
+<<~RUBY
+pre
+#{
+<<RUBY
+ hello
+RUBY
+}
+post
+RUBY
+
+# depth greater than PM_LEX_STACK_SIZE
+<<-A
+#{
+<<-B
+#{
+<<-C
+#{3}
+C
+}
+B
+}
+A
diff --git a/test/prism/fixtures/heredocs_with_ignored_newlines.txt b/test/prism/fixtures/heredocs_with_ignored_newlines.txt
new file mode 100644
index 0000000000..8e12546ec7
--- /dev/null
+++ b/test/prism/fixtures/heredocs_with_ignored_newlines.txt
@@ -0,0 +1,14 @@
+<<-HERE\
+HERE
+
+<<~THERE\
+ way over
+ <<HERE
+ not here
+ HERE
+
+ <<~BUT\
+ but
+ BUT
+ there
+THERE
diff --git a/test/prism/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt b/test/prism/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt
new file mode 100644
index 0000000000..aeacbd8126
--- /dev/null
+++ b/test/prism/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt
@@ -0,0 +1,4 @@
+<<-EOE
+ some
+ heredocs
+EOE \ No newline at end of file
diff --git a/test/prism/fixtures/if.txt b/test/prism/fixtures/if.txt
new file mode 100644
index 0000000000..4139bae5ed
--- /dev/null
+++ b/test/prism/fixtures/if.txt
@@ -0,0 +1,42 @@
+if true; 1; end
+
+if true
+1 else 2 end
+
+if true then true elsif false then false elsif nil then nil else self end
+
+1 if true
+
+tap { break if true }
+
+tap { next if true }
+
+return if true
+
+tap { if exit_loop then break 42 end }
+
+if foo
+then bar
+end
+
+a if b if c
+
+if true
+ a b:
+else
+end
+
+if type in 1
+elsif type in B
+end
+
+if f1
+ lambda do |_|
+ end
+elsif f2
+ lambda do |_|
+ end
+else
+ lambda do |_|
+ end
+end
diff --git a/test/prism/fixtures/indented_file_end.txt b/test/prism/fixtures/indented_file_end.txt
new file mode 100644
index 0000000000..5a96dcacf7
--- /dev/null
+++ b/test/prism/fixtures/indented_file_end.txt
@@ -0,0 +1,4 @@
+ def hi
+
+ end # hi there
+ \ No newline at end of file
diff --git a/test/prism/fixtures/integer_operations.txt b/test/prism/fixtures/integer_operations.txt
new file mode 100644
index 0000000000..37163acf30
--- /dev/null
+++ b/test/prism/fixtures/integer_operations.txt
@@ -0,0 +1,63 @@
+!1
+
+~1
+
+1 != 2
+
+1 !~ 2
+
+1 % 2
+
+1 & 2
+
+1 * 2
+
+1**2
+
+1 + 2
+
+1 - 2
+
+1 / 2
+
+1/2/3
+
+1 < 2
+
+1 << 2
+
+1 <= 2
+
+1 <=> 2
+
+1 == 2
+
+1 === 2
+
+1 =~ 2
+
+1 > 2
+
+1 >= 2
+
+1 >> 2
+
+1 ^ 2
+
+1 | 2
+
+1 && 2
+
+1 and 2
+
+1 * 2 ** 3
+
+1 * 2 + 3
+
+1 or 2
+
+1 || 2
+
+1 + 2 * 3
+
+(1 + 1)
diff --git a/test/prism/fixtures/keyword_method_names.txt b/test/prism/fixtures/keyword_method_names.txt
new file mode 100644
index 0000000000..9154469441
--- /dev/null
+++ b/test/prism/fixtures/keyword_method_names.txt
@@ -0,0 +1,29 @@
+def def
+end
+
+def self.ensure
+end
+
+private def foo
+ bar do
+ end
+end
+
+def m(a, **nil)
+end
+
+def __ENCODING__.a
+end
+
+%{abc}
+
+%"abc"
+
+def __FILE__.a
+end
+
+def __LINE__.a
+end
+
+def nil::a
+end
diff --git a/test/prism/fixtures/keywords.txt b/test/prism/fixtures/keywords.txt
new file mode 100644
index 0000000000..6d24a9f476
--- /dev/null
+++ b/test/prism/fixtures/keywords.txt
@@ -0,0 +1,11 @@
+tap { redo }
+
+begin; rescue; retry; end
+
+self
+
+__ENCODING__
+
+__FILE__
+
+__LINE__
diff --git a/test/prism/fixtures/lambda.txt b/test/prism/fixtures/lambda.txt
new file mode 100644
index 0000000000..5c21eafb24
--- /dev/null
+++ b/test/prism/fixtures/lambda.txt
@@ -0,0 +1,11 @@
+->(
+ foo
+) {}
+
+->(x: "b#{a}") { }
+
+->(a: b * 3) {}
+
+-> foo = bar do end
+
+-> foo: bar do end
diff --git a/test/prism/fixtures/method_calls.txt b/test/prism/fixtures/method_calls.txt
new file mode 100644
index 0000000000..987fb3f90f
--- /dev/null
+++ b/test/prism/fixtures/method_calls.txt
@@ -0,0 +1,156 @@
+foo.bar %{baz}
+
+a.b(c, d)
+
+a.b()
+
+foo
+ .bar
+ &.baz
+
+a!
+
+a.()
+
+a.(1, 2, 3)
+
+a::b
+
+a::b c
+
+foo.bar = 1
+
+a?
+
+a(&block)
+
+a(**kwargs)
+
+a.b.c
+
+a(b, c)
+
+a()
+
+a(*args)
+
+a b, c
+
+a.b c, d
+
+foo.foo, bar.bar = 1, 2
+
+a&.b
+
+a&.()
+
+a&.b(c)
+
+a&.b()
+
+foo :a, :b if bar? or baz and qux
+
+foo(:a,
+
+ :b
+)
+
+foo(*rest)
+
+foo(:a, :h => [:x, :y], :a => :b, &:bar)
+
+hi 123, { :there => :friend, **{}, whatup: :dog }
+
+foo :a, b: true do |a, b| puts a end
+
+hi there: :friend
+
+hi :there => :friend, **{}, whatup: :dog
+
+hi(:there => :friend, **{}, whatup: :dog)
+
+foo({ a: true, b: false, }, &:block)
+
+hi :there => :friend
+
+foo(:a,
+:b,
+)
+
+foo(
+:a,
+b: :c,
+)
+
+foo &:block
+
+foo a: true, b: false, &:block
+
+some_func 1, kwarg: 2
+
+Kernel.Integer(10)
+
+x.each { }
+
+foo.map { $& }
+
+A::B::C :foo
+
+A::B::C(:foo)
+
+A::B::C(:foo) { }
+
+foo("a": -1)
+
+foo bar: { baz: qux do end }
+
+foo bar: { **kw do end }
+
+foo "#{bar.map do "baz" end}" do end
+
+foo class Bar baz do end end
+
+foo module Bar baz do end end
+
+foo [baz do end]
+
+p begin 1.times do 1 end end
+
+foo :a,
+ if x
+ bar do |a|
+ a
+ end
+ end
+
+foo :a,
+ while x
+ bar do |a|
+ a
+ end
+ end,
+ until x
+ baz do
+ end
+ end
+
+{} + A {}
+
+{} + A { |a| a }
+
+A {} + A {}
+
+lst << A {}
+
+"#{ join (" ") }"
+
+"#{(v)}"
+
+def f(*); p *; end
+
+foo 1, Bar { 1 }
+
+foo = 1
+foo {}
+
+@a.b "c#{name}": 42
diff --git a/test/prism/fixtures/methods.txt b/test/prism/fixtures/methods.txt
new file mode 100644
index 0000000000..4bfd976eda
--- /dev/null
+++ b/test/prism/fixtures/methods.txt
@@ -0,0 +1,183 @@
+def foo((bar, baz))
+end
+
+def foo((bar, baz), optional = 1, (bin, bag))
+end
+
+
+def a; ensure; end
+
+def (b).a
+end
+
+def (a)::b
+end
+
+def false.a
+end
+
+def a(...)
+end
+
+def $var.a
+end
+
+def a.b
+end
+
+def @var.a
+end
+
+def a b:; end
+
+%,abc,
+
+def a(b:)
+end
+
+def a(**b)
+end
+
+def a(**)
+end
+
+a = 1; def a
+end
+
+def a b, c, d
+end
+
+def nil.a
+end
+
+def a b:, c: 1
+end
+
+def a(b:, c: 1)
+end
+
+def a(b:
+ 1, c:)
+end
+
+%.abc.
+
+def a b = 1, c = 2
+end
+
+def a()
+end
+
+def a b, c = 2
+end
+
+def a b
+end
+
+def a; rescue; else; ensure; end
+
+def a *b
+end
+
+def a(*)
+end
+
+def a
+b = 1
+end
+
+def self.a
+end
+
+def true.a
+end
+
+def a
+end
+
+def hi
+return :hi if true
+:bye
+end
+
+def foo = 1
+def bar = 2
+
+def foo(bar) = 123
+
+def foo = 123
+
+def a(*); b(*); end
+
+def a(...); b(...); end
+
+def a(...); b(1, 2, ...); end
+
+def (c = b).a
+end
+
+def a &b
+end
+
+def a(&)
+end
+
+def @@var.a
+end
+
+def (a = b).C
+end
+
+def self.Array_function; end
+
+Const = 1; def Const.a
+end
+
+def a(...); "foo#{b(...)}"; end
+
+def foo
+ {}.merge **bar, **baz, **qux
+end
+
+def bar(a: (1...10))
+end
+
+def bar(a: (...10))
+end
+
+def bar(a: (1...))
+end
+
+def bar(a = (1...10))
+end
+
+def bar(a = (...10))
+end
+
+def bar(a = (1...))
+end
+
+def method(a)
+ item >> a {}
+end
+
+foo = 1
+def foo.bar; end
+
+def f(*); [*]; end
+
+def f x:-a; end
+
+def f x:+a; end
+
+def f x:!a; end
+
+def foo x:%(xx); end
+
+def foo(...)
+ bar(...)
+end
+
+def foo(bar = (def baz(bar) = bar; 1)) = 2
+
+def (class Foo; end).foo(bar = 1) = 2
diff --git a/test/prism/fixtures/modules.txt b/test/prism/fixtures/modules.txt
new file mode 100644
index 0000000000..76bd9bea43
--- /dev/null
+++ b/test/prism/fixtures/modules.txt
@@ -0,0 +1,18 @@
+module A a = 1 end
+
+%Q{aaa #{bbb} ccc}
+
+module m::M
+end
+
+module A
+ x = 1; rescue; end
+
+module ::A
+end
+
+module A[]::B
+end
+
+module A[1]::B
+end
diff --git a/test/prism/fixtures/multi_write.txt b/test/prism/fixtures/multi_write.txt
new file mode 100644
index 0000000000..edbcafb969
--- /dev/null
+++ b/test/prism/fixtures/multi_write.txt
@@ -0,0 +1,4 @@
+foo = 1 rescue nil
+foo, bar = 1 rescue nil
+foo = 1, 2 rescue nil
+foo, bar = 1, 2 rescue nil
diff --git a/test/prism/fixtures/newline_terminated.txt b/test/prism/fixtures/newline_terminated.txt
new file mode 100644
index 0000000000..12f3bda229
--- /dev/null
+++ b/test/prism/fixtures/newline_terminated.txt
Binary files differ
diff --git a/test/prism/fixtures/next.txt b/test/prism/fixtures/next.txt
new file mode 100644
index 0000000000..2ef14c6304
--- /dev/null
+++ b/test/prism/fixtures/next.txt
@@ -0,0 +1,24 @@
+tap { next }
+
+tap { next (1), (2), (3) }
+
+tap { next 1 }
+
+tap { next 1, 2,
+3 }
+
+tap { next 1, 2, 3 }
+
+tap { next [1, 2, 3] }
+
+tap { next(
+ 1
+ 2
+) }
+
+tap { next
+1 }
+
+tap { next() }
+
+tap { next(1) }
diff --git a/test/prism/fixtures/nils.txt b/test/prism/fixtures/nils.txt
new file mode 100644
index 0000000000..8084db2534
--- /dev/null
+++ b/test/prism/fixtures/nils.txt
@@ -0,0 +1,13 @@
+nil
+
+()
+
+(
+;
+;
+)
+
+END { 1 }
+
+BEGIN { 1 }
+
diff --git a/test/prism/fixtures/non_alphanumeric_methods.txt b/test/prism/fixtures/non_alphanumeric_methods.txt
new file mode 100644
index 0000000000..1da3fd852b
--- /dev/null
+++ b/test/prism/fixtures/non_alphanumeric_methods.txt
@@ -0,0 +1,105 @@
+def !
+end
+
+def !=
+end
+
+def !~
+end
+
+def %
+end
+
+def self.+
+end
+
+def &
+end
+
+def *
+end
+
+def **
+end
+
+%|abc|
+
+def + **b
+end
+
+def +()
+end
+
+def + b
+end
+
+def self.+
+end
+
+def +
+end
+
+def +@
+end
+
+def -
+end
+
+def a.-;end
+
+def -@
+end
+
+def /
+end
+
+def <
+end
+
+def <<
+end
+
+def <=
+end
+
+def <=>
+end
+
+def ==
+end
+
+def ===
+end
+
+def =~
+end
+
+def >
+end
+
+def >=
+end
+
+def >>
+end
+
+def []
+end
+
+def []=
+end
+
+def ^
+end
+
+def `
+end
+
+def self.`
+end
+
+def |
+end
+
+def ~
+end
diff --git a/test/prism/fixtures/not.txt b/test/prism/fixtures/not.txt
new file mode 100644
index 0000000000..520b34fa37
--- /dev/null
+++ b/test/prism/fixtures/not.txt
@@ -0,0 +1,37 @@
+not foo and not bar
+
+not(foo and bar)
+
+not foo
+
+not foo and not
+ bar
+
+
+not foo and
+ not
+ bar
+
+
+not foo and
+ not
+
+
+ bar
+
+not(foo
+
+
+)
+
+not(
+
+
+foo
+
+
+ )
+
+not foo .. bar
+
+not (foo .. bar)
diff --git a/test/prism/fixtures/numbers.txt b/test/prism/fixtures/numbers.txt
new file mode 100644
index 0000000000..47f20dcb42
--- /dev/null
+++ b/test/prism/fixtures/numbers.txt
@@ -0,0 +1,67 @@
+0
+
+1
+
+1.0
+
+2
+
+0b0
+
+0b1
+
+0b10
+
+0d0
+
+0d1
+
+0d2
+
+00
+
+01
+
+02
+
+0o0
+
+0o1
+
+0o2
+
+0x0
+
+0x1
+
+0x2
+
+1i
+
+1r
+
+-1
+
+1ri
+
+1.2r
+
+1.2ri
+
+-1ri
+
+-1.2r
+
+-1.2ri
+
+0o1r
+
+0o1i
+
+0o1ri
+
+0d1r
+
+0d1i
+
+0b1ri
diff --git a/test/prism/fixtures/patterns.txt b/test/prism/fixtures/patterns.txt
new file mode 100644
index 0000000000..7ce3b9e4a8
--- /dev/null
+++ b/test/prism/fixtures/patterns.txt
@@ -0,0 +1,217 @@
+foo => bar
+foo => 1
+foo => 1.0
+foo => 1i
+foo => 1r
+foo => :foo
+foo => %s[foo]
+foo => :"foo"
+foo => /foo/
+foo => `foo`
+foo => %x[foo]
+foo => %i[foo]
+foo => %I[foo]
+foo => %w[foo]
+foo => %W[foo]
+foo => %q[foo]
+foo => %Q[foo]
+foo => "foo"
+foo => nil
+foo => self
+foo => true
+foo => false
+foo => __FILE__
+foo => __LINE__
+foo => __ENCODING__
+foo => -> { bar }
+
+foo => 1 .. 1
+foo => 1.0 .. 1.0
+foo => 1i .. 1i
+foo => 1r .. 1r
+foo => :foo .. :foo
+foo => %s[foo] .. %s[foo]
+foo => :"foo" .. :"foo"
+foo => /foo/ .. /foo/
+foo => `foo` .. `foo`
+foo => %x[foo] .. %x[foo]
+foo => %i[foo] .. %i[foo]
+foo => %I[foo] .. %I[foo]
+foo => %w[foo] .. %w[foo]
+foo => %W[foo] .. %W[foo]
+foo => %q[foo] .. %q[foo]
+foo => %Q[foo] .. %Q[foo]
+foo => "foo" .. "foo"
+foo => nil .. nil
+foo => self .. self
+foo => true .. true
+foo => false .. false
+foo => __FILE__ .. __FILE__
+foo => __LINE__ .. __LINE__
+foo => __ENCODING__ .. __ENCODING__
+foo => -> { bar } .. -> { bar }
+
+bar = 1; foo => ^bar
+foo => ^@bar
+foo => ^@@bar
+foo => ^$bar
+
+foo => ^(1)
+foo => ^(nil)
+foo => ^("bar" + "baz")
+
+foo => Foo
+foo => Foo::Bar::Baz
+foo => ::Foo
+foo => ::Foo::Bar::Baz
+
+foo => Foo()
+foo => Foo(1)
+foo => Foo(1, 2, 3)
+foo => Foo(bar)
+foo => Foo(*bar, baz)
+foo => Foo(bar, *baz)
+foo => Foo(*bar, baz, *qux)
+
+foo => Foo[]
+foo => Foo[1]
+foo => Foo[1, 2, 3]
+foo => Foo[Foo[]]
+foo => Foo[bar]
+foo => Foo[*bar, baz]
+foo => Foo[bar, *baz]
+foo => Foo[*bar, baz, *qux]
+
+foo => *bar
+foo => *bar, baz, qux
+foo => bar, *baz, qux
+foo => bar, baz, *qux
+foo => *bar, baz, *qux
+
+foo => bar,
+
+; # end the previous pattern for ParseTest#test_filepath_patterns.txt which parses the whole file at once
+
+foo => []
+foo => [[[[[]]]]]
+
+foo => [*bar]
+foo => [*bar, baz, qux]
+foo => [bar, *baz, qux]
+foo => [bar, baz, *qux]
+foo => [*bar, baz, *qux]
+
+foo in bar
+foo in 1
+foo in 1.0
+foo in 1i
+foo in 1r
+foo in :foo
+foo in %s[foo]
+foo in :"foo"
+foo in /foo/
+foo in `foo`
+foo in %x[foo]
+foo in %i[foo]
+foo in %I[foo]
+foo in %w[foo]
+foo in %W[foo]
+foo in %q[foo]
+foo in %Q[foo]
+foo in "foo"
+foo in nil
+foo in self
+foo in true
+foo in false
+foo in __FILE__
+foo in __LINE__
+foo in __ENCODING__
+foo in -> { bar }
+
+foo in bar,
+
+; # end the previous pattern for ParseTest#test_filepath_patterns.txt which parses the whole file at once
+
+case foo; in bar then end
+case foo; in 1 then end
+case foo; in 1.0 then end
+case foo; in 1i then end
+case foo; in 1r then end
+case foo; in :foo then end
+case foo; in %s[foo] then end
+case foo; in :"foo" then end
+case foo; in /foo/ then end
+case foo; in `foo` then end
+case foo; in %x[foo] then end
+case foo; in %i[foo] then end
+case foo; in %I[foo] then end
+case foo; in %w[foo] then end
+case foo; in %W[foo] then end
+case foo; in %q[foo] then end
+case foo; in %Q[foo] then end
+case foo; in "foo" then end
+case foo; in nil then end
+case foo; in self then end
+case foo; in true then end
+case foo; in false then end
+case foo; in __FILE__ then end
+case foo; in __LINE__ then end
+case foo; in __ENCODING__ then end
+case foo; in -> { bar } then end
+
+case foo; in bar if baz then end
+case foo; in 1 if baz then end
+case foo; in 1.0 if baz then end
+case foo; in 1i if baz then end
+case foo; in 1r if baz then end
+case foo; in :foo if baz then end
+case foo; in %s[foo] if baz then end
+case foo; in :"foo" if baz then end
+case foo; in /foo/ if baz then end
+case foo; in `foo` if baz then end
+case foo; in %x[foo] if baz then end
+case foo; in %i[foo] if baz then end
+case foo; in %I[foo] if baz then end
+case foo; in %w[foo] if baz then end
+case foo; in %W[foo] if baz then end
+case foo; in %q[foo] if baz then end
+case foo; in %Q[foo] if baz then end
+case foo; in "foo" if baz then end
+case foo; in nil if baz then end
+case foo; in self if baz then end
+case foo; in true if baz then end
+case foo; in false if baz then end
+case foo; in __FILE__ if baz then end
+case foo; in __LINE__ if baz then end
+case foo; in __ENCODING__ if baz then end
+case foo; in -> { bar } if baz then end
+
+if a in []
+end
+
+a => [
+ b
+]
+
+foo in A[
+ bar: B[
+ value: a
+ ]
+]
+
+foo in bar => baz
+foo => bar => baz
+
+foo, bar, baz = 1, 2
+foo do
+ [1, 2] => [foo, bar] => baz
+end
+
+foo => Object[{x:}]
+
+1.then { 1 in ^_1 }
+
+(
+ a,
+ b
+) = c
diff --git a/test/prism/fixtures/procs.txt b/test/prism/fixtures/procs.txt
new file mode 100644
index 0000000000..7ffb11e78a
--- /dev/null
+++ b/test/prism/fixtures/procs.txt
@@ -0,0 +1,27 @@
+-> (a; b, c, d) { b }
+
+-> do
+ensure
+end
+
+-> do
+rescue
+else
+ensure
+end
+
+-> { foo }
+
+-> do; foo; end
+
+-> a, b = 1, c:, d:, &e { a }
+
+-> (a, b = 1, *c, d:, e:, **f, &g) { a }
+
+-> (a, b = 1, *c, d:, e:, **f, &g) do
+ a
+end
+
+-> (a) { -> b { a * b } }
+
+-> ((a, b), *c) { }
diff --git a/test/prism/fixtures/range_begin_open_exclusive.txt b/test/prism/fixtures/range_begin_open_exclusive.txt
new file mode 100644
index 0000000000..3b12672b4f
--- /dev/null
+++ b/test/prism/fixtures/range_begin_open_exclusive.txt
@@ -0,0 +1 @@
+...2
diff --git a/test/prism/fixtures/range_begin_open_inclusive.txt b/test/prism/fixtures/range_begin_open_inclusive.txt
new file mode 100644
index 0000000000..052f45900b
--- /dev/null
+++ b/test/prism/fixtures/range_begin_open_inclusive.txt
@@ -0,0 +1 @@
+..2
diff --git a/test/prism/fixtures/range_end_open_exclusive.txt b/test/prism/fixtures/range_end_open_exclusive.txt
new file mode 100644
index 0000000000..2ffd68afdb
--- /dev/null
+++ b/test/prism/fixtures/range_end_open_exclusive.txt
@@ -0,0 +1 @@
+2...
diff --git a/test/prism/fixtures/range_end_open_inclusive.txt b/test/prism/fixtures/range_end_open_inclusive.txt
new file mode 100644
index 0000000000..48445391f6
--- /dev/null
+++ b/test/prism/fixtures/range_end_open_inclusive.txt
@@ -0,0 +1 @@
+2..
diff --git a/test/prism/fixtures/ranges.txt b/test/prism/fixtures/ranges.txt
new file mode 100644
index 0000000000..e2e4136ae9
--- /dev/null
+++ b/test/prism/fixtures/ranges.txt
@@ -0,0 +1,49 @@
+(...2)
+
+(..2)
+
+1...2
+
+foo[...2]
+
+{ foo: ...bar }
+
+(1...)
+
+1..2
+
+{ foo: ..bar }
+
+(1..)
+
+1 .. ..1
+
+1.. && 2
+
+1.. == 2
+
+1.. != 2
+
+1.. === 2
+
+1.. <=> 2
+
+1.. =~ 2
+
+1.. !~ 2
+
+1.. < 2
+
+1.. > 2
+
+1.. <= 2
+
+1.. >= 2
+
+1.. << 2
+
+1.. >> 2
+
+1.. + 2
+
+1.. - 2
diff --git a/test/prism/fixtures/regex.txt b/test/prism/fixtures/regex.txt
new file mode 100644
index 0000000000..84b5ca0600
--- /dev/null
+++ b/test/prism/fixtures/regex.txt
@@ -0,0 +1,46 @@
+foo /bar/
+
+%r{abc}i
+
+/a\b/
+
+/aaa #$bbb/
+
+/aaa #{bbb} ccc/
+
+[/(?<foo>bar)/ =~ baz, foo]
+
+/abc/i
+
+%r/[a-z$._?][\w$.?#@~]*:/i
+
+%r/([a-z$._?][\w$.?#@~]*)(\s+)(equ)/i
+
+%r/[a-z$._?][\w$.?#@~]*/i
+
+%r(
+(?:[#$%_']|\(\)|\(,\)|\[\]|[0-9])*
+ (?:[#$%_']+)
+)
+
+/(?#\))/ =~ "hi"
+
+%r#pound#
+
+/aaa #{bbb}/o
+
+/(?<a\
+b>)/ =~ ""; ab
+
+/(?<abc>)(?<abc>)/ =~ ""; abc
+
+/(?<a b>)/ =~ ""
+
+a = 1
+tap { /(?<a>)/ =~ to_s }
+
+/(?<foo>)/ =~ ""
+/(?<Foo>)/ =~ ""
+
+/(?<nil>)/ =~ ""
+def foo(nil:) = /(?<nil>)/ =~ ""
diff --git a/test/prism/fixtures/regex_char_width.txt b/test/prism/fixtures/regex_char_width.txt
new file mode 100644
index 0000000000..7096b71584
--- /dev/null
+++ b/test/prism/fixtures/regex_char_width.txt
@@ -0,0 +1,3 @@
+# encoding: sjis
+/Ⅷ(?<a>.)Ⅹ(?<b>.)/ =~ 'ⅧaⅩb'
+[a, b]
diff --git a/test/prism/fixtures/repeat_parameters.txt b/test/prism/fixtures/repeat_parameters.txt
new file mode 100644
index 0000000000..9c69e9718a
--- /dev/null
+++ b/test/prism/fixtures/repeat_parameters.txt
@@ -0,0 +1,38 @@
+def foo(a, _)
+end
+
+def foo(a, _, _)
+end
+
+def foo(a, _, _, _b)
+end
+
+def foo(a, _, _, _b, _b)
+end
+
+def foo(a, (b, *_c, d), (e, *_c, f))
+end
+
+def foo(_a, _a, b, c)
+end
+
+def foo((a, *_b, c), (d, *_b, e))
+end
+
+def foo(_a = 1, _a = 2)
+end
+
+def foo(_a:, _a:)
+end
+
+def foo(_a: 1, _a: 2)
+end
+
+def foo(_a, **_a)
+end
+
+def foo(_a, &_a)
+end
+
+def foo(_a, *_a)
+end
diff --git a/test/prism/fixtures/rescue.txt b/test/prism/fixtures/rescue.txt
new file mode 100644
index 0000000000..99170fbe0f
--- /dev/null
+++ b/test/prism/fixtures/rescue.txt
@@ -0,0 +1,35 @@
+foo rescue nil
+
+foo rescue
+nil
+
+tap { break rescue nil }
+
+tap { next rescue nil }
+
+return rescue nil
+
+foo rescue nil || 1
+
+foo rescue nil ? 1 : 2
+
+begin; a; rescue *b; end
+
+foo do |x|
+ bar(y) rescue ArgumentError fail "baz"
+end
+
+if a = foo rescue nil
+ bar
+end
+
+def some_method = other_method 42 rescue nil
+
+def a
+ a b:
+rescue
+end
+
+foo if bar rescue baz
+
+z = x y rescue c d
diff --git a/test/prism/fixtures/return.txt b/test/prism/fixtures/return.txt
new file mode 100644
index 0000000000..a8b5b95fab
--- /dev/null
+++ b/test/prism/fixtures/return.txt
@@ -0,0 +1,24 @@
+return
+
+return (1), (2), (3)
+
+return *1
+
+return 1
+
+return 1, 2,
+3
+
+return 1, 2, 3
+
+return [1, 2, 3]
+
+return(
+ 1
+ 2
+)
+
+return()
+
+return(1)
+
diff --git a/test/prism/fixtures/seattlerb/BEGIN.txt b/test/prism/fixtures/seattlerb/BEGIN.txt
new file mode 100644
index 0000000000..bed5755901
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/BEGIN.txt
@@ -0,0 +1 @@
+BEGIN { 42 }
diff --git a/test/prism/fixtures/seattlerb/README.rdoc b/test/prism/fixtures/seattlerb/README.rdoc
new file mode 100644
index 0000000000..1e5bfbdfe0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/README.rdoc
@@ -0,0 +1,113 @@
+= ruby_parser
+
+home :: https://github.com/seattlerb/ruby_parser
+bugs :: https://github.com/seattlerb/ruby_parser/issues
+rdoc :: http://docs.seattlerb.org/ruby_parser
+
+== DESCRIPTION:
+
+ruby_parser (RP) is a ruby parser written in pure ruby (utilizing
+racc--which does by default use a C extension). It outputs
+s-expressions which can be manipulated and converted back to ruby via
+the ruby2ruby gem.
+
+As an example:
+
+ def conditional1 arg1
+ return 1 if arg1 == 0
+ return 0
+ end
+
+becomes:
+
+ s(:defn, :conditional1, s(:args, :arg1),
+ s(:if,
+ s(:call, s(:lvar, :arg1), :==, s(:lit, 0)),
+ s(:return, s(:lit, 1)),
+ nil),
+ s(:return, s(:lit, 0)))
+
+Tested against 801,039 files from the latest of all rubygems (as of 2013-05):
+
+* 1.8 parser is at 99.9739% accuracy, 3.651 sigma
+* 1.9 parser is at 99.9940% accuracy, 4.013 sigma
+* 2.0 parser is at 99.9939% accuracy, 4.008 sigma
+* 2.6 parser is at 99.9972% accuracy, 4.191 sigma
+* 3.0 parser has a 100% parse rate.
+ * Tested against 2,672,412 unique ruby files across 167k gems.
+ * As do all the others now, basically.
+
+== FEATURES/PROBLEMS:
+
+* Pure ruby, no compiles.
+* Includes preceding comment data for defn/defs/class/module nodes!
+* Incredibly simple interface.
+* Output is 100% equivalent to ParseTree.
+ * Can utilize PT's SexpProcessor and UnifiedRuby for language processing.
+* Known Issue: Speed is now pretty good, but can always improve:
+ * RP parses a corpus of 3702 files in 125s (avg 108 Kb/s)
+ * MRI+PT parsed the same in 67.38s (avg 200.89 Kb/s)
+* Known Issue: Code is much better, but still has a long way to go.
+* Known Issue: Totally awesome.
+* Known Issue: line number values can be slightly off. Parsing LR sucks.
+
+== SYNOPSIS:
+
+ RubyParser.new.parse "1+1"
+ # => s(:call, s(:lit, 1), :+, s(:lit, 1))
+
+You can also use Ruby19Parser, Ruby18Parser, or RubyParser.for_current_ruby:
+
+ RubyParser.for_current_ruby.parse "1+1"
+ # => s(:call, s(:lit, 1), :+, s(:lit, 1))
+
+== DEVELOPER NOTES:
+
+To add a new version:
+
+* New parser should be generated from lib/ruby_parser[23].yy.
+* Extend lib/ruby_parser[23].yy with new class name.
+* Add new version number to V2/V3 in Rakefile for rule creation.
+* Add new `ruby_parse "x.y.z"` line to Rakefile for rake compare (line ~300).
+* Require generated parser in lib/ruby_parser.rb.
+* Add new V## = ::Ruby##Parser; end to ruby_parser.rb (bottom of file).
+* Add empty TestRubyParserShared##Plus module and TestRubyParserV## to test/test_ruby_parser.rb.
+* Extend Manifest.txt with generated file names.
+* Add new version number to sexp_processor's pt_testcase.rb in all_versions.
+
+Until all of these are done, you won't have a clean test run.
+
+== REQUIREMENTS:
+
+* ruby. woot.
+* sexp_processor for Sexp and SexpProcessor classes, and testing.
+* racc full package for parser development (compiling .y to .rb).
+
+== INSTALL:
+
+* sudo gem install ruby_parser
+
+== LICENSE:
+
+(The MIT License)
+
+Copyright (c) Ryan Davis, seattle.rb
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/test/prism/fixtures/seattlerb/TestRubyParserShared.txt b/test/prism/fixtures/seattlerb/TestRubyParserShared.txt
new file mode 100644
index 0000000000..c55b3e1f70
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/TestRubyParserShared.txt
@@ -0,0 +1,92 @@
+%I[
+
+
+]
+
+%I[
+line2
+line3
+]
+
+%W[
+
+
+]
+
+%W[
+line2
+line3
+]
+
+%i[
+
+
+]
+
+%i[
+line2
+line3
+]
+
+%r[
+
+
+]
+
+%w[
+
+
+]
+
+%w[
+line2
+line3
+]
+
+[
+:line2,
+:line3
+]
+
+class X # line 1
+ def self.y(a, # line 2
+ b) # line 3
+ a + b # line 4
+ end # line 5
+end # line 6
+
+
+class X # line 1
+ class Y # line 2
+ Z = 42 # line 3
+ end # line 4
+end # line 5
+
+
+class X # line 1
+ def y(a, # line 2
+ b) # line 3
+ a + b # line 4
+ end # line 5
+end # line 6
+
+
+module X
+ X = [
+ :line3,
+ :line4,
+ ]
+end
+
+
+module X # line 1
+ module Y # line 2
+ Z = 42 # line 3
+ end # line 4
+end # line 5
+
+
+x(
+:line2,
+:line3
+)
diff --git a/test/prism/fixtures/seattlerb/__ENCODING__.txt b/test/prism/fixtures/seattlerb/__ENCODING__.txt
new file mode 100644
index 0000000000..d6debf2f92
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/__ENCODING__.txt
@@ -0,0 +1 @@
+__ENCODING__
diff --git a/test/prism/fixtures/seattlerb/alias_gvar_backref.txt b/test/prism/fixtures/seattlerb/alias_gvar_backref.txt
new file mode 100644
index 0000000000..016bd94fe0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/alias_gvar_backref.txt
@@ -0,0 +1 @@
+alias $MATCH $&
diff --git a/test/prism/fixtures/seattlerb/alias_resword.txt b/test/prism/fixtures/seattlerb/alias_resword.txt
new file mode 100644
index 0000000000..63e782614b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/alias_resword.txt
@@ -0,0 +1 @@
+alias in out
diff --git a/test/prism/fixtures/seattlerb/and_multi.txt b/test/prism/fixtures/seattlerb/and_multi.txt
new file mode 100644
index 0000000000..8902086cac
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/and_multi.txt
@@ -0,0 +1,3 @@
+true and
+not false and
+true
diff --git a/test/prism/fixtures/seattlerb/aref_args_assocs.txt b/test/prism/fixtures/seattlerb/aref_args_assocs.txt
new file mode 100644
index 0000000000..3244eebafc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/aref_args_assocs.txt
@@ -0,0 +1 @@
+[1 => 2]
diff --git a/test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt b/test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt
new file mode 100644
index 0000000000..0b6ffa7e2c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt
@@ -0,0 +1 @@
+[1, 2 => 3]
diff --git a/test/prism/fixtures/seattlerb/args_kw_block.txt b/test/prism/fixtures/seattlerb/args_kw_block.txt
new file mode 100644
index 0000000000..cb6ab39852
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/args_kw_block.txt
@@ -0,0 +1 @@
+def f(a: 1, &b); end
diff --git a/test/prism/fixtures/seattlerb/array_line_breaks.txt b/test/prism/fixtures/seattlerb/array_line_breaks.txt
new file mode 100644
index 0000000000..be9f2d9cb8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/array_line_breaks.txt
@@ -0,0 +1,4 @@
+[
+'a',
+'b']
+1
diff --git a/test/prism/fixtures/seattlerb/array_lits_trailing_calls.txt b/test/prism/fixtures/seattlerb/array_lits_trailing_calls.txt
new file mode 100644
index 0000000000..868384a407
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/array_lits_trailing_calls.txt
@@ -0,0 +1,3 @@
+%w[].b
+
+[].b
diff --git a/test/prism/fixtures/seattlerb/assoc__bare.txt b/test/prism/fixtures/seattlerb/assoc__bare.txt
new file mode 100644
index 0000000000..96c2940f31
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/assoc__bare.txt
@@ -0,0 +1 @@
+{ y: }
diff --git a/test/prism/fixtures/seattlerb/assoc_label.txt b/test/prism/fixtures/seattlerb/assoc_label.txt
new file mode 100644
index 0000000000..372dc75031
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/assoc_label.txt
@@ -0,0 +1 @@
+a(b:1)
diff --git a/test/prism/fixtures/seattlerb/attr_asgn_colon_id.txt b/test/prism/fixtures/seattlerb/attr_asgn_colon_id.txt
new file mode 100644
index 0000000000..f63c2f5dcb
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/attr_asgn_colon_id.txt
@@ -0,0 +1 @@
+A::b = 1
diff --git a/test/prism/fixtures/seattlerb/attrasgn_array_arg.txt b/test/prism/fixtures/seattlerb/attrasgn_array_arg.txt
new file mode 100644
index 0000000000..db9e2db063
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/attrasgn_array_arg.txt
@@ -0,0 +1 @@
+a[[1, 2]] = 3
diff --git a/test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt b/test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt
new file mode 100644
index 0000000000..0b8e31632d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt
@@ -0,0 +1 @@
+[1, 2, 3, 4][from .. to] = ["a", "b", "c"]
diff --git a/test/prism/fixtures/seattlerb/attrasgn_primary_dot_constant.txt b/test/prism/fixtures/seattlerb/attrasgn_primary_dot_constant.txt
new file mode 100644
index 0000000000..380a718963
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/attrasgn_primary_dot_constant.txt
@@ -0,0 +1 @@
+a.B = 1
diff --git a/test/prism/fixtures/seattlerb/backticks_interpolation_line.txt b/test/prism/fixtures/seattlerb/backticks_interpolation_line.txt
new file mode 100644
index 0000000000..b3ba31c72a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/backticks_interpolation_line.txt
@@ -0,0 +1 @@
+x `#{y}`
diff --git a/test/prism/fixtures/seattlerb/bang_eq.txt b/test/prism/fixtures/seattlerb/bang_eq.txt
new file mode 100644
index 0000000000..0283460e46
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bang_eq.txt
@@ -0,0 +1 @@
+1 != 2
diff --git a/test/prism/fixtures/seattlerb/bdot2.txt b/test/prism/fixtures/seattlerb/bdot2.txt
new file mode 100644
index 0000000000..4fb2692299
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bdot2.txt
@@ -0,0 +1,3 @@
+..10
+; ..a
+; c
diff --git a/test/prism/fixtures/seattlerb/bdot3.txt b/test/prism/fixtures/seattlerb/bdot3.txt
new file mode 100644
index 0000000000..8079cf9872
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bdot3.txt
@@ -0,0 +1,3 @@
+...10
+; ...a
+; c
diff --git a/test/prism/fixtures/seattlerb/begin_ensure_no_bodies.txt b/test/prism/fixtures/seattlerb/begin_ensure_no_bodies.txt
new file mode 100644
index 0000000000..51dde02ea3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/begin_ensure_no_bodies.txt
@@ -0,0 +1,3 @@
+begin
+ensure
+end
diff --git a/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt b/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt
new file mode 100644
index 0000000000..ae6e2c3636
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt
@@ -0,0 +1,9 @@
+begin
+ 1
+rescue
+ 2
+else
+ 3
+ensure
+ 4
+end
diff --git a/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt b/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt
new file mode 100644
index 0000000000..456d9a5d6e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt
@@ -0,0 +1,9 @@
+begin
+
+rescue
+
+else
+
+ensure
+
+end
diff --git a/test/prism/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt b/test/prism/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt
new file mode 100644
index 0000000000..896e3c030a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt
@@ -0,0 +1,4 @@
+begin
+rescue
+ensure
+end
diff --git a/test/prism/fixtures/seattlerb/block_arg__bare.txt b/test/prism/fixtures/seattlerb/block_arg__bare.txt
new file mode 100644
index 0000000000..6454b00345
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg__bare.txt
@@ -0,0 +1 @@
+def x(&); end
diff --git a/test/prism/fixtures/seattlerb/block_arg_kwsplat.txt b/test/prism/fixtures/seattlerb/block_arg_kwsplat.txt
new file mode 100644
index 0000000000..a9c255cc66
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg_kwsplat.txt
@@ -0,0 +1 @@
+a { |**b| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_opt_arg_block.txt b/test/prism/fixtures/seattlerb/block_arg_opt_arg_block.txt
new file mode 100644
index 0000000000..14cb02c68e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg_opt_arg_block.txt
@@ -0,0 +1 @@
+a { |b, c=1, d, &e| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_opt_splat.txt b/test/prism/fixtures/seattlerb/block_arg_opt_splat.txt
new file mode 100644
index 0000000000..a077ae1f34
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg_opt_splat.txt
@@ -0,0 +1 @@
+a { |b, c = 1, *d| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt b/test/prism/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt
new file mode 100644
index 0000000000..5016a7c6b9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt
@@ -0,0 +1 @@
+a { |b, c=1, *d, e, &f| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_optional.txt b/test/prism/fixtures/seattlerb/block_arg_optional.txt
new file mode 100644
index 0000000000..966afc5640
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg_optional.txt
@@ -0,0 +1 @@
+a { |b = 1| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_scope.txt b/test/prism/fixtures/seattlerb/block_arg_scope.txt
new file mode 100644
index 0000000000..2362e08559
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg_scope.txt
@@ -0,0 +1 @@
+a { |b; c| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_scope2.txt b/test/prism/fixtures/seattlerb/block_arg_scope2.txt
new file mode 100644
index 0000000000..f7222dc7b1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg_scope2.txt
@@ -0,0 +1 @@
+a {|b; c, d| }
diff --git a/test/prism/fixtures/seattlerb/block_arg_splat_arg.txt b/test/prism/fixtures/seattlerb/block_arg_splat_arg.txt
new file mode 100644
index 0000000000..d7c31aae6b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_arg_splat_arg.txt
@@ -0,0 +1 @@
+a { |b, *c, d| }
diff --git a/test/prism/fixtures/seattlerb/block_args_kwargs.txt b/test/prism/fixtures/seattlerb/block_args_kwargs.txt
new file mode 100644
index 0000000000..467b577a7e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_args_kwargs.txt
@@ -0,0 +1 @@
+f { |**kwargs| kwargs }
diff --git a/test/prism/fixtures/seattlerb/block_args_no_kwargs.txt b/test/prism/fixtures/seattlerb/block_args_no_kwargs.txt
new file mode 100644
index 0000000000..5c9bfa3a62
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_args_no_kwargs.txt
@@ -0,0 +1 @@
+f { |**nil| }
diff --git a/test/prism/fixtures/seattlerb/block_args_opt1.txt b/test/prism/fixtures/seattlerb/block_args_opt1.txt
new file mode 100644
index 0000000000..372689e36a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_args_opt1.txt
@@ -0,0 +1 @@
+f { |a, b = 42| [a, b] }
diff --git a/test/prism/fixtures/seattlerb/block_args_opt2.txt b/test/prism/fixtures/seattlerb/block_args_opt2.txt
new file mode 100644
index 0000000000..10d0746646
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_args_opt2.txt
@@ -0,0 +1 @@
+a { | b=1, c=2 | }
diff --git a/test/prism/fixtures/seattlerb/block_args_opt2_2.txt b/test/prism/fixtures/seattlerb/block_args_opt2_2.txt
new file mode 100644
index 0000000000..563a9bf915
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_args_opt2_2.txt
@@ -0,0 +1 @@
+f { |a, b = 42, c = 24| [a, b, c] }
diff --git a/test/prism/fixtures/seattlerb/block_args_opt3.txt b/test/prism/fixtures/seattlerb/block_args_opt3.txt
new file mode 100644
index 0000000000..bb5a7c8458
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_args_opt3.txt
@@ -0,0 +1 @@
+f { |a, b = 42, c = 24, &d| [a, b, c, d] }
diff --git a/test/prism/fixtures/seattlerb/block_call_defn_call_block_call.txt b/test/prism/fixtures/seattlerb/block_call_defn_call_block_call.txt
new file mode 100644
index 0000000000..ff1b3a4c9f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_call_defn_call_block_call.txt
@@ -0,0 +1,4 @@
+a def b(c)
+ d
+ end
+ e.f do end
diff --git a/test/prism/fixtures/seattlerb/block_call_dot_op2_brace_block.txt b/test/prism/fixtures/seattlerb/block_call_dot_op2_brace_block.txt
new file mode 100644
index 0000000000..63da9ee7af
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_call_dot_op2_brace_block.txt
@@ -0,0 +1 @@
+a.b c() do d end.e do |f| g end
diff --git a/test/prism/fixtures/seattlerb/block_call_dot_op2_cmd_args_do_block.txt b/test/prism/fixtures/seattlerb/block_call_dot_op2_cmd_args_do_block.txt
new file mode 100644
index 0000000000..24e7d0f1f1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_call_dot_op2_cmd_args_do_block.txt
@@ -0,0 +1 @@
+a.b c() do d end.e f do |g| h end
diff --git a/test/prism/fixtures/seattlerb/block_call_operation_colon.txt b/test/prism/fixtures/seattlerb/block_call_operation_colon.txt
new file mode 100644
index 0000000000..593b9e1bc0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_call_operation_colon.txt
@@ -0,0 +1 @@
+a.b c do end::d
diff --git a/test/prism/fixtures/seattlerb/block_call_operation_dot.txt b/test/prism/fixtures/seattlerb/block_call_operation_dot.txt
new file mode 100644
index 0000000000..20b8e4fcb8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_call_operation_dot.txt
@@ -0,0 +1 @@
+a.b c do end.d
diff --git a/test/prism/fixtures/seattlerb/block_call_paren_call_block_call.txt b/test/prism/fixtures/seattlerb/block_call_paren_call_block_call.txt
new file mode 100644
index 0000000000..7f8be95100
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_call_paren_call_block_call.txt
@@ -0,0 +1,2 @@
+a (b)
+c.d do end
diff --git a/test/prism/fixtures/seattlerb/block_command_operation_colon.txt b/test/prism/fixtures/seattlerb/block_command_operation_colon.txt
new file mode 100644
index 0000000000..db221ad496
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_command_operation_colon.txt
@@ -0,0 +1 @@
+a :b do end::c :d
diff --git a/test/prism/fixtures/seattlerb/block_command_operation_dot.txt b/test/prism/fixtures/seattlerb/block_command_operation_dot.txt
new file mode 100644
index 0000000000..56b71677e8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_command_operation_dot.txt
@@ -0,0 +1 @@
+a :b do end.c :d
diff --git a/test/prism/fixtures/seattlerb/block_decomp_anon_splat_arg.txt b/test/prism/fixtures/seattlerb/block_decomp_anon_splat_arg.txt
new file mode 100644
index 0000000000..96f5d5d2ec
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_decomp_anon_splat_arg.txt
@@ -0,0 +1 @@
+f { |(*, a)| }
diff --git a/test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt b/test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt
new file mode 100644
index 0000000000..f8db3874de
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt
@@ -0,0 +1 @@
+a { |(b, *)| }
diff --git a/test/prism/fixtures/seattlerb/block_decomp_arg_splat_arg.txt b/test/prism/fixtures/seattlerb/block_decomp_arg_splat_arg.txt
new file mode 100644
index 0000000000..e64f4e8c3d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_decomp_arg_splat_arg.txt
@@ -0,0 +1 @@
+f { |(a, *b, c)| }
diff --git a/test/prism/fixtures/seattlerb/block_decomp_splat.txt b/test/prism/fixtures/seattlerb/block_decomp_splat.txt
new file mode 100644
index 0000000000..970f00a626
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_decomp_splat.txt
@@ -0,0 +1 @@
+f { |(*a)| }
diff --git a/test/prism/fixtures/seattlerb/block_kw.txt b/test/prism/fixtures/seattlerb/block_kw.txt
new file mode 100644
index 0000000000..bacfd32e80
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_kw.txt
@@ -0,0 +1 @@
+blah { |k:42| }
diff --git a/test/prism/fixtures/seattlerb/block_kw__required.txt b/test/prism/fixtures/seattlerb/block_kw__required.txt
new file mode 100644
index 0000000000..b84ab97037
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_kw__required.txt
@@ -0,0 +1 @@
+blah do |k:| end
diff --git a/test/prism/fixtures/seattlerb/block_kwarg_lvar.txt b/test/prism/fixtures/seattlerb/block_kwarg_lvar.txt
new file mode 100644
index 0000000000..390b9195e0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_kwarg_lvar.txt
@@ -0,0 +1 @@
+bl { |kw: :val| kw }
diff --git a/test/prism/fixtures/seattlerb/block_kwarg_lvar_multiple.txt b/test/prism/fixtures/seattlerb/block_kwarg_lvar_multiple.txt
new file mode 100644
index 0000000000..df3e4afde8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_kwarg_lvar_multiple.txt
@@ -0,0 +1 @@
+bl { |kw: :val, kw2: :val2 | kw }
diff --git a/test/prism/fixtures/seattlerb/block_opt_arg.txt b/test/prism/fixtures/seattlerb/block_opt_arg.txt
new file mode 100644
index 0000000000..5e312fdf41
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_opt_arg.txt
@@ -0,0 +1 @@
+a { |b=1, c| }
diff --git a/test/prism/fixtures/seattlerb/block_opt_splat.txt b/test/prism/fixtures/seattlerb/block_opt_splat.txt
new file mode 100644
index 0000000000..772a3fc412
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_opt_splat.txt
@@ -0,0 +1 @@
+a { |b = 1, *c| }
diff --git a/test/prism/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt b/test/prism/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt
new file mode 100644
index 0000000000..76466f9d54
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt
@@ -0,0 +1 @@
+a { |b=1, *c, d, &e| }
diff --git a/test/prism/fixtures/seattlerb/block_optarg.txt b/test/prism/fixtures/seattlerb/block_optarg.txt
new file mode 100644
index 0000000000..a471554da1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_optarg.txt
@@ -0,0 +1 @@
+a { |b = :c| }
diff --git a/test/prism/fixtures/seattlerb/block_paren_splat.txt b/test/prism/fixtures/seattlerb/block_paren_splat.txt
new file mode 100644
index 0000000000..3dd4bba1ed
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_paren_splat.txt
@@ -0,0 +1 @@
+a { |(b, *c)| }
diff --git a/test/prism/fixtures/seattlerb/block_reg_optarg.txt b/test/prism/fixtures/seattlerb/block_reg_optarg.txt
new file mode 100644
index 0000000000..c024651f78
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_reg_optarg.txt
@@ -0,0 +1 @@
+a { |b, c = :d| }
diff --git a/test/prism/fixtures/seattlerb/block_return.txt b/test/prism/fixtures/seattlerb/block_return.txt
new file mode 100644
index 0000000000..f30ba71d8f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_return.txt
@@ -0,0 +1 @@
+return foo arg do |bar| end
diff --git a/test/prism/fixtures/seattlerb/block_scope.txt b/test/prism/fixtures/seattlerb/block_scope.txt
new file mode 100644
index 0000000000..7a83d8ab87
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_scope.txt
@@ -0,0 +1 @@
+a { |;b| }
diff --git a/test/prism/fixtures/seattlerb/block_splat_reg.txt b/test/prism/fixtures/seattlerb/block_splat_reg.txt
new file mode 100644
index 0000000000..58f0619e5d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/block_splat_reg.txt
@@ -0,0 +1 @@
+a { |*b, c| }
diff --git a/test/prism/fixtures/seattlerb/bug169.txt b/test/prism/fixtures/seattlerb/bug169.txt
new file mode 100644
index 0000000000..db2e5ace5e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug169.txt
@@ -0,0 +1 @@
+m () {}
diff --git a/test/prism/fixtures/seattlerb/bug179.txt b/test/prism/fixtures/seattlerb/bug179.txt
new file mode 100644
index 0000000000..02ae07a3be
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug179.txt
@@ -0,0 +1 @@
+p ()..nil
diff --git a/test/prism/fixtures/seattlerb/bug190.txt b/test/prism/fixtures/seattlerb/bug190.txt
new file mode 100644
index 0000000000..861b2d305f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug190.txt
@@ -0,0 +1 @@
+%r'\''
diff --git a/test/prism/fixtures/seattlerb/bug191.txt b/test/prism/fixtures/seattlerb/bug191.txt
new file mode 100644
index 0000000000..03f7fd1228
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug191.txt
@@ -0,0 +1,3 @@
+a ? "": b
+
+a ? '': b
diff --git a/test/prism/fixtures/seattlerb/bug202.txt b/test/prism/fixtures/seattlerb/bug202.txt
new file mode 100644
index 0000000000..a3b06ffdfc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug202.txt
@@ -0,0 +1,2 @@
+$测试 = 1
+测试 = 1
diff --git a/test/prism/fixtures/seattlerb/bug236.txt b/test/prism/fixtures/seattlerb/bug236.txt
new file mode 100644
index 0000000000..cefe1eb058
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug236.txt
@@ -0,0 +1,3 @@
+x{|a,|}
+
+x{|a|}
diff --git a/test/prism/fixtures/seattlerb/bug290.txt b/test/prism/fixtures/seattlerb/bug290.txt
new file mode 100644
index 0000000000..dbcd28cd48
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug290.txt
@@ -0,0 +1,3 @@
+begin
+ foo
+end
diff --git a/test/prism/fixtures/seattlerb/bug_187.txt b/test/prism/fixtures/seattlerb/bug_187.txt
new file mode 100644
index 0000000000..1e1ecd8202
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_187.txt
@@ -0,0 +1,3 @@
+private def f
+a.b do end
+end
diff --git a/test/prism/fixtures/seattlerb/bug_215.txt b/test/prism/fixtures/seattlerb/bug_215.txt
new file mode 100644
index 0000000000..f0d09ba5ff
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_215.txt
@@ -0,0 +1 @@
+undef %s(foo)
diff --git a/test/prism/fixtures/seattlerb/bug_249.txt b/test/prism/fixtures/seattlerb/bug_249.txt
new file mode 100644
index 0000000000..ccccdf5326
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_249.txt
@@ -0,0 +1,4 @@
+mount (Class.new do
+def initialize
+end
+ end).new, :at => 'endpoint'
diff --git a/test/prism/fixtures/seattlerb/bug_and.txt b/test/prism/fixtures/seattlerb/bug_and.txt
new file mode 100644
index 0000000000..6243359a9e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_and.txt
@@ -0,0 +1,4 @@
+true and
+true
+
+true and []
diff --git a/test/prism/fixtures/seattlerb/bug_args__19.txt b/test/prism/fixtures/seattlerb/bug_args__19.txt
new file mode 100644
index 0000000000..08466554fd
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_args__19.txt
@@ -0,0 +1 @@
+f { |(a, b)| d }
diff --git a/test/prism/fixtures/seattlerb/bug_args_masgn.txt b/test/prism/fixtures/seattlerb/bug_args_masgn.txt
new file mode 100644
index 0000000000..e0a71e9197
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_args_masgn.txt
@@ -0,0 +1 @@
+f { |(a, b), c| }
diff --git a/test/prism/fixtures/seattlerb/bug_args_masgn2.txt b/test/prism/fixtures/seattlerb/bug_args_masgn2.txt
new file mode 100644
index 0000000000..2f12756bfe
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_args_masgn2.txt
@@ -0,0 +1 @@
+f { |((a, b), c), d| }
diff --git a/test/prism/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt b/test/prism/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt
new file mode 100644
index 0000000000..a2b0178676
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt
@@ -0,0 +1 @@
+f { |((k, v), i)| }
diff --git a/test/prism/fixtures/seattlerb/bug_call_arglist_parens.txt b/test/prism/fixtures/seattlerb/bug_call_arglist_parens.txt
new file mode 100644
index 0000000000..4f04368802
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_call_arglist_parens.txt
@@ -0,0 +1,11 @@
+ def f
+ g ( 1), 2
+ end
+
+
+ def f()
+ g (1), 2
+ end
+
+
+g ( 1), 2
diff --git a/test/prism/fixtures/seattlerb/bug_case_when_regexp.txt b/test/prism/fixtures/seattlerb/bug_case_when_regexp.txt
new file mode 100644
index 0000000000..2536696a42
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_case_when_regexp.txt
@@ -0,0 +1 @@
+case :x; when /x/ then end
diff --git a/test/prism/fixtures/seattlerb/bug_comma.txt b/test/prism/fixtures/seattlerb/bug_comma.txt
new file mode 100644
index 0000000000..d86f1ea9dd
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_comma.txt
@@ -0,0 +1 @@
+if test ?d, dir then end
diff --git a/test/prism/fixtures/seattlerb/bug_cond_pct.txt b/test/prism/fixtures/seattlerb/bug_cond_pct.txt
new file mode 100644
index 0000000000..1b4f90058e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_cond_pct.txt
@@ -0,0 +1 @@
+case; when %r%blahblah%; end
diff --git a/test/prism/fixtures/seattlerb/bug_hash_args.txt b/test/prism/fixtures/seattlerb/bug_hash_args.txt
new file mode 100644
index 0000000000..b815f8a666
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_hash_args.txt
@@ -0,0 +1 @@
+foo(:bar, baz: nil)
diff --git a/test/prism/fixtures/seattlerb/bug_hash_args_trailing_comma.txt b/test/prism/fixtures/seattlerb/bug_hash_args_trailing_comma.txt
new file mode 100644
index 0000000000..6057b245a5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_hash_args_trailing_comma.txt
@@ -0,0 +1 @@
+foo(:bar, baz: nil,)
diff --git a/test/prism/fixtures/seattlerb/bug_hash_interp_array.txt b/test/prism/fixtures/seattlerb/bug_hash_interp_array.txt
new file mode 100644
index 0000000000..01fe238056
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_hash_interp_array.txt
@@ -0,0 +1 @@
+{ "#{}": [] }
diff --git a/test/prism/fixtures/seattlerb/bug_masgn_right.txt b/test/prism/fixtures/seattlerb/bug_masgn_right.txt
new file mode 100644
index 0000000000..12ea7b8d62
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_masgn_right.txt
@@ -0,0 +1 @@
+f { |a, (b, c)| }
diff --git a/test/prism/fixtures/seattlerb/bug_not_parens.txt b/test/prism/fixtures/seattlerb/bug_not_parens.txt
new file mode 100644
index 0000000000..8847b7bec6
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_not_parens.txt
@@ -0,0 +1 @@
+not(a)
diff --git a/test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt b/test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt
new file mode 100644
index 0000000000..6a0b25cbdc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt
@@ -0,0 +1 @@
+a ||= b rescue nil
diff --git a/test/prism/fixtures/seattlerb/call_and.txt b/test/prism/fixtures/seattlerb/call_and.txt
new file mode 100644
index 0000000000..c17be8f356
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_and.txt
@@ -0,0 +1 @@
+1 & 2
diff --git a/test/prism/fixtures/seattlerb/call_arg_assoc.txt b/test/prism/fixtures/seattlerb/call_arg_assoc.txt
new file mode 100644
index 0000000000..376c299be5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_arg_assoc.txt
@@ -0,0 +1 @@
+f(1, 2=>3)
diff --git a/test/prism/fixtures/seattlerb/call_arg_assoc_kwsplat.txt b/test/prism/fixtures/seattlerb/call_arg_assoc_kwsplat.txt
new file mode 100644
index 0000000000..a4be0fb62c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_arg_assoc_kwsplat.txt
@@ -0,0 +1 @@
+f(1, kw: 2, **3)
diff --git a/test/prism/fixtures/seattlerb/call_arg_kwsplat.txt b/test/prism/fixtures/seattlerb/call_arg_kwsplat.txt
new file mode 100644
index 0000000000..4848fd9e8d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_arg_kwsplat.txt
@@ -0,0 +1 @@
+a(b, **1)
diff --git a/test/prism/fixtures/seattlerb/call_args_assoc_quoted.txt b/test/prism/fixtures/seattlerb/call_args_assoc_quoted.txt
new file mode 100644
index 0000000000..0af2259577
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_args_assoc_quoted.txt
@@ -0,0 +1,5 @@
+x "#{k}":42
+
+x "k":42
+
+x 'k':42
diff --git a/test/prism/fixtures/seattlerb/call_args_assoc_trailing_comma.txt b/test/prism/fixtures/seattlerb/call_args_assoc_trailing_comma.txt
new file mode 100644
index 0000000000..6ad08f3238
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_args_assoc_trailing_comma.txt
@@ -0,0 +1 @@
+f(1, 2=>3,)
diff --git a/test/prism/fixtures/seattlerb/call_args_command.txt b/test/prism/fixtures/seattlerb/call_args_command.txt
new file mode 100644
index 0000000000..dd6df29c7b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_args_command.txt
@@ -0,0 +1 @@
+a.b c.d 1
diff --git a/test/prism/fixtures/seattlerb/call_array_arg.txt b/test/prism/fixtures/seattlerb/call_array_arg.txt
new file mode 100644
index 0000000000..5c724fa328
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_array_arg.txt
@@ -0,0 +1 @@
+1 == [:b, :c]
diff --git a/test/prism/fixtures/seattlerb/call_array_block_call.txt b/test/prism/fixtures/seattlerb/call_array_block_call.txt
new file mode 100644
index 0000000000..6d4c1b276e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_array_block_call.txt
@@ -0,0 +1 @@
+a [ nil, b do end ]
diff --git a/test/prism/fixtures/seattlerb/call_array_lambda_block_call.txt b/test/prism/fixtures/seattlerb/call_array_lambda_block_call.txt
new file mode 100644
index 0000000000..dc5b5807b2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_array_lambda_block_call.txt
@@ -0,0 +1,2 @@
+a [->() {}] do
+end
diff --git a/test/prism/fixtures/seattlerb/call_array_lit_inline_hash.txt b/test/prism/fixtures/seattlerb/call_array_lit_inline_hash.txt
new file mode 100644
index 0000000000..daba00947e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_array_lit_inline_hash.txt
@@ -0,0 +1 @@
+a([:b, :c => 1])
diff --git a/test/prism/fixtures/seattlerb/call_assoc.txt b/test/prism/fixtures/seattlerb/call_assoc.txt
new file mode 100644
index 0000000000..2adc1eee1c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_assoc.txt
@@ -0,0 +1 @@
+f(2=>3)
diff --git a/test/prism/fixtures/seattlerb/call_assoc_new.txt b/test/prism/fixtures/seattlerb/call_assoc_new.txt
new file mode 100644
index 0000000000..b8457bfdfc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_assoc_new.txt
@@ -0,0 +1 @@
+f(a:3)
diff --git a/test/prism/fixtures/seattlerb/call_assoc_new_if_multiline.txt b/test/prism/fixtures/seattlerb/call_assoc_new_if_multiline.txt
new file mode 100644
index 0000000000..fe0a37dabb
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_assoc_new_if_multiline.txt
@@ -0,0 +1,5 @@
+a(b: if :c
+1
+else
+2
+end)
diff --git a/test/prism/fixtures/seattlerb/call_assoc_trailing_comma.txt b/test/prism/fixtures/seattlerb/call_assoc_trailing_comma.txt
new file mode 100644
index 0000000000..4d86a4541d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_assoc_trailing_comma.txt
@@ -0,0 +1 @@
+f(1=>2,)
diff --git a/test/prism/fixtures/seattlerb/call_bang_command_call.txt b/test/prism/fixtures/seattlerb/call_bang_command_call.txt
new file mode 100644
index 0000000000..4f3ba4b93c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_bang_command_call.txt
@@ -0,0 +1 @@
+! a.b 1
diff --git a/test/prism/fixtures/seattlerb/call_bang_squiggle.txt b/test/prism/fixtures/seattlerb/call_bang_squiggle.txt
new file mode 100644
index 0000000000..d7039f910a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_bang_squiggle.txt
@@ -0,0 +1 @@
+1 !~ 2
diff --git a/test/prism/fixtures/seattlerb/call_begin_call_block_call.txt b/test/prism/fixtures/seattlerb/call_begin_call_block_call.txt
new file mode 100644
index 0000000000..e9b43491fe
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_begin_call_block_call.txt
@@ -0,0 +1,3 @@
+a begin
+b.c do end
+end
diff --git a/test/prism/fixtures/seattlerb/call_block_arg_named.txt b/test/prism/fixtures/seattlerb/call_block_arg_named.txt
new file mode 100644
index 0000000000..08fea89d11
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_block_arg_named.txt
@@ -0,0 +1 @@
+x(&blk)
diff --git a/test/prism/fixtures/seattlerb/call_carat.txt b/test/prism/fixtures/seattlerb/call_carat.txt
new file mode 100644
index 0000000000..3e88c09837
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_carat.txt
@@ -0,0 +1 @@
+1 ^ 2
diff --git a/test/prism/fixtures/seattlerb/call_colon2.txt b/test/prism/fixtures/seattlerb/call_colon2.txt
new file mode 100644
index 0000000000..47aab7e637
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_colon2.txt
@@ -0,0 +1 @@
+A::b
diff --git a/test/prism/fixtures/seattlerb/call_colon_parens.txt b/test/prism/fixtures/seattlerb/call_colon_parens.txt
new file mode 100644
index 0000000000..51ed4df11b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_colon_parens.txt
@@ -0,0 +1 @@
+1::()
diff --git a/test/prism/fixtures/seattlerb/call_div.txt b/test/prism/fixtures/seattlerb/call_div.txt
new file mode 100644
index 0000000000..85b4d7b0b0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_div.txt
@@ -0,0 +1 @@
+1 / 2
diff --git a/test/prism/fixtures/seattlerb/call_dot_parens.txt b/test/prism/fixtures/seattlerb/call_dot_parens.txt
new file mode 100644
index 0000000000..0270596a07
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_dot_parens.txt
@@ -0,0 +1 @@
+1.()
diff --git a/test/prism/fixtures/seattlerb/call_env.txt b/test/prism/fixtures/seattlerb/call_env.txt
new file mode 100644
index 0000000000..dadc0d3861
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_env.txt
@@ -0,0 +1 @@
+a.happy
diff --git a/test/prism/fixtures/seattlerb/call_eq3.txt b/test/prism/fixtures/seattlerb/call_eq3.txt
new file mode 100644
index 0000000000..6a2fb465cb
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_eq3.txt
@@ -0,0 +1 @@
+1 === 2
diff --git a/test/prism/fixtures/seattlerb/call_gt.txt b/test/prism/fixtures/seattlerb/call_gt.txt
new file mode 100644
index 0000000000..9d0a1caa90
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_gt.txt
@@ -0,0 +1 @@
+1 > 2
diff --git a/test/prism/fixtures/seattlerb/call_kwsplat.txt b/test/prism/fixtures/seattlerb/call_kwsplat.txt
new file mode 100644
index 0000000000..eda700c3e1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_kwsplat.txt
@@ -0,0 +1 @@
+a(**1)
diff --git a/test/prism/fixtures/seattlerb/call_leading_dots.txt b/test/prism/fixtures/seattlerb/call_leading_dots.txt
new file mode 100644
index 0000000000..1e7b2e5179
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_leading_dots.txt
@@ -0,0 +1,3 @@
+a
+.b
+.c
diff --git a/test/prism/fixtures/seattlerb/call_leading_dots_comment.txt b/test/prism/fixtures/seattlerb/call_leading_dots_comment.txt
new file mode 100644
index 0000000000..c5deec5642
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_leading_dots_comment.txt
@@ -0,0 +1,4 @@
+a
+.b
+#.c
+.d
diff --git a/test/prism/fixtures/seattlerb/call_lt.txt b/test/prism/fixtures/seattlerb/call_lt.txt
new file mode 100644
index 0000000000..17e69c79b5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_lt.txt
@@ -0,0 +1 @@
+1 < 2
diff --git a/test/prism/fixtures/seattlerb/call_lte.txt b/test/prism/fixtures/seattlerb/call_lte.txt
new file mode 100644
index 0000000000..7574027634
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_lte.txt
@@ -0,0 +1 @@
+1 <= 2
diff --git a/test/prism/fixtures/seattlerb/call_not.txt b/test/prism/fixtures/seattlerb/call_not.txt
new file mode 100644
index 0000000000..51e4742f55
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_not.txt
@@ -0,0 +1 @@
+not 42
diff --git a/test/prism/fixtures/seattlerb/call_pipe.txt b/test/prism/fixtures/seattlerb/call_pipe.txt
new file mode 100644
index 0000000000..1555910665
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_pipe.txt
@@ -0,0 +1 @@
+1 | 2
diff --git a/test/prism/fixtures/seattlerb/call_rshift.txt b/test/prism/fixtures/seattlerb/call_rshift.txt
new file mode 100644
index 0000000000..9ff1def4e0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_rshift.txt
@@ -0,0 +1 @@
+1 >> 2
diff --git a/test/prism/fixtures/seattlerb/call_self_brackets.txt b/test/prism/fixtures/seattlerb/call_self_brackets.txt
new file mode 100644
index 0000000000..6533df2ce0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_self_brackets.txt
@@ -0,0 +1 @@
+self[1]
diff --git a/test/prism/fixtures/seattlerb/call_spaceship.txt b/test/prism/fixtures/seattlerb/call_spaceship.txt
new file mode 100644
index 0000000000..905c3a1c46
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_spaceship.txt
@@ -0,0 +1 @@
+1 <=> 2
diff --git a/test/prism/fixtures/seattlerb/call_stabby_do_end_with_block.txt b/test/prism/fixtures/seattlerb/call_stabby_do_end_with_block.txt
new file mode 100644
index 0000000000..2d1afdad28
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_stabby_do_end_with_block.txt
@@ -0,0 +1 @@
+a -> do 1 end do 2 end
diff --git a/test/prism/fixtures/seattlerb/call_stabby_with_braces_block.txt b/test/prism/fixtures/seattlerb/call_stabby_with_braces_block.txt
new file mode 100644
index 0000000000..0d995a04d1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_stabby_with_braces_block.txt
@@ -0,0 +1 @@
+a -> { 1 } do 2 end
diff --git a/test/prism/fixtures/seattlerb/call_star.txt b/test/prism/fixtures/seattlerb/call_star.txt
new file mode 100644
index 0000000000..096ec022d4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_star.txt
@@ -0,0 +1 @@
+1 * 2
diff --git a/test/prism/fixtures/seattlerb/call_star2.txt b/test/prism/fixtures/seattlerb/call_star2.txt
new file mode 100644
index 0000000000..bef4719d3c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_star2.txt
@@ -0,0 +1 @@
+1 ** 2
diff --git a/test/prism/fixtures/seattlerb/call_trailing_comma.txt b/test/prism/fixtures/seattlerb/call_trailing_comma.txt
new file mode 100644
index 0000000000..e9a3ca35be
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_trailing_comma.txt
@@ -0,0 +1 @@
+f(1,)
diff --git a/test/prism/fixtures/seattlerb/call_trailing_dots.txt b/test/prism/fixtures/seattlerb/call_trailing_dots.txt
new file mode 100644
index 0000000000..960cdbb45f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_trailing_dots.txt
@@ -0,0 +1,3 @@
+a.
+b.
+c
diff --git a/test/prism/fixtures/seattlerb/call_unary_bang.txt b/test/prism/fixtures/seattlerb/call_unary_bang.txt
new file mode 100644
index 0000000000..91f702d4a9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/call_unary_bang.txt
@@ -0,0 +1 @@
+!1
diff --git a/test/prism/fixtures/seattlerb/case_in.txt b/test/prism/fixtures/seattlerb/case_in.txt
new file mode 100644
index 0000000000..0835da0956
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in.txt
@@ -0,0 +1,111 @@
+case :a
+in "b":
+end
+
+case :a
+in %I[a b]
+end
+
+case :a
+in %W[a b]
+end
+
+case :a
+in %i[a b]
+end
+
+case :a
+in %w[a b]
+end
+
+case :a
+in (...10)
+end
+
+case :a
+in (..10)
+end
+
+case :a
+in (1...)
+end
+
+case :a
+in (1...3)
+end
+
+case :a
+in (42)
+end
+
+case :a
+in **nil
+end
+
+case :a
+in /regexp/
+end
+
+case :a
+in :b, *_, :c
+end
+
+case :a
+in :b, [:c]
+end
+
+case :a
+in Symbol()
+end
+
+case :a
+in Symbol(*lhs, x, *rhs)
+end
+
+case :a
+in Symbol[*lhs, x, *rhs]
+end
+
+case :a
+in [->(b) { true }, c]
+end
+
+case :a
+in [:a, b, c, [:d, *e, nil]]
+end
+
+case :a
+in [A, *, B]
+end
+
+case :a
+in [[:b, c], [:d, ^e]]
+end
+
+case :a
+in []
+end
+
+case :a
+in [^(a)]
+end
+
+case :a
+in [^@a, ^$b, ^@@c]
+end
+
+case :a
+in `echo hi`
+end
+
+case :a
+in nil, nil, nil
+end
+
+case :a
+in { "b": }
+end
+
+case :a
+in {}
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_31.txt b/test/prism/fixtures/seattlerb/case_in_31.txt
new file mode 100644
index 0000000000..b9bf25b132
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_31.txt
@@ -0,0 +1,4 @@
+case :a
+in [:b, *c]
+ :d
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_37.txt b/test/prism/fixtures/seattlerb/case_in_37.txt
new file mode 100644
index 0000000000..25b6fb9261
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_37.txt
@@ -0,0 +1,4 @@
+case :a
+in { b: [Hash, *] }
+ :c
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_42.txt b/test/prism/fixtures/seattlerb/case_in_42.txt
new file mode 100644
index 0000000000..bc6a2233f5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_42.txt
@@ -0,0 +1,3 @@
+case :a
+in :b, *_ then nil
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_42_2.txt b/test/prism/fixtures/seattlerb/case_in_42_2.txt
new file mode 100644
index 0000000000..ce4b65a5d0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_42_2.txt
@@ -0,0 +1,3 @@
+case :a
+in A(*list) then nil
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_47.txt b/test/prism/fixtures/seattlerb/case_in_47.txt
new file mode 100644
index 0000000000..60f17ed7ce
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_47.txt
@@ -0,0 +1,4 @@
+case :a
+in [*, :b, :c]
+ :d
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_67.txt b/test/prism/fixtures/seattlerb/case_in_67.txt
new file mode 100644
index 0000000000..c1c55e68c7
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_67.txt
@@ -0,0 +1,3 @@
+case :a
+in 1.. then nil
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_86.txt b/test/prism/fixtures/seattlerb/case_in_86.txt
new file mode 100644
index 0000000000..63ba92e533
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_86.txt
@@ -0,0 +1,3 @@
+case [:a, :b]
+in ::NilClass, * then nil
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_86_2.txt b/test/prism/fixtures/seattlerb/case_in_86_2.txt
new file mode 100644
index 0000000000..4ad16c451a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_86_2.txt
@@ -0,0 +1,3 @@
+case [:a, :b]
+in *, ::NilClass then nil
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_array_pat_const.txt b/test/prism/fixtures/seattlerb/case_in_array_pat_const.txt
new file mode 100644
index 0000000000..8551e48e2c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_array_pat_const.txt
@@ -0,0 +1,4 @@
+case :a
+in B[c]
+ :d
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_array_pat_const2.txt b/test/prism/fixtures/seattlerb/case_in_array_pat_const2.txt
new file mode 100644
index 0000000000..fca423ea61
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_array_pat_const2.txt
@@ -0,0 +1,4 @@
+case :a
+in B::C[d]
+ :e
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_array_pat_paren_assign.txt b/test/prism/fixtures/seattlerb/case_in_array_pat_paren_assign.txt
new file mode 100644
index 0000000000..c56f728337
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_array_pat_paren_assign.txt
@@ -0,0 +1,4 @@
+case :a
+in B(C => d)
+ :d
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_const.txt b/test/prism/fixtures/seattlerb/case_in_const.txt
new file mode 100644
index 0000000000..5b0dcc18e2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_const.txt
@@ -0,0 +1,4 @@
+case Array
+in Class
+ :b
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_else.txt b/test/prism/fixtures/seattlerb/case_in_else.txt
new file mode 100644
index 0000000000..6f096862c5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_else.txt
@@ -0,0 +1,7 @@
+case Array
+in Class
+ :b
+else
+ :c
+end
+
diff --git a/test/prism/fixtures/seattlerb/case_in_find.txt b/test/prism/fixtures/seattlerb/case_in_find.txt
new file mode 100644
index 0000000000..476fcabe11
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_find.txt
@@ -0,0 +1,3 @@
+case :a
+ in *a, :+, *b
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_find_array.txt b/test/prism/fixtures/seattlerb/case_in_find_array.txt
new file mode 100644
index 0000000000..5eb4010b7f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_find_array.txt
@@ -0,0 +1,3 @@
+case :a
+in [*, :b, c, *]
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_hash_pat.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat.txt
new file mode 100644
index 0000000000..cb012e8d99
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_hash_pat.txt
@@ -0,0 +1,5 @@
+case :a
+in { b: 'c', d: "e" } then
+ :f
+end
+
diff --git a/test/prism/fixtures/seattlerb/case_in_hash_pat_assign.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_assign.txt
new file mode 100644
index 0000000000..58fd59ff9c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_hash_pat_assign.txt
@@ -0,0 +1,4 @@
+case :a
+in { b: Integer => x, d: "e", f: } then
+ :g
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt
new file mode 100644
index 0000000000..de3a10740c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt
@@ -0,0 +1,4 @@
+case :a
+in B(a: 42)
+ :d
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_true.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_true.txt
new file mode 100644
index 0000000000..449fd0d4d4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_true.txt
@@ -0,0 +1,5 @@
+case :a
+in b: true then
+ :c
+end
+
diff --git a/test/prism/fixtures/seattlerb/case_in_hash_pat_rest.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_rest.txt
new file mode 100644
index 0000000000..6f67cb1d10
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_hash_pat_rest.txt
@@ -0,0 +1,3 @@
+case :a
+in b: c, **rest then :d
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt
new file mode 100644
index 0000000000..91d0592412
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt
@@ -0,0 +1,3 @@
+case :a
+in **rest then :d
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_if_unless_post_mod.txt b/test/prism/fixtures/seattlerb/case_in_if_unless_post_mod.txt
new file mode 100644
index 0000000000..dbe24a5c8a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_if_unless_post_mod.txt
@@ -0,0 +1,6 @@
+case :a
+in A if true
+ :C
+in D unless false
+ :E
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_multiple.txt b/test/prism/fixtures/seattlerb/case_in_multiple.txt
new file mode 100644
index 0000000000..1b6dd06cfe
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_multiple.txt
@@ -0,0 +1,6 @@
+case :a
+in A::B
+ :C
+in D::E
+ :F
+end
diff --git a/test/prism/fixtures/seattlerb/case_in_or.txt b/test/prism/fixtures/seattlerb/case_in_or.txt
new file mode 100644
index 0000000000..875e37749f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/case_in_or.txt
@@ -0,0 +1,5 @@
+case :a
+in B | C
+ :d
+end
+
diff --git a/test/prism/fixtures/seattlerb/class_comments.txt b/test/prism/fixtures/seattlerb/class_comments.txt
new file mode 100644
index 0000000000..9701eca7e5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/class_comments.txt
@@ -0,0 +1,9 @@
+# blah 1
+# blah 2
+
+class X
+ # blah 3
+ def blah
+ # blah 4
+ end
+end
diff --git a/test/prism/fixtures/seattlerb/cond_unary_minus.txt b/test/prism/fixtures/seattlerb/cond_unary_minus.txt
new file mode 100644
index 0000000000..80293115da
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/cond_unary_minus.txt
@@ -0,0 +1 @@
+if -1; end
diff --git a/test/prism/fixtures/seattlerb/const_2_op_asgn_or2.txt b/test/prism/fixtures/seattlerb/const_2_op_asgn_or2.txt
new file mode 100644
index 0000000000..6912c2d76b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/const_2_op_asgn_or2.txt
@@ -0,0 +1 @@
+::X::Y ||= 1
diff --git a/test/prism/fixtures/seattlerb/const_3_op_asgn_or.txt b/test/prism/fixtures/seattlerb/const_3_op_asgn_or.txt
new file mode 100644
index 0000000000..bbcd25a369
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/const_3_op_asgn_or.txt
@@ -0,0 +1 @@
+::X ||= 1
diff --git a/test/prism/fixtures/seattlerb/const_op_asgn_and1.txt b/test/prism/fixtures/seattlerb/const_op_asgn_and1.txt
new file mode 100644
index 0000000000..3964df0ead
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/const_op_asgn_and1.txt
@@ -0,0 +1 @@
+::X &= 1
diff --git a/test/prism/fixtures/seattlerb/const_op_asgn_and2.txt b/test/prism/fixtures/seattlerb/const_op_asgn_and2.txt
new file mode 100644
index 0000000000..1bef4b4154
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/const_op_asgn_and2.txt
@@ -0,0 +1 @@
+::X &&= 1
diff --git a/test/prism/fixtures/seattlerb/const_op_asgn_or.txt b/test/prism/fixtures/seattlerb/const_op_asgn_or.txt
new file mode 100644
index 0000000000..729e425262
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/const_op_asgn_or.txt
@@ -0,0 +1 @@
+X::Y ||= 1
diff --git a/test/prism/fixtures/seattlerb/defined_eh_parens.txt b/test/prism/fixtures/seattlerb/defined_eh_parens.txt
new file mode 100644
index 0000000000..5ca5d9f4c4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defined_eh_parens.txt
@@ -0,0 +1 @@
+defined?(42)
diff --git a/test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt b/test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt
new file mode 100644
index 0000000000..f629a5de60
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt
@@ -0,0 +1 @@
+def call(interp, *, args) end
diff --git a/test/prism/fixtures/seattlerb/defn_arg_forward_args.txt b/test/prism/fixtures/seattlerb/defn_arg_forward_args.txt
new file mode 100644
index 0000000000..500e2e1fe0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_arg_forward_args.txt
@@ -0,0 +1 @@
+def a(x, ...); b(x, ...); end
diff --git a/test/prism/fixtures/seattlerb/defn_args_forward_args.txt b/test/prism/fixtures/seattlerb/defn_args_forward_args.txt
new file mode 100644
index 0000000000..fc1ee138de
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_args_forward_args.txt
@@ -0,0 +1 @@
+def a(x, y, z, ...); b(:get, z, ...); end
diff --git a/test/prism/fixtures/seattlerb/defn_comments.txt b/test/prism/fixtures/seattlerb/defn_comments.txt
new file mode 100644
index 0000000000..04c7ea1a10
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_comments.txt
@@ -0,0 +1,5 @@
+# blah 1
+# blah 2
+
+def blah
+end
diff --git a/test/prism/fixtures/seattlerb/defn_endless_command.txt b/test/prism/fixtures/seattlerb/defn_endless_command.txt
new file mode 100644
index 0000000000..172de2ca6c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_endless_command.txt
@@ -0,0 +1 @@
+def some_method = other_method 42
diff --git a/test/prism/fixtures/seattlerb/defn_endless_command_rescue.txt b/test/prism/fixtures/seattlerb/defn_endless_command_rescue.txt
new file mode 100644
index 0000000000..05ed392e38
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_endless_command_rescue.txt
@@ -0,0 +1 @@
+def some_method = other_method 42 rescue 24
diff --git a/test/prism/fixtures/seattlerb/defn_forward_args.txt b/test/prism/fixtures/seattlerb/defn_forward_args.txt
new file mode 100644
index 0000000000..46ed199875
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_forward_args.txt
@@ -0,0 +1 @@
+def a(...); b(...); end
diff --git a/test/prism/fixtures/seattlerb/defn_forward_args__no_parens.txt b/test/prism/fixtures/seattlerb/defn_forward_args__no_parens.txt
new file mode 100644
index 0000000000..2d34077c93
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_forward_args__no_parens.txt
@@ -0,0 +1,3 @@
+def f ...
+ m(...)
+end
diff --git a/test/prism/fixtures/seattlerb/defn_kwarg_env.txt b/test/prism/fixtures/seattlerb/defn_kwarg_env.txt
new file mode 100644
index 0000000000..b512677195
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_kwarg_env.txt
@@ -0,0 +1 @@
+def test(**testing) test_splat(**testing) end
diff --git a/test/prism/fixtures/seattlerb/defn_kwarg_kwarg.txt b/test/prism/fixtures/seattlerb/defn_kwarg_kwarg.txt
new file mode 100644
index 0000000000..3962d2645c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_kwarg_kwarg.txt
@@ -0,0 +1 @@
+def f(a, b: 1, c: 2) end
diff --git a/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat.txt b/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat.txt
new file mode 100644
index 0000000000..bd39819482
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat.txt
@@ -0,0 +1 @@
+def a(b: 1, **c) end
diff --git a/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt b/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt
new file mode 100644
index 0000000000..aba71cba07
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt
@@ -0,0 +1 @@
+def a(b: 1, **) end
diff --git a/test/prism/fixtures/seattlerb/defn_kwarg_lvar.txt b/test/prism/fixtures/seattlerb/defn_kwarg_lvar.txt
new file mode 100644
index 0000000000..9eac108cca
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_kwarg_lvar.txt
@@ -0,0 +1 @@
+def fun(kw: :val); kw; end
diff --git a/test/prism/fixtures/seattlerb/defn_kwarg_no_parens.txt b/test/prism/fixtures/seattlerb/defn_kwarg_no_parens.txt
new file mode 100644
index 0000000000..481457bf0e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_kwarg_no_parens.txt
@@ -0,0 +1,2 @@
+def f a: 1
+end
diff --git a/test/prism/fixtures/seattlerb/defn_kwarg_val.txt b/test/prism/fixtures/seattlerb/defn_kwarg_val.txt
new file mode 100644
index 0000000000..1a2803926f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_kwarg_val.txt
@@ -0,0 +1 @@
+def f(a, b:1) end
diff --git a/test/prism/fixtures/seattlerb/defn_no_kwargs.txt b/test/prism/fixtures/seattlerb/defn_no_kwargs.txt
new file mode 100644
index 0000000000..857ec8debb
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_no_kwargs.txt
@@ -0,0 +1 @@
+def x(**nil); end
diff --git a/test/prism/fixtures/seattlerb/defn_oneliner.txt b/test/prism/fixtures/seattlerb/defn_oneliner.txt
new file mode 100644
index 0000000000..4aef08ce46
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_oneliner.txt
@@ -0,0 +1 @@
+def exec(cmd) = system(cmd)
diff --git a/test/prism/fixtures/seattlerb/defn_oneliner_eq2.txt b/test/prism/fixtures/seattlerb/defn_oneliner_eq2.txt
new file mode 100644
index 0000000000..1b1ce27a15
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_oneliner_eq2.txt
@@ -0,0 +1,3 @@
+class X
+ def ==(o) = 42
+end
diff --git a/test/prism/fixtures/seattlerb/defn_oneliner_noargs.txt b/test/prism/fixtures/seattlerb/defn_oneliner_noargs.txt
new file mode 100644
index 0000000000..cb4f76d244
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_oneliner_noargs.txt
@@ -0,0 +1 @@
+def exec = system
diff --git a/test/prism/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt b/test/prism/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt
new file mode 100644
index 0000000000..c582e896c1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt
@@ -0,0 +1 @@
+def exec() = system
diff --git a/test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt b/test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt
new file mode 100644
index 0000000000..ffe2228c9d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt
@@ -0,0 +1,13 @@
+def exec(cmd)
+ system(cmd)
+rescue
+ nil
+end
+
+
+def exec(cmd)
+ system(cmd) rescue nil
+end
+
+
+def exec(cmd) = system(cmd) rescue nil
diff --git a/test/prism/fixtures/seattlerb/defn_opt_last_arg.txt b/test/prism/fixtures/seattlerb/defn_opt_last_arg.txt
new file mode 100644
index 0000000000..91500bf137
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_opt_last_arg.txt
@@ -0,0 +1,2 @@
+def m arg = false
+end
diff --git a/test/prism/fixtures/seattlerb/defn_opt_reg.txt b/test/prism/fixtures/seattlerb/defn_opt_reg.txt
new file mode 100644
index 0000000000..c665674bc4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_opt_reg.txt
@@ -0,0 +1 @@
+def f(a=nil, b) end
diff --git a/test/prism/fixtures/seattlerb/defn_opt_splat_arg.txt b/test/prism/fixtures/seattlerb/defn_opt_splat_arg.txt
new file mode 100644
index 0000000000..876398b478
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_opt_splat_arg.txt
@@ -0,0 +1 @@
+def f (a = 1, *b, c) end
diff --git a/test/prism/fixtures/seattlerb/defn_powarg.txt b/test/prism/fixtures/seattlerb/defn_powarg.txt
new file mode 100644
index 0000000000..73415f0db9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_powarg.txt
@@ -0,0 +1 @@
+def f(**opts) end
diff --git a/test/prism/fixtures/seattlerb/defn_reg_opt_reg.txt b/test/prism/fixtures/seattlerb/defn_reg_opt_reg.txt
new file mode 100644
index 0000000000..69f501a38e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_reg_opt_reg.txt
@@ -0,0 +1 @@
+def f(a, b = :c, d) end
diff --git a/test/prism/fixtures/seattlerb/defn_splat_arg.txt b/test/prism/fixtures/seattlerb/defn_splat_arg.txt
new file mode 100644
index 0000000000..a2a84bed30
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_splat_arg.txt
@@ -0,0 +1 @@
+def f(*, a) end
diff --git a/test/prism/fixtures/seattlerb/defn_unary_not.txt b/test/prism/fixtures/seattlerb/defn_unary_not.txt
new file mode 100644
index 0000000000..fb83c84a13
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defn_unary_not.txt
@@ -0,0 +1 @@
+def !@; true; end
diff --git a/test/prism/fixtures/seattlerb/defns_reserved.txt b/test/prism/fixtures/seattlerb/defns_reserved.txt
new file mode 100644
index 0000000000..7de9322f0d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defns_reserved.txt
@@ -0,0 +1 @@
+def self.return; end
diff --git a/test/prism/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt b/test/prism/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt
new file mode 100644
index 0000000000..4d493d73dd
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt
@@ -0,0 +1 @@
+p def self.b; x.y do; end; end
diff --git a/test/prism/fixtures/seattlerb/defs_comments.txt b/test/prism/fixtures/seattlerb/defs_comments.txt
new file mode 100644
index 0000000000..52b9b4a6b3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defs_comments.txt
@@ -0,0 +1,5 @@
+# blah 1
+# blah 2
+
+def self.blah
+end
diff --git a/test/prism/fixtures/seattlerb/defs_endless_command.txt b/test/prism/fixtures/seattlerb/defs_endless_command.txt
new file mode 100644
index 0000000000..3b605657de
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defs_endless_command.txt
@@ -0,0 +1 @@
+def x.some_method = other_method 42
diff --git a/test/prism/fixtures/seattlerb/defs_endless_command_rescue.txt b/test/prism/fixtures/seattlerb/defs_endless_command_rescue.txt
new file mode 100644
index 0000000000..6ece366db0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defs_endless_command_rescue.txt
@@ -0,0 +1 @@
+def x.some_method = other_method 42 rescue 24
diff --git a/test/prism/fixtures/seattlerb/defs_kwarg.txt b/test/prism/fixtures/seattlerb/defs_kwarg.txt
new file mode 100644
index 0000000000..59970a371e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defs_kwarg.txt
@@ -0,0 +1,2 @@
+def self.a b: 1
+end
diff --git a/test/prism/fixtures/seattlerb/defs_oneliner.txt b/test/prism/fixtures/seattlerb/defs_oneliner.txt
new file mode 100644
index 0000000000..1867edcfbf
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defs_oneliner.txt
@@ -0,0 +1 @@
+def self.exec(cmd) = system(cmd)
diff --git a/test/prism/fixtures/seattlerb/defs_oneliner_eq2.txt b/test/prism/fixtures/seattlerb/defs_oneliner_eq2.txt
new file mode 100644
index 0000000000..1e55f68bf3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defs_oneliner_eq2.txt
@@ -0,0 +1,3 @@
+class X
+ def self.==(o) = 42
+end
diff --git a/test/prism/fixtures/seattlerb/defs_oneliner_rescue.txt b/test/prism/fixtures/seattlerb/defs_oneliner_rescue.txt
new file mode 100644
index 0000000000..7a04012b8f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/defs_oneliner_rescue.txt
@@ -0,0 +1,13 @@
+def self.exec(cmd)
+ system(cmd)
+rescue
+ nil
+end
+
+
+def self.exec(cmd)
+ system(cmd) rescue nil
+end
+
+
+def self.exec(cmd) = system(cmd) rescue nil
diff --git a/test/prism/fixtures/seattlerb/difficult0_.txt b/test/prism/fixtures/seattlerb/difficult0_.txt
new file mode 100644
index 0000000000..5c73907cae
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult0_.txt
@@ -0,0 +1,4 @@
+p <<-END+'b
+ a
+ END
+ c'+'d'
diff --git a/test/prism/fixtures/seattlerb/difficult1_line_numbers.txt b/test/prism/fixtures/seattlerb/difficult1_line_numbers.txt
new file mode 100644
index 0000000000..8008127dc9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult1_line_numbers.txt
@@ -0,0 +1,13 @@
+if true
+ p 1
+ a.b 2
+ c.d 3, 4
+ e.f 5
+ g.h 6, 7
+ p(1)
+ a.b(2)
+ c.d(3, 4)
+ e.f(5)
+ g.h(6, 7)
+end
+
diff --git a/test/prism/fixtures/seattlerb/difficult1_line_numbers2.txt b/test/prism/fixtures/seattlerb/difficult1_line_numbers2.txt
new file mode 100644
index 0000000000..1964562416
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult1_line_numbers2.txt
@@ -0,0 +1,8 @@
+if true then
+ p("a")
+ b = 1
+ p b
+ c =1
+end
+a
+
diff --git a/test/prism/fixtures/seattlerb/difficult2_.txt b/test/prism/fixtures/seattlerb/difficult2_.txt
new file mode 100644
index 0000000000..3259097492
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult2_.txt
@@ -0,0 +1,2 @@
+1 ? b('') : 2
+a d: 3
diff --git a/test/prism/fixtures/seattlerb/difficult3_.txt b/test/prism/fixtures/seattlerb/difficult3_.txt
new file mode 100644
index 0000000000..9f95860b82
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3_.txt
@@ -0,0 +1 @@
+f { |a, (b, *c)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3_2.txt b/test/prism/fixtures/seattlerb/difficult3_2.txt
new file mode 100644
index 0000000000..8abfe3f634
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3_2.txt
@@ -0,0 +1 @@
+f { |*a, b| }
diff --git a/test/prism/fixtures/seattlerb/difficult3_3.txt b/test/prism/fixtures/seattlerb/difficult3_3.txt
new file mode 100644
index 0000000000..6f43ab7b1d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3_3.txt
@@ -0,0 +1 @@
+f { |*a, b, &c| }
diff --git a/test/prism/fixtures/seattlerb/difficult3_4.txt b/test/prism/fixtures/seattlerb/difficult3_4.txt
new file mode 100644
index 0000000000..7070e1e964
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3_4.txt
@@ -0,0 +1 @@
+a=b ? true: false
diff --git a/test/prism/fixtures/seattlerb/difficult3_5.txt b/test/prism/fixtures/seattlerb/difficult3_5.txt
new file mode 100644
index 0000000000..6d52692481
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3_5.txt
@@ -0,0 +1 @@
+f ->() { g do end }
diff --git a/test/prism/fixtures/seattlerb/difficult3__10.txt b/test/prism/fixtures/seattlerb/difficult3__10.txt
new file mode 100644
index 0000000000..89974f5114
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3__10.txt
@@ -0,0 +1 @@
+f { |a, (*b, c)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__11.txt b/test/prism/fixtures/seattlerb/difficult3__11.txt
new file mode 100644
index 0000000000..911d037961
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3__11.txt
@@ -0,0 +1 @@
+f { |a, (*)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__12.txt b/test/prism/fixtures/seattlerb/difficult3__12.txt
new file mode 100644
index 0000000000..2405a80ec1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3__12.txt
@@ -0,0 +1 @@
+f { |a, (*, b)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__6.txt b/test/prism/fixtures/seattlerb/difficult3__6.txt
new file mode 100644
index 0000000000..3a45ae86fb
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3__6.txt
@@ -0,0 +1 @@
+f { |a, (b, *c, d)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__7.txt b/test/prism/fixtures/seattlerb/difficult3__7.txt
new file mode 100644
index 0000000000..55272a1fc4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3__7.txt
@@ -0,0 +1 @@
+f { |a, (b, *)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__8.txt b/test/prism/fixtures/seattlerb/difficult3__8.txt
new file mode 100644
index 0000000000..76740db4ff
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3__8.txt
@@ -0,0 +1 @@
+f { |a, (b, *, c)| }
diff --git a/test/prism/fixtures/seattlerb/difficult3__9.txt b/test/prism/fixtures/seattlerb/difficult3__9.txt
new file mode 100644
index 0000000000..b65f7fd052
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult3__9.txt
@@ -0,0 +1 @@
+f { |a, (*b)| }
diff --git a/test/prism/fixtures/seattlerb/difficult4__leading_dots.txt b/test/prism/fixtures/seattlerb/difficult4__leading_dots.txt
new file mode 100644
index 0000000000..332dc8225c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult4__leading_dots.txt
@@ -0,0 +1,2 @@
+a
+.b
diff --git a/test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt b/test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt
new file mode 100644
index 0000000000..fe73f641fe
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt
@@ -0,0 +1,2 @@
+1
+..3
diff --git a/test/prism/fixtures/seattlerb/difficult6_.txt b/test/prism/fixtures/seattlerb/difficult6_.txt
new file mode 100644
index 0000000000..7396a9a76f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult6_.txt
@@ -0,0 +1 @@
+->(a, b=nil) { p [a, b] }
diff --git a/test/prism/fixtures/seattlerb/difficult6__7.txt b/test/prism/fixtures/seattlerb/difficult6__7.txt
new file mode 100644
index 0000000000..048358bbdc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult6__7.txt
@@ -0,0 +1 @@
+a.b (1) {c}
diff --git a/test/prism/fixtures/seattlerb/difficult6__8.txt b/test/prism/fixtures/seattlerb/difficult6__8.txt
new file mode 100644
index 0000000000..ba1cbc235d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult6__8.txt
@@ -0,0 +1 @@
+a::b (1) {c}
diff --git a/test/prism/fixtures/seattlerb/difficult7_.txt b/test/prism/fixtures/seattlerb/difficult7_.txt
new file mode 100644
index 0000000000..112b75c5f2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/difficult7_.txt
@@ -0,0 +1,5 @@
+ {
+ a: lambda { b ? c() : d },
+ e: nil,
+ }
+
diff --git a/test/prism/fixtures/seattlerb/do_bug.txt b/test/prism/fixtures/seattlerb/do_bug.txt
new file mode 100644
index 0000000000..a274e72baf
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/do_bug.txt
@@ -0,0 +1,4 @@
+a 1
+a.b do |c|
+ # do nothing
+end
diff --git a/test/prism/fixtures/seattlerb/do_lambda.txt b/test/prism/fixtures/seattlerb/do_lambda.txt
new file mode 100644
index 0000000000..06d2a38d30
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/do_lambda.txt
@@ -0,0 +1 @@
+->() do end
diff --git a/test/prism/fixtures/seattlerb/dot2_nil__26.txt b/test/prism/fixtures/seattlerb/dot2_nil__26.txt
new file mode 100644
index 0000000000..cc070eb69f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/dot2_nil__26.txt
@@ -0,0 +1 @@
+a..
diff --git a/test/prism/fixtures/seattlerb/dot3_nil__26.txt b/test/prism/fixtures/seattlerb/dot3_nil__26.txt
new file mode 100644
index 0000000000..7f4aef7af7
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/dot3_nil__26.txt
@@ -0,0 +1 @@
+a...
diff --git a/test/prism/fixtures/seattlerb/dstr_evstr.txt b/test/prism/fixtures/seattlerb/dstr_evstr.txt
new file mode 100644
index 0000000000..5fe4a858c1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/dstr_evstr.txt
@@ -0,0 +1 @@
+"#{'a'}#{b}"
diff --git a/test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt b/test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt
new file mode 100644
index 0000000000..7a55030fa8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt
@@ -0,0 +1 @@
+:"#{field}"
diff --git a/test/prism/fixtures/seattlerb/dstr_lex_state.txt b/test/prism/fixtures/seattlerb/dstr_lex_state.txt
new file mode 100644
index 0000000000..6cac1d8e95
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/dstr_lex_state.txt
@@ -0,0 +1 @@
+"#{p:a}"
diff --git a/test/prism/fixtures/seattlerb/dstr_str.txt b/test/prism/fixtures/seattlerb/dstr_str.txt
new file mode 100644
index 0000000000..226ce2b191
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/dstr_str.txt
@@ -0,0 +1 @@
+"#{'a'} b"
diff --git a/test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt b/test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt
new file mode 100644
index 0000000000..e5781453c1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt
@@ -0,0 +1 @@
+:"Variet\303\240"
diff --git a/test/prism/fixtures/seattlerb/dsym_to_sym.txt b/test/prism/fixtures/seattlerb/dsym_to_sym.txt
new file mode 100644
index 0000000000..813c90342c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/dsym_to_sym.txt
@@ -0,0 +1,3 @@
+alias :"<<" :">>"
+
+alias :<< :>>
diff --git a/test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt b/test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt
new file mode 100644
index 0000000000..aae82e1207
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt
@@ -0,0 +1,6 @@
+1
+=begin
+comment
+comment
+=end
+2
diff --git a/test/prism/fixtures/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt b/test/prism/fixtures/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt
new file mode 100644
index 0000000000..88ff599e91
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt
@@ -0,0 +1,3 @@
+h[k]=begin
+ 42
+ end
diff --git a/test/prism/fixtures/seattlerb/evstr_evstr.txt b/test/prism/fixtures/seattlerb/evstr_evstr.txt
new file mode 100644
index 0000000000..cf0b5ee873
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/evstr_evstr.txt
@@ -0,0 +1 @@
+"#{a}#{b}"
diff --git a/test/prism/fixtures/seattlerb/evstr_str.txt b/test/prism/fixtures/seattlerb/evstr_str.txt
new file mode 100644
index 0000000000..5746909b19
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/evstr_str.txt
@@ -0,0 +1 @@
+"#{a} b"
diff --git a/test/prism/fixtures/seattlerb/expr_not_bang.txt b/test/prism/fixtures/seattlerb/expr_not_bang.txt
new file mode 100644
index 0000000000..6ed80c76d3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/expr_not_bang.txt
@@ -0,0 +1 @@
+! a b
diff --git a/test/prism/fixtures/seattlerb/f_kw.txt b/test/prism/fixtures/seattlerb/f_kw.txt
new file mode 100644
index 0000000000..4dd42662b8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/f_kw.txt
@@ -0,0 +1 @@
+def x k:42; end
diff --git a/test/prism/fixtures/seattlerb/f_kw__required.txt b/test/prism/fixtures/seattlerb/f_kw__required.txt
new file mode 100644
index 0000000000..2e1e258ff0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/f_kw__required.txt
@@ -0,0 +1 @@
+def x k:; end
diff --git a/test/prism/fixtures/seattlerb/flip2_env_lvar.txt b/test/prism/fixtures/seattlerb/flip2_env_lvar.txt
new file mode 100644
index 0000000000..619b2c915e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/flip2_env_lvar.txt
@@ -0,0 +1 @@
+if a..b then end
diff --git a/test/prism/fixtures/seattlerb/float_with_if_modifier.txt b/test/prism/fixtures/seattlerb/float_with_if_modifier.txt
new file mode 100644
index 0000000000..6a62d4a308
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/float_with_if_modifier.txt
@@ -0,0 +1 @@
+1.0if true
diff --git a/test/prism/fixtures/seattlerb/heredoc__backslash_dos_format.txt b/test/prism/fixtures/seattlerb/heredoc__backslash_dos_format.txt
new file mode 100644
index 0000000000..cfbcb2a11d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc__backslash_dos_format.txt
@@ -0,0 +1,5 @@
+str = <<-XXX
+before\
+after
+XXX
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_backslash_nl.txt b/test/prism/fixtures/seattlerb/heredoc_backslash_nl.txt
new file mode 100644
index 0000000000..0cc5b35fd5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_backslash_nl.txt
@@ -0,0 +1,8 @@
+" why would someone do this? \
+ blah
+"
+
+<<-DESC
+ why would someone do this? \
+ blah
+DESC
diff --git a/test/prism/fixtures/seattlerb/heredoc_bad_hex_escape.txt b/test/prism/fixtures/seattlerb/heredoc_bad_hex_escape.txt
new file mode 100644
index 0000000000..2c386cc6a9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_bad_hex_escape.txt
@@ -0,0 +1,3 @@
+s = <<eos
+a\xE9b
+eos
diff --git a/test/prism/fixtures/seattlerb/heredoc_bad_oct_escape.txt b/test/prism/fixtures/seattlerb/heredoc_bad_oct_escape.txt
new file mode 100644
index 0000000000..235a041e90
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_bad_oct_escape.txt
@@ -0,0 +1,5 @@
+s = <<-EOS
+a\247b
+cöd
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_comma_arg.txt b/test/prism/fixtures/seattlerb/heredoc_comma_arg.txt
new file mode 100644
index 0000000000..c230b12f65
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_comma_arg.txt
@@ -0,0 +1,7 @@
+[" some text
+",]
+
+[<<-FILE,
+ some text
+FILE
+]
diff --git a/test/prism/fixtures/seattlerb/heredoc_lineno.txt b/test/prism/fixtures/seattlerb/heredoc_lineno.txt
new file mode 100644
index 0000000000..73a2e3806b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_lineno.txt
@@ -0,0 +1,7 @@
+c = <<'CCC'
+line2
+line3
+line4
+CCC
+
+d = 42
diff --git a/test/prism/fixtures/seattlerb/heredoc_nested.txt b/test/prism/fixtures/seattlerb/heredoc_nested.txt
new file mode 100644
index 0000000000..508d6d3c05
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_nested.txt
@@ -0,0 +1,7 @@
+[<<A,
+#{<<B}
+b
+B
+a
+A
+0]
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly.txt
new file mode 100644
index 0000000000..e630ff62b4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly.txt
@@ -0,0 +1,7 @@
+a = <<~"EOF"
+ x
+ y
+ z
+ EOF
+
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
new file mode 100644
index 0000000000..61b62157db
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
@@ -0,0 +1,4 @@
+a = foo(<<~EOF.chop)
+
+ #{bar}baz
+ EOF
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt
new file mode 100644
index 0000000000..0d89134c87
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt
@@ -0,0 +1,7 @@
+a = <<~EOF
+ x
+
+ z
+EOF
+
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_empty.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_empty.txt
new file mode 100644
index 0000000000..4602d757fb
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly_empty.txt
@@ -0,0 +1,2 @@
+<<~A
+A
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt
new file mode 100644
index 0000000000..47ff3c9070
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt
@@ -0,0 +1,5 @@
+a = <<~EOF
+ w
+ x#{42} y
+ z
+ EOF
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_no_indent.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_no_indent.txt
new file mode 100644
index 0000000000..7076f6ef71
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly_no_indent.txt
@@ -0,0 +1,3 @@
+<<~A
+a
+A
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt
new file mode 100644
index 0000000000..b193f0473b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt
@@ -0,0 +1,6 @@
+a = <<~"EOF"
+ blah blah
+ blah blah
+ EOF
+
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt
new file mode 100644
index 0000000000..5b75dd2b59
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt
@@ -0,0 +1,6 @@
+a = <<~"EOF"
+ blah blah
+ blah blah
+ EOF
+
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt
new file mode 100644
index 0000000000..3f9198296d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt
@@ -0,0 +1,7 @@
+a = <<~EOF
+ x
+
+ z
+EOF
+
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt b/test/prism/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt
new file mode 100644
index 0000000000..12c8fac126
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt
@@ -0,0 +1,4 @@
+<<END\
+blah
+END
+.strip
diff --git a/test/prism/fixtures/seattlerb/heredoc_unicode.txt b/test/prism/fixtures/seattlerb/heredoc_unicode.txt
new file mode 100644
index 0000000000..216a5cfe24
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_unicode.txt
@@ -0,0 +1,4 @@
+<<OOTPÜT
+.
+OOTPÜT
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt b/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt
new file mode 100644
index 0000000000..cb4967d154
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt
@@ -0,0 +1,5 @@
+<<EOS
+foo\rbar
+baz\r
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt b/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt
new file mode 100644
index 0000000000..75ed936b5d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt
@@ -0,0 +1,5 @@
+<<EOS
+foo\rbar
+baz\r
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt
new file mode 100644
index 0000000000..1c58c05cc5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt
@@ -0,0 +1,4 @@
+<<'eot'
+body
+eot
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt
new file mode 100644
index 0000000000..706cb0d5c0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt
@@ -0,0 +1,5 @@
+<<EOS
+foo bar
+baz
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt
new file mode 100644
index 0000000000..8ed84799b1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt
@@ -0,0 +1,5 @@
+<<EOS
+foo bar
+baz
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt b/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt
new file mode 100644
index 0000000000..250e606f45
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt
@@ -0,0 +1,4 @@
+<<EOS
+foo\r#@bar
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt b/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt
new file mode 100644
index 0000000000..12f97aff5e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt
@@ -0,0 +1,4 @@
+<<EOS
+foo\r#@bar
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt b/test/prism/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt
new file mode 100644
index 0000000000..f94c2c9e27
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt
@@ -0,0 +1,3 @@
+<<-HEREDOC
+#${
+HEREDOC
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt b/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt
new file mode 100644
index 0000000000..468ba85cf7
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt
@@ -0,0 +1,6 @@
+<<EOS
+
+
+\r
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt b/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt
new file mode 100644
index 0000000000..e973eff110
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt
@@ -0,0 +1,6 @@
+<<EOS
+
+
+\r
+EOS
+
diff --git a/test/prism/fixtures/seattlerb/if_elsif.txt b/test/prism/fixtures/seattlerb/if_elsif.txt
new file mode 100644
index 0000000000..bc1c0a2b3d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/if_elsif.txt
@@ -0,0 +1 @@
+if 1; elsif 2; end
diff --git a/test/prism/fixtures/seattlerb/if_symbol.txt b/test/prism/fixtures/seattlerb/if_symbol.txt
new file mode 100644
index 0000000000..8d6e958ede
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/if_symbol.txt
@@ -0,0 +1 @@
+if f :x; end
diff --git a/test/prism/fixtures/seattlerb/in_expr_no_case.txt b/test/prism/fixtures/seattlerb/in_expr_no_case.txt
new file mode 100644
index 0000000000..40db7f868b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/in_expr_no_case.txt
@@ -0,0 +1 @@
+'woot' in String
diff --git a/test/prism/fixtures/seattlerb/index_0.txt b/test/prism/fixtures/seattlerb/index_0.txt
new file mode 100644
index 0000000000..050d4566ba
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/index_0.txt
@@ -0,0 +1 @@
+a[] = b
diff --git a/test/prism/fixtures/seattlerb/index_0_opasgn.txt b/test/prism/fixtures/seattlerb/index_0_opasgn.txt
new file mode 100644
index 0000000000..7189f0c3ea
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/index_0_opasgn.txt
@@ -0,0 +1 @@
+a[] += b
diff --git a/test/prism/fixtures/seattlerb/integer_with_if_modifier.txt b/test/prism/fixtures/seattlerb/integer_with_if_modifier.txt
new file mode 100644
index 0000000000..bf2f621e92
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/integer_with_if_modifier.txt
@@ -0,0 +1 @@
+1_234if true
diff --git a/test/prism/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt b/test/prism/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt
new file mode 100644
index 0000000000..f4c7cb9662
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt
@@ -0,0 +1,5 @@
+%I(
+a
+b
+)
+1
diff --git a/test/prism/fixtures/seattlerb/interpolated_word_array_line_breaks.txt b/test/prism/fixtures/seattlerb/interpolated_word_array_line_breaks.txt
new file mode 100644
index 0000000000..d52b4789cf
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/interpolated_word_array_line_breaks.txt
@@ -0,0 +1,5 @@
+%W(
+a
+b
+)
+1
diff --git a/test/prism/fixtures/seattlerb/iter_args_1.txt b/test/prism/fixtures/seattlerb/iter_args_1.txt
new file mode 100644
index 0000000000..c890ef62c3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_1.txt
@@ -0,0 +1 @@
+f { |a,b| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_10_1.txt b/test/prism/fixtures/seattlerb/iter_args_10_1.txt
new file mode 100644
index 0000000000..3f558c5392
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_10_1.txt
@@ -0,0 +1 @@
+f { |a, b = 42, *c| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_10_2.txt b/test/prism/fixtures/seattlerb/iter_args_10_2.txt
new file mode 100644
index 0000000000..4158e79d14
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_10_2.txt
@@ -0,0 +1 @@
+f { |a, b = 42, *c, &d| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_11_1.txt b/test/prism/fixtures/seattlerb/iter_args_11_1.txt
new file mode 100644
index 0000000000..f86175c1a0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_11_1.txt
@@ -0,0 +1 @@
+f { |a, b = 42, *c, d| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_11_2.txt b/test/prism/fixtures/seattlerb/iter_args_11_2.txt
new file mode 100644
index 0000000000..e4b017e44a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_11_2.txt
@@ -0,0 +1 @@
+f { |a, b = 42, *c, d, &e| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_2__19.txt b/test/prism/fixtures/seattlerb/iter_args_2__19.txt
new file mode 100644
index 0000000000..84dd744243
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_2__19.txt
@@ -0,0 +1 @@
+f { |(a, b)| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_3.txt b/test/prism/fixtures/seattlerb/iter_args_3.txt
new file mode 100644
index 0000000000..261968ff13
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_3.txt
@@ -0,0 +1 @@
+f { |a, (b, c), d| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_4.txt b/test/prism/fixtures/seattlerb/iter_args_4.txt
new file mode 100644
index 0000000000..7db4d43ad3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_4.txt
@@ -0,0 +1 @@
+f { |a, *b, c| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_5.txt b/test/prism/fixtures/seattlerb/iter_args_5.txt
new file mode 100644
index 0000000000..088fcdfcc5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_5.txt
@@ -0,0 +1 @@
+f { |a, &b| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_6.txt b/test/prism/fixtures/seattlerb/iter_args_6.txt
new file mode 100644
index 0000000000..e980ec064b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_6.txt
@@ -0,0 +1 @@
+f { |a, b=42, c| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_7_1.txt b/test/prism/fixtures/seattlerb/iter_args_7_1.txt
new file mode 100644
index 0000000000..e1dbf4b312
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_7_1.txt
@@ -0,0 +1 @@
+f { |a = 42, *b| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_7_2.txt b/test/prism/fixtures/seattlerb/iter_args_7_2.txt
new file mode 100644
index 0000000000..e46e78e00e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_7_2.txt
@@ -0,0 +1 @@
+f { |a = 42, *b, &c| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_8_1.txt b/test/prism/fixtures/seattlerb/iter_args_8_1.txt
new file mode 100644
index 0000000000..a0ec82ea5b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_8_1.txt
@@ -0,0 +1 @@
+f { |a = 42, *b, c| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_8_2.txt b/test/prism/fixtures/seattlerb/iter_args_8_2.txt
new file mode 100644
index 0000000000..a1839fe706
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_8_2.txt
@@ -0,0 +1 @@
+f { |a = 42, *b, c, &d| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_9_1.txt b/test/prism/fixtures/seattlerb/iter_args_9_1.txt
new file mode 100644
index 0000000000..13e5b20fe7
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_9_1.txt
@@ -0,0 +1 @@
+f { |a = 42, b| }
diff --git a/test/prism/fixtures/seattlerb/iter_args_9_2.txt b/test/prism/fixtures/seattlerb/iter_args_9_2.txt
new file mode 100644
index 0000000000..83f6e1e029
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_args_9_2.txt
@@ -0,0 +1 @@
+f { |a = 42, b, &c| }
diff --git a/test/prism/fixtures/seattlerb/iter_kwarg.txt b/test/prism/fixtures/seattlerb/iter_kwarg.txt
new file mode 100644
index 0000000000..d4296cad76
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_kwarg.txt
@@ -0,0 +1 @@
+a { |b: 1| }
diff --git a/test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt b/test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt
new file mode 100644
index 0000000000..dd0ea13a6f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt
@@ -0,0 +1 @@
+a { |b: 1, **c| }
diff --git a/test/prism/fixtures/seattlerb/label_vs_string.txt b/test/prism/fixtures/seattlerb/label_vs_string.txt
new file mode 100644
index 0000000000..27ba8b64de
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/label_vs_string.txt
@@ -0,0 +1,2 @@
+_buf << ':
+'
diff --git a/test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt b/test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt
new file mode 100644
index 0000000000..bbf663a46a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt
@@ -0,0 +1,7 @@
+f -> do end
+
+f -> {}
+
+f ->() do end
+
+f ->() {}
diff --git a/test/prism/fixtures/seattlerb/lasgn_arg_rescue_arg.txt b/test/prism/fixtures/seattlerb/lasgn_arg_rescue_arg.txt
new file mode 100644
index 0000000000..0dad496c28
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lasgn_arg_rescue_arg.txt
@@ -0,0 +1 @@
+a = 1 rescue 2
diff --git a/test/prism/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt b/test/prism/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt
new file mode 100644
index 0000000000..3f63c0b748
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt
@@ -0,0 +1 @@
+a = b(1) rescue 2
diff --git a/test/prism/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt b/test/prism/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt
new file mode 100644
index 0000000000..0e86f1587d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt
@@ -0,0 +1 @@
+a = b 1 rescue 2
diff --git a/test/prism/fixtures/seattlerb/lasgn_command.txt b/test/prism/fixtures/seattlerb/lasgn_command.txt
new file mode 100644
index 0000000000..aca35b880c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lasgn_command.txt
@@ -0,0 +1 @@
+a = b.c 1
diff --git a/test/prism/fixtures/seattlerb/lasgn_env.txt b/test/prism/fixtures/seattlerb/lasgn_env.txt
new file mode 100644
index 0000000000..aec10273e5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lasgn_env.txt
@@ -0,0 +1 @@
+a = 42
diff --git a/test/prism/fixtures/seattlerb/lasgn_ivar_env.txt b/test/prism/fixtures/seattlerb/lasgn_ivar_env.txt
new file mode 100644
index 0000000000..2fa8471c01
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lasgn_ivar_env.txt
@@ -0,0 +1 @@
+@a = 42
diff --git a/test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt b/test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt
new file mode 100644
index 0000000000..5147131852
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt
@@ -0,0 +1 @@
+a = b = c 1
diff --git a/test/prism/fixtures/seattlerb/lasgn_middle_splat.txt b/test/prism/fixtures/seattlerb/lasgn_middle_splat.txt
new file mode 100644
index 0000000000..bb378ca680
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/lasgn_middle_splat.txt
@@ -0,0 +1 @@
+a = b, *c, d
diff --git a/test/prism/fixtures/seattlerb/magic_encoding_comment.txt b/test/prism/fixtures/seattlerb/magic_encoding_comment.txt
new file mode 100644
index 0000000000..a02711ea05
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/magic_encoding_comment.txt
@@ -0,0 +1,4 @@
+# encoding: utf-8
+class ExampleUTF8ClassNameVarietà; def self.è; così = :però; end
+end
+
diff --git a/test/prism/fixtures/seattlerb/masgn_anon_splat_arg.txt b/test/prism/fixtures/seattlerb/masgn_anon_splat_arg.txt
new file mode 100644
index 0000000000..b796a742ed
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_anon_splat_arg.txt
@@ -0,0 +1 @@
+*, a = b
diff --git a/test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt b/test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt
new file mode 100644
index 0000000000..e0919793d4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt
@@ -0,0 +1 @@
+a, b::c = d
diff --git a/test/prism/fixtures/seattlerb/masgn_arg_ident.txt b/test/prism/fixtures/seattlerb/masgn_arg_ident.txt
new file mode 100644
index 0000000000..45f248d854
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_arg_ident.txt
@@ -0,0 +1 @@
+a, b.C = d
diff --git a/test/prism/fixtures/seattlerb/masgn_arg_splat_arg.txt b/test/prism/fixtures/seattlerb/masgn_arg_splat_arg.txt
new file mode 100644
index 0000000000..05fe7c4d5f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_arg_splat_arg.txt
@@ -0,0 +1 @@
+a, *b, c = d
diff --git a/test/prism/fixtures/seattlerb/masgn_colon2.txt b/test/prism/fixtures/seattlerb/masgn_colon2.txt
new file mode 100644
index 0000000000..4e4f838d7d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_colon2.txt
@@ -0,0 +1 @@
+a, b::C = 1, 2
diff --git a/test/prism/fixtures/seattlerb/masgn_colon3.txt b/test/prism/fixtures/seattlerb/masgn_colon3.txt
new file mode 100644
index 0000000000..46098ba8c5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_colon3.txt
@@ -0,0 +1 @@
+::A, ::B = 1, 2
diff --git a/test/prism/fixtures/seattlerb/masgn_command_call.txt b/test/prism/fixtures/seattlerb/masgn_command_call.txt
new file mode 100644
index 0000000000..6da01e8a31
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_command_call.txt
@@ -0,0 +1 @@
+a, = b.c 1
diff --git a/test/prism/fixtures/seattlerb/masgn_double_paren.txt b/test/prism/fixtures/seattlerb/masgn_double_paren.txt
new file mode 100644
index 0000000000..ffac0a85a3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_double_paren.txt
@@ -0,0 +1 @@
+((a,b))=c
diff --git a/test/prism/fixtures/seattlerb/masgn_lhs_splat.txt b/test/prism/fixtures/seattlerb/masgn_lhs_splat.txt
new file mode 100644
index 0000000000..2419ef1671
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_lhs_splat.txt
@@ -0,0 +1 @@
+*a = 1, 2, 3
diff --git a/test/prism/fixtures/seattlerb/masgn_paren.txt b/test/prism/fixtures/seattlerb/masgn_paren.txt
new file mode 100644
index 0000000000..3889b9ff48
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_paren.txt
@@ -0,0 +1 @@
+(a, b) = c.d
diff --git a/test/prism/fixtures/seattlerb/masgn_splat_arg.txt b/test/prism/fixtures/seattlerb/masgn_splat_arg.txt
new file mode 100644
index 0000000000..a7c91425b0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_splat_arg.txt
@@ -0,0 +1 @@
+*a, b = c
diff --git a/test/prism/fixtures/seattlerb/masgn_splat_arg_arg.txt b/test/prism/fixtures/seattlerb/masgn_splat_arg_arg.txt
new file mode 100644
index 0000000000..46196bd703
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_splat_arg_arg.txt
@@ -0,0 +1 @@
+*a, b, c = d
diff --git a/test/prism/fixtures/seattlerb/masgn_star.txt b/test/prism/fixtures/seattlerb/masgn_star.txt
new file mode 100644
index 0000000000..c5eea37de2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_star.txt
@@ -0,0 +1 @@
+* = 1
diff --git a/test/prism/fixtures/seattlerb/masgn_var_star_var.txt b/test/prism/fixtures/seattlerb/masgn_var_star_var.txt
new file mode 100644
index 0000000000..04089c36ac
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/masgn_var_star_var.txt
@@ -0,0 +1 @@
+a, *, b = c
diff --git a/test/prism/fixtures/seattlerb/messy_op_asgn_lineno.txt b/test/prism/fixtures/seattlerb/messy_op_asgn_lineno.txt
new file mode 100644
index 0000000000..a7d1035ae3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/messy_op_asgn_lineno.txt
@@ -0,0 +1 @@
+a (B::C *= d e)
diff --git a/test/prism/fixtures/seattlerb/method_call_assoc_trailing_comma.txt b/test/prism/fixtures/seattlerb/method_call_assoc_trailing_comma.txt
new file mode 100644
index 0000000000..86f0fbdfc9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/method_call_assoc_trailing_comma.txt
@@ -0,0 +1 @@
+a.f(1=>2,)
diff --git a/test/prism/fixtures/seattlerb/method_call_trailing_comma.txt b/test/prism/fixtures/seattlerb/method_call_trailing_comma.txt
new file mode 100644
index 0000000000..1a155fba12
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/method_call_trailing_comma.txt
@@ -0,0 +1 @@
+a.f(1,)
diff --git a/test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt b/test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt
new file mode 100644
index 0000000000..7389b95563
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt
@@ -0,0 +1 @@
+a, b, c, * = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_back_splat.txt b/test/prism/fixtures/seattlerb/mlhs_back_splat.txt
new file mode 100644
index 0000000000..ec5d23889a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/mlhs_back_splat.txt
@@ -0,0 +1 @@
+a, b, c, *s = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_front_anonsplat.txt b/test/prism/fixtures/seattlerb/mlhs_front_anonsplat.txt
new file mode 100644
index 0000000000..67e569438c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/mlhs_front_anonsplat.txt
@@ -0,0 +1 @@
+*, x, y, z = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_front_splat.txt b/test/prism/fixtures/seattlerb/mlhs_front_splat.txt
new file mode 100644
index 0000000000..dabadc382d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/mlhs_front_splat.txt
@@ -0,0 +1 @@
+*s, x, y, z = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_keyword.txt b/test/prism/fixtures/seattlerb/mlhs_keyword.txt
new file mode 100644
index 0000000000..899e7f8ed3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/mlhs_keyword.txt
@@ -0,0 +1 @@
+a.!=(true, true)
diff --git a/test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt b/test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt
new file mode 100644
index 0000000000..a70a7e531b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt
@@ -0,0 +1 @@
+a, b, c, *, x, y, z = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_mid_splat.txt b/test/prism/fixtures/seattlerb/mlhs_mid_splat.txt
new file mode 100644
index 0000000000..2d23fd3966
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/mlhs_mid_splat.txt
@@ -0,0 +1 @@
+a, b, c, *s, x, y, z = f
diff --git a/test/prism/fixtures/seattlerb/mlhs_rescue.txt b/test/prism/fixtures/seattlerb/mlhs_rescue.txt
new file mode 100644
index 0000000000..b4c79ae32e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/mlhs_rescue.txt
@@ -0,0 +1 @@
+a, b = f rescue 42
diff --git a/test/prism/fixtures/seattlerb/module_comments.txt b/test/prism/fixtures/seattlerb/module_comments.txt
new file mode 100644
index 0000000000..cecb717c5b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/module_comments.txt
@@ -0,0 +1,10 @@
+# blah 1
+
+ # blah 2
+
+module X
+ # blah 3
+ def blah
+ # blah 4
+ end
+end
diff --git a/test/prism/fixtures/seattlerb/multiline_hash_declaration.txt b/test/prism/fixtures/seattlerb/multiline_hash_declaration.txt
new file mode 100644
index 0000000000..21530307d2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/multiline_hash_declaration.txt
@@ -0,0 +1,8 @@
+f(state:
+ {
+})
+
+f(state: {
+})
+
+f(state: {})
diff --git a/test/prism/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt b/test/prism/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt
new file mode 100644
index 0000000000..1e14673f4e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt
@@ -0,0 +1,5 @@
+%i(
+a
+b
+)
+1
diff --git a/test/prism/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt b/test/prism/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt
new file mode 100644
index 0000000000..79c1418770
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt
@@ -0,0 +1,5 @@
+%w(
+a
+b
+)
+1
diff --git a/test/prism/fixtures/seattlerb/op_asgn_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_command_call.txt
new file mode 100644
index 0000000000..92c989cb0d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/op_asgn_command_call.txt
@@ -0,0 +1 @@
+a ||= b.c 2
diff --git a/test/prism/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt
new file mode 100644
index 0000000000..89cfccda66
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt
@@ -0,0 +1 @@
+A.B ||= c 1
diff --git a/test/prism/fixtures/seattlerb/op_asgn_index_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_index_command_call.txt
new file mode 100644
index 0000000000..2bfced81fe
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/op_asgn_index_command_call.txt
@@ -0,0 +1 @@
+a[:b] ||= c 1, 2
diff --git a/test/prism/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt
new file mode 100644
index 0000000000..a567f60e83
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt
@@ -0,0 +1 @@
+A::B *= c d
diff --git a/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt
new file mode 100644
index 0000000000..0784b49167
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt
@@ -0,0 +1 @@
+A::b += 1
diff --git a/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
new file mode 100644
index 0000000000..c0f16eb3c1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
@@ -0,0 +1 @@
+A::b *= c d
diff --git a/test/prism/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt
new file mode 100644
index 0000000000..69057abf04
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt
@@ -0,0 +1 @@
+a.b ||= c 1
diff --git a/test/prism/fixtures/seattlerb/parse_def_special_name.txt b/test/prism/fixtures/seattlerb/parse_def_special_name.txt
new file mode 100644
index 0000000000..8d7d06c688
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_def_special_name.txt
@@ -0,0 +1 @@
+def next; end
diff --git a/test/prism/fixtures/seattlerb/parse_if_not_canonical.txt b/test/prism/fixtures/seattlerb/parse_if_not_canonical.txt
new file mode 100644
index 0000000000..1fd9bb7327
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_if_not_canonical.txt
@@ -0,0 +1,2 @@
+if not var.nil? then 'foo' else 'bar'
+end
diff --git a/test/prism/fixtures/seattlerb/parse_if_not_noncanonical.txt b/test/prism/fixtures/seattlerb/parse_if_not_noncanonical.txt
new file mode 100644
index 0000000000..1fd9bb7327
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_if_not_noncanonical.txt
@@ -0,0 +1,2 @@
+if not var.nil? then 'foo' else 'bar'
+end
diff --git a/test/prism/fixtures/seattlerb/parse_line_block.txt b/test/prism/fixtures/seattlerb/parse_line_block.txt
new file mode 100644
index 0000000000..21664649db
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_block.txt
@@ -0,0 +1,2 @@
+a = 42
+p a
diff --git a/test/prism/fixtures/seattlerb/parse_line_block_inline_comment.txt b/test/prism/fixtures/seattlerb/parse_line_block_inline_comment.txt
new file mode 100644
index 0000000000..f55ced714f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_block_inline_comment.txt
@@ -0,0 +1,3 @@
+a
+b # comment
+c
diff --git a/test/prism/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt b/test/prism/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt
new file mode 100644
index 0000000000..6f1fee62a0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt
@@ -0,0 +1,7 @@
+
+
+
+a
+b # comment
+# another comment
+c
diff --git a/test/prism/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt b/test/prism/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt
new file mode 100644
index 0000000000..b00de34dc0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt
@@ -0,0 +1,4 @@
+a
+b # comment
+# another comment
+c
diff --git a/test/prism/fixtures/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt b/test/prism/fixtures/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt
new file mode 100644
index 0000000000..73785eb794
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt
@@ -0,0 +1,2 @@
+a @b
+
diff --git a/test/prism/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt b/test/prism/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt
new file mode 100644
index 0000000000..6f136e6d6f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt
@@ -0,0 +1,2 @@
+a(@b
+)
diff --git a/test/prism/fixtures/seattlerb/parse_line_call_no_args.txt b/test/prism/fixtures/seattlerb/parse_line_call_no_args.txt
new file mode 100644
index 0000000000..7900afd4b8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_call_no_args.txt
@@ -0,0 +1,3 @@
+f do |x, y|
+ x + y
+end
diff --git a/test/prism/fixtures/seattlerb/parse_line_defn_complex.txt b/test/prism/fixtures/seattlerb/parse_line_defn_complex.txt
new file mode 100644
index 0000000000..244a8e862b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_defn_complex.txt
@@ -0,0 +1,5 @@
+def x(y)
+ p(y)
+ y *= 2
+ return y;
+end
diff --git a/test/prism/fixtures/seattlerb/parse_line_defn_no_parens.txt b/test/prism/fixtures/seattlerb/parse_line_defn_no_parens.txt
new file mode 100644
index 0000000000..373ca7fbec
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_defn_no_parens.txt
@@ -0,0 +1,6 @@
+def f
+
+end
+
+def f
+end
diff --git a/test/prism/fixtures/seattlerb/parse_line_defn_no_parens_args.txt b/test/prism/fixtures/seattlerb/parse_line_defn_no_parens_args.txt
new file mode 100644
index 0000000000..10f004a149
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_defn_no_parens_args.txt
@@ -0,0 +1,2 @@
+def f a
+end
diff --git a/test/prism/fixtures/seattlerb/parse_line_dot2.txt b/test/prism/fixtures/seattlerb/parse_line_dot2.txt
new file mode 100644
index 0000000000..61c7554221
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_dot2.txt
@@ -0,0 +1,5 @@
+0..
+4
+a..
+b
+c
diff --git a/test/prism/fixtures/seattlerb/parse_line_dot2_open.txt b/test/prism/fixtures/seattlerb/parse_line_dot2_open.txt
new file mode 100644
index 0000000000..b3e1e5aaf9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_dot2_open.txt
@@ -0,0 +1,3 @@
+0..
+; a..
+; c
diff --git a/test/prism/fixtures/seattlerb/parse_line_dot3.txt b/test/prism/fixtures/seattlerb/parse_line_dot3.txt
new file mode 100644
index 0000000000..d1866b41de
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_dot3.txt
@@ -0,0 +1,5 @@
+0...
+4
+a...
+b
+c
diff --git a/test/prism/fixtures/seattlerb/parse_line_dot3_open.txt b/test/prism/fixtures/seattlerb/parse_line_dot3_open.txt
new file mode 100644
index 0000000000..38e7634b21
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_dot3_open.txt
@@ -0,0 +1,3 @@
+0...
+; a...
+; c
diff --git a/test/prism/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt b/test/prism/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt
new file mode 100644
index 0000000000..29c1754915
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt
@@ -0,0 +1,3 @@
+"a\n#{
+}"
+true
diff --git a/test/prism/fixtures/seattlerb/parse_line_dstr_soft_newline.txt b/test/prism/fixtures/seattlerb/parse_line_dstr_soft_newline.txt
new file mode 100644
index 0000000000..e4dbd7bcb2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_dstr_soft_newline.txt
@@ -0,0 +1,4 @@
+"a
+#{
+}"
+true
diff --git a/test/prism/fixtures/seattlerb/parse_line_evstr_after_break.txt b/test/prism/fixtures/seattlerb/parse_line_evstr_after_break.txt
new file mode 100644
index 0000000000..c1d91a51c4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_evstr_after_break.txt
@@ -0,0 +1,2 @@
+"a"\
+"#{b}"
diff --git a/test/prism/fixtures/seattlerb/parse_line_hash_lit.txt b/test/prism/fixtures/seattlerb/parse_line_hash_lit.txt
new file mode 100644
index 0000000000..25f8c90a06
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_hash_lit.txt
@@ -0,0 +1,3 @@
+{
+:s1 => 1,
+}
diff --git a/test/prism/fixtures/seattlerb/parse_line_heredoc.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc.txt
new file mode 100644
index 0000000000..201339534c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_heredoc.txt
@@ -0,0 +1,5 @@
+ string = <<-HEREDOC.strip
+ very long string
+ HEREDOC
+ puts string
+
diff --git a/test/prism/fixtures/seattlerb/parse_line_heredoc_evstr.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc_evstr.txt
new file mode 100644
index 0000000000..d50844db4b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_heredoc_evstr.txt
@@ -0,0 +1,4 @@
+<<-A
+a
+#{b}
+A
diff --git a/test/prism/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt
new file mode 100644
index 0000000000..3fbf0f2c26
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt
@@ -0,0 +1,7 @@
+<<-EOFOO
+\n\n\n\n\n\n\n\n\n
+EOFOO
+
+class Foo
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt
new file mode 100644
index 0000000000..5dab9cf4e7
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt
@@ -0,0 +1,5 @@
+ string = <<-"^D"
+ very long string
+ ^D
+ puts string
+
diff --git a/test/prism/fixtures/seattlerb/parse_line_iter_call_no_parens.txt b/test/prism/fixtures/seattlerb/parse_line_iter_call_no_parens.txt
new file mode 100644
index 0000000000..bf1b33c8a2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_iter_call_no_parens.txt
@@ -0,0 +1,3 @@
+f a do |x, y|
+ x + y
+end
diff --git a/test/prism/fixtures/seattlerb/parse_line_iter_call_parens.txt b/test/prism/fixtures/seattlerb/parse_line_iter_call_parens.txt
new file mode 100644
index 0000000000..25e9ea1c67
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_iter_call_parens.txt
@@ -0,0 +1,3 @@
+f(a) do |x, y|
+ x + y
+end
diff --git a/test/prism/fixtures/seattlerb/parse_line_multiline_str.txt b/test/prism/fixtures/seattlerb/parse_line_multiline_str.txt
new file mode 100644
index 0000000000..cdefb3c9b7
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_multiline_str.txt
@@ -0,0 +1,3 @@
+"a
+b"
+1
diff --git a/test/prism/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt b/test/prism/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt
new file mode 100644
index 0000000000..a179ba8c9c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt
@@ -0,0 +1,2 @@
+"a\nb"
+1
diff --git a/test/prism/fixtures/seattlerb/parse_line_newlines.txt b/test/prism/fixtures/seattlerb/parse_line_newlines.txt
new file mode 100644
index 0000000000..28b0c286e8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_newlines.txt
@@ -0,0 +1,3 @@
+true
+
+
diff --git a/test/prism/fixtures/seattlerb/parse_line_op_asgn.txt b/test/prism/fixtures/seattlerb/parse_line_op_asgn.txt
new file mode 100644
index 0000000000..f2691c2ce4
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_op_asgn.txt
@@ -0,0 +1,4 @@
+ foo +=
+ bar
+ baz
+
diff --git a/test/prism/fixtures/seattlerb/parse_line_postexe.txt b/test/prism/fixtures/seattlerb/parse_line_postexe.txt
new file mode 100644
index 0000000000..fd8b318d19
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_postexe.txt
@@ -0,0 +1,3 @@
+END {
+foo
+}
diff --git a/test/prism/fixtures/seattlerb/parse_line_preexe.txt b/test/prism/fixtures/seattlerb/parse_line_preexe.txt
new file mode 100644
index 0000000000..b3eda77ebc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_preexe.txt
@@ -0,0 +1,3 @@
+BEGIN {
+foo
+}
diff --git a/test/prism/fixtures/seattlerb/parse_line_rescue.txt b/test/prism/fixtures/seattlerb/parse_line_rescue.txt
new file mode 100644
index 0000000000..a583160ce2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_rescue.txt
@@ -0,0 +1,8 @@
+begin
+ a
+rescue
+ b
+rescue
+ c
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_line_return.txt b/test/prism/fixtures/seattlerb/parse_line_return.txt
new file mode 100644
index 0000000000..81021c2644
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_return.txt
@@ -0,0 +1,6 @@
+ def blah
+ if true then
+ return 42
+ end
+ end
+
diff --git a/test/prism/fixtures/seattlerb/parse_line_str_with_newline_escape.txt b/test/prism/fixtures/seattlerb/parse_line_str_with_newline_escape.txt
new file mode 100644
index 0000000000..b2b6bb8234
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_str_with_newline_escape.txt
@@ -0,0 +1 @@
+a("\n", true)
diff --git a/test/prism/fixtures/seattlerb/parse_line_to_ary.txt b/test/prism/fixtures/seattlerb/parse_line_to_ary.txt
new file mode 100644
index 0000000000..590d0abd14
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_to_ary.txt
@@ -0,0 +1,3 @@
+a,
+b = c
+d
diff --git a/test/prism/fixtures/seattlerb/parse_line_trailing_newlines.txt b/test/prism/fixtures/seattlerb/parse_line_trailing_newlines.txt
new file mode 100644
index 0000000000..afa826fb50
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_line_trailing_newlines.txt
@@ -0,0 +1,2 @@
+a
+b
diff --git a/test/prism/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt b/test/prism/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt
new file mode 100644
index 0000000000..649c109ea1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt
@@ -0,0 +1 @@
+1[2=>3,]
diff --git a/test/prism/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt b/test/prism/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt
new file mode 100644
index 0000000000..741cd4ffd1
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt
@@ -0,0 +1 @@
+1[2,]
diff --git a/test/prism/fixtures/seattlerb/parse_pattern_019.txt b/test/prism/fixtures/seattlerb/parse_pattern_019.txt
new file mode 100644
index 0000000000..1e8a75902d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_pattern_019.txt
@@ -0,0 +1,5 @@
+case 0
+in -1..1
+ true
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_pattern_044.txt b/test/prism/fixtures/seattlerb/parse_pattern_044.txt
new file mode 100644
index 0000000000..a6a0ac6c1c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_pattern_044.txt
@@ -0,0 +1,5 @@
+case obj
+in Object[]
+ true
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_pattern_051.txt b/test/prism/fixtures/seattlerb/parse_pattern_051.txt
new file mode 100644
index 0000000000..b7cf769f50
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_pattern_051.txt
@@ -0,0 +1,5 @@
+case [0, 1, 2]
+in [0, 1,]
+ true
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_pattern_058.txt b/test/prism/fixtures/seattlerb/parse_pattern_058.txt
new file mode 100644
index 0000000000..bd7537098e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_pattern_058.txt
@@ -0,0 +1,5 @@
+case {a: 0}
+in {a:, **rest}
+ [a, rest]
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_pattern_058_2.txt b/test/prism/fixtures/seattlerb/parse_pattern_058_2.txt
new file mode 100644
index 0000000000..eb1b3cd8ab
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_pattern_058_2.txt
@@ -0,0 +1,5 @@
+case {a: 0}
+in {a:, **}
+ [a]
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_pattern_069.txt b/test/prism/fixtures/seattlerb/parse_pattern_069.txt
new file mode 100644
index 0000000000..f43dff8959
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_pattern_069.txt
@@ -0,0 +1,5 @@
+case :a
+in Object[b: 1]
+ 1
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_pattern_076.txt b/test/prism/fixtures/seattlerb/parse_pattern_076.txt
new file mode 100644
index 0000000000..bb947605b3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_pattern_076.txt
@@ -0,0 +1,5 @@
+case {a: 1}
+in {a: 1, **nil}
+ true
+end
+
diff --git a/test/prism/fixtures/seattlerb/parse_until_not_canonical.txt b/test/prism/fixtures/seattlerb/parse_until_not_canonical.txt
new file mode 100644
index 0000000000..4de38968dc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_until_not_canonical.txt
@@ -0,0 +1,3 @@
+until not var.nil?
+ 'foo'
+end
diff --git a/test/prism/fixtures/seattlerb/parse_until_not_noncanonical.txt b/test/prism/fixtures/seattlerb/parse_until_not_noncanonical.txt
new file mode 100644
index 0000000000..4de38968dc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_until_not_noncanonical.txt
@@ -0,0 +1,3 @@
+until not var.nil?
+ 'foo'
+end
diff --git a/test/prism/fixtures/seattlerb/parse_while_not_canonical.txt b/test/prism/fixtures/seattlerb/parse_while_not_canonical.txt
new file mode 100644
index 0000000000..5aa464167f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_while_not_canonical.txt
@@ -0,0 +1,3 @@
+while not var.nil?
+ 'foo'
+end
diff --git a/test/prism/fixtures/seattlerb/parse_while_not_noncanonical.txt b/test/prism/fixtures/seattlerb/parse_while_not_noncanonical.txt
new file mode 100644
index 0000000000..5aa464167f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/parse_while_not_noncanonical.txt
@@ -0,0 +1,3 @@
+while not var.nil?
+ 'foo'
+end
diff --git a/test/prism/fixtures/seattlerb/pctW_lineno.txt b/test/prism/fixtures/seattlerb/pctW_lineno.txt
new file mode 100644
index 0000000000..b222ff0174
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/pctW_lineno.txt
@@ -0,0 +1,5 @@
+%W(a\nb
+c d
+e\
+f
+gy h\y i\y)
diff --git a/test/prism/fixtures/seattlerb/pct_Q_backslash_nl.txt b/test/prism/fixtures/seattlerb/pct_Q_backslash_nl.txt
new file mode 100644
index 0000000000..d88e1fd21c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/pct_Q_backslash_nl.txt
@@ -0,0 +1,2 @@
+%Q{ \
+}
diff --git a/test/prism/fixtures/seattlerb/pct_nl.txt b/test/prism/fixtures/seattlerb/pct_nl.txt
new file mode 100644
index 0000000000..2cee1cdd44
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/pct_nl.txt
@@ -0,0 +1,3 @@
+x = %
+
+
diff --git a/test/prism/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt b/test/prism/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt
new file mode 100644
index 0000000000..4e084661bf
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt
@@ -0,0 +1,4 @@
+%W( 1 #{<<A} 3
+2
+A
+ 4 5 )
diff --git a/test/prism/fixtures/seattlerb/pipe_semicolon.txt b/test/prism/fixtures/seattlerb/pipe_semicolon.txt
new file mode 100644
index 0000000000..e692cc434f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/pipe_semicolon.txt
@@ -0,0 +1 @@
+a.b do | ; c | end
diff --git a/test/prism/fixtures/seattlerb/pipe_space.txt b/test/prism/fixtures/seattlerb/pipe_space.txt
new file mode 100644
index 0000000000..7f0df799b9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/pipe_space.txt
@@ -0,0 +1 @@
+a.b do | | end
diff --git a/test/prism/fixtures/seattlerb/qWords_space.txt b/test/prism/fixtures/seattlerb/qWords_space.txt
new file mode 100644
index 0000000000..a8299ba3f8
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/qWords_space.txt
@@ -0,0 +1 @@
+%W( )
diff --git a/test/prism/fixtures/seattlerb/qsymbols.txt b/test/prism/fixtures/seattlerb/qsymbols.txt
new file mode 100644
index 0000000000..cb9ff09ae0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/qsymbols.txt
@@ -0,0 +1 @@
+%I(a b c)
diff --git a/test/prism/fixtures/seattlerb/qsymbols_empty.txt b/test/prism/fixtures/seattlerb/qsymbols_empty.txt
new file mode 100644
index 0000000000..10a3279907
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/qsymbols_empty.txt
@@ -0,0 +1 @@
+%I()
diff --git a/test/prism/fixtures/seattlerb/qsymbols_empty_space.txt b/test/prism/fixtures/seattlerb/qsymbols_empty_space.txt
new file mode 100644
index 0000000000..819f16ad06
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/qsymbols_empty_space.txt
@@ -0,0 +1 @@
+%I( )
diff --git a/test/prism/fixtures/seattlerb/qsymbols_interp.txt b/test/prism/fixtures/seattlerb/qsymbols_interp.txt
new file mode 100644
index 0000000000..2f34883867
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/qsymbols_interp.txt
@@ -0,0 +1 @@
+%I(a b#{1+1} c)
diff --git a/test/prism/fixtures/seattlerb/quoted_symbol_hash_arg.txt b/test/prism/fixtures/seattlerb/quoted_symbol_hash_arg.txt
new file mode 100644
index 0000000000..4f1295ef18
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/quoted_symbol_hash_arg.txt
@@ -0,0 +1 @@
+puts 'a': {}
diff --git a/test/prism/fixtures/seattlerb/quoted_symbol_keys.txt b/test/prism/fixtures/seattlerb/quoted_symbol_keys.txt
new file mode 100644
index 0000000000..c6a946723d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/quoted_symbol_keys.txt
@@ -0,0 +1 @@
+{ 'a': :b }
diff --git a/test/prism/fixtures/seattlerb/qw_escape.txt b/test/prism/fixtures/seattlerb/qw_escape.txt
new file mode 100644
index 0000000000..a94a0e5dcb
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/qw_escape.txt
@@ -0,0 +1 @@
+%q(\')
diff --git a/test/prism/fixtures/seattlerb/qw_escape_term.txt b/test/prism/fixtures/seattlerb/qw_escape_term.txt
new file mode 100644
index 0000000000..9734fc3421
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/qw_escape_term.txt
@@ -0,0 +1 @@
+%q|blah blah \| blah blah|
diff --git a/test/prism/fixtures/seattlerb/qwords_empty.txt b/test/prism/fixtures/seattlerb/qwords_empty.txt
new file mode 100644
index 0000000000..69cc6679d6
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/qwords_empty.txt
@@ -0,0 +1 @@
+%w()
diff --git a/test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt b/test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt
new file mode 100644
index 0000000000..427b94cc4d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt
@@ -0,0 +1 @@
+?\u{00a0}
diff --git a/test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt b/test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt
new file mode 100644
index 0000000000..71aa7a4347
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt
@@ -0,0 +1 @@
+?\u00a0
diff --git a/test/prism/fixtures/seattlerb/regexp.txt b/test/prism/fixtures/seattlerb/regexp.txt
new file mode 100644
index 0000000000..bc06458c5c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/regexp.txt
@@ -0,0 +1,9 @@
+/wtf/
+
+/wtf/m
+
+/wtf/n
+
+/wtf/nm
+
+/wtf/nmnmnmnm
diff --git a/test/prism/fixtures/seattlerb/regexp_esc_C_slash.txt b/test/prism/fixtures/seattlerb/regexp_esc_C_slash.txt
new file mode 100644
index 0000000000..1fd9207c66
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/regexp_esc_C_slash.txt
@@ -0,0 +1 @@
+/\cC\d/
diff --git a/test/prism/fixtures/seattlerb/regexp_esc_u.txt b/test/prism/fixtures/seattlerb/regexp_esc_u.txt
new file mode 100644
index 0000000000..b91704fb0a
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/regexp_esc_u.txt
@@ -0,0 +1 @@
+/[\u0021-\u0027]/
diff --git a/test/prism/fixtures/seattlerb/regexp_escape_extended.txt b/test/prism/fixtures/seattlerb/regexp_escape_extended.txt
new file mode 100644
index 0000000000..73dcbab69c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/regexp_escape_extended.txt
@@ -0,0 +1 @@
+/\“/
diff --git a/test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt b/test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt
new file mode 100644
index 0000000000..5a02bd92ca
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt
@@ -0,0 +1,3 @@
+/\u{c0de babe}/
+
+/\u{df}/
diff --git a/test/prism/fixtures/seattlerb/required_kwarg_no_value.txt b/test/prism/fixtures/seattlerb/required_kwarg_no_value.txt
new file mode 100644
index 0000000000..453bcbb33b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/required_kwarg_no_value.txt
@@ -0,0 +1,2 @@
+def x a:, b:
+end
diff --git a/test/prism/fixtures/seattlerb/rescue_do_end_ensure_result.txt b/test/prism/fixtures/seattlerb/rescue_do_end_ensure_result.txt
new file mode 100644
index 0000000000..7049be66c5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/rescue_do_end_ensure_result.txt
@@ -0,0 +1,5 @@
+proc do
+ :begin
+ensure
+ :ensure
+end.call
diff --git a/test/prism/fixtures/seattlerb/rescue_do_end_no_raise.txt b/test/prism/fixtures/seattlerb/rescue_do_end_no_raise.txt
new file mode 100644
index 0000000000..5f16ec2f15
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/rescue_do_end_no_raise.txt
@@ -0,0 +1,9 @@
+tap do
+ :begin
+rescue
+ :rescue
+else
+ :else
+ensure
+ :ensure
+end
diff --git a/test/prism/fixtures/seattlerb/rescue_do_end_raised.txt b/test/prism/fixtures/seattlerb/rescue_do_end_raised.txt
new file mode 100644
index 0000000000..d04215eb48
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/rescue_do_end_raised.txt
@@ -0,0 +1,5 @@
+tap do
+ raise
+ensure
+ :ensure
+end
diff --git a/test/prism/fixtures/seattlerb/rescue_do_end_rescued.txt b/test/prism/fixtures/seattlerb/rescue_do_end_rescued.txt
new file mode 100644
index 0000000000..4b377511f0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/rescue_do_end_rescued.txt
@@ -0,0 +1,9 @@
+tap do
+ raise
+rescue
+ :rescue
+else
+ :else
+ensure
+ :ensure
+end
diff --git a/test/prism/fixtures/seattlerb/rescue_in_block.txt b/test/prism/fixtures/seattlerb/rescue_in_block.txt
new file mode 100644
index 0000000000..c6e834aa1e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/rescue_in_block.txt
@@ -0,0 +1,4 @@
+blah do
+rescue
+ stuff
+end
diff --git a/test/prism/fixtures/seattlerb/rescue_parens.txt b/test/prism/fixtures/seattlerb/rescue_parens.txt
new file mode 100644
index 0000000000..f0eb4db417
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/rescue_parens.txt
@@ -0,0 +1 @@
+a (b rescue c)
diff --git a/test/prism/fixtures/seattlerb/return_call_assocs.txt b/test/prism/fixtures/seattlerb/return_call_assocs.txt
new file mode 100644
index 0000000000..34ea778f17
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/return_call_assocs.txt
@@ -0,0 +1,11 @@
+return 1, :z => 1
+
+return 1, :z => 1, :w => 2
+
+return y :z=>1
+
+return y z:1
+
+return y(z:1)
+
+return y(z=>1)
diff --git a/test/prism/fixtures/seattlerb/rhs_asgn.txt b/test/prism/fixtures/seattlerb/rhs_asgn.txt
new file mode 100644
index 0000000000..ca581031e2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/rhs_asgn.txt
@@ -0,0 +1 @@
+42 => n
diff --git a/test/prism/fixtures/seattlerb/ruby21_numbers.txt b/test/prism/fixtures/seattlerb/ruby21_numbers.txt
new file mode 100644
index 0000000000..34ceb63a0c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/ruby21_numbers.txt
@@ -0,0 +1 @@
+[1i, 2r, 3ri]
diff --git a/test/prism/fixtures/seattlerb/safe_attrasgn.txt b/test/prism/fixtures/seattlerb/safe_attrasgn.txt
new file mode 100644
index 0000000000..1279e02cfc
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_attrasgn.txt
@@ -0,0 +1 @@
+a&.b = 1
diff --git a/test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt b/test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt
new file mode 100644
index 0000000000..3a17ac6bcf
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt
@@ -0,0 +1 @@
+a&.B = 1
diff --git a/test/prism/fixtures/seattlerb/safe_call.txt b/test/prism/fixtures/seattlerb/safe_call.txt
new file mode 100644
index 0000000000..8ecd27e0fe
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_call.txt
@@ -0,0 +1 @@
+a&.b
diff --git a/test/prism/fixtures/seattlerb/safe_call_after_newline.txt b/test/prism/fixtures/seattlerb/safe_call_after_newline.txt
new file mode 100644
index 0000000000..58e3fba554
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_call_after_newline.txt
@@ -0,0 +1,2 @@
+a
+&.b
diff --git a/test/prism/fixtures/seattlerb/safe_call_dot_parens.txt b/test/prism/fixtures/seattlerb/safe_call_dot_parens.txt
new file mode 100644
index 0000000000..5def076640
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_call_dot_parens.txt
@@ -0,0 +1 @@
+a&.()
diff --git a/test/prism/fixtures/seattlerb/safe_call_newline.txt b/test/prism/fixtures/seattlerb/safe_call_newline.txt
new file mode 100644
index 0000000000..8778b46585
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_call_newline.txt
@@ -0,0 +1,2 @@
+a&.b
+
diff --git a/test/prism/fixtures/seattlerb/safe_call_operator.txt b/test/prism/fixtures/seattlerb/safe_call_operator.txt
new file mode 100644
index 0000000000..f3fe2b0392
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_call_operator.txt
@@ -0,0 +1 @@
+a&.> 1
diff --git a/test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt b/test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt
new file mode 100644
index 0000000000..d3b07b77b2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt
@@ -0,0 +1,2 @@
+c = a&.b
+
diff --git a/test/prism/fixtures/seattlerb/safe_calls.txt b/test/prism/fixtures/seattlerb/safe_calls.txt
new file mode 100644
index 0000000000..eafeace500
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_calls.txt
@@ -0,0 +1 @@
+a&.b&.c(1)
diff --git a/test/prism/fixtures/seattlerb/safe_op_asgn.txt b/test/prism/fixtures/seattlerb/safe_op_asgn.txt
new file mode 100644
index 0000000000..8915a1cccf
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_op_asgn.txt
@@ -0,0 +1 @@
+a&.b += x 1
diff --git a/test/prism/fixtures/seattlerb/safe_op_asgn2.txt b/test/prism/fixtures/seattlerb/safe_op_asgn2.txt
new file mode 100644
index 0000000000..0960b2548b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/safe_op_asgn2.txt
@@ -0,0 +1,2 @@
+a&.b ||=
+x;
diff --git a/test/prism/fixtures/seattlerb/slashy_newlines_within_string.txt b/test/prism/fixtures/seattlerb/slashy_newlines_within_string.txt
new file mode 100644
index 0000000000..421989c76f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/slashy_newlines_within_string.txt
@@ -0,0 +1,7 @@
+puts "hello\
+ my\
+ dear\
+ friend"
+
+a + b
+
diff --git a/test/prism/fixtures/seattlerb/stabby_arg_no_paren.txt b/test/prism/fixtures/seattlerb/stabby_arg_no_paren.txt
new file mode 100644
index 0000000000..f16bed4ccf
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/stabby_arg_no_paren.txt
@@ -0,0 +1 @@
+->a{}
diff --git a/test/prism/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt b/test/prism/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt
new file mode 100644
index 0000000000..87a7c5dad3
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt
@@ -0,0 +1 @@
+->(b, c=1, *d, e, &f){}
diff --git a/test/prism/fixtures/seattlerb/stabby_block_iter_call.txt b/test/prism/fixtures/seattlerb/stabby_block_iter_call.txt
new file mode 100644
index 0000000000..5e9e3f5527
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/stabby_block_iter_call.txt
@@ -0,0 +1,4 @@
+x -> () do
+a.b do
+end
+end
diff --git a/test/prism/fixtures/seattlerb/stabby_block_iter_call_no_target_with_arg.txt b/test/prism/fixtures/seattlerb/stabby_block_iter_call_no_target_with_arg.txt
new file mode 100644
index 0000000000..7235394751
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/stabby_block_iter_call_no_target_with_arg.txt
@@ -0,0 +1,4 @@
+x -> () do
+a(1) do
+end
+end
diff --git a/test/prism/fixtures/seattlerb/stabby_block_kw.txt b/test/prism/fixtures/seattlerb/stabby_block_kw.txt
new file mode 100644
index 0000000000..74d9e0a328
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/stabby_block_kw.txt
@@ -0,0 +1 @@
+-> (k:42) { }
diff --git a/test/prism/fixtures/seattlerb/stabby_block_kw__required.txt b/test/prism/fixtures/seattlerb/stabby_block_kw__required.txt
new file mode 100644
index 0000000000..bd16ffa73c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/stabby_block_kw__required.txt
@@ -0,0 +1 @@
+-> (k:) { }
diff --git a/test/prism/fixtures/seattlerb/stabby_proc_scope.txt b/test/prism/fixtures/seattlerb/stabby_proc_scope.txt
new file mode 100644
index 0000000000..1f7f9ff52b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/stabby_proc_scope.txt
@@ -0,0 +1 @@
+->(a; b) {}
diff --git a/test/prism/fixtures/seattlerb/str_backslashes.txt b/test/prism/fixtures/seattlerb/str_backslashes.txt
new file mode 100644
index 0000000000..5fd6da361b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_backslashes.txt
@@ -0,0 +1 @@
+x '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n'
diff --git a/test/prism/fixtures/seattlerb/str_double_double_escaped_newline.txt b/test/prism/fixtures/seattlerb/str_double_double_escaped_newline.txt
new file mode 100644
index 0000000000..2b022a55f6
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_double_double_escaped_newline.txt
@@ -0,0 +1 @@
+a "\\n";b
diff --git a/test/prism/fixtures/seattlerb/str_double_escaped_newline.txt b/test/prism/fixtures/seattlerb/str_double_escaped_newline.txt
new file mode 100644
index 0000000000..e439225344
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_double_escaped_newline.txt
@@ -0,0 +1 @@
+a "\n";b
diff --git a/test/prism/fixtures/seattlerb/str_double_newline.txt b/test/prism/fixtures/seattlerb/str_double_newline.txt
new file mode 100644
index 0000000000..2d439506ca
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_double_newline.txt
@@ -0,0 +1,2 @@
+a "
+";b
diff --git a/test/prism/fixtures/seattlerb/str_evstr.txt b/test/prism/fixtures/seattlerb/str_evstr.txt
new file mode 100644
index 0000000000..86c6d1526d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_evstr.txt
@@ -0,0 +1 @@
+"a #{b}"
diff --git a/test/prism/fixtures/seattlerb/str_evstr_escape.txt b/test/prism/fixtures/seattlerb/str_evstr_escape.txt
new file mode 100644
index 0000000000..517dfd4778
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_evstr_escape.txt
@@ -0,0 +1 @@
+"a #{b}\302\275"
diff --git a/test/prism/fixtures/seattlerb/str_heredoc_interp.txt b/test/prism/fixtures/seattlerb/str_heredoc_interp.txt
new file mode 100644
index 0000000000..aa2613008c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_heredoc_interp.txt
@@ -0,0 +1,5 @@
+<<""
+#{x}
+blah2
+
+
diff --git a/test/prism/fixtures/seattlerb/str_interp_ternary_or_label.txt b/test/prism/fixtures/seattlerb/str_interp_ternary_or_label.txt
new file mode 100644
index 0000000000..fe6637678f
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_interp_ternary_or_label.txt
@@ -0,0 +1 @@
+"#{a.b? ? ""+a+"": ""}"
diff --git a/test/prism/fixtures/seattlerb/str_lit_concat_bad_encodings.txt b/test/prism/fixtures/seattlerb/str_lit_concat_bad_encodings.txt
new file mode 100644
index 0000000000..f4eb3971bb
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_lit_concat_bad_encodings.txt
@@ -0,0 +1,2 @@
+"\xE3\xD3\x8B\xE3\x83\xBC\x83\xE3\x83\xE3\x82\xB3\xA3\x82\x99" \
+ "\xE3\x83\xB3\xE3\x83\x8F\xE3\x82\x9A\xC3\xBD;foo@bar.com"
diff --git a/test/prism/fixtures/seattlerb/str_newline_hash_line_number.txt b/test/prism/fixtures/seattlerb/str_newline_hash_line_number.txt
new file mode 100644
index 0000000000..9c8f702000
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_newline_hash_line_number.txt
@@ -0,0 +1,2 @@
+"\n\n\n\n#"
+1
diff --git a/test/prism/fixtures/seattlerb/str_pct_Q_nested.txt b/test/prism/fixtures/seattlerb/str_pct_Q_nested.txt
new file mode 100644
index 0000000000..1f3d0613e5
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_pct_Q_nested.txt
@@ -0,0 +1 @@
+%Q[before [#{nest}] after]
diff --git a/test/prism/fixtures/seattlerb/str_pct_nested_nested.txt b/test/prism/fixtures/seattlerb/str_pct_nested_nested.txt
new file mode 100644
index 0000000000..cb12415215
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_pct_nested_nested.txt
@@ -0,0 +1 @@
+%{ { #{ "#{1}" } } }
diff --git a/test/prism/fixtures/seattlerb/str_pct_q.txt b/test/prism/fixtures/seattlerb/str_pct_q.txt
new file mode 100644
index 0000000000..65d71197c9
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_pct_q.txt
@@ -0,0 +1 @@
+%q{a b c}
diff --git a/test/prism/fixtures/seattlerb/str_single_double_escaped_newline.txt b/test/prism/fixtures/seattlerb/str_single_double_escaped_newline.txt
new file mode 100644
index 0000000000..2ff0aec111
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_single_double_escaped_newline.txt
@@ -0,0 +1 @@
+a '\\n';b
diff --git a/test/prism/fixtures/seattlerb/str_single_escaped_newline.txt b/test/prism/fixtures/seattlerb/str_single_escaped_newline.txt
new file mode 100644
index 0000000000..5abb8d6334
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_single_escaped_newline.txt
@@ -0,0 +1 @@
+a '\n';b
diff --git a/test/prism/fixtures/seattlerb/str_single_newline.txt b/test/prism/fixtures/seattlerb/str_single_newline.txt
new file mode 100644
index 0000000000..1033cc7e96
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_single_newline.txt
@@ -0,0 +1,2 @@
+a '
+';b
diff --git a/test/prism/fixtures/seattlerb/str_str.txt b/test/prism/fixtures/seattlerb/str_str.txt
new file mode 100644
index 0000000000..388d777dc2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_str.txt
@@ -0,0 +1 @@
+"a #{'b'}"
diff --git a/test/prism/fixtures/seattlerb/str_str_str.txt b/test/prism/fixtures/seattlerb/str_str_str.txt
new file mode 100644
index 0000000000..d64e01dc5d
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/str_str_str.txt
@@ -0,0 +1 @@
+"a #{'b'} c"
diff --git a/test/prism/fixtures/seattlerb/super_arg.txt b/test/prism/fixtures/seattlerb/super_arg.txt
new file mode 100644
index 0000000000..1b19ecd51c
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/super_arg.txt
@@ -0,0 +1 @@
+super 42
diff --git a/test/prism/fixtures/seattlerb/symbol_empty.txt b/test/prism/fixtures/seattlerb/symbol_empty.txt
new file mode 100644
index 0000000000..cbb260bb4e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/symbol_empty.txt
@@ -0,0 +1 @@
+:''
diff --git a/test/prism/fixtures/seattlerb/symbol_list.txt b/test/prism/fixtures/seattlerb/symbol_list.txt
new file mode 100644
index 0000000000..d357195184
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/symbol_list.txt
@@ -0,0 +1 @@
+%I[#{a} #{b}]
diff --git a/test/prism/fixtures/seattlerb/symbols.txt b/test/prism/fixtures/seattlerb/symbols.txt
new file mode 100644
index 0000000000..3ec930ce66
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/symbols.txt
@@ -0,0 +1 @@
+%i(a b c)
diff --git a/test/prism/fixtures/seattlerb/symbols_empty.txt b/test/prism/fixtures/seattlerb/symbols_empty.txt
new file mode 100644
index 0000000000..840948efb2
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/symbols_empty.txt
@@ -0,0 +1 @@
+%i()
diff --git a/test/prism/fixtures/seattlerb/symbols_empty_space.txt b/test/prism/fixtures/seattlerb/symbols_empty_space.txt
new file mode 100644
index 0000000000..16c2e68a2b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/symbols_empty_space.txt
@@ -0,0 +1 @@
+%i( )
diff --git a/test/prism/fixtures/seattlerb/symbols_interp.txt b/test/prism/fixtures/seattlerb/symbols_interp.txt
new file mode 100644
index 0000000000..63116eb632
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/symbols_interp.txt
@@ -0,0 +1 @@
+%i(a b#{1+1} c)
diff --git a/test/prism/fixtures/seattlerb/thingy.txt b/test/prism/fixtures/seattlerb/thingy.txt
new file mode 100644
index 0000000000..5aa598c4be
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/thingy.txt
@@ -0,0 +1,3 @@
+f.(42)
+
+f::(42)
diff --git a/test/prism/fixtures/seattlerb/uminus_float.txt b/test/prism/fixtures/seattlerb/uminus_float.txt
new file mode 100644
index 0000000000..1344bfd9db
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/uminus_float.txt
@@ -0,0 +1 @@
+-0.0
diff --git a/test/prism/fixtures/seattlerb/unary_minus.txt b/test/prism/fixtures/seattlerb/unary_minus.txt
new file mode 100644
index 0000000000..66af866f85
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/unary_minus.txt
@@ -0,0 +1 @@
+-a
diff --git a/test/prism/fixtures/seattlerb/unary_plus.txt b/test/prism/fixtures/seattlerb/unary_plus.txt
new file mode 100644
index 0000000000..daea40b71e
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/unary_plus.txt
@@ -0,0 +1 @@
++a
diff --git a/test/prism/fixtures/seattlerb/unary_plus_on_literal.txt b/test/prism/fixtures/seattlerb/unary_plus_on_literal.txt
new file mode 100644
index 0000000000..752331df47
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/unary_plus_on_literal.txt
@@ -0,0 +1 @@
++:a
diff --git a/test/prism/fixtures/seattlerb/unary_tilde.txt b/test/prism/fixtures/seattlerb/unary_tilde.txt
new file mode 100644
index 0000000000..f0a507b437
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/unary_tilde.txt
@@ -0,0 +1 @@
+~a
diff --git a/test/prism/fixtures/seattlerb/utf8_bom.txt b/test/prism/fixtures/seattlerb/utf8_bom.txt
new file mode 100644
index 0000000000..c8e9e1cbae
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/utf8_bom.txt
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby -w
+p 0
+
diff --git a/test/prism/fixtures/seattlerb/when_splat.txt b/test/prism/fixtures/seattlerb/when_splat.txt
new file mode 100644
index 0000000000..6b79f5dad0
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/when_splat.txt
@@ -0,0 +1 @@
+case a; when *b then; end
diff --git a/test/prism/fixtures/seattlerb/words_interp.txt b/test/prism/fixtures/seattlerb/words_interp.txt
new file mode 100644
index 0000000000..f71486495b
--- /dev/null
+++ b/test/prism/fixtures/seattlerb/words_interp.txt
@@ -0,0 +1 @@
+%W(#{1}b)
diff --git a/test/prism/fixtures/single_method_call_with_bang.txt b/test/prism/fixtures/single_method_call_with_bang.txt
new file mode 100644
index 0000000000..929efb3053
--- /dev/null
+++ b/test/prism/fixtures/single_method_call_with_bang.txt
@@ -0,0 +1 @@
+foo!
diff --git a/test/prism/fixtures/single_quote_heredocs.txt b/test/prism/fixtures/single_quote_heredocs.txt
new file mode 100644
index 0000000000..0122b2726c
--- /dev/null
+++ b/test/prism/fixtures/single_quote_heredocs.txt
@@ -0,0 +1,3 @@
+<<-'EOS'
+ cd L:\Work\MG3710IQPro\Develop
+EOS
diff --git a/test/prism/fixtures/spanning_heredoc.txt b/test/prism/fixtures/spanning_heredoc.txt
new file mode 100644
index 0000000000..d09cb11b1f
--- /dev/null
+++ b/test/prism/fixtures/spanning_heredoc.txt
@@ -0,0 +1,63 @@
+# test regex, string, and lists that span a heredoc thanks to an escaped newline
+
+# ripper incorrectly creates a "b\nb" token instead of two separate string tokens
+pp <<-A.gsub(/b\
+a
+A
+b/, "")
+
+# ripper incorrectly creates a "d\nd" token instead of two separate string tokens
+pp <<-A, "d\
+c
+A
+d"
+
+# ripper gets this right
+pp <<-A, %q[f\
+e
+A
+f]
+
+# ripper incorrectly creates a "h\nh" token instead of two separate string tokens
+pp <<-A, %Q[h\
+g
+A
+h]
+
+# ripper can't parse this successfully, though ruby runs it correctly
+pp <<-A, %w[j\
+i
+A
+j]
+
+# ripper can't parse this successfully, though ruby runs it correctly
+# TODO: prism does not include the "\n" in "l\nl" in the AST like ruby does
+pp <<-A, %W[l\
+k
+A
+l]
+
+# ripper can't parse this successfully, though ruby runs it correctly
+pp <<-A, %i[n\
+m
+A
+n]
+
+# ripper gets this one wrong in the same way that prism does ...
+# TODO: prism does not include the "\n" in "p\np" in the AST like ruby does
+pp <<-A, %I[p\
+o
+A
+p]
+
+<<A; /\
+A
+(?<a>)/ =~ ''
+
+<<A; :'a
+A
+b'
+
+<<A; :"a
+A
+b"
diff --git a/test/prism/fixtures/spanning_heredoc_newlines.txt b/test/prism/fixtures/spanning_heredoc_newlines.txt
new file mode 100644
index 0000000000..32c9943aeb
--- /dev/null
+++ b/test/prism/fixtures/spanning_heredoc_newlines.txt
@@ -0,0 +1,23 @@
+<<A+%
+A
+
+
+<<A+%r
+A
+
+
+<<A+%q
+A
+
+
+<<A+%Q
+A
+
+
+<<A+%s
+A
+
+
+<<A+%x
+A
+
diff --git a/test/prism/fixtures/strings.txt b/test/prism/fixtures/strings.txt
new file mode 100644
index 0000000000..2ce8b738a3
--- /dev/null
+++ b/test/prism/fixtures/strings.txt
@@ -0,0 +1,105 @@
+%%abc%
+
+%^abc^
+
+%&abc&
+
+%*abc*
+
+%_abc_
+
+%+abc+
+
+%-abc-
+
+%:abc:
+
+%;abc;
+
+%'abc'
+
+%~abc~
+
+%?abc?
+
+%w{ }
+
+%/abc/
+
+%`abc`
+
+"#@@foo"
+
+%\abc\
+
+%{aaa #{bbb} ccc}
+
+%[foo[]]
+
+"foo" +
+#
+"bar"
+
+%q{abc}
+
+%s[abc]
+
+%{abc}
+
+''
+
+"abc"
+
+"#@---"
+
+"aaa #{bbb} ccc"
+
+'abc'
+
+%w[a b c]
+
+%w[a[] b[[]] c[]]
+
+%w[foo\ bar \#{1}]
+
+%w[foo\ bar baz]
+
+%W[a b#{c}d e]
+
+%W[a b c]
+
+%w[
+ a
+ b
+ c
+]
+
+'\' foo \' bar'
+
+'\\ foo \\ bar'
+
+"#$foo"
+
+"#@foo"
+
+"\x7 \x23 \x61"
+
+"\7 \43 \141"
+
+%[abc]
+
+%(abc)
+
+%@abc@
+
+%$abc$
+
+?a
+
+?a "a"
+
+%Q{abc}
+
+%^#$^#
+
+%@#@#
diff --git a/test/prism/fixtures/super.txt b/test/prism/fixtures/super.txt
new file mode 100644
index 0000000000..cd7aaf992e
--- /dev/null
+++ b/test/prism/fixtures/super.txt
@@ -0,0 +1,17 @@
+super
+
+super()
+
+super(1)
+
+super(1, 2, 3)
+
+super &:foo
+
+super(&:foo)
+
+super {}
+
+super(1, 2, 3) {}
+
+super(1, 2, 3, &:foo)
diff --git a/test/prism/fixtures/symbols.txt b/test/prism/fixtures/symbols.txt
new file mode 100644
index 0000000000..7563eb874f
--- /dev/null
+++ b/test/prism/fixtures/symbols.txt
@@ -0,0 +1,93 @@
+:'abc'
+
+:"#{var}"
+
+:"abc#{1}"
+
+[:Υ, :ά, :ŗ, :ρ]
+
+:-@
+
+:-
+
+:%
+
+:|
+
+:+@
+
+:+
+
+:/
+
+:**
+
+:*
+
+:~@
+
+[1, 1.0, 1r, 1i]
+
+:~
+
+:a
+
+%i[a b c]
+
+%i[a b#{1} #{2}c d#{3}f]
+
+%I[a b#{1} #{2}c d#{3}f]
+
+:@@a
+
+:👍
+
+%i[a\b]
+
+:$a
+
+:@a
+
+:do
+
+:&
+
+:`
+
+:!@
+
+:!~
+
+:!
+
+:[]
+
+:[]=
+
+:^
+
+:==
+
+:===
+
+:=~
+
+:>=
+
+:>>
+
+:>
+
+:<=>
+
+:<=
+
+:<<
+
+:<
+
+:__LINE__
+
+:__FILE__
+
+:__ENCODING__
diff --git a/test/prism/fixtures/ternary_operator.txt b/test/prism/fixtures/ternary_operator.txt
new file mode 100644
index 0000000000..79d2d7d837
--- /dev/null
+++ b/test/prism/fixtures/ternary_operator.txt
@@ -0,0 +1,15 @@
+a ? b : c
+
+a ? defined? b : defined? c
+
+empty??true:nil
+
+empty??false:nil
+
+empty??nil:nil
+
+a??nil:nil
+
+a ?var1 : var2
+
+nil??_a =2:1
diff --git a/test/prism/fixtures/tilde_heredocs.txt b/test/prism/fixtures/tilde_heredocs.txt
new file mode 100644
index 0000000000..cca47ef00b
--- /dev/null
+++ b/test/prism/fixtures/tilde_heredocs.txt
@@ -0,0 +1,97 @@
+<<~EOF
+ a
+#{1}
+ a
+EOF
+
+<<~EOF
+ a
+EOF
+
+<<~EOF
+ a
+ b
+ c
+EOF
+
+<<~EOF
+ #{1} a
+EOF
+
+<<~EOF
+ a #{1}
+EOF
+
+<<~EOF
+ a
+ #{1}
+EOF
+
+<<~EOF
+ a
+ #{1}
+EOF
+
+<<~EOF
+ a
+ b
+EOF
+
+<<~EOF
+ a
+ b
+EOF
+
+<<~EOF
+ a
+ b
+EOF
+
+<<~'EOF'
+ a #{1}
+EOF
+
+<<~EOF
+ a
+ b
+EOF
+
+<<~EOF
+ a
+ b
+EOF
+
+<<~EOF
+ a
+ b
+EOF
+
+<<~EOF
+ a
+
+ b
+EOF
+
+<<~EOF
+ a
+
+ b
+EOF
+
+<<~EOF
+ a
+
+
+
+ b
+EOF
+
+<<~EOF
+
+ #{1}a
+ EOF
+
+<<~EOT
+ #{1}
+ b
+EOT
diff --git a/test/prism/fixtures/undef.txt b/test/prism/fixtures/undef.txt
new file mode 100644
index 0000000000..129c349433
--- /dev/null
+++ b/test/prism/fixtures/undef.txt
@@ -0,0 +1,17 @@
+undef a
+
+undef a, b
+
+undef if
+
+undef <=>
+
+undef :a
+
+undef :a, :b, :c
+
+undef :'abc'
+
+undef :"abc#{1}"
+
+undef Constant
diff --git a/test/prism/fixtures/unescaping.txt b/test/prism/fixtures/unescaping.txt
new file mode 100644
index 0000000000..e2da5a696c
--- /dev/null
+++ b/test/prism/fixtures/unescaping.txt
@@ -0,0 +1,9 @@
+["\c#{1}"]
+
+/\c#{1}/
+
+"\c#{1}"
+
+<<~HERE
+ \c#{1}
+HERE
diff --git a/test/prism/fixtures/unless.txt b/test/prism/fixtures/unless.txt
new file mode 100644
index 0000000000..678d58991b
--- /dev/null
+++ b/test/prism/fixtures/unless.txt
@@ -0,0 +1,14 @@
+unless true; 1; end
+
+unless true
+1 else 2 end
+
+1 unless true
+
+tap { break unless true }
+
+tap { next unless true }
+
+return unless true
+
+foo :a, :b unless bar?
diff --git a/test/prism/fixtures/unparser/LICENSE b/test/prism/fixtures/unparser/LICENSE
new file mode 100644
index 0000000000..44863d7afb
--- /dev/null
+++ b/test/prism/fixtures/unparser/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2013 Markus Schirp
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/test/prism/fixtures/unparser/corpus/literal/alias.txt b/test/prism/fixtures/unparser/corpus/literal/alias.txt
new file mode 100644
index 0000000000..fb06a295e8
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/alias.txt
@@ -0,0 +1,2 @@
+alias $foo $bar
+alias :foo :bar
diff --git a/test/prism/fixtures/unparser/corpus/literal/assignment.txt b/test/prism/fixtures/unparser/corpus/literal/assignment.txt
new file mode 100644
index 0000000000..84a74e8928
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/assignment.txt
@@ -0,0 +1,53 @@
+$a = 1
+($a, $b) = [1, 2]
+((a,), b) = 1
+(*a) = []
+(*foo) = [1, 2]
+(@@a, @@b) = [1, 2]
+(@a, @b) = [1, 2]
+(a, (b, c)) = [1, [2, 3]]
+(a, *) = [1, 2]
+(a, *foo) = [1, 2]
+(a, b) = [1, 2]
+(a, b) = foo
+(a,) = foo
+(a.foo, a.bar) = [1, 2]
+(a[*foo], a[1]) = [1, 2]
+(a[0], a[1]) = [1, 2]
+(*c.foo) = 1
+::Foo = ::Bar
+@@a = 1
+@a = 1
+CONST = 1
+Name::Spaced::CONST = 1
+a = ((b, c) = 1)
+a = 1
+foo = foo()
+foo.[]=()
+foo.[]=(1, 2)
+foo.[]=true
+foo[*index] = value
+foo[1..2] = value
+foo[] = 1
+foo[a, b] = value
+foo[index] = value
+x = %()
+x.x=%()
+x[%()] = bar
+a[%()] ||= bar
+@a ||= %()
+x = <<-HEREDOC
+ #{}
+HEREDOC
+x.x=<<-HEREDOC
+ #{}
+HEREDOC
+x[] = <<-HEREDOC
+ #{}
+HEREDOC
+a[<<-HEREDOC] ||= bar
+ #{}
+HEREDOC
+@a ||= <<-HEREDOC
+ #{}
+HEREDOC
diff --git a/test/prism/fixtures/unparser/corpus/literal/block.txt b/test/prism/fixtures/unparser/corpus/literal/block.txt
new file mode 100644
index 0000000000..b2baf1dc12
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/block.txt
@@ -0,0 +1,96 @@
+foo {
+}
+foo { |a|
+}
+foo { |a,|
+}
+foo { |a,; x|
+}
+foo { |a, b|
+}
+foo(1) {
+ nil
+}
+foo { |a, *b|
+ nil
+}
+foo { |a, *|
+ nil
+}
+foo {
+ bar
+}
+foo.bar { |(a, b), c|
+ d
+}
+foo.bar { |*a; b|
+}
+foo.bar { |a; b|
+}
+foo.bar { |; a, b|
+}
+foo.bar { |*|
+ d
+}
+foo.bar { |(*)|
+ d
+}
+foo.bar { |((*))|
+ d
+}
+foo.bar { |(a, (*))|
+ d
+}
+foo.bar { |(a, b)|
+ d
+}
+foo.bar {
+}.baz
+m do
+rescue Exception => e
+end
+m do
+ foo
+rescue Exception => bar
+ bar
+end
+m do
+ bar
+rescue SomeError, *bar
+ baz
+end
+m do
+ bar
+rescue SomeError, *bar => exception
+ baz
+end
+m do
+ bar
+rescue *bar
+ baz
+end
+m do
+ bar
+rescue LoadError
+end
+m do
+ bar
+rescue
+else
+ baz
+end
+m do
+ bar
+rescue *bar => exception
+ baz
+end
+m do
+ensure
+end
+m do
+rescue
+ensure
+end
+bar {
+ _1 + _2
+}
diff --git a/test/prism/fixtures/unparser/corpus/literal/case.txt b/test/prism/fixtures/unparser/corpus/literal/case.txt
new file mode 100644
index 0000000000..c455fd7c39
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/case.txt
@@ -0,0 +1,37 @@
+case
+when bar
+ baz
+when baz
+ bar
+end
+case foo
+when bar
+when baz
+ bar
+end
+case foo
+when bar
+ baz
+when baz
+ bar
+end
+case foo
+when bar, baz
+ :other
+end
+case foo
+when *bar
+ :value
+end
+case foo
+when bar
+ baz
+else
+ :foo
+end
+case foo
+when *bar | baz
+end
+case foo
+when *bar.baz=1
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/class.txt b/test/prism/fixtures/unparser/corpus/literal/class.txt
new file mode 100644
index 0000000000..f0198625e9
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/class.txt
@@ -0,0 +1,35 @@
+class A
+end
+
+class << a
+end
+
+class << a
+ b
+end
+
+class A::B
+end
+
+class A::B::C
+end
+
+class A < B
+end
+
+class A < B::C
+end
+
+class A::B < C::D
+end
+
+class A
+ include(B.new)
+
+ def foo
+ :bar
+ end
+end
+
+class ::A
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/def.txt b/test/prism/fixtures/unparser/corpus/literal/def.txt
new file mode 100644
index 0000000000..61339bd4a6
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/def.txt
@@ -0,0 +1,134 @@
+def foo
+ a
+rescue
+ b
+else
+ c
+ensure
+ d
+end
+
+def foo
+ a rescue b
+rescue
+ b
+else
+ c
+ensure
+ d
+end
+
+def foo(bar:, baz:)
+end
+
+def foo
+end
+
+def foo
+ bar
+end
+
+def foo
+ foo
+rescue
+ bar
+ensure
+ baz
+end
+
+def foo
+ bar
+ensure
+ baz
+end
+
+def foo
+ bar
+rescue
+ baz
+end
+
+def foo(bar)
+ bar
+end
+
+def foo(bar, baz)
+ bar
+end
+
+def foo(bar = ())
+ bar
+end
+
+def foo(bar = (baz; nil))
+end
+
+def foo(bar = true)
+ bar
+end
+
+def foo(bar, baz = true)
+ bar
+end
+
+def foo(bar: 1)
+end
+
+def foo(bar: baz)
+end
+
+def foo(bar: bar())
+end
+
+def foo(*)
+ bar
+end
+
+def foo(*bar)
+ bar
+end
+
+def foo(bar, *baz)
+ bar
+end
+
+def foo(baz = true, *bor)
+ bar
+end
+
+def foo(baz = true, *bor, &block)
+ bar
+end
+
+def foo(bar, baz = true, *bor)
+ bar
+end
+
+def foo(&block)
+ bar
+end
+
+def foo(bar, &block)
+ bar
+end
+
+def foo
+ bar
+ baz
+end
+
+def f(((a)))
+end
+
+def foo(bar:, baz: "value")
+end
+
+def f
+ <<-HEREDOC
+ #{}
+ HEREDOC
+end
+
+def f
+ %()
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/defined.txt b/test/prism/fixtures/unparser/corpus/literal/defined.txt
new file mode 100644
index 0000000000..65e7c370fd
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/defined.txt
@@ -0,0 +1,3 @@
+defined?(@foo)
+defined?(Foo)
+defined?(((a, b) = [1, 2]))
diff --git a/test/prism/fixtures/unparser/corpus/literal/defs.txt b/test/prism/fixtures/unparser/corpus/literal/defs.txt
new file mode 100644
index 0000000000..b70aa9efc5
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/defs.txt
@@ -0,0 +1,40 @@
+def self.foo
+end
+
+def self.foo
+ bar
+end
+
+def self.foo
+ bar
+ baz
+end
+
+def Foo.bar
+ bar
+end
+
+def (foo { |bar|
+}).bar
+ bar
+end
+
+def (foo(1)).bar
+ bar
+end
+
+def (Foo::Bar.baz).bar
+ baz
+end
+
+def (Foo::Bar).bar
+ baz
+end
+
+def Foo.bar
+ baz
+end
+
+def foo.bar
+ baz
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/dstr.txt b/test/prism/fixtures/unparser/corpus/literal/dstr.txt
new file mode 100644
index 0000000000..8a912d28ed
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/dstr.txt
@@ -0,0 +1,37 @@
+if true
+ "#{}a"
+end
+if true
+ <<-HEREDOC
+a
+#{}a
+b
+ HEREDOC
+ x
+end
+<<-HEREDOC
+\#{}\#{}
+#{}
+#{}
+#{}
+HEREDOC
+<<-HEREDOC rescue nil
+#{}
+a
+HEREDOC
+"a#$1"
+"a#$a"
+"a#@a"
+"a#@@a"
+if true
+ return <<-HEREDOC
+ #{42}
+ HEREDOC
+end
+foo(<<-HEREDOC)
+ #{bar}
+HEREDOC
+foo(<<-HEREDOC) { |x|
+ #{bar}
+HEREDOC
+}
diff --git a/test/prism/fixtures/unparser/corpus/literal/empty.txt b/test/prism/fixtures/unparser/corpus/literal/empty.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/empty.txt
diff --git a/test/prism/fixtures/unparser/corpus/literal/empty_begin.txt b/test/prism/fixtures/unparser/corpus/literal/empty_begin.txt
new file mode 100644
index 0000000000..6a452c185a
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/empty_begin.txt
@@ -0,0 +1 @@
+()
diff --git a/test/prism/fixtures/unparser/corpus/literal/flipflop.txt b/test/prism/fixtures/unparser/corpus/literal/flipflop.txt
new file mode 100644
index 0000000000..139904a53f
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/flipflop.txt
@@ -0,0 +1,10 @@
+if ((i == 4)..(i == 4))
+ foo
+end
+if ((i == 4)...(i == 4))
+ foo
+end
+if ..foo
+end
+if foo..;
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/for.txt b/test/prism/fixtures/unparser/corpus/literal/for.txt
new file mode 100644
index 0000000000..4c19a352d9
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/for.txt
@@ -0,0 +1,12 @@
+bar(for a in bar do
+ baz
+end)
+for a in bar do
+ baz
+end
+for (a, *b) in bar do
+ baz
+end
+for (a, b) in bar do
+ baz
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/hookexe.txt b/test/prism/fixtures/unparser/corpus/literal/hookexe.txt
new file mode 100644
index 0000000000..08f14f47b3
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/hookexe.txt
@@ -0,0 +1,7 @@
+BEGIN {
+ foo
+}
+bar
+END {
+ baz
+}
diff --git a/test/prism/fixtures/unparser/corpus/literal/if.txt b/test/prism/fixtures/unparser/corpus/literal/if.txt
new file mode 100644
index 0000000000..0c13801f9e
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/if.txt
@@ -0,0 +1,36 @@
+if /foo/
+ bar
+end
+if 3
+ 9
+end
+if 4
+ 5
+else
+ 6
+end
+unless 3
+ nil
+end
+unless 3
+ 9
+end
+if foo
+end
+
+module A
+ foo = bar if foo
+end
+
+module B
+ foo = bar unless foo
+end
+unless foo
+ foo = bar
+end
+if foo { |pair|
+ pair
+}
+ pair = :foo
+ foo
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/kwbegin.txt b/test/prism/fixtures/unparser/corpus/literal/kwbegin.txt
new file mode 100644
index 0000000000..6cc1e74ca6
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/kwbegin.txt
@@ -0,0 +1,80 @@
+begin
+rescue
+end
+
+begin
+ensure
+end
+
+begin
+ a
+end
+
+begin
+ a
+rescue
+ b
+end
+
+begin
+ a
+ b
+rescue
+ b
+end
+
+begin
+rescue A
+end
+
+begin
+rescue A => foo
+end
+
+begin
+ a
+rescue A
+ b
+rescue B
+ c
+ensure
+ d
+end
+
+begin
+ begin
+ foo
+ bar
+ rescue
+ end
+rescue
+ baz
+ bar
+end
+
+begin
+ raise(Exception) rescue foo = bar
+rescue Exception
+end
+
+begin
+ foo
+rescue => bar
+ bar
+end
+
+begin
+ foo
+rescue Exception, Other => bar
+ bar
+end
+
+begin
+ bar
+rescue SomeError, *bar => exception
+ baz
+end
+
+class << self
+ undef :bar rescue nil
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/lambda.txt b/test/prism/fixtures/unparser/corpus/literal/lambda.txt
new file mode 100644
index 0000000000..4eb722dad1
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/lambda.txt
@@ -0,0 +1,13 @@
+lambda {
+}
+lambda { |a, b|
+ a
+}
+->() {
+}
+->(a) {
+}
+->(a, b) {
+}
+->(a, b; c) {
+}
diff --git a/test/prism/fixtures/unparser/corpus/literal/literal.txt b/test/prism/fixtures/unparser/corpus/literal/literal.txt
new file mode 100644
index 0000000000..2fc7cd1d79
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/literal.txt
@@ -0,0 +1,91 @@
+{ "foo" => <<-HEREDOC, "bar" => :baz }
+ #{}
+HEREDOC
+{ "foo" => %(), "bar" => :baz }
+["foo", %()]
+a(<<-HEREDOC).a
+ #{}
+HEREDOC
+a(%()).a
+{ "foo" => <<-HEREDOC, **baz }
+ #{}
+HEREDOC
+{ "foo" => %(), **baz }
+"#@a #@@a #$a"
+0
+++1
+1
+1
+1r
+1.5r
+1.3r
+5i
+-5i
+0.6i
+-0.6i
+1000000000000000000000000000000i
+1ri
+"foo" "bar"
+"foobar #{baz}"
+"foo#{1}bar"
+"\\\\#{}"
+"#{}\#{}"
+"\#{}#{}"
+"foo\\\#{@bar}"
+"\""
+"foo bar"
+"foo\nbar"
+`foo`
+`foo#{@bar}`
+`)`
+`\``
+`"`
+:foo
+:"A B"
+:foo
+:"A B"
+:"A\"B"
+:""
+/foo/
+/[^-+',.\/:@[:alnum:]\[\]]+/
+/foo#{@bar}/
+/foo#{@bar}/imx
+/#{"\u0000"}/
+/\n/
+/\n/
+/\n/x
+/\/\//x
+:"foo#{bar}baz"
+:"#{"foo"}"
+(0.0 / 0.0)..1
+1..(0.0 / 0.0)
+(0.0 / 0.0)..100
+-0.1
+0.1
+[1, 2]
+[1, (), n2]
+[1]
+[]
+[1, *@foo]
+[*@foo, 1]
+[*@foo, *@baz]
+{}
+{ () => () }
+{ 1 => 2 }
+{ 1 => 2, 3 => 4 }
+{ a: (1 rescue foo), b: 2 }
+{ a: 1, b: 2 }
+{ a: :a }
+{ :"a b" => 1 }
+{ :-@ => 1 }
+"#{}
+#{}\na"
+foo {
+ "#{}
+#{}\na"
+}
+:"a\\
+b"
+` x
+#{foo}
+#`
diff --git a/test/prism/fixtures/unparser/corpus/literal/module.txt b/test/prism/fixtures/unparser/corpus/literal/module.txt
new file mode 100644
index 0000000000..cec03f3bfd
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/module.txt
@@ -0,0 +1,16 @@
+module A
+end
+
+module A::B
+end
+
+module A::B::C
+end
+
+module A
+ include(B.new)
+
+ def foo
+ :bar
+ end
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/opasgn.txt b/test/prism/fixtures/unparser/corpus/literal/opasgn.txt
new file mode 100644
index 0000000000..5858d773d0
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/opasgn.txt
@@ -0,0 +1,24 @@
+a += 2
+a -= 2
+a **= 2
+a *= 2
+a /= 2
+a &&= b
+a ||= 2
+(a ||= 2).bar
+(h ||= {})[k] = v
+a.b += 2
+a.b -= 2
+a.b **= 2
+a.b *= 2
+a.b /= 2
+a.b &&= b
+a.b ||= 2
+a[b] += 2
+a[b] -= 2
+a[b] **= 2
+a[b] *= 2
+a[b] /= 2
+a[b] &&= b
+a[b] ||= 2
+foo.A += 1
diff --git a/test/prism/fixtures/unparser/corpus/literal/pattern.txt b/test/prism/fixtures/unparser/corpus/literal/pattern.txt
new file mode 100644
index 0000000000..7cfaa4dc67
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/pattern.txt
@@ -0,0 +1,41 @@
+case foo
+in A[1, 2, *a, 3] then
+ true
+in [1, 2, ] then
+ y
+in A(x:) then
+ true
+in {**a} then
+ true
+in {} if true then
+ true
+in [x, y, *] then
+ true
+in {a: 1, aa: 2} then
+ true
+in {} then
+ true
+in {**nil} then
+ true
+in {"a": 1} then
+ true
+in 1 | 2 then
+ true
+in 1 => a then
+ true
+in ^x then
+ true
+in 1
+in 2 then
+ true
+else
+ true
+end
+case foo
+in A[1, 2, *a, 3]
+end
+case foo
+in A
+else
+end
+1 in [a]
diff --git a/test/prism/fixtures/unparser/corpus/literal/pragma.txt b/test/prism/fixtures/unparser/corpus/literal/pragma.txt
new file mode 100644
index 0000000000..4f6dd71b38
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/pragma.txt
@@ -0,0 +1,4 @@
+__ENCODING__
+__FILE__
+__LINE__
+__dir__
diff --git a/test/prism/fixtures/unparser/corpus/literal/range.txt b/test/prism/fixtures/unparser/corpus/literal/range.txt
new file mode 100644
index 0000000000..eb1f3874c0
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/range.txt
@@ -0,0 +1,4 @@
+(1..)
+1..2
+(1...)
+1...2
diff --git a/test/prism/fixtures/unparser/corpus/literal/rescue.txt b/test/prism/fixtures/unparser/corpus/literal/rescue.txt
new file mode 100644
index 0000000000..a787816808
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/rescue.txt
@@ -0,0 +1,3 @@
+foo rescue bar
+foo rescue return bar
+x = (foo rescue return bar)
diff --git a/test/prism/fixtures/unparser/corpus/literal/send.txt b/test/prism/fixtures/unparser/corpus/literal/send.txt
new file mode 100644
index 0000000000..1e9c2a94be
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/send.txt
@@ -0,0 +1,84 @@
+module A
+ foo ||= ((a, _) = b)
+end
+
+module A
+ local = 1
+ local.bar
+end
+class A
+end.bar
+module A
+end.bar
+begin
+rescue
+end.bar
+case (def foo
+end; :bar)
+when bar
+end.baz
+case foo
+when bar
+end.baz
+class << self
+end.bar
+def self.foo
+end.bar
+def foo
+end.bar
+until foo
+end.bar
+while foo
+end.bar
+loop {
+}.bar
+if foo
+end.baz
+(/bar/ =~ :foo).foo
+(1..2).max
+(foo =~ /bar/).foo
+/bar/ =~ :foo
+/bar/ =~ foo
+1..2.max
+A.foo
+FOO()
+a&.b
+a.foo
+foo
+foo << (bar * baz)
+foo =~ /bar/
+foo(&(foo || bar))
+foo(&block)
+foo(*args, &block)
+foo(*arguments)
+foo(1, 2)
+foo(bar)
+foo(bar, *args)
+foo(foo =~ /bar/)
+foo.bar(&baz)
+foo.bar(*arga, foo, *argb)
+foo.bar(*args)
+foo.bar(*args, foo)
+foo.bar(:baz, &baz)
+foo.bar(baz: boz)
+foo.bar(foo, "baz" => boz)
+foo.bar(foo, *args)
+foo.bar(foo, *args, &block)
+foo.bar(foo, {})
+foo.bar({ foo: boz }, boz)
+foo.bar=:baz
+foo(a: b)
+foo.&(a: b)
+foo.&(**a)
+foo[*baz]
+foo[1, 2]
+foo[]
+self.foo
+self.foo=:bar
+(a + b) / (c - d)
+(a + b) / c.-(e, f)
+(a + b) / c.-(*f)
+x(**foo)
+foo&.!
+foo.~(b)
+a&.+(b)
diff --git a/test/prism/fixtures/unparser/corpus/literal/since/27.txt b/test/prism/fixtures/unparser/corpus/literal/since/27.txt
new file mode 100644
index 0000000000..c332f9e48e
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/since/27.txt
@@ -0,0 +1,4 @@
+-> {
+ _1 + _2
+}
+(..1)
diff --git a/test/prism/fixtures/unparser/corpus/literal/since/30.txt b/test/prism/fixtures/unparser/corpus/literal/since/30.txt
new file mode 100644
index 0000000000..b73328a4b0
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/since/30.txt
@@ -0,0 +1,4 @@
+1 => [a]
+1 => [*]
+1 in [*, 42, *]
+1 in [*, a, *foo]
diff --git a/test/prism/fixtures/unparser/corpus/literal/since/31.txt b/test/prism/fixtures/unparser/corpus/literal/since/31.txt
new file mode 100644
index 0000000000..504eb94d5b
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/since/31.txt
@@ -0,0 +1,7 @@
+def foo(&)
+ bar(&)
+end
+
+def foo(a, &)
+ bar(&)
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/since/32.txt b/test/prism/fixtures/unparser/corpus/literal/since/32.txt
new file mode 100644
index 0000000000..b8e096d8fc
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/since/32.txt
@@ -0,0 +1,11 @@
+def foo(argument, **)
+ bar(argument, **)
+end
+
+def foo(argument, *)
+ bar(argument, *)
+end
+
+def foo(**)
+ { default: 1, ** }
+end
diff --git a/test/prism/fixtures/unparser/corpus/literal/singletons.txt b/test/prism/fixtures/unparser/corpus/literal/singletons.txt
new file mode 100644
index 0000000000..496e6a41ce
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/singletons.txt
@@ -0,0 +1,4 @@
+false
+nil
+self
+true
diff --git a/test/prism/fixtures/unparser/corpus/literal/super.txt b/test/prism/fixtures/unparser/corpus/literal/super.txt
new file mode 100644
index 0000000000..0e73e6f052
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/super.txt
@@ -0,0 +1,21 @@
+super
+super()
+super(a)
+super(a, b)
+super(&block)
+super(a, &block)
+super(a {
+ foo
+})
+super {
+ foo
+}
+super(a) {
+ foo
+}
+super() {
+ foo
+}
+super(a, b) {
+ foo
+}
diff --git a/test/prism/fixtures/unparser/corpus/literal/unary.txt b/test/prism/fixtures/unparser/corpus/literal/unary.txt
new file mode 100644
index 0000000000..77685cb71d
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/unary.txt
@@ -0,0 +1,8 @@
+!1
+!(!1)
+!(!(foo || bar))
+!(!1).baz
+~a
+-a
++a
+-(-a).foo
diff --git a/test/prism/fixtures/unparser/corpus/literal/undef.txt b/test/prism/fixtures/unparser/corpus/literal/undef.txt
new file mode 100644
index 0000000000..a65d8d0cc4
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/undef.txt
@@ -0,0 +1,2 @@
+undef :foo
+undef :foo, :bar
diff --git a/test/prism/fixtures/unparser/corpus/literal/variables.txt b/test/prism/fixtures/unparser/corpus/literal/variables.txt
new file mode 100644
index 0000000000..1de938f376
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/variables.txt
@@ -0,0 +1,10 @@
+a
+@a
+@@a
+$a
+$1
+$`
+CONST
+SCOPED::CONST
+::TOPLEVEL
+::TOPLEVEL::CONST
diff --git a/test/prism/fixtures/unparser/corpus/literal/while.txt b/test/prism/fixtures/unparser/corpus/literal/while.txt
new file mode 100644
index 0000000000..19a60ef5ff
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/literal/while.txt
@@ -0,0 +1,73 @@
+module A
+ foo { |bar|
+ while foo
+ foo = bar
+ end
+ }
+end
+
+def foo
+ foo = bar while foo != baz
+end
+
+module A
+ foo = bar while foo
+end
+
+module A
+ foo = bar until foo
+end
+
+module A
+ while foo
+ foo = bar
+ end
+end
+
+module A
+ each { |baz|
+ while foo
+ foo = bar
+ end
+ }
+end
+
+module A
+ each { |foo|
+ while foo
+ foo = bar
+ end
+ }
+end
+x = (begin
+ foo
+end while baz)
+begin
+ foo
+end while baz
+begin
+ foo
+ bar
+end until baz
+begin
+ foo
+ bar
+end while baz
+while false
+end
+while false
+ 3
+end
+while (foo {
+})
+ :body
+end
+until false
+end
+until false
+ 3
+end
+until (foo {
+})
+ :body
+end
diff --git a/test/prism/fixtures/unparser/corpus/semantic/and.txt b/test/prism/fixtures/unparser/corpus/semantic/and.txt
new file mode 100644
index 0000000000..43d1712445
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/and.txt
@@ -0,0 +1,8 @@
+a...b or c...d
+a...b and c...d
+
+if a...b or c...d
+end
+
+if a...b and c...d
+end
diff --git a/test/prism/fixtures/unparser/corpus/semantic/block.txt b/test/prism/fixtures/unparser/corpus/semantic/block.txt
new file mode 100644
index 0000000000..5891690025
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/block.txt
@@ -0,0 +1,26 @@
+foo do
+end
+
+foo do
+rescue
+end
+
+foo do
+ nil rescue nil
+ nil
+end
+
+foo do |a|
+end
+
+foo(<<-DOC) do |a|
+ b
+DOC
+ a
+end
+
+foo(<<-DOC) do
+ b
+DOC
+ a
+end
diff --git a/test/prism/fixtures/unparser/corpus/semantic/def.txt b/test/prism/fixtures/unparser/corpus/semantic/def.txt
new file mode 100644
index 0000000000..7574619392
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/def.txt
@@ -0,0 +1,7 @@
+def foo
+ (a - b)
+end
+
+def foo
+ a rescue Exception
+end
diff --git a/test/prism/fixtures/unparser/corpus/semantic/dstr.txt b/test/prism/fixtures/unparser/corpus/semantic/dstr.txt
new file mode 100644
index 0000000000..919e736077
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/dstr.txt
@@ -0,0 +1,127 @@
+<<DOC
+DOC
+
+<<'DOC'
+DOC
+
+<<~DOC
+DOC
+
+<<~'DOC'
+DOC
+
+<<DOC
+ a
+DOC
+
+<<'DOC'
+ a
+DOC
+
+<<DOC
+ a
+ #{}
+DOC
+
+<<~DOC
+ a
+ #{}
+DOC
+
+<<~DOC
+ a
+ #{}
+ b
+DOC
+
+<<~DOC
+ a
+ b
+DOC
+
+<<'DOC'
+a
+
+b
+DOC
+
+<<'DOC'
+ a
+
+ b
+DOC
+
+<<'DOC'
+ a\nb
+DOC
+
+<<DOC
+#{}a
+ #{}a
+DOC
+
+<<DOC
+ #{}
+ \#{}
+DOC
+
+<<DOC
+ a#{}b
+ c
+DOC
+
+<<~DOC
+ #{}
+DOC
+
+if true
+ <<~DOC
+ #{}
+ DOC
+end
+
+if true
+ <<~DOC
+ b#{}
+ DOC
+end
+
+if true
+ <<~DOC
+ #{}a
+ DOC
+end
+
+if true
+ <<-'DOC'
+ a
+
+ b
+ DOC
+end
+
+"#{}a"
+
+%(\n"#{}"\n)
+
+%Q(-\n"#{}"\n)
+
+"a
+#{}
+b"
+
+"a\n#{}
+b"
+
+"a
+#{}\nb"
+
+'a' \
+"#{}"
+
+"" "" ""
+
+"a#{@a}" "b"
+"a#@a" "b"
+"a#$a" "b"
+"a#@@a" "b"
diff --git a/test/prism/fixtures/unparser/corpus/semantic/kwbegin.txt b/test/prism/fixtures/unparser/corpus/semantic/kwbegin.txt
new file mode 100644
index 0000000000..d275a96a5c
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/kwbegin.txt
@@ -0,0 +1,42 @@
+begin
+rescue
+end
+
+begin
+rescue
+else
+end
+
+begin
+ a
+end
+
+begin
+ a
+rescue
+ b
+end
+
+begin
+ a
+ b
+rescue
+ b
+end
+
+begin
+rescue A
+else
+end
+
+begin; rescue A; else; end
+
+begin
+ a
+rescue A
+ b
+rescue B
+ c
+ensure
+ d
+end
diff --git a/test/prism/fixtures/unparser/corpus/semantic/literal.txt b/test/prism/fixtures/unparser/corpus/semantic/literal.txt
new file mode 100644
index 0000000000..c424db5a53
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/literal.txt
@@ -0,0 +1,14 @@
+1.0r
+-0r
+0x1
+1_000
+1e10
+10e10000000000
+-10e10000000000
+?c
+%r(/)
+%r(\))
+%r(#{@bar}baz)
+10.2e10000000000
+-10.2e10000000000
+w(foo bar)
diff --git a/test/prism/fixtures/unparser/corpus/semantic/opasgn.txt b/test/prism/fixtures/unparser/corpus/semantic/opasgn.txt
new file mode 100644
index 0000000000..8b4bc5d239
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/opasgn.txt
@@ -0,0 +1 @@
+y["#{42}\n"] += "#{42}\n"
diff --git a/test/prism/fixtures/unparser/corpus/semantic/send.txt b/test/prism/fixtures/unparser/corpus/semantic/send.txt
new file mode 100644
index 0000000000..a65b27d2f2
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/send.txt
@@ -0,0 +1,6 @@
+foo
+foo(1)
+
+a.===(b).c == d
+
+a == d.c.===(c)
diff --git a/test/prism/fixtures/unparser/corpus/semantic/undef.txt b/test/prism/fixtures/unparser/corpus/semantic/undef.txt
new file mode 100644
index 0000000000..47debc3114
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/undef.txt
@@ -0,0 +1,2 @@
+undef foo
+undef foo, bar
diff --git a/test/prism/fixtures/unparser/corpus/semantic/while.txt b/test/prism/fixtures/unparser/corpus/semantic/while.txt
new file mode 100644
index 0000000000..a55dcc52fc
--- /dev/null
+++ b/test/prism/fixtures/unparser/corpus/semantic/while.txt
@@ -0,0 +1,25 @@
+a until b? {}
+
+until b? {}
+ a
+end
+
+foo = bar while foo
+
+a until b && a { }
+
+while a = b
+ a
+end
+
+a until b(<<-FOO) do
+FOO
+ c
+end
+
+module A
+ foo = exp
+ while foo
+ foo = bar
+ end
+end
diff --git a/test/prism/fixtures/until.txt b/test/prism/fixtures/until.txt
new file mode 100644
index 0000000000..652fc8c5a7
--- /dev/null
+++ b/test/prism/fixtures/until.txt
@@ -0,0 +1,13 @@
+until true; 1; end
+
+1 until true
+
+tap { break until true }
+
+tap { next until true }
+
+return until true
+
+foo :a, :b until bar?
+
+foo while bar in baz
diff --git a/test/prism/fixtures/variables.txt b/test/prism/fixtures/variables.txt
new file mode 100644
index 0000000000..1545c30c80
--- /dev/null
+++ b/test/prism/fixtures/variables.txt
@@ -0,0 +1,47 @@
+@@abc
+
+@@abc = 1
+
+@@foo, @@bar = 1
+
+@@foo = 1, 2
+
+$abc = 1
+
+$abc
+
+@abc
+
+@abc = 1
+
+a
+
+abc = 1
+
+$foo, $bar = 1
+
+$foo = 1, 2
+
+@foo, @bar = 1
+
+@foo = 1, 2
+
+foo = 1; foo = 1, 2
+
+foo = 1, 2
+
+foo, * = 1, 2
+
+foo, = 1, 2
+
+foo, *bar = 1, 2
+
+foo, (bar, baz) = 1, [2, 3]
+
+foo = *bar
+
+Foo = 1, 2
+
+(a; b; c)
+
+a, (b, c), d = []
diff --git a/test/prism/fixtures/while.txt b/test/prism/fixtures/while.txt
new file mode 100644
index 0000000000..b776f755ee
--- /dev/null
+++ b/test/prism/fixtures/while.txt
@@ -0,0 +1,23 @@
+while true; 1; end
+
+1 while true
+
+tap { break while true }
+
+tap { next while true }
+
+return while true
+
+foo :a, :b while bar?
+
+tap { while def self.foo a = tap do end; end; break; end }
+
+tap { while class Foo a = tap do end; end; break; end }
+
+tap { while class << self; tap do end; end; break; end }
+
+tap { while class << self; a = tap do end; end; break; end }
+
+while def foo = bar do end; end
+
+foo while bar in baz
diff --git a/test/prism/fixtures/whitequark/LICENSE b/test/prism/fixtures/whitequark/LICENSE
new file mode 100644
index 0000000000..971310e3d6
--- /dev/null
+++ b/test/prism/fixtures/whitequark/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2013-2016 whitequark <whitequark@whitequark.org>
+
+Parts of the source are derived from ruby_parser:
+Copyright (c) Ryan Davis, seattle.rb
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/test/prism/fixtures/whitequark/__ENCODING__.txt b/test/prism/fixtures/whitequark/__ENCODING__.txt
new file mode 100644
index 0000000000..d6debf2f92
--- /dev/null
+++ b/test/prism/fixtures/whitequark/__ENCODING__.txt
@@ -0,0 +1 @@
+__ENCODING__
diff --git a/test/prism/fixtures/whitequark/__ENCODING___legacy_.txt b/test/prism/fixtures/whitequark/__ENCODING___legacy_.txt
new file mode 100644
index 0000000000..d6debf2f92
--- /dev/null
+++ b/test/prism/fixtures/whitequark/__ENCODING___legacy_.txt
@@ -0,0 +1 @@
+__ENCODING__
diff --git a/test/prism/fixtures/whitequark/alias.txt b/test/prism/fixtures/whitequark/alias.txt
new file mode 100644
index 0000000000..e33b120022
--- /dev/null
+++ b/test/prism/fixtures/whitequark/alias.txt
@@ -0,0 +1 @@
+alias :foo bar
diff --git a/test/prism/fixtures/whitequark/alias_gvar.txt b/test/prism/fixtures/whitequark/alias_gvar.txt
new file mode 100644
index 0000000000..b975d97f8e
--- /dev/null
+++ b/test/prism/fixtures/whitequark/alias_gvar.txt
@@ -0,0 +1,3 @@
+alias $a $+
+
+alias $a $b
diff --git a/test/prism/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt b/test/prism/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt
new file mode 100644
index 0000000000..9b2e3afad5
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt
@@ -0,0 +1 @@
+a ? b & '': nil
diff --git a/test/prism/fixtures/whitequark/and.txt b/test/prism/fixtures/whitequark/and.txt
new file mode 100644
index 0000000000..43fa6a65cd
--- /dev/null
+++ b/test/prism/fixtures/whitequark/and.txt
@@ -0,0 +1,3 @@
+foo && bar
+
+foo and bar
diff --git a/test/prism/fixtures/whitequark/and_asgn.txt b/test/prism/fixtures/whitequark/and_asgn.txt
new file mode 100644
index 0000000000..a979265914
--- /dev/null
+++ b/test/prism/fixtures/whitequark/and_asgn.txt
@@ -0,0 +1,3 @@
+foo.a &&= 1
+
+foo[0, 1] &&= 2
diff --git a/test/prism/fixtures/whitequark/and_or_masgn.txt b/test/prism/fixtures/whitequark/and_or_masgn.txt
new file mode 100644
index 0000000000..e346041604
--- /dev/null
+++ b/test/prism/fixtures/whitequark/and_or_masgn.txt
@@ -0,0 +1,3 @@
+foo && (a, b = bar)
+
+foo || (a, b = bar)
diff --git a/test/prism/fixtures/whitequark/anonymous_blockarg.txt b/test/prism/fixtures/whitequark/anonymous_blockarg.txt
new file mode 100644
index 0000000000..e3eaaad6ce
--- /dev/null
+++ b/test/prism/fixtures/whitequark/anonymous_blockarg.txt
@@ -0,0 +1 @@
+def foo(&); bar(&); end
diff --git a/test/prism/fixtures/whitequark/arg.txt b/test/prism/fixtures/whitequark/arg.txt
new file mode 100644
index 0000000000..b1984ad5c4
--- /dev/null
+++ b/test/prism/fixtures/whitequark/arg.txt
@@ -0,0 +1,3 @@
+def f(foo); end
+
+def f(foo, bar); end
diff --git a/test/prism/fixtures/whitequark/arg_duplicate_ignored.txt b/test/prism/fixtures/whitequark/arg_duplicate_ignored.txt
new file mode 100644
index 0000000000..0f5cc33961
--- /dev/null
+++ b/test/prism/fixtures/whitequark/arg_duplicate_ignored.txt
@@ -0,0 +1,3 @@
+def foo(_, _); end
+
+def foo(_a, _a); end
diff --git a/test/prism/fixtures/whitequark/arg_label.txt b/test/prism/fixtures/whitequark/arg_label.txt
new file mode 100644
index 0000000000..82db416cb4
--- /dev/null
+++ b/test/prism/fixtures/whitequark/arg_label.txt
@@ -0,0 +1,6 @@
+def foo
+ a:b end
+
+def foo() a:b end
+
+f { || a:b }
diff --git a/test/prism/fixtures/whitequark/arg_scope.txt b/test/prism/fixtures/whitequark/arg_scope.txt
new file mode 100644
index 0000000000..6c67ab72e3
--- /dev/null
+++ b/test/prism/fixtures/whitequark/arg_scope.txt
@@ -0,0 +1 @@
+lambda{|;a|a}
diff --git a/test/prism/fixtures/whitequark/args.txt b/test/prism/fixtures/whitequark/args.txt
new file mode 100644
index 0000000000..773be477d3
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args.txt
@@ -0,0 +1,63 @@
+def f &b; end
+
+def f (((a))); end
+
+def f ((*)); end
+
+def f ((*, p)); end
+
+def f ((*r)); end
+
+def f ((*r, p)); end
+
+def f ((a, *)); end
+
+def f ((a, *, p)); end
+
+def f ((a, *r)); end
+
+def f ((a, *r, p)); end
+
+def f ((a, a1)); end
+
+def f (foo: 1, &b); end
+
+def f (foo: 1, bar: 2, **baz, &b); end
+
+def f **baz, &b; end
+
+def f *, **; end
+
+def f *r, &b; end
+
+def f *r, p, &b; end
+
+def f ; end
+
+def f a, &b; end
+
+def f a, *r, &b; end
+
+def f a, *r, p, &b; end
+
+def f a, o=1, &b; end
+
+def f a, o=1, *r, &b; end
+
+def f a, o=1, *r, p, &b; end
+
+def f a, o=1, p, &b; end
+
+def f foo:
+; end
+
+def f foo: -1
+; end
+
+def f o=1, &b; end
+
+def f o=1, *r, &b; end
+
+def f o=1, *r, p, &b; end
+
+def f o=1, p, &b; end
diff --git a/test/prism/fixtures/whitequark/args_args_assocs.txt b/test/prism/fixtures/whitequark/args_args_assocs.txt
new file mode 100644
index 0000000000..445f899442
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args_args_assocs.txt
@@ -0,0 +1,3 @@
+fun(foo, :foo => 1)
+
+fun(foo, :foo => 1, &baz)
diff --git a/test/prism/fixtures/whitequark/args_args_assocs_comma.txt b/test/prism/fixtures/whitequark/args_args_assocs_comma.txt
new file mode 100644
index 0000000000..b566a59037
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args_args_assocs_comma.txt
@@ -0,0 +1 @@
+foo[bar, :baz => 1,]
diff --git a/test/prism/fixtures/whitequark/args_args_comma.txt b/test/prism/fixtures/whitequark/args_args_comma.txt
new file mode 100644
index 0000000000..80770716dd
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args_args_comma.txt
@@ -0,0 +1 @@
+foo[bar,]
diff --git a/test/prism/fixtures/whitequark/args_args_star.txt b/test/prism/fixtures/whitequark/args_args_star.txt
new file mode 100644
index 0000000000..d4dc9cc579
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args_args_star.txt
@@ -0,0 +1,3 @@
+fun(foo, *bar)
+
+fun(foo, *bar, &baz)
diff --git a/test/prism/fixtures/whitequark/args_assocs_comma.txt b/test/prism/fixtures/whitequark/args_assocs_comma.txt
new file mode 100644
index 0000000000..15e5cd65dc
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args_assocs_comma.txt
@@ -0,0 +1 @@
+foo[:baz => 1,]
diff --git a/test/prism/fixtures/whitequark/args_block_pass.txt b/test/prism/fixtures/whitequark/args_block_pass.txt
new file mode 100644
index 0000000000..35d7d23885
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args_block_pass.txt
@@ -0,0 +1 @@
+fun(&bar)
diff --git a/test/prism/fixtures/whitequark/args_cmd.txt b/test/prism/fixtures/whitequark/args_cmd.txt
new file mode 100644
index 0000000000..dd0c8891d0
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args_cmd.txt
@@ -0,0 +1 @@
+fun(f bar)
diff --git a/test/prism/fixtures/whitequark/args_star.txt b/test/prism/fixtures/whitequark/args_star.txt
new file mode 100644
index 0000000000..ce1e6f8465
--- /dev/null
+++ b/test/prism/fixtures/whitequark/args_star.txt
@@ -0,0 +1,3 @@
+fun(*bar)
+
+fun(*bar, &baz)
diff --git a/test/prism/fixtures/whitequark/array_assocs.txt b/test/prism/fixtures/whitequark/array_assocs.txt
new file mode 100644
index 0000000000..fcecfcdefc
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_assocs.txt
@@ -0,0 +1,3 @@
+[ 1 => 2 ]
+
+[ 1, 2 => 3 ]
diff --git a/test/prism/fixtures/whitequark/array_plain.txt b/test/prism/fixtures/whitequark/array_plain.txt
new file mode 100644
index 0000000000..44e2ace7e5
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_plain.txt
@@ -0,0 +1 @@
+[1, 2]
diff --git a/test/prism/fixtures/whitequark/array_splat.txt b/test/prism/fixtures/whitequark/array_splat.txt
new file mode 100644
index 0000000000..144c1eb124
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_splat.txt
@@ -0,0 +1,5 @@
+[*foo]
+
+[1, *foo, 2]
+
+[1, *foo]
diff --git a/test/prism/fixtures/whitequark/array_symbols.txt b/test/prism/fixtures/whitequark/array_symbols.txt
new file mode 100644
index 0000000000..a9f9df0404
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_symbols.txt
@@ -0,0 +1 @@
+%i[foo bar]
diff --git a/test/prism/fixtures/whitequark/array_symbols_empty.txt b/test/prism/fixtures/whitequark/array_symbols_empty.txt
new file mode 100644
index 0000000000..da3a89ee9b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_symbols_empty.txt
@@ -0,0 +1,3 @@
+%I()
+
+%i[]
diff --git a/test/prism/fixtures/whitequark/array_symbols_interp.txt b/test/prism/fixtures/whitequark/array_symbols_interp.txt
new file mode 100644
index 0000000000..d4950d0c05
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_symbols_interp.txt
@@ -0,0 +1,3 @@
+%I[foo #{bar}]
+
+%I[foo#{bar}]
diff --git a/test/prism/fixtures/whitequark/array_words.txt b/test/prism/fixtures/whitequark/array_words.txt
new file mode 100644
index 0000000000..a07380cadc
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_words.txt
@@ -0,0 +1 @@
+%w[foo bar]
diff --git a/test/prism/fixtures/whitequark/array_words_empty.txt b/test/prism/fixtures/whitequark/array_words_empty.txt
new file mode 100644
index 0000000000..7568263f4a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_words_empty.txt
@@ -0,0 +1,3 @@
+%W()
+
+%w[]
diff --git a/test/prism/fixtures/whitequark/array_words_interp.txt b/test/prism/fixtures/whitequark/array_words_interp.txt
new file mode 100644
index 0000000000..1460f7dc03
--- /dev/null
+++ b/test/prism/fixtures/whitequark/array_words_interp.txt
@@ -0,0 +1,3 @@
+%W[foo #{bar}]
+
+%W[foo #{bar}foo#@baz]
diff --git a/test/prism/fixtures/whitequark/asgn_cmd.txt b/test/prism/fixtures/whitequark/asgn_cmd.txt
new file mode 100644
index 0000000000..81f8cc1c8d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/asgn_cmd.txt
@@ -0,0 +1,3 @@
+foo = bar = m foo
+
+foo = m foo
diff --git a/test/prism/fixtures/whitequark/asgn_mrhs.txt b/test/prism/fixtures/whitequark/asgn_mrhs.txt
new file mode 100644
index 0000000000..f0b0055e55
--- /dev/null
+++ b/test/prism/fixtures/whitequark/asgn_mrhs.txt
@@ -0,0 +1,5 @@
+foo = *bar
+
+foo = bar, 1
+
+foo = baz, *bar
diff --git a/test/prism/fixtures/whitequark/back_ref.txt b/test/prism/fixtures/whitequark/back_ref.txt
new file mode 100644
index 0000000000..03166e10ee
--- /dev/null
+++ b/test/prism/fixtures/whitequark/back_ref.txt
@@ -0,0 +1 @@
+$+
diff --git a/test/prism/fixtures/whitequark/bang.txt b/test/prism/fixtures/whitequark/bang.txt
new file mode 100644
index 0000000000..6cf9410cf5
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bang.txt
@@ -0,0 +1 @@
+!foo
diff --git a/test/prism/fixtures/whitequark/bang_cmd.txt b/test/prism/fixtures/whitequark/bang_cmd.txt
new file mode 100644
index 0000000000..0a5252c001
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bang_cmd.txt
@@ -0,0 +1 @@
+!m foo
diff --git a/test/prism/fixtures/whitequark/begin_cmdarg.txt b/test/prism/fixtures/whitequark/begin_cmdarg.txt
new file mode 100644
index 0000000000..a5873668e9
--- /dev/null
+++ b/test/prism/fixtures/whitequark/begin_cmdarg.txt
@@ -0,0 +1 @@
+p begin 1.times do 1 end end
diff --git a/test/prism/fixtures/whitequark/beginless_erange_after_newline.txt b/test/prism/fixtures/whitequark/beginless_erange_after_newline.txt
new file mode 100644
index 0000000000..ae6c75564a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/beginless_erange_after_newline.txt
@@ -0,0 +1,2 @@
+foo
+...100
diff --git a/test/prism/fixtures/whitequark/beginless_irange_after_newline.txt b/test/prism/fixtures/whitequark/beginless_irange_after_newline.txt
new file mode 100644
index 0000000000..bfc8d5e5e8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/beginless_irange_after_newline.txt
@@ -0,0 +1,2 @@
+foo
+..100
diff --git a/test/prism/fixtures/whitequark/beginless_range.txt b/test/prism/fixtures/whitequark/beginless_range.txt
new file mode 100644
index 0000000000..ef52703b8a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/beginless_range.txt
@@ -0,0 +1,3 @@
+...100
+
+..100
diff --git a/test/prism/fixtures/whitequark/blockarg.txt b/test/prism/fixtures/whitequark/blockarg.txt
new file mode 100644
index 0000000000..63552e97be
--- /dev/null
+++ b/test/prism/fixtures/whitequark/blockarg.txt
@@ -0,0 +1 @@
+def f(&block); end
diff --git a/test/prism/fixtures/whitequark/blockargs.txt b/test/prism/fixtures/whitequark/blockargs.txt
new file mode 100644
index 0000000000..cdd2c4f331
--- /dev/null
+++ b/test/prism/fixtures/whitequark/blockargs.txt
@@ -0,0 +1,71 @@
+f{ }
+
+f{ | | }
+
+f{ |&b| }
+
+f{ |**baz, &b| }
+
+f{ |*, &b| }
+
+f{ |*r, p, &b| }
+
+f{ |*s, &b| }
+
+f{ |*s| }
+
+f{ |*| }
+
+f{ |;
+a
+| }
+
+f{ |;a| }
+
+f{ |a, &b| }
+
+f{ |a, *, &b| }
+
+f{ |a, *r, p, &b| }
+
+f{ |a, *s, &b| }
+
+f{ |a, *s| }
+
+f{ |a, *| }
+
+f{ |a, b,| }
+
+f{ |a, c| }
+
+f{ |a, o=1, &b| }
+
+f{ |a, o=1, *r, p, &b| }
+
+f{ |a, o=1, o1=2, *r, &b| }
+
+f{ |a, o=1, p, &b| }
+
+f{ |a,| }
+
+f{ |a| }
+
+f{ |a| }
+
+f{ |a| }
+
+f{ |foo: 1, &b| }
+
+f{ |foo: 1, bar: 2, **baz, &b| }
+
+f{ |foo:| }
+
+f{ |o=1, &b| }
+
+f{ |o=1, *r, &b| }
+
+f{ |o=1, *r, p, &b| }
+
+f{ |o=1, p, &b| }
+
+f{ || }
diff --git a/test/prism/fixtures/whitequark/bug_435.txt b/test/prism/fixtures/whitequark/bug_435.txt
new file mode 100644
index 0000000000..3e4e0d5abd
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_435.txt
@@ -0,0 +1 @@
+"#{-> foo {}}"
diff --git a/test/prism/fixtures/whitequark/bug_447.txt b/test/prism/fixtures/whitequark/bug_447.txt
new file mode 100644
index 0000000000..7da59bbc2f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_447.txt
@@ -0,0 +1,3 @@
+m [] do end
+
+m [], 1 do end
diff --git a/test/prism/fixtures/whitequark/bug_452.txt b/test/prism/fixtures/whitequark/bug_452.txt
new file mode 100644
index 0000000000..8b41dd6027
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_452.txt
@@ -0,0 +1 @@
+td (1_500).toString(); td.num do; end
diff --git a/test/prism/fixtures/whitequark/bug_466.txt b/test/prism/fixtures/whitequark/bug_466.txt
new file mode 100644
index 0000000000..ad02ad38ae
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_466.txt
@@ -0,0 +1 @@
+foo "#{(1+1).to_i}" do; end
diff --git a/test/prism/fixtures/whitequark/bug_473.txt b/test/prism/fixtures/whitequark/bug_473.txt
new file mode 100644
index 0000000000..0d2ea883a1
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_473.txt
@@ -0,0 +1 @@
+m "#{[]}"
diff --git a/test/prism/fixtures/whitequark/bug_480.txt b/test/prism/fixtures/whitequark/bug_480.txt
new file mode 100644
index 0000000000..0558b2c957
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_480.txt
@@ -0,0 +1 @@
+m "#{}#{()}"
diff --git a/test/prism/fixtures/whitequark/bug_481.txt b/test/prism/fixtures/whitequark/bug_481.txt
new file mode 100644
index 0000000000..6328e9dbbd
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_481.txt
@@ -0,0 +1 @@
+m def x(); end; 1.tap do end
diff --git a/test/prism/fixtures/whitequark/bug_ascii_8bit_in_literal.txt b/test/prism/fixtures/whitequark/bug_ascii_8bit_in_literal.txt
new file mode 100644
index 0000000000..85399bd19a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_ascii_8bit_in_literal.txt
@@ -0,0 +1,2 @@
+# coding:utf-8
+ "\xD0\xBF\xD1\x80\xD0\xBE\xD0\xB2\xD0\xB5\xD1\x80\xD0\xBA\xD0\xB0"
diff --git a/test/prism/fixtures/whitequark/bug_cmd_string_lookahead.txt b/test/prism/fixtures/whitequark/bug_cmd_string_lookahead.txt
new file mode 100644
index 0000000000..7e9e54c518
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_cmd_string_lookahead.txt
@@ -0,0 +1 @@
+desc "foo" do end
diff --git a/test/prism/fixtures/whitequark/bug_cmdarg.txt b/test/prism/fixtures/whitequark/bug_cmdarg.txt
new file mode 100644
index 0000000000..0281cd6668
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_cmdarg.txt
@@ -0,0 +1,5 @@
+assert do: true
+
+assert dogs
+
+f x: -> do meth do end end
diff --git a/test/prism/fixtures/whitequark/bug_def_no_paren_eql_begin.txt b/test/prism/fixtures/whitequark/bug_def_no_paren_eql_begin.txt
new file mode 100644
index 0000000000..615dc88217
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_def_no_paren_eql_begin.txt
@@ -0,0 +1,4 @@
+def foo
+=begin
+=end
+end
diff --git a/test/prism/fixtures/whitequark/bug_do_block_in_call_args.txt b/test/prism/fixtures/whitequark/bug_do_block_in_call_args.txt
new file mode 100644
index 0000000000..21340fd6e8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_do_block_in_call_args.txt
@@ -0,0 +1 @@
+bar def foo; self.each do end end
diff --git a/test/prism/fixtures/whitequark/bug_do_block_in_cmdarg.txt b/test/prism/fixtures/whitequark/bug_do_block_in_cmdarg.txt
new file mode 100644
index 0000000000..7dece50408
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_do_block_in_cmdarg.txt
@@ -0,0 +1 @@
+tap (proc do end)
diff --git a/test/prism/fixtures/whitequark/bug_do_block_in_hash_brace.txt b/test/prism/fixtures/whitequark/bug_do_block_in_hash_brace.txt
new file mode 100644
index 0000000000..6c4dd205d2
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_do_block_in_hash_brace.txt
@@ -0,0 +1,9 @@
+p :foo, {"a": proc do end, b: proc do end}
+
+p :foo, {** proc do end, b: proc do end}
+
+p :foo, {:a => proc do end, b: proc do end}
+
+p :foo, {a: proc do end, b: proc do end}
+
+p :foo, {proc do end => proc do end, b: proc do end}
diff --git a/test/prism/fixtures/whitequark/bug_heredoc_do.txt b/test/prism/fixtures/whitequark/bug_heredoc_do.txt
new file mode 100644
index 0000000000..06fef0a99f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_heredoc_do.txt
@@ -0,0 +1,3 @@
+f <<-TABLE do
+TABLE
+end
diff --git a/test/prism/fixtures/whitequark/bug_interp_single.txt b/test/prism/fixtures/whitequark/bug_interp_single.txt
new file mode 100644
index 0000000000..be0b1a8542
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_interp_single.txt
@@ -0,0 +1,3 @@
+"#{1}"
+
+%W"#{1}"
diff --git a/test/prism/fixtures/whitequark/bug_lambda_leakage.txt b/test/prism/fixtures/whitequark/bug_lambda_leakage.txt
new file mode 100644
index 0000000000..372b36929a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_lambda_leakage.txt
@@ -0,0 +1 @@
+->(scope) {}; scope
diff --git a/test/prism/fixtures/whitequark/bug_regex_verification.txt b/test/prism/fixtures/whitequark/bug_regex_verification.txt
new file mode 100644
index 0000000000..f8483c8b10
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_regex_verification.txt
@@ -0,0 +1 @@
+/#)/x
diff --git a/test/prism/fixtures/whitequark/bug_rescue_empty_else.txt b/test/prism/fixtures/whitequark/bug_rescue_empty_else.txt
new file mode 100644
index 0000000000..e8c81edc57
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_rescue_empty_else.txt
@@ -0,0 +1 @@
+begin; rescue LoadError; else; end
diff --git a/test/prism/fixtures/whitequark/bug_while_not_parens_do.txt b/test/prism/fixtures/whitequark/bug_while_not_parens_do.txt
new file mode 100644
index 0000000000..628c36ef13
--- /dev/null
+++ b/test/prism/fixtures/whitequark/bug_while_not_parens_do.txt
@@ -0,0 +1 @@
+while not (true) do end
diff --git a/test/prism/fixtures/whitequark/case_cond.txt b/test/prism/fixtures/whitequark/case_cond.txt
new file mode 100644
index 0000000000..a236b27ebd
--- /dev/null
+++ b/test/prism/fixtures/whitequark/case_cond.txt
@@ -0,0 +1 @@
+case; when foo; 'foo'; end
diff --git a/test/prism/fixtures/whitequark/case_cond_else.txt b/test/prism/fixtures/whitequark/case_cond_else.txt
new file mode 100644
index 0000000000..06eefa4a1b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/case_cond_else.txt
@@ -0,0 +1 @@
+case; when foo; 'foo'; else 'bar'; end
diff --git a/test/prism/fixtures/whitequark/case_expr.txt b/test/prism/fixtures/whitequark/case_expr.txt
new file mode 100644
index 0000000000..472672c781
--- /dev/null
+++ b/test/prism/fixtures/whitequark/case_expr.txt
@@ -0,0 +1 @@
+case foo; when 'bar'; bar; end
diff --git a/test/prism/fixtures/whitequark/case_expr_else.txt b/test/prism/fixtures/whitequark/case_expr_else.txt
new file mode 100644
index 0000000000..3c55826134
--- /dev/null
+++ b/test/prism/fixtures/whitequark/case_expr_else.txt
@@ -0,0 +1 @@
+case foo; when 'bar'; bar; else baz; end
diff --git a/test/prism/fixtures/whitequark/casgn_scoped.txt b/test/prism/fixtures/whitequark/casgn_scoped.txt
new file mode 100644
index 0000000000..964d0f4c9b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/casgn_scoped.txt
@@ -0,0 +1 @@
+Bar::Foo = 10
diff --git a/test/prism/fixtures/whitequark/casgn_toplevel.txt b/test/prism/fixtures/whitequark/casgn_toplevel.txt
new file mode 100644
index 0000000000..047a3b6745
--- /dev/null
+++ b/test/prism/fixtures/whitequark/casgn_toplevel.txt
@@ -0,0 +1 @@
+::Foo = 10
diff --git a/test/prism/fixtures/whitequark/casgn_unscoped.txt b/test/prism/fixtures/whitequark/casgn_unscoped.txt
new file mode 100644
index 0000000000..5632cf64ee
--- /dev/null
+++ b/test/prism/fixtures/whitequark/casgn_unscoped.txt
@@ -0,0 +1 @@
+Foo = 10
diff --git a/test/prism/fixtures/whitequark/character.txt b/test/prism/fixtures/whitequark/character.txt
new file mode 100644
index 0000000000..b22ffbb71a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/character.txt
@@ -0,0 +1 @@
+?a
diff --git a/test/prism/fixtures/whitequark/class.txt b/test/prism/fixtures/whitequark/class.txt
new file mode 100644
index 0000000000..a30a248e96
--- /dev/null
+++ b/test/prism/fixtures/whitequark/class.txt
@@ -0,0 +1,3 @@
+class Foo end
+
+class Foo; end
diff --git a/test/prism/fixtures/whitequark/class_super.txt b/test/prism/fixtures/whitequark/class_super.txt
new file mode 100644
index 0000000000..8829d82d36
--- /dev/null
+++ b/test/prism/fixtures/whitequark/class_super.txt
@@ -0,0 +1 @@
+class Foo < Bar; end
diff --git a/test/prism/fixtures/whitequark/class_super_label.txt b/test/prism/fixtures/whitequark/class_super_label.txt
new file mode 100644
index 0000000000..5d47897ab6
--- /dev/null
+++ b/test/prism/fixtures/whitequark/class_super_label.txt
@@ -0,0 +1 @@
+class Foo < a:b; end
diff --git a/test/prism/fixtures/whitequark/comments_before_leading_dot__27.txt b/test/prism/fixtures/whitequark/comments_before_leading_dot__27.txt
new file mode 100644
index 0000000000..208f2d87fe
--- /dev/null
+++ b/test/prism/fixtures/whitequark/comments_before_leading_dot__27.txt
@@ -0,0 +1,19 @@
+a #
+ #
+&.foo
+
+
+a #
+ #
+.foo
+
+
+a #
+#
+&.foo
+
+
+a #
+#
+.foo
+
diff --git a/test/prism/fixtures/whitequark/complex.txt b/test/prism/fixtures/whitequark/complex.txt
new file mode 100644
index 0000000000..1dbf2c13f4
--- /dev/null
+++ b/test/prism/fixtures/whitequark/complex.txt
@@ -0,0 +1,7 @@
+42.1i
+
+42.1ri
+
+42i
+
+42ri
diff --git a/test/prism/fixtures/whitequark/cond_begin.txt b/test/prism/fixtures/whitequark/cond_begin.txt
new file mode 100644
index 0000000000..49d709b79c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_begin.txt
@@ -0,0 +1 @@
+if (bar); foo; end
diff --git a/test/prism/fixtures/whitequark/cond_begin_masgn.txt b/test/prism/fixtures/whitequark/cond_begin_masgn.txt
new file mode 100644
index 0000000000..f9b65026b4
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_begin_masgn.txt
@@ -0,0 +1 @@
+if (bar; a, b = foo); end
diff --git a/test/prism/fixtures/whitequark/cond_eflipflop.txt b/test/prism/fixtures/whitequark/cond_eflipflop.txt
new file mode 100644
index 0000000000..1236c2dbb5
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_eflipflop.txt
@@ -0,0 +1,3 @@
+!(foo...bar)
+
+if foo...bar; end
diff --git a/test/prism/fixtures/whitequark/cond_eflipflop_with_beginless_range.txt b/test/prism/fixtures/whitequark/cond_eflipflop_with_beginless_range.txt
new file mode 100644
index 0000000000..757863b12b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_eflipflop_with_beginless_range.txt
@@ -0,0 +1 @@
+if ...bar; end
diff --git a/test/prism/fixtures/whitequark/cond_eflipflop_with_endless_range.txt b/test/prism/fixtures/whitequark/cond_eflipflop_with_endless_range.txt
new file mode 100644
index 0000000000..8a3b815ec9
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_eflipflop_with_endless_range.txt
@@ -0,0 +1 @@
+if foo...; end
diff --git a/test/prism/fixtures/whitequark/cond_iflipflop.txt b/test/prism/fixtures/whitequark/cond_iflipflop.txt
new file mode 100644
index 0000000000..84bee71a74
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_iflipflop.txt
@@ -0,0 +1,3 @@
+!(foo..bar)
+
+if foo..bar; end
diff --git a/test/prism/fixtures/whitequark/cond_iflipflop_with_beginless_range.txt b/test/prism/fixtures/whitequark/cond_iflipflop_with_beginless_range.txt
new file mode 100644
index 0000000000..4ff5b09690
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_iflipflop_with_beginless_range.txt
@@ -0,0 +1 @@
+if ..bar; end
diff --git a/test/prism/fixtures/whitequark/cond_iflipflop_with_endless_range.txt b/test/prism/fixtures/whitequark/cond_iflipflop_with_endless_range.txt
new file mode 100644
index 0000000000..2739ad0e2a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_iflipflop_with_endless_range.txt
@@ -0,0 +1 @@
+if foo..; end
diff --git a/test/prism/fixtures/whitequark/cond_match_current_line.txt b/test/prism/fixtures/whitequark/cond_match_current_line.txt
new file mode 100644
index 0000000000..21878c7bd8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cond_match_current_line.txt
@@ -0,0 +1,3 @@
+!/wat/
+
+if /wat/; end
diff --git a/test/prism/fixtures/whitequark/const_op_asgn.txt b/test/prism/fixtures/whitequark/const_op_asgn.txt
new file mode 100644
index 0000000000..e72e7adee8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/const_op_asgn.txt
@@ -0,0 +1,9 @@
+::A += 1
+
+A += 1
+
+B::A += 1
+
+def x; ::A ||= 1; end
+
+def x; self::A ||= 1; end
diff --git a/test/prism/fixtures/whitequark/const_scoped.txt b/test/prism/fixtures/whitequark/const_scoped.txt
new file mode 100644
index 0000000000..4b03d85fc0
--- /dev/null
+++ b/test/prism/fixtures/whitequark/const_scoped.txt
@@ -0,0 +1 @@
+Bar::Foo
diff --git a/test/prism/fixtures/whitequark/const_toplevel.txt b/test/prism/fixtures/whitequark/const_toplevel.txt
new file mode 100644
index 0000000000..f783ae752b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/const_toplevel.txt
@@ -0,0 +1 @@
+::Foo
diff --git a/test/prism/fixtures/whitequark/const_unscoped.txt b/test/prism/fixtures/whitequark/const_unscoped.txt
new file mode 100644
index 0000000000..bc56c4d894
--- /dev/null
+++ b/test/prism/fixtures/whitequark/const_unscoped.txt
@@ -0,0 +1 @@
+Foo
diff --git a/test/prism/fixtures/whitequark/cpath.txt b/test/prism/fixtures/whitequark/cpath.txt
new file mode 100644
index 0000000000..a4041692d1
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cpath.txt
@@ -0,0 +1,3 @@
+module ::Foo; end
+
+module Bar::Foo; end
diff --git a/test/prism/fixtures/whitequark/cvar.txt b/test/prism/fixtures/whitequark/cvar.txt
new file mode 100644
index 0000000000..4997896e4a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cvar.txt
@@ -0,0 +1 @@
+@@foo
diff --git a/test/prism/fixtures/whitequark/cvasgn.txt b/test/prism/fixtures/whitequark/cvasgn.txt
new file mode 100644
index 0000000000..8f7e19c4fe
--- /dev/null
+++ b/test/prism/fixtures/whitequark/cvasgn.txt
@@ -0,0 +1 @@
+@@var = 10
diff --git a/test/prism/fixtures/whitequark/dedenting_heredoc.txt b/test/prism/fixtures/whitequark/dedenting_heredoc.txt
new file mode 100644
index 0000000000..84937d84ab
--- /dev/null
+++ b/test/prism/fixtures/whitequark/dedenting_heredoc.txt
@@ -0,0 +1,75 @@
+p <<~"E"
+ x
+ #{" y"}
+E
+
+p <<~"E"
+ x
+ #{foo}
+E
+
+p <<~E
+ x
+ y
+E
+
+p <<~E
+ x
+ y
+E
+
+p <<~E
+ x
+ y
+E
+
+p <<~E
+ x
+ y
+E
+
+p <<~E
+ x
+ \ y
+E
+
+p <<~E
+ x
+ \ y
+E
+
+p <<~E
+ E
+
+p <<~E
+ x
+
+y
+E
+
+p <<~E
+ x
+
+ y
+E
+
+p <<~E
+ x
+ y
+E
+
+p <<~E
+ x
+E
+
+p <<~E
+ ð
+E
+
+p <<~E
+E
+
+p <<~`E`
+ x
+ #{foo}
+E
diff --git a/test/prism/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt b/test/prism/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt
new file mode 100644
index 0000000000..0427715d61
--- /dev/null
+++ b/test/prism/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt
@@ -0,0 +1,4 @@
+<<~'FOO'
+ baz\\
+ qux
+FOO
diff --git a/test/prism/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt b/test/prism/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt
new file mode 100644
index 0000000000..fd7bc02419
--- /dev/null
+++ b/test/prism/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt
@@ -0,0 +1,4 @@
+<<~'FOO'
+ baz\
+ qux
+FOO
diff --git a/test/prism/fixtures/whitequark/def.txt b/test/prism/fixtures/whitequark/def.txt
new file mode 100644
index 0000000000..d96a4238b3
--- /dev/null
+++ b/test/prism/fixtures/whitequark/def.txt
@@ -0,0 +1,11 @@
+def BEGIN; end
+
+def END; end
+
+def String; end
+
+def String=; end
+
+def foo; end
+
+def until; end
diff --git a/test/prism/fixtures/whitequark/defined.txt b/test/prism/fixtures/whitequark/defined.txt
new file mode 100644
index 0000000000..5cf93e22e3
--- /dev/null
+++ b/test/prism/fixtures/whitequark/defined.txt
@@ -0,0 +1,5 @@
+defined? @foo
+
+defined? foo
+
+defined?(foo)
diff --git a/test/prism/fixtures/whitequark/defs.txt b/test/prism/fixtures/whitequark/defs.txt
new file mode 100644
index 0000000000..e0b7aa86eb
--- /dev/null
+++ b/test/prism/fixtures/whitequark/defs.txt
@@ -0,0 +1,9 @@
+def (foo).foo; end
+
+def String.foo; end
+
+def String::foo; end
+
+def self.foo; end
+
+def self::foo; end
diff --git a/test/prism/fixtures/whitequark/empty_stmt.txt b/test/prism/fixtures/whitequark/empty_stmt.txt
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/test/prism/fixtures/whitequark/empty_stmt.txt
@@ -0,0 +1 @@
+
diff --git a/test/prism/fixtures/whitequark/endless_comparison_method.txt b/test/prism/fixtures/whitequark/endless_comparison_method.txt
new file mode 100644
index 0000000000..e10c3a6ced
--- /dev/null
+++ b/test/prism/fixtures/whitequark/endless_comparison_method.txt
@@ -0,0 +1,11 @@
+def !=(other) = do_something
+
+def !=(other) = do_something
+
+def <=(other) = do_something
+
+def ==(other) = do_something
+
+def ===(other) = do_something
+
+def >=(other) = do_something
diff --git a/test/prism/fixtures/whitequark/endless_method.txt b/test/prism/fixtures/whitequark/endless_method.txt
new file mode 100644
index 0000000000..7002526229
--- /dev/null
+++ b/test/prism/fixtures/whitequark/endless_method.txt
@@ -0,0 +1,7 @@
+def foo() = 42
+
+def inc(x) = x + 1
+
+def obj.foo() = 42
+
+def obj.inc(x) = x + 1
diff --git a/test/prism/fixtures/whitequark/endless_method_command_syntax.txt b/test/prism/fixtures/whitequark/endless_method_command_syntax.txt
new file mode 100644
index 0000000000..d9dad2d747
--- /dev/null
+++ b/test/prism/fixtures/whitequark/endless_method_command_syntax.txt
@@ -0,0 +1,15 @@
+def foo = puts "Hello"
+
+def foo() = puts "Hello"
+
+def foo(x) = puts x
+
+def obj.foo = puts "Hello"
+
+def obj.foo() = puts "Hello"
+
+def obj.foo(x) = puts x
+
+def rescued(x) = raise "to be caught" rescue "instance #{x}"
+
+def self.rescued(x) = raise "to be caught" rescue "class #{x}"
diff --git a/test/prism/fixtures/whitequark/endless_method_forwarded_args_legacy.txt b/test/prism/fixtures/whitequark/endless_method_forwarded_args_legacy.txt
new file mode 100644
index 0000000000..5955e40b5b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/endless_method_forwarded_args_legacy.txt
@@ -0,0 +1 @@
+def foo(...) = bar(...)
diff --git a/test/prism/fixtures/whitequark/endless_method_with_rescue_mod.txt b/test/prism/fixtures/whitequark/endless_method_with_rescue_mod.txt
new file mode 100644
index 0000000000..93dc63a45d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/endless_method_with_rescue_mod.txt
@@ -0,0 +1,3 @@
+def m() = 1 rescue 2
+
+def self.m() = 1 rescue 2
diff --git a/test/prism/fixtures/whitequark/endless_method_without_args.txt b/test/prism/fixtures/whitequark/endless_method_without_args.txt
new file mode 100644
index 0000000000..90ea8f7c6d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/endless_method_without_args.txt
@@ -0,0 +1,7 @@
+def foo = 42
+
+def foo = 42 rescue nil
+
+def self.foo = 42
+
+def self.foo = 42 rescue nil
diff --git a/test/prism/fixtures/whitequark/ensure.txt b/test/prism/fixtures/whitequark/ensure.txt
new file mode 100644
index 0000000000..6c4b47c63c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ensure.txt
@@ -0,0 +1 @@
+begin; meth; ensure; bar; end
diff --git a/test/prism/fixtures/whitequark/ensure_empty.txt b/test/prism/fixtures/whitequark/ensure_empty.txt
new file mode 100644
index 0000000000..39a175c371
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ensure_empty.txt
@@ -0,0 +1 @@
+begin ensure end
diff --git a/test/prism/fixtures/whitequark/false.txt b/test/prism/fixtures/whitequark/false.txt
new file mode 100644
index 0000000000..c508d5366f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/false.txt
@@ -0,0 +1 @@
+false
diff --git a/test/prism/fixtures/whitequark/float.txt b/test/prism/fixtures/whitequark/float.txt
new file mode 100644
index 0000000000..8c7592a192
--- /dev/null
+++ b/test/prism/fixtures/whitequark/float.txt
@@ -0,0 +1,3 @@
+-1.33
+
+1.33
diff --git a/test/prism/fixtures/whitequark/for.txt b/test/prism/fixtures/whitequark/for.txt
new file mode 100644
index 0000000000..a27ae578da
--- /dev/null
+++ b/test/prism/fixtures/whitequark/for.txt
@@ -0,0 +1,3 @@
+for a in foo do p a; end
+
+for a in foo; p a; end
diff --git a/test/prism/fixtures/whitequark/for_mlhs.txt b/test/prism/fixtures/whitequark/for_mlhs.txt
new file mode 100644
index 0000000000..53cd5229a4
--- /dev/null
+++ b/test/prism/fixtures/whitequark/for_mlhs.txt
@@ -0,0 +1 @@
+for a, b in foo; p a, b; end
diff --git a/test/prism/fixtures/whitequark/forward_arg.txt b/test/prism/fixtures/whitequark/forward_arg.txt
new file mode 100644
index 0000000000..c7590a8d53
--- /dev/null
+++ b/test/prism/fixtures/whitequark/forward_arg.txt
@@ -0,0 +1 @@
+def foo(...); bar(...); end
diff --git a/test/prism/fixtures/whitequark/forward_arg_with_open_args.txt b/test/prism/fixtures/whitequark/forward_arg_with_open_args.txt
new file mode 100644
index 0000000000..fd4c06bcb5
--- /dev/null
+++ b/test/prism/fixtures/whitequark/forward_arg_with_open_args.txt
@@ -0,0 +1,27 @@
+(def foo ...
+ bar(...)
+end)
+
+(def foo ...; bar(...); end)
+
+def foo ...
+end
+
+def foo ...; bar(...); end
+
+def foo a, ...
+ bar(...)
+end
+
+def foo a, ...; bar(...); end
+
+def foo a, b = 1, ...
+end
+
+def foo b = 1, ...
+ bar(...)
+end
+
+def foo b = 1, ...; bar(...); end
+
+def foo(a, ...) bar(...) end
diff --git a/test/prism/fixtures/whitequark/forward_args_legacy.txt b/test/prism/fixtures/whitequark/forward_args_legacy.txt
new file mode 100644
index 0000000000..0d9162457f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/forward_args_legacy.txt
@@ -0,0 +1,5 @@
+def foo(...); bar(...); end
+
+def foo(...); end
+
+def foo(...); super(...); end
diff --git a/test/prism/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt b/test/prism/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt
new file mode 100644
index 0000000000..7dbf472232
--- /dev/null
+++ b/test/prism/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt
@@ -0,0 +1 @@
+def foo(argument, **); bar(argument, **); end
diff --git a/test/prism/fixtures/whitequark/forwarded_argument_with_restarg.txt b/test/prism/fixtures/whitequark/forwarded_argument_with_restarg.txt
new file mode 100644
index 0000000000..f734bfd9ec
--- /dev/null
+++ b/test/prism/fixtures/whitequark/forwarded_argument_with_restarg.txt
@@ -0,0 +1 @@
+def foo(argument, *); bar(argument, *); end
diff --git a/test/prism/fixtures/whitequark/forwarded_kwrestarg.txt b/test/prism/fixtures/whitequark/forwarded_kwrestarg.txt
new file mode 100644
index 0000000000..16cd8b2913
--- /dev/null
+++ b/test/prism/fixtures/whitequark/forwarded_kwrestarg.txt
@@ -0,0 +1 @@
+def foo(**); bar(**); end
diff --git a/test/prism/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/prism/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
new file mode 100644
index 0000000000..52759b838f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
@@ -0,0 +1 @@
+def foo(**); bar(**, from_foo: true); end
diff --git a/test/prism/fixtures/whitequark/forwarded_restarg.txt b/test/prism/fixtures/whitequark/forwarded_restarg.txt
new file mode 100644
index 0000000000..65ac2cc1ed
--- /dev/null
+++ b/test/prism/fixtures/whitequark/forwarded_restarg.txt
@@ -0,0 +1 @@
+def foo(*); bar(*); end
diff --git a/test/prism/fixtures/whitequark/gvar.txt b/test/prism/fixtures/whitequark/gvar.txt
new file mode 100644
index 0000000000..bbf13489ad
--- /dev/null
+++ b/test/prism/fixtures/whitequark/gvar.txt
@@ -0,0 +1 @@
+$foo
diff --git a/test/prism/fixtures/whitequark/gvasgn.txt b/test/prism/fixtures/whitequark/gvasgn.txt
new file mode 100644
index 0000000000..2bcc22cdd1
--- /dev/null
+++ b/test/prism/fixtures/whitequark/gvasgn.txt
@@ -0,0 +1 @@
+$var = 10
diff --git a/test/prism/fixtures/whitequark/hash_empty.txt b/test/prism/fixtures/whitequark/hash_empty.txt
new file mode 100644
index 0000000000..ffcd4415b0
--- /dev/null
+++ b/test/prism/fixtures/whitequark/hash_empty.txt
@@ -0,0 +1 @@
+{ }
diff --git a/test/prism/fixtures/whitequark/hash_hashrocket.txt b/test/prism/fixtures/whitequark/hash_hashrocket.txt
new file mode 100644
index 0000000000..2cbb3bd96d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/hash_hashrocket.txt
@@ -0,0 +1,3 @@
+{ 1 => 2 }
+
+{ 1 => 2, :foo => "bar" }
diff --git a/test/prism/fixtures/whitequark/hash_kwsplat.txt b/test/prism/fixtures/whitequark/hash_kwsplat.txt
new file mode 100644
index 0000000000..921aa97c7c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/hash_kwsplat.txt
@@ -0,0 +1 @@
+{ foo: 2, **bar }
diff --git a/test/prism/fixtures/whitequark/hash_label.txt b/test/prism/fixtures/whitequark/hash_label.txt
new file mode 100644
index 0000000000..3aacae4b69
--- /dev/null
+++ b/test/prism/fixtures/whitequark/hash_label.txt
@@ -0,0 +1 @@
+{ foo: 2 }
diff --git a/test/prism/fixtures/whitequark/hash_label_end.txt b/test/prism/fixtures/whitequark/hash_label_end.txt
new file mode 100644
index 0000000000..ac9f7c4b41
--- /dev/null
+++ b/test/prism/fixtures/whitequark/hash_label_end.txt
@@ -0,0 +1,5 @@
+f(a ? "a":1)
+
+{ 'foo': 2 }
+
+{ 'foo': 2, 'bar': {}}
diff --git a/test/prism/fixtures/whitequark/hash_pair_value_omission.txt b/test/prism/fixtures/whitequark/hash_pair_value_omission.txt
new file mode 100644
index 0000000000..9d8ccb5877
--- /dev/null
+++ b/test/prism/fixtures/whitequark/hash_pair_value_omission.txt
@@ -0,0 +1,5 @@
+{BAR:}
+
+{a:, b:}
+
+{puts:}
diff --git a/test/prism/fixtures/whitequark/heredoc.txt b/test/prism/fixtures/whitequark/heredoc.txt
new file mode 100644
index 0000000000..1bfc963f94
--- /dev/null
+++ b/test/prism/fixtures/whitequark/heredoc.txt
@@ -0,0 +1,14 @@
+<<'HERE'
+foo
+bar
+HERE
+
+<<HERE
+foo
+bar
+HERE
+
+<<`HERE`
+foo
+bar
+HERE
diff --git a/test/prism/fixtures/whitequark/if.txt b/test/prism/fixtures/whitequark/if.txt
new file mode 100644
index 0000000000..3de3525286
--- /dev/null
+++ b/test/prism/fixtures/whitequark/if.txt
@@ -0,0 +1,3 @@
+if foo then bar; end
+
+if foo; bar; end
diff --git a/test/prism/fixtures/whitequark/if_else.txt b/test/prism/fixtures/whitequark/if_else.txt
new file mode 100644
index 0000000000..62bab8138c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/if_else.txt
@@ -0,0 +1,3 @@
+if foo then bar; else baz; end
+
+if foo; bar; else baz; end
diff --git a/test/prism/fixtures/whitequark/if_elsif.txt b/test/prism/fixtures/whitequark/if_elsif.txt
new file mode 100644
index 0000000000..4d71e82214
--- /dev/null
+++ b/test/prism/fixtures/whitequark/if_elsif.txt
@@ -0,0 +1 @@
+if foo; bar; elsif baz; 1; else 2; end
diff --git a/test/prism/fixtures/whitequark/if_masgn__24.txt b/test/prism/fixtures/whitequark/if_masgn__24.txt
new file mode 100644
index 0000000000..0c2c8bb04f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/if_masgn__24.txt
@@ -0,0 +1 @@
+if (a, b = foo); end
diff --git a/test/prism/fixtures/whitequark/if_mod.txt b/test/prism/fixtures/whitequark/if_mod.txt
new file mode 100644
index 0000000000..da177b5606
--- /dev/null
+++ b/test/prism/fixtures/whitequark/if_mod.txt
@@ -0,0 +1 @@
+bar if foo
diff --git a/test/prism/fixtures/whitequark/if_nl_then.txt b/test/prism/fixtures/whitequark/if_nl_then.txt
new file mode 100644
index 0000000000..b68107bad2
--- /dev/null
+++ b/test/prism/fixtures/whitequark/if_nl_then.txt
@@ -0,0 +1,2 @@
+if foo
+then bar end
diff --git a/test/prism/fixtures/whitequark/int.txt b/test/prism/fixtures/whitequark/int.txt
new file mode 100644
index 0000000000..6d419918c6
--- /dev/null
+++ b/test/prism/fixtures/whitequark/int.txt
@@ -0,0 +1,5 @@
++42
+
+-42
+
+42
diff --git a/test/prism/fixtures/whitequark/int___LINE__.txt b/test/prism/fixtures/whitequark/int___LINE__.txt
new file mode 100644
index 0000000000..05dcf7afe0
--- /dev/null
+++ b/test/prism/fixtures/whitequark/int___LINE__.txt
@@ -0,0 +1 @@
+__LINE__
diff --git a/test/prism/fixtures/whitequark/interp_digit_var.txt b/test/prism/fixtures/whitequark/interp_digit_var.txt
new file mode 100644
index 0000000000..1ae5a2e3e0
--- /dev/null
+++ b/test/prism/fixtures/whitequark/interp_digit_var.txt
@@ -0,0 +1,87 @@
+ "#@1"
+
+ "#@@1"
+
+ %I[#@1]
+
+ %I[#@@1]
+
+ %Q{#@1}
+
+ %Q{#@@1}
+
+ %W[#@1]
+
+ %W[#@@1]
+
+ %i[ #@1 ]
+
+ %i[ #@@1 ]
+
+ %q{#@1}
+
+ %q{#@@1}
+
+ %r{#@1}
+
+ %r{#@@1}
+
+ %s{#@1}
+
+ %s{#@@1}
+
+ %w[ #@1 ]
+
+ %w[ #@@1 ]
+
+ %x{#@1}
+
+ %x{#@@1}
+
+ %{#@1}
+
+ %{#@@1}
+
+ '#@1'
+
+ '#@@1'
+
+ /#@1/
+
+ /#@@1/
+
+ :"#@1"
+
+ :"#@@1"
+
+ :'#@1'
+
+ :'#@@1'
+
+ `#@1`
+
+ `#@@1`
+
+<<-"HERE"
+#@1
+HERE
+
+<<-"HERE"
+#@@1
+HERE
+
+<<-'HERE'
+#@1
+HERE
+
+<<-'HERE'
+#@@1
+HERE
+
+<<-`HERE`
+#@1
+HERE
+
+<<-`HERE`
+#@@1
+HERE
diff --git a/test/prism/fixtures/whitequark/ivar.txt b/test/prism/fixtures/whitequark/ivar.txt
new file mode 100644
index 0000000000..9149fc67f9
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ivar.txt
@@ -0,0 +1 @@
+@foo
diff --git a/test/prism/fixtures/whitequark/ivasgn.txt b/test/prism/fixtures/whitequark/ivasgn.txt
new file mode 100644
index 0000000000..ac291799db
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ivasgn.txt
@@ -0,0 +1 @@
+@var = 10
diff --git a/test/prism/fixtures/whitequark/keyword_argument_omission.txt b/test/prism/fixtures/whitequark/keyword_argument_omission.txt
new file mode 100644
index 0000000000..47883dc9a5
--- /dev/null
+++ b/test/prism/fixtures/whitequark/keyword_argument_omission.txt
@@ -0,0 +1 @@
+foo(a:, b:)
diff --git a/test/prism/fixtures/whitequark/kwarg.txt b/test/prism/fixtures/whitequark/kwarg.txt
new file mode 100644
index 0000000000..ca02a1fd2a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/kwarg.txt
@@ -0,0 +1 @@
+def f(foo:); end
diff --git a/test/prism/fixtures/whitequark/kwbegin_compstmt.txt b/test/prism/fixtures/whitequark/kwbegin_compstmt.txt
new file mode 100644
index 0000000000..33ceff2489
--- /dev/null
+++ b/test/prism/fixtures/whitequark/kwbegin_compstmt.txt
@@ -0,0 +1 @@
+begin foo!; bar! end
diff --git a/test/prism/fixtures/whitequark/kwnilarg.txt b/test/prism/fixtures/whitequark/kwnilarg.txt
new file mode 100644
index 0000000000..8fc482d5af
--- /dev/null
+++ b/test/prism/fixtures/whitequark/kwnilarg.txt
@@ -0,0 +1,5 @@
+->(**nil) {}
+
+def f(**nil); end
+
+m { |**nil| }
diff --git a/test/prism/fixtures/whitequark/kwoptarg.txt b/test/prism/fixtures/whitequark/kwoptarg.txt
new file mode 100644
index 0000000000..dc3ce728d6
--- /dev/null
+++ b/test/prism/fixtures/whitequark/kwoptarg.txt
@@ -0,0 +1 @@
+def f(foo: 1); end
diff --git a/test/prism/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt b/test/prism/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt
new file mode 100644
index 0000000000..99dcc7239b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt
@@ -0,0 +1 @@
+def f(a: nil, **); b(**) end
diff --git a/test/prism/fixtures/whitequark/kwrestarg_named.txt b/test/prism/fixtures/whitequark/kwrestarg_named.txt
new file mode 100644
index 0000000000..e17a661001
--- /dev/null
+++ b/test/prism/fixtures/whitequark/kwrestarg_named.txt
@@ -0,0 +1 @@
+def f(**foo); end
diff --git a/test/prism/fixtures/whitequark/kwrestarg_unnamed.txt b/test/prism/fixtures/whitequark/kwrestarg_unnamed.txt
new file mode 100644
index 0000000000..1b26b1d2ac
--- /dev/null
+++ b/test/prism/fixtures/whitequark/kwrestarg_unnamed.txt
@@ -0,0 +1 @@
+def f(**); end
diff --git a/test/prism/fixtures/whitequark/lbrace_arg_after_command_args.txt b/test/prism/fixtures/whitequark/lbrace_arg_after_command_args.txt
new file mode 100644
index 0000000000..277c200c9f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/lbrace_arg_after_command_args.txt
@@ -0,0 +1 @@
+let (:a) { m do; end }
diff --git a/test/prism/fixtures/whitequark/lparenarg_after_lvar__since_25.txt b/test/prism/fixtures/whitequark/lparenarg_after_lvar__since_25.txt
new file mode 100644
index 0000000000..dc3a98b1c8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/lparenarg_after_lvar__since_25.txt
@@ -0,0 +1,3 @@
+foo (-1.3).abs
+
+meth (-1.3).abs
diff --git a/test/prism/fixtures/whitequark/lvar.txt b/test/prism/fixtures/whitequark/lvar.txt
new file mode 100644
index 0000000000..257cc5642c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/lvar.txt
@@ -0,0 +1 @@
+foo
diff --git a/test/prism/fixtures/whitequark/lvar_injecting_match.txt b/test/prism/fixtures/whitequark/lvar_injecting_match.txt
new file mode 100644
index 0000000000..ba814a1088
--- /dev/null
+++ b/test/prism/fixtures/whitequark/lvar_injecting_match.txt
@@ -0,0 +1 @@
+/(?<match>bar)/ =~ 'bar'; match
diff --git a/test/prism/fixtures/whitequark/lvasgn.txt b/test/prism/fixtures/whitequark/lvasgn.txt
new file mode 100644
index 0000000000..330b8eff27
--- /dev/null
+++ b/test/prism/fixtures/whitequark/lvasgn.txt
@@ -0,0 +1 @@
+var = 10; var
diff --git a/test/prism/fixtures/whitequark/masgn.txt b/test/prism/fixtures/whitequark/masgn.txt
new file mode 100644
index 0000000000..032124287c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/masgn.txt
@@ -0,0 +1,5 @@
+(foo, bar) = 1, 2
+
+foo, bar = 1, 2
+
+foo, bar, baz = 1, 2
diff --git a/test/prism/fixtures/whitequark/masgn_attr.txt b/test/prism/fixtures/whitequark/masgn_attr.txt
new file mode 100644
index 0000000000..91a703ef44
--- /dev/null
+++ b/test/prism/fixtures/whitequark/masgn_attr.txt
@@ -0,0 +1,5 @@
+self.A, foo = foo
+
+self.a, self[1, 2] = foo
+
+self::a, foo = foo
diff --git a/test/prism/fixtures/whitequark/masgn_cmd.txt b/test/prism/fixtures/whitequark/masgn_cmd.txt
new file mode 100644
index 0000000000..18e096f1ee
--- /dev/null
+++ b/test/prism/fixtures/whitequark/masgn_cmd.txt
@@ -0,0 +1 @@
+foo, bar = m foo
diff --git a/test/prism/fixtures/whitequark/masgn_const.txt b/test/prism/fixtures/whitequark/masgn_const.txt
new file mode 100644
index 0000000000..3b6fba588a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/masgn_const.txt
@@ -0,0 +1,3 @@
+::A, foo = foo
+
+self::A, foo = foo
diff --git a/test/prism/fixtures/whitequark/masgn_nested.txt b/test/prism/fixtures/whitequark/masgn_nested.txt
new file mode 100644
index 0000000000..a1ccf4e385
--- /dev/null
+++ b/test/prism/fixtures/whitequark/masgn_nested.txt
@@ -0,0 +1,3 @@
+((b, )) = foo
+
+a, (b, c) = foo
diff --git a/test/prism/fixtures/whitequark/masgn_splat.txt b/test/prism/fixtures/whitequark/masgn_splat.txt
new file mode 100644
index 0000000000..a15dab10f2
--- /dev/null
+++ b/test/prism/fixtures/whitequark/masgn_splat.txt
@@ -0,0 +1,19 @@
+* = bar
+
+*, c, d = bar
+
+*b = bar
+
+*b, c = bar
+
+@foo, @@bar = *foo
+
+a, * = bar
+
+a, *, c = bar
+
+a, *b = bar
+
+a, *b, c = bar
+
+a, b = *foo, bar
diff --git a/test/prism/fixtures/whitequark/module.txt b/test/prism/fixtures/whitequark/module.txt
new file mode 100644
index 0000000000..f999df3791
--- /dev/null
+++ b/test/prism/fixtures/whitequark/module.txt
@@ -0,0 +1 @@
+module Foo; end
diff --git a/test/prism/fixtures/whitequark/multiple_pattern_matches.txt b/test/prism/fixtures/whitequark/multiple_pattern_matches.txt
new file mode 100644
index 0000000000..54a4bb4774
--- /dev/null
+++ b/test/prism/fixtures/whitequark/multiple_pattern_matches.txt
@@ -0,0 +1,5 @@
+{a: 0} => a:
+{a: 0} => a:
+
+{a: 0} in a:
+{a: 0} in a:
diff --git a/test/prism/fixtures/whitequark/newline_in_hash_argument.txt b/test/prism/fixtures/whitequark/newline_in_hash_argument.txt
new file mode 100644
index 0000000000..1681844331
--- /dev/null
+++ b/test/prism/fixtures/whitequark/newline_in_hash_argument.txt
@@ -0,0 +1,14 @@
+case foo
+in a:
+0
+true
+in "b":
+0
+true
+end
+
+obj.set "foo":
+1
+
+obj.set foo:
+1
diff --git a/test/prism/fixtures/whitequark/nil.txt b/test/prism/fixtures/whitequark/nil.txt
new file mode 100644
index 0000000000..607602cfc6
--- /dev/null
+++ b/test/prism/fixtures/whitequark/nil.txt
@@ -0,0 +1 @@
+nil
diff --git a/test/prism/fixtures/whitequark/nil_expression.txt b/test/prism/fixtures/whitequark/nil_expression.txt
new file mode 100644
index 0000000000..aabf53f005
--- /dev/null
+++ b/test/prism/fixtures/whitequark/nil_expression.txt
@@ -0,0 +1,3 @@
+()
+
+begin end
diff --git a/test/prism/fixtures/whitequark/non_lvar_injecting_match.txt b/test/prism/fixtures/whitequark/non_lvar_injecting_match.txt
new file mode 100644
index 0000000000..f1eb7d3c2c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/non_lvar_injecting_match.txt
@@ -0,0 +1 @@
+/#{1}(?<match>bar)/ =~ 'bar'
diff --git a/test/prism/fixtures/whitequark/not.txt b/test/prism/fixtures/whitequark/not.txt
new file mode 100644
index 0000000000..d87f68f48c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/not.txt
@@ -0,0 +1,5 @@
+not foo
+
+not()
+
+not(foo)
diff --git a/test/prism/fixtures/whitequark/not_cmd.txt b/test/prism/fixtures/whitequark/not_cmd.txt
new file mode 100644
index 0000000000..685ec209ee
--- /dev/null
+++ b/test/prism/fixtures/whitequark/not_cmd.txt
@@ -0,0 +1 @@
+not m foo
diff --git a/test/prism/fixtures/whitequark/not_masgn__24.txt b/test/prism/fixtures/whitequark/not_masgn__24.txt
new file mode 100644
index 0000000000..cb93b9103d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/not_masgn__24.txt
@@ -0,0 +1 @@
+!(a, b = foo)
diff --git a/test/prism/fixtures/whitequark/nth_ref.txt b/test/prism/fixtures/whitequark/nth_ref.txt
new file mode 100644
index 0000000000..16ef65b105
--- /dev/null
+++ b/test/prism/fixtures/whitequark/nth_ref.txt
@@ -0,0 +1 @@
+$10
diff --git a/test/prism/fixtures/whitequark/numbered_args_after_27.txt b/test/prism/fixtures/whitequark/numbered_args_after_27.txt
new file mode 100644
index 0000000000..96fe7a32e2
--- /dev/null
+++ b/test/prism/fixtures/whitequark/numbered_args_after_27.txt
@@ -0,0 +1,7 @@
+-> do _1 + _9 end
+
+-> { _1 + _9}
+
+m do _1 + _9 end
+
+m { _1 + _9 }
diff --git a/test/prism/fixtures/whitequark/numparam_outside_block.txt b/test/prism/fixtures/whitequark/numparam_outside_block.txt
new file mode 100644
index 0000000000..37cbce182d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/numparam_outside_block.txt
@@ -0,0 +1,9 @@
+_1
+
+class << foo; _1; end
+
+class A; _1; end
+
+def self.m; _1; end
+
+module A; _1; end
diff --git a/test/prism/fixtures/whitequark/numparam_ruby_bug_19025.txt b/test/prism/fixtures/whitequark/numparam_ruby_bug_19025.txt
new file mode 100644
index 0000000000..f9ffd4329a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/numparam_ruby_bug_19025.txt
@@ -0,0 +1 @@
+p { [_1 **2] }
diff --git a/test/prism/fixtures/whitequark/op_asgn.txt b/test/prism/fixtures/whitequark/op_asgn.txt
new file mode 100644
index 0000000000..a5a28b1010
--- /dev/null
+++ b/test/prism/fixtures/whitequark/op_asgn.txt
@@ -0,0 +1,5 @@
+foo.A += 1
+
+foo.a += 1
+
+foo::a += 1
diff --git a/test/prism/fixtures/whitequark/op_asgn_cmd.txt b/test/prism/fixtures/whitequark/op_asgn_cmd.txt
new file mode 100644
index 0000000000..017aa9bef7
--- /dev/null
+++ b/test/prism/fixtures/whitequark/op_asgn_cmd.txt
@@ -0,0 +1,7 @@
+foo.A += m foo
+
+foo.a += m foo
+
+foo::A += m foo
+
+foo::a += m foo
diff --git a/test/prism/fixtures/whitequark/op_asgn_index.txt b/test/prism/fixtures/whitequark/op_asgn_index.txt
new file mode 100644
index 0000000000..92cfb225fc
--- /dev/null
+++ b/test/prism/fixtures/whitequark/op_asgn_index.txt
@@ -0,0 +1 @@
+foo[0, 1] += 2
diff --git a/test/prism/fixtures/whitequark/op_asgn_index_cmd.txt b/test/prism/fixtures/whitequark/op_asgn_index_cmd.txt
new file mode 100644
index 0000000000..161b244bd4
--- /dev/null
+++ b/test/prism/fixtures/whitequark/op_asgn_index_cmd.txt
@@ -0,0 +1 @@
+foo[0, 1] += m foo
diff --git a/test/prism/fixtures/whitequark/optarg.txt b/test/prism/fixtures/whitequark/optarg.txt
new file mode 100644
index 0000000000..9d60609961
--- /dev/null
+++ b/test/prism/fixtures/whitequark/optarg.txt
@@ -0,0 +1,3 @@
+def f foo = 1; end
+
+def f(foo=1, bar=2); end
diff --git a/test/prism/fixtures/whitequark/or.txt b/test/prism/fixtures/whitequark/or.txt
new file mode 100644
index 0000000000..c2042ebb41
--- /dev/null
+++ b/test/prism/fixtures/whitequark/or.txt
@@ -0,0 +1,3 @@
+foo or bar
+
+foo || bar
diff --git a/test/prism/fixtures/whitequark/or_asgn.txt b/test/prism/fixtures/whitequark/or_asgn.txt
new file mode 100644
index 0000000000..6e4ecc9f93
--- /dev/null
+++ b/test/prism/fixtures/whitequark/or_asgn.txt
@@ -0,0 +1,3 @@
+foo.a ||= 1
+
+foo[0, 1] ||= 2
diff --git a/test/prism/fixtures/whitequark/parser_bug_272.txt b/test/prism/fixtures/whitequark/parser_bug_272.txt
new file mode 100644
index 0000000000..2f2f2b84d2
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_272.txt
@@ -0,0 +1 @@
+a @b do |c|;end
diff --git a/test/prism/fixtures/whitequark/parser_bug_490.txt b/test/prism/fixtures/whitequark/parser_bug_490.txt
new file mode 100644
index 0000000000..cf544b1ff6
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_490.txt
@@ -0,0 +1,5 @@
+def m; class << self; A = nil; end; end
+
+def m; class << self; class C; end; end; end
+
+def m; class << self; module M; end; end; end
diff --git a/test/prism/fixtures/whitequark/parser_bug_507.txt b/test/prism/fixtures/whitequark/parser_bug_507.txt
new file mode 100644
index 0000000000..bf616b85c8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_507.txt
@@ -0,0 +1 @@
+m = -> *args do end
diff --git a/test/prism/fixtures/whitequark/parser_bug_518.txt b/test/prism/fixtures/whitequark/parser_bug_518.txt
new file mode 100644
index 0000000000..22f4afe3c8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_518.txt
@@ -0,0 +1,2 @@
+class A < B
+end
diff --git a/test/prism/fixtures/whitequark/parser_bug_525.txt b/test/prism/fixtures/whitequark/parser_bug_525.txt
new file mode 100644
index 0000000000..59d0e735b4
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_525.txt
@@ -0,0 +1 @@
+m1 :k => m2 do; m3() do end; end
diff --git a/test/prism/fixtures/whitequark/parser_bug_604.txt b/test/prism/fixtures/whitequark/parser_bug_604.txt
new file mode 100644
index 0000000000..7eb91c2f46
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_604.txt
@@ -0,0 +1 @@
+m a + b do end
diff --git a/test/prism/fixtures/whitequark/parser_bug_640.txt b/test/prism/fixtures/whitequark/parser_bug_640.txt
new file mode 100644
index 0000000000..fb62ded04c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_640.txt
@@ -0,0 +1,4 @@
+<<~FOO
+ baz\
+ qux
+FOO
diff --git a/test/prism/fixtures/whitequark/parser_bug_645.txt b/test/prism/fixtures/whitequark/parser_bug_645.txt
new file mode 100644
index 0000000000..cb1e5a0dcf
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_645.txt
@@ -0,0 +1 @@
+-> (arg={}) {}
diff --git a/test/prism/fixtures/whitequark/parser_bug_830.txt b/test/prism/fixtures/whitequark/parser_bug_830.txt
new file mode 100644
index 0000000000..e5865e960d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_830.txt
@@ -0,0 +1 @@
+/\(/
diff --git a/test/prism/fixtures/whitequark/parser_bug_989.txt b/test/prism/fixtures/whitequark/parser_bug_989.txt
new file mode 100644
index 0000000000..b7b99612b4
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_bug_989.txt
@@ -0,0 +1,3 @@
+ <<-HERE
+ content
+ HERE
diff --git a/test/prism/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt b/test/prism/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt
new file mode 100644
index 0000000000..bddae8e153
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt
@@ -0,0 +1,3 @@
+<<~HERE
+ #{}
+HERE
diff --git a/test/prism/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt b/test/prism/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt
new file mode 100644
index 0000000000..564cebdd74
--- /dev/null
+++ b/test/prism/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt
@@ -0,0 +1,62 @@
+"a\
+b"
+
+%I{a\
+b}
+
+%Q{a\
+b}
+
+%W{a\
+b}
+
+%i{a\
+b}
+
+%q{a\
+b}
+
+%r{a\
+b}
+
+%s{a\
+b}
+
+%w{a\
+b}
+
+%x{a\
+b}
+
+%{a\
+b}
+
+'a\
+b'
+
+/a\
+b/
+
+:"a\
+b"
+
+:'a\
+b'
+
+<<-"HERE"
+a\
+b
+HERE
+
+<<-'HERE'
+a\
+b
+HERE
+
+<<-`HERE`
+a\
+b
+HERE
+
+`a\
+b`
diff --git a/test/prism/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt b/test/prism/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt
new file mode 100644
index 0000000000..fe0edaed55
--- /dev/null
+++ b/test/prism/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt
@@ -0,0 +1,4 @@
+ case [__FILE__, __LINE__ + 1, __ENCODING__]
+ in [__FILE__, __LINE__, __ENCODING__]
+ end
+
diff --git a/test/prism/fixtures/whitequark/pattern_matching_blank_else.txt b/test/prism/fixtures/whitequark/pattern_matching_blank_else.txt
new file mode 100644
index 0000000000..6bf059af41
--- /dev/null
+++ b/test/prism/fixtures/whitequark/pattern_matching_blank_else.txt
@@ -0,0 +1 @@
+case 1; in 2; 3; else; end
diff --git a/test/prism/fixtures/whitequark/pattern_matching_else.txt b/test/prism/fixtures/whitequark/pattern_matching_else.txt
new file mode 100644
index 0000000000..29f14c91ab
--- /dev/null
+++ b/test/prism/fixtures/whitequark/pattern_matching_else.txt
@@ -0,0 +1 @@
+case 1; in 2; 3; else; 4; end
diff --git a/test/prism/fixtures/whitequark/pattern_matching_single_line.txt b/test/prism/fixtures/whitequark/pattern_matching_single_line.txt
new file mode 100644
index 0000000000..12279afa24
--- /dev/null
+++ b/test/prism/fixtures/whitequark/pattern_matching_single_line.txt
@@ -0,0 +1,3 @@
+1 => [a]; a
+
+1 in [a]; a
diff --git a/test/prism/fixtures/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt b/test/prism/fixtures/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt
new file mode 100644
index 0000000000..1e429335d0
--- /dev/null
+++ b/test/prism/fixtures/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt
@@ -0,0 +1,11 @@
+[1, 2] => a, b; a
+
+[1, 2] in a, b; a
+
+{a: 1} => a:; a
+
+{a: 1} in a:; a
+
+{key: :value} => key: value; value
+
+{key: :value} in key: value; value
diff --git a/test/prism/fixtures/whitequark/postexe.txt b/test/prism/fixtures/whitequark/postexe.txt
new file mode 100644
index 0000000000..baee33af66
--- /dev/null
+++ b/test/prism/fixtures/whitequark/postexe.txt
@@ -0,0 +1 @@
+END { 1 }
diff --git a/test/prism/fixtures/whitequark/preexe.txt b/test/prism/fixtures/whitequark/preexe.txt
new file mode 100644
index 0000000000..9e802f3f4e
--- /dev/null
+++ b/test/prism/fixtures/whitequark/preexe.txt
@@ -0,0 +1 @@
+BEGIN { 1 }
diff --git a/test/prism/fixtures/whitequark/procarg0.txt b/test/prism/fixtures/whitequark/procarg0.txt
new file mode 100644
index 0000000000..74cae2c2eb
--- /dev/null
+++ b/test/prism/fixtures/whitequark/procarg0.txt
@@ -0,0 +1,3 @@
+m { |(foo, bar)| }
+
+m { |foo| }
diff --git a/test/prism/fixtures/whitequark/range_exclusive.txt b/test/prism/fixtures/whitequark/range_exclusive.txt
new file mode 100644
index 0000000000..9e07faed27
--- /dev/null
+++ b/test/prism/fixtures/whitequark/range_exclusive.txt
@@ -0,0 +1 @@
+1...2
diff --git a/test/prism/fixtures/whitequark/range_inclusive.txt b/test/prism/fixtures/whitequark/range_inclusive.txt
new file mode 100644
index 0000000000..8c12abf7de
--- /dev/null
+++ b/test/prism/fixtures/whitequark/range_inclusive.txt
@@ -0,0 +1 @@
+1..2
diff --git a/test/prism/fixtures/whitequark/rational.txt b/test/prism/fixtures/whitequark/rational.txt
new file mode 100644
index 0000000000..e11cacc742
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rational.txt
@@ -0,0 +1,3 @@
+42.1r
+
+42r
diff --git a/test/prism/fixtures/whitequark/regex_interp.txt b/test/prism/fixtures/whitequark/regex_interp.txt
new file mode 100644
index 0000000000..f9ad7fcbc8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/regex_interp.txt
@@ -0,0 +1 @@
+/foo#{bar}baz/
diff --git a/test/prism/fixtures/whitequark/regex_plain.txt b/test/prism/fixtures/whitequark/regex_plain.txt
new file mode 100644
index 0000000000..b86faecf98
--- /dev/null
+++ b/test/prism/fixtures/whitequark/regex_plain.txt
@@ -0,0 +1 @@
+/source/im
diff --git a/test/prism/fixtures/whitequark/resbody_list.txt b/test/prism/fixtures/whitequark/resbody_list.txt
new file mode 100644
index 0000000000..e40d45fc45
--- /dev/null
+++ b/test/prism/fixtures/whitequark/resbody_list.txt
@@ -0,0 +1 @@
+begin; meth; rescue Exception; bar; end
diff --git a/test/prism/fixtures/whitequark/resbody_list_mrhs.txt b/test/prism/fixtures/whitequark/resbody_list_mrhs.txt
new file mode 100644
index 0000000000..92b8bb2c02
--- /dev/null
+++ b/test/prism/fixtures/whitequark/resbody_list_mrhs.txt
@@ -0,0 +1 @@
+begin; meth; rescue Exception, foo; bar; end
diff --git a/test/prism/fixtures/whitequark/resbody_list_var.txt b/test/prism/fixtures/whitequark/resbody_list_var.txt
new file mode 100644
index 0000000000..0a2fb90b6d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/resbody_list_var.txt
@@ -0,0 +1 @@
+begin; meth; rescue foo => ex; bar; end
diff --git a/test/prism/fixtures/whitequark/resbody_var.txt b/test/prism/fixtures/whitequark/resbody_var.txt
new file mode 100644
index 0000000000..2104ac58e7
--- /dev/null
+++ b/test/prism/fixtures/whitequark/resbody_var.txt
@@ -0,0 +1,3 @@
+begin; meth; rescue => @ex; bar; end
+
+begin; meth; rescue => ex; bar; end
diff --git a/test/prism/fixtures/whitequark/rescue.txt b/test/prism/fixtures/whitequark/rescue.txt
new file mode 100644
index 0000000000..2d3be9dc56
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue.txt
@@ -0,0 +1 @@
+begin; meth; rescue; foo; end
diff --git a/test/prism/fixtures/whitequark/rescue_else.txt b/test/prism/fixtures/whitequark/rescue_else.txt
new file mode 100644
index 0000000000..a22f8d100e
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_else.txt
@@ -0,0 +1 @@
+begin; meth; rescue; foo; else; bar; end
diff --git a/test/prism/fixtures/whitequark/rescue_else_ensure.txt b/test/prism/fixtures/whitequark/rescue_else_ensure.txt
new file mode 100644
index 0000000000..167eee194a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_else_ensure.txt
@@ -0,0 +1 @@
+begin; meth; rescue; baz; else foo; ensure; bar end
diff --git a/test/prism/fixtures/whitequark/rescue_ensure.txt b/test/prism/fixtures/whitequark/rescue_ensure.txt
new file mode 100644
index 0000000000..8237257c41
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_ensure.txt
@@ -0,0 +1 @@
+begin; meth; rescue; baz; ensure; bar; end
diff --git a/test/prism/fixtures/whitequark/rescue_in_lambda_block.txt b/test/prism/fixtures/whitequark/rescue_in_lambda_block.txt
new file mode 100644
index 0000000000..ccd8ed72c5
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_in_lambda_block.txt
@@ -0,0 +1 @@
+-> do rescue; end
diff --git a/test/prism/fixtures/whitequark/rescue_mod.txt b/test/prism/fixtures/whitequark/rescue_mod.txt
new file mode 100644
index 0000000000..06375d3e9b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_mod.txt
@@ -0,0 +1 @@
+meth rescue bar
diff --git a/test/prism/fixtures/whitequark/rescue_mod_asgn.txt b/test/prism/fixtures/whitequark/rescue_mod_asgn.txt
new file mode 100644
index 0000000000..abf7cd9a3d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_mod_asgn.txt
@@ -0,0 +1 @@
+foo = meth rescue bar
diff --git a/test/prism/fixtures/whitequark/rescue_mod_masgn.txt b/test/prism/fixtures/whitequark/rescue_mod_masgn.txt
new file mode 100644
index 0000000000..0716eb1f67
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_mod_masgn.txt
@@ -0,0 +1 @@
+foo, bar = meth rescue [1, 2]
diff --git a/test/prism/fixtures/whitequark/rescue_mod_op_assign.txt b/test/prism/fixtures/whitequark/rescue_mod_op_assign.txt
new file mode 100644
index 0000000000..178efa3a20
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_mod_op_assign.txt
@@ -0,0 +1 @@
+foo += meth rescue bar
diff --git a/test/prism/fixtures/whitequark/rescue_without_begin_end.txt b/test/prism/fixtures/whitequark/rescue_without_begin_end.txt
new file mode 100644
index 0000000000..8416569e2c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/rescue_without_begin_end.txt
@@ -0,0 +1 @@
+meth do; foo; rescue; bar; end
diff --git a/test/prism/fixtures/whitequark/restarg_named.txt b/test/prism/fixtures/whitequark/restarg_named.txt
new file mode 100644
index 0000000000..355cd8f493
--- /dev/null
+++ b/test/prism/fixtures/whitequark/restarg_named.txt
@@ -0,0 +1 @@
+def f(*foo); end
diff --git a/test/prism/fixtures/whitequark/restarg_unnamed.txt b/test/prism/fixtures/whitequark/restarg_unnamed.txt
new file mode 100644
index 0000000000..c9932dd30c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/restarg_unnamed.txt
@@ -0,0 +1 @@
+def f(*); end
diff --git a/test/prism/fixtures/whitequark/return.txt b/test/prism/fixtures/whitequark/return.txt
new file mode 100644
index 0000000000..e3d966bda0
--- /dev/null
+++ b/test/prism/fixtures/whitequark/return.txt
@@ -0,0 +1,7 @@
+return
+
+return foo
+
+return()
+
+return(foo)
diff --git a/test/prism/fixtures/whitequark/return_block.txt b/test/prism/fixtures/whitequark/return_block.txt
new file mode 100644
index 0000000000..00723a7517
--- /dev/null
+++ b/test/prism/fixtures/whitequark/return_block.txt
@@ -0,0 +1 @@
+return fun foo do end
diff --git a/test/prism/fixtures/whitequark/ruby_bug_10279.txt b/test/prism/fixtures/whitequark/ruby_bug_10279.txt
new file mode 100644
index 0000000000..4d0fb213d8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_10279.txt
@@ -0,0 +1 @@
+{a: if true then 42 end}
diff --git a/test/prism/fixtures/whitequark/ruby_bug_10653.txt b/test/prism/fixtures/whitequark/ruby_bug_10653.txt
new file mode 100644
index 0000000000..51354a1f70
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_10653.txt
@@ -0,0 +1,5 @@
+false ? raise do end : tap do end
+
+false ? raise {} : tap {}
+
+true ? 1.tap do |n| p n end : 0
diff --git a/test/prism/fixtures/whitequark/ruby_bug_11107.txt b/test/prism/fixtures/whitequark/ruby_bug_11107.txt
new file mode 100644
index 0000000000..1f28cb06f6
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_11107.txt
@@ -0,0 +1 @@
+p ->() do a() do end end
diff --git a/test/prism/fixtures/whitequark/ruby_bug_11380.txt b/test/prism/fixtures/whitequark/ruby_bug_11380.txt
new file mode 100644
index 0000000000..1631548e3a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_11380.txt
@@ -0,0 +1 @@
+p -> { :hello }, a: 1 do end
diff --git a/test/prism/fixtures/whitequark/ruby_bug_11873.txt b/test/prism/fixtures/whitequark/ruby_bug_11873.txt
new file mode 100644
index 0000000000..a25aa9e267
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_11873.txt
@@ -0,0 +1,23 @@
+a b(c d), "x" do end
+
+a b(c d), /x/ do end
+
+a b(c d), /x/m do end
+
+a b(c(d)), "x" do end
+
+a b(c(d)), /x/ do end
+
+a b(c(d)), /x/m do end
+
+a b{c d}, "x" do end
+
+a b{c d}, /x/ do end
+
+a b{c d}, /x/m do end
+
+a b{c(d)}, "x" do end
+
+a b{c(d)}, /x/ do end
+
+a b{c(d)}, /x/m do end
diff --git a/test/prism/fixtures/whitequark/ruby_bug_11873_a.txt b/test/prism/fixtures/whitequark/ruby_bug_11873_a.txt
new file mode 100644
index 0000000000..1856235ce5
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_11873_a.txt
@@ -0,0 +1,39 @@
+a b(c d), 1 do end
+
+a b(c d), 1.0 do end
+
+a b(c d), 1.0i do end
+
+a b(c d), 1.0r do end
+
+a b(c d), :e do end
+
+a b(c(d)), 1 do end
+
+a b(c(d)), 1.0 do end
+
+a b(c(d)), 1.0i do end
+
+a b(c(d)), 1.0r do end
+
+a b(c(d)), :e do end
+
+a b{c d}, 1 do end
+
+a b{c d}, 1.0 do end
+
+a b{c d}, 1.0i do end
+
+a b{c d}, 1.0r do end
+
+a b{c d}, :e do end
+
+a b{c(d)}, 1 do end
+
+a b{c(d)}, 1.0 do end
+
+a b{c(d)}, 1.0i do end
+
+a b{c(d)}, 1.0r do end
+
+a b{c(d)}, :e do end
diff --git a/test/prism/fixtures/whitequark/ruby_bug_11873_b.txt b/test/prism/fixtures/whitequark/ruby_bug_11873_b.txt
new file mode 100644
index 0000000000..1b86662008
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_11873_b.txt
@@ -0,0 +1 @@
+p p{p(p);p p}, tap do end
diff --git a/test/prism/fixtures/whitequark/ruby_bug_11989.txt b/test/prism/fixtures/whitequark/ruby_bug_11989.txt
new file mode 100644
index 0000000000..d49b8614ed
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_11989.txt
@@ -0,0 +1,3 @@
+p <<~"E"
+ x\n y
+E
diff --git a/test/prism/fixtures/whitequark/ruby_bug_11990.txt b/test/prism/fixtures/whitequark/ruby_bug_11990.txt
new file mode 100644
index 0000000000..d0fe7b2739
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_11990.txt
@@ -0,0 +1,3 @@
+p <<~E " y"
+ x
+E
diff --git a/test/prism/fixtures/whitequark/ruby_bug_12073.txt b/test/prism/fixtures/whitequark/ruby_bug_12073.txt
new file mode 100644
index 0000000000..b2e3784422
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_12073.txt
@@ -0,0 +1,3 @@
+a = 1; a b: 1
+
+def foo raise; raise A::B, ''; end
diff --git a/test/prism/fixtures/whitequark/ruby_bug_12402.txt b/test/prism/fixtures/whitequark/ruby_bug_12402.txt
new file mode 100644
index 0000000000..060d5d95a1
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_12402.txt
@@ -0,0 +1,27 @@
+foo += raise bar rescue nil
+
+foo += raise(bar) rescue nil
+
+foo = raise bar rescue nil
+
+foo = raise(bar) rescue nil
+
+foo.C += raise bar rescue nil
+
+foo.C += raise(bar) rescue nil
+
+foo.m += raise bar rescue nil
+
+foo.m += raise(bar) rescue nil
+
+foo::C ||= raise bar rescue nil
+
+foo::C ||= raise(bar) rescue nil
+
+foo::m += raise bar rescue nil
+
+foo::m += raise(bar) rescue nil
+
+foo[0] += raise bar rescue nil
+
+foo[0] += raise(bar) rescue nil
diff --git a/test/prism/fixtures/whitequark/ruby_bug_12669.txt b/test/prism/fixtures/whitequark/ruby_bug_12669.txt
new file mode 100644
index 0000000000..cd89689446
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_12669.txt
@@ -0,0 +1,7 @@
+a += b += raise :x
+
+a += b = raise :x
+
+a = b += raise :x
+
+a = b = raise :x
diff --git a/test/prism/fixtures/whitequark/ruby_bug_12686.txt b/test/prism/fixtures/whitequark/ruby_bug_12686.txt
new file mode 100644
index 0000000000..7742e791b8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_12686.txt
@@ -0,0 +1 @@
+f (g rescue nil)
diff --git a/test/prism/fixtures/whitequark/ruby_bug_13547.txt b/test/prism/fixtures/whitequark/ruby_bug_13547.txt
new file mode 100644
index 0000000000..29eafc3a4c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_13547.txt
@@ -0,0 +1 @@
+meth[] {}
diff --git a/test/prism/fixtures/whitequark/ruby_bug_14690.txt b/test/prism/fixtures/whitequark/ruby_bug_14690.txt
new file mode 100644
index 0000000000..b73b1d8aad
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_14690.txt
@@ -0,0 +1 @@
+let () { m(a) do; end }
diff --git a/test/prism/fixtures/whitequark/ruby_bug_15789.txt b/test/prism/fixtures/whitequark/ruby_bug_15789.txt
new file mode 100644
index 0000000000..6324db5110
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_15789.txt
@@ -0,0 +1,3 @@
+m ->(a = ->{_1}) {a}
+
+m ->(a: ->{_1}) {a}
diff --git a/test/prism/fixtures/whitequark/ruby_bug_9669.txt b/test/prism/fixtures/whitequark/ruby_bug_9669.txt
new file mode 100644
index 0000000000..60dfa09d51
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ruby_bug_9669.txt
@@ -0,0 +1,8 @@
+def a b:
+return
+end
+
+o = {
+a:
+1
+}
diff --git a/test/prism/fixtures/whitequark/sclass.txt b/test/prism/fixtures/whitequark/sclass.txt
new file mode 100644
index 0000000000..e6aadaef21
--- /dev/null
+++ b/test/prism/fixtures/whitequark/sclass.txt
@@ -0,0 +1 @@
+class << foo; nil; end
diff --git a/test/prism/fixtures/whitequark/self.txt b/test/prism/fixtures/whitequark/self.txt
new file mode 100644
index 0000000000..31f9efa4a1
--- /dev/null
+++ b/test/prism/fixtures/whitequark/self.txt
@@ -0,0 +1 @@
+self
diff --git a/test/prism/fixtures/whitequark/send_attr_asgn.txt b/test/prism/fixtures/whitequark/send_attr_asgn.txt
new file mode 100644
index 0000000000..b477966b2a
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_attr_asgn.txt
@@ -0,0 +1,7 @@
+foo.A = 1
+
+foo.a = 1
+
+foo::A = 1
+
+foo::a = 1
diff --git a/test/prism/fixtures/whitequark/send_attr_asgn_conditional.txt b/test/prism/fixtures/whitequark/send_attr_asgn_conditional.txt
new file mode 100644
index 0000000000..1279e02cfc
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_attr_asgn_conditional.txt
@@ -0,0 +1 @@
+a&.b = 1
diff --git a/test/prism/fixtures/whitequark/send_binary_op.txt b/test/prism/fixtures/whitequark/send_binary_op.txt
new file mode 100644
index 0000000000..3e3e9300b3
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_binary_op.txt
@@ -0,0 +1,41 @@
+foo != 1
+
+foo !~ 1
+
+foo % 1
+
+foo & 1
+
+foo * 1
+
+foo ** 1
+
+foo + 1
+
+foo - 1
+
+foo / 1
+
+foo < 1
+
+foo << 1
+
+foo <= 1
+
+foo <=> 1
+
+foo == 1
+
+foo === 1
+
+foo =~ 1
+
+foo > 1
+
+foo >= 1
+
+foo >> 1
+
+foo ^ 1
+
+foo | 1
diff --git a/test/prism/fixtures/whitequark/send_block_chain_cmd.txt b/test/prism/fixtures/whitequark/send_block_chain_cmd.txt
new file mode 100644
index 0000000000..c6fe1aab0e
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_block_chain_cmd.txt
@@ -0,0 +1,13 @@
+meth 1 do end.fun bar
+
+meth 1 do end.fun bar do end
+
+meth 1 do end.fun {}
+
+meth 1 do end.fun(bar)
+
+meth 1 do end.fun(bar) {}
+
+meth 1 do end::fun bar
+
+meth 1 do end::fun(bar)
diff --git a/test/prism/fixtures/whitequark/send_block_conditional.txt b/test/prism/fixtures/whitequark/send_block_conditional.txt
new file mode 100644
index 0000000000..dcc8361762
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_block_conditional.txt
@@ -0,0 +1 @@
+foo&.bar {}
diff --git a/test/prism/fixtures/whitequark/send_call.txt b/test/prism/fixtures/whitequark/send_call.txt
new file mode 100644
index 0000000000..99701270bb
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_call.txt
@@ -0,0 +1,3 @@
+foo.(1)
+
+foo::(1)
diff --git a/test/prism/fixtures/whitequark/send_conditional.txt b/test/prism/fixtures/whitequark/send_conditional.txt
new file mode 100644
index 0000000000..8ecd27e0fe
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_conditional.txt
@@ -0,0 +1 @@
+a&.b
diff --git a/test/prism/fixtures/whitequark/send_index.txt b/test/prism/fixtures/whitequark/send_index.txt
new file mode 100644
index 0000000000..f9c4dafc4e
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_index.txt
@@ -0,0 +1 @@
+foo[1, 2]
diff --git a/test/prism/fixtures/whitequark/send_index_asgn.txt b/test/prism/fixtures/whitequark/send_index_asgn.txt
new file mode 100644
index 0000000000..e232fa3b96
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_index_asgn.txt
@@ -0,0 +1 @@
+foo[1, 2] = 3
diff --git a/test/prism/fixtures/whitequark/send_index_asgn_legacy.txt b/test/prism/fixtures/whitequark/send_index_asgn_legacy.txt
new file mode 100644
index 0000000000..e232fa3b96
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_index_asgn_legacy.txt
@@ -0,0 +1 @@
+foo[1, 2] = 3
diff --git a/test/prism/fixtures/whitequark/send_index_cmd.txt b/test/prism/fixtures/whitequark/send_index_cmd.txt
new file mode 100644
index 0000000000..32090e7536
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_index_cmd.txt
@@ -0,0 +1 @@
+foo[m bar]
diff --git a/test/prism/fixtures/whitequark/send_index_legacy.txt b/test/prism/fixtures/whitequark/send_index_legacy.txt
new file mode 100644
index 0000000000..f9c4dafc4e
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_index_legacy.txt
@@ -0,0 +1 @@
+foo[1, 2]
diff --git a/test/prism/fixtures/whitequark/send_lambda.txt b/test/prism/fixtures/whitequark/send_lambda.txt
new file mode 100644
index 0000000000..eadd6c9c03
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_lambda.txt
@@ -0,0 +1,5 @@
+-> * { }
+
+-> do end
+
+->{ }
diff --git a/test/prism/fixtures/whitequark/send_lambda_args.txt b/test/prism/fixtures/whitequark/send_lambda_args.txt
new file mode 100644
index 0000000000..68392f2f34
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_lambda_args.txt
@@ -0,0 +1,3 @@
+-> (a) { }
+
+->(a) { }
diff --git a/test/prism/fixtures/whitequark/send_lambda_args_noparen.txt b/test/prism/fixtures/whitequark/send_lambda_args_noparen.txt
new file mode 100644
index 0000000000..c0ae077f95
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_lambda_args_noparen.txt
@@ -0,0 +1,3 @@
+-> a: 1 { }
+
+-> a: { }
diff --git a/test/prism/fixtures/whitequark/send_lambda_args_shadow.txt b/test/prism/fixtures/whitequark/send_lambda_args_shadow.txt
new file mode 100644
index 0000000000..230f35ab89
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_lambda_args_shadow.txt
@@ -0,0 +1 @@
+->(a; foo, bar) { }
diff --git a/test/prism/fixtures/whitequark/send_lambda_legacy.txt b/test/prism/fixtures/whitequark/send_lambda_legacy.txt
new file mode 100644
index 0000000000..a509407c43
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_lambda_legacy.txt
@@ -0,0 +1 @@
+->{ }
diff --git a/test/prism/fixtures/whitequark/send_op_asgn_conditional.txt b/test/prism/fixtures/whitequark/send_op_asgn_conditional.txt
new file mode 100644
index 0000000000..906088dcd1
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_op_asgn_conditional.txt
@@ -0,0 +1 @@
+a&.b &&= 1
diff --git a/test/prism/fixtures/whitequark/send_plain.txt b/test/prism/fixtures/whitequark/send_plain.txt
new file mode 100644
index 0000000000..ebaf1d18c7
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_plain.txt
@@ -0,0 +1,5 @@
+foo.fun
+
+foo::Fun()
+
+foo::fun
diff --git a/test/prism/fixtures/whitequark/send_plain_cmd.txt b/test/prism/fixtures/whitequark/send_plain_cmd.txt
new file mode 100644
index 0000000000..e3fd63f272
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_plain_cmd.txt
@@ -0,0 +1,5 @@
+foo.fun bar
+
+foo::Fun bar
+
+foo::fun bar
diff --git a/test/prism/fixtures/whitequark/send_self.txt b/test/prism/fixtures/whitequark/send_self.txt
new file mode 100644
index 0000000000..f084b9bca7
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_self.txt
@@ -0,0 +1,5 @@
+fun
+
+fun!
+
+fun(1)
diff --git a/test/prism/fixtures/whitequark/send_self_block.txt b/test/prism/fixtures/whitequark/send_self_block.txt
new file mode 100644
index 0000000000..1cd6703c82
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_self_block.txt
@@ -0,0 +1,7 @@
+fun do end
+
+fun { }
+
+fun() { }
+
+fun(1) { }
diff --git a/test/prism/fixtures/whitequark/send_unary_op.txt b/test/prism/fixtures/whitequark/send_unary_op.txt
new file mode 100644
index 0000000000..73814d199f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/send_unary_op.txt
@@ -0,0 +1,5 @@
++foo
+
+-foo
+
+~foo
diff --git a/test/prism/fixtures/whitequark/slash_newline_in_heredocs.txt b/test/prism/fixtures/whitequark/slash_newline_in_heredocs.txt
new file mode 100644
index 0000000000..4962a058ea
--- /dev/null
+++ b/test/prism/fixtures/whitequark/slash_newline_in_heredocs.txt
@@ -0,0 +1,13 @@
+<<-E
+ 1 \
+ 2
+ 3
+E
+
+
+<<~E
+ 1 \
+ 2
+ 3
+E
+
diff --git a/test/prism/fixtures/whitequark/space_args_arg.txt b/test/prism/fixtures/whitequark/space_args_arg.txt
new file mode 100644
index 0000000000..47957cba54
--- /dev/null
+++ b/test/prism/fixtures/whitequark/space_args_arg.txt
@@ -0,0 +1 @@
+fun (1)
diff --git a/test/prism/fixtures/whitequark/space_args_arg_block.txt b/test/prism/fixtures/whitequark/space_args_arg_block.txt
new file mode 100644
index 0000000000..5560a82818
--- /dev/null
+++ b/test/prism/fixtures/whitequark/space_args_arg_block.txt
@@ -0,0 +1,5 @@
+foo.fun (1) {}
+
+foo::fun (1) {}
+
+fun (1) {}
diff --git a/test/prism/fixtures/whitequark/space_args_arg_call.txt b/test/prism/fixtures/whitequark/space_args_arg_call.txt
new file mode 100644
index 0000000000..3b0ae831fe
--- /dev/null
+++ b/test/prism/fixtures/whitequark/space_args_arg_call.txt
@@ -0,0 +1 @@
+fun (1).to_i
diff --git a/test/prism/fixtures/whitequark/space_args_arg_newline.txt b/test/prism/fixtures/whitequark/space_args_arg_newline.txt
new file mode 100644
index 0000000000..a6cdac6ed1
--- /dev/null
+++ b/test/prism/fixtures/whitequark/space_args_arg_newline.txt
@@ -0,0 +1,2 @@
+fun (1
+)
diff --git a/test/prism/fixtures/whitequark/space_args_block.txt b/test/prism/fixtures/whitequark/space_args_block.txt
new file mode 100644
index 0000000000..555a097605
--- /dev/null
+++ b/test/prism/fixtures/whitequark/space_args_block.txt
@@ -0,0 +1 @@
+fun () {}
diff --git a/test/prism/fixtures/whitequark/space_args_cmd.txt b/test/prism/fixtures/whitequark/space_args_cmd.txt
new file mode 100644
index 0000000000..a749695cb7
--- /dev/null
+++ b/test/prism/fixtures/whitequark/space_args_cmd.txt
@@ -0,0 +1 @@
+fun (f bar)
diff --git a/test/prism/fixtures/whitequark/string___FILE__.txt b/test/prism/fixtures/whitequark/string___FILE__.txt
new file mode 100644
index 0000000000..4815727d05
--- /dev/null
+++ b/test/prism/fixtures/whitequark/string___FILE__.txt
@@ -0,0 +1 @@
+__FILE__
diff --git a/test/prism/fixtures/whitequark/string_concat.txt b/test/prism/fixtures/whitequark/string_concat.txt
new file mode 100644
index 0000000000..30cc4f8116
--- /dev/null
+++ b/test/prism/fixtures/whitequark/string_concat.txt
@@ -0,0 +1 @@
+"foo#@a" "bar"
diff --git a/test/prism/fixtures/whitequark/string_dvar.txt b/test/prism/fixtures/whitequark/string_dvar.txt
new file mode 100644
index 0000000000..bbe5b617b2
--- /dev/null
+++ b/test/prism/fixtures/whitequark/string_dvar.txt
@@ -0,0 +1 @@
+"#@a #@@a #$a"
diff --git a/test/prism/fixtures/whitequark/string_interp.txt b/test/prism/fixtures/whitequark/string_interp.txt
new file mode 100644
index 0000000000..5fdd803341
--- /dev/null
+++ b/test/prism/fixtures/whitequark/string_interp.txt
@@ -0,0 +1 @@
+"foo#{bar}baz"
diff --git a/test/prism/fixtures/whitequark/string_plain.txt b/test/prism/fixtures/whitequark/string_plain.txt
new file mode 100644
index 0000000000..4aca78decb
--- /dev/null
+++ b/test/prism/fixtures/whitequark/string_plain.txt
@@ -0,0 +1,3 @@
+%q(foobar)
+
+'foobar'
diff --git a/test/prism/fixtures/whitequark/super.txt b/test/prism/fixtures/whitequark/super.txt
new file mode 100644
index 0000000000..9e68a9e988
--- /dev/null
+++ b/test/prism/fixtures/whitequark/super.txt
@@ -0,0 +1,5 @@
+super foo
+
+super()
+
+super(foo)
diff --git a/test/prism/fixtures/whitequark/super_block.txt b/test/prism/fixtures/whitequark/super_block.txt
new file mode 100644
index 0000000000..05a7d7fdd8
--- /dev/null
+++ b/test/prism/fixtures/whitequark/super_block.txt
@@ -0,0 +1,3 @@
+super do end
+
+super foo, bar do end
diff --git a/test/prism/fixtures/whitequark/symbol_interp.txt b/test/prism/fixtures/whitequark/symbol_interp.txt
new file mode 100644
index 0000000000..d5011b270d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/symbol_interp.txt
@@ -0,0 +1 @@
+:"foo#{bar}baz"
diff --git a/test/prism/fixtures/whitequark/symbol_plain.txt b/test/prism/fixtures/whitequark/symbol_plain.txt
new file mode 100644
index 0000000000..fd1fd0017c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/symbol_plain.txt
@@ -0,0 +1,3 @@
+:'foo'
+
+:foo
diff --git a/test/prism/fixtures/whitequark/ternary.txt b/test/prism/fixtures/whitequark/ternary.txt
new file mode 100644
index 0000000000..3a149d4e1c
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ternary.txt
@@ -0,0 +1 @@
+foo ? 1 : 2
diff --git a/test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt b/test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt
new file mode 100644
index 0000000000..19aa523c07
--- /dev/null
+++ b/test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt
@@ -0,0 +1 @@
+t=1;(foo)?t:T
diff --git a/test/prism/fixtures/whitequark/trailing_forward_arg.txt b/test/prism/fixtures/whitequark/trailing_forward_arg.txt
new file mode 100644
index 0000000000..043870ade2
--- /dev/null
+++ b/test/prism/fixtures/whitequark/trailing_forward_arg.txt
@@ -0,0 +1 @@
+def foo(a, b, ...); bar(a, 42, ...); end
diff --git a/test/prism/fixtures/whitequark/true.txt b/test/prism/fixtures/whitequark/true.txt
new file mode 100644
index 0000000000..27ba77ddaf
--- /dev/null
+++ b/test/prism/fixtures/whitequark/true.txt
@@ -0,0 +1 @@
+true
diff --git a/test/prism/fixtures/whitequark/unary_num_pow_precedence.txt b/test/prism/fixtures/whitequark/unary_num_pow_precedence.txt
new file mode 100644
index 0000000000..f0343e3c8b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/unary_num_pow_precedence.txt
@@ -0,0 +1,5 @@
++2.0 ** 10
+
+-2 ** 10
+
+-2.0 ** 10
diff --git a/test/prism/fixtures/whitequark/undef.txt b/test/prism/fixtures/whitequark/undef.txt
new file mode 100644
index 0000000000..3e88ec7084
--- /dev/null
+++ b/test/prism/fixtures/whitequark/undef.txt
@@ -0,0 +1 @@
+undef foo, :bar, :"foo#{1}"
diff --git a/test/prism/fixtures/whitequark/unless.txt b/test/prism/fixtures/whitequark/unless.txt
new file mode 100644
index 0000000000..d04043ed90
--- /dev/null
+++ b/test/prism/fixtures/whitequark/unless.txt
@@ -0,0 +1,3 @@
+unless foo then bar; end
+
+unless foo; bar; end
diff --git a/test/prism/fixtures/whitequark/unless_else.txt b/test/prism/fixtures/whitequark/unless_else.txt
new file mode 100644
index 0000000000..8243d42031
--- /dev/null
+++ b/test/prism/fixtures/whitequark/unless_else.txt
@@ -0,0 +1,3 @@
+unless foo then bar; else baz; end
+
+unless foo; bar; else baz; end
diff --git a/test/prism/fixtures/whitequark/unless_mod.txt b/test/prism/fixtures/whitequark/unless_mod.txt
new file mode 100644
index 0000000000..2d0376a310
--- /dev/null
+++ b/test/prism/fixtures/whitequark/unless_mod.txt
@@ -0,0 +1 @@
+bar unless foo
diff --git a/test/prism/fixtures/whitequark/until.txt b/test/prism/fixtures/whitequark/until.txt
new file mode 100644
index 0000000000..06082233cb
--- /dev/null
+++ b/test/prism/fixtures/whitequark/until.txt
@@ -0,0 +1,3 @@
+until foo do meth end
+
+until foo; meth end
diff --git a/test/prism/fixtures/whitequark/until_mod.txt b/test/prism/fixtures/whitequark/until_mod.txt
new file mode 100644
index 0000000000..46a85d2ba9
--- /dev/null
+++ b/test/prism/fixtures/whitequark/until_mod.txt
@@ -0,0 +1 @@
+meth until foo
diff --git a/test/prism/fixtures/whitequark/until_post.txt b/test/prism/fixtures/whitequark/until_post.txt
new file mode 100644
index 0000000000..988e43b665
--- /dev/null
+++ b/test/prism/fixtures/whitequark/until_post.txt
@@ -0,0 +1 @@
+begin meth end until foo
diff --git a/test/prism/fixtures/whitequark/var_and_asgn.txt b/test/prism/fixtures/whitequark/var_and_asgn.txt
new file mode 100644
index 0000000000..25502968f9
--- /dev/null
+++ b/test/prism/fixtures/whitequark/var_and_asgn.txt
@@ -0,0 +1 @@
+a &&= 1
diff --git a/test/prism/fixtures/whitequark/var_op_asgn.txt b/test/prism/fixtures/whitequark/var_op_asgn.txt
new file mode 100644
index 0000000000..402d818a7e
--- /dev/null
+++ b/test/prism/fixtures/whitequark/var_op_asgn.txt
@@ -0,0 +1,7 @@
+@@var |= 10
+
+@a |= 1
+
+a += 1
+
+def a; @@var |= 10; end
diff --git a/test/prism/fixtures/whitequark/var_op_asgn_cmd.txt b/test/prism/fixtures/whitequark/var_op_asgn_cmd.txt
new file mode 100644
index 0000000000..33f4bc0e73
--- /dev/null
+++ b/test/prism/fixtures/whitequark/var_op_asgn_cmd.txt
@@ -0,0 +1 @@
+foo += m foo
diff --git a/test/prism/fixtures/whitequark/var_or_asgn.txt b/test/prism/fixtures/whitequark/var_or_asgn.txt
new file mode 100644
index 0000000000..aa30b3d5ca
--- /dev/null
+++ b/test/prism/fixtures/whitequark/var_or_asgn.txt
@@ -0,0 +1 @@
+a ||= 1
diff --git a/test/prism/fixtures/whitequark/when_multi.txt b/test/prism/fixtures/whitequark/when_multi.txt
new file mode 100644
index 0000000000..b4fbd33125
--- /dev/null
+++ b/test/prism/fixtures/whitequark/when_multi.txt
@@ -0,0 +1 @@
+case foo; when 'bar', 'baz'; bar; end
diff --git a/test/prism/fixtures/whitequark/when_splat.txt b/test/prism/fixtures/whitequark/when_splat.txt
new file mode 100644
index 0000000000..695e5da34e
--- /dev/null
+++ b/test/prism/fixtures/whitequark/when_splat.txt
@@ -0,0 +1 @@
+case foo; when 1, *baz; bar; when *foo; end
diff --git a/test/prism/fixtures/whitequark/when_then.txt b/test/prism/fixtures/whitequark/when_then.txt
new file mode 100644
index 0000000000..63293452b3
--- /dev/null
+++ b/test/prism/fixtures/whitequark/when_then.txt
@@ -0,0 +1 @@
+case foo; when 'bar' then bar; end
diff --git a/test/prism/fixtures/whitequark/while.txt b/test/prism/fixtures/whitequark/while.txt
new file mode 100644
index 0000000000..28b204f247
--- /dev/null
+++ b/test/prism/fixtures/whitequark/while.txt
@@ -0,0 +1,3 @@
+while foo do meth end
+
+while foo; meth end
diff --git a/test/prism/fixtures/whitequark/while_mod.txt b/test/prism/fixtures/whitequark/while_mod.txt
new file mode 100644
index 0000000000..ce3cf01d14
--- /dev/null
+++ b/test/prism/fixtures/whitequark/while_mod.txt
@@ -0,0 +1 @@
+meth while foo
diff --git a/test/prism/fixtures/whitequark/while_post.txt b/test/prism/fixtures/whitequark/while_post.txt
new file mode 100644
index 0000000000..ac6e05008b
--- /dev/null
+++ b/test/prism/fixtures/whitequark/while_post.txt
@@ -0,0 +1 @@
+begin meth end while foo
diff --git a/test/prism/fixtures/whitequark/xstring_interp.txt b/test/prism/fixtures/whitequark/xstring_interp.txt
new file mode 100644
index 0000000000..dfede8123f
--- /dev/null
+++ b/test/prism/fixtures/whitequark/xstring_interp.txt
@@ -0,0 +1 @@
+`foo#{bar}baz`
diff --git a/test/prism/fixtures/whitequark/xstring_plain.txt b/test/prism/fixtures/whitequark/xstring_plain.txt
new file mode 100644
index 0000000000..fce255049d
--- /dev/null
+++ b/test/prism/fixtures/whitequark/xstring_plain.txt
@@ -0,0 +1 @@
+`foobar`
diff --git a/test/prism/fixtures/whitequark/zsuper.txt b/test/prism/fixtures/whitequark/zsuper.txt
new file mode 100644
index 0000000000..16f5c2d3aa
--- /dev/null
+++ b/test/prism/fixtures/whitequark/zsuper.txt
@@ -0,0 +1 @@
+super
diff --git a/test/prism/fixtures/xstring.txt b/test/prism/fixtures/xstring.txt
new file mode 100644
index 0000000000..7ec09468d8
--- /dev/null
+++ b/test/prism/fixtures/xstring.txt
@@ -0,0 +1,13 @@
+%x[foo]
+
+`foo #{bar} baz`
+
+`foo`
+
+%x{
+ foo
+}
+
+``
+
+%x{}
diff --git a/test/prism/fixtures/xstring_with_backslash.txt b/test/prism/fixtures/xstring_with_backslash.txt
new file mode 100644
index 0000000000..b51bb0f6f9
--- /dev/null
+++ b/test/prism/fixtures/xstring_with_backslash.txt
@@ -0,0 +1 @@
+`f\oo`
diff --git a/test/prism/fixtures/yield.txt b/test/prism/fixtures/yield.txt
new file mode 100644
index 0000000000..752ba27a2e
--- /dev/null
+++ b/test/prism/fixtures/yield.txt
@@ -0,0 +1,7 @@
+def foo; yield; end
+
+def foo; yield(); end
+
+def foo; yield(1); end
+
+def foo; yield(1, 2, 3); end
diff --git a/test/prism/format_errors_test.rb b/test/prism/format_errors_test.rb
new file mode 100644
index 0000000000..a1edbef2e8
--- /dev/null
+++ b/test/prism/format_errors_test.rb
@@ -0,0 +1,24 @@
+# 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/fuzzer_test.rb b/test/prism/fuzzer_test.rb
new file mode 100644
index 0000000000..511210e7ee
--- /dev/null
+++ b/test/prism/fuzzer_test.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+return if ENV["PRISM_BUILD_MINIMAL"]
+
+require_relative "test_helper"
+
+module Prism
+ # These tests are simply to exercise snippets found by the fuzzer that caused
+ # invalid memory access.
+ class FuzzerTest < TestCase
+ def self.snippet(name, source)
+ define_method(:"test_fuzzer_#{name}") { Prism.dump(source) }
+ end
+
+ snippet "incomplete global variable", "$"
+ snippet "incomplete symbol", ":"
+ snippet "incomplete escaped string", '"\\'
+ snippet "trailing comment", "1\n#\n"
+ snippet "comment followed by whitespace at end of file", "1\n#\n "
+ snippet "trailing asterisk", "a *"
+ snippet "incomplete decimal number", "0d"
+ snippet "incomplete binary number", "0b"
+ snippet "incomplete octal number", "0o"
+ snippet "incomplete hex number", "0x"
+ snippet "incomplete escaped list", "%w[\\"
+ snippet "incomplete escaped regex", "/a\\"
+ snippet "unterminated heredoc with unterminated escape at end of file", "<<A\n\\"
+ snippet "escaped octal at end of file 1", '"\\3'
+ snippet "escaped octal at end of file 2", '"\\33'
+ snippet "escaped hex at end of file 1", '"\\x'
+ snippet "escaped hex at end of file 2", '"\\x3'
+ snippet "escaped unicode at end of file 1", '"\\u{3'
+ snippet "escaped unicode at end of file 2", '"\\u{33'
+ snippet "escaped unicode at end of file 3", '"\\u{333'
+ snippet "escaped unicode at end of file 4", '"\\u{3333'
+ snippet "escaped unicode at end of file 5", '"\\u{33333'
+ snippet "escaped unicode at end of file 6", '"\\u{333333'
+ snippet "escaped unicode at end of file 7", '"\\u3'
+ snippet "escaped unicode at end of file 8", '"\\u33'
+ snippet "escaped unicode at end of file 9", '"\\u333'
+ snippet "float suffix at end of file", "1e"
+
+ snippet "statements node with multiple heredocs", <<~EOF
+ for <<A + <<B
+ A
+ B
+ EOF
+ snippet "create a binary call node with arg before receiver", <<~EOF
+ <<-A.g/{/
+ A
+ /, ""\\
+ EOF
+ snippet "regular expression with start and end out of order", <<~RUBY
+ <<-A.g//,
+ A
+ /{/, ''\\
+ RUBY
+ snippet "interpolated regular expression with start and end out of order", <<~RUBY
+ <<-A.g/{/,
+ A
+ a
+ /{/, ''\\
+ RUBY
+
+ snippet "parameter name that is zero length", "a { |b;"
+ end
+end
diff --git a/test/prism/heredoc_dedent_test.rb b/test/prism/heredoc_dedent_test.rb
new file mode 100644
index 0000000000..9fbc4d936a
--- /dev/null
+++ b/test/prism/heredoc_dedent_test.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class HeredocDedentTest < TestCase
+ filepath = File.expand_path("fixtures/tilde_heredocs.txt", __dir__)
+
+ File.read(filepath).split(/(?=\n)\n(?=<)/).each_with_index do |heredoc, index|
+ # The first example in this file has incorrect dedent calculated by
+ # TruffleRuby so we skip it.
+ next if index == 0 && RUBY_ENGINE == "truffleruby"
+
+ define_method "test_heredoc_#{index}" do
+ node = Prism.parse(heredoc).value.statements.body.first
+
+ if node.is_a?(StringNode)
+ actual = node.unescaped
+ else
+ actual = node.parts.map { |part| part.is_a?(StringNode) ? part.unescaped : "1" }.join
+ end
+
+ assert_equal(eval(heredoc), actual, "Expected heredocs to match.")
+ end
+ end
+ end
+end
diff --git a/test/prism/index_write_test.rb b/test/prism/index_write_test.rb
new file mode 100644
index 0000000000..1c6f7bce89
--- /dev/null
+++ b/test/prism/index_write_test.rb
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class IndexWriteTest < TestCase
+ def test_keywords_3_3_0
+ assert_parse_success(<<~RUBY, "3.3.0")
+ foo[bar: 1] = 1
+ foo[bar: 1] &&= 1
+ foo[bar: 1] ||= 1
+ foo[bar: 1] += 1
+ RUBY
+
+ assert_parse_success(<<~RUBY, "3.3.0")
+ def foo(**)
+ bar[**] = 1
+ bar[**] &&= 1
+ bar[**] ||= 1
+ bar[**] += 1
+ end
+ RUBY
+ end
+
+ def test_block_3_3_0
+ assert_parse_success(<<~RUBY, "3.3.0")
+ foo[&bar] = 1
+ foo[&bar] &&= 1
+ foo[&bar] ||= 1
+ foo[&bar] += 1
+ RUBY
+
+ assert_parse_success(<<~RUBY, "3.3.0")
+ def foo(&)
+ bar[&] = 1
+ bar[&] &&= 1
+ bar[&] ||= 1
+ bar[&] += 1
+ end
+ 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
+
+ # 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
+
+ # assert_parse_failure(<<~RUBY)
+ # def foo(&)
+ # bar[&] = 1
+ # bar[&] &&= 1
+ # bar[&] ||= 1
+ # bar[&] += 1
+ # end
+ # RUBY
+ # end
+
+ private
+
+ def assert_parse_success(source, version = "latest")
+ assert Prism.parse_success?(source, version: version)
+ end
+
+ def assert_parse_failure(source, version = "latest")
+ assert Prism.parse_failure?(source, version: version)
+ end
+ end
+end
diff --git a/test/prism/integer_parse_test.rb b/test/prism/integer_parse_test.rb
new file mode 100644
index 0000000000..f42e817e79
--- /dev/null
+++ b/test/prism/integer_parse_test.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+return if Prism::BACKEND == :FFI
+
+module Prism
+ class IntegerParseTest < TestCase
+ def test_integer_parse
+ assert_integer_parse(1)
+ assert_integer_parse(50)
+ assert_integer_parse(100)
+ assert_integer_parse(100, "1_0_0")
+ assert_integer_parse(8, "0_1_0")
+
+ assert_integer_parse(10, "0b1010")
+ assert_integer_parse(10, "0B1010")
+ assert_integer_parse(10, "0o12")
+ assert_integer_parse(10, "0O12")
+ assert_integer_parse(10, "012")
+ assert_integer_parse(10, "0d10")
+ assert_integer_parse(10, "0D10")
+ assert_integer_parse(10, "0xA")
+ assert_integer_parse(10, "0XA")
+
+ assert_integer_parse(2**32)
+ assert_integer_parse(2**64 + 2**32)
+ assert_integer_parse(2**128 + 2**64 + 2**32)
+
+ num = 99 ** 99
+ assert_integer_parse(num, "0b#{num.to_s(2)}")
+ assert_integer_parse(num, "0o#{num.to_s(8)}")
+ assert_integer_parse(num, "0d#{num.to_s(10)}")
+ assert_integer_parse(num, "0x#{num.to_s(16)}")
+ end
+
+ 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
+ end
+ end
+end
diff --git a/test/prism/library_symbols_test.rb b/test/prism/library_symbols_test.rb
new file mode 100644
index 0000000000..b10a367c18
--- /dev/null
+++ b/test/prism/library_symbols_test.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+return if RUBY_PLATFORM !~ /linux/
+
+# TODO: determine why these symbols are incorrect on ppc64le
+return if RUBY_PLATFORM =~ /powerpc64le/
+
+module Prism
+ #
+ # examine a prism dll or static archive for expected external symbols.
+ # these tests only work on a linux system right now.
+ #
+ class LibrarySymbolsTest < TestCase
+ def setup
+ super
+
+ @libprism_a = File.expand_path("../../build/libprism.a", __dir__)
+ @libprism_so = File.expand_path("../../build/libprism.so", __dir__)
+ @prism_so = File.expand_path("../../lib/prism/prism.so", __dir__)
+ end
+
+ # objdump runner and helpers
+ def objdump(path)
+ assert_path_exist(path)
+ %x(objdump --section=.text --syms #{path}).split("\n")
+ end
+
+ def global_objdump_symbols(path)
+ objdump(path).select { |line| line[17] == "g" }
+ end
+
+ def hidden_global_objdump_symbols(path)
+ global_objdump_symbols(path).select { |line| line =~ / \.hidden / }
+ end
+
+ def visible_global_objdump_symbols(path)
+ global_objdump_symbols(path).reject { |line| line =~ / \.hidden / }
+ end
+
+ # nm runner and helpers
+ def nm(path)
+ assert_path_exist(path)
+ %x(nm #{path}).split("\n")
+ end
+
+ def global_nm_symbols(path)
+ nm(path).select { |line| line[17] == "T" }
+ end
+
+ def local_nm_symbols(path)
+ nm(path).select { |line| line[17] == "t" }
+ end
+
+ # dig the symbol name out of each line. works for both `objdump` and `nm` output.
+ def names(symbol_lines)
+ symbol_lines.map { |line| line.split(/\s+/).last }
+ end
+
+ #
+ # static archive - libprism.a
+ #
+ def test_libprism_a_contains_nothing_globally_visible
+ omit("libprism.a is not built") unless File.exist?(@libprism_a)
+
+ assert_empty(names(visible_global_objdump_symbols(@libprism_a)))
+ end
+
+ def test_libprism_a_contains_hidden_pm_symbols
+ omit("libprism.a is not built") unless File.exist?(@libprism_a)
+
+ names(hidden_global_objdump_symbols(@libprism_a)).tap do |symbols|
+ assert_includes(symbols, "pm_parse")
+ assert_includes(symbols, "pm_version")
+ end
+ end
+
+ #
+ # shared object - libprism.so
+ #
+ def test_libprism_so_exports_only_the_necessary_functions
+ omit("libprism.so is not built") unless File.exist?(@libprism_so)
+
+ names(global_nm_symbols(@libprism_so)).tap do |symbols|
+ assert_includes(symbols, "pm_parse")
+ assert_includes(symbols, "pm_version")
+ end
+ names(local_nm_symbols(@libprism_so)).tap do |symbols|
+ assert_includes(symbols, "pm_encoding_utf_8_isupper_char")
+ end
+ # TODO: someone who uses this library needs to finish this test
+ end
+
+ #
+ # shared object - prism.so
+ #
+ def test_prism_so_exports_only_the_C_extension_init_function
+ omit("prism.so is not built") unless File.exist?(@prism_so)
+
+ names(global_nm_symbols(@prism_so)).tap do |symbols|
+ assert_equal(["Init_prism"], symbols)
+ end
+ end
+ end
+end
diff --git a/test/prism/locals_test.rb b/test/prism/locals_test.rb
new file mode 100644
index 0000000000..0eb73f1b9c
--- /dev/null
+++ b/test/prism/locals_test.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+# This test is going to use the RubyVM::InstructionSequence class to compile
+# local tables and compare against them to ensure we have the same locals in the
+# same order. This is important to guarantee that we compile indices correctly
+# on CRuby (in terms of compatibility).
+#
+# There have also been changes made in other versions of Ruby, so we only want
+# to test on the most recent versions.
+return if !defined?(RubyVM::InstructionSequence) || RUBY_VERSION < "3.4.0"
+
+# Omit tests if running on a 32-bit machine because there is a bug with how
+# Ruby is handling large ISeqs on 32-bit machines
+return if RUBY_PLATFORM =~ /i686/
+
+require_relative "test_helper"
+
+module Prism
+ class LocalsTest < TestCase
+ base = File.join(__dir__, "fixtures")
+ Dir["**/*.txt", base: base].each do |relative|
+ # Skip this fixture because it has a different number of locals because
+ # CRuby is eliminating dead code.
+ next if relative == "whitequark/ruby_bug_10653.txt"
+
+ filepath = File.join(base, relative)
+ define_method("test_#{relative}") { assert_locals(filepath) }
+ end
+
+ def setup
+ @previous_default_external = Encoding.default_external
+ ignore_warnings { Encoding.default_external = Encoding::UTF_8 }
+ end
+
+ def teardown
+ ignore_warnings { Encoding.default_external = @previous_default_external }
+ end
+
+ private
+
+ def assert_locals(filepath)
+ source = File.read(filepath)
+
+ expected = Debug.cruby_locals(source)
+ actual = Debug.prism_locals(source)
+
+ assert_equal(expected, actual)
+ end
+
+ def ignore_warnings
+ previous_verbosity = $VERBOSE
+ $VERBOSE = nil
+ yield
+ ensure
+ $VERBOSE = previous_verbosity
+ end
+ end
+end
diff --git a/test/prism/location_test.rb b/test/prism/location_test.rb
new file mode 100644
index 0000000000..81417fbcb3
--- /dev/null
+++ b/test/prism/location_test.rb
@@ -0,0 +1,947 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class LocationTest < TestCase
+ def test_AliasGlobalVariableNode
+ assert_location(AliasGlobalVariableNode, "alias $foo $bar")
+ end
+
+ def test_AliasMethodNode
+ assert_location(AliasMethodNode, "alias foo bar")
+ end
+
+ def test_AlternationPatternNode
+ assert_location(AlternationPatternNode, "foo => bar | baz", 7...16, &:pattern)
+ end
+
+ def test_AndNode
+ assert_location(AndNode, "foo and bar")
+ assert_location(AndNode, "foo && bar")
+ end
+
+ def test_ArgumentsNode
+ assert_location(ArgumentsNode, "foo(bar, baz, qux)", 4...17, &:arguments)
+ end
+
+ def test_ArrayNode
+ assert_location(ArrayNode, "[foo, bar, baz]")
+ assert_location(ArrayNode, "%i[foo bar baz]")
+ assert_location(ArrayNode, "%I[foo bar baz]")
+ assert_location(ArrayNode, "%w[foo bar baz]")
+ assert_location(ArrayNode, "%W[foo bar baz]")
+ end
+
+ def test_ArrayPatternNode
+ assert_location(ArrayPatternNode, "foo => bar, baz", 7...15, &:pattern)
+ assert_location(ArrayPatternNode, "foo => [bar, baz]", 7...17, &:pattern)
+ assert_location(ArrayPatternNode, "foo => *bar", 7...11, &:pattern)
+ assert_location(ArrayPatternNode, "foo => []", 7...9, &:pattern)
+ assert_location(ArrayPatternNode, "foo => Foo[]", 7...12, &:pattern)
+ assert_location(ArrayPatternNode, "foo => Foo[bar]", 7...15, &:pattern)
+ end
+
+ def test_AssocNode
+ assert_location(AssocNode, "{ '': 1 }", 2...7) { |node| node.elements.first }
+ assert_location(AssocNode, "{ foo: :bar }", 2...11) { |node| node.elements.first }
+ assert_location(AssocNode, "{ :foo => :bar }", 2...14) { |node| node.elements.first }
+ assert_location(AssocNode, "foo(bar: :baz)", 4...13) { |node| node.arguments.arguments.first.elements.first }
+ end
+
+ def test_AssocSplatNode
+ assert_location(AssocSplatNode, "{ **foo }", 2...7) { |node| node.elements.first }
+ assert_location(AssocSplatNode, "foo(**bar)", 4...9) { |node| node.arguments.arguments.first.elements.first }
+ end
+
+ def test_BackReferenceReadNode
+ assert_location(BackReferenceReadNode, "$+")
+ end
+
+ def test_BeginNode
+ assert_location(BeginNode, "begin foo end")
+ assert_location(BeginNode, "begin foo rescue bar end")
+ assert_location(BeginNode, "begin foo; rescue bar\nelse baz end")
+ assert_location(BeginNode, "begin foo; rescue bar\nelse baz\nensure qux end")
+
+ assert_location(BeginNode, "class Foo\nrescue then end", 0..25, &:body)
+ assert_location(BeginNode, "module Foo\nrescue then end", 0..26, &:body)
+ end
+
+ def test_BlockArgumentNode
+ assert_location(BlockArgumentNode, "foo(&bar)", 4...8, &:block)
+ end
+
+ def test_BlockLocalVariableNode
+ assert_location(BlockLocalVariableNode, "foo { |;bar| }", 8...11) do |node|
+ node.block.parameters.locals.first
+ end
+ end
+
+ def test_BlockNode
+ assert_location(BlockNode, "foo {}", 4...6, &:block)
+ assert_location(BlockNode, "foo do end", 4...10, &:block)
+ end
+
+ def test_BlockParameterNode
+ assert_location(BlockParameterNode, "def foo(&bar) end", 8...12) { |node| node.parameters.block }
+ end
+
+ def test_BlockParametersNode
+ assert_location(BlockParametersNode, "foo { || }", 6...8) { |node| node.block.parameters }
+ assert_location(BlockParametersNode, "foo { |bar| baz }", 6...11) { |node| node.block.parameters }
+ assert_location(BlockParametersNode, "foo { |bar; baz| baz }", 6...16) { |node| node.block.parameters }
+
+ assert_location(BlockParametersNode, "-> () {}", 3...5, &:parameters)
+ assert_location(BlockParametersNode, "-> (bar) { baz }", 3...8, &:parameters)
+ assert_location(BlockParametersNode, "-> (bar; baz) { baz }", 3...13, &:parameters)
+ end
+
+ def test_BreakNode
+ assert_location(BreakNode, "tap { break }", 6...11) { |node| node.block.body.body.first }
+ assert_location(BreakNode, "tap { break foo }", 6...15) { |node| node.block.body.body.first }
+ assert_location(BreakNode, "tap { break foo, bar }", 6...20) { |node| node.block.body.body.first }
+ assert_location(BreakNode, "tap { break(foo) }", 6...16) { |node| node.block.body.body.first }
+ end
+
+ def test_CallNode
+ assert_location(CallNode, "foo")
+ assert_location(CallNode, "foo?")
+ assert_location(CallNode, "foo!")
+
+ assert_location(CallNode, "foo()")
+ assert_location(CallNode, "foo?()")
+ assert_location(CallNode, "foo!()")
+
+ assert_location(CallNode, "foo(bar)")
+ assert_location(CallNode, "foo?(bar)")
+ assert_location(CallNode, "foo!(bar)")
+
+ assert_location(CallNode, "!foo")
+ assert_location(CallNode, "~foo")
+ assert_location(CallNode, "+foo")
+ assert_location(CallNode, "-foo")
+
+ assert_location(CallNode, "not foo")
+ assert_location(CallNode, "not(foo)")
+ assert_location(CallNode, "not()")
+
+ assert_location(CallNode, "foo + bar")
+ assert_location(CallNode, "foo -\n bar")
+
+ assert_location(CallNode, "Foo()")
+ assert_location(CallNode, "Foo(bar)")
+
+ assert_location(CallNode, "Foo::Bar()")
+ assert_location(CallNode, "Foo::Bar(baz)")
+
+ assert_location(CallNode, "Foo::bar")
+ assert_location(CallNode, "Foo::bar()")
+ assert_location(CallNode, "Foo::bar(baz)")
+
+ assert_location(CallNode, "Foo.bar")
+ assert_location(CallNode, "Foo.bar()")
+ assert_location(CallNode, "Foo.bar(baz)")
+
+ assert_location(CallNode, "foo::bar")
+ assert_location(CallNode, "foo::bar()")
+ assert_location(CallNode, "foo::bar(baz)")
+
+ assert_location(CallNode, "foo.bar")
+ assert_location(CallNode, "foo.bar()")
+ assert_location(CallNode, "foo.bar(baz)")
+
+ assert_location(CallNode, "foo&.bar")
+ assert_location(CallNode, "foo&.bar()")
+ assert_location(CallNode, "foo&.bar(baz)")
+
+ assert_location(CallNode, "foo[]")
+ assert_location(CallNode, "foo[bar]")
+ assert_location(CallNode, "foo[bar, baz]")
+
+ assert_location(CallNode, "foo[] = 1")
+ assert_location(CallNode, "foo[bar] = 1")
+ assert_location(CallNode, "foo[bar, baz] = 1")
+
+ assert_location(CallNode, "foo.()")
+ assert_location(CallNode, "foo.(bar)")
+
+ assert_location(CallNode, "foo&.()")
+ assert_location(CallNode, "foo&.(bar)")
+
+ assert_location(CallNode, "foo::()")
+ assert_location(CallNode, "foo::(bar)")
+ assert_location(CallNode, "foo::(bar, baz)")
+
+ 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
+ assert_location(CallAndWriteNode, "foo.foo &&= bar")
+ end
+
+ def test_CallOperatorWriteNode
+ assert_location(CallOperatorWriteNode, "foo.foo += bar")
+ end
+
+ def test_CallOrWriteNode
+ assert_location(CallOrWriteNode, "foo.foo ||= bar")
+ end
+
+ def test_CallTargetNode
+ assert_location(CallTargetNode, "foo.bar, = baz", 0...7) do |node|
+ node.lefts.first
+ end
+ end
+
+ def test_CapturePatternNode
+ assert_location(CapturePatternNode, "case foo; in bar => baz; end", 13...23) do |node|
+ node.conditions.first.pattern
+ end
+ end
+
+ def test_CaseNode
+ assert_location(CaseNode, "case foo; when bar; end")
+ assert_location(CaseNode, "case foo; when bar; else; end")
+ assert_location(CaseNode, "case foo; when bar; when baz; end")
+ assert_location(CaseNode, "case foo; when bar; when baz; else; end")
+ end
+
+ def test_CaseMatchNode
+ assert_location(CaseMatchNode, "case foo; in bar; end")
+ assert_location(CaseMatchNode, "case foo; in bar; else; end")
+ assert_location(CaseMatchNode, "case foo; in bar; in baz; end")
+ assert_location(CaseMatchNode, "case foo; in bar; in baz; else; end")
+ end
+
+ def test_ClassNode
+ assert_location(ClassNode, "class Foo end")
+ assert_location(ClassNode, "class Foo < Bar; end")
+ end
+
+ def test_ClassVariableAndWriteNode
+ assert_location(ClassVariableAndWriteNode, "@@foo &&= bar")
+ end
+
+ def test_ClassVariableOperatorWriteNode
+ assert_location(ClassVariableOperatorWriteNode, "@@foo += bar")
+ end
+
+ def test_ClassVariableOrWriteNode
+ assert_location(ClassVariableOrWriteNode, "@@foo ||= bar")
+ end
+
+ def test_ClassVariableReadNode
+ assert_location(ClassVariableReadNode, "@@foo")
+ end
+
+ def test_ClassVariableTargetNode
+ assert_location(ClassVariableTargetNode, "@@foo, @@bar = baz", 0...5) do |node|
+ node.lefts.first
+ end
+ end
+
+ def test_ClassVariableWriteNode
+ assert_location(ClassVariableWriteNode, "@@foo = bar")
+ end
+
+ def test_ConstantPathAndWriteNode
+ assert_location(ConstantPathAndWriteNode, "Parent::Child &&= bar")
+ end
+
+ def test_ConstantPathNode
+ assert_location(ConstantPathNode, "Foo::Bar")
+ assert_location(ConstantPathNode, "::Foo")
+ assert_location(ConstantPathNode, "::Foo::Bar")
+ end
+
+ def test_ConstantPathOperatorWriteNode
+ assert_location(ConstantPathOperatorWriteNode, "Parent::Child += bar")
+ end
+
+ def test_ConstantPathOrWriteNode
+ assert_location(ConstantPathOrWriteNode, "Parent::Child ||= bar")
+ end
+
+ def test_ConstantPathTargetNode
+ assert_location(ConstantPathTargetNode, "::Foo, ::Bar = baz", 0...5) do |node|
+ node.lefts.first
+ end
+ end
+
+ def test_ConstantPathWriteNode
+ assert_location(ConstantPathWriteNode, "Foo::Bar = baz")
+ assert_location(ConstantPathWriteNode, "::Foo = bar")
+ assert_location(ConstantPathWriteNode, "::Foo::Bar = baz")
+ end
+
+ def test_ConstantAndWriteNode
+ assert_location(ConstantAndWriteNode, "Foo &&= bar")
+ end
+
+ def test_ConstantOperatorWriteNode
+ assert_location(ConstantOperatorWriteNode, "Foo += bar")
+ end
+
+ def test_ConstantOrWriteNode
+ assert_location(ConstantOrWriteNode, "Foo ||= bar")
+ end
+
+ def test_ConstantReadNode
+ assert_location(ConstantReadNode, "Foo")
+ assert_location(ConstantReadNode, "Foo::Bar", 5...8, &:child)
+ end
+
+ def test_ConstantTargetNode
+ assert_location(ConstantTargetNode, "Foo, Bar = baz", 0...3) do |node|
+ node.lefts.first
+ end
+ end
+
+ def test_ConstantWriteNode
+ assert_location(ConstantWriteNode, "Foo = bar")
+ end
+
+ def test_DefNode
+ assert_location(DefNode, "def foo; bar; end")
+ assert_location(DefNode, "def foo = bar")
+ assert_location(DefNode, "def foo.bar; baz; end")
+ assert_location(DefNode, "def foo.bar = baz")
+ end
+
+ def test_DefinedNode
+ assert_location(DefinedNode, "defined? foo")
+ assert_location(DefinedNode, "defined?(foo)")
+ end
+
+ def test_ElseNode
+ assert_location(ElseNode, "if foo; bar; else; baz; end", 13...27, &:consequent)
+ assert_location(ElseNode, "foo ? bar : baz", 10...15, &:consequent)
+ end
+
+ def test_EmbeddedStatementsNode
+ assert_location(EmbeddedStatementsNode, '"foo #{bar} baz"', 5...11) { |node| node.parts[1] }
+ end
+
+ def test_EmbeddedVariableNode
+ assert_location(EmbeddedVariableNode, '"foo #@@bar baz"', 5...11) { |node| node.parts[1] }
+ end
+
+ def test_EnsureNode
+ assert_location(EnsureNode, "begin; foo; ensure; bar; end", 12...28, &:ensure_clause)
+ end
+
+ def test_FalseNode
+ assert_location(FalseNode, "false")
+ end
+
+ def test_FindPatternNode
+ assert_location(FindPatternNode, "case foo; in *, bar, *; end", 13...22) do |node|
+ node.conditions.first.pattern
+ end
+ end
+
+ def test_FlipFlopNode
+ assert_location(FlipFlopNode, "if foo..bar; end", 3..11, &:predicate)
+ end
+
+ def test_FloatNode
+ assert_location(FloatNode, "0.0")
+ assert_location(FloatNode, "1.0")
+ assert_location(FloatNode, "1.0e10")
+ assert_location(FloatNode, "1.0e-10")
+ end
+
+ def test_ForNode
+ assert_location(ForNode, "for foo in bar; end")
+ assert_location(ForNode, "for foo, bar in baz do end")
+ end
+
+ def test_ForwardingArgumentsNode
+ assert_location(ForwardingArgumentsNode, "def foo(...); bar(...); end", 18...21) do |node|
+ node.body.body.first.arguments.arguments.first
+ end
+ end
+
+ def test_ForwardingParameterNode
+ assert_location(ForwardingParameterNode, "def foo(...); end", 8...11) do |node|
+ node.parameters.keyword_rest
+ end
+ end
+
+ def test_ForwardingSuperNode
+ assert_location(ForwardingSuperNode, "super")
+ assert_location(ForwardingSuperNode, "super {}")
+ end
+
+ def test_GlobalVariableAndWriteNode
+ assert_location(GlobalVariableAndWriteNode, "$foo &&= bar")
+ end
+
+ def test_GlobalVariableOperatorWriteNode
+ assert_location(GlobalVariableOperatorWriteNode, "$foo += bar")
+ end
+
+ def test_GlobalVariableOrWriteNode
+ assert_location(GlobalVariableOrWriteNode, "$foo ||= bar")
+ end
+
+ def test_GlobalVariableReadNode
+ assert_location(GlobalVariableReadNode, "$foo")
+ end
+
+ def test_GlobalVariableTargetNode
+ assert_location(GlobalVariableTargetNode, "$foo, $bar = baz", 0...4) do |node|
+ node.lefts.first
+ end
+ end
+
+ def test_GlobalVariableWriteNode
+ assert_location(GlobalVariableWriteNode, "$foo = bar")
+ end
+
+ def test_HashNode
+ assert_location(HashNode, "{ foo: 2 }")
+ assert_location(HashNode, "{ \nfoo: 2, \nbar: 3 \n}")
+ end
+
+ def test_HashPatternNode
+ assert_location(HashPatternNode, "case foo; in bar: baz; end", 13...21) do |node|
+ node.conditions.first.pattern
+ end
+ end
+
+ def test_IfNode
+ assert_location(IfNode, "if type in 1;elsif type in B;end")
+ end
+
+ def test_ImaginaryNode
+ assert_location(ImaginaryNode, "1i")
+ assert_location(ImaginaryNode, "1ri")
+ end
+
+ def test_ImplicitNode
+ assert_location(ImplicitNode, "{ foo: }", 2...6) do |node|
+ node.elements.first.value
+ end
+
+ assert_location(ImplicitNode, "{ Foo: }", 2..6) do |node|
+ node.elements.first.value
+ end
+
+ assert_location(ImplicitNode, "foo = 1; { foo: }", 11..15) do |node|
+ node.elements.first.value
+ end
+ end
+
+ def test_ImplicitRestNode
+ assert_location(ImplicitRestNode, "foo, = bar", 3..4, &:rest)
+
+ assert_location(ImplicitRestNode, "for foo, in bar do end", 7..8) do |node|
+ node.index.rest
+ end
+
+ assert_location(ImplicitRestNode, "foo { |bar,| }", 10..11) do |node|
+ node.block.parameters.parameters.rest
+ end
+
+ assert_location(ImplicitRestNode, "foo in [bar,]", 11..12) do |node|
+ node.pattern.rest
+ end
+ end
+
+ def test_InNode
+ assert_location(InNode, "case foo; in bar; end", 10...16) do |node|
+ node.conditions.first
+ end
+ end
+
+ def test_IndexAndWriteNode
+ assert_location(IndexAndWriteNode, "foo[foo] &&= bar")
+ end
+
+ def test_IndexOperatorWriteNode
+ assert_location(IndexOperatorWriteNode, "foo[foo] += bar")
+ end
+
+ def test_IndexOrWriteNode
+ assert_location(IndexOrWriteNode, "foo[foo] ||= bar")
+ end
+
+ def test_IndexTargetNode
+ assert_location(IndexTargetNode, "foo[bar, &baz], = qux", 0...14) do |node|
+ node.lefts.first
+ end
+ end
+
+ def test_InstanceVariableAndWriteNode
+ assert_location(InstanceVariableAndWriteNode, "@foo &&= bar")
+ end
+
+ def test_InstanceVariableOperatorWriteNode
+ assert_location(InstanceVariableOperatorWriteNode, "@foo += bar")
+ end
+
+ def test_InstanceVariableOrWriteNode
+ assert_location(InstanceVariableOrWriteNode, "@foo ||= bar")
+ end
+
+ def test_InstanceVariableReadNode
+ assert_location(InstanceVariableReadNode, "@foo")
+ end
+
+ def test_InstanceVariableTargetNode
+ assert_location(InstanceVariableTargetNode, "@foo, @bar = baz", 0...4) do |node|
+ node.lefts.first
+ end
+ end
+
+ def test_InstanceVariableWriteNode
+ assert_location(InstanceVariableWriteNode, "@foo = bar")
+ end
+
+ def test_IntegerNode
+ assert_location(IntegerNode, "0")
+ assert_location(IntegerNode, "1")
+ assert_location(IntegerNode, "1_000")
+ assert_location(IntegerNode, "0x1")
+ assert_location(IntegerNode, "0x1_000")
+ assert_location(IntegerNode, "0b1")
+ assert_location(IntegerNode, "0b1_000")
+ assert_location(IntegerNode, "0o1")
+ assert_location(IntegerNode, "0o1_000")
+ end
+
+ def test_InterpolatedMatchLastLineNode
+ assert_location(InterpolatedMatchLastLineNode, "if /foo \#{bar}/ then end", 3...15, &:predicate)
+ end
+
+ def test_InterpolatedRegularExpressionNode
+ assert_location(InterpolatedRegularExpressionNode, "/\#{foo}/")
+ assert_location(InterpolatedRegularExpressionNode, "/\#{foo}/io")
+ end
+
+ def test_InterpolatedStringNode
+ assert_location(InterpolatedStringNode, "\"foo \#@bar baz\"")
+ assert_location(InterpolatedStringNode, "<<~A\nhello \#{1} world\nA", 0...4)
+ assert_location(InterpolatedStringNode, '"foo" "bar"')
+ end
+
+ def test_InterpolatedSymbolNode
+ assert_location(InterpolatedSymbolNode, ':"#{foo}bar"')
+ end
+
+ def test_InterpolatedXStringNode
+ assert_location(InterpolatedXStringNode, '`foo #{bar} baz`')
+ end
+
+ def test_ItParametersNode
+ assert_location(ItParametersNode, "-> { it }", &:parameters)
+ end
+
+ def test_KeywordHashNode
+ assert_location(KeywordHashNode, "foo(a, b: 1)", 7...11) { |node| node.arguments.arguments[1] }
+ end
+
+ def test_KeywordRestParameterNode
+ assert_location(KeywordRestParameterNode, "def foo(**); end", 8...10) do |node|
+ node.parameters.keyword_rest
+ end
+
+ assert_location(KeywordRestParameterNode, "def foo(**bar); end", 8...13) do |node|
+ node.parameters.keyword_rest
+ end
+ end
+
+ def test_LambdaNode
+ assert_location(LambdaNode, "-> { foo }")
+ assert_location(LambdaNode, "-> do foo end")
+ end
+
+ def test_LocalVariableAndWriteNode
+ assert_location(LocalVariableAndWriteNode, "foo &&= bar")
+ assert_location(LocalVariableAndWriteNode, "foo = 1; foo &&= bar", 9...20)
+ end
+
+ def test_LocalVariableOperatorWriteNode
+ assert_location(LocalVariableOperatorWriteNode, "foo += bar")
+ assert_location(LocalVariableOperatorWriteNode, "foo = 1; foo += bar", 9...19)
+ end
+
+ def test_LocalVariableOrWriteNode
+ assert_location(LocalVariableOrWriteNode, "foo ||= bar")
+ assert_location(LocalVariableOrWriteNode, "foo = 1; foo ||= bar", 9...20)
+ end
+
+ 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
+ assert_location(LocalVariableTargetNode, "foo, bar = baz", 0...3) do |node|
+ node.lefts.first
+ end
+ end
+
+ def test_LocalVariableWriteNode
+ assert_location(LocalVariableWriteNode, "foo = bar")
+ end
+
+ def test_MatchLastLineNode
+ assert_location(MatchLastLineNode, "if /foo/ then end", 3...8, &:predicate)
+ end
+
+ def test_MatchPredicateNode
+ assert_location(MatchPredicateNode, "foo in bar")
+ end
+
+ def test_MatchRequiredNode
+ assert_location(MatchRequiredNode, "foo => bar")
+ end
+
+ def test_MatchWriteNode
+ assert_location(MatchWriteNode, "/(?<foo>)/ =~ foo")
+ end
+
+ def test_ModuleNode
+ assert_location(ModuleNode, "module Foo end")
+ end
+
+ def test_MultiTargetNode
+ assert_location(MultiTargetNode, "for foo, bar in baz do end", 4...12, &:index)
+ assert_location(MultiTargetNode, "foo, (bar, baz) = qux", 5...15) { |node| node.lefts.last }
+ assert_location(MultiTargetNode, "def foo((bar)); end", 8...13) do |node|
+ node.parameters.requireds.first
+ end
+ end
+
+ def test_MultiWriteNode
+ assert_location(MultiWriteNode, "foo, bar = baz")
+ assert_location(MultiWriteNode, "(foo, bar) = baz")
+ assert_location(MultiWriteNode, "((foo, bar)) = baz")
+ end
+
+ def test_NextNode
+ assert_location(NextNode, "tap { next }", 6...10) { |node| node.block.body.body.first }
+ assert_location(NextNode, "tap { next foo }", 6...14) { |node| node.block.body.body.first }
+ assert_location(NextNode, "tap { next foo, bar }", 6...19) { |node| node.block.body.body.first }
+ assert_location(NextNode, "tap { next(foo) }", 6...15) { |node| node.block.body.body.first }
+ end
+
+ def test_NilNode
+ assert_location(NilNode, "nil")
+ end
+
+ def test_NoKeywordsParameterNode
+ assert_location(NoKeywordsParameterNode, "def foo(**nil); end", 8...13) { |node| node.parameters.keyword_rest }
+ end
+
+ def test_NumberedParametersNode
+ assert_location(NumberedParametersNode, "-> { _1 }", &:parameters)
+ assert_location(NumberedParametersNode, "foo { _1 }", 4...10) { |node| node.block.parameters }
+ end
+
+ def test_NumberedReferenceReadNode
+ assert_location(NumberedReferenceReadNode, "$1")
+ end
+
+ def test_OptionalKeywordParameterNode
+ assert_location(OptionalKeywordParameterNode, "def foo(bar: nil); end", 8...16) do |node|
+ node.parameters.keywords.first
+ end
+ end
+
+ def test_OptionalParameterNode
+ assert_location(OptionalParameterNode, "def foo(bar = nil); end", 8...17) do |node|
+ node.parameters.optionals.first
+ end
+ end
+
+ def test_OrNode
+ assert_location(OrNode, "foo || bar")
+ assert_location(OrNode, "foo or bar")
+ end
+
+ def test_ParametersNode
+ assert_location(ParametersNode, "def foo(bar, baz); end", 8...16, &:parameters)
+ end
+
+ def test_ParenthesesNode
+ assert_location(ParenthesesNode, "()")
+ assert_location(ParenthesesNode, "(foo)")
+ assert_location(ParenthesesNode, "foo (bar), baz", 4...9) { |node| node.arguments.arguments.first }
+ assert_location(ParenthesesNode, "def (foo).bar; end", 4...9, &:receiver)
+ end
+
+ def test_PinnedExpressionNode
+ assert_location(PinnedExpressionNode, "foo in ^(bar)", 7...13, &:pattern)
+ end
+
+ def test_PinnedVariableNode
+ assert_location(PinnedVariableNode, "bar = 1; foo in ^bar", 16...20, &:pattern)
+ assert_location(PinnedVariableNode, "proc { 1 in ^it }.call(1)", 12...15) do |node|
+ node.receiver.block.body.body.first.pattern
+ end
+ end
+
+ def test_PostExecutionNode
+ assert_location(PostExecutionNode, "END {}")
+ assert_location(PostExecutionNode, "END { foo }")
+ end
+
+ def test_PreExecutionNode
+ assert_location(PreExecutionNode, "BEGIN {}")
+ assert_location(PreExecutionNode, "BEGIN { foo }")
+ end
+
+ def test_RangeNode
+ assert_location(RangeNode, "1..2")
+ assert_location(RangeNode, "1...2")
+
+ assert_location(RangeNode, "..2")
+ assert_location(RangeNode, "...2")
+
+ assert_location(RangeNode, "1..")
+ assert_location(RangeNode, "1...")
+ end
+
+ def test_RationalNode
+ assert_location(RationalNode, "1r")
+ assert_location(RationalNode, "1.0r")
+ end
+
+ def test_RedoNode
+ assert_location(RedoNode, "tap { redo }", 6...10) { |node| node.block.body.body.first }
+ end
+
+ def test_RegularExpressionNode
+ assert_location(RegularExpressionNode, "/foo/")
+ assert_location(RegularExpressionNode, "/foo/io")
+ end
+
+ def test_RequiredKeywordParameterNode
+ assert_location(RequiredKeywordParameterNode, "def foo(bar:); end", 8...12) do |node|
+ node.parameters.keywords.first
+ end
+ end
+
+ def test_RequiredParameterNode
+ assert_location(RequiredParameterNode, "def foo(bar); end", 8...11) do |node|
+ node.parameters.requireds.first
+ end
+ end
+
+ def test_RescueNode
+ code = <<~RUBY
+ begin
+ body
+ rescue TypeError
+ rescue ArgumentError
+ end
+ RUBY
+ assert_location(RescueNode, code, 13...50) { |node| node.rescue_clause }
+ assert_location(RescueNode, code, 30...50) { |node| node.rescue_clause.consequent }
+ end
+
+ def test_RescueModifierNode
+ assert_location(RescueModifierNode, "foo rescue bar")
+ end
+
+ def test_RestParameterNode
+ assert_location(RestParameterNode, "def foo(*bar); end", 8...12) do |node|
+ node.parameters.rest
+ end
+ end
+
+ def test_RetryNode
+ assert_location(RetryNode, "begin; rescue; retry; end", 15...20) { |node| node.rescue_clause.statements.body.first }
+ end
+
+ def test_ReturnNode
+ assert_location(ReturnNode, "return")
+ assert_location(ReturnNode, "return foo")
+ assert_location(ReturnNode, "return foo, bar")
+ assert_location(ReturnNode, "return(foo)")
+ end
+
+ def test_SelfNode
+ assert_location(SelfNode, "self")
+ end
+
+ def test_ShareableConstantNode
+ source = <<~RUBY
+ # shareable_constant_value: literal
+ C = { foo: 1 }
+ RUBY
+
+ assert_location(ShareableConstantNode, source, 36...50)
+ end
+
+ def test_SingletonClassNode
+ assert_location(SingletonClassNode, "class << self; end")
+ end
+
+ def test_SourceEncodingNode
+ assert_location(SourceEncodingNode, "__ENCODING__")
+ end
+
+ def test_SourceFileNode
+ assert_location(SourceFileNode, "__FILE__")
+ end
+
+ def test_SourceLineNode
+ assert_location(SourceLineNode, "__LINE__")
+ end
+
+ def test_SplatNode
+ assert_location(SplatNode, "*foo = bar", 0...4, &:rest)
+ end
+
+ def test_StatementsNode
+ assert_location(StatementsNode, "foo { 1 }", 6...7) { |node| node.block.body }
+
+ assert_location(StatementsNode, "(1)", 1...2, &:body)
+
+ assert_location(StatementsNode, "def foo; 1; end", 9...10, &:body)
+ assert_location(StatementsNode, "def foo = 1", 10...11, &:body)
+ assert_location(StatementsNode, "def foo; 1\n2; end", 9...12, &:body)
+
+ assert_location(StatementsNode, "if foo; bar; end", 8...11, &:statements)
+ assert_location(StatementsNode, "foo if bar", 0...3, &:statements)
+
+ assert_location(StatementsNode, "if foo; foo; elsif bar; bar; end", 24...27) { |node| node.consequent.statements }
+ assert_location(StatementsNode, "if foo; foo; else; bar; end", 19...22) { |node| node.consequent.statements }
+
+ assert_location(StatementsNode, "unless foo; bar; end", 12...15, &:statements)
+ assert_location(StatementsNode, "foo unless bar", 0...3, &:statements)
+
+ assert_location(StatementsNode, "case; when foo; bar; end", 16...19) { |node| node.conditions.first.statements }
+
+ assert_location(StatementsNode, "while foo; bar; end", 11...14, &:statements)
+ assert_location(StatementsNode, "foo while bar", 0...3, &:statements)
+
+ assert_location(StatementsNode, "until foo; bar; end", 11...14, &:statements)
+ assert_location(StatementsNode, "foo until bar", 0...3, &:statements)
+
+ assert_location(StatementsNode, "for foo in bar; baz; end", 16...19, &:statements)
+
+ assert_location(StatementsNode, "begin; foo; end", 7...10, &:statements)
+ assert_location(StatementsNode, "begin; rescue; foo; end", 15...18) { |node| node.rescue_clause.statements }
+ assert_location(StatementsNode, "begin; ensure; foo; end", 15...18) { |node| node.ensure_clause.statements }
+ assert_location(StatementsNode, "begin; rescue; else; foo; end", 21...24) { |node| node.else_clause.statements }
+
+ assert_location(StatementsNode, "class Foo; foo; end", 11...14, &:body)
+ assert_location(StatementsNode, "module Foo; foo; end", 12...15, &:body)
+ assert_location(StatementsNode, "class << self; foo; end", 15...18, &:body)
+
+ assert_location(StatementsNode, "-> { foo }", 5...8, &:body)
+ assert_location(StatementsNode, "BEGIN { foo }", 8...11, &:statements)
+ assert_location(StatementsNode, "END { foo }", 6...9, &:statements)
+
+ assert_location(StatementsNode, "\"\#{foo}\"", 3...6) { |node| node.parts.first.statements }
+ end
+
+ def test_StringNode
+ assert_location(StringNode, '"foo"')
+ assert_location(StringNode, '%q[foo]')
+ end
+
+ def test_SuperNode
+ assert_location(SuperNode, "super foo")
+ assert_location(SuperNode, "super foo, bar")
+
+ assert_location(SuperNode, "super()")
+ assert_location(SuperNode, "super(foo)")
+ assert_location(SuperNode, "super(foo, bar)")
+
+ assert_location(SuperNode, "super() {}")
+ end
+
+ def test_SymbolNode
+ assert_location(SymbolNode, ":foo")
+ end
+
+ def test_TrueNode
+ assert_location(TrueNode, "true")
+ end
+
+ def test_UndefNode
+ assert_location(UndefNode, "undef foo")
+ assert_location(UndefNode, "undef foo, bar")
+ end
+
+ def test_UnlessNode
+ assert_location(UnlessNode, "foo unless bar")
+ assert_location(UnlessNode, "unless bar; foo; end")
+ end
+
+ def test_UntilNode
+ assert_location(UntilNode, "foo = bar until baz")
+ assert_location(UntilNode, "until bar;baz;end")
+ end
+
+ def test_WhenNode
+ assert_location(WhenNode, "case foo; when bar; end", 10...18) { |node| node.conditions.first }
+ end
+
+ def test_WhileNode
+ assert_location(WhileNode, "foo = bar while foo != baz")
+ assert_location(WhileNode, "while a;bar;baz;end")
+ end
+
+ def test_XStringNode
+ assert_location(XStringNode, "`foo`")
+ assert_location(XStringNode, "%x[foo]")
+ end
+
+ def test_YieldNode
+ assert_location(YieldNode, "def test; yield; end", 10...15) { |node| node.body.body.first }
+ assert_location(YieldNode, "def test; yield foo; end", 10...19) { |node| node.body.body.first }
+ assert_location(YieldNode, "def test; yield foo, bar; end", 10...24) { |node| node.body.body.first }
+ assert_location(YieldNode, "def test; yield(foo); end", 10...20) { |node| node.body.body.first }
+ end
+
+ def test_all_tested
+ expected = Prism.constants.grep(/.Node$/).sort - %i[MissingNode ProgramNode]
+ actual = LocationTest.instance_methods(false).grep(/.Node$/).map { |name| name[5..].to_sym }.sort
+ assert_equal expected, actual
+ end
+
+ private
+
+ def assert_location(kind, source, expected = 0...source.length, **options)
+ result = Prism.parse(source, **options)
+ assert result.success?
+
+ node = result.value.statements.body.last
+ node = yield node if block_given?
+
+ if expected.begin == 0
+ assert_equal 0, node.location.start_column
+ end
+
+ if expected.end == source.length
+ assert_equal source.split("\n").last.length, node.location.end_column
+ end
+
+ assert_kind_of kind, node
+ assert_equal expected.begin, node.location.start_offset
+ assert_equal expected.end, node.location.end_offset
+ end
+ end
+end
diff --git a/test/prism/magic_comment_test.rb b/test/prism/magic_comment_test.rb
new file mode 100644
index 0000000000..9e2e92af92
--- /dev/null
+++ b/test/prism/magic_comment_test.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+return if RUBY_ENGINE != "ruby"
+
+module Prism
+ class MagicCommentTest < TestCase
+ examples = [
+ "# encoding: ascii",
+ "# coding: ascii",
+ "# eNcOdInG: ascii",
+ "# CoDiNg: ascii",
+ "# \s\t\v encoding \s\t\v : \s\t\v ascii \s\t\v",
+ "# -*- encoding: ascii -*-",
+ "# -*- coding: ascii -*-",
+ "# -*- eNcOdInG: ascii -*-",
+ "# -*- CoDiNg: ascii -*-",
+ "# -*- \s\t\v encoding \s\t\v : \s\t\v ascii \s\t\v -*-",
+ "# -*- foo: bar; encoding: ascii -*-",
+ "# coding \t \r \v : \t \v \r ascii-8bit",
+ "# vim: filetype=ruby, fileencoding=windows-31j, tabsize=3, shiftwidth=3"
+ ]
+
+ examples.each.with_index(1) do |example, index|
+ define_method(:"test_magic_comment_#{index}") do
+ expected = RubyVM::InstructionSequence.compile(%Q{#{example}\n""}).eval.encoding
+ actual = Prism.parse(example).encoding
+ assert_equal expected, actual
+ end
+ end
+ end
+end
diff --git a/test/prism/memsize_test.rb b/test/prism/memsize_test.rb
new file mode 100644
index 0000000000..d7e1448dbc
--- /dev/null
+++ b/test/prism/memsize_test.rb
@@ -0,0 +1,17 @@
+# 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
new file mode 100644
index 0000000000..e9975b346e
--- /dev/null
+++ b/test/prism/newline_test.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+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.each do |relative|
+ define_method("test_newline_flags_#{relative}") do
+ assert_newlines(base, relative)
+ end
+ end
+
+ private
+
+ def assert_newlines(base, relative)
+ filepath = File.join(base, relative)
+ source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
+ expected = rubyvm_lines(source)
+
+ result = Prism.parse_file(filepath)
+ assert_empty result.errors
+ actual = prism_lines(result)
+
+ source.each_line.with_index(1) do |line, line_number|
+ # Lines like `while (foo = bar)` result in two line flags in the
+ # bytecode but only one newline flag in the AST. We need to remove the
+ # extra line flag from the bytecode to make the test pass.
+ if line.match?(/while \(/)
+ index = expected.index(line_number)
+ expected.delete_at(index) if index
+ end
+
+ # Lines like `foo =` where the value is on the next line result in
+ # another line flag in the bytecode but only one newline flag in the
+ # AST.
+ if line.match?(/^\s+\w+ =$/)
+ if source.lines[line_number].match?(/^\s+case/)
+ actual[actual.index(line_number)] += 1
+ else
+ actual.delete_at(actual.index(line_number))
+ end
+ end
+
+ if line.match?(/^\s+\w+ = \[$/)
+ if !expected.include?(line_number) && !expected.include?(line_number + 2)
+ actual[actual.index(line_number)] += 1
+ end
+ end
+ end
+
+ assert_equal expected, actual
+ end
+
+ def ignore_warnings
+ previous_verbosity = $VERBOSE
+ $VERBOSE = nil
+ yield
+ ensure
+ $VERBOSE = previous_verbosity
+ end
+
+ def rubyvm_lines(source)
+ queue = [ignore_warnings { RubyVM::InstructionSequence.compile(source) }]
+ lines = []
+
+ while iseq = queue.shift
+ lines.concat(iseq.trace_points.filter_map { |line, event| line if event == :line })
+ iseq.each_child { |insn| queue << insn unless insn.label.start_with?("ensure in ") }
+ end
+
+ lines.sort
+ end
+
+ def prism_lines(result)
+ result.mark_newlines!
+
+ queue = [result.value]
+ newlines = []
+
+ while node = queue.shift
+ queue.concat(node.compact_child_nodes)
+ newlines << result.source.line(node.location.start_offset) if node&.newline?
+ end
+
+ newlines.sort
+ end
+ end
+end
diff --git a/test/prism/parameters_signature_test.rb b/test/prism/parameters_signature_test.rb
new file mode 100644
index 0000000000..0eed8d993d
--- /dev/null
+++ b/test/prism/parameters_signature_test.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+return if RUBY_VERSION < "3.2"
+
+module Prism
+ class ParametersSignatureTest < TestCase
+ def test_req
+ assert_parameters([[:req, :a]], "a")
+ end
+
+ def test_req_destructure
+ assert_parameters([[:req]], "(a, b)")
+ end
+
+ def test_opt
+ assert_parameters([[:opt, :a]], "a = 1")
+ end
+
+ def test_rest
+ assert_parameters([[:rest, :a]], "*a")
+ end
+
+ def test_rest_anonymous
+ assert_parameters([[:rest, :*]], "*")
+ end
+
+ def test_post
+ assert_parameters([[:rest, :a], [:req, :b]], "*a, b")
+ end
+
+ def test_post_destructure
+ assert_parameters([[:rest, :a], [:req]], "*a, (b, c)")
+ end
+
+ def test_keyreq
+ assert_parameters([[:keyreq, :a]], "a:")
+ end
+
+ def test_key
+ assert_parameters([[:key, :a]], "a: 1")
+ end
+
+ def test_keyrest
+ assert_parameters([[:keyrest, :a]], "**a")
+ end
+
+ def test_nokey
+ assert_parameters([[:nokey]], "**nil")
+ end
+
+ def test_keyrest_anonymous
+ assert_parameters([[:keyrest, :**]], "**")
+ end
+
+ def test_key_ordering
+ omit("TruffleRuby returns keys in order they were declared") if RUBY_ENGINE == "truffleruby"
+
+ assert_parameters([[:keyreq, :a], [:keyreq, :b], [:key, :c], [:key, :d]], "a:, c: 1, b:, d: 2")
+ end
+
+ def test_block
+ assert_parameters([[:block, :a]], "&a")
+ end
+
+ def test_block_anonymous
+ assert_parameters([[:block, :&]], "&")
+ end
+
+ def test_forwarding
+ assert_parameters([[:rest, :*], [:keyrest, :**], [:block, :&]], "...")
+ end
+
+ private
+
+ def assert_parameters(expected, source)
+ eval("def self.m(#{source}); end")
+
+ begin
+ assert_equal(expected, method(:m).parameters)
+ assert_equal(expected, signature(source))
+ ensure
+ singleton_class.undef_method(:m)
+ end
+ end
+
+ def signature(source)
+ program = Prism.parse("def m(#{source}); end").value
+ program.statements.body.first.parameters.signature
+ end
+ end
+end
diff --git a/test/prism/parse_comments_test.rb b/test/prism/parse_comments_test.rb
new file mode 100644
index 0000000000..30086e3155
--- /dev/null
+++ b/test/prism/parse_comments_test.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class ParseCommentsTest < TestCase
+ def test_parse_comments
+ comments = Prism.parse_comments("# foo")
+
+ assert_kind_of Array, comments
+ assert_equal 1, comments.length
+ end
+
+ def test_parse_file_comments
+ comments = Prism.parse_file_comments(__FILE__)
+
+ assert_kind_of Array, comments
+ assert_equal 1, comments.length
+ end
+ end
+end
diff --git a/test/prism/parse_stream_test.rb b/test/prism/parse_stream_test.rb
new file mode 100644
index 0000000000..9e6347b92b
--- /dev/null
+++ b/test/prism/parse_stream_test.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+require "stringio"
+
+module Prism
+ class ParseStreamTest < TestCase
+ def test_single_line
+ io = StringIO.new("1 + 2")
+ result = Prism.parse_stream(io)
+
+ assert result.success?
+ assert_kind_of Prism::CallNode, result.value.statements.body.first
+ end
+
+ def test_multi_line
+ io = StringIO.new("1 + 2\n3 + 4")
+ result = Prism.parse_stream(io)
+
+ assert result.success?
+ assert_kind_of Prism::CallNode, result.value.statements.body.first
+ assert_kind_of Prism::CallNode, result.value.statements.body.last
+ end
+
+ def test_multi_read
+ io = StringIO.new("a" * 4096 * 4)
+ result = Prism.parse_stream(io)
+
+ assert result.success?
+ assert_kind_of Prism::CallNode, result.value.statements.body.first
+ end
+
+ def test___END__
+ io = StringIO.new("1 + 2\n3 + 4\n__END__\n5 + 6")
+ result = Prism.parse_stream(io)
+
+ assert result.success?
+ assert_equal 2, result.value.statements.body.length
+ assert_equal "5 + 6", io.read
+ end
+
+ def test_false___END___in_string
+ io = StringIO.new("1 + 2\n3 + 4\n\"\n__END__\n\"\n5 + 6")
+ result = Prism.parse_stream(io)
+
+ assert result.success?
+ assert_equal 4, result.value.statements.body.length
+ end
+
+ def test_false___END___in_regexp
+ io = StringIO.new("1 + 2\n3 + 4\n/\n__END__\n/\n5 + 6")
+ result = Prism.parse_stream(io)
+
+ assert result.success?
+ assert_equal 4, result.value.statements.body.length
+ end
+
+ def test_false___END___in_list
+ io = StringIO.new("1 + 2\n3 + 4\n%w[\n__END__\n]\n5 + 6")
+ result = Prism.parse_stream(io)
+
+ assert result.success?
+ assert_equal 4, result.value.statements.body.length
+ end
+
+ def test_false___END___in_heredoc
+ io = StringIO.new("1 + 2\n3 + 4\n<<-EOF\n__END__\nEOF\n5 + 6")
+ result = Prism.parse_stream(io)
+
+ assert result.success?
+ assert_equal 4, result.value.statements.body.length
+ end
+ end
+end
diff --git a/test/prism/parse_test.rb b/test/prism/parse_test.rb
new file mode 100644
index 0000000000..afb53e0668
--- /dev/null
+++ b/test/prism/parse_test.rb
@@ -0,0 +1,371 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class ParseTest < TestCase
+ # A subclass of Ripper that extracts out magic comments.
+ class MagicCommentRipper < Ripper
+ attr_reader :magic_comments
+
+ def initialize(*)
+ super
+ @magic_comments = []
+ end
+
+ def on_magic_comment(key, value)
+ @magic_comments << [key, value]
+ super
+ end
+ end
+
+ # When we pretty-print the trees to compare against the snapshots, we want to
+ # be certain that we print with the same external encoding. This is because
+ # methods like Symbol#inspect take into account external encoding and it could
+ # change how the snapshot is generated. On machines with certain settings
+ # (like LANG=C or -Eascii-8bit) this could have been changed. So here we're
+ # going to force it to be UTF-8 to keep the snapshots consistent.
+ def setup
+ @previous_default_external = Encoding.default_external
+ ignore_warnings { Encoding.default_external = Encoding::UTF_8 }
+ end
+
+ def teardown
+ ignore_warnings { Encoding.default_external = @previous_default_external }
+ end
+
+ def test_empty_string
+ result = Prism.parse("")
+ assert_equal [], result.value.statements.body
+ end
+
+ def test_parse_takes_file_path
+ filepath = "filepath.rb"
+ result = Prism.parse("def foo; __FILE__; end", filepath: filepath)
+
+ assert_equal filepath, find_source_file_node(result.value).filepath
+ end
+
+ def test_parse_takes_line
+ line = 4
+ result = Prism.parse("def foo\n __FILE__\nend", line: line)
+
+ assert_equal line, result.value.location.start_line
+ assert_equal line + 1, find_source_file_node(result.value).location.start_line
+
+ result = Prism.parse_lex("def foo\n __FILE__\nend", line: line)
+ assert_equal line, result.value.first.location.start_line
+ end
+
+ def test_parse_takes_negative_lines
+ line = -2
+ result = Prism.parse("def foo\n __FILE__\nend", line: line)
+
+ assert_equal line, result.value.location.start_line
+ assert_equal line + 1, find_source_file_node(result.value).location.start_line
+
+ result = Prism.parse_lex("def foo\n __FILE__\nend", line: line)
+ assert_equal line, result.value.first.location.start_line
+ end
+
+ def test_parse_lex
+ node, tokens = Prism.parse_lex("def foo; end").value
+
+ assert_kind_of ProgramNode, node
+ assert_equal 5, tokens.length
+ end
+
+ if !ENV["PRISM_BUILD_MINIMAL"]
+ def test_dump_file
+ assert_nothing_raised do
+ Prism.dump_file(__FILE__)
+ end
+
+ error = assert_raise Errno::ENOENT do
+ Prism.dump_file("idontexist.rb")
+ end
+
+ assert_equal "No such file or directory - idontexist.rb", error.message
+
+ assert_raise TypeError do
+ Prism.dump_file(nil)
+ end
+ end
+ end
+
+ def test_lex_file
+ assert_nothing_raised do
+ Prism.lex_file(__FILE__)
+ end
+
+ error = assert_raise Errno::ENOENT do
+ Prism.lex_file("idontexist.rb")
+ end
+
+ assert_equal "No such file or directory - idontexist.rb", error.message
+
+ assert_raise TypeError do
+ Prism.lex_file(nil)
+ end
+ end
+
+ def test_parse_lex_file
+ node, tokens = Prism.parse_lex_file(__FILE__).value
+
+ assert_kind_of ProgramNode, node
+ refute_empty tokens
+
+ error = assert_raise Errno::ENOENT do
+ Prism.parse_lex_file("idontexist.rb")
+ end
+
+ assert_equal "No such file or directory - idontexist.rb", error.message
+
+ assert_raise TypeError do
+ Prism.parse_lex_file(nil)
+ end
+ end
+
+ def test_parse_file
+ node = Prism.parse_file(__FILE__).value
+ assert_kind_of ProgramNode, node
+
+ error = assert_raise Errno::ENOENT do
+ Prism.parse_file("idontexist.rb")
+ end
+
+ assert_equal "No such file or directory - idontexist.rb", error.message
+
+ assert_raise TypeError do
+ Prism.parse_file(nil)
+ end
+ end
+
+ def test_parse_file_success
+ assert_predicate Prism.parse_file_comments(__FILE__), :any?
+
+ error = assert_raise Errno::ENOENT do
+ Prism.parse_file_comments("idontexist.rb")
+ end
+
+ assert_equal "No such file or directory - idontexist.rb", error.message
+
+ assert_raise TypeError do
+ Prism.parse_file_comments(nil)
+ end
+ end
+
+ def test_parse_file_comments
+ assert_predicate Prism.parse_file_comments(__FILE__), :any?
+
+ error = assert_raise Errno::ENOENT do
+ Prism.parse_file_comments("idontexist.rb")
+ end
+
+ assert_equal "No such file or directory - idontexist.rb", error.message
+
+ assert_raise TypeError do
+ Prism.parse_file_comments(nil)
+ end
+ end
+
+ # To accurately compare against Ripper, we need to make sure that we're
+ # running on CRuby 3.2+.
+ ripper_enabled = RUBY_ENGINE == "ruby" && RUBY_VERSION >= "3.2.0"
+
+ # The FOCUS environment variable allows you to specify one particular fixture
+ # to test, instead of all of them.
+ base = File.join(__dir__, "fixtures")
+ relatives = ENV["FOCUS"] ? [ENV["FOCUS"]] : Dir["**/*.txt", base: base]
+
+ relatives.each do |relative|
+ # These fail on TruffleRuby due to a difference in Symbol#inspect: :测试 vs :"测试"
+ next if RUBY_ENGINE == "truffleruby" and %w[emoji_method_calls.txt seattlerb/bug202.txt seattlerb/magic_encoding_comment.txt].include?(relative)
+
+ filepath = File.join(base, relative)
+ snapshot = File.expand_path(File.join("snapshots", relative), __dir__)
+
+ directory = File.dirname(snapshot)
+ FileUtils.mkdir_p(directory) unless File.directory?(directory)
+
+ ripper_should_match = ripper_enabled
+ check_valid_syntax = RUBY_VERSION >= "3.2.0"
+
+ case relative
+ when "seattlerb/pct_w_heredoc_interp_nested.txt"
+ # This file has changed behavior in Ripper in Ruby 3.3, so we skip it if
+ # we're on an earlier version.
+ ripper_should_match = false if RUBY_VERSION < "3.3.0"
+ when "seattlerb/heredoc_nested.txt", "whitequark/dedenting_heredoc.txt"
+ # It seems like there are some oddities with nested heredocs and ripper.
+ # Waiting for feedback on https://bugs.ruby-lang.org/issues/19838.
+ ripper_should_match = false
+ when "spanning_heredoc.txt", "spanning_heredoc_newlines.txt"
+ # Ripper seems to have a bug that the regex portions before and after
+ # the heredoc are combined into a single token. See
+ # https://bugs.ruby-lang.org/issues/19838.
+ ripper_should_match = false
+ when "heredocs_leading_whitespace.txt"
+ # Ruby < 3.3.0 cannot parse heredocs where there are leading whitespace
+ # characters in the heredoc start.
+ # Example: <<~' EOF' or <<-' EOF'
+ # https://bugs.ruby-lang.org/issues/19539
+ if RUBY_VERSION < "3.3.0"
+ ripper_should_match = false
+ check_valid_syntax = false
+ end
+ end
+
+ define_method "test_filepath_#{relative}" do
+ # First, read the source from the filepath. Use binmode to avoid
+ # converting CRLF on Windows, and explicitly set the external encoding
+ # to UTF-8 to override the binmode default.
+ source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
+
+ # Make sure that the given source is valid syntax, otherwise we have an
+ # invalid fixture.
+ assert_valid_syntax(source) if check_valid_syntax
+
+ # Next, assert that there were no errors during parsing.
+ result = Prism.parse(source, filepath: relative)
+ assert_empty result.errors
+
+ # Next, pretty print the source.
+ printed = PP.pp(result.value, +"", 79)
+
+ if File.exist?(snapshot)
+ saved = File.read(snapshot)
+
+ # If the snapshot file exists, but the printed value does not match the
+ # snapshot, then update the snapshot file.
+ if printed != saved
+ File.write(snapshot, printed)
+ warn("Updated snapshot at #{snapshot}.")
+ end
+
+ # If the snapshot file exists, then assert that the printed value
+ # matches the snapshot.
+ assert_equal(saved, printed)
+ else
+ # If the snapshot file does not yet exist, then write it out now.
+ File.write(snapshot, printed)
+ warn("Created snapshot at #{snapshot}.")
+ end
+
+ if !ENV["PRISM_BUILD_MINIMAL"]
+ # Next, assert that the value can be serialized and deserialized
+ # without changing the shape of the tree.
+ assert_equal_nodes(result.value, Prism.load(source, Prism.dump(source, filepath: relative)).value)
+ end
+
+ # Next, check that the location ranges of each node in the tree are a
+ # superset of their respective child nodes.
+ assert_non_overlapping_locations(result.value)
+
+ # 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)
+
+ if ripper_should_match
+ # Finally, assert that we can lex the source and get the same tokens as
+ # Ripper.
+ lex_result = Prism.lex_compat(source)
+ assert_equal [], lex_result.errors
+ tokens = lex_result.value
+
+ begin
+ Prism.lex_ripper(source).zip(tokens).each do |(ripper, prism)|
+ assert_equal ripper, prism
+ end
+ rescue SyntaxError
+ raise ArgumentError, "Test file has invalid syntax #{filepath}"
+ end
+
+ # Next, check that we get the correct number of magic comments when
+ # lexing with ripper.
+ expected = MagicCommentRipper.new(source).tap(&:parse).magic_comments
+ actual = result.magic_comments
+
+ assert_equal expected.length, actual.length
+ expected.zip(actual).each do |(expected_key, expected_value), magic_comment|
+ assert_equal expected_key, magic_comment.key
+ assert_equal expected_value, magic_comment.value
+ end
+ end
+ end
+ end
+
+ Dir["*.txt", base: base].each do |relative|
+ next if relative == "newline_terminated.txt" || relative == "spanning_heredoc_newlines.txt"
+
+ # We test every snippet (separated by \n\n) in isolation
+ # to ensure the parser does not try to read bytes further than the end of each snippet
+ define_method "test_individual_snippets_#{relative}" do
+ filepath = File.join(base, relative)
+
+ # First, read the source from the filepath. Use binmode to avoid converting CRLF on Windows,
+ # and explicitly set the external encoding to UTF-8 to override the binmode default.
+ file_contents = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
+
+ file_contents.split(/(?<=\S)\n\n(?=\S)/).each do |snippet|
+ snippet = snippet.rstrip
+ result = Prism.parse(snippet, filepath: relative)
+ assert_empty result.errors
+
+ if !ENV["PRISM_BUILD_MINIMAL"]
+ assert_equal_nodes(result.value, Prism.load(snippet, Prism.dump(snippet, filepath: relative)).value)
+ end
+ end
+ end
+ end
+
+ private
+
+ # Check that the location ranges of each node in the tree are a superset of
+ # their respective child nodes.
+ def assert_non_overlapping_locations(node)
+ queue = [node]
+
+ while (current = queue.shift)
+ # We only want to compare parent/child location overlap in the case that
+ # we are not looking at a heredoc. That's because heredoc locations are
+ # special in that they only use the declaration of the heredoc.
+ compare = !(current.is_a?(StringNode) ||
+ current.is_a?(XStringNode) ||
+ current.is_a?(InterpolatedStringNode) ||
+ current.is_a?(InterpolatedXStringNode)) ||
+ !current.opening&.start_with?("<<")
+
+ current.child_nodes.each do |child|
+ # child_nodes can return nil values, so we need to skip those.
+ next unless child
+
+ # Now that we know we have a child node, add that to the queue.
+ queue << child
+
+ if compare
+ assert_operator current.location.start_offset, :<=, child.location.start_offset
+ assert_operator current.location.end_offset, :>=, child.location.end_offset
+ end
+ end
+ end
+ end
+
+ def find_source_file_node(program)
+ queue = [program]
+ while (node = queue.shift)
+ return node if node.is_a?(SourceFileNode)
+ queue.concat(node.compact_child_nodes)
+ end
+ end
+
+ def ignore_warnings
+ previous_verbosity = $VERBOSE
+ $VERBOSE = nil
+ yield
+ ensure
+ $VERBOSE = previous_verbosity
+ end
+ end
+end
diff --git a/test/prism/parser_test.rb b/test/prism/parser_test.rb
new file mode 100644
index 0000000000..79b65cf75b
--- /dev/null
+++ b/test/prism/parser_test.rb
@@ -0,0 +1,186 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+begin
+ verbose, $VERBOSE = $VERBOSE, nil
+ require "parser/ruby33"
+ require "prism/translation/parser33"
+rescue LoadError
+ # In CRuby's CI, we're not going to test against the parser gem because we
+ # don't want to have to install it. So in this case we'll just skip this test.
+ return
+ensure
+ $VERBOSE = verbose
+end
+
+# First, opt in to every AST feature.
+Parser::Builders::Default.modernize
+
+# Modify the source map == check so that it doesn't check against the node
+# itself so we don't get into a recursive loop.
+Parser::Source::Map.prepend(
+ Module.new {
+ def ==(other)
+ self.class == other.class &&
+ (instance_variables - %i[@node]).map do |ivar|
+ instance_variable_get(ivar) == other.instance_variable_get(ivar)
+ end.reduce(:&)
+ end
+ }
+)
+
+# Next, ensure that we're comparing the nodes and also comparing the source
+# ranges so that we're getting all of the necessary information.
+Parser::AST::Node.prepend(
+ Module.new {
+ def ==(other)
+ super && (location == other.location)
+ end
+ }
+)
+
+module Prism
+ class ParserTest < TestCase
+ base = File.join(__dir__, "fixtures")
+
+ # These files are erroring because of the parser gem being wrong.
+ skip_incorrect = [
+ "embdoc_no_newline_at_end.txt"
+ ]
+
+ # These files are either failing to parse or failing to translate, so we'll
+ # skip them for now.
+ skip_all = skip_incorrect | [
+ "dash_heredocs.txt",
+ "dos_endings.txt",
+ "heredocs_with_ignored_newlines.txt",
+ "regex.txt",
+ "regex_char_width.txt",
+ "spanning_heredoc.txt",
+ "spanning_heredoc_newlines.txt",
+ "unescaping.txt"
+ ]
+
+ # Not sure why these files are failing on JRuby, but skipping them for now.
+ if RUBY_ENGINE == "jruby"
+ skip_all.push("emoji_method_calls.txt", "symbols.txt")
+ end
+
+ # These files are failing to translate their lexer output into the lexer
+ # output expected by the parser gem, so we'll skip them for now.
+ skip_tokens = [
+ "comments.txt",
+ "heredoc_with_comment.txt",
+ "indented_file_end.txt",
+ "methods.txt",
+ "strings.txt",
+ "tilde_heredocs.txt",
+ "xstring_with_backslash.txt"
+ ]
+
+ Dir["*.txt", base: base].each do |name|
+ next if skip_all.include?(name)
+
+ define_method("test_#{name}") do
+ assert_equal_parses(File.join(base, name), compare_tokens: !skip_tokens.include?(name))
+ end
+ end
+
+ private
+
+ def assert_equal_parses(filepath, compare_tokens: true)
+ buffer = Parser::Source::Buffer.new(filepath, 1)
+ buffer.source = File.read(filepath)
+
+ parser = Parser::Ruby33.new
+ parser.diagnostics.consumer = ->(*) {}
+ parser.diagnostics.all_errors_are_fatal = true
+
+ expected_ast, expected_comments, expected_tokens =
+ begin
+ parser.tokenize(buffer)
+ rescue ArgumentError, Parser::SyntaxError
+ return
+ end
+
+ actual_ast, actual_comments, actual_tokens =
+ Prism::Translation::Parser33.new.tokenize(buffer)
+
+ assert_equal expected_ast, actual_ast, -> { assert_equal_asts_message(expected_ast, actual_ast) }
+ assert_equal_tokens(expected_tokens, actual_tokens) if compare_tokens
+ assert_equal_comments(expected_comments, actual_comments)
+ end
+
+ def assert_equal_asts_message(expected_ast, actual_ast)
+ queue = [[expected_ast, actual_ast]]
+
+ while (left, right = queue.shift)
+ if left.type != right.type
+ return "expected: #{left.type}\nactual: #{right.type}"
+ end
+
+ if left.location != right.location
+ return "expected:\n#{left.inspect}\n#{left.location.inspect}\nactual:\n#{right.inspect}\n#{right.location.inspect}"
+ end
+
+ if left.type == :str && left.children[0] != right.children[0]
+ return "expected: #{left.inspect}\nactual: #{right.inspect}"
+ end
+
+ left.children.zip(right.children).each do |left_child, right_child|
+ queue << [left_child, right_child] if left_child.is_a?(Parser::AST::Node)
+ end
+ end
+
+ "expected: #{expected_ast.inspect}\nactual: #{actual_ast.inspect}"
+ end
+
+ def assert_equal_tokens(expected_tokens, actual_tokens)
+ if expected_tokens != actual_tokens
+ expected_index = 0
+ actual_index = 0
+
+ while expected_index < expected_tokens.length
+ expected_token = expected_tokens[expected_index]
+ actual_token = actual_tokens[actual_index]
+
+ expected_index += 1
+ actual_index += 1
+
+ # The parser gem always has a space before a string end in list
+ # literals, but we don't. So we'll skip over the space.
+ if expected_token[0] == :tSPACE && actual_token[0] == :tSTRING_END
+ expected_index += 1
+ next
+ end
+
+ # There are a lot of tokens that have very specific meaning according
+ # to the context of the parser. We don't expose that information in
+ # prism, so we need to normalize these tokens a bit.
+ case actual_token[0]
+ when :kDO
+ actual_token[0] = expected_token[0] if %i[kDO_BLOCK kDO_LAMBDA].include?(expected_token[0])
+ when :tLPAREN
+ actual_token[0] = expected_token[0] if expected_token[0] == :tLPAREN2
+ when :tPOW
+ actual_token[0] = expected_token[0] if expected_token[0] == :tDSTAR
+ end
+
+ # Now we can assert that the tokens are actually equal.
+ assert_equal expected_token, actual_token, -> {
+ "expected: #{expected_token.inspect}\n" \
+ "actual: #{actual_token.inspect}"
+ }
+ end
+ end
+ end
+
+ def assert_equal_comments(expected_comments, actual_comments)
+ assert_equal expected_comments, actual_comments, -> {
+ "expected: #{expected_comments.inspect}\n" \
+ "actual: #{actual_comments.inspect}"
+ }
+ end
+ end
+end
diff --git a/test/prism/pattern_test.rb b/test/prism/pattern_test.rb
new file mode 100644
index 0000000000..e0aa079cb9
--- /dev/null
+++ b/test/prism/pattern_test.rb
@@ -0,0 +1,132 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class PatternTest < TestCase
+ def test_invalid_syntax
+ assert_raise(Pattern::CompilationError) { scan("", "<>") }
+ end
+
+ def test_invalid_constant
+ assert_raise(Pattern::CompilationError) { scan("", "Foo") }
+ end
+
+ def test_invalid_nested_constant
+ assert_raise(Pattern::CompilationError) { scan("", "Foo::Bar") }
+ end
+
+ def test_regexp_with_interpolation
+ assert_raise(Pattern::CompilationError) { scan("", "/\#{foo}/") }
+ end
+
+ def test_string_with_interpolation
+ assert_raise(Pattern::CompilationError) { scan("", '"#{foo}"') }
+ end
+
+ def test_symbol_with_interpolation
+ assert_raise(Pattern::CompilationError) { scan("", ":\"\#{foo}\"") }
+ end
+
+ def test_invalid_node
+ assert_raise(Pattern::CompilationError) { scan("", "IntegerNode[^foo]") }
+ end
+
+ def test_self
+ assert_raise(Pattern::CompilationError) { scan("", "self") }
+ end
+
+ def test_array_pattern_no_constant
+ results = scan("1 + 2", "[IntegerNode]")
+
+ assert_equal 1, results.length
+ end
+
+ def test_array_pattern
+ results = scan("1 + 2", "CallNode[name: :+, receiver: IntegerNode, arguments: [IntegerNode]]")
+
+ assert_equal 1, results.length
+ end
+
+ def test_alternation_pattern
+ results = scan("Foo + Bar + 1", "ConstantReadNode | IntegerNode")
+
+ assert_equal 3, results.length
+ assert_equal 1, results.grep(IntegerNode).first.value
+ end
+
+ def test_constant_read_node
+ results = scan("Foo + Bar + Baz", "ConstantReadNode")
+
+ assert_equal 3, results.length
+ assert_equal %w[Bar Baz Foo], results.map(&:slice).sort
+ end
+
+ def test_object_const
+ results = scan("1 + 2 + 3", "IntegerNode[]")
+
+ assert_equal 3, results.length
+ end
+
+ def test_constant_path
+ results = scan("Foo + Bar + Baz", "Prism::ConstantReadNode")
+
+ assert_equal 3, results.length
+ end
+
+ def test_hash_pattern_no_constant
+ results = scan("Foo + Bar + Baz", "{ name: :+ }")
+
+ assert_equal 2, results.length
+ end
+
+ def test_hash_pattern_regexp
+ results = scan("Foo + Bar + Baz", "{ name: /^[[:punct:]]$/ }")
+
+ assert_equal 2, results.length
+ assert_equal ["Prism::CallNode"], results.map { |node| node.class.name }.uniq
+ end
+
+ def test_nil
+ results = scan("foo", "{ receiver: nil }")
+
+ assert_equal 1, results.length
+ end
+
+ def test_regexp_options
+ results = scan("@foo + @bar + @baz", "InstanceVariableReadNode[name: /^@B/i]")
+
+ assert_equal 2, results.length
+ end
+
+ def test_string_empty
+ results = scan("", "''")
+
+ assert_empty results
+ end
+
+ def test_symbol_empty
+ results = scan("", ":''")
+
+ assert_empty results
+ end
+
+ def test_symbol_plain
+ results = scan("@foo", "{ name: :\"@foo\" }")
+
+ assert_equal 1, results.length
+ end
+
+ def test_symbol
+ results = scan("@foo", "{ name: :@foo }")
+
+ assert_equal 1, results.length
+ end
+
+ private
+
+ def scan(source, query)
+ Prism::Pattern.new(query).scan(Prism.parse(source).value).to_a
+ end
+ end
+end
diff --git a/test/prism/regexp_test.rb b/test/prism/regexp_test.rb
new file mode 100644
index 0000000000..0a5fc2b4fc
--- /dev/null
+++ b/test/prism/regexp_test.rb
@@ -0,0 +1,263 @@
+# frozen_string_literal: true
+
+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)"))
+ end
+
+ def test_named_captures_with_single_quotes
+ assert_equal(["foo"], named_captures("(?'foo'bar)"))
+ end
+
+ def test_nested_named_captures_with_arrows
+ 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))"))
+ end
+
+ def test_allows_duplicate_named_captures
+ assert_equal(["foo", "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)}"))
+ 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"))
+ end
+
+ def test_anchors
+ refute_nil(named_captures("^foo$"))
+ end
+
+ def test_any
+ refute_nil(named_captures("."))
+ end
+
+ def test_posix_character_classes
+ refute_nil(named_captures("[[:digit:]]"))
+ end
+
+ def test_negated_posix_character_classes
+ refute_nil(named_captures("[[:^digit:]]"))
+ end
+
+ def test_invalid_posix_character_classes_should_fall_back_to_regular_classes
+ refute_nil(named_captures("[[:foo]]"))
+ end
+
+ def test_character_sets
+ refute_nil(named_captures("[abc]"))
+ end
+
+ def test_nested_character_sets
+ refute_nil(named_captures("[[abc]]"))
+ end
+
+ def test_nested_character_sets_with_operators
+ refute_nil(named_captures("[[abc] && [def]]"))
+ end
+
+ def test_named_capture_inside_nested_character_set
+ assert_equal([], named_captures("[foo (?<foo>bar)]"))
+ end
+
+ def test_negated_character_sets
+ refute_nil(named_captures("[^abc]"))
+ end
+
+ def test_character_ranges
+ refute_nil(named_captures("[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>)]"))
+ end
+
+ def test_comments
+ refute_nil(named_captures("(?#foo)"))
+ end
+
+ def test_comments_with_escaped_parentheses
+ refute_nil(named_captures("(?#foo\\)\\))"))
+ end
+
+ def test_non_capturing_groups
+ refute_nil(named_captures("(?:foo)"))
+ end
+
+ def test_positive_lookaheads
+ refute_nil(named_captures("(?=foo)"))
+ end
+
+ def test_negative_lookaheads
+ refute_nil(named_captures("(?!foo)"))
+ end
+
+ def test_positive_lookbehinds
+ refute_nil(named_captures("(?<=foo)"))
+ end
+
+ def test_negative_lookbehinds
+ refute_nil(named_captures("(?<!foo)"))
+ end
+
+ def test_atomic_groups
+ refute_nil(named_captures("(?>foo)"))
+ end
+
+ def test_absence_operator
+ refute_nil(named_captures("(?~foo)"))
+ end
+
+ def test_conditional_expression_with_index
+ refute_nil(named_captures("(?(1)foo)"))
+ end
+
+ def test_conditional_expression_with_name
+ refute_nil(named_captures("(?(foo)bar)"))
+ end
+
+ def test_conditional_expression_with_group
+ refute_nil(named_captures("(?(<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)"))
+ end
+
+ def test_options_on_groups_getting_turned_off
+ refute_nil(named_captures("(?-imx:foo)"))
+ end
+
+ def test_options_on_groups_some_getting_turned_on_some_getting_turned_off
+ refute_nil(named_captures("(?im-x:foo)"))
+ end
+
+ def test_star_quantifier
+ refute_nil(named_captures("foo*"))
+ end
+
+ def test_plus_quantifier
+ refute_nil(named_captures("foo+"))
+ end
+
+ def test_question_mark_quantifier
+ refute_nil(named_captures("foo?"))
+ end
+
+ def test_endless_range_quantifier
+ refute_nil(named_captures("foo{1,}"))
+ end
+
+ def test_beginless_range_quantifier
+ refute_nil(named_captures("foo{,1}"))
+ end
+
+ def test_range_quantifier
+ refute_nil(named_captures("foo{1,2}"))
+ end
+
+ def test_fake_range_quantifier_because_of_spaces
+ refute_nil(named_captures("foo{1, 2}"))
+ end
+
+ ##############################################################################
+ # These test that flag values are correct.
+ ##############################################################################
+
+ def test_flag_ignorecase
+ assert_equal(Regexp::IGNORECASE, options("i"))
+ end
+
+ def test_flag_extended
+ assert_equal(Regexp::EXTENDED, options("x"))
+ end
+
+ def test_flag_multiline
+ assert_equal(Regexp::MULTILINE, options("m"))
+ end
+
+ def test_flag_fixedencoding
+ assert_equal(Regexp::FIXEDENCODING, options("e"))
+ assert_equal(Regexp::FIXEDENCODING, options("u"))
+ assert_equal(Regexp::FIXEDENCODING, options("s"))
+ end
+
+ def test_flag_noencoding
+ assert_equal(Regexp::NOENCODING, options("n"))
+ end
+
+ def test_flag_once
+ assert_equal(0, options("o"))
+ end
+
+ def test_flag_combined
+ value = Regexp::IGNORECASE | Regexp::MULTILINE | Regexp::EXTENDED
+ assert_equal(value, options("mix"))
+ end
+
+ def test_last_encoding_option_wins
+ regex = "/foo/nu"
+ option = Prism.parse(regex).value.statements.body.first.options
+
+ assert_equal Regexp::FIXEDENCODING, option
+
+ regex = "/foo/un"
+ option = Prism.parse(regex).value.statements.body.first.options
+
+ assert_equal Regexp::NOENCODING, option
+ end
+
+ private
+
+ def named_captures(source)
+ Debug.named_captures(source)
+ end
+
+ def options(flags)
+ options =
+ ["/foo/#{flags}", "/foo\#{1}/#{flags}"].map do |source|
+ Prism.parse(source).value.statements.body.first.options
+ end
+
+ # Check that we get the same set of options from both regular expressions
+ # and interpolated regular expressions.
+ assert_equal(1, options.uniq.length)
+
+ # Return the options from the first regular expression since we know they
+ # are the same.
+ options.first
+ end
+ end
+end
diff --git a/test/prism/ripper_test.rb b/test/prism/ripper_test.rb
new file mode 100644
index 0000000000..07238fc3d5
--- /dev/null
+++ b/test/prism/ripper_test.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+return if RUBY_VERSION < "3.3"
+
+require_relative "test_helper"
+
+module Prism
+ class RipperTest < TestCase
+ base = File.join(__dir__, "fixtures")
+ relatives = ENV["FOCUS"] ? [ENV["FOCUS"]] : Dir["**/*.txt", base: base]
+
+ incorrect = [
+ # Ripper incorrectly attributes the block to the keyword.
+ "seattlerb/block_break.txt",
+ "seattlerb/block_next.txt",
+ "seattlerb/block_return.txt",
+ "whitequark/break_block.txt",
+ "whitequark/next_block.txt",
+ "whitequark/return_block.txt",
+
+ # Ripper is not accounting for locals created by patterns using the **
+ # operator within an `in` clause.
+ "seattlerb/parse_pattern_058.txt",
+
+ # Ripper cannot handle named capture groups in regular expressions.
+ "regex.txt",
+ "regex_char_width.txt",
+ "whitequark/lvar_injecting_match.txt",
+
+ # Ripper fails to understand some structures that span across heredocs.
+ "spanning_heredoc.txt"
+ ]
+
+ omitted = [
+ "dos_endings.txt",
+ "heredocs_with_ignored_newlines.txt",
+ "seattlerb/block_call_dot_op2_brace_block.txt",
+ "seattlerb/block_command_operation_colon.txt",
+ "seattlerb/block_command_operation_dot.txt",
+ "seattlerb/heredoc__backslash_dos_format.txt",
+ "seattlerb/heredoc_backslash_nl.txt",
+ "seattlerb/heredoc_nested.txt",
+ "seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt",
+ "tilde_heredocs.txt",
+ "unparser/corpus/semantic/dstr.txt",
+ "whitequark/dedenting_heredoc.txt",
+ "whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt",
+ "whitequark/parser_slash_slash_n_escaping_in_literals.txt",
+ "whitequark/send_block_chain_cmd.txt",
+ "whitequark/slash_newline_in_heredocs.txt"
+ ]
+
+ relatives.each do |relative|
+ # Skip the tests that Ripper is reporting the wrong results for.
+ next if incorrect.include?(relative)
+
+ # Skip the tests we haven't implemented yet.
+ next if omitted.include?(relative)
+
+ filepath = File.join(__dir__, "fixtures", relative)
+
+ define_method "test_ripper_#{relative}" do
+ source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
+
+ case relative
+ when /break|next|redo|if|unless|rescue|control|keywords|retry/
+ source = "-> do\nrescue\n#{source}\nend"
+ end
+
+ case source
+ when /^ *yield/
+ source = "def __invalid_yield__\n#{source}\nend"
+ end
+
+ assert_ripper(source)
+ end
+ end
+
+ private
+
+ def assert_ripper(source)
+ assert_equal Ripper.sexp_raw(source), Prism::Translation::Ripper.sexp_raw(source)
+ end
+ end
+end
diff --git a/test/prism/ruby_api_test.rb b/test/prism/ruby_api_test.rb
new file mode 100644
index 0000000000..6418887147
--- /dev/null
+++ b/test/prism/ruby_api_test.rb
@@ -0,0 +1,253 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class RubyAPITest < TestCase
+ if !ENV["PRISM_BUILD_MINIMAL"]
+ def test_ruby_api
+ filepath = __FILE__
+ source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
+
+ assert_equal Prism.lex(source, filepath: filepath).value, Prism.lex_file(filepath).value
+ assert_equal Prism.dump(source, filepath: filepath), Prism.dump_file(filepath)
+
+ serialized = Prism.dump(source, filepath: filepath)
+ ast1 = Prism.load(source, serialized).value
+ ast2 = Prism.parse(source, filepath: filepath).value
+ ast3 = Prism.parse_file(filepath).value
+
+ assert_equal_nodes ast1, ast2
+ assert_equal_nodes ast2, ast3
+ end
+ end
+
+ def test_parse_success?
+ assert Prism.parse_success?("1")
+ refute Prism.parse_success?("<>")
+ end
+
+ def test_parse_file_success?
+ assert Prism.parse_file_success?(__FILE__)
+ end
+
+ def test_options
+ assert_equal "", Prism.parse("__FILE__").value.statements.body[0].filepath
+ assert_equal "foo.rb", Prism.parse("__FILE__", filepath: "foo.rb").value.statements.body[0].filepath
+
+ assert_equal 1, Prism.parse("foo").value.statements.body[0].location.start_line
+ assert_equal 10, Prism.parse("foo", line: 10).value.statements.body[0].location.start_line
+
+ refute Prism.parse("\"foo\"").value.statements.body[0].frozen?
+ assert Prism.parse("\"foo\"", frozen_string_literal: true).value.statements.body[0].frozen?
+ refute Prism.parse("\"foo\"", frozen_string_literal: false).value.statements.body[0].frozen?
+
+ assert_kind_of Prism::CallNode, Prism.parse("foo").value.statements.body[0]
+ assert_kind_of Prism::LocalVariableReadNode, Prism.parse("foo", scopes: [[:foo]]).value.statements.body[0]
+ assert_equal 1, Prism.parse("foo", scopes: [[:foo], []]).value.statements.body[0].depth
+
+ assert_equal [:foo], Prism.parse("foo", scopes: [[:foo]]).value.locals
+ end
+
+ def test_literal_value_method
+ assert_equal 123, parse_expression("123").value
+ assert_equal 3.14, parse_expression("3.14").value
+ assert_equal 42i, parse_expression("42i").value
+ assert_equal 42.1ri, parse_expression("42.1ri").value
+ assert_equal 3.14i, parse_expression("3.14i").value
+ assert_equal 42r, parse_expression("42r").value
+ assert_equal 0.5r, parse_expression("0.5r").value
+ assert_equal 42ri, parse_expression("42ri").value
+ assert_equal 0.5ri, parse_expression("0.5ri").value
+ assert_equal 0xFFr, parse_expression("0xFFr").value
+ assert_equal 0xFFri, parse_expression("0xFFri").value
+ end
+
+ def test_location_join
+ recv, args_node, _ = parse_expression("1234 + 567").child_nodes
+ arg = args_node.arguments[0]
+
+ joined = recv.location.join(arg.location)
+ assert_equal 0, joined.start_offset
+ assert_equal 10, joined.length
+
+ assert_raise RuntimeError, "Incompatible locations" do
+ arg.location.join(recv.location)
+ end
+
+ other_arg = parse_expression("1234 + 567").arguments.arguments[0]
+
+ assert_raise RuntimeError, "Incompatible sources" do
+ other_arg.location.join(recv.location)
+ end
+
+ assert_raise RuntimeError, "Incompatible sources" do
+ recv.location.join(other_arg.location)
+ end
+ end
+
+ def test_location_character_offsets
+ program = Prism.parse("😀 + 😀\n😍 ||= 😍").value
+
+ # first 😀
+ location = program.statements.body.first.receiver.location
+ assert_equal 0, location.start_character_offset
+ assert_equal 1, location.end_character_offset
+ assert_equal 0, location.start_character_column
+ assert_equal 1, location.end_character_column
+
+ # second 😀
+ location = program.statements.body.first.arguments.arguments.first.location
+ assert_equal 4, location.start_character_offset
+ assert_equal 5, location.end_character_offset
+ assert_equal 4, location.start_character_column
+ assert_equal 5, location.end_character_column
+
+ # first 😍
+ location = program.statements.body.last.name_loc
+ assert_equal 6, location.start_character_offset
+ assert_equal 7, location.end_character_offset
+ assert_equal 0, location.start_character_column
+ assert_equal 1, location.end_character_column
+
+ # second 😍
+ location = program.statements.body.last.value.location
+ assert_equal 12, location.start_character_offset
+ assert_equal 13, location.end_character_offset
+ assert_equal 6, location.start_character_column
+ assert_equal 7, location.end_character_column
+ end
+
+ def test_location_code_units
+ program = Prism.parse("😀 + 😀\n😍 ||= 😍").value
+
+ # first 😀
+ location = program.statements.body.first.receiver.location
+
+ assert_equal 0, location.start_code_units_offset(Encoding::UTF_8)
+ assert_equal 0, location.start_code_units_offset(Encoding::UTF_16LE)
+ assert_equal 0, location.start_code_units_offset(Encoding::UTF_32LE)
+
+ assert_equal 1, location.end_code_units_offset(Encoding::UTF_8)
+ assert_equal 2, location.end_code_units_offset(Encoding::UTF_16LE)
+ assert_equal 1, location.end_code_units_offset(Encoding::UTF_32LE)
+
+ assert_equal 0, location.start_code_units_column(Encoding::UTF_8)
+ assert_equal 0, location.start_code_units_column(Encoding::UTF_16LE)
+ assert_equal 0, location.start_code_units_column(Encoding::UTF_32LE)
+
+ assert_equal 1, location.end_code_units_column(Encoding::UTF_8)
+ assert_equal 2, location.end_code_units_column(Encoding::UTF_16LE)
+ assert_equal 1, location.end_code_units_column(Encoding::UTF_32LE)
+
+ # second 😀
+ location = program.statements.body.first.arguments.arguments.first.location
+
+ assert_equal 4, location.start_code_units_offset(Encoding::UTF_8)
+ assert_equal 5, location.start_code_units_offset(Encoding::UTF_16LE)
+ assert_equal 4, location.start_code_units_offset(Encoding::UTF_32LE)
+
+ assert_equal 5, location.end_code_units_offset(Encoding::UTF_8)
+ assert_equal 7, location.end_code_units_offset(Encoding::UTF_16LE)
+ assert_equal 5, location.end_code_units_offset(Encoding::UTF_32LE)
+
+ assert_equal 4, location.start_code_units_column(Encoding::UTF_8)
+ assert_equal 5, location.start_code_units_column(Encoding::UTF_16LE)
+ assert_equal 4, location.start_code_units_column(Encoding::UTF_32LE)
+
+ assert_equal 5, location.end_code_units_column(Encoding::UTF_8)
+ assert_equal 7, location.end_code_units_column(Encoding::UTF_16LE)
+ assert_equal 5, location.end_code_units_column(Encoding::UTF_32LE)
+
+ # first 😍
+ location = program.statements.body.last.name_loc
+
+ assert_equal 6, location.start_code_units_offset(Encoding::UTF_8)
+ assert_equal 8, location.start_code_units_offset(Encoding::UTF_16LE)
+ assert_equal 6, location.start_code_units_offset(Encoding::UTF_32LE)
+
+ assert_equal 7, location.end_code_units_offset(Encoding::UTF_8)
+ assert_equal 10, location.end_code_units_offset(Encoding::UTF_16LE)
+ assert_equal 7, location.end_code_units_offset(Encoding::UTF_32LE)
+
+ assert_equal 0, location.start_code_units_column(Encoding::UTF_8)
+ assert_equal 0, location.start_code_units_column(Encoding::UTF_16LE)
+ assert_equal 0, location.start_code_units_column(Encoding::UTF_32LE)
+
+ assert_equal 1, location.end_code_units_column(Encoding::UTF_8)
+ assert_equal 2, location.end_code_units_column(Encoding::UTF_16LE)
+ assert_equal 1, location.end_code_units_column(Encoding::UTF_32LE)
+
+ # second 😍
+ location = program.statements.body.last.value.location
+
+ assert_equal 12, location.start_code_units_offset(Encoding::UTF_8)
+ assert_equal 15, location.start_code_units_offset(Encoding::UTF_16LE)
+ assert_equal 12, location.start_code_units_offset(Encoding::UTF_32LE)
+
+ assert_equal 13, location.end_code_units_offset(Encoding::UTF_8)
+ assert_equal 17, location.end_code_units_offset(Encoding::UTF_16LE)
+ assert_equal 13, location.end_code_units_offset(Encoding::UTF_32LE)
+
+ assert_equal 6, location.start_code_units_column(Encoding::UTF_8)
+ assert_equal 7, location.start_code_units_column(Encoding::UTF_16LE)
+ assert_equal 6, location.start_code_units_column(Encoding::UTF_32LE)
+
+ assert_equal 7, location.end_code_units_column(Encoding::UTF_8)
+ assert_equal 9, location.end_code_units_column(Encoding::UTF_16LE)
+ assert_equal 7, location.end_code_units_column(Encoding::UTF_32LE)
+ end
+
+ def test_location_chop
+ location = Prism.parse("foo").value.location
+
+ assert_equal "fo", location.chop.slice
+ assert_equal "", location.chop.chop.chop.slice
+
+ # Check that we don't go negative.
+ 10.times { location = location.chop }
+ assert_equal "", location.slice
+ end
+
+ def test_heredoc?
+ refute parse_expression("\"foo\"").heredoc?
+ refute parse_expression("\"foo \#{1}\"").heredoc?
+ refute parse_expression("`foo`").heredoc?
+ refute parse_expression("`foo \#{1}`").heredoc?
+
+ assert parse_expression("<<~HERE\nfoo\nHERE\n").heredoc?
+ assert parse_expression("<<~HERE\nfoo \#{1}\nHERE\n").heredoc?
+ assert parse_expression("<<~`HERE`\nfoo\nHERE\n").heredoc?
+ assert parse_expression("<<~`HERE`\nfoo \#{1}\nHERE\n").heredoc?
+ end
+
+ # Through some bit hackery, we want to allow consumers to use the integer
+ # base flags as the base itself. It has a nice property that the current
+ # alignment provides them in the correct order. So here we test that our
+ # assumption holds so that it doesn't change out from under us.
+ #
+ # In C, this would look something like:
+ #
+ # ((flags & ~DECIMAL) << 1) || 10
+ #
+ # We have to do some other work in Ruby because 0 is truthy and ~ on an
+ # integer doesn't have a fixed width.
+ def test_integer_base_flags
+ base = -> (node) do
+ value = (node.send(:flags) & (0b1111 - IntegerBaseFlags::DECIMAL)) << 1
+ value == 0 ? 10 : value
+ end
+
+ assert_equal 2, base[parse_expression("0b1")]
+ assert_equal 8, base[parse_expression("0o1")]
+ assert_equal 10, base[parse_expression("0d1")]
+ assert_equal 16, base[parse_expression("0x1")]
+ end
+
+ private
+
+ def parse_expression(source)
+ Prism.parse(source).value.statements.body.first
+ end
+ end
+end
diff --git a/test/prism/ruby_parser_test.rb b/test/prism/ruby_parser_test.rb
new file mode 100644
index 0000000000..8edeac4b4f
--- /dev/null
+++ b/test/prism/ruby_parser_test.rb
@@ -0,0 +1,144 @@
+# frozen_string_literal: true
+
+return if RUBY_ENGINE == "jruby"
+
+require_relative "test_helper"
+
+begin
+ require "ruby_parser"
+rescue LoadError
+ # In CRuby's CI, we're not going to test against the ruby_parser gem because
+ # we don't want to have to install it. So in this case we'll just skip this
+ # test.
+ return
+end
+
+# We want to also compare lines and files to make sure we're setting them
+# correctly.
+Sexp.prepend(
+ Module.new do
+ def ==(other)
+ super && line == other.line && line_max == other.line_max && file == other.file
+ end
+ end
+)
+
+module Prism
+ class RubyParserTest < TestCase
+ 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
+ failures = %w[
+ alias.txt
+ dos_endings.txt
+ heredocs_with_ignored_newlines.txt
+ method_calls.txt
+ methods.txt
+ multi_write.txt
+ not.txt
+ patterns.txt
+ regex.txt
+ seattlerb/and_multi.txt
+ seattlerb/heredoc__backslash_dos_format.txt
+ seattlerb/heredoc_bad_hex_escape.txt
+ seattlerb/heredoc_bad_oct_escape.txt
+ seattlerb/heredoc_with_extra_carriage_horrible_mix.txt
+ seattlerb/heredoc_with_extra_carriage_returns_windows.txt
+ seattlerb/heredoc_with_only_carriage_returns_windows.txt
+ seattlerb/heredoc_with_only_carriage_returns.txt
+ spanning_heredoc_newlines.txt
+ spanning_heredoc.txt
+ 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
+ whitequark/op_asgn_cmd.txt
+ whitequark/parser_bug_640.txt
+ whitequark/parser_slash_slash_n_escaping_in_literals.txt
+ whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt
+ whitequark/pattern_matching_single_line.txt
+ whitequark/ruby_bug_11989.txt
+ whitequark/slash_newline_in_heredocs.txt
+ ]
+
+ Dir["**/*.txt", base: base].each do |name|
+ next if failures.include?(name)
+
+ define_method("test_#{name}") do
+ begin
+ # Parsing with ruby parser tends to be noisy with warnings, so we're
+ # turning those off.
+ previous_verbose, $VERBOSE = $VERBOSE, nil
+ assert_parse_file(base, name, todos.include?(name))
+ ensure
+ $VERBOSE = previous_verbose
+ end
+ end
+ end
+
+ private
+
+ def assert_parse_file(base, name, allowed_failure)
+ filepath = File.join(base, name)
+ expected = ::RubyParser.new.parse(File.read(filepath), filepath)
+ actual = Prism::Translation::RubyParser.parse_file(filepath)
+
+ if !allowed_failure
+ assert_equal_nodes expected, actual
+ elsif expected == actual
+ puts "#{name} now passes"
+ end
+ end
+
+ def assert_equal_nodes(left, right)
+ return if left == right
+
+ if left.is_a?(Sexp) && right.is_a?(Sexp)
+ if left.line != right.line
+ assert_equal "(#{left.inspect} line=#{left.line})", "(#{right.inspect} line=#{right.line})"
+ elsif left.file != right.file
+ assert_equal "(#{left.inspect} file=#{left.file})", "(#{right.inspect} file=#{right.file})"
+ elsif left.length != right.length
+ assert_equal "(#{left.inspect} length=#{left.length})", "(#{right.inspect} length=#{right.length})"
+ else
+ left.zip(right).each { |l, r| assert_equal_nodes(l, r) }
+ end
+ else
+ assert_equal left, right
+ end
+ end
+ end
+end
diff --git a/test/prism/snapshots/alias.txt b/test/prism/snapshots/alias.txt
new file mode 100644
index 0000000000..a952e96f67
--- /dev/null
+++ b/test/prism/snapshots/alias.txt
@@ -0,0 +1,194 @@
+@ ProgramNode (location: (1,0)-(23,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(23,11))
+ └── body: (length: 12)
+ ├── @ AliasMethodNode (location: (1,0)-(1,15))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (1,6)-(1,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,6)-(1,7) = ":"
+ │ │ ├── value_loc: (1,7)-(1,10) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (1,11)-(1,15))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,11)-(1,12) = ":"
+ │ │ ├── value_loc: (1,12)-(1,15) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ └── keyword_loc: (1,0)-(1,5) = "alias"
+ ├── @ AliasMethodNode (location: (3,0)-(3,21))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (3,6)-(3,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,6)-(3,9) = "%s["
+ │ │ ├── value_loc: (3,9)-(3,12) = "abc"
+ │ │ ├── closing_loc: (3,12)-(3,13) = "]"
+ │ │ └── unescaped: "abc"
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (3,14)-(3,21))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,14)-(3,17) = "%s["
+ │ │ ├── value_loc: (3,17)-(3,20) = "def"
+ │ │ ├── closing_loc: (3,20)-(3,21) = "]"
+ │ │ └── unescaped: "def"
+ │ └── keyword_loc: (3,0)-(3,5) = "alias"
+ ├── @ AliasMethodNode (location: (5,0)-(5,19))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (5,6)-(5,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,6)-(5,8) = ":'"
+ │ │ ├── value_loc: (5,8)-(5,11) = "abc"
+ │ │ ├── closing_loc: (5,11)-(5,12) = "'"
+ │ │ └── unescaped: "abc"
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (5,13)-(5,19))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,13)-(5,15) = ":'"
+ │ │ ├── value_loc: (5,15)-(5,18) = "def"
+ │ │ ├── closing_loc: (5,18)-(5,19) = "'"
+ │ │ └── unescaped: "def"
+ │ └── keyword_loc: (5,0)-(5,5) = "alias"
+ ├── @ AliasMethodNode (location: (7,0)-(7,23))
+ │ ├── new_name:
+ │ │ @ InterpolatedSymbolNode (location: (7,6)-(7,16))
+ │ │ ├── opening_loc: (7,6)-(7,8) = ":\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (7,8)-(7,11))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (7,8)-(7,11) = "abc"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "abc"
+ │ │ │ └── @ EmbeddedStatementsNode (location: (7,11)-(7,15))
+ │ │ │ ├── opening_loc: (7,11)-(7,13) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (7,13)-(7,14))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (7,13)-(7,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (7,14)-(7,15) = "}"
+ │ │ └── closing_loc: (7,15)-(7,16) = "\""
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (7,17)-(7,23))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (7,17)-(7,19) = ":'"
+ │ │ ├── value_loc: (7,19)-(7,22) = "def"
+ │ │ ├── closing_loc: (7,22)-(7,23) = "'"
+ │ │ └── unescaped: "def"
+ │ └── keyword_loc: (7,0)-(7,5) = "alias"
+ ├── @ AliasGlobalVariableNode (location: (9,0)-(9,11))
+ │ ├── new_name:
+ │ │ @ GlobalVariableReadNode (location: (9,6)-(9,8))
+ │ │ └── name: :$a
+ │ ├── old_name:
+ │ │ @ BackReferenceReadNode (location: (9,9)-(9,11))
+ │ │ └── name: :$'
+ │ └── keyword_loc: (9,0)-(9,5) = "alias"
+ ├── @ AliasMethodNode (location: (11,0)-(11,13))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (11,6)-(11,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (11,6)-(11,9) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (11,10)-(11,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (11,10)-(11,13) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ └── keyword_loc: (11,0)-(11,5) = "alias"
+ ├── @ AliasGlobalVariableNode (location: (13,0)-(13,15))
+ │ ├── new_name:
+ │ │ @ GlobalVariableReadNode (location: (13,6)-(13,10))
+ │ │ └── name: :$foo
+ │ ├── old_name:
+ │ │ @ GlobalVariableReadNode (location: (13,11)-(13,15))
+ │ │ └── name: :$bar
+ │ └── keyword_loc: (13,0)-(13,5) = "alias"
+ ├── @ AliasMethodNode (location: (15,0)-(15,12))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (15,6)-(15,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (15,6)-(15,9) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (15,10)-(15,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (15,10)-(15,12) = "if"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "if"
+ │ └── keyword_loc: (15,0)-(15,5) = "alias"
+ ├── @ AliasMethodNode (location: (17,0)-(17,13))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (17,6)-(17,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (17,6)-(17,9) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (17,10)-(17,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (17,10)-(17,13) = "<=>"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "<=>"
+ │ └── keyword_loc: (17,0)-(17,5) = "alias"
+ ├── @ AliasMethodNode (location: (19,0)-(19,15))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (19,6)-(19,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (19,6)-(19,7) = ":"
+ │ │ ├── value_loc: (19,7)-(19,9) = "=="
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "=="
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (19,10)-(19,15))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (19,10)-(19,11) = ":"
+ │ │ ├── value_loc: (19,11)-(19,15) = "eql?"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "eql?"
+ │ └── keyword_loc: (19,0)-(19,5) = "alias"
+ ├── @ AliasMethodNode (location: (21,0)-(21,9))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (21,6)-(21,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (21,6)-(21,7) = "A"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "A"
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (21,8)-(21,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (21,8)-(21,9) = "B"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "B"
+ │ └── keyword_loc: (21,0)-(21,5) = "alias"
+ └── @ AliasMethodNode (location: (23,0)-(23,11))
+ ├── new_name:
+ │ @ SymbolNode (location: (23,6)-(23,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (23,6)-(23,7) = ":"
+ │ ├── value_loc: (23,7)-(23,8) = "A"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "A"
+ ├── old_name:
+ │ @ SymbolNode (location: (23,9)-(23,11))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (23,9)-(23,10) = ":"
+ │ ├── value_loc: (23,10)-(23,11) = "B"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "B"
+ └── keyword_loc: (23,0)-(23,5) = "alias"
diff --git a/test/prism/snapshots/arithmetic.txt b/test/prism/snapshots/arithmetic.txt
new file mode 100644
index 0000000000..c8a31c3d70
--- /dev/null
+++ b/test/prism/snapshots/arithmetic.txt
@@ -0,0 +1,255 @@
+@ ProgramNode (location: (1,0)-(13,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(13,8))
+ └── body: (length: 7)
+ ├── @ CallNode (location: (1,0)-(1,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,5)-(1,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,5)-(1,8) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (1,4)-(1,5) = "!"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,4))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (3,1)-(3,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (3,1)-(3,4) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :-@
+ │ │ ├── message_loc: (3,0)-(3,1) = "-"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :*
+ │ ├── message_loc: (3,4)-(3,5) = "*"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,5)-(3,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,5)-(3,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,5)-(3,8) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (5,0)-(5,4))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (5,1)-(5,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (5,1)-(5,4) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :+@
+ │ │ ├── message_loc: (5,0)-(5,1) = "+"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :**
+ │ ├── message_loc: (5,4)-(5,6) = "**"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,6)-(5,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (5,6)-(5,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (5,6)-(5,9) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (7,0)-(7,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,4)-(7,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (7,4)-(7,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (7,5)-(7,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (7,5)-(7,8) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :~
+ │ │ ├── message_loc: (7,4)-(7,5) = "~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (9,0)-(9,17))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (9,0)-(9,10))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (9,0)-(9,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (9,0)-(9,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :<<
+ │ │ ├── message_loc: (9,4)-(9,6) = "<<"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (9,7)-(9,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (9,7)-(9,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (9,7)-(9,10) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<<
+ │ ├── message_loc: (9,11)-(9,13) = "<<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,14)-(9,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (9,14)-(9,17))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (9,14)-(9,17) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (11,0)-(11,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (11,1)-(11,5))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (11,1)-(11,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :**
+ │ │ ├── message_loc: (11,2)-(11,4) = "**"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (11,4)-(11,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (11,4)-(11,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :-@
+ │ ├── message_loc: (11,0)-(11,1) = "-"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (13,0)-(13,8))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (13,0)-(13,2))
+ │ ├── flags: decimal
+ │ └── value: -1
+ ├── call_operator_loc: (13,2)-(13,3) = "."
+ ├── name: :zero?
+ ├── message_loc: (13,3)-(13,8) = "zero?"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/arrays.txt b/test/prism/snapshots/arrays.txt
new file mode 100644
index 0000000000..e8e53aacb9
--- /dev/null
+++ b/test/prism/snapshots/arrays.txt
@@ -0,0 +1,1837 @@
+@ ProgramNode (location: (1,0)-(122,32))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(122,32))
+ └── body: (length: 50)
+ ├── @ ArrayNode (location: (1,0)-(1,4))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 1)
+ │ │ └── @ SplatNode (location: (1,1)-(1,3))
+ │ │ ├── operator_loc: (1,1)-(1,2) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (1,2)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,2)-(1,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "["
+ │ └── closing_loc: (1,3)-(1,4) = "]"
+ ├── @ CallNode (location: (3,0)-(3,23))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (3,3)-(3,13) = "[bar, baz]"
+ │ ├── opening_loc: (3,3)-(3,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,4)-(3,23))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ CallNode (location: (3,4)-(3,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (3,4)-(3,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── @ CallNode (location: (3,9)-(3,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (3,9)-(3,12) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ ArrayNode (location: (3,16)-(3,23))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (3,16)-(3,17))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ IntegerNode (location: (3,19)-(3,20))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (3,22)-(3,23))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ ├── closing_loc: (3,12)-(3,13) = "]"
+ │ └── block: ∅
+ ├── @ ArrayNode (location: (5,0)-(5,13))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (5,1)-(5,12))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (5,1)-(5,12))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (5,1)-(5,3))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (5,1)-(5,2) = "a"
+ │ │ │ ├── closing_loc: (5,2)-(5,3) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ ArrayNode (location: (5,4)-(5,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ ├── @ SymbolNode (location: (5,5)-(5,7))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (5,5)-(5,6) = ":"
+ │ │ │ │ │ ├── value_loc: (5,6)-(5,7) = "b"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ └── @ SymbolNode (location: (5,9)-(5,11))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (5,9)-(5,10) = ":"
+ │ │ │ │ ├── value_loc: (5,10)-(5,11) = "c"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "c"
+ │ │ │ ├── opening_loc: (5,4)-(5,5) = "["
+ │ │ │ └── closing_loc: (5,11)-(5,12) = "]"
+ │ │ └── operator_loc: ∅
+ │ ├── opening_loc: (5,0)-(5,1) = "["
+ │ └── closing_loc: (5,12)-(5,13) = "]"
+ ├── @ ArrayNode (location: (9,0)-(15,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 5)
+ │ │ ├── @ SymbolNode (location: (9,1)-(9,3))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (9,1)-(9,2) = ":"
+ │ │ │ ├── value_loc: (9,2)-(9,3) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ SymbolNode (location: (9,5)-(9,7))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (9,5)-(9,6) = ":"
+ │ │ │ ├── value_loc: (9,6)-(9,7) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ ├── @ SymbolNode (location: (10,0)-(10,2))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (10,0)-(10,1) = ":"
+ │ │ │ ├── value_loc: (10,1)-(10,2) = "c"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "c"
+ │ │ ├── @ IntegerNode (location: (10,3)-(10,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ SymbolNode (location: (14,0)-(14,2))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (14,0)-(14,1) = ":"
+ │ │ ├── value_loc: (14,1)-(14,2) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── opening_loc: (9,0)-(9,1) = "["
+ │ └── closing_loc: (15,0)-(15,1) = "]"
+ ├── @ ArrayNode (location: (18,0)-(26,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 5)
+ │ │ ├── @ SymbolNode (location: (18,1)-(18,3))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (18,1)-(18,2) = ":"
+ │ │ │ ├── value_loc: (18,2)-(18,3) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ SymbolNode (location: (18,5)-(18,7))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (18,5)-(18,6) = ":"
+ │ │ │ ├── value_loc: (18,6)-(18,7) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ ├── @ SymbolNode (location: (19,0)-(19,2))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (19,0)-(19,1) = ":"
+ │ │ │ ├── value_loc: (19,1)-(19,2) = "c"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "c"
+ │ │ ├── @ IntegerNode (location: (19,3)-(19,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ SymbolNode (location: (23,0)-(23,2))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (23,0)-(23,1) = ":"
+ │ │ ├── value_loc: (23,1)-(23,2) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── opening_loc: (18,0)-(18,1) = "["
+ │ └── closing_loc: (26,0)-(26,1) = "]"
+ ├── @ ArrayNode (location: (28,0)-(28,12))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (28,1)-(28,11))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (28,1)-(28,11))
+ │ │ ├── key:
+ │ │ │ @ CallNode (location: (28,1)-(28,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (28,1)-(28,4) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (28,8)-(28,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (28,8)-(28,11) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (28,5)-(28,7) = "=>"
+ │ ├── opening_loc: (28,0)-(28,1) = "["
+ │ └── closing_loc: (28,11)-(28,12) = "]"
+ ├── @ CallNode (location: (30,0)-(30,19))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ CallNode (location: (30,0)-(30,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (30,0)-(30,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (30,0)-(30,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]
+ │ │ ├── message_loc: (30,3)-(30,8) = "[bar]"
+ │ │ ├── opening_loc: (30,3)-(30,4) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (30,4)-(30,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (30,4)-(30,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (30,4)-(30,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (30,7)-(30,8) = "]"
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (30,8)-(30,13) = "[baz]"
+ │ ├── opening_loc: (30,8)-(30,9) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (30,9)-(30,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (30,9)-(30,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (30,9)-(30,12) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (30,16)-(30,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :qux
+ │ │ ├── message_loc: (30,16)-(30,19) = "qux"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (30,12)-(30,13) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (32,0)-(32,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (32,0)-(32,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (32,0)-(32,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (32,0)-(32,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]
+ │ │ ├── message_loc: (32,3)-(32,8) = "[bar]"
+ │ │ ├── opening_loc: (32,3)-(32,4) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (32,4)-(32,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (32,4)-(32,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (32,4)-(32,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (32,7)-(32,8) = "]"
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (32,8)-(32,13) = "[baz]"
+ │ ├── opening_loc: (32,8)-(32,9) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (32,9)-(32,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (32,9)-(32,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (32,9)-(32,12) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (32,12)-(32,13) = "]"
+ │ └── block: ∅
+ ├── @ ArrayNode (location: (34,0)-(35,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (34,0)-(34,1) = "["
+ │ └── closing_loc: (35,0)-(35,1) = "]"
+ ├── @ CallNode (location: (37,0)-(37,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (37,0)-(37,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (37,0)-(37,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (37,3)-(37,13) = "[bar, baz]"
+ │ ├── opening_loc: (37,3)-(37,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (37,4)-(37,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (37,4)-(37,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (37,4)-(37,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (37,9)-(37,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (37,9)-(37,12) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (37,12)-(37,13) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (39,0)-(39,19))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ CallNode (location: (39,0)-(39,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (39,0)-(39,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (39,3)-(39,13) = "[bar, baz]"
+ │ ├── opening_loc: (39,3)-(39,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (39,4)-(39,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ CallNode (location: (39,4)-(39,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (39,4)-(39,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── @ CallNode (location: (39,9)-(39,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (39,9)-(39,12) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (39,16)-(39,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :qux
+ │ │ ├── message_loc: (39,16)-(39,19) = "qux"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (39,12)-(39,13) = "]"
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (41,0)-(41,21))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ IndexTargetNode (location: (41,0)-(41,6))
+ │ │ │ ├── flags: attribute_write
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (41,0)-(41,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (41,0)-(41,3) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (41,3)-(41,4) = "["
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (41,4)-(41,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (41,4)-(41,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 0
+ │ │ │ ├── closing_loc: (41,5)-(41,6) = "]"
+ │ │ │ └── block: ∅
+ │ │ └── @ IndexTargetNode (location: (41,8)-(41,14))
+ │ │ ├── flags: attribute_write
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (41,8)-(41,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (41,8)-(41,11) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (41,11)-(41,12) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (41,12)-(41,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (41,12)-(41,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 0
+ │ │ ├── closing_loc: (41,13)-(41,14) = "]"
+ │ │ └── block: ∅
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (41,15)-(41,16) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (41,17)-(41,21))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (41,17)-(41,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (41,20)-(41,21))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ CallNode (location: (43,0)-(43,19))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (43,0)-(43,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (43,0)-(43,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (43,3)-(43,19) = "[bar[baz] = qux]"
+ │ ├── opening_loc: (43,3)-(43,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (43,4)-(43,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (43,4)-(43,18))
+ │ │ ├── flags: attribute_write
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (43,4)-(43,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (43,4)-(43,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]=
+ │ │ ├── message_loc: (43,7)-(43,12) = "[baz]"
+ │ │ ├── opening_loc: (43,7)-(43,8) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (43,8)-(43,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ CallNode (location: (43,8)-(43,11))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (43,8)-(43,11) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── @ CallNode (location: (43,15)-(43,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :qux
+ │ │ │ ├── message_loc: (43,15)-(43,18) = "qux"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (43,11)-(43,12) = "]"
+ │ │ └── block: ∅
+ │ ├── closing_loc: (43,18)-(43,19) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (45,0)-(45,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (45,0)-(45,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (45,0)-(45,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (45,3)-(45,8) = "[bar]"
+ │ ├── opening_loc: (45,3)-(45,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (45,4)-(45,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (45,4)-(45,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (45,4)-(45,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (45,7)-(45,8) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (47,0)-(47,14))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ CallNode (location: (47,0)-(47,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (47,0)-(47,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (47,3)-(47,8) = "[bar]"
+ │ ├── opening_loc: (47,3)-(47,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (47,4)-(47,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (47,4)-(47,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (47,4)-(47,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (47,11)-(47,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (47,11)-(47,14) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (47,7)-(47,8) = "]"
+ │ └── block: ∅
+ ├── @ ArrayNode (location: (49,0)-(49,6))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (49,1)-(49,5))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (49,1)-(49,5))
+ │ │ ├── value:
+ │ │ │ @ HashNode (location: (49,3)-(49,5))
+ │ │ │ ├── opening_loc: (49,3)-(49,4) = "{"
+ │ │ │ ├── elements: (length: 0)
+ │ │ │ └── closing_loc: (49,4)-(49,5) = "}"
+ │ │ └── operator_loc: (49,1)-(49,3) = "**"
+ │ ├── opening_loc: (49,0)-(49,1) = "["
+ │ └── closing_loc: (49,5)-(49,6) = "]"
+ ├── @ ArrayNode (location: (51,0)-(51,6))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (51,1)-(51,5))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (51,1)-(51,5))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (51,3)-(51,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :kw
+ │ │ │ ├── message_loc: (51,3)-(51,5) = "kw"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (51,1)-(51,3) = "**"
+ │ ├── opening_loc: (51,0)-(51,1) = "["
+ │ └── closing_loc: (51,5)-(51,6) = "]"
+ ├── @ ArrayNode (location: (53,0)-(53,9))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (53,1)-(53,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ KeywordHashNode (location: (53,4)-(53,8))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (53,4)-(53,8))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (53,6)-(53,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :kw
+ │ │ │ ├── message_loc: (53,6)-(53,8) = "kw"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (53,4)-(53,6) = "**"
+ │ ├── opening_loc: (53,0)-(53,1) = "["
+ │ └── closing_loc: (53,8)-(53,9) = "]"
+ ├── @ ArrayNode (location: (55,0)-(55,21))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (55,1)-(55,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ KeywordHashNode (location: (55,4)-(55,20))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 3)
+ │ │ ├── @ AssocSplatNode (location: (55,4)-(55,8))
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (55,6)-(55,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :kw
+ │ │ │ │ ├── message_loc: (55,6)-(55,8) = "kw"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (55,4)-(55,6) = "**"
+ │ │ ├── @ AssocSplatNode (location: (55,10)-(55,14))
+ │ │ │ ├── value:
+ │ │ │ │ @ HashNode (location: (55,12)-(55,14))
+ │ │ │ │ ├── opening_loc: (55,12)-(55,13) = "{"
+ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ └── closing_loc: (55,13)-(55,14) = "}"
+ │ │ │ └── operator_loc: (55,10)-(55,12) = "**"
+ │ │ └── @ AssocSplatNode (location: (55,16)-(55,20))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (55,18)-(55,20))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :kw
+ │ │ │ ├── message_loc: (55,18)-(55,20) = "kw"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (55,16)-(55,18) = "**"
+ │ ├── opening_loc: (55,0)-(55,1) = "["
+ │ └── closing_loc: (55,20)-(55,21) = "]"
+ ├── @ ArrayNode (location: (57,0)-(59,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (58,2)-(58,12))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (58,2)-(58,12))
+ │ │ ├── key:
+ │ │ │ @ CallNode (location: (58,2)-(58,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (58,2)-(58,5) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (58,9)-(58,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (58,9)-(58,12) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (58,6)-(58,8) = "=>"
+ │ ├── opening_loc: (57,0)-(57,1) = "["
+ │ └── closing_loc: (59,0)-(59,1) = "]"
+ ├── @ ArrayNode (location: (62,0)-(62,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ SymbolNode (location: (62,3)-(62,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (62,3)-(62,6) = "one"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "one"
+ │ │ ├── @ SymbolNode (location: (62,7)-(62,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (62,7)-(62,10) = "two"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "two"
+ │ │ └── @ SymbolNode (location: (62,11)-(62,16))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (62,11)-(62,16) = "three"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "three"
+ │ ├── opening_loc: (62,0)-(62,3) = "%i#"
+ │ └── closing_loc: (62,16)-(62,17) = "#"
+ ├── @ ArrayNode (location: (64,0)-(64,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (64,3)-(64,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (64,3)-(64,6) = "one"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "one"
+ │ │ ├── @ StringNode (location: (64,7)-(64,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (64,7)-(64,10) = "two"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "two"
+ │ │ └── @ StringNode (location: (64,11)-(64,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (64,11)-(64,16) = "three"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "three"
+ │ ├── opening_loc: (64,0)-(64,3) = "%w#"
+ │ └── closing_loc: (64,16)-(64,17) = "#"
+ ├── @ XStringNode (location: (66,0)-(66,17))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (66,0)-(66,3) = "%x#"
+ │ ├── content_loc: (66,3)-(66,16) = "one two three"
+ │ ├── closing_loc: (66,16)-(66,17) = "#"
+ │ └── unescaped: "one two three"
+ ├── @ ArrayNode (location: (69,0)-(69,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ SymbolNode (location: (69,3)-(69,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (69,3)-(69,6) = "one"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "one"
+ │ │ ├── @ SymbolNode (location: (69,7)-(69,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (69,7)-(69,10) = "two"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "two"
+ │ │ └── @ SymbolNode (location: (69,11)-(69,16))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (69,11)-(69,16) = "three"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "three"
+ │ ├── opening_loc: (69,0)-(69,3) = "%i@"
+ │ └── closing_loc: (69,16)-(69,17) = "@"
+ ├── @ ArrayNode (location: (71,0)-(71,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (71,3)-(71,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (71,3)-(71,6) = "one"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "one"
+ │ │ ├── @ StringNode (location: (71,7)-(71,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (71,7)-(71,10) = "two"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "two"
+ │ │ └── @ StringNode (location: (71,11)-(71,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (71,11)-(71,16) = "three"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "three"
+ │ ├── opening_loc: (71,0)-(71,3) = "%w@"
+ │ └── closing_loc: (71,16)-(71,17) = "@"
+ ├── @ XStringNode (location: (73,0)-(73,17))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (73,0)-(73,3) = "%x@"
+ │ ├── content_loc: (73,3)-(73,16) = "one two three"
+ │ ├── closing_loc: (73,16)-(73,17) = "@"
+ │ └── unescaped: "one two three"
+ ├── @ ArrayNode (location: (76,0)-(76,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ SymbolNode (location: (76,3)-(76,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (76,3)-(76,6) = "one"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "one"
+ │ │ ├── @ SymbolNode (location: (76,7)-(76,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (76,7)-(76,10) = "two"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "two"
+ │ │ └── @ SymbolNode (location: (76,11)-(76,16))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (76,11)-(76,16) = "three"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "three"
+ │ ├── opening_loc: (76,0)-(76,3) = "%i{"
+ │ └── closing_loc: (76,16)-(76,17) = "}"
+ ├── @ ArrayNode (location: (78,0)-(78,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (78,3)-(78,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (78,3)-(78,6) = "one"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "one"
+ │ │ ├── @ StringNode (location: (78,7)-(78,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (78,7)-(78,10) = "two"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "two"
+ │ │ └── @ StringNode (location: (78,11)-(78,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (78,11)-(78,16) = "three"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "three"
+ │ ├── opening_loc: (78,0)-(78,3) = "%w{"
+ │ └── closing_loc: (78,16)-(78,17) = "}"
+ ├── @ XStringNode (location: (80,0)-(80,17))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (80,0)-(80,3) = "%x{"
+ │ ├── content_loc: (80,3)-(80,16) = "one two three"
+ │ ├── closing_loc: (80,16)-(80,17) = "}"
+ │ └── unescaped: "one two three"
+ ├── @ ArrayNode (location: (82,0)-(82,7))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (82,3)-(82,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (82,3)-(82,6) = "\\C:"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\\C:"
+ │ ├── opening_loc: (82,0)-(82,3) = "%w["
+ │ └── closing_loc: (82,6)-(82,7) = "]"
+ ├── @ IndexOperatorWriteNode (location: (84,0)-(84,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (84,0)-(84,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (84,0)-(84,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (84,3)-(84,4) = "["
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (84,4)-(84,5) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :+
+ │ ├── operator_loc: (84,6)-(84,8) = "+="
+ │ └── value:
+ │ @ IntegerNode (location: (84,9)-(84,10))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexOrWriteNode (location: (86,0)-(86,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (86,0)-(86,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (86,0)-(86,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (86,3)-(86,4) = "["
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (86,4)-(86,5) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (86,6)-(86,9) = "||="
+ │ └── value:
+ │ @ IntegerNode (location: (86,10)-(86,11))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexAndWriteNode (location: (88,0)-(88,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (88,0)-(88,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (88,0)-(88,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (88,3)-(88,4) = "["
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (88,4)-(88,5) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (88,6)-(88,9) = "&&="
+ │ └── value:
+ │ @ IntegerNode (location: (88,10)-(88,11))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexOperatorWriteNode (location: (90,0)-(90,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (90,0)-(90,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (90,0)-(90,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (90,0)-(90,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (90,3)-(90,4) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (90,4)-(90,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (90,7)-(90,8) = "["
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (90,8)-(90,9) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :+
+ │ ├── operator_loc: (90,10)-(90,12) = "+="
+ │ └── value:
+ │ @ IntegerNode (location: (90,13)-(90,14))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexOrWriteNode (location: (92,0)-(92,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (92,0)-(92,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (92,0)-(92,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (92,0)-(92,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (92,3)-(92,4) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (92,4)-(92,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (92,7)-(92,8) = "["
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (92,8)-(92,9) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (92,10)-(92,13) = "||="
+ │ └── value:
+ │ @ IntegerNode (location: (92,14)-(92,15))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexAndWriteNode (location: (94,0)-(94,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (94,0)-(94,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (94,0)-(94,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (94,0)-(94,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (94,3)-(94,4) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (94,4)-(94,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (94,7)-(94,8) = "["
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (94,8)-(94,9) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (94,10)-(94,13) = "&&="
+ │ └── value:
+ │ @ IntegerNode (location: (94,14)-(94,15))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexOperatorWriteNode (location: (96,0)-(96,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (96,0)-(96,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (96,0)-(96,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (96,3)-(96,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (96,4)-(96,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (96,4)-(96,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (96,4)-(96,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (96,7)-(96,8) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :+
+ │ ├── operator_loc: (96,9)-(96,11) = "+="
+ │ └── value:
+ │ @ IntegerNode (location: (96,12)-(96,13))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexOrWriteNode (location: (98,0)-(98,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (98,0)-(98,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (98,0)-(98,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (98,3)-(98,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (98,4)-(98,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (98,4)-(98,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (98,4)-(98,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (98,7)-(98,8) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (98,9)-(98,12) = "||="
+ │ └── value:
+ │ @ IntegerNode (location: (98,13)-(98,14))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexAndWriteNode (location: (100,0)-(100,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (100,0)-(100,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (100,0)-(100,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (100,3)-(100,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (100,4)-(100,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (100,4)-(100,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (100,4)-(100,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (100,7)-(100,8) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (100,9)-(100,12) = "&&="
+ │ └── value:
+ │ @ IntegerNode (location: (100,13)-(100,14))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexOperatorWriteNode (location: (102,0)-(102,17))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (102,0)-(102,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (102,0)-(102,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (102,0)-(102,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (102,3)-(102,4) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (102,4)-(102,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (102,7)-(102,8) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (102,8)-(102,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (102,8)-(102,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (102,8)-(102,11) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (102,11)-(102,12) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :+
+ │ ├── operator_loc: (102,13)-(102,15) = "+="
+ │ └── value:
+ │ @ IntegerNode (location: (102,16)-(102,17))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexOrWriteNode (location: (104,0)-(104,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (104,0)-(104,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (104,0)-(104,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (104,0)-(104,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (104,3)-(104,4) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (104,4)-(104,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (104,7)-(104,8) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (104,8)-(104,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (104,8)-(104,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (104,8)-(104,11) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (104,11)-(104,12) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (104,13)-(104,16) = "||="
+ │ └── value:
+ │ @ IntegerNode (location: (104,17)-(104,18))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IndexAndWriteNode (location: (106,0)-(106,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (106,0)-(106,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (106,0)-(106,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (106,0)-(106,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (106,3)-(106,4) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (106,4)-(106,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (106,7)-(106,8) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (106,8)-(106,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (106,8)-(106,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (106,8)-(106,11) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (106,11)-(106,12) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (106,13)-(106,16) = "&&="
+ │ └── value:
+ │ @ IntegerNode (location: (106,17)-(106,18))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ DefNode (location: (108,0)-(108,19))
+ │ ├── name: :f
+ │ ├── name_loc: (108,4)-(108,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (108,6)-(108,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (108,6)-(108,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (108,6)-(108,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (108,10)-(108,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (108,10)-(108,14))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (108,10)-(108,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (108,10)-(108,11) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]
+ │ │ ├── message_loc: (108,11)-(108,14) = "[*]"
+ │ │ ├── opening_loc: (108,11)-(108,12) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (108,12)-(108,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SplatNode (location: (108,12)-(108,13))
+ │ │ │ ├── operator_loc: (108,12)-(108,13) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── closing_loc: (108,13)-(108,14) = "]"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (108,0)-(108,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (108,5)-(108,6) = "("
+ │ ├── rparen_loc: (108,7)-(108,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (108,16)-(108,19) = "end"
+ ├── @ DefNode (location: (110,0)-(110,22))
+ │ ├── name: :f
+ │ ├── name_loc: (110,4)-(110,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (110,6)-(110,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (110,6)-(110,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (110,6)-(110,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (110,10)-(110,17))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (110,10)-(110,17))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (110,10)-(110,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (110,10)-(110,11) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]
+ │ │ ├── message_loc: (110,11)-(110,17) = "[1, *]"
+ │ │ ├── opening_loc: (110,11)-(110,12) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (110,12)-(110,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (110,12)-(110,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ SplatNode (location: (110,15)-(110,16))
+ │ │ │ ├── operator_loc: (110,15)-(110,16) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── closing_loc: (110,16)-(110,17) = "]"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (110,0)-(110,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (110,5)-(110,6) = "("
+ │ ├── rparen_loc: (110,7)-(110,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (110,19)-(110,22) = "end"
+ ├── @ DefNode (location: (112,0)-(112,23))
+ │ ├── name: :f
+ │ ├── name_loc: (112,4)-(112,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (112,6)-(112,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (112,6)-(112,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (112,6)-(112,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (112,10)-(112,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (112,10)-(112,18))
+ │ │ ├── flags: attribute_write
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (112,10)-(112,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (112,10)-(112,11) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]=
+ │ │ ├── message_loc: (112,11)-(112,14) = "[*]"
+ │ │ ├── opening_loc: (112,11)-(112,12) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (112,12)-(112,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ SplatNode (location: (112,12)-(112,13))
+ │ │ │ │ ├── operator_loc: (112,12)-(112,13) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ └── @ IntegerNode (location: (112,17)-(112,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: (112,13)-(112,14) = "]"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (112,0)-(112,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (112,5)-(112,6) = "("
+ │ ├── rparen_loc: (112,7)-(112,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (112,20)-(112,23) = "end"
+ ├── @ DefNode (location: (114,0)-(114,26))
+ │ ├── name: :f
+ │ ├── name_loc: (114,4)-(114,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (114,6)-(114,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (114,6)-(114,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (114,6)-(114,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (114,10)-(114,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (114,10)-(114,21))
+ │ │ ├── flags: attribute_write
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (114,10)-(114,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (114,10)-(114,11) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]=
+ │ │ ├── message_loc: (114,11)-(114,17) = "[1, *]"
+ │ │ ├── opening_loc: (114,11)-(114,12) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (114,12)-(114,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (114,12)-(114,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ SplatNode (location: (114,15)-(114,16))
+ │ │ │ │ ├── operator_loc: (114,15)-(114,16) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ └── @ IntegerNode (location: (114,20)-(114,21))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: (114,16)-(114,17) = "]"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (114,0)-(114,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (114,5)-(114,6) = "("
+ │ ├── rparen_loc: (114,7)-(114,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (114,23)-(114,26) = "end"
+ ├── @ DefNode (location: (116,0)-(116,24))
+ │ ├── name: :f
+ │ ├── name_loc: (116,4)-(116,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (116,6)-(116,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (116,6)-(116,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (116,6)-(116,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (116,10)-(116,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IndexOperatorWriteNode (location: (116,10)-(116,19))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (116,10)-(116,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (116,10)-(116,11) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── opening_loc: (116,11)-(116,12) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (116,12)-(116,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SplatNode (location: (116,12)-(116,13))
+ │ │ │ ├── operator_loc: (116,12)-(116,13) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── closing_loc: (116,13)-(116,14) = "]"
+ │ │ ├── block: ∅
+ │ │ ├── operator: :+
+ │ │ ├── operator_loc: (116,15)-(116,17) = "+="
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (116,18)-(116,19))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (116,0)-(116,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (116,5)-(116,6) = "("
+ │ ├── rparen_loc: (116,7)-(116,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (116,21)-(116,24) = "end"
+ ├── @ DefNode (location: (118,0)-(118,28))
+ │ ├── name: :f
+ │ ├── name_loc: (118,4)-(118,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (118,6)-(118,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (118,6)-(118,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (118,6)-(118,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (118,10)-(118,23))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IndexAndWriteNode (location: (118,10)-(118,23))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (118,10)-(118,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (118,10)-(118,11) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── opening_loc: (118,11)-(118,12) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (118,12)-(118,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (118,12)-(118,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ SplatNode (location: (118,15)-(118,16))
+ │ │ │ ├── operator_loc: (118,15)-(118,16) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── closing_loc: (118,16)-(118,17) = "]"
+ │ │ ├── block: ∅
+ │ │ ├── operator_loc: (118,18)-(118,21) = "&&="
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (118,22)-(118,23))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (118,0)-(118,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (118,5)-(118,6) = "("
+ │ ├── rparen_loc: (118,7)-(118,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (118,25)-(118,28) = "end"
+ ├── @ DefNode (location: (120,0)-(120,29))
+ │ ├── name: :f
+ │ ├── name_loc: (120,4)-(120,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (120,6)-(120,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (120,6)-(120,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (120,6)-(120,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (120,0)-(120,29))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (120,10)-(120,24))
+ │ │ │ ├── keyword_loc: (120,10)-(120,16) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: (120,17)-(120,19) = "=>"
+ │ │ │ ├── reference:
+ │ │ │ │ @ IndexTargetNode (location: (120,20)-(120,24))
+ │ │ │ │ ├── flags: attribute_write
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ CallNode (location: (120,20)-(120,21))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ ├── message_loc: (120,20)-(120,21) = "a"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── opening_loc: (120,21)-(120,22) = "["
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (120,22)-(120,23))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ SplatNode (location: (120,22)-(120,23))
+ │ │ │ │ │ ├── operator_loc: (120,22)-(120,23) = "*"
+ │ │ │ │ │ └── expression: ∅
+ │ │ │ │ ├── closing_loc: (120,23)-(120,24) = "]"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (120,26)-(120,29) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (120,0)-(120,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (120,5)-(120,6) = "("
+ │ ├── rparen_loc: (120,7)-(120,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (120,26)-(120,29) = "end"
+ └── @ DefNode (location: (122,0)-(122,32))
+ ├── name: :f
+ ├── name_loc: (122,4)-(122,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (122,6)-(122,7))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (122,6)-(122,7))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (122,6)-(122,7) = "*"
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ BeginNode (location: (122,0)-(122,32))
+ │ ├── begin_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (122,10)-(122,27))
+ │ │ ├── keyword_loc: (122,10)-(122,16) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: (122,17)-(122,19) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ IndexTargetNode (location: (122,20)-(122,27))
+ │ │ │ ├── flags: attribute_write
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (122,20)-(122,21))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (122,20)-(122,21) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (122,21)-(122,22) = "["
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (122,22)-(122,26))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 2)
+ │ │ │ │ ├── @ IntegerNode (location: (122,22)-(122,23))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── @ SplatNode (location: (122,25)-(122,26))
+ │ │ │ │ ├── operator_loc: (122,25)-(122,26) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── closing_loc: (122,26)-(122,27) = "]"
+ │ │ │ └── block: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (122,29)-(122,32) = "end"
+ ├── locals: []
+ ├── def_keyword_loc: (122,0)-(122,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (122,5)-(122,6) = "("
+ ├── rparen_loc: (122,7)-(122,8) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (122,29)-(122,32) = "end"
diff --git a/test/prism/snapshots/begin_ensure.txt b/test/prism/snapshots/begin_ensure.txt
new file mode 100644
index 0000000000..9af9b9e573
--- /dev/null
+++ b/test/prism/snapshots/begin_ensure.txt
@@ -0,0 +1,251 @@
+@ ProgramNode (location: (1,0)-(21,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(21,15))
+ └── body: (length: 5)
+ ├── @ BeginNode (location: (1,0)-(5,3))
+ │ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,0)-(2,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,0)-(2,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (2,0)-(2,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (3,0)-(5,3))
+ │ │ ├── ensure_keyword_loc: (3,0)-(3,6) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (4,0)-(4,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (4,0)-(4,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (4,0)-(4,1) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ BeginNode (location: (7,0)-(7,24))
+ │ ├── begin_keyword_loc: (7,0)-(7,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (7,7)-(7,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (7,7)-(7,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (7,7)-(7,8) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (7,10)-(7,24))
+ │ │ ├── ensure_keyword_loc: (7,10)-(7,16) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (7,18)-(7,19))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (7,18)-(7,19))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (7,18)-(7,19) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (7,21)-(7,24) = "end"
+ │ └── end_keyword_loc: (7,21)-(7,24) = "end"
+ ├── @ BeginNode (location: (9,0)-(11,4))
+ │ ├── begin_keyword_loc: (9,0)-(9,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (9,6)-(9,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (9,6)-(9,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (9,6)-(9,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (10,1)-(11,4))
+ │ │ ├── ensure_keyword_loc: (10,1)-(10,7) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (10,8)-(10,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (10,8)-(10,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (10,8)-(10,9) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (11,1)-(11,4) = "end"
+ │ └── end_keyword_loc: (11,1)-(11,4) = "end"
+ ├── @ BeginNode (location: (13,0)-(13,22))
+ │ ├── begin_keyword_loc: (13,0)-(13,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (13,6)-(13,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (13,6)-(13,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (13,6)-(13,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (13,9)-(13,22))
+ │ │ ├── ensure_keyword_loc: (13,9)-(13,15) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (13,16)-(13,17))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (13,16)-(13,17))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (13,16)-(13,17) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (13,19)-(13,22) = "end"
+ │ └── end_keyword_loc: (13,19)-(13,22) = "end"
+ └── @ BeginNode (location: (15,0)-(21,15))
+ ├── begin_keyword_loc: (15,0)-(15,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (15,6)-(21,11))
+ │ └── body: (length: 1)
+ │ └── @ BeginNode (location: (15,6)-(21,11))
+ │ ├── begin_keyword_loc: (15,6)-(15,11) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (15,11)-(21,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (15,11)-(21,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ SymbolNode (location: (15,11)-(15,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (15,11)-(15,12) = ":"
+ │ │ │ ├── value_loc: (15,12)-(15,13) = "s"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "s"
+ │ │ ├── call_operator_loc: (15,13)-(15,14) = "."
+ │ │ ├── name: :l
+ │ │ ├── message_loc: (15,14)-(15,15) = "l"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (15,16)-(21,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ BeginNode (location: (15,16)-(21,7))
+ │ │ │ ├── begin_keyword_loc: (15,16)-(15,21) = "begin"
+ │ │ │ ├── statements: ∅
+ │ │ │ ├── rescue_clause: ∅
+ │ │ │ ├── else_clause: ∅
+ │ │ │ ├── ensure_clause:
+ │ │ │ │ @ EnsureNode (location: (15,22)-(21,7))
+ │ │ │ │ ├── ensure_keyword_loc: (15,22)-(15,28) = "ensure"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (15,29)-(21,3))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (15,29)-(21,3))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── receiver:
+ │ │ │ │ │ │ @ ConstantReadNode (location: (15,29)-(15,35))
+ │ │ │ │ │ │ └── name: :Module
+ │ │ │ │ │ ├── call_operator_loc: (15,35)-(15,36) = "."
+ │ │ │ │ │ ├── name: :new
+ │ │ │ │ │ ├── message_loc: (15,36)-(15,39) = "new"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (15,40)-(21,3))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body:
+ │ │ │ │ │ │ @ StatementsNode (location: (16,2)-(20,5))
+ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ └── @ BeginNode (location: (16,2)-(20,5))
+ │ │ │ │ │ │ ├── begin_keyword_loc: (16,2)-(16,7) = "begin"
+ │ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ │ @ StatementsNode (location: (17,4)-(17,9))
+ │ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ │ └── @ BreakNode (location: (17,4)-(17,9))
+ │ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ │ └── keyword_loc: (17,4)-(17,9) = "break"
+ │ │ │ │ │ │ ├── rescue_clause: ∅
+ │ │ │ │ │ │ ├── else_clause: ∅
+ │ │ │ │ │ │ ├── ensure_clause:
+ │ │ │ │ │ │ │ @ EnsureNode (location: (18,4)-(20,5))
+ │ │ │ │ │ │ │ ├── ensure_keyword_loc: (18,4)-(18,10) = "ensure"
+ │ │ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ │ │ @ StatementsNode (location: (18,11)-(19,7))
+ │ │ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ │ │ └── @ CallNode (location: (18,11)-(19,7))
+ │ │ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ │ │ ├── receiver:
+ │ │ │ │ │ │ │ │ │ @ ConstantReadNode (location: (18,11)-(18,17))
+ │ │ │ │ │ │ │ │ │ └── name: :Module
+ │ │ │ │ │ │ │ │ ├── call_operator_loc: (18,17)-(18,18) = "."
+ │ │ │ │ │ │ │ │ ├── name: :new
+ │ │ │ │ │ │ │ │ ├── message_loc: (18,18)-(18,21) = "new"
+ │ │ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ │ │ └── block:
+ │ │ │ │ │ │ │ │ @ BlockNode (location: (18,22)-(19,7))
+ │ │ │ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ │ │ │ ├── opening_loc: (18,22)-(18,24) = "do"
+ │ │ │ │ │ │ │ │ └── closing_loc: (19,4)-(19,7) = "end"
+ │ │ │ │ │ │ │ └── end_keyword_loc: (20,2)-(20,5) = "end"
+ │ │ │ │ │ │ └── end_keyword_loc: (20,2)-(20,5) = "end"
+ │ │ │ │ │ ├── opening_loc: (15,40)-(15,42) = "do"
+ │ │ │ │ │ └── closing_loc: (21,0)-(21,3) = "end"
+ │ │ │ │ └── end_keyword_loc: (21,4)-(21,7) = "end"
+ │ │ │ └── end_keyword_loc: (21,4)-(21,7) = "end"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (21,8)-(21,11) = "end"
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (21,12)-(21,15) = "end"
diff --git a/test/prism/snapshots/begin_rescue.txt b/test/prism/snapshots/begin_rescue.txt
new file mode 100644
index 0000000000..f624f85c07
--- /dev/null
+++ b/test/prism/snapshots/begin_rescue.txt
@@ -0,0 +1,699 @@
+@ ProgramNode (location: (1,0)-(78,3))
+├── locals: [:ex]
+└── statements:
+ @ StatementsNode (location: (1,0)-(78,3))
+ └── body: (length: 17)
+ ├── @ BeginNode (location: (1,0)-(1,33))
+ │ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,7)-(1,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,7)-(1,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,7)-(1,8) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (1,10)-(1,19))
+ │ │ ├── keyword_loc: (1,10)-(1,16) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,18)-(1,19))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,18)-(1,19))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,18)-(1,19) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause:
+ │ │ @ ElseNode (location: (1,21)-(1,33))
+ │ │ ├── else_keyword_loc: (1,21)-(1,25) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,27)-(1,28))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,27)-(1,28))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (1,27)-(1,28) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (1,30)-(1,33) = "end"
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (1,30)-(1,33) = "end"
+ ├── @ BeginNode (location: (3,0)-(3,44))
+ │ ├── begin_keyword_loc: (3,0)-(3,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,7)-(3,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,7)-(3,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (3,7)-(3,8) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (3,10)-(3,19))
+ │ │ ├── keyword_loc: (3,10)-(3,16) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,18)-(3,19))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,18)-(3,19))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (3,18)-(3,19) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause:
+ │ │ @ ElseNode (location: (3,21)-(3,36))
+ │ │ ├── else_keyword_loc: (3,21)-(3,25) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,27)-(3,28))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,27)-(3,28))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (3,27)-(3,28) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (3,30)-(3,36) = "ensure"
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (3,30)-(3,44))
+ │ │ ├── ensure_keyword_loc: (3,30)-(3,36) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,38)-(3,39))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,38)-(3,39))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (3,38)-(3,39) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (3,41)-(3,44) = "end"
+ │ └── end_keyword_loc: (3,41)-(3,44) = "end"
+ ├── @ BeginNode (location: (5,0)-(7,3))
+ │ ├── begin_keyword_loc: (5,0)-(5,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (6,0)-(6,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (6,0)-(6,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (6,0)-(6,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (7,0)-(7,3) = "end"
+ ├── @ BeginNode (location: (9,0)-(9,13))
+ │ ├── begin_keyword_loc: (9,0)-(9,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (9,7)-(9,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (9,7)-(9,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (9,7)-(9,8) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (9,10)-(9,13) = "end"
+ ├── @ BeginNode (location: (11,0)-(12,4))
+ │ ├── begin_keyword_loc: (11,0)-(11,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (11,6)-(11,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (11,6)-(11,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (11,6)-(11,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (12,1)-(12,4) = "end"
+ ├── @ BeginNode (location: (14,0)-(14,12))
+ │ ├── begin_keyword_loc: (14,0)-(14,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (14,6)-(14,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (14,6)-(14,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (14,6)-(14,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (14,9)-(14,12) = "end"
+ ├── @ BeginNode (location: (16,0)-(24,3))
+ │ ├── begin_keyword_loc: (16,0)-(16,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (17,0)-(17,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (17,0)-(17,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (17,0)-(17,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (18,0)-(23,1))
+ │ │ ├── keyword_loc: (18,0)-(18,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (19,0)-(19,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (19,0)-(19,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (19,0)-(19,1) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent:
+ │ │ @ RescueNode (location: (20,0)-(23,1))
+ │ │ ├── keyword_loc: (20,0)-(20,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (21,0)-(21,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (21,0)-(21,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (21,0)-(21,1) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent:
+ │ │ @ RescueNode (location: (22,0)-(23,1))
+ │ │ ├── keyword_loc: (22,0)-(22,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (23,0)-(23,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (23,0)-(23,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (23,0)-(23,1) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (24,0)-(24,3) = "end"
+ ├── @ BeginNode (location: (26,0)-(32,3))
+ │ ├── begin_keyword_loc: (26,0)-(26,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (27,2)-(27,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (27,2)-(27,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (27,2)-(27,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (28,0)-(31,3))
+ │ │ ├── keyword_loc: (28,0)-(28,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (28,7)-(28,16))
+ │ │ │ └── name: :Exception
+ │ │ ├── operator_loc: (28,17)-(28,19) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (28,20)-(28,22))
+ │ │ │ ├── name: :ex
+ │ │ │ └── depth: 0
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (29,2)-(29,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (29,2)-(29,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (29,2)-(29,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent:
+ │ │ @ RescueNode (location: (30,0)-(31,3))
+ │ │ ├── keyword_loc: (30,0)-(30,6) = "rescue"
+ │ │ ├── exceptions: (length: 2)
+ │ │ │ ├── @ ConstantReadNode (location: (30,7)-(30,23))
+ │ │ │ │ └── name: :AnotherException
+ │ │ │ └── @ ConstantReadNode (location: (30,25)-(30,41))
+ │ │ │ └── name: :OneMoreException
+ │ │ ├── operator_loc: (30,42)-(30,44) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (30,45)-(30,47))
+ │ │ │ ├── name: :ex
+ │ │ │ └── depth: 0
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (31,2)-(31,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (31,2)-(31,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (31,2)-(31,3) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (32,0)-(32,3) = "end"
+ ├── @ BeginNode (location: (34,0)-(40,3))
+ │ ├── begin_keyword_loc: (34,0)-(34,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (35,2)-(35,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (35,2)-(35,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (35,2)-(35,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (36,0)-(37,3))
+ │ │ ├── keyword_loc: (36,0)-(36,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (36,7)-(36,16))
+ │ │ │ └── name: :Exception
+ │ │ ├── operator_loc: (36,17)-(36,19) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (36,20)-(36,22))
+ │ │ │ ├── name: :ex
+ │ │ │ └── depth: 0
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (37,2)-(37,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (37,2)-(37,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (37,2)-(37,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (38,0)-(40,3))
+ │ │ ├── ensure_keyword_loc: (38,0)-(38,6) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (39,2)-(39,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (39,2)-(39,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (39,2)-(39,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (40,0)-(40,3) = "end"
+ │ └── end_keyword_loc: (40,0)-(40,3) = "end"
+ ├── @ StringNode (location: (42,0)-(42,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (42,0)-(42,2) = "%!"
+ │ ├── content_loc: (42,2)-(42,5) = "abc"
+ │ ├── closing_loc: (42,5)-(42,6) = "!"
+ │ └── unescaped: "abc"
+ ├── @ BeginNode (location: (44,0)-(48,3))
+ │ ├── begin_keyword_loc: (44,0)-(44,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (45,0)-(45,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (45,0)-(45,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (45,0)-(45,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (46,0)-(47,1))
+ │ │ ├── keyword_loc: (46,0)-(46,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (47,0)-(47,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (47,0)-(47,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (47,0)-(47,1) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (48,0)-(48,3) = "end"
+ ├── @ BeginNode (location: (50,0)-(50,20))
+ │ ├── begin_keyword_loc: (50,0)-(50,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (50,6)-(50,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (50,6)-(50,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (50,6)-(50,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (50,8)-(50,16))
+ │ │ ├── keyword_loc: (50,8)-(50,14) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (50,15)-(50,16))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (50,15)-(50,16))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (50,15)-(50,16) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (50,17)-(50,20) = "end"
+ ├── @ BeginNode (location: (52,0)-(54,5))
+ │ ├── begin_keyword_loc: (52,0)-(52,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (53,0)-(53,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (53,0)-(53,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (53,0)-(53,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (53,2)-(54,1))
+ │ │ ├── keyword_loc: (53,2)-(53,8) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (54,0)-(54,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (54,0)-(54,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (54,0)-(54,1) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (54,2)-(54,5) = "end"
+ ├── @ BeginNode (location: (56,0)-(60,3))
+ │ ├── begin_keyword_loc: (56,0)-(56,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (57,0)-(57,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (57,0)-(57,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (57,0)-(57,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (58,0)-(59,1))
+ │ │ ├── keyword_loc: (58,0)-(58,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (58,7)-(58,16))
+ │ │ │ └── name: :Exception
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (59,0)-(59,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (59,0)-(59,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (59,0)-(59,1) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (60,0)-(60,3) = "end"
+ ├── @ BeginNode (location: (62,0)-(66,3))
+ │ ├── begin_keyword_loc: (62,0)-(62,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (63,0)-(63,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (63,0)-(63,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (63,0)-(63,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (64,0)-(65,1))
+ │ │ ├── keyword_loc: (64,0)-(64,6) = "rescue"
+ │ │ ├── exceptions: (length: 2)
+ │ │ │ ├── @ ConstantReadNode (location: (64,7)-(64,16))
+ │ │ │ │ └── name: :Exception
+ │ │ │ └── @ ConstantReadNode (location: (64,18)-(64,33))
+ │ │ │ └── name: :CustomException
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (65,0)-(65,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (65,0)-(65,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (65,0)-(65,1) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (66,0)-(66,3) = "end"
+ ├── @ BeginNode (location: (68,0)-(72,3))
+ │ ├── begin_keyword_loc: (68,0)-(68,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (69,2)-(69,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (69,2)-(69,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (69,2)-(69,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (70,0)-(71,3))
+ │ │ ├── keyword_loc: (70,0)-(70,6) = "rescue"
+ │ │ ├── exceptions: (length: 2)
+ │ │ │ ├── @ ConstantReadNode (location: (70,7)-(70,16))
+ │ │ │ │ └── name: :Exception
+ │ │ │ └── @ ConstantReadNode (location: (70,18)-(70,33))
+ │ │ │ └── name: :CustomException
+ │ │ ├── operator_loc: (70,34)-(70,36) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (70,37)-(70,39))
+ │ │ │ ├── name: :ex
+ │ │ │ └── depth: 0
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (71,2)-(71,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (71,2)-(71,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (71,2)-(71,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (72,0)-(72,3) = "end"
+ └── @ BeginNode (location: (74,0)-(78,3))
+ ├── begin_keyword_loc: (74,0)-(74,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (75,2)-(75,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (75,2)-(75,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (75,2)-(75,3) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (76,0)-(77,3))
+ │ ├── keyword_loc: (76,0)-(76,6) = "rescue"
+ │ ├── exceptions: (length: 1)
+ │ │ └── @ ConstantReadNode (location: (76,7)-(76,16))
+ │ │ └── name: :Exception
+ │ ├── operator_loc: (76,17)-(76,19) = "=>"
+ │ ├── reference:
+ │ │ @ LocalVariableTargetNode (location: (76,20)-(76,22))
+ │ │ ├── name: :ex
+ │ │ └── depth: 0
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (77,2)-(77,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (77,2)-(77,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (77,2)-(77,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (78,0)-(78,3) = "end"
diff --git a/test/prism/snapshots/blocks.txt b/test/prism/snapshots/blocks.txt
new file mode 100644
index 0000000000..0b1ec52e38
--- /dev/null
+++ b/test/prism/snapshots/blocks.txt
@@ -0,0 +1,774 @@
+@ ProgramNode (location: (1,0)-(54,17))
+├── locals: [:fork]
+└── statements:
+ @ StatementsNode (location: (1,0)-(54,17))
+ └── body: (length: 20)
+ ├── @ CallNode (location: (1,0)-(1,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (1,3)-(1,8) = "[bar]"
+ │ ├── opening_loc: (1,3)-(1,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,4)-(1,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (1,7)-(1,8) = "]"
+ │ └── block:
+ │ @ BlockNode (location: (1,9)-(1,16))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,11)-(1,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,11)-(1,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (1,11)-(1,14) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,9)-(1,10) = "{"
+ │ └── closing_loc: (1,15)-(1,16) = "}"
+ ├── @ CallNode (location: (3,0)-(5,3))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (3,3)-(3,8) = "[bar]"
+ │ ├── opening_loc: (3,3)-(3,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,4)-(3,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,4)-(3,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,4)-(3,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (3,7)-(3,8) = "]"
+ │ └── block:
+ │ @ BlockNode (location: (3,9)-(5,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (4,0)-(4,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (4,0)-(4,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (4,0)-(4,3) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (3,9)-(3,11) = "do"
+ │ └── closing_loc: (5,0)-(5,3) = "end"
+ ├── @ CallNode (location: (7,0)-(7,35))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (7,0)-(7,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :x
+ │ │ ├── message_loc: (7,0)-(7,1) = "x"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (7,1)-(7,2) = "."
+ │ ├── name: :reduce
+ │ ├── message_loc: (7,2)-(7,8) = "reduce"
+ │ ├── opening_loc: (7,8)-(7,9) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,9)-(7,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (7,9)-(7,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ ├── closing_loc: (7,10)-(7,11) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (7,12)-(7,35))
+ │ ├── locals: [:x, :memo]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (7,14)-(7,23))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (7,15)-(7,22))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (7,15)-(7,16))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :x
+ │ │ │ │ └── @ RequiredParameterNode (location: (7,18)-(7,22))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :memo
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (7,14)-(7,15) = "|"
+ │ │ └── closing_loc: (7,22)-(7,23) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,24)-(7,33))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableOperatorWriteNode (location: (7,24)-(7,33))
+ │ │ ├── name_loc: (7,24)-(7,28) = "memo"
+ │ │ ├── operator_loc: (7,29)-(7,31) = "+="
+ │ │ ├── value:
+ │ │ │ @ LocalVariableReadNode (location: (7,32)-(7,33))
+ │ │ │ ├── name: :x
+ │ │ │ └── depth: 0
+ │ │ ├── name: :memo
+ │ │ ├── operator: :+
+ │ │ └── depth: 0
+ │ ├── opening_loc: (7,12)-(7,13) = "{"
+ │ └── closing_loc: (7,34)-(7,35) = "}"
+ ├── @ CallNode (location: (9,0)-(9,10))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (9,0)-(9,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (9,4)-(9,10))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (9,4)-(9,6) = "do"
+ │ └── closing_loc: (9,7)-(9,10) = "end"
+ ├── @ CallNode (location: (11,0)-(11,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (11,0)-(11,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,4)-(11,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (11,4)-(11,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (11,4)-(11,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ ParenthesesNode (location: (11,9)-(11,21))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (11,10)-(11,20))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (11,10)-(11,20))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (11,10)-(11,13) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (11,14)-(11,20))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (11,14)-(11,16) = "do"
+ │ │ │ └── closing_loc: (11,17)-(11,20) = "end"
+ │ │ ├── opening_loc: (11,9)-(11,10) = "("
+ │ │ └── closing_loc: (11,20)-(11,21) = ")"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (13,0)-(13,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (13,0)-(13,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,4)-(13,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (13,4)-(13,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (13,4)-(13,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (13,8)-(13,14))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (13,8)-(13,10) = "do"
+ │ └── closing_loc: (13,11)-(13,14) = "end"
+ ├── @ CallNode (location: (15,0)-(15,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (15,0)-(15,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,4)-(15,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (15,4)-(15,11))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (15,4)-(15,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (15,8)-(15,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (15,8)-(15,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (15,8)-(15,11) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (15,12)-(15,18))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (15,12)-(15,14) = "do"
+ │ └── closing_loc: (15,15)-(15,18) = "end"
+ ├── @ CallNode (location: (17,0)-(18,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (17,0)-(17,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (17,4)-(18,3))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (17,7)-(17,17))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (17,8)-(17,16))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (17,8)-(17,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── name_loc: (17,8)-(17,9) = "a"
+ │ │ │ │ ├── operator_loc: (17,10)-(17,11) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ CallNode (location: (17,12)-(17,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ CallNode (location: (17,12)-(17,13))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ ├── message_loc: (17,12)-(17,13) = "b"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :[]
+ │ │ │ │ ├── message_loc: (17,13)-(17,16) = "[1]"
+ │ │ │ │ ├── opening_loc: (17,13)-(17,14) = "["
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (17,14)-(17,15))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (17,14)-(17,15))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── closing_loc: (17,15)-(17,16) = "]"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (17,7)-(17,8) = "|"
+ │ │ └── closing_loc: (17,16)-(17,17) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (17,4)-(17,6) = "do"
+ │ └── closing_loc: (18,0)-(18,3) = "end"
+ ├── @ CallNode (location: (20,0)-(22,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (20,0)-(20,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (20,4)-(22,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (20,4)-(22,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (21,0)-(21,6))
+ │ │ │ ├── keyword_loc: (21,0)-(21,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (22,0)-(22,3) = "end"
+ │ ├── opening_loc: (20,4)-(20,6) = "do"
+ │ └── closing_loc: (22,0)-(22,3) = "end"
+ ├── @ CallNode (location: (24,0)-(29,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (24,0)-(24,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (24,4)-(29,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (25,2)-(28,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (25,2)-(28,5))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (25,2)-(25,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (25,6)-(28,5))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (26,4)-(27,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (26,4)-(27,7))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (26,4)-(26,7) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (26,8)-(27,7))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (26,8)-(26,10) = "do"
+ │ │ │ └── closing_loc: (27,4)-(27,7) = "end"
+ │ │ ├── opening_loc: (25,6)-(25,8) = "do"
+ │ │ └── closing_loc: (28,2)-(28,5) = "end"
+ │ ├── opening_loc: (24,4)-(24,6) = "do"
+ │ └── closing_loc: (29,0)-(29,3) = "end"
+ ├── @ CallNode (location: (31,0)-(31,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (31,0)-(31,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (31,0)-(31,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (31,3)-(31,8) = "[bar]"
+ │ ├── opening_loc: (31,3)-(31,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,4)-(31,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (31,4)-(31,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (31,4)-(31,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (31,7)-(31,8) = "]"
+ │ └── block:
+ │ @ BlockNode (location: (31,9)-(31,16))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (31,11)-(31,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (31,11)-(31,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (31,11)-(31,14) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (31,9)-(31,10) = "{"
+ │ └── closing_loc: (31,15)-(31,16) = "}"
+ ├── @ CallNode (location: (33,0)-(33,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (33,0)-(33,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (33,4)-(33,24))
+ │ ├── locals: [:x, :y, :z]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (33,6)-(33,20))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (33,7)-(33,19))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (33,7)-(33,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :x
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (33,10)-(33,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :y
+ │ │ │ │ ├── name_loc: (33,10)-(33,11) = "y"
+ │ │ │ │ ├── operator_loc: (33,12)-(33,13) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (33,14)-(33,15))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 1)
+ │ │ │ │ └── @ RequiredKeywordParameterNode (location: (33,17)-(33,19))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :z
+ │ │ │ │ └── name_loc: (33,17)-(33,19) = "z:"
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (33,6)-(33,7) = "|"
+ │ │ └── closing_loc: (33,19)-(33,20) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (33,21)-(33,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (33,21)-(33,22))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── opening_loc: (33,4)-(33,5) = "{"
+ │ └── closing_loc: (33,23)-(33,24) = "}"
+ ├── @ CallNode (location: (35,0)-(35,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (35,0)-(35,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (35,4)-(35,11))
+ │ ├── locals: [:x]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (35,6)-(35,9))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (35,7)-(35,8))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (35,7)-(35,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :x
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (35,6)-(35,7) = "|"
+ │ │ └── closing_loc: (35,8)-(35,9) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (35,4)-(35,5) = "{"
+ │ └── closing_loc: (35,10)-(35,11) = "}"
+ ├── @ LocalVariableWriteNode (location: (37,0)-(37,8))
+ │ ├── name: :fork
+ │ ├── depth: 0
+ │ ├── name_loc: (37,0)-(37,4) = "fork"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (37,7)-(37,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (37,5)-(37,6) = "="
+ ├── @ CallNode (location: (38,0)-(39,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fork
+ │ ├── message_loc: (38,0)-(38,4) = "fork"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (38,5)-(39,3))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (38,8)-(38,11))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (38,9)-(38,10))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (38,9)-(38,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (38,8)-(38,9) = "|"
+ │ │ └── closing_loc: (38,10)-(38,11) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (38,5)-(38,7) = "do"
+ │ └── closing_loc: (39,0)-(39,3) = "end"
+ ├── @ CallNode (location: (41,0)-(41,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fork
+ │ ├── message_loc: (41,0)-(41,4) = "fork"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (41,5)-(41,12))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (41,7)-(41,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (41,8)-(41,9))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (41,8)-(41,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (41,7)-(41,8) = "|"
+ │ │ └── closing_loc: (41,9)-(41,10) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (41,5)-(41,6) = "{"
+ │ └── closing_loc: (41,11)-(41,12) = "}"
+ ├── @ CallNode (location: (43,0)-(44,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :C
+ │ ├── message_loc: (43,0)-(43,1) = "C"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (43,2)-(44,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (43,2)-(43,4) = "do"
+ │ └── closing_loc: (44,0)-(44,3) = "end"
+ ├── @ CallNode (location: (46,0)-(46,4))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :C
+ │ ├── message_loc: (46,0)-(46,1) = "C"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (46,2)-(46,4))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (46,2)-(46,3) = "{"
+ │ └── closing_loc: (46,3)-(46,4) = "}"
+ ├── @ CallNode (location: (48,0)-(52,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (48,0)-(48,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (48,4)-(52,1))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (48,4)-(52,1))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :lambda
+ │ │ ├── message_loc: (48,4)-(48,10) = "lambda"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (48,11)-(52,1))
+ │ │ ├── locals: [:a, :b]
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (48,13)-(51,3))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (49,2)-(50,6))
+ │ │ │ │ ├── requireds: (length: 0)
+ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 2)
+ │ │ │ │ │ ├── @ OptionalKeywordParameterNode (location: (49,2)-(49,6))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ │ ├── name_loc: (49,2)-(49,4) = "a:"
+ │ │ │ │ │ │ └── value:
+ │ │ │ │ │ │ @ IntegerNode (location: (49,5)-(49,6))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 1
+ │ │ │ │ │ └── @ OptionalKeywordParameterNode (location: (50,2)-(50,6))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ ├── name_loc: (50,2)-(50,4) = "b:"
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ IntegerNode (location: (50,5)-(50,6))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (48,13)-(48,14) = "|"
+ │ │ │ └── closing_loc: (51,2)-(51,3) = "|"
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (48,11)-(48,12) = "{"
+ │ │ └── closing_loc: (52,0)-(52,1) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (54,0)-(54,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (54,0)-(54,3) = "foo"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (54,4)-(54,17))
+ ├── locals: [:bar]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (54,7)-(54,13))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (54,8)-(54,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (54,8)-(54,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :bar
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ ImplicitRestNode (location: (54,11)-(54,12))
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (54,7)-(54,8) = "|"
+ │ └── closing_loc: (54,12)-(54,13) = "|"
+ ├── body: ∅
+ ├── opening_loc: (54,4)-(54,6) = "do"
+ └── closing_loc: (54,14)-(54,17) = "end"
diff --git a/test/prism/snapshots/boolean_operators.txt b/test/prism/snapshots/boolean_operators.txt
new file mode 100644
index 0000000000..ace8047e18
--- /dev/null
+++ b/test/prism/snapshots/boolean_operators.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(5,7))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,7))
+ └── body: (length: 3)
+ ├── @ LocalVariableAndWriteNode (location: (1,0)-(1,7))
+ │ ├── name_loc: (1,0)-(1,1) = "a"
+ │ ├── operator_loc: (1,2)-(1,5) = "&&="
+ │ ├── value:
+ │ │ @ CallNode (location: (1,6)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,6)-(1,7) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,6))
+ │ ├── name_loc: (3,0)-(3,1) = "a"
+ │ ├── operator_loc: (3,2)-(3,4) = "+="
+ │ ├── value:
+ │ │ @ CallNode (location: (3,5)-(3,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (3,5)-(3,6) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── name: :a
+ │ ├── operator: :+
+ │ └── depth: 0
+ └── @ LocalVariableOrWriteNode (location: (5,0)-(5,7))
+ ├── name_loc: (5,0)-(5,1) = "a"
+ ├── operator_loc: (5,2)-(5,5) = "||="
+ ├── value:
+ │ @ CallNode (location: (5,6)-(5,7))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (5,6)-(5,7) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── name: :a
+ └── depth: 0
diff --git a/test/prism/snapshots/booleans.txt b/test/prism/snapshots/booleans.txt
new file mode 100644
index 0000000000..4731966243
--- /dev/null
+++ b/test/prism/snapshots/booleans.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(3,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,4))
+ └── body: (length: 2)
+ ├── @ FalseNode (location: (1,0)-(1,5))
+ └── @ TrueNode (location: (3,0)-(3,4))
diff --git a/test/prism/snapshots/break.txt b/test/prism/snapshots/break.txt
new file mode 100644
index 0000000000..c15a9e4675
--- /dev/null
+++ b/test/prism/snapshots/break.txt
@@ -0,0 +1,401 @@
+@ ProgramNode (location: (1,0)-(25,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(25,23))
+ └── body: (length: 11)
+ ├── @ CallNode (location: (1,0)-(1,13))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (1,0)-(1,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,4)-(1,13))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,6)-(1,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (1,6)-(1,11))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (1,6)-(1,11) = "break"
+ │ ├── opening_loc: (1,4)-(1,5) = "{"
+ │ └── closing_loc: (1,12)-(1,13) = "}"
+ ├── @ CallNode (location: (3,0)-(3,27))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (3,0)-(3,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,4)-(3,27))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,6)-(3,25))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (3,6)-(3,25))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,12)-(3,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 3)
+ │ │ │ ├── @ ParenthesesNode (location: (3,12)-(3,15))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (3,13)-(3,14))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (3,13)-(3,14))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── opening_loc: (3,12)-(3,13) = "("
+ │ │ │ │ └── closing_loc: (3,14)-(3,15) = ")"
+ │ │ │ ├── @ ParenthesesNode (location: (3,17)-(3,20))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (3,18)-(3,19))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (3,18)-(3,19))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ ├── opening_loc: (3,17)-(3,18) = "("
+ │ │ │ │ └── closing_loc: (3,19)-(3,20) = ")"
+ │ │ │ └── @ ParenthesesNode (location: (3,22)-(3,25))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (3,23)-(3,24))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (3,23)-(3,24))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 3
+ │ │ │ ├── opening_loc: (3,22)-(3,23) = "("
+ │ │ │ └── closing_loc: (3,24)-(3,25) = ")"
+ │ │ └── keyword_loc: (3,6)-(3,11) = "break"
+ │ ├── opening_loc: (3,4)-(3,5) = "{"
+ │ └── closing_loc: (3,26)-(3,27) = "}"
+ ├── @ CallNode (location: (5,0)-(5,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (5,0)-(5,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,4)-(5,15))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,6)-(5,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (5,6)-(5,13))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,12)-(5,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,12)-(5,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── keyword_loc: (5,6)-(5,11) = "break"
+ │ ├── opening_loc: (5,4)-(5,5) = "{"
+ │ └── closing_loc: (5,14)-(5,15) = "}"
+ ├── @ CallNode (location: (7,0)-(8,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (7,0)-(7,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (7,4)-(8,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,6)-(8,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (7,6)-(8,1))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,12)-(8,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (7,12)-(7,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ IntegerNode (location: (7,15)-(7,16))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (8,0)-(8,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ └── keyword_loc: (7,6)-(7,11) = "break"
+ │ ├── opening_loc: (7,4)-(7,5) = "{"
+ │ └── closing_loc: (8,2)-(8,3) = "}"
+ ├── @ CallNode (location: (10,0)-(10,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (10,0)-(10,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (10,4)-(10,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (10,6)-(10,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (10,6)-(10,19))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (10,12)-(10,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (10,12)-(10,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ IntegerNode (location: (10,15)-(10,16))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (10,18)-(10,19))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ └── keyword_loc: (10,6)-(10,11) = "break"
+ │ ├── opening_loc: (10,4)-(10,5) = "{"
+ │ └── closing_loc: (10,20)-(10,21) = "}"
+ ├── @ CallNode (location: (12,0)-(12,23))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (12,0)-(12,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (12,4)-(12,23))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (12,6)-(12,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (12,6)-(12,21))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (12,12)-(12,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ArrayNode (location: (12,12)-(12,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 3)
+ │ │ │ │ ├── @ IntegerNode (location: (12,13)-(12,14))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── @ IntegerNode (location: (12,16)-(12,17))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ └── @ IntegerNode (location: (12,19)-(12,20))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 3
+ │ │ │ ├── opening_loc: (12,12)-(12,13) = "["
+ │ │ │ └── closing_loc: (12,20)-(12,21) = "]"
+ │ │ └── keyword_loc: (12,6)-(12,11) = "break"
+ │ ├── opening_loc: (12,4)-(12,5) = "{"
+ │ └── closing_loc: (12,22)-(12,23) = "}"
+ ├── @ CallNode (location: (14,0)-(17,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (14,0)-(14,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (14,4)-(17,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (14,6)-(17,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (14,6)-(17,1))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (14,11)-(17,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ParenthesesNode (location: (14,11)-(17,1))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (15,2)-(16,3))
+ │ │ │ │ └── body: (length: 2)
+ │ │ │ │ ├── @ IntegerNode (location: (15,2)-(15,3))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── @ IntegerNode (location: (16,2)-(16,3))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── opening_loc: (14,11)-(14,12) = "("
+ │ │ │ └── closing_loc: (17,0)-(17,1) = ")"
+ │ │ └── keyword_loc: (14,6)-(14,11) = "break"
+ │ ├── opening_loc: (14,4)-(14,5) = "{"
+ │ └── closing_loc: (17,2)-(17,3) = "}"
+ ├── @ CallNode (location: (19,0)-(19,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (19,0)-(19,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (19,4)-(19,15))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (19,6)-(19,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (19,6)-(19,13))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (19,11)-(19,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ParenthesesNode (location: (19,11)-(19,13))
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (19,11)-(19,12) = "("
+ │ │ │ └── closing_loc: (19,12)-(19,13) = ")"
+ │ │ └── keyword_loc: (19,6)-(19,11) = "break"
+ │ ├── opening_loc: (19,4)-(19,5) = "{"
+ │ └── closing_loc: (19,14)-(19,15) = "}"
+ ├── @ CallNode (location: (21,0)-(21,16))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (21,0)-(21,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (21,4)-(21,16))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (21,6)-(21,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (21,6)-(21,14))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (21,11)-(21,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ParenthesesNode (location: (21,11)-(21,14))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (21,12)-(21,13))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (21,12)-(21,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── opening_loc: (21,11)-(21,12) = "("
+ │ │ │ └── closing_loc: (21,13)-(21,14) = ")"
+ │ │ └── keyword_loc: (21,6)-(21,11) = "break"
+ │ ├── opening_loc: (21,4)-(21,5) = "{"
+ │ └── closing_loc: (21,15)-(21,16) = "}"
+ ├── @ CallNode (location: (23,0)-(23,22))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (23,0)-(23,16))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (23,0)-(23,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (23,4)-(23,16))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (23,6)-(23,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ BreakNode (location: (23,6)-(23,14))
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (23,12)-(23,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (23,12)-(23,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── keyword_loc: (23,6)-(23,11) = "break"
+ │ │ ├── opening_loc: (23,4)-(23,5) = "{"
+ │ │ └── closing_loc: (23,15)-(23,16) = "}"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :==
+ │ ├── message_loc: (23,17)-(23,19) = "=="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (23,20)-(23,22))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (23,20)-(23,22))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (25,0)-(25,23))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (25,0)-(25,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (25,0)-(25,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (25,4)-(25,17))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (25,6)-(25,9))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (25,7)-(25,8))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (25,7)-(25,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (25,6)-(25,7) = "|"
+ │ │ └── closing_loc: (25,8)-(25,9) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (25,10)-(25,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (25,10)-(25,15))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (25,10)-(25,15) = "break"
+ │ ├── opening_loc: (25,4)-(25,5) = "{"
+ │ └── closing_loc: (25,16)-(25,17) = "}"
+ ├── call_operator_loc: ∅
+ ├── name: :==
+ ├── message_loc: (25,18)-(25,20) = "=="
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (25,21)-(25,23))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (25,21)-(25,23))
+ │ ├── flags: decimal
+ │ └── value: 42
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/case.txt b/test/prism/snapshots/case.txt
new file mode 100644
index 0000000000..417bf9492a
--- /dev/null
+++ b/test/prism/snapshots/case.txt
@@ -0,0 +1,495 @@
+@ ProgramNode (location: (1,0)-(55,3))
+├── locals: [:b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(55,3))
+ └── body: (length: 15)
+ ├── @ CaseNode (location: (1,0)-(3,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (1,5)-(1,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ │ ├── value_loc: (1,6)-(1,8) = "hi"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "hi"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (2,0)-(2,8))
+ │ │ ├── keyword_loc: (2,0)-(2,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (2,5)-(2,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (2,5)-(2,6) = ":"
+ │ │ │ ├── value_loc: (2,6)-(2,8) = "hi"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "hi"
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ CaseNode (location: (5,0)-(5,58))
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (5,5)-(5,9))
+ │ ├── conditions: (length: 2)
+ │ │ ├── @ WhenNode (location: (5,11)-(5,30))
+ │ │ │ ├── keyword_loc: (5,11)-(5,15) = "when"
+ │ │ │ ├── conditions: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (5,16)-(5,20))
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ └── statements:
+ │ │ │ @ StatementsNode (location: (5,22)-(5,30))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (5,22)-(5,30))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :puts
+ │ │ │ ├── message_loc: (5,22)-(5,26) = "puts"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (5,27)-(5,30))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (5,27)-(5,30))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (5,27)-(5,28) = ":"
+ │ │ │ │ ├── value_loc: (5,28)-(5,30) = "hi"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "hi"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ WhenNode (location: (5,32)-(5,53))
+ │ │ ├── keyword_loc: (5,32)-(5,36) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ FalseNode (location: (5,37)-(5,42))
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (5,44)-(5,53))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,44)-(5,53))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (5,44)-(5,48) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,49)-(5,53))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (5,49)-(5,53))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (5,49)-(5,50) = ":"
+ │ │ │ ├── value_loc: (5,50)-(5,53) = "bye"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "bye"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (5,0)-(5,4) = "case"
+ │ └── end_keyword_loc: (5,55)-(5,58) = "end"
+ ├── @ CaseNode (location: (7,0)-(7,20))
+ │ ├── predicate: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (7,6)-(7,15))
+ │ │ ├── keyword_loc: (7,6)-(7,10) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ SplatNode (location: (7,11)-(7,15))
+ │ │ │ ├── operator_loc: (7,11)-(7,12) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (7,12)-(7,15))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (7,12)-(7,15) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (7,0)-(7,4) = "case"
+ │ └── end_keyword_loc: (7,17)-(7,20) = "end"
+ ├── @ CaseNode (location: (9,0)-(13,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (9,5)-(9,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (9,5)-(9,6) = ":"
+ │ │ ├── value_loc: (9,6)-(9,8) = "hi"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "hi"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (10,0)-(10,8))
+ │ │ ├── keyword_loc: (10,0)-(10,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (10,5)-(10,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (10,5)-(10,6) = ":"
+ │ │ │ ├── value_loc: (10,6)-(10,8) = "hi"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "hi"
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (11,0)-(13,3))
+ │ │ ├── else_keyword_loc: (11,0)-(11,4) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (12,0)-(12,2))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (12,0)-(12,2))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (12,0)-(12,1) = ":"
+ │ │ │ ├── value_loc: (12,1)-(12,2) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── end_keyword_loc: (13,0)-(13,3) = "end"
+ │ ├── case_keyword_loc: (9,0)-(9,4) = "case"
+ │ └── end_keyword_loc: (13,0)-(13,3) = "end"
+ ├── @ CaseNode (location: (15,0)-(15,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (15,5)-(15,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :this
+ │ │ ├── message_loc: (15,5)-(15,9) = "this"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (15,11)-(15,31))
+ │ │ ├── keyword_loc: (15,11)-(15,15) = "when"
+ │ │ ├── conditions: (length: 2)
+ │ │ │ ├── @ ConstantReadNode (location: (15,16)-(15,22))
+ │ │ │ │ └── name: :FooBar
+ │ │ │ └── @ ConstantReadNode (location: (15,24)-(15,31))
+ │ │ │ └── name: :BazBonk
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (15,0)-(15,4) = "case"
+ │ └── end_keyword_loc: (15,33)-(15,36) = "end"
+ ├── @ CaseNode (location: (17,0)-(19,3))
+ │ ├── predicate: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (18,0)-(18,15))
+ │ │ ├── keyword_loc: (18,0)-(18,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ CallNode (location: (18,5)-(18,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (18,5)-(18,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (18,5)-(18,8) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :==
+ │ │ │ ├── message_loc: (18,9)-(18,11) = "=="
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (18,12)-(18,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (18,12)-(18,15))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (18,12)-(18,15) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (17,0)-(17,4) = "case"
+ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ ├── @ CaseNode (location: (21,0)-(25,3))
+ │ ├── predicate: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (22,0)-(22,6))
+ │ │ ├── keyword_loc: (22,0)-(22,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ CallNode (location: (22,5)-(22,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (22,5)-(22,6) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (23,0)-(25,3))
+ │ │ ├── else_keyword_loc: (23,0)-(23,4) = "else"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (25,0)-(25,3) = "end"
+ │ ├── case_keyword_loc: (21,0)-(21,4) = "case"
+ │ └── end_keyword_loc: (25,0)-(25,3) = "end"
+ ├── @ CaseNode (location: (27,0)-(30,6))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (27,5)-(27,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :type
+ │ │ ├── message_loc: (27,5)-(27,9) = "type"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (28,3)-(28,10))
+ │ │ ├── keyword_loc: (28,3)-(28,7) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (28,8)-(28,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (28,8)-(28,9) = ":"
+ │ │ │ ├── value_loc: (28,9)-(28,10) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (29,5)-(30,6))
+ │ │ ├── else_keyword_loc: (29,5)-(29,9) = "else"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (30,3)-(30,6) = "end"
+ │ ├── case_keyword_loc: (27,0)-(27,4) = "case"
+ │ └── end_keyword_loc: (30,3)-(30,6) = "end"
+ ├── @ CaseNode (location: (32,0)-(32,25))
+ │ ├── predicate: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (32,14)-(32,20))
+ │ │ ├── keyword_loc: (32,14)-(32,18) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (32,19)-(32,20))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (32,0)-(32,4) = "case"
+ │ └── end_keyword_loc: (32,22)-(32,25) = "end"
+ ├── @ CaseNode (location: (34,0)-(36,3))
+ │ ├── predicate:
+ │ │ @ MatchPredicateNode (location: (34,5)-(34,11))
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (34,5)-(34,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (34,10)-(34,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (34,7)-(34,9) = "in"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (35,0)-(35,6))
+ │ │ ├── keyword_loc: (35,0)-(35,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (35,5)-(35,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (34,0)-(34,4) = "case"
+ │ └── end_keyword_loc: (36,0)-(36,3) = "end"
+ ├── @ CaseNode (location: (38,0)-(38,24))
+ │ ├── predicate:
+ │ │ @ MatchPredicateNode (location: (38,5)-(38,11))
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (38,5)-(38,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (38,10)-(38,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (38,7)-(38,9) = "in"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (38,13)-(38,19))
+ │ │ ├── keyword_loc: (38,13)-(38,17) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (38,18)-(38,19))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (38,0)-(38,4) = "case"
+ │ └── end_keyword_loc: (38,21)-(38,24) = "end"
+ ├── @ CaseMatchNode (location: (40,0)-(42,3))
+ │ ├── predicate:
+ │ │ @ MatchPredicateNode (location: (40,5)-(40,11))
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (40,5)-(40,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (40,10)-(40,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (40,7)-(40,9) = "in"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (41,0)-(41,4))
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (41,3)-(41,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (41,0)-(41,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (40,0)-(40,4) = "case"
+ │ └── end_keyword_loc: (42,0)-(42,3) = "end"
+ ├── @ CaseMatchNode (location: (44,0)-(44,22))
+ │ ├── predicate:
+ │ │ @ MatchPredicateNode (location: (44,5)-(44,11))
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (44,5)-(44,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (44,10)-(44,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (44,7)-(44,9) = "in"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (44,13)-(44,17))
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (44,16)-(44,17))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (44,13)-(44,15) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (44,0)-(44,4) = "case"
+ │ └── end_keyword_loc: (44,19)-(44,22) = "end"
+ ├── @ CaseMatchNode (location: (46,0)-(49,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (46,5)-(46,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (46,5)-(46,6) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (47,0)-(48,3))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (47,3)-(47,15))
+ │ │ │ ├── if_keyword_loc: (47,5)-(47,7) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ AndNode (location: (47,8)-(47,15))
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ CallNode (location: (47,8)-(47,9))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :c
+ │ │ │ │ │ ├── message_loc: (47,8)-(47,9) = "c"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ CallNode (location: (47,14)-(47,15))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (47,14)-(47,15) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── operator_loc: (47,10)-(47,13) = "and"
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (47,3)-(47,4))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableTargetNode (location: (47,3)-(47,4))
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (48,2)-(48,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (48,2)-(48,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :e
+ │ │ │ ├── message_loc: (48,2)-(48,3) = "e"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── in_loc: (47,0)-(47,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (46,0)-(46,4) = "case"
+ │ └── end_keyword_loc: (49,0)-(49,3) = "end"
+ └── @ CallNode (location: (51,0)-(55,3))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (51,0)-(51,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: (51,1)-(51,2) = "."
+ ├── name: :then
+ ├── message_loc: (51,2)-(51,6) = "then"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (51,7)-(55,3))
+ ├── locals: [:_1]
+ ├── parameters:
+ │ @ NumberedParametersNode (location: (51,7)-(55,3))
+ │ └── maximum: 1
+ ├── body:
+ │ @ StatementsNode (location: (52,2)-(54,5))
+ │ └── body: (length: 1)
+ │ └── @ CaseMatchNode (location: (52,2)-(54,5))
+ │ ├── predicate:
+ │ │ @ IntegerNode (location: (52,7)-(52,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (53,2)-(53,8))
+ │ │ ├── pattern:
+ │ │ │ @ PinnedVariableNode (location: (53,5)-(53,8))
+ │ │ │ ├── variable:
+ │ │ │ │ @ LocalVariableReadNode (location: (53,6)-(53,8))
+ │ │ │ │ ├── name: :_1
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: (53,5)-(53,6) = "^"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (53,2)-(53,4) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (52,2)-(52,6) = "case"
+ │ └── end_keyword_loc: (54,2)-(54,5) = "end"
+ ├── opening_loc: (51,7)-(51,9) = "do"
+ └── closing_loc: (55,0)-(55,3) = "end"
diff --git a/test/prism/snapshots/classes.txt b/test/prism/snapshots/classes.txt
new file mode 100644
index 0000000000..4a36bd5cdc
--- /dev/null
+++ b/test/prism/snapshots/classes.txt
@@ -0,0 +1,365 @@
+@ ProgramNode (location: (1,0)-(35,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(35,3))
+ └── body: (length: 14)
+ ├── @ ClassNode (location: (1,0)-(1,17))
+ │ ├── locals: [:a]
+ │ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (1,6)-(1,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,8)-(1,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (1,8)-(1,13))
+ │ │ ├── name: :a
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (1,8)-(1,9) = "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (1,10)-(1,11) = "="
+ │ ├── end_keyword_loc: (1,14)-(1,17) = "end"
+ │ └── name: :A
+ ├── @ ClassNode (location: (3,0)-(3,20))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (3,0)-(3,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (3,6)-(3,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (3,0)-(3,20))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (3,9)-(3,20))
+ │ │ │ ├── ensure_keyword_loc: (3,9)-(3,15) = "ensure"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── end_keyword_loc: (3,17)-(3,20) = "end"
+ │ │ └── end_keyword_loc: (3,17)-(3,20) = "end"
+ │ ├── end_keyword_loc: (3,17)-(3,20) = "end"
+ │ └── name: :A
+ ├── @ ClassNode (location: (5,0)-(5,34))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (5,0)-(5,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (5,6)-(5,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (5,0)-(5,34))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (5,9)-(5,15))
+ │ │ │ ├── keyword_loc: (5,9)-(5,15) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause:
+ │ │ │ @ ElseNode (location: (5,17)-(5,29))
+ │ │ │ ├── else_keyword_loc: (5,17)-(5,21) = "else"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── end_keyword_loc: (5,23)-(5,29) = "ensure"
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (5,23)-(5,34))
+ │ │ │ ├── ensure_keyword_loc: (5,23)-(5,29) = "ensure"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── end_keyword_loc: (5,31)-(5,34) = "end"
+ │ │ └── end_keyword_loc: (5,31)-(5,34) = "end"
+ │ ├── end_keyword_loc: (5,31)-(5,34) = "end"
+ │ └── name: :A
+ ├── @ ClassNode (location: (7,0)-(9,3))
+ │ ├── locals: [:a]
+ │ ├── class_keyword_loc: (7,0)-(7,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (7,6)-(7,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: (7,8)-(7,9) = "<"
+ │ ├── superclass:
+ │ │ @ ConstantReadNode (location: (7,10)-(7,11))
+ │ │ └── name: :B
+ │ ├── body:
+ │ │ @ StatementsNode (location: (8,0)-(8,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (8,0)-(8,5))
+ │ │ ├── name: :a
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (8,0)-(8,1) = "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (8,4)-(8,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (8,2)-(8,3) = "="
+ │ ├── end_keyword_loc: (9,0)-(9,3) = "end"
+ │ └── name: :A
+ ├── @ SingletonClassNode (location: (11,0)-(12,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (11,0)-(11,5) = "class"
+ │ ├── operator_loc: (11,6)-(11,8) = "<<"
+ │ ├── expression:
+ │ │ @ CallNode (location: (11,9)-(11,16))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (11,13)-(11,16))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (11,13)-(11,16) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (11,9)-(11,12) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ └── end_keyword_loc: (12,0)-(12,3) = "end"
+ ├── @ ClassNode (location: (14,0)-(14,40))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (14,0)-(14,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (14,6)-(14,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (14,9)-(14,35))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SingletonClassNode (location: (14,9)-(14,35))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (14,9)-(14,14) = "class"
+ │ │ ├── operator_loc: (14,15)-(14,17) = "<<"
+ │ │ ├── expression:
+ │ │ │ @ SelfNode (location: (14,18)-(14,22))
+ │ │ ├── body:
+ │ │ │ @ BeginNode (location: (14,9)-(14,35))
+ │ │ │ ├── begin_keyword_loc: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ ├── rescue_clause: ∅
+ │ │ │ ├── else_clause: ∅
+ │ │ │ ├── ensure_clause:
+ │ │ │ │ @ EnsureNode (location: (14,24)-(14,35))
+ │ │ │ │ ├── ensure_keyword_loc: (14,24)-(14,30) = "ensure"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── end_keyword_loc: (14,32)-(14,35) = "end"
+ │ │ │ └── end_keyword_loc: (14,32)-(14,35) = "end"
+ │ │ └── end_keyword_loc: (14,32)-(14,35) = "end"
+ │ ├── end_keyword_loc: (14,37)-(14,40) = "end"
+ │ └── name: :A
+ ├── @ ClassNode (location: (16,0)-(16,54))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (16,0)-(16,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (16,6)-(16,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (16,9)-(16,49))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SingletonClassNode (location: (16,9)-(16,49))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (16,9)-(16,14) = "class"
+ │ │ ├── operator_loc: (16,15)-(16,17) = "<<"
+ │ │ ├── expression:
+ │ │ │ @ SelfNode (location: (16,18)-(16,22))
+ │ │ ├── body:
+ │ │ │ @ BeginNode (location: (16,9)-(16,49))
+ │ │ │ ├── begin_keyword_loc: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ ├── rescue_clause:
+ │ │ │ │ @ RescueNode (location: (16,24)-(16,30))
+ │ │ │ │ ├── keyword_loc: (16,24)-(16,30) = "rescue"
+ │ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ │ ├── operator_loc: ∅
+ │ │ │ │ ├── reference: ∅
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── consequent: ∅
+ │ │ │ ├── else_clause:
+ │ │ │ │ @ ElseNode (location: (16,32)-(16,44))
+ │ │ │ │ ├── else_keyword_loc: (16,32)-(16,36) = "else"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── end_keyword_loc: (16,38)-(16,44) = "ensure"
+ │ │ │ ├── ensure_clause:
+ │ │ │ │ @ EnsureNode (location: (16,38)-(16,49))
+ │ │ │ │ ├── ensure_keyword_loc: (16,38)-(16,44) = "ensure"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── end_keyword_loc: (16,46)-(16,49) = "end"
+ │ │ │ └── end_keyword_loc: (16,46)-(16,49) = "end"
+ │ │ └── end_keyword_loc: (16,46)-(16,49) = "end"
+ │ ├── end_keyword_loc: (16,51)-(16,54) = "end"
+ │ └── name: :A
+ ├── @ SingletonClassNode (location: (18,0)-(19,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (18,0)-(18,5) = "class"
+ │ ├── operator_loc: (18,6)-(18,8) = "<<"
+ │ ├── expression:
+ │ │ @ CallNode (location: (18,9)-(18,16))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (18,9)-(18,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (18,9)-(18,12) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (18,12)-(18,13) = "."
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (18,13)-(18,16) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ ├── @ SingletonClassNode (location: (21,0)-(21,20))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (21,0)-(21,5) = "class"
+ │ ├── operator_loc: (21,6)-(21,8) = "<<"
+ │ ├── expression:
+ │ │ @ CallNode (location: (21,9)-(21,16))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (21,9)-(21,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (21,9)-(21,12) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (21,12)-(21,13) = "."
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (21,13)-(21,16) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ └── end_keyword_loc: (21,17)-(21,20) = "end"
+ ├── @ SingletonClassNode (location: (23,0)-(24,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (23,0)-(23,5) = "class"
+ │ ├── operator_loc: (23,6)-(23,8) = "<<"
+ │ ├── expression:
+ │ │ @ SelfNode (location: (23,9)-(23,13))
+ │ ├── body: ∅
+ │ └── end_keyword_loc: (24,0)-(24,3) = "end"
+ ├── @ SingletonClassNode (location: (26,0)-(26,17))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (26,0)-(26,5) = "class"
+ │ ├── operator_loc: (26,6)-(26,8) = "<<"
+ │ ├── expression:
+ │ │ @ SelfNode (location: (26,9)-(26,13))
+ │ ├── body: ∅
+ │ └── end_keyword_loc: (26,14)-(26,17) = "end"
+ ├── @ SingletonClassNode (location: (28,0)-(30,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (28,0)-(28,5) = "class"
+ │ ├── operator_loc: (28,6)-(28,8) = "<<"
+ │ ├── expression:
+ │ │ @ SelfNode (location: (28,9)-(28,13))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (29,0)-(29,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (29,0)-(29,5))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (29,0)-(29,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :+
+ │ │ ├── message_loc: (29,2)-(29,3) = "+"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (29,4)-(29,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (29,4)-(29,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (30,0)-(30,3) = "end"
+ ├── @ SingletonClassNode (location: (32,0)-(32,23))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (32,0)-(32,5) = "class"
+ │ ├── operator_loc: (32,6)-(32,8) = "<<"
+ │ ├── expression:
+ │ │ @ SelfNode (location: (32,9)-(32,13))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (32,14)-(32,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (32,14)-(32,19))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (32,14)-(32,15))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :+
+ │ │ ├── message_loc: (32,16)-(32,17) = "+"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (32,18)-(32,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (32,18)-(32,19))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (32,20)-(32,23) = "end"
+ └── @ ClassNode (location: (34,0)-(35,3))
+ ├── locals: []
+ ├── class_keyword_loc: (34,0)-(34,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (34,6)-(34,7))
+ │ └── name: :A
+ ├── inheritance_operator_loc: (34,8)-(34,9) = "<"
+ ├── superclass:
+ │ @ CallNode (location: (34,10)-(34,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (34,10)-(34,11))
+ │ │ └── name: :B
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (34,11)-(34,14) = "[1]"
+ │ ├── opening_loc: (34,11)-(34,12) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (34,12)-(34,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (34,12)-(34,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: (34,13)-(34,14) = "]"
+ │ └── block: ∅
+ ├── body: ∅
+ ├── end_keyword_loc: (35,0)-(35,3) = "end"
+ └── name: :A
diff --git a/test/prism/snapshots/command_method_call.txt b/test/prism/snapshots/command_method_call.txt
new file mode 100644
index 0000000000..7fd6341304
--- /dev/null
+++ b/test/prism/snapshots/command_method_call.txt
@@ -0,0 +1,755 @@
+@ ProgramNode (location: (1,0)-(41,10))
+├── locals: [:foo, :bar]
+└── statements:
+ @ StatementsNode (location: (1,0)-(41,10))
+ └── body: (length: 21)
+ ├── @ CallNode (location: (1,0)-(1,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,4)-(3,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,4)-(3,9))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,4)-(3,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,8)-(3,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,8)-(3,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ IfNode (location: (5,0)-(5,14))
+ │ ├── if_keyword_loc: (5,6)-(5,8) = "if"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (5,9)-(5,14))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (5,9)-(5,12) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,13)-(5,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,13)-(5,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,0)-(5,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,0)-(5,5))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,4)-(5,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,4)-(5,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ UnlessNode (location: (7,0)-(7,18))
+ │ ├── keyword_loc: (7,6)-(7,12) = "unless"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (7,13)-(7,18))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (7,13)-(7,16) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,17)-(7,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (7,17)-(7,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (7,0)-(7,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (7,0)-(7,5))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,4)-(7,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (7,4)-(7,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ WhileNode (location: (9,0)-(9,17))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (9,6)-(9,11) = "while"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (9,12)-(9,17))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (9,12)-(9,15) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (9,16)-(9,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (9,16)-(9,17))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (9,0)-(9,5))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (9,0)-(9,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (9,0)-(9,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,4)-(9,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (9,4)-(9,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ UntilNode (location: (11,0)-(11,17))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (11,6)-(11,11) = "until"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (11,12)-(11,17))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (11,12)-(11,15) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (11,16)-(11,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (11,16)-(11,17))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (11,0)-(11,5))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (11,0)-(11,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (11,0)-(11,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,4)-(11,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (11,4)-(11,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ RescueModifierNode (location: (13,0)-(13,18))
+ │ ├── expression:
+ │ │ @ CallNode (location: (13,0)-(13,5))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (13,0)-(13,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (13,4)-(13,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (13,4)-(13,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (13,6)-(13,12) = "rescue"
+ │ └── rescue_expression:
+ │ @ CallNode (location: (13,13)-(13,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (13,13)-(13,16) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,17)-(13,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (13,17)-(13,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (15,0)-(15,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (15,0)-(15,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (15,0)-(15,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (15,3)-(15,10) = "[bar 1]"
+ │ ├── opening_loc: (15,3)-(15,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,4)-(15,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (15,4)-(15,9))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (15,4)-(15,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (15,8)-(15,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (15,8)-(15,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (15,9)-(15,10) = "]"
+ │ └── block: ∅
+ ├── @ AndNode (location: (17,0)-(17,15))
+ │ ├── left:
+ │ │ @ CallNode (location: (17,0)-(17,5))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (17,0)-(17,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (17,4)-(17,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (17,4)-(17,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (17,10)-(17,15))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (17,10)-(17,13) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (17,14)-(17,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (17,14)-(17,15))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (17,6)-(17,9) = "and"
+ ├── @ OrNode (location: (19,0)-(19,14))
+ │ ├── left:
+ │ │ @ CallNode (location: (19,0)-(19,5))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (19,0)-(19,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (19,4)-(19,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (19,4)-(19,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (19,9)-(19,14))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (19,9)-(19,12) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (19,13)-(19,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (19,13)-(19,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (19,6)-(19,8) = "or"
+ ├── @ CallNode (location: (21,0)-(21,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (21,4)-(21,9))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (21,4)-(21,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (21,8)-(21,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (21,8)-(21,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (21,0)-(21,3) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ LocalVariableWriteNode (location: (23,0)-(23,17))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (23,0)-(23,3) = "foo"
+ │ ├── value:
+ │ │ @ LocalVariableWriteNode (location: (23,6)-(23,17))
+ │ │ ├── name: :bar
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (23,6)-(23,9) = "bar"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (23,12)-(23,17))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (23,12)-(23,15) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (23,16)-(23,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (23,16)-(23,17))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (23,10)-(23,11) = "="
+ │ └── operator_loc: (23,4)-(23,5) = "="
+ ├── @ DefNode (location: (25,0)-(25,15))
+ │ ├── name: :foo
+ │ ├── name_loc: (25,4)-(25,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (25,10)-(25,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (25,10)-(25,15))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (25,10)-(25,13) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (25,14)-(25,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (25,14)-(25,15))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (25,0)-(25,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (25,8)-(25,9) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ CallNode (location: (27,0)-(27,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (27,0)-(27,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: (27,1)-(27,2) = "."
+ │ ├── name: :foo
+ │ ├── message_loc: (27,2)-(27,5) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,6)-(27,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (27,6)-(27,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (29,0)-(29,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (29,0)-(29,5))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (29,0)-(29,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: (29,1)-(29,2) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (29,2)-(29,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (29,5)-(29,6) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (29,6)-(29,9) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (29,10)-(29,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (29,10)-(29,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (31,0)-(31,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (31,0)-(31,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (31,0)-(31,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ IntegerNode (location: (31,0)-(31,1))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── call_operator_loc: (31,1)-(31,2) = "."
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (31,2)-(31,5) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]
+ │ │ ├── message_loc: (31,5)-(31,8) = "[2]"
+ │ │ ├── opening_loc: (31,5)-(31,6) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (31,6)-(31,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (31,6)-(31,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: (31,7)-(31,8) = "]"
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (31,8)-(31,9) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (31,9)-(31,12) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,13)-(31,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (31,13)-(31,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (33,0)-(33,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (33,0)-(33,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (33,0)-(33,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: (33,1)-(33,2) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (33,2)-(33,5) = "foo"
+ │ │ ├── opening_loc: (33,5)-(33,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (33,6)-(33,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (33,6)-(33,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: (33,7)-(33,8) = ")"
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (33,8)-(33,9) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (33,9)-(33,12) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (33,13)-(33,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (33,13)-(33,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (35,0)-(35,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (35,0)-(35,9))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (35,0)-(35,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: (35,1)-(35,2) = "."
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (35,2)-(35,5) = "foo"
+ │ │ ├── opening_loc: (35,5)-(35,6) = "("
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: (35,8)-(35,9) = ")"
+ │ │ └── block:
+ │ │ @ BlockArgumentNode (location: (35,6)-(35,8))
+ │ │ ├── expression:
+ │ │ │ @ IntegerNode (location: (35,7)-(35,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (35,6)-(35,7) = "&"
+ │ ├── call_operator_loc: (35,9)-(35,10) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (35,10)-(35,13) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,14)-(35,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (35,14)-(35,15))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ AndNode (location: (37,0)-(37,17))
+ │ ├── left:
+ │ │ @ CallNode (location: (37,0)-(37,6))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (37,1)-(37,6))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (37,1)-(37,4) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (37,5)-(37,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (37,5)-(37,6))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (37,0)-(37,1) = "!"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (37,11)-(37,17))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (37,12)-(37,17))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (37,12)-(37,15) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (37,16)-(37,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (37,16)-(37,17))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (37,11)-(37,12) = "!"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (37,7)-(37,10) = "and"
+ ├── @ OrNode (location: (39,0)-(39,16))
+ │ ├── left:
+ │ │ @ CallNode (location: (39,0)-(39,6))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (39,1)-(39,6))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (39,1)-(39,4) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (39,5)-(39,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (39,5)-(39,6))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (39,0)-(39,1) = "!"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (39,10)-(39,16))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (39,11)-(39,16))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (39,11)-(39,14) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (39,15)-(39,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (39,15)-(39,16))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (39,10)-(39,11) = "!"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (39,7)-(39,9) = "or"
+ └── @ CallNode (location: (41,0)-(41,10))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (41,4)-(41,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (41,5)-(41,10))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (41,5)-(41,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (41,9)-(41,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (41,9)-(41,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (41,4)-(41,5) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (41,0)-(41,3) = "not"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/comments.txt b/test/prism/snapshots/comments.txt
new file mode 100644
index 0000000000..b7088adcd5
--- /dev/null
+++ b/test/prism/snapshots/comments.txt
@@ -0,0 +1,145 @@
+@ ProgramNode (location: (1,0)-(24,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(24,5))
+ └── body: (length: 9)
+ ├── @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (3,0)-(3,1) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :c
+ │ ├── message_loc: (5,0)-(5,1) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (6,0)-(6,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :d
+ │ ├── message_loc: (6,0)-(6,1) = "d"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (8,0)-(10,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (8,0)-(8,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :e
+ │ │ ├── message_loc: (8,0)-(8,1) = "e"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (10,2)-(10,3) = "."
+ │ ├── name: :f
+ │ ├── message_loc: (10,3)-(10,4) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (12,0)-(14,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (12,0)-(12,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :g
+ │ │ ├── message_loc: (12,0)-(12,1) = "g"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (14,0)-(14,1) = "."
+ │ ├── name: :h
+ │ ├── message_loc: (14,1)-(14,2) = "h"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (16,0)-(17,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (16,0)-(16,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :i
+ │ │ ├── message_loc: (16,0)-(16,1) = "i"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (17,0)-(17,1) = "."
+ │ ├── name: :j
+ │ ├── message_loc: (17,1)-(17,2) = "j"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (19,0)-(20,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (19,0)-(19,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :k
+ │ │ ├── message_loc: (19,0)-(19,1) = "k"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (20,2)-(20,3) = "."
+ │ ├── name: :l
+ │ ├── message_loc: (20,3)-(20,4) = "l"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (22,0)-(24,5))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (22,0)-(22,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (22,0)-(22,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (24,2)-(24,4) = "&."
+ ├── name: :n
+ ├── message_loc: (24,4)-(24,5) = "n"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/constants.txt b/test/prism/snapshots/constants.txt
new file mode 100644
index 0000000000..59e234148a
--- /dev/null
+++ b/test/prism/snapshots/constants.txt
@@ -0,0 +1,1242 @@
+@ ProgramNode (location: (1,0)-(184,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(184,10))
+ └── body: (length: 90)
+ ├── @ ConstantPathNode (location: (1,0)-(1,4))
+ │ ├── parent:
+ │ │ @ ConstantReadNode (location: (1,0)-(1,1))
+ │ │ └── name: :A
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (1,3)-(1,4))
+ │ │ └── name: :B
+ │ └── delimiter_loc: (1,1)-(1,3) = "::"
+ ├── @ 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) = "::"
+ ├── @ ConstantPathNode (location: (5,0)-(5,4))
+ │ ├── parent:
+ │ │ @ CallNode (location: (5,0)-(5,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (5,0)-(5,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (5,3)-(5,4))
+ │ │ └── name: :B
+ │ └── delimiter_loc: (5,1)-(5,3) = "::"
+ ├── @ 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) = "::"
+ │ ├── operator_loc: (7,5)-(7,6) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (7,7)-(7,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ ConstantWriteNode (location: (9,0)-(9,5))
+ │ ├── name: :A
+ │ ├── name_loc: (9,0)-(9,1) = "A"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (9,4)-(9,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (9,2)-(9,3) = "="
+ ├── @ ConstantReadNode (location: (11,0)-(11,3))
+ │ └── name: :ABC
+ ├── @ CallNode (location: (13,0)-(13,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :Foo
+ │ ├── message_loc: (13,0)-(13,3) = "Foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,4)-(13,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (13,4)-(13,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (15,0)-(15,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :Foo
+ │ ├── message_loc: (15,0)-(15,3) = "Foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,4)-(15,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (15,4)-(15,8))
+ │ │ ├── operator_loc: (15,4)-(15,5) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (15,5)-(15,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (15,5)-(15,8) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (17,0)-(17,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :Foo
+ │ ├── message_loc: (17,0)-(17,3) = "Foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (17,4)-(17,9))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (17,4)-(17,9))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (17,4)-(17,9))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (17,6)-(17,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (17,6)-(17,9) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (17,4)-(17,6) = "**"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (19,0)-(19,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :Foo
+ │ ├── message_loc: (19,0)-(19,3) = "Foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockArgumentNode (location: (19,4)-(19,8))
+ │ ├── expression:
+ │ │ @ CallNode (location: (19,5)-(19,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (19,5)-(19,8) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (19,4)-(19,5) = "&"
+ ├── @ CallNode (location: (21,0)-(21,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (21,0)-(21,3))
+ │ │ └── name: :Foo
+ │ ├── call_operator_loc: (21,3)-(21,5) = "::"
+ │ ├── name: :Bar
+ │ ├── message_loc: (21,5)-(21,8) = "Bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (21,9)-(21,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (21,9)-(21,13))
+ │ │ ├── operator_loc: (21,9)-(21,10) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (21,10)-(21,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (21,10)-(21,13) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (23,0)-(23,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (23,0)-(23,3))
+ │ │ └── name: :Foo
+ │ ├── call_operator_loc: (23,3)-(23,5) = "::"
+ │ ├── name: :Bar
+ │ ├── message_loc: (23,5)-(23,8) = "Bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (23,9)-(23,14))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (23,9)-(23,14))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (23,9)-(23,14))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (23,11)-(23,14))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (23,11)-(23,14) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (23,9)-(23,11) = "**"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (25,0)-(25,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (25,0)-(25,3))
+ │ │ └── name: :Foo
+ │ ├── call_operator_loc: (25,3)-(25,5) = "::"
+ │ ├── name: :Bar
+ │ ├── message_loc: (25,5)-(25,8) = "Bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockArgumentNode (location: (25,9)-(25,13))
+ │ ├── expression:
+ │ │ @ CallNode (location: (25,10)-(25,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (25,10)-(25,13) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (25,9)-(25,10) = "&"
+ ├── @ CallNode (location: (27,0)-(27,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantPathNode (location: (27,0)-(27,3))
+ │ │ ├── parent: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (27,2)-(27,3))
+ │ │ │ └── name: :A
+ │ │ └── delimiter_loc: (27,0)-(27,2) = "::"
+ │ ├── call_operator_loc: (27,3)-(27,5) = "::"
+ │ ├── name: :foo
+ │ ├── message_loc: (27,5)-(27,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ConstantPathWriteNode (location: (29,0)-(29,7))
+ │ ├── target:
+ │ │ @ ConstantPathNode (location: (29,0)-(29,3))
+ │ │ ├── parent: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (29,2)-(29,3))
+ │ │ │ └── name: :A
+ │ │ └── delimiter_loc: (29,0)-(29,2) = "::"
+ │ ├── operator_loc: (29,4)-(29,5) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (29,6)-(29,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ ConstantPathWriteNode (location: (31,0)-(31,10))
+ │ ├── target:
+ │ │ @ ConstantPathNode (location: (31,0)-(31,6))
+ │ │ ├── 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) = "::"
+ │ ├── operator_loc: (31,7)-(31,8) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (31,9)-(31,10))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ ConstantPathNode (location: (33,0)-(33,6))
+ │ ├── 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) = "::"
+ ├── @ ConstantPathNode (location: (35,0)-(35,3))
+ │ ├── parent: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (35,2)-(35,3))
+ │ │ └── name: :A
+ │ └── delimiter_loc: (35,0)-(35,2) = "::"
+ ├── @ CallNode (location: (37,0)-(37,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (37,0)-(37,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (37,1)-(37,3) = "::"
+ │ ├── name: :false
+ │ ├── message_loc: (37,3)-(37,8) = "false"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (39,0)-(39,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantPathNode (location: (39,0)-(39,4))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (39,0)-(39,1))
+ │ │ │ └── name: :A
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (39,3)-(39,4))
+ │ │ │ └── name: :B
+ │ │ └── delimiter_loc: (39,1)-(39,3) = "::"
+ │ ├── call_operator_loc: (39,4)-(39,6) = "::"
+ │ ├── name: :true
+ │ ├── message_loc: (39,6)-(39,10) = "true"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (41,0)-(41,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (41,0)-(41,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (41,1)-(41,3) = "::"
+ │ ├── name: :&
+ │ ├── message_loc: (41,3)-(41,4) = "&"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (43,0)-(43,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (43,0)-(43,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (43,1)-(43,3) = "::"
+ │ ├── name: :`
+ │ ├── message_loc: (43,3)-(43,4) = "`"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (45,0)-(45,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (45,0)-(45,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (45,1)-(45,3) = "::"
+ │ ├── name: :!
+ │ ├── message_loc: (45,3)-(45,4) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (47,0)-(47,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (47,0)-(47,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (47,1)-(47,3) = "::"
+ │ ├── name: :!=
+ │ ├── message_loc: (47,3)-(47,5) = "!="
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (49,0)-(49,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (49,0)-(49,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (49,1)-(49,3) = "::"
+ │ ├── name: :^
+ │ ├── message_loc: (49,3)-(49,4) = "^"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (51,0)-(51,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (51,0)-(51,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (51,1)-(51,3) = "::"
+ │ ├── name: :==
+ │ ├── message_loc: (51,3)-(51,5) = "=="
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (53,0)-(53,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (53,0)-(53,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (53,1)-(53,3) = "::"
+ │ ├── name: :===
+ │ ├── message_loc: (53,3)-(53,6) = "==="
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (55,0)-(55,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (55,0)-(55,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (55,1)-(55,3) = "::"
+ │ ├── name: :=~
+ │ ├── message_loc: (55,3)-(55,5) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (57,0)-(57,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (57,0)-(57,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (57,1)-(57,3) = "::"
+ │ ├── name: :>
+ │ ├── message_loc: (57,3)-(57,4) = ">"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (59,0)-(59,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (59,0)-(59,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (59,1)-(59,3) = "::"
+ │ ├── name: :>=
+ │ ├── message_loc: (59,3)-(59,5) = ">="
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (61,0)-(61,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (61,0)-(61,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (61,1)-(61,3) = "::"
+ │ ├── name: :>>
+ │ ├── message_loc: (61,3)-(61,5) = ">>"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (63,0)-(63,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (63,0)-(63,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (63,1)-(63,3) = "::"
+ │ ├── name: :<<
+ │ ├── message_loc: (63,3)-(63,5) = "<<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ConstantPathNode (location: (65,0)-(67,1))
+ │ ├── parent:
+ │ │ @ ConstantReadNode (location: (65,0)-(65,1))
+ │ │ └── name: :A
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (67,0)-(67,1))
+ │ │ └── name: :C
+ │ └── delimiter_loc: (65,1)-(65,3) = "::"
+ ├── @ CallNode (location: (69,0)-(69,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (69,0)-(69,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (69,1)-(69,3) = "::"
+ │ ├── name: :alias
+ │ ├── message_loc: (69,3)-(69,8) = "alias"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (71,0)-(71,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (71,0)-(71,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (71,1)-(71,3) = "::"
+ │ ├── name: :and
+ │ ├── message_loc: (71,3)-(71,6) = "and"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (73,0)-(73,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (73,0)-(73,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (73,1)-(73,3) = "::"
+ │ ├── name: :begin
+ │ ├── message_loc: (73,3)-(73,8) = "begin"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ConstantPathNode (location: (75,0)-(75,8))
+ │ ├── parent:
+ │ │ @ ConstantReadNode (location: (75,0)-(75,1))
+ │ │ └── name: :A
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (75,3)-(75,8))
+ │ │ └── name: :BEGIN
+ │ └── delimiter_loc: (75,1)-(75,3) = "::"
+ ├── @ CallNode (location: (77,0)-(77,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (77,0)-(77,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (77,1)-(77,3) = "::"
+ │ ├── name: :break
+ │ ├── message_loc: (77,3)-(77,8) = "break"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (79,0)-(79,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (79,0)-(79,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (79,1)-(79,3) = "::"
+ │ ├── name: :class
+ │ ├── message_loc: (79,3)-(79,8) = "class"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (81,0)-(81,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (81,0)-(81,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (81,1)-(81,3) = "::"
+ │ ├── name: :def
+ │ ├── message_loc: (81,3)-(81,6) = "def"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (83,0)-(83,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (83,0)-(83,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (83,1)-(83,3) = "::"
+ │ ├── name: :defined
+ │ ├── message_loc: (83,3)-(83,10) = "defined"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (85,0)-(85,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (85,0)-(85,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (85,1)-(85,3) = "::"
+ │ ├── name: :do
+ │ ├── message_loc: (85,3)-(85,5) = "do"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (87,0)-(87,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (87,0)-(87,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (87,1)-(87,3) = "::"
+ │ ├── name: :else
+ │ ├── message_loc: (87,3)-(87,7) = "else"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (89,0)-(89,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (89,0)-(89,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (89,1)-(89,3) = "::"
+ │ ├── name: :elsif
+ │ ├── message_loc: (89,3)-(89,8) = "elsif"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (91,0)-(91,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (91,0)-(91,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (91,1)-(91,3) = "::"
+ │ ├── name: :end
+ │ ├── message_loc: (91,3)-(91,6) = "end"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ConstantPathNode (location: (93,0)-(93,6))
+ │ ├── parent:
+ │ │ @ ConstantReadNode (location: (93,0)-(93,1))
+ │ │ └── name: :A
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (93,3)-(93,6))
+ │ │ └── name: :END
+ │ └── delimiter_loc: (93,1)-(93,3) = "::"
+ ├── @ CallNode (location: (95,0)-(95,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (95,0)-(95,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (95,1)-(95,3) = "::"
+ │ ├── name: :ensure
+ │ ├── message_loc: (95,3)-(95,9) = "ensure"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (97,0)-(97,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (97,0)-(97,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (97,1)-(97,3) = "::"
+ │ ├── name: :false
+ │ ├── message_loc: (97,3)-(97,8) = "false"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (99,0)-(99,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (99,0)-(99,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (99,1)-(99,3) = "::"
+ │ ├── name: :for
+ │ ├── message_loc: (99,3)-(99,6) = "for"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (101,0)-(101,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (101,0)-(101,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (101,1)-(101,3) = "::"
+ │ ├── name: :if
+ │ ├── message_loc: (101,3)-(101,5) = "if"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (103,0)-(103,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (103,0)-(103,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (103,1)-(103,3) = "::"
+ │ ├── name: :in
+ │ ├── message_loc: (103,3)-(103,5) = "in"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (105,0)-(105,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (105,0)-(105,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (105,1)-(105,3) = "::"
+ │ ├── name: :next
+ │ ├── message_loc: (105,3)-(105,7) = "next"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (107,0)-(107,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (107,0)-(107,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (107,1)-(107,3) = "::"
+ │ ├── name: :nil
+ │ ├── message_loc: (107,3)-(107,6) = "nil"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (109,0)-(109,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (109,0)-(109,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (109,1)-(109,3) = "::"
+ │ ├── name: :not
+ │ ├── message_loc: (109,3)-(109,6) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (111,0)-(111,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (111,0)-(111,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (111,1)-(111,3) = "::"
+ │ ├── name: :or
+ │ ├── message_loc: (111,3)-(111,5) = "or"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (113,0)-(113,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (113,0)-(113,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (113,1)-(113,3) = "::"
+ │ ├── name: :redo
+ │ ├── message_loc: (113,3)-(113,7) = "redo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (115,0)-(115,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (115,0)-(115,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (115,1)-(115,3) = "::"
+ │ ├── name: :rescue
+ │ ├── message_loc: (115,3)-(115,9) = "rescue"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (117,0)-(117,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (117,0)-(117,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (117,1)-(117,3) = "::"
+ │ ├── name: :retry
+ │ ├── message_loc: (117,3)-(117,8) = "retry"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (119,0)-(119,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (119,0)-(119,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (119,1)-(119,3) = "::"
+ │ ├── name: :return
+ │ ├── message_loc: (119,3)-(119,9) = "return"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (121,0)-(121,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (121,0)-(121,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (121,1)-(121,3) = "::"
+ │ ├── name: :self
+ │ ├── message_loc: (121,3)-(121,7) = "self"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (123,0)-(123,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (123,0)-(123,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (123,1)-(123,3) = "::"
+ │ ├── name: :super
+ │ ├── message_loc: (123,3)-(123,8) = "super"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (125,0)-(125,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (125,0)-(125,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (125,1)-(125,3) = "::"
+ │ ├── name: :then
+ │ ├── message_loc: (125,3)-(125,7) = "then"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (127,0)-(127,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (127,0)-(127,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (127,1)-(127,3) = "::"
+ │ ├── name: :true
+ │ ├── message_loc: (127,3)-(127,7) = "true"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (129,0)-(129,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (129,0)-(129,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (129,1)-(129,3) = "::"
+ │ ├── name: :undef
+ │ ├── message_loc: (129,3)-(129,8) = "undef"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (131,0)-(131,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (131,0)-(131,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (131,1)-(131,3) = "::"
+ │ ├── name: :unless
+ │ ├── message_loc: (131,3)-(131,9) = "unless"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (133,0)-(133,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (133,0)-(133,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (133,1)-(133,3) = "::"
+ │ ├── name: :until
+ │ ├── message_loc: (133,3)-(133,8) = "until"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (135,0)-(135,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (135,0)-(135,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (135,1)-(135,3) = "::"
+ │ ├── name: :when
+ │ ├── message_loc: (135,3)-(135,7) = "when"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (137,0)-(137,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (137,0)-(137,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (137,1)-(137,3) = "::"
+ │ ├── name: :while
+ │ ├── message_loc: (137,3)-(137,8) = "while"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (139,0)-(139,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (139,0)-(139,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (139,1)-(139,3) = "::"
+ │ ├── name: :yield
+ │ ├── message_loc: (139,3)-(139,8) = "yield"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (141,0)-(141,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (141,0)-(141,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (141,1)-(141,3) = "::"
+ │ ├── name: :__ENCODING__
+ │ ├── message_loc: (141,3)-(141,15) = "__ENCODING__"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (143,0)-(143,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (143,0)-(143,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (143,1)-(143,3) = "::"
+ │ ├── name: :__FILE__
+ │ ├── message_loc: (143,3)-(143,11) = "__FILE__"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (145,0)-(145,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (145,0)-(145,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (145,1)-(145,3) = "::"
+ │ ├── name: :__LINE__
+ │ ├── message_loc: (145,3)-(145,11) = "__LINE__"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (147,0)-(147,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (147,0)-(147,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (147,1)-(147,3) = "::"
+ │ ├── name: :<
+ │ ├── message_loc: (147,3)-(147,4) = "<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (149,0)-(149,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (149,0)-(149,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (149,1)-(149,3) = "::"
+ │ ├── name: :<=>
+ │ ├── message_loc: (149,3)-(149,6) = "<=>"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (151,0)-(151,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (151,0)-(151,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (151,1)-(151,3) = "::"
+ │ ├── name: :<<
+ │ ├── message_loc: (151,3)-(151,5) = "<<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (153,0)-(153,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (153,0)-(153,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (153,1)-(153,3) = "::"
+ │ ├── name: :-
+ │ ├── message_loc: (153,3)-(153,4) = "-"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (155,0)-(155,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (155,0)-(155,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (155,1)-(155,3) = "::"
+ │ ├── name: :%
+ │ ├── message_loc: (155,3)-(155,4) = "%"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (157,0)-(157,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (157,0)-(157,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (157,1)-(157,3) = "::"
+ │ ├── name: :%
+ │ ├── message_loc: (157,3)-(157,4) = "%"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (157,4)-(157,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (157,4)-(157,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :i
+ │ │ ├── message_loc: (157,4)-(157,5) = "i"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (159,0)-(159,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (159,0)-(159,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (159,1)-(159,3) = "::"
+ │ ├── name: :%
+ │ ├── message_loc: (159,3)-(159,4) = "%"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (159,4)-(159,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (159,4)-(159,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :w
+ │ │ ├── message_loc: (159,4)-(159,5) = "w"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (161,0)-(161,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (161,0)-(161,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (161,1)-(161,3) = "::"
+ │ ├── name: :%
+ │ ├── message_loc: (161,3)-(161,4) = "%"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (161,4)-(161,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (161,4)-(161,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :x
+ │ │ ├── message_loc: (161,4)-(161,5) = "x"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (163,0)-(163,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (163,0)-(163,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (163,1)-(163,3) = "::"
+ │ ├── name: :%
+ │ ├── message_loc: (163,3)-(163,4) = "%"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (163,4)-(163,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ConstantReadNode (location: (163,4)-(163,5))
+ │ │ └── name: :I
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (165,0)-(165,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (165,0)-(165,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (165,1)-(165,3) = "::"
+ │ ├── name: :%
+ │ ├── message_loc: (165,3)-(165,4) = "%"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (165,4)-(165,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ConstantReadNode (location: (165,4)-(165,5))
+ │ │ └── name: :W
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (167,0)-(167,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (167,0)-(167,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (167,1)-(167,3) = "::"
+ │ ├── name: :|
+ │ ├── message_loc: (167,3)-(167,4) = "|"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (169,0)-(169,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (169,0)-(169,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (169,1)-(169,3) = "::"
+ │ ├── name: :+
+ │ ├── message_loc: (169,3)-(169,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (171,0)-(171,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (171,0)-(171,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (171,1)-(171,3) = "::"
+ │ ├── name: :/
+ │ ├── message_loc: (171,3)-(171,4) = "/"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (173,0)-(173,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (173,0)-(173,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (173,1)-(173,3) = "::"
+ │ ├── name: :*
+ │ ├── message_loc: (173,3)-(173,4) = "*"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (175,0)-(175,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (175,0)-(175,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (175,1)-(175,3) = "::"
+ │ ├── name: :**
+ │ ├── message_loc: (175,3)-(175,5) = "**"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (177,0)-(177,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (177,0)-(177,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (177,1)-(177,3) = "::"
+ │ ├── name: :~
+ │ ├── message_loc: (177,3)-(177,4) = "~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ConstantPathNode (location: (179,0)-(180,1))
+ │ ├── parent:
+ │ │ @ CallNode (location: (179,0)-(179,4))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ ConstantReadNode (location: (179,0)-(179,1))
+ │ │ │ └── name: :A
+ │ │ ├── call_operator_loc: (179,1)-(179,3) = "::"
+ │ │ ├── name: :_
+ │ │ ├── message_loc: (179,3)-(179,4) = "_"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (180,0)-(180,1))
+ │ │ └── name: :C
+ │ └── delimiter_loc: (179,4)-(179,6) = "::"
+ └── @ RangeNode (location: (182,0)-(184,10))
+ ├── flags: ∅
+ ├── left:
+ │ @ CallNode (location: (182,0)-(182,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (182,0)-(182,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (182,1)-(182,3) = "::"
+ │ ├── name: :_
+ │ ├── message_loc: (182,3)-(182,4) = "_"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── right:
+ │ @ CallNode (location: (184,0)-(184,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (184,0)-(184,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (184,1)-(184,3) = "::"
+ │ ├── name: :__END__
+ │ ├── message_loc: (184,3)-(184,10) = "__END__"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (182,4)-(182,6) = ".."
diff --git a/test/prism/snapshots/dash_heredocs.txt b/test/prism/snapshots/dash_heredocs.txt
new file mode 100644
index 0000000000..bd2b05ea0d
--- /dev/null
+++ b/test/prism/snapshots/dash_heredocs.txt
@@ -0,0 +1,260 @@
+@ ProgramNode (location: (1,0)-(57,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(57,11))
+ └── body: (length: 13)
+ ├── @ StringNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,6) = "<<-EOF"
+ │ ├── content_loc: (2,0)-(3,0) = " a\n"
+ │ ├── closing_loc: (3,0)-(4,0) = "EOF\n"
+ │ └── unescaped: " a\n"
+ ├── @ CallNode (location: (5,0)-(5,20))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (5,0)-(5,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (5,0)-(5,8) = "<<-FIRST"
+ │ │ ├── content_loc: (6,0)-(7,0) = " a\n"
+ │ │ ├── closing_loc: (7,0)-(8,0) = "FIRST\n"
+ │ │ └── unescaped: " a\n"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (5,9)-(5,10) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,11)-(5,20))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (5,11)-(5,20))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (5,11)-(5,20) = "<<-SECOND"
+ │ │ ├── content_loc: (8,0)-(9,0) = " b\n"
+ │ │ ├── closing_loc: (9,0)-(10,0) = "SECOND\n"
+ │ │ └── unescaped: " b\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ InterpolatedXStringNode (location: (11,0)-(11,8))
+ │ ├── opening_loc: (11,0)-(11,8) = "<<-`EOF`"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (12,0)-(13,0))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (12,0)-(13,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (13,0)-(13,4))
+ │ │ │ ├── opening_loc: (13,0)-(13,2) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (13,2)-(13,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (13,2)-(13,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (13,2)-(13,3) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (13,3)-(13,4) = "}"
+ │ │ └── @ StringNode (location: (13,4)-(14,0))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (13,4)-(14,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (14,0)-(15,0) = "EOF\n"
+ ├── @ StringNode (location: (16,0)-(16,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (16,0)-(16,6) = "<<-EOF"
+ │ ├── content_loc: (17,0)-(18,0) = " a\n"
+ │ ├── closing_loc: (18,0)-(19,0) = "EOF\n"
+ │ └── unescaped: " a\n"
+ ├── @ StringNode (location: (20,0)-(20,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (20,0)-(20,6) = "<<-EOF"
+ │ ├── content_loc: (21,0)-(23,0) = " a\n b\n"
+ │ ├── closing_loc: (23,0)-(24,0) = " EOF\n"
+ │ └── unescaped: " a\n b\n"
+ ├── @ InterpolatedStringNode (location: (25,0)-(25,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (25,0)-(25,8) = "<<-\"EOF\""
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (26,0)-(27,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (26,0)-(27,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (27,0)-(27,4))
+ │ │ │ ├── opening_loc: (27,0)-(27,2) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (27,2)-(27,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (27,2)-(27,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (27,2)-(27,3) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (27,3)-(27,4) = "}"
+ │ │ └── @ StringNode (location: (27,4)-(28,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (27,4)-(28,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (28,0)-(29,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (30,0)-(30,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (30,0)-(30,6) = "<<-EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (31,0)-(32,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (31,0)-(32,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (32,0)-(32,4))
+ │ │ │ ├── opening_loc: (32,0)-(32,2) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (32,2)-(32,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (32,2)-(32,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (32,2)-(32,3) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (32,3)-(32,4) = "}"
+ │ │ └── @ StringNode (location: (32,4)-(33,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (32,4)-(33,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (33,0)-(34,0) = "EOF\n"
+ ├── @ StringNode (location: (35,0)-(35,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (35,0)-(35,2) = "%#"
+ │ ├── content_loc: (35,2)-(35,5) = "abc"
+ │ ├── closing_loc: (35,5)-(35,6) = "#"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (37,0)-(37,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (37,0)-(37,6) = "<<-EOF"
+ │ ├── content_loc: (38,0)-(40,0) = " a\n b\n"
+ │ ├── closing_loc: (40,0)-(41,0) = "EOF\n"
+ │ └── unescaped: " a\n b\n"
+ ├── @ StringNode (location: (42,0)-(42,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (42,0)-(42,5) = "<<-''"
+ │ ├── content_loc: (43,0)-(43,0) = ""
+ │ ├── closing_loc: (43,0)-(44,0) = "\n"
+ │ └── unescaped: ""
+ ├── @ StringNode (location: (45,0)-(45,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (45,0)-(45,8) = "<<-'EOF'"
+ │ ├── content_loc: (46,0)-(47,0) = " a \#{1}\n"
+ │ ├── closing_loc: (47,0)-(48,0) = "EOF\n"
+ │ └── unescaped: " a \#{1}\n"
+ ├── @ CallNode (location: (49,0)-(49,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (49,0)-(49,4))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (49,0)-(49,4) = "<<-A"
+ │ │ ├── content_loc: (50,0)-(51,0) = " a\n"
+ │ │ ├── closing_loc: (51,0)-(52,0) = "A\n"
+ │ │ └── unescaped: " a\n"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (49,5)-(49,6) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (49,7)-(49,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (49,7)-(49,11))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (49,7)-(49,11) = "<<-B"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (52,0)-(53,2))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (52,0)-(53,2) = " b\n "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " b\n "
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (53,2)-(54,3))
+ │ │ │ │ ├── opening_loc: (53,2)-(53,4) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (53,4)-(53,5))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (53,4)-(53,5))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ └── closing_loc: (54,2)-(54,3) = "}"
+ │ │ │ └── @ StringNode (location: (54,3)-(55,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (54,3)-(55,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (55,0)-(56,0) = "B\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (57,0)-(57,11))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ StringNode (location: (57,0)-(57,4))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (57,0)-(57,4) = "<<-A"
+ │ ├── content_loc: (58,0)-(59,0) = " a\n"
+ │ ├── closing_loc: (59,0)-(60,0) = "A\n"
+ │ └── unescaped: " a\n"
+ ├── call_operator_loc: ∅
+ ├── name: :+
+ ├── message_loc: (57,5)-(57,6) = "+"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (57,7)-(57,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (57,7)-(57,11))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (57,7)-(57,11) = "<<-B"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (60,0)-(61,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (60,0)-(61,2) = " b\n "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " b\n "
+ │ │ ├── @ EmbeddedStatementsNode (location: (61,2)-(62,4))
+ │ │ │ ├── opening_loc: (61,2)-(61,4) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (62,2)-(62,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (62,2)-(62,3))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── closing_loc: (62,3)-(62,4) = "}"
+ │ │ └── @ StringNode (location: (62,4)-(63,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (62,4)-(63,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (63,0)-(64,0) = "B\n"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/defined.txt b/test/prism/snapshots/defined.txt
new file mode 100644
index 0000000000..53a5081811
--- /dev/null
+++ b/test/prism/snapshots/defined.txt
@@ -0,0 +1,88 @@
+@ ProgramNode (location: (1,0)-(10,1))
+├── locals: [:x]
+└── statements:
+ @ StatementsNode (location: (1,0)-(10,1))
+ └── body: (length: 5)
+ ├── @ AndNode (location: (1,0)-(1,25))
+ │ ├── left:
+ │ │ @ DefinedNode (location: (1,0)-(1,10))
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rparen_loc: ∅
+ │ │ └── keyword_loc: (1,0)-(1,8) = "defined?"
+ │ ├── right:
+ │ │ @ DefinedNode (location: (1,15)-(1,25))
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,24)-(1,25))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── rparen_loc: ∅
+ │ │ └── keyword_loc: (1,15)-(1,23) = "defined?"
+ │ └── operator_loc: (1,11)-(1,14) = "and"
+ ├── @ DefinedNode (location: (3,0)-(3,16))
+ │ ├── lparen_loc: (3,8)-(3,9) = "("
+ │ ├── value:
+ │ │ @ LocalVariableOperatorWriteNode (location: (3,9)-(3,15))
+ │ │ ├── name_loc: (3,9)-(3,10) = "x"
+ │ │ ├── operator_loc: (3,11)-(3,13) = "%="
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,14)-(3,15))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── name: :x
+ │ │ ├── operator: :%
+ │ │ └── depth: 0
+ │ ├── rparen_loc: (3,15)-(3,16) = ")"
+ │ └── keyword_loc: (3,0)-(3,8) = "defined?"
+ ├── @ DefinedNode (location: (5,0)-(5,21))
+ │ ├── lparen_loc: (5,8)-(5,9) = "("
+ │ ├── value:
+ │ │ @ AndNode (location: (5,9)-(5,20))
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (5,9)-(5,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (5,9)-(5,12) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (5,17)-(5,20))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (5,17)-(5,20) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (5,13)-(5,16) = "and"
+ │ ├── rparen_loc: (5,20)-(5,21) = ")"
+ │ └── keyword_loc: (5,0)-(5,8) = "defined?"
+ ├── @ DefinedNode (location: (7,0)-(7,10))
+ │ ├── lparen_loc: ∅
+ │ ├── value:
+ │ │ @ IntegerNode (location: (7,9)-(7,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── rparen_loc: ∅
+ │ └── keyword_loc: (7,0)-(7,8) = "defined?"
+ └── @ DefinedNode (location: (9,0)-(10,1))
+ ├── lparen_loc: (9,8)-(9,9) = "("
+ ├── value:
+ │ @ StringNode (location: (9,9)-(9,14))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (9,9)-(9,10) = "\""
+ │ ├── content_loc: (9,10)-(9,13) = "foo"
+ │ ├── closing_loc: (9,13)-(9,14) = "\""
+ │ └── unescaped: "foo"
+ ├── rparen_loc: (10,0)-(10,1) = ")"
+ └── keyword_loc: (9,0)-(9,8) = "defined?"
diff --git a/test/prism/snapshots/dos_endings.txt b/test/prism/snapshots/dos_endings.txt
new file mode 100644
index 0000000000..1ae15e1e87
--- /dev/null
+++ b/test/prism/snapshots/dos_endings.txt
@@ -0,0 +1,110 @@
+@ ProgramNode (location: (1,0)-(17,20))
+├── locals: [:x, :a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(17,20))
+ └── body: (length: 5)
+ ├── @ CallNode (location: (1,0)-(2,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :puts
+ │ ├── message_loc: (1,0)-(1,4) = "puts"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,5)-(2,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (1,5)-(2,12))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (1,5)-(1,9))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "\""
+ │ │ │ │ ├── content_loc: (1,6)-(1,8) = "hi"
+ │ │ │ │ ├── closing_loc: (1,8)-(1,9) = "\""
+ │ │ │ │ └── unescaped: "hi"
+ │ │ │ └── @ StringNode (location: (2,5)-(2,12))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (2,5)-(2,6) = "\""
+ │ │ │ ├── content_loc: (2,6)-(2,11) = "there"
+ │ │ │ ├── closing_loc: (2,11)-(2,12) = "\""
+ │ │ │ └── unescaped: "there"
+ │ │ └── closing_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ArrayNode (location: (4,0)-(5,2))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ SymbolNode (location: (4,3)-(5,1))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (4,3)-(5,1) = "a\\\r\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\nb"
+ │ ├── opening_loc: (4,0)-(4,3) = "%I{"
+ │ └── closing_loc: (5,1)-(5,2) = "}"
+ ├── @ StringNode (location: (7,0)-(7,4))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(7,4) = "<<-E"
+ │ ├── content_loc: (8,0)-(11,0) = " 1 \\\r\n 2\r\n 3\r\n"
+ │ ├── closing_loc: (11,0)-(12,0) = "E\r\n"
+ │ └── unescaped: " 1 2\n 3\n"
+ ├── @ LocalVariableWriteNode (location: (13,0)-(15,0))
+ │ ├── name: :x
+ │ ├── depth: 0
+ │ ├── name_loc: (13,0)-(13,1) = "x"
+ │ ├── value:
+ │ │ @ StringNode (location: (13,4)-(15,0))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (13,4)-(14,0) = "%\r\n"
+ │ │ ├── content_loc: (14,0)-(14,0) = ""
+ │ │ ├── closing_loc: (14,0)-(15,0) = "\r\n"
+ │ │ └── unescaped: ""
+ │ └── operator_loc: (13,2)-(13,3) = "="
+ └── @ LocalVariableWriteNode (location: (17,0)-(17,20))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (17,0)-(17,1) = "a"
+ ├── value:
+ │ @ CallNode (location: (17,4)-(17,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (17,4)-(17,7) = "foo"
+ │ ├── opening_loc: (17,7)-(17,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (17,8)-(17,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (17,8)-(17,19))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ InterpolatedStringNode (location: (17,8)-(17,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (17,8)-(17,14) = "<<~EOF"
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (18,0)-(19,0))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (18,0)-(19,0) = "\r\n"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "\n"
+ │ │ │ │ └── @ StringNode (location: (19,0)-(20,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (19,0)-(20,0) = " baz\r\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "baz\n"
+ │ │ │ └── closing_loc: (20,0)-(21,0) = " EOF\r\n"
+ │ │ ├── call_operator_loc: (17,14)-(17,15) = "."
+ │ │ ├── name: :chop
+ │ │ ├── message_loc: (17,15)-(17,19) = "chop"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (17,19)-(17,20) = ")"
+ │ └── block: ∅
+ └── operator_loc: (17,2)-(17,3) = "="
diff --git a/test/prism/snapshots/dstring.txt b/test/prism/snapshots/dstring.txt
new file mode 100644
index 0000000000..3978a2f087
--- /dev/null
+++ b/test/prism/snapshots/dstring.txt
@@ -0,0 +1,85 @@
+@ ProgramNode (location: (1,0)-(29,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(29,1))
+ └── body: (length: 8)
+ ├── @ StringNode (location: (1,0)-(2,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── content_loc: (1,1)-(2,5) = "foo\n bar"
+ │ ├── closing_loc: (2,5)-(2,6) = "\""
+ │ └── unescaped: "foo\n bar"
+ ├── @ InterpolatedStringNode (location: (4,0)-(5,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (4,0)-(4,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (4,1)-(5,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (4,1)-(5,2) = "foo\n "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo\n "
+ │ │ └── @ EmbeddedStatementsNode (location: (5,2)-(5,8))
+ │ │ ├── opening_loc: (5,2)-(5,4) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (5,4)-(5,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (5,4)-(5,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (5,4)-(5,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (5,7)-(5,8) = "}"
+ │ └── closing_loc: (5,8)-(5,9) = "\""
+ ├── @ InterpolatedStringNode (location: (7,0)-(9,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (7,0)-(8,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (7,0)-(7,1) = "\""
+ │ │ │ ├── content_loc: (7,1)-(8,1) = "fo\no"
+ │ │ │ ├── closing_loc: (8,1)-(8,2) = "\""
+ │ │ │ └── unescaped: "fo\no"
+ │ │ └── @ StringNode (location: (8,3)-(9,2))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (8,3)-(8,4) = "\""
+ │ │ ├── content_loc: (8,4)-(9,1) = "ba\nr"
+ │ │ ├── closing_loc: (9,1)-(9,2) = "\""
+ │ │ └── unescaped: "ba\nr"
+ │ └── closing_loc: ∅
+ ├── @ StringNode (location: (11,0)-(13,1))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (11,0)-(11,1) = "\""
+ │ ├── content_loc: (11,1)-(13,0) = "\nfoo\\\n"
+ │ ├── closing_loc: (13,0)-(13,1) = "\""
+ │ └── unescaped: "\nfoo"
+ ├── @ StringNode (location: (15,0)-(17,1))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (15,0)-(15,1) = "\""
+ │ ├── content_loc: (15,1)-(17,0) = "\nfoo\\\\\n"
+ │ ├── closing_loc: (17,0)-(17,1) = "\""
+ │ └── unescaped: "\nfoo\\\n"
+ ├── @ StringNode (location: (19,0)-(21,1))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (19,0)-(19,1) = "\""
+ │ ├── content_loc: (19,1)-(21,0) = "\nfoo\\\\\\\n"
+ │ ├── closing_loc: (21,0)-(21,1) = "\""
+ │ └── unescaped: "\nfoo\\"
+ ├── @ StringNode (location: (23,0)-(25,1))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (23,0)-(23,1) = "\""
+ │ ├── content_loc: (23,1)-(25,0) = "\nfoo\\\\\\\\\n"
+ │ ├── closing_loc: (25,0)-(25,1) = "\""
+ │ └── unescaped: "\nfoo\\\\\n"
+ └── @ StringNode (location: (27,0)-(29,1))
+ ├── flags: ∅
+ ├── opening_loc: (27,0)-(27,1) = "\""
+ ├── content_loc: (27,1)-(29,0) = "\nfoo\\\\\\\\\\\n"
+ ├── closing_loc: (29,0)-(29,1) = "\""
+ └── unescaped: "\nfoo\\\\"
diff --git a/test/prism/snapshots/dsym_str.txt b/test/prism/snapshots/dsym_str.txt
new file mode 100644
index 0000000000..33a5e2da21
--- /dev/null
+++ b/test/prism/snapshots/dsym_str.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(2,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,6))
+ └── body: (length: 1)
+ └── @ SymbolNode (location: (1,0)-(2,6))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,2) = ":\""
+ ├── value_loc: (1,2)-(2,5) = "foo\n bar"
+ ├── closing_loc: (2,5)-(2,6) = "\""
+ └── unescaped: "foo\n bar"
diff --git a/test/prism/snapshots/embdoc_no_newline_at_end.txt b/test/prism/snapshots/embdoc_no_newline_at_end.txt
new file mode 100644
index 0000000000..3a21ce5559
--- /dev/null
+++ b/test/prism/snapshots/embdoc_no_newline_at_end.txt
@@ -0,0 +1,5 @@
+@ ProgramNode (location: (1,0)-(1,0))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,0))
+ └── body: (length: 0)
diff --git a/test/prism/snapshots/emoji_method_calls.txt b/test/prism/snapshots/emoji_method_calls.txt
new file mode 100644
index 0000000000..8f71181ac1
--- /dev/null
+++ b/test/prism/snapshots/emoji_method_calls.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,3)-(1,4) = "."
+ ├── name: :🌊=
+ ├── message_loc: (1,4)-(1,8) = "🌊"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,11)-(1,12))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,11)-(1,12))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/endless_methods.txt b/test/prism/snapshots/endless_methods.txt
new file mode 100644
index 0000000000..6e20c0deec
--- /dev/null
+++ b/test/prism/snapshots/endless_methods.txt
@@ -0,0 +1,107 @@
+@ ProgramNode (location: (1,0)-(5,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,22))
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,0)-(1,11))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,10)-(1,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (1,8)-(1,9) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (3,0)-(3,14))
+ │ ├── name: :bar
+ │ ├── name_loc: (3,4)-(3,7) = "bar"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,10)-(3,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,10)-(3,14))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :A
+ │ │ ├── message_loc: (3,10)-(3,11) = "A"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,12)-(3,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (3,12)-(3,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (3,12)-(3,13) = "\""
+ │ │ │ ├── content_loc: (3,13)-(3,13) = ""
+ │ │ │ ├── closing_loc: (3,13)-(3,14) = "\""
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (3,8)-(3,9) = "="
+ │ └── end_keyword_loc: ∅
+ └── @ DefNode (location: (5,0)-(5,22))
+ ├── name: :method
+ ├── name_loc: (5,4)-(5,10) = "method"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (5,13)-(5,22))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (5,13)-(5,22))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (5,13)-(5,18))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (5,13)-(5,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :+
+ │ │ ├── message_loc: (5,15)-(5,16) = "+"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,17)-(5,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,17)-(5,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (5,19)-(5,20) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,21)-(5,22))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,21)-(5,22))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: (5,11)-(5,12) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/endless_range_in_conditional.txt b/test/prism/snapshots/endless_range_in_conditional.txt
new file mode 100644
index 0000000000..1802c4faed
--- /dev/null
+++ b/test/prism/snapshots/endless_range_in_conditional.txt
@@ -0,0 +1,53 @@
+@ ProgramNode (location: (1,0)-(3,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,12))
+ └── body: (length: 3)
+ ├── @ IfNode (location: (1,0)-(1,13))
+ │ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ │ ├── predicate:
+ │ │ @ FlipFlopNode (location: (1,3)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (1,4)-(1,6) = ".."
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (1,10)-(1,13) = "end"
+ ├── @ IfNode (location: (2,0)-(2,12))
+ │ ├── if_keyword_loc: (2,0)-(2,2) = "if"
+ │ ├── predicate:
+ │ │ @ FlipFlopNode (location: (2,3)-(2,6))
+ │ │ ├── flags: ∅
+ │ │ ├── left: ∅
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (2,5)-(2,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (2,3)-(2,5) = ".."
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (2,9)-(2,12) = "end"
+ └── @ IfNode (location: (3,0)-(3,12))
+ ├── if_keyword_loc: (3,0)-(3,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (3,3)-(3,6))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (3,3)-(3,4))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right: ∅
+ │ └── operator_loc: (3,4)-(3,6) = ".."
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (3,9)-(3,12) = "end"
diff --git a/test/prism/snapshots/for.txt b/test/prism/snapshots/for.txt
new file mode 100644
index 0000000000..cc4bbc1166
--- /dev/null
+++ b/test/prism/snapshots/for.txt
@@ -0,0 +1,188 @@
+@ ProgramNode (location: (1,0)-(19,22))
+├── locals: [:i, :j, :k]
+└── statements:
+ @ StatementsNode (location: (1,0)-(19,22))
+ └── body: (length: 6)
+ ├── @ ForNode (location: (1,0)-(3,3))
+ │ ├── index:
+ │ │ @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ │ ├── name: :i
+ │ │ └── depth: 0
+ │ ├── collection:
+ │ │ @ RangeNode (location: (1,9)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 10
+ │ │ └── operator_loc: (1,10)-(1,12) = ".."
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,0)-(2,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (2,0)-(2,1))
+ │ │ ├── name: :i
+ │ │ └── depth: 0
+ │ ├── for_keyword_loc: (1,0)-(1,3) = "for"
+ │ ├── in_keyword_loc: (1,6)-(1,8) = "in"
+ │ ├── do_keyword_loc: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ ForNode (location: (5,0)-(5,22))
+ │ ├── index:
+ │ │ @ LocalVariableTargetNode (location: (5,4)-(5,5))
+ │ │ ├── name: :i
+ │ │ └── depth: 0
+ │ ├── collection:
+ │ │ @ RangeNode (location: (5,9)-(5,14))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (5,9)-(5,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (5,12)-(5,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 10
+ │ │ └── operator_loc: (5,10)-(5,12) = ".."
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,16)-(5,17))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (5,16)-(5,17))
+ │ │ ├── name: :i
+ │ │ └── depth: 0
+ │ ├── for_keyword_loc: (5,0)-(5,3) = "for"
+ │ ├── in_keyword_loc: (5,6)-(5,8) = "in"
+ │ ├── do_keyword_loc: ∅
+ │ └── end_keyword_loc: (5,19)-(5,22) = "end"
+ ├── @ ForNode (location: (7,0)-(9,3))
+ │ ├── index:
+ │ │ @ MultiTargetNode (location: (7,4)-(7,7))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (7,4)-(7,5))
+ │ │ │ │ ├── name: :i
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (7,6)-(7,7))
+ │ │ │ ├── name: :j
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: ∅
+ │ │ └── rparen_loc: ∅
+ │ ├── collection:
+ │ │ @ RangeNode (location: (7,11)-(7,16))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (7,11)-(7,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (7,14)-(7,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 10
+ │ │ └── operator_loc: (7,12)-(7,14) = ".."
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (8,0)-(8,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (8,0)-(8,1))
+ │ │ ├── name: :i
+ │ │ └── depth: 0
+ │ ├── for_keyword_loc: (7,0)-(7,3) = "for"
+ │ ├── in_keyword_loc: (7,8)-(7,10) = "in"
+ │ ├── do_keyword_loc: ∅
+ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ ├── @ ForNode (location: (11,0)-(13,3))
+ │ ├── index:
+ │ │ @ MultiTargetNode (location: (11,4)-(11,9))
+ │ │ ├── lefts: (length: 3)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (11,4)-(11,5))
+ │ │ │ │ ├── name: :i
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── @ LocalVariableTargetNode (location: (11,6)-(11,7))
+ │ │ │ │ ├── name: :j
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (11,8)-(11,9))
+ │ │ │ ├── name: :k
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: ∅
+ │ │ └── rparen_loc: ∅
+ │ ├── collection:
+ │ │ @ RangeNode (location: (11,13)-(11,18))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (11,13)-(11,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (11,16)-(11,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 10
+ │ │ └── operator_loc: (11,14)-(11,16) = ".."
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (12,0)-(12,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (12,0)-(12,1))
+ │ │ ├── name: :i
+ │ │ └── depth: 0
+ │ ├── for_keyword_loc: (11,0)-(11,3) = "for"
+ │ ├── in_keyword_loc: (11,10)-(11,12) = "in"
+ │ ├── do_keyword_loc: ∅
+ │ └── end_keyword_loc: (13,0)-(13,3) = "end"
+ ├── @ ForNode (location: (15,0)-(17,3))
+ │ ├── index:
+ │ │ @ LocalVariableTargetNode (location: (15,4)-(15,5))
+ │ │ ├── name: :i
+ │ │ └── depth: 0
+ │ ├── collection:
+ │ │ @ RangeNode (location: (15,9)-(15,14))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (15,9)-(15,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (15,12)-(15,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 10
+ │ │ └── operator_loc: (15,10)-(15,12) = ".."
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (16,0)-(16,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (16,0)-(16,1))
+ │ │ ├── name: :i
+ │ │ └── depth: 0
+ │ ├── for_keyword_loc: (15,0)-(15,3) = "for"
+ │ ├── in_keyword_loc: (15,6)-(15,8) = "in"
+ │ ├── do_keyword_loc: (15,15)-(15,17) = "do"
+ │ └── end_keyword_loc: (17,0)-(17,3) = "end"
+ └── @ ForNode (location: (19,0)-(19,22))
+ ├── index:
+ │ @ LocalVariableTargetNode (location: (19,4)-(19,5))
+ │ ├── name: :i
+ │ └── depth: 0
+ ├── collection:
+ │ @ RangeNode (location: (19,9)-(19,14))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (19,9)-(19,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ IntegerNode (location: (19,12)-(19,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ └── operator_loc: (19,10)-(19,12) = ".."
+ ├── statements:
+ │ @ StatementsNode (location: (19,16)-(19,17))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (19,16)-(19,17))
+ │ ├── name: :i
+ │ └── depth: 0
+ ├── for_keyword_loc: (19,0)-(19,3) = "for"
+ ├── in_keyword_loc: (19,6)-(19,8) = "in"
+ ├── do_keyword_loc: ∅
+ └── end_keyword_loc: (19,19)-(19,22) = "end"
diff --git a/test/prism/snapshots/global_variables.txt b/test/prism/snapshots/global_variables.txt
new file mode 100644
index 0000000000..9f775ed80d
--- /dev/null
+++ b/test/prism/snapshots/global_variables.txt
@@ -0,0 +1,191 @@
+@ ProgramNode (location: (1,0)-(93,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(93,4))
+ └── body: (length: 47)
+ ├── @ GlobalVariableReadNode (location: (1,0)-(1,16))
+ │ └── name: :$global_variable
+ ├── @ GlobalVariableReadNode (location: (3,0)-(3,2))
+ │ └── name: :$_
+ ├── @ GlobalVariableReadNode (location: (5,0)-(5,3))
+ │ └── name: :$-w
+ ├── @ GlobalVariableReadNode (location: (7,0)-(7,10))
+ │ └── name: :$LOAD_PATH
+ ├── @ GlobalVariableReadNode (location: (9,0)-(9,6))
+ │ └── name: :$stdin
+ ├── @ GlobalVariableReadNode (location: (11,0)-(11,7))
+ │ └── name: :$stdout
+ ├── @ GlobalVariableReadNode (location: (13,0)-(13,7))
+ │ └── name: :$stderr
+ ├── @ GlobalVariableReadNode (location: (15,0)-(15,2))
+ │ └── name: :$!
+ ├── @ GlobalVariableReadNode (location: (17,0)-(17,2))
+ │ └── name: :$?
+ ├── @ GlobalVariableReadNode (location: (19,0)-(19,2))
+ │ └── name: :$~
+ ├── @ BackReferenceReadNode (location: (21,0)-(21,2))
+ │ └── name: :$&
+ ├── @ BackReferenceReadNode (location: (23,0)-(23,2))
+ │ └── name: :$`
+ ├── @ BackReferenceReadNode (location: (25,0)-(25,2))
+ │ └── name: :$'
+ ├── @ BackReferenceReadNode (location: (27,0)-(27,2))
+ │ └── name: :$+
+ ├── @ GlobalVariableReadNode (location: (29,0)-(29,2))
+ │ └── name: :$:
+ ├── @ GlobalVariableReadNode (location: (31,0)-(31,2))
+ │ └── name: :$;
+ ├── @ GlobalVariableReadNode (location: (33,0)-(33,2))
+ │ └── name: :$,
+ ├── @ GlobalVariableReadNode (location: (35,0)-(35,6))
+ │ └── name: :$DEBUG
+ ├── @ GlobalVariableReadNode (location: (37,0)-(37,9))
+ │ └── name: :$FILENAME
+ ├── @ GlobalVariableReadNode (location: (39,0)-(39,2))
+ │ └── name: :$0
+ ├── @ GlobalVariableReadNode (location: (41,0)-(41,3))
+ │ └── name: :$-0
+ ├── @ GlobalVariableReadNode (location: (43,0)-(43,16))
+ │ └── name: :$LOADED_FEATURES
+ ├── @ GlobalVariableReadNode (location: (45,0)-(45,8))
+ │ └── name: :$VERBOSE
+ ├── @ GlobalVariableReadNode (location: (47,0)-(47,3))
+ │ └── name: :$-K
+ ├── @ SymbolNode (location: (49,0)-(49,17))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (49,0)-(49,1) = ":"
+ │ ├── value_loc: (49,1)-(49,17) = "$global_variable"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$global_variable"
+ ├── @ SymbolNode (location: (51,0)-(51,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (51,0)-(51,1) = ":"
+ │ ├── value_loc: (51,1)-(51,3) = "$_"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$_"
+ ├── @ SymbolNode (location: (53,0)-(53,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (53,0)-(53,1) = ":"
+ │ ├── value_loc: (53,1)-(53,4) = "$-w"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$-w"
+ ├── @ SymbolNode (location: (55,0)-(55,11))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (55,0)-(55,1) = ":"
+ │ ├── value_loc: (55,1)-(55,11) = "$LOAD_PATH"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$LOAD_PATH"
+ ├── @ SymbolNode (location: (57,0)-(57,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (57,0)-(57,1) = ":"
+ │ ├── value_loc: (57,1)-(57,7) = "$stdin"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$stdin"
+ ├── @ SymbolNode (location: (59,0)-(59,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (59,0)-(59,1) = ":"
+ │ ├── value_loc: (59,1)-(59,8) = "$stdout"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$stdout"
+ ├── @ SymbolNode (location: (61,0)-(61,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (61,0)-(61,1) = ":"
+ │ ├── value_loc: (61,1)-(61,8) = "$stderr"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$stderr"
+ ├── @ SymbolNode (location: (63,0)-(63,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (63,0)-(63,1) = ":"
+ │ ├── value_loc: (63,1)-(63,3) = "$!"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$!"
+ ├── @ SymbolNode (location: (65,0)-(65,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (65,0)-(65,1) = ":"
+ │ ├── value_loc: (65,1)-(65,3) = "$?"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$?"
+ ├── @ SymbolNode (location: (67,0)-(67,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (67,0)-(67,1) = ":"
+ │ ├── value_loc: (67,1)-(67,3) = "$~"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$~"
+ ├── @ SymbolNode (location: (69,0)-(69,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (69,0)-(69,1) = ":"
+ │ ├── value_loc: (69,1)-(69,3) = "$&"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$&"
+ ├── @ SymbolNode (location: (71,0)-(71,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (71,0)-(71,1) = ":"
+ │ ├── value_loc: (71,1)-(71,3) = "$`"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$`"
+ ├── @ SymbolNode (location: (73,0)-(73,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (73,0)-(73,1) = ":"
+ │ ├── value_loc: (73,1)-(73,3) = "$'"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$'"
+ ├── @ SymbolNode (location: (75,0)-(75,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (75,0)-(75,1) = ":"
+ │ ├── value_loc: (75,1)-(75,3) = "$+"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$+"
+ ├── @ SymbolNode (location: (77,0)-(77,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (77,0)-(77,1) = ":"
+ │ ├── value_loc: (77,1)-(77,3) = "$:"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$:"
+ ├── @ SymbolNode (location: (79,0)-(79,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (79,0)-(79,1) = ":"
+ │ ├── value_loc: (79,1)-(79,3) = "$;"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$;"
+ ├── @ SymbolNode (location: (81,0)-(81,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (81,0)-(81,1) = ":"
+ │ ├── value_loc: (81,1)-(81,7) = "$DEBUG"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$DEBUG"
+ ├── @ SymbolNode (location: (83,0)-(83,10))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (83,0)-(83,1) = ":"
+ │ ├── value_loc: (83,1)-(83,10) = "$FILENAME"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$FILENAME"
+ ├── @ SymbolNode (location: (85,0)-(85,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (85,0)-(85,1) = ":"
+ │ ├── value_loc: (85,1)-(85,3) = "$0"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$0"
+ ├── @ SymbolNode (location: (87,0)-(87,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (87,0)-(87,1) = ":"
+ │ ├── value_loc: (87,1)-(87,4) = "$-0"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$-0"
+ ├── @ SymbolNode (location: (89,0)-(89,17))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (89,0)-(89,1) = ":"
+ │ ├── value_loc: (89,1)-(89,17) = "$LOADED_FEATURES"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$LOADED_FEATURES"
+ ├── @ SymbolNode (location: (91,0)-(91,9))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (91,0)-(91,1) = ":"
+ │ ├── value_loc: (91,1)-(91,9) = "$VERBOSE"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$VERBOSE"
+ └── @ SymbolNode (location: (93,0)-(93,4))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (93,0)-(93,1) = ":"
+ ├── value_loc: (93,1)-(93,4) = "$-K"
+ ├── closing_loc: ∅
+ └── unescaped: "$-K"
diff --git a/test/prism/snapshots/hashes.txt b/test/prism/snapshots/hashes.txt
new file mode 100644
index 0000000000..7a3ac4b0ea
--- /dev/null
+++ b/test/prism/snapshots/hashes.txt
@@ -0,0 +1,384 @@
+@ ProgramNode (location: (1,0)-(28,9))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(28,9))
+ └── body: (length: 10)
+ ├── @ HashNode (location: (1,0)-(1,2))
+ │ ├── opening_loc: (1,0)-(1,1) = "{"
+ │ ├── elements: (length: 0)
+ │ └── closing_loc: (1,1)-(1,2) = "}"
+ ├── @ HashNode (location: (3,0)-(4,1))
+ │ ├── opening_loc: (3,0)-(3,1) = "{"
+ │ ├── elements: (length: 0)
+ │ └── closing_loc: (4,0)-(4,1) = "}"
+ ├── @ HashNode (location: (6,0)-(6,18))
+ │ ├── opening_loc: (6,0)-(6,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (6,2)-(6,8))
+ │ │ │ ├── key:
+ │ │ │ │ @ CallNode (location: (6,2)-(6,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (6,2)-(6,3) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (6,7)-(6,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (6,7)-(6,8) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (6,4)-(6,6) = "=>"
+ │ │ └── @ AssocNode (location: (6,10)-(6,16))
+ │ │ ├── key:
+ │ │ │ @ CallNode (location: (6,10)-(6,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (6,10)-(6,11) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (6,15)-(6,16))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (6,15)-(6,16) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (6,12)-(6,14) = "=>"
+ │ └── closing_loc: (6,17)-(6,18) = "}"
+ ├── @ HashNode (location: (8,0)-(8,15))
+ │ ├── opening_loc: (8,0)-(8,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (8,2)-(8,8))
+ │ │ │ ├── key:
+ │ │ │ │ @ CallNode (location: (8,2)-(8,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (8,2)-(8,3) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (8,7)-(8,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (8,7)-(8,8) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (8,4)-(8,6) = "=>"
+ │ │ └── @ AssocSplatNode (location: (8,10)-(8,13))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (8,12)-(8,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (8,12)-(8,13) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (8,10)-(8,12) = "**"
+ │ └── closing_loc: (8,14)-(8,15) = "}"
+ ├── @ HashNode (location: (10,0)-(16,5))
+ │ ├── opening_loc: (10,0)-(10,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (11,6)-(11,10))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (11,6)-(11,8))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (11,6)-(11,7) = "a"
+ │ │ │ │ ├── closing_loc: (11,7)-(11,8) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (11,9)-(11,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (11,9)-(11,10) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: ∅
+ │ │ └── @ AssocNode (location: (12,6)-(12,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (12,6)-(12,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (12,6)-(12,7) = "c"
+ │ │ │ ├── closing_loc: (12,7)-(12,8) = ":"
+ │ │ │ └── unescaped: "c"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (12,9)-(12,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (12,9)-(12,10) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (16,4)-(16,5) = "}"
+ ├── @ HashNode (location: (18,0)-(18,25))
+ │ ├── opening_loc: (18,0)-(18,1) = "{"
+ │ ├── elements: (length: 4)
+ │ │ ├── @ AssocNode (location: (18,2)-(18,6))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (18,2)-(18,4))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (18,2)-(18,3) = "a"
+ │ │ │ │ ├── closing_loc: (18,3)-(18,4) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (18,5)-(18,6))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (18,5)-(18,6) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── @ AssocNode (location: (18,8)-(18,12))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (18,8)-(18,10))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (18,8)-(18,9) = "c"
+ │ │ │ │ ├── closing_loc: (18,9)-(18,10) = ":"
+ │ │ │ │ └── unescaped: "c"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (18,11)-(18,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :d
+ │ │ │ │ ├── message_loc: (18,11)-(18,12) = "d"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── @ AssocSplatNode (location: (18,14)-(18,17))
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (18,16)-(18,17))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :e
+ │ │ │ │ ├── message_loc: (18,16)-(18,17) = "e"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (18,14)-(18,16) = "**"
+ │ │ └── @ AssocNode (location: (18,19)-(18,23))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (18,19)-(18,21))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (18,19)-(18,20) = "f"
+ │ │ │ ├── closing_loc: (18,20)-(18,21) = ":"
+ │ │ │ └── unescaped: "f"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (18,22)-(18,23))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :g
+ │ │ │ ├── message_loc: (18,22)-(18,23) = "g"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (18,24)-(18,25) = "}"
+ ├── @ HashNode (location: (20,0)-(20,12))
+ │ ├── opening_loc: (20,0)-(20,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (20,2)-(20,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (20,2)-(20,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (20,2)-(20,3) = "\""
+ │ │ │ ├── value_loc: (20,3)-(20,4) = "a"
+ │ │ │ ├── closing_loc: (20,4)-(20,6) = "\":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (20,7)-(20,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (20,8)-(20,10))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b?
+ │ │ │ │ ├── message_loc: (20,8)-(20,10) = "b?"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :!
+ │ │ │ ├── message_loc: (20,7)-(20,8) = "!"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (20,11)-(20,12) = "}"
+ ├── @ LocalVariableWriteNode (location: (22,0)-(22,5))
+ │ ├── name: :a
+ │ ├── depth: 0
+ │ ├── name_loc: (22,0)-(22,1) = "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (22,4)-(22,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (22,2)-(22,3) = "="
+ ├── @ CallNode (location: (23,0)-(26,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (23,0)-(23,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (23,4)-(26,3))
+ │ ├── locals: [:b]
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (24,2)-(25,20))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ LocalVariableWriteNode (location: (24,2)-(24,7))
+ │ │ │ ├── name: :b
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (24,2)-(24,3) = "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (24,6)-(24,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: (24,4)-(24,5) = "="
+ │ │ └── @ HashNode (location: (25,2)-(25,20))
+ │ │ ├── opening_loc: (25,2)-(25,3) = "{"
+ │ │ ├── elements: (length: 4)
+ │ │ │ ├── @ AssocNode (location: (25,4)-(25,6))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (25,4)-(25,6))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (25,4)-(25,5) = "a"
+ │ │ │ │ │ ├── closing_loc: (25,5)-(25,6) = ":"
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ ImplicitNode (location: (25,4)-(25,6))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ LocalVariableReadNode (location: (25,4)-(25,6))
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ └── depth: 1
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ ├── @ AssocNode (location: (25,8)-(25,10))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (25,8)-(25,10))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (25,8)-(25,9) = "b"
+ │ │ │ │ │ ├── closing_loc: (25,9)-(25,10) = ":"
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ ImplicitNode (location: (25,8)-(25,10))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ LocalVariableReadNode (location: (25,8)-(25,10))
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ ├── @ AssocNode (location: (25,12)-(25,14))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (25,12)-(25,14))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (25,12)-(25,13) = "c"
+ │ │ │ │ │ ├── closing_loc: (25,13)-(25,14) = ":"
+ │ │ │ │ │ └── unescaped: "c"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ ImplicitNode (location: (25,12)-(25,14))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ CallNode (location: (25,12)-(25,14))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :c
+ │ │ │ │ │ ├── message_loc: (25,12)-(25,13) = "c"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ └── @ AssocNode (location: (25,16)-(25,18))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (25,16)-(25,18))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (25,16)-(25,17) = "D"
+ │ │ │ │ ├── closing_loc: (25,17)-(25,18) = ":"
+ │ │ │ │ └── unescaped: "D"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (25,16)-(25,18))
+ │ │ │ │ └── value:
+ │ │ │ │ @ ConstantReadNode (location: (25,16)-(25,18))
+ │ │ │ │ └── name: :D
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (25,19)-(25,20) = "}"
+ │ ├── opening_loc: (23,4)-(23,6) = "do"
+ │ └── closing_loc: (26,0)-(26,3) = "end"
+ └── @ HashNode (location: (28,0)-(28,9))
+ ├── opening_loc: (28,0)-(28,1) = "{"
+ ├── elements: (length: 1)
+ │ └── @ AssocNode (location: (28,2)-(28,7))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (28,2)-(28,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (28,2)-(28,3) = "a"
+ │ │ ├── closing_loc: (28,3)-(28,4) = ":"
+ │ │ └── unescaped: "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (28,5)-(28,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: -1
+ │ └── operator_loc: ∅
+ └── closing_loc: (28,8)-(28,9) = "}"
diff --git a/test/prism/snapshots/heredoc.txt b/test/prism/snapshots/heredoc.txt
new file mode 100644
index 0000000000..3ca66dd989
--- /dev/null
+++ b/test/prism/snapshots/heredoc.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,6) = "<<TEXT"
+ ├── content_loc: (2,0)-(2,0) = ""
+ ├── closing_loc: (2,0)-(3,0) = "TEXT\n"
+ └── unescaped: ""
diff --git a/test/prism/snapshots/heredoc_with_carriage_returns.txt b/test/prism/snapshots/heredoc_with_carriage_returns.txt
new file mode 100644
index 0000000000..134f863234
--- /dev/null
+++ b/test/prism/snapshots/heredoc_with_carriage_returns.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,6) = "<<TEXT"
+ ├── content_loc: (2,0)-(2,0) = ""
+ ├── closing_loc: (2,0)-(3,0) = "TEXT\r\n"
+ └── unescaped: ""
diff --git a/test/prism/snapshots/heredoc_with_comment.txt b/test/prism/snapshots/heredoc_with_comment.txt
new file mode 100644
index 0000000000..f2225ca981
--- /dev/null
+++ b/test/prism/snapshots/heredoc_with_comment.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,15))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ StringNode (location: (1,0)-(1,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,9) = "<<-TARGET"
+ │ ├── content_loc: (2,0)-(3,0) = " content makes for an obvious error\r\n"
+ │ ├── closing_loc: (3,0)-(3,6) = "TARGET"
+ │ └── unescaped: " content makes for an obvious error\n"
+ ├── call_operator_loc: (1,9)-(1,10) = "."
+ ├── name: :chomp
+ ├── message_loc: (1,10)-(1,15) = "chomp"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/heredoc_with_escaped_newline_at_start.txt b/test/prism/snapshots/heredoc_with_escaped_newline_at_start.txt
new file mode 100644
index 0000000000..acc6b082fc
--- /dev/null
+++ b/test/prism/snapshots/heredoc_with_escaped_newline_at_start.txt
@@ -0,0 +1,67 @@
+@ ProgramNode (location: (1,0)-(5,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,25))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,25))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (1,0)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,0)-(1,9) = "<<-TARGET"
+ │ │ ├── content_loc: (2,0)-(2,0) = ""
+ │ │ ├── closing_loc: (2,0)-(3,0) = "TARGET\n"
+ │ │ └── unescaped: ""
+ │ ├── call_operator_loc: (1,9)-(1,10) = "."
+ │ ├── name: :gsub
+ │ ├── message_loc: (1,10)-(1,14) = "gsub"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,15)-(1,25))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ RegularExpressionNode (location: (1,15)-(1,21))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,15)-(1,16) = "/"
+ │ │ │ ├── content_loc: (1,16)-(1,20) = "^\\s{"
+ │ │ │ ├── closing_loc: (1,20)-(1,21) = "/"
+ │ │ │ └── unescaped: "^\\s{"
+ │ │ └── @ StringNode (location: (1,23)-(1,25))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,23)-(1,24) = "'"
+ │ │ ├── content_loc: (1,24)-(1,24) = ""
+ │ │ ├── closing_loc: (1,24)-(1,25) = "'"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,25))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ StringNode (location: (5,0)-(5,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (5,0)-(5,9) = "<<-TARGET"
+ │ ├── content_loc: (6,0)-(6,0) = ""
+ │ ├── closing_loc: (6,0)-(7,0) = "TARGET\r\n"
+ │ └── unescaped: ""
+ ├── call_operator_loc: (5,9)-(5,10) = "."
+ ├── name: :gsub
+ ├── message_loc: (5,10)-(5,14) = "gsub"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (5,15)-(5,25))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ RegularExpressionNode (location: (5,15)-(5,21))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,15)-(5,16) = "/"
+ │ │ ├── content_loc: (5,16)-(5,20) = "^\\s{"
+ │ │ ├── closing_loc: (5,20)-(5,21) = "/"
+ │ │ └── unescaped: "^\\s{"
+ │ └── @ StringNode (location: (5,23)-(5,25))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (5,23)-(5,24) = "'"
+ │ ├── content_loc: (5,24)-(5,24) = ""
+ │ ├── closing_loc: (5,24)-(5,25) = "'"
+ │ └── unescaped: ""
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/heredoc_with_trailing_newline.txt b/test/prism/snapshots/heredoc_with_trailing_newline.txt
new file mode 100644
index 0000000000..b064931aa8
--- /dev/null
+++ b/test/prism/snapshots/heredoc_with_trailing_newline.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,6) = "<<-END"
+ ├── content_loc: (2,0)-(2,0) = ""
+ ├── closing_loc: (2,0)-(2,3) = "END"
+ └── unescaped: ""
diff --git a/test/prism/snapshots/heredocs_leading_whitespace.txt b/test/prism/snapshots/heredocs_leading_whitespace.txt
new file mode 100644
index 0000000000..dbcb0d5a19
--- /dev/null
+++ b/test/prism/snapshots/heredocs_leading_whitespace.txt
@@ -0,0 +1,63 @@
+@ ProgramNode (location: (1,0)-(26,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(26,10))
+ └── body: (length: 6)
+ ├── @ StringNode (location: (1,0)-(1,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,10) = "<<-' FOO'"
+ │ ├── content_loc: (2,0)-(4,0) = "a\nb\n"
+ │ ├── closing_loc: (4,0)-(5,0) = " FOO\n"
+ │ └── unescaped: "a\nb\n"
+ ├── @ StringNode (location: (6,0)-(6,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (6,0)-(6,10) = "<<-\" FOO\""
+ │ ├── content_loc: (7,0)-(9,0) = "a\nb\n"
+ │ ├── closing_loc: (9,0)-(10,0) = " FOO\n"
+ │ └── unescaped: "a\nb\n"
+ ├── @ XStringNode (location: (11,0)-(11,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (11,0)-(11,10) = "<<-` FOO`"
+ │ ├── content_loc: (12,0)-(14,0) = "a\nb\n"
+ │ ├── closing_loc: (14,0)-(15,0) = " FOO\n"
+ │ └── unescaped: "a\nb\n"
+ ├── @ StringNode (location: (16,0)-(16,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (16,0)-(16,10) = "<<-' FOO'"
+ │ ├── content_loc: (17,0)-(19,0) = "a\nb\n"
+ │ ├── closing_loc: (19,0)-(20,0) = " FOO\n"
+ │ └── unescaped: "a\nb\n"
+ ├── @ InterpolatedStringNode (location: (21,0)-(21,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (21,0)-(21,10) = "<<~' FOO'"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (22,0)-(23,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (22,0)-(23,0) = "a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ StringNode (location: (23,0)-(24,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (23,0)-(24,0) = "b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (24,0)-(25,0) = " FOO\n"
+ └── @ InterpolatedStringNode (location: (26,0)-(26,10))
+ ├── flags: ∅
+ ├── opening_loc: (26,0)-(26,10) = "<<~' FOO'"
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (27,0)-(28,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (27,0)-(28,0) = "a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\n"
+ │ └── @ StringNode (location: (28,0)-(29,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (28,0)-(29,0) = "b\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "b\n"
+ └── closing_loc: (29,0)-(30,0) = " FOO\n"
diff --git a/test/prism/snapshots/heredocs_nested.txt b/test/prism/snapshots/heredocs_nested.txt
new file mode 100644
index 0000000000..f830b028c7
--- /dev/null
+++ b/test/prism/snapshots/heredocs_nested.txt
@@ -0,0 +1,94 @@
+@ ProgramNode (location: (1,0)-(12,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(12,4))
+ └── body: (length: 2)
+ ├── @ InterpolatedStringNode (location: (1,0)-(1,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,7) = "<<~RUBY"
+ │ ├── parts: (length: 4)
+ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(3,0) = "pre\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "pre\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (3,0)-(7,1))
+ │ │ │ ├── opening_loc: (3,0)-(3,2) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (4,0)-(4,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (4,0)-(4,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (4,0)-(4,6) = "<<RUBY"
+ │ │ │ │ ├── content_loc: (5,0)-(6,0) = " hello\n"
+ │ │ │ │ ├── closing_loc: (6,0)-(7,0) = "RUBY\n"
+ │ │ │ │ └── unescaped: " hello\n"
+ │ │ │ └── closing_loc: (7,0)-(7,1) = "}"
+ │ │ ├── @ StringNode (location: (7,1)-(8,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (7,1)-(8,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (8,0)-(9,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (8,0)-(9,0) = "post\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "post\n"
+ │ └── closing_loc: (9,0)-(10,0) = "RUBY\n"
+ └── @ InterpolatedStringNode (location: (12,0)-(12,4))
+ ├── flags: ∅
+ ├── opening_loc: (12,0)-(12,4) = "<<-A"
+ ├── parts: (length: 2)
+ │ ├── @ EmbeddedStatementsNode (location: (13,0)-(21,1))
+ │ │ ├── opening_loc: (13,0)-(13,2) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (14,0)-(14,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ InterpolatedStringNode (location: (14,0)-(14,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (14,0)-(14,4) = "<<-B"
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (15,0)-(19,1))
+ │ │ │ │ │ ├── opening_loc: (15,0)-(15,2) = "\#{"
+ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ @ StatementsNode (location: (16,0)-(16,4))
+ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ └── @ InterpolatedStringNode (location: (16,0)-(16,4))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ ├── opening_loc: (16,0)-(16,4) = "<<-C"
+ │ │ │ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (17,0)-(17,4))
+ │ │ │ │ │ │ │ │ ├── opening_loc: (17,0)-(17,2) = "\#{"
+ │ │ │ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ │ │ │ @ StatementsNode (location: (17,2)-(17,3))
+ │ │ │ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ │ │ │ └── @ IntegerNode (location: (17,2)-(17,3))
+ │ │ │ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ │ │ │ └── value: 3
+ │ │ │ │ │ │ │ │ └── closing_loc: (17,3)-(17,4) = "}"
+ │ │ │ │ │ │ │ └── @ StringNode (location: (17,4)-(18,0))
+ │ │ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ │ ├── content_loc: (17,4)-(18,0) = "\n"
+ │ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ │ └── unescaped: "\n"
+ │ │ │ │ │ │ └── closing_loc: (18,0)-(19,0) = "C\n"
+ │ │ │ │ │ └── closing_loc: (19,0)-(19,1) = "}"
+ │ │ │ │ └── @ StringNode (location: (19,1)-(20,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (19,1)-(20,0) = "\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "\n"
+ │ │ │ └── closing_loc: (20,0)-(21,0) = "B\n"
+ │ │ └── closing_loc: (21,0)-(21,1) = "}"
+ │ └── @ StringNode (location: (21,1)-(22,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (21,1)-(22,0) = "\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\n"
+ └── closing_loc: (22,0)-(23,0) = "A\n"
diff --git a/test/prism/snapshots/heredocs_with_ignored_newlines.txt b/test/prism/snapshots/heredocs_with_ignored_newlines.txt
new file mode 100644
index 0000000000..0f964ec294
--- /dev/null
+++ b/test/prism/snapshots/heredocs_with_ignored_newlines.txt
@@ -0,0 +1,70 @@
+@ ProgramNode (location: (1,0)-(4,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,8))
+ └── body: (length: 2)
+ ├── @ StringNode (location: (1,0)-(1,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,7) = "<<-HERE"
+ │ ├── content_loc: (2,0)-(2,0) = ""
+ │ ├── closing_loc: (2,0)-(3,0) = "HERE\n"
+ │ └── unescaped: ""
+ └── @ InterpolatedStringNode (location: (4,0)-(4,8))
+ ├── flags: ∅
+ ├── opening_loc: (4,0)-(4,8) = "<<~THERE"
+ ├── parts: (length: 9)
+ │ ├── @ StringNode (location: (5,0)-(6,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (5,0)-(6,0) = " way over\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "way over\n"
+ │ ├── @ StringNode (location: (6,0)-(7,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (6,0)-(7,0) = " <<HERE\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "<<HERE\n"
+ │ ├── @ StringNode (location: (7,0)-(8,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (7,0)-(8,0) = " not here\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " not here\n"
+ │ ├── @ StringNode (location: (8,0)-(9,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (8,0)-(9,0) = " HERE\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "HERE\n"
+ │ ├── @ StringNode (location: (9,0)-(10,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (9,0)-(10,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ ├── @ StringNode (location: (10,0)-(11,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (10,0)-(11,0) = " <<~BUT\\\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "<<~BUT"
+ │ ├── @ StringNode (location: (11,0)-(12,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (11,0)-(12,0) = " but\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " but\n"
+ │ ├── @ StringNode (location: (12,0)-(13,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (12,0)-(13,0) = " BUT\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "BUT\n"
+ │ └── @ StringNode (location: (13,0)-(14,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (13,0)-(14,0) = " there\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: " there\n"
+ └── closing_loc: (14,0)-(15,0) = "THERE\n"
diff --git a/test/prism/snapshots/heredocs_with_ignored_newlines_and_non_empty.txt b/test/prism/snapshots/heredocs_with_ignored_newlines_and_non_empty.txt
new file mode 100644
index 0000000000..df422f0c1c
--- /dev/null
+++ b/test/prism/snapshots/heredocs_with_ignored_newlines_and_non_empty.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,6) = "<<-EOE"
+ ├── content_loc: (2,0)-(4,0) = " some\n heredocs\n"
+ ├── closing_loc: (4,0)-(4,3) = "EOE"
+ └── unescaped: " some\n heredocs\n"
diff --git a/test/prism/snapshots/if.txt b/test/prism/snapshots/if.txt
new file mode 100644
index 0000000000..eb33d1699d
--- /dev/null
+++ b/test/prism/snapshots/if.txt
@@ -0,0 +1,530 @@
+@ ProgramNode (location: (1,0)-(42,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(42,3))
+ └── body: (length: 13)
+ ├── @ IfNode (location: (1,0)-(1,15))
+ │ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (1,3)-(1,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,9)-(1,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,9)-(1,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (1,12)-(1,15) = "end"
+ ├── @ IfNode (location: (3,0)-(4,12))
+ │ ├── if_keyword_loc: (3,0)-(3,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (3,3)-(3,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (4,0)-(4,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (4,0)-(4,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (4,2)-(4,12))
+ │ │ ├── else_keyword_loc: (4,2)-(4,6) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (4,7)-(4,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (4,7)-(4,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── end_keyword_loc: (4,9)-(4,12) = "end"
+ │ └── end_keyword_loc: (4,9)-(4,12) = "end"
+ ├── @ IfNode (location: (6,0)-(6,73))
+ │ ├── if_keyword_loc: (6,0)-(6,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (6,3)-(6,7))
+ │ ├── then_keyword_loc: (6,8)-(6,12) = "then"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (6,13)-(6,17))
+ │ │ └── body: (length: 1)
+ │ │ └── @ TrueNode (location: (6,13)-(6,17))
+ │ ├── consequent:
+ │ │ @ IfNode (location: (6,18)-(6,73))
+ │ │ ├── if_keyword_loc: (6,18)-(6,23) = "elsif"
+ │ │ ├── predicate:
+ │ │ │ @ FalseNode (location: (6,24)-(6,29))
+ │ │ ├── then_keyword_loc: (6,30)-(6,34) = "then"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (6,35)-(6,40))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ FalseNode (location: (6,35)-(6,40))
+ │ │ ├── consequent:
+ │ │ │ @ IfNode (location: (6,41)-(6,73))
+ │ │ │ ├── if_keyword_loc: (6,41)-(6,46) = "elsif"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ NilNode (location: (6,47)-(6,50))
+ │ │ │ ├── then_keyword_loc: (6,51)-(6,55) = "then"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (6,56)-(6,59))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ NilNode (location: (6,56)-(6,59))
+ │ │ │ ├── consequent:
+ │ │ │ │ @ ElseNode (location: (6,60)-(6,73))
+ │ │ │ │ ├── else_keyword_loc: (6,60)-(6,64) = "else"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (6,65)-(6,69))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ SelfNode (location: (6,65)-(6,69))
+ │ │ │ │ └── end_keyword_loc: (6,70)-(6,73) = "end"
+ │ │ │ └── end_keyword_loc: (6,70)-(6,73) = "end"
+ │ │ └── end_keyword_loc: (6,70)-(6,73) = "end"
+ │ └── end_keyword_loc: (6,70)-(6,73) = "end"
+ ├── @ IfNode (location: (8,0)-(8,9))
+ │ ├── if_keyword_loc: (8,2)-(8,4) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (8,5)-(8,9))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (8,0)-(8,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (8,0)-(8,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ CallNode (location: (10,0)-(10,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (10,0)-(10,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (10,4)-(10,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (10,6)-(10,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IfNode (location: (10,6)-(10,19))
+ │ │ ├── if_keyword_loc: (10,12)-(10,14) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (10,15)-(10,19))
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (10,6)-(10,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ BreakNode (location: (10,6)-(10,11))
+ │ │ │ ├── arguments: ∅
+ │ │ │ └── keyword_loc: (10,6)-(10,11) = "break"
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── opening_loc: (10,4)-(10,5) = "{"
+ │ └── closing_loc: (10,20)-(10,21) = "}"
+ ├── @ CallNode (location: (12,0)-(12,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (12,0)-(12,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (12,4)-(12,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (12,6)-(12,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IfNode (location: (12,6)-(12,18))
+ │ │ ├── if_keyword_loc: (12,11)-(12,13) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (12,14)-(12,18))
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (12,6)-(12,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ NextNode (location: (12,6)-(12,10))
+ │ │ │ ├── arguments: ∅
+ │ │ │ └── keyword_loc: (12,6)-(12,10) = "next"
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── opening_loc: (12,4)-(12,5) = "{"
+ │ └── closing_loc: (12,19)-(12,20) = "}"
+ ├── @ IfNode (location: (14,0)-(14,14))
+ │ ├── if_keyword_loc: (14,7)-(14,9) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (14,10)-(14,14))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (14,0)-(14,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ReturnNode (location: (14,0)-(14,6))
+ │ │ ├── keyword_loc: (14,0)-(14,6) = "return"
+ │ │ └── arguments: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ CallNode (location: (16,0)-(16,38))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (16,0)-(16,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (16,4)-(16,38))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (16,6)-(16,36))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IfNode (location: (16,6)-(16,36))
+ │ │ ├── if_keyword_loc: (16,6)-(16,8) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (16,9)-(16,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :exit_loop
+ │ │ │ ├── message_loc: (16,9)-(16,18) = "exit_loop"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: (16,19)-(16,23) = "then"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (16,24)-(16,32))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ BreakNode (location: (16,24)-(16,32))
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (16,30)-(16,32))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (16,30)-(16,32))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── keyword_loc: (16,24)-(16,29) = "break"
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: (16,33)-(16,36) = "end"
+ │ ├── opening_loc: (16,4)-(16,5) = "{"
+ │ └── closing_loc: (16,37)-(16,38) = "}"
+ ├── @ IfNode (location: (18,0)-(20,3))
+ │ ├── if_keyword_loc: (18,0)-(18,2) = "if"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (18,3)-(18,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (18,3)-(18,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (19,0)-(19,4) = "then"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (19,5)-(19,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (19,5)-(19,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (19,5)-(19,8) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (20,0)-(20,3) = "end"
+ ├── @ IfNode (location: (22,0)-(22,11))
+ │ ├── if_keyword_loc: (22,7)-(22,9) = "if"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (22,10)-(22,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (22,10)-(22,11) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (22,0)-(22,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IfNode (location: (22,0)-(22,6))
+ │ │ ├── if_keyword_loc: (22,2)-(22,4) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (22,5)-(22,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (22,5)-(22,6) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (22,0)-(22,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (22,0)-(22,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (22,0)-(22,1) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ IfNode (location: (24,0)-(27,3))
+ │ ├── if_keyword_loc: (24,0)-(24,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (24,3)-(24,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (25,2)-(25,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (25,2)-(25,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (25,2)-(25,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (25,4)-(25,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ KeywordHashNode (location: (25,4)-(25,6))
+ │ │ │ ├── flags: symbol_keys
+ │ │ │ └── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (25,4)-(25,6))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (25,4)-(25,6))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (25,4)-(25,5) = "b"
+ │ │ │ │ ├── closing_loc: (25,5)-(25,6) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (25,4)-(25,6))
+ │ │ │ │ └── value:
+ │ │ │ │ @ CallNode (location: (25,4)-(25,6))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (25,4)-(25,5) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (26,0)-(27,3))
+ │ │ ├── else_keyword_loc: (26,0)-(26,4) = "else"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (27,0)-(27,3) = "end"
+ │ └── end_keyword_loc: (27,0)-(27,3) = "end"
+ ├── @ IfNode (location: (29,0)-(31,3))
+ │ ├── if_keyword_loc: (29,0)-(29,2) = "if"
+ │ ├── predicate:
+ │ │ @ MatchPredicateNode (location: (29,3)-(29,12))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (29,3)-(29,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :type
+ │ │ │ ├── message_loc: (29,3)-(29,7) = "type"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (29,11)-(29,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (29,8)-(29,10) = "in"
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── consequent:
+ │ │ @ IfNode (location: (30,0)-(31,3))
+ │ │ ├── if_keyword_loc: (30,0)-(30,5) = "elsif"
+ │ │ ├── predicate:
+ │ │ │ @ MatchPredicateNode (location: (30,6)-(30,15))
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (30,6)-(30,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :type
+ │ │ │ │ ├── message_loc: (30,6)-(30,10) = "type"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── pattern:
+ │ │ │ │ @ ConstantReadNode (location: (30,14)-(30,15))
+ │ │ │ │ └── name: :B
+ │ │ │ └── operator_loc: (30,11)-(30,13) = "in"
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: (31,0)-(31,3) = "end"
+ │ └── end_keyword_loc: (31,0)-(31,3) = "end"
+ └── @ IfNode (location: (33,0)-(42,3))
+ ├── if_keyword_loc: (33,0)-(33,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (33,3)-(33,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f1
+ │ ├── message_loc: (33,3)-(33,5) = "f1"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (34,2)-(35,5))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (34,2)-(35,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :lambda
+ │ ├── message_loc: (34,2)-(34,8) = "lambda"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (34,9)-(35,5))
+ │ ├── locals: [:_]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (34,12)-(34,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (34,13)-(34,14))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (34,13)-(34,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :_
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (34,12)-(34,13) = "|"
+ │ │ └── closing_loc: (34,14)-(34,15) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (34,9)-(34,11) = "do"
+ │ └── closing_loc: (35,2)-(35,5) = "end"
+ ├── consequent:
+ │ @ IfNode (location: (36,0)-(42,3))
+ │ ├── if_keyword_loc: (36,0)-(36,5) = "elsif"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (36,6)-(36,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :f2
+ │ │ ├── message_loc: (36,6)-(36,8) = "f2"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (37,2)-(38,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (37,2)-(38,5))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :lambda
+ │ │ ├── message_loc: (37,2)-(37,8) = "lambda"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (37,9)-(38,5))
+ │ │ ├── locals: [:_]
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (37,12)-(37,15))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (37,13)-(37,14))
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (37,13)-(37,14))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :_
+ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (37,12)-(37,13) = "|"
+ │ │ │ └── closing_loc: (37,14)-(37,15) = "|"
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (37,9)-(37,11) = "do"
+ │ │ └── closing_loc: (38,2)-(38,5) = "end"
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (39,0)-(42,3))
+ │ │ ├── else_keyword_loc: (39,0)-(39,4) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (40,2)-(41,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (40,2)-(41,5))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :lambda
+ │ │ │ ├── message_loc: (40,2)-(40,8) = "lambda"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (40,9)-(41,5))
+ │ │ │ ├── locals: [:_]
+ │ │ │ ├── parameters:
+ │ │ │ │ @ BlockParametersNode (location: (40,12)-(40,15))
+ │ │ │ │ ├── parameters:
+ │ │ │ │ │ @ ParametersNode (location: (40,13)-(40,14))
+ │ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (40,13)-(40,14))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :_
+ │ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── locals: (length: 0)
+ │ │ │ │ ├── opening_loc: (40,12)-(40,13) = "|"
+ │ │ │ │ └── closing_loc: (40,14)-(40,15) = "|"
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (40,9)-(40,11) = "do"
+ │ │ │ └── closing_loc: (41,2)-(41,5) = "end"
+ │ │ └── end_keyword_loc: (42,0)-(42,3) = "end"
+ │ └── end_keyword_loc: (42,0)-(42,3) = "end"
+ └── end_keyword_loc: (42,0)-(42,3) = "end"
diff --git a/test/prism/snapshots/indented_file_end.txt b/test/prism/snapshots/indented_file_end.txt
new file mode 100644
index 0000000000..aa43ec5a1e
--- /dev/null
+++ b/test/prism/snapshots/indented_file_end.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,4)-(3,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,4)-(3,7))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,4)-(3,7))
+ ├── name: :hi
+ ├── name_loc: (1,8)-(1,10) = "hi"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,4)-(1,7) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (3,4)-(3,7) = "end"
diff --git a/test/prism/snapshots/integer_operations.txt b/test/prism/snapshots/integer_operations.txt
new file mode 100644
index 0000000000..4660928ad2
--- /dev/null
+++ b/test/prism/snapshots/integer_operations.txt
@@ -0,0 +1,635 @@
+@ ProgramNode (location: (1,0)-(63,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(63,7))
+ └── body: (length: 32)
+ ├── @ CallNode (location: (1,0)-(1,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (1,1)-(1,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,0)-(1,1) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (3,1)-(3,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :~
+ │ ├── message_loc: (3,0)-(3,1) = "~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (5,0)-(5,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!=
+ │ ├── message_loc: (5,2)-(5,4) = "!="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,5)-(5,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,5)-(5,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (7,0)-(7,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (7,0)-(7,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!~
+ │ ├── message_loc: (7,2)-(7,4) = "!~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,5)-(7,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (7,5)-(7,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (9,0)-(9,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (9,0)-(9,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :%
+ │ ├── message_loc: (9,2)-(9,3) = "%"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,4)-(9,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (9,4)-(9,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (11,0)-(11,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (11,0)-(11,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :&
+ │ ├── message_loc: (11,2)-(11,3) = "&"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,4)-(11,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (11,4)-(11,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (13,0)-(13,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (13,0)-(13,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :*
+ │ ├── message_loc: (13,2)-(13,3) = "*"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,4)-(13,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (13,4)-(13,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (15,0)-(15,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (15,0)-(15,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :**
+ │ ├── message_loc: (15,1)-(15,3) = "**"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,3)-(15,4))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (15,3)-(15,4))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (17,0)-(17,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (17,0)-(17,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (17,2)-(17,3) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (17,4)-(17,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (17,4)-(17,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (19,0)-(19,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (19,0)-(19,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :-
+ │ ├── message_loc: (19,2)-(19,3) = "-"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (19,4)-(19,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (19,4)-(19,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (21,0)-(21,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (21,0)-(21,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :/
+ │ ├── message_loc: (21,2)-(21,3) = "/"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (21,4)-(21,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (21,4)-(21,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (23,0)-(23,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (23,0)-(23,3))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (23,0)-(23,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :/
+ │ │ ├── message_loc: (23,1)-(23,2) = "/"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (23,2)-(23,3))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (23,2)-(23,3))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :/
+ │ ├── message_loc: (23,3)-(23,4) = "/"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (23,4)-(23,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (23,4)-(23,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (25,0)-(25,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (25,0)-(25,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<
+ │ ├── message_loc: (25,2)-(25,3) = "<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (25,4)-(25,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (25,4)-(25,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (27,0)-(27,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (27,0)-(27,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<<
+ │ ├── message_loc: (27,2)-(27,4) = "<<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,5)-(27,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (27,5)-(27,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (29,0)-(29,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (29,0)-(29,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<=
+ │ ├── message_loc: (29,2)-(29,4) = "<="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (29,5)-(29,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (29,5)-(29,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (31,0)-(31,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (31,0)-(31,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<=>
+ │ ├── message_loc: (31,2)-(31,5) = "<=>"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,6)-(31,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (31,6)-(31,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (33,0)-(33,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (33,0)-(33,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :==
+ │ ├── message_loc: (33,2)-(33,4) = "=="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (33,5)-(33,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (33,5)-(33,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (35,0)-(35,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (35,0)-(35,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :===
+ │ ├── message_loc: (35,2)-(35,5) = "==="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,6)-(35,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (35,6)-(35,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (37,0)-(37,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (37,0)-(37,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (37,2)-(37,4) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (37,5)-(37,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (37,5)-(37,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (39,0)-(39,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (39,0)-(39,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>
+ │ ├── message_loc: (39,2)-(39,3) = ">"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (39,4)-(39,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (39,4)-(39,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (41,0)-(41,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (41,0)-(41,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>=
+ │ ├── message_loc: (41,2)-(41,4) = ">="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (41,5)-(41,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (41,5)-(41,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (43,0)-(43,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (43,0)-(43,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>>
+ │ ├── message_loc: (43,2)-(43,4) = ">>"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (43,5)-(43,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (43,5)-(43,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (45,0)-(45,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (45,0)-(45,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :^
+ │ ├── message_loc: (45,2)-(45,3) = "^"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (45,4)-(45,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (45,4)-(45,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (47,0)-(47,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (47,0)-(47,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :|
+ │ ├── message_loc: (47,2)-(47,3) = "|"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (47,4)-(47,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (47,4)-(47,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ AndNode (location: (49,0)-(49,6))
+ │ ├── left:
+ │ │ @ IntegerNode (location: (49,0)-(49,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ IntegerNode (location: (49,5)-(49,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (49,2)-(49,4) = "&&"
+ ├── @ AndNode (location: (51,0)-(51,7))
+ │ ├── left:
+ │ │ @ IntegerNode (location: (51,0)-(51,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ IntegerNode (location: (51,6)-(51,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (51,2)-(51,5) = "and"
+ ├── @ CallNode (location: (53,0)-(53,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (53,0)-(53,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :*
+ │ ├── message_loc: (53,2)-(53,3) = "*"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (53,4)-(53,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (53,4)-(53,10))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (53,4)-(53,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :**
+ │ │ ├── message_loc: (53,6)-(53,8) = "**"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (53,9)-(53,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (53,9)-(53,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (55,0)-(55,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (55,0)-(55,5))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (55,0)-(55,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :*
+ │ │ ├── message_loc: (55,2)-(55,3) = "*"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (55,4)-(55,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (55,4)-(55,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (55,6)-(55,7) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (55,8)-(55,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (55,8)-(55,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ OrNode (location: (57,0)-(57,6))
+ │ ├── left:
+ │ │ @ IntegerNode (location: (57,0)-(57,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ IntegerNode (location: (57,5)-(57,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (57,2)-(57,4) = "or"
+ ├── @ OrNode (location: (59,0)-(59,6))
+ │ ├── left:
+ │ │ @ IntegerNode (location: (59,0)-(59,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ IntegerNode (location: (59,5)-(59,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (59,2)-(59,4) = "||"
+ ├── @ CallNode (location: (61,0)-(61,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (61,0)-(61,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (61,2)-(61,3) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (61,4)-(61,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (61,4)-(61,9))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (61,4)-(61,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :*
+ │ │ ├── message_loc: (61,6)-(61,7) = "*"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (61,8)-(61,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (61,8)-(61,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ ParenthesesNode (location: (63,0)-(63,7))
+ ├── body:
+ │ @ StatementsNode (location: (63,1)-(63,6))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (63,1)-(63,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (63,1)-(63,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (63,3)-(63,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (63,5)-(63,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (63,5)-(63,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (63,0)-(63,1) = "("
+ └── closing_loc: (63,6)-(63,7) = ")"
diff --git a/test/prism/snapshots/keyword_method_names.txt b/test/prism/snapshots/keyword_method_names.txt
new file mode 100644
index 0000000000..6d59790b07
--- /dev/null
+++ b/test/prism/snapshots/keyword_method_names.txt
@@ -0,0 +1,173 @@
+@ ProgramNode (location: (1,0)-(29,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(29,3))
+ └── body: (length: 10)
+ ├── @ DefNode (location: (1,0)-(2,3))
+ │ ├── name: :def
+ │ ├── name_loc: (1,4)-(1,7) = "def"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (2,0)-(2,3) = "end"
+ ├── @ DefNode (location: (4,0)-(5,3))
+ │ ├── name: :ensure
+ │ ├── name_loc: (4,9)-(4,15) = "ensure"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (4,4)-(4,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (4,0)-(4,3) = "def"
+ │ ├── operator_loc: (4,8)-(4,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ CallNode (location: (7,0)-(10,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :private
+ │ ├── message_loc: (7,0)-(7,7) = "private"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,8)-(10,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ DefNode (location: (7,8)-(10,3))
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (7,12)-(7,15) = "foo"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (8,2)-(9,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (8,2)-(9,5))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (8,2)-(8,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (8,6)-(9,5))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (8,6)-(8,8) = "do"
+ │ │ │ └── closing_loc: (9,2)-(9,5) = "end"
+ │ │ ├── locals: []
+ │ │ ├── def_keyword_loc: (7,8)-(7,11) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (10,0)-(10,3) = "end"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ DefNode (location: (12,0)-(13,3))
+ │ ├── name: :m
+ │ ├── name_loc: (12,4)-(12,5) = "m"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (12,6)-(12,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (12,6)-(12,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ NoKeywordsParameterNode (location: (12,9)-(12,14))
+ │ │ │ ├── operator_loc: (12,9)-(12,11) = "**"
+ │ │ │ └── keyword_loc: (12,11)-(12,14) = "nil"
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (12,0)-(12,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (12,5)-(12,6) = "("
+ │ ├── rparen_loc: (12,14)-(12,15) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (13,0)-(13,3) = "end"
+ ├── @ DefNode (location: (15,0)-(16,3))
+ │ ├── name: :a
+ │ ├── name_loc: (15,17)-(15,18) = "a"
+ │ ├── receiver:
+ │ │ @ SourceEncodingNode (location: (15,4)-(15,16))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (15,0)-(15,3) = "def"
+ │ ├── operator_loc: (15,16)-(15,17) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (16,0)-(16,3) = "end"
+ ├── @ StringNode (location: (18,0)-(18,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (18,0)-(18,2) = "%{"
+ │ ├── content_loc: (18,2)-(18,5) = "abc"
+ │ ├── closing_loc: (18,5)-(18,6) = "}"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (20,0)-(20,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (20,0)-(20,2) = "%\""
+ │ ├── content_loc: (20,2)-(20,5) = "abc"
+ │ ├── closing_loc: (20,5)-(20,6) = "\""
+ │ └── unescaped: "abc"
+ ├── @ DefNode (location: (22,0)-(23,3))
+ │ ├── name: :a
+ │ ├── name_loc: (22,13)-(22,14) = "a"
+ │ ├── receiver:
+ │ │ @ SourceFileNode (location: (22,4)-(22,12))
+ │ │ ├── flags: ∅
+ │ │ └── filepath: "keyword_method_names.txt"
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (22,0)-(22,3) = "def"
+ │ ├── operator_loc: (22,12)-(22,13) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (23,0)-(23,3) = "end"
+ ├── @ DefNode (location: (25,0)-(26,3))
+ │ ├── name: :a
+ │ ├── name_loc: (25,13)-(25,14) = "a"
+ │ ├── receiver:
+ │ │ @ SourceLineNode (location: (25,4)-(25,12))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (25,0)-(25,3) = "def"
+ │ ├── operator_loc: (25,12)-(25,13) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (26,0)-(26,3) = "end"
+ └── @ DefNode (location: (28,0)-(29,3))
+ ├── name: :a
+ ├── name_loc: (28,9)-(28,10) = "a"
+ ├── receiver:
+ │ @ NilNode (location: (28,4)-(28,7))
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (28,0)-(28,3) = "def"
+ ├── operator_loc: (28,7)-(28,9) = "::"
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (29,0)-(29,3) = "end"
diff --git a/test/prism/snapshots/keywords.txt b/test/prism/snapshots/keywords.txt
new file mode 100644
index 0000000000..b3d5c5e1c3
--- /dev/null
+++ b/test/prism/snapshots/keywords.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(11,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,8))
+ └── body: (length: 6)
+ ├── @ CallNode (location: (1,0)-(1,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (1,0)-(1,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,4)-(1,12))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,6)-(1,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RedoNode (location: (1,6)-(1,10))
+ │ ├── opening_loc: (1,4)-(1,5) = "{"
+ │ └── closing_loc: (1,11)-(1,12) = "}"
+ ├── @ BeginNode (location: (3,0)-(3,25))
+ │ ├── begin_keyword_loc: (3,0)-(3,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (3,7)-(3,20))
+ │ │ ├── keyword_loc: (3,7)-(3,13) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,15)-(3,20))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ RetryNode (location: (3,15)-(3,20))
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (3,22)-(3,25) = "end"
+ ├── @ SelfNode (location: (5,0)-(5,4))
+ ├── @ SourceEncodingNode (location: (7,0)-(7,12))
+ ├── @ SourceFileNode (location: (9,0)-(9,8))
+ │ ├── flags: ∅
+ │ └── filepath: "keywords.txt"
+ └── @ SourceLineNode (location: (11,0)-(11,8))
diff --git a/test/prism/snapshots/lambda.txt b/test/prism/snapshots/lambda.txt
new file mode 100644
index 0000000000..0864b10369
--- /dev/null
+++ b/test/prism/snapshots/lambda.txt
@@ -0,0 +1,202 @@
+@ ProgramNode (location: (1,0)-(11,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,18))
+ └── body: (length: 5)
+ ├── @ LambdaNode (location: (1,0)-(3,4))
+ │ ├── locals: [:foo]
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (3,2)-(3,3) = "{"
+ │ ├── closing_loc: (3,3)-(3,4) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,2)-(3,1))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (2,2)-(2,5))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (2,2)-(2,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :foo
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ │ └── closing_loc: (3,0)-(3,1) = ")"
+ │ └── body: ∅
+ ├── @ LambdaNode (location: (5,0)-(5,18))
+ │ ├── locals: [:x]
+ │ ├── operator_loc: (5,0)-(5,2) = "->"
+ │ ├── opening_loc: (5,15)-(5,16) = "{"
+ │ ├── closing_loc: (5,17)-(5,18) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (5,2)-(5,14))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (5,3)-(5,13))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 1)
+ │ │ │ │ └── @ OptionalKeywordParameterNode (location: (5,3)-(5,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :x
+ │ │ │ │ ├── name_loc: (5,3)-(5,5) = "x:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ InterpolatedStringNode (location: (5,6)-(5,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (5,6)-(5,7) = "\""
+ │ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ │ ├── @ StringNode (location: (5,7)-(5,8))
+ │ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── content_loc: (5,7)-(5,8) = "b"
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ │ └── @ EmbeddedStatementsNode (location: (5,8)-(5,12))
+ │ │ │ │ │ ├── opening_loc: (5,8)-(5,10) = "\#{"
+ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ @ StatementsNode (location: (5,10)-(5,11))
+ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ └── @ CallNode (location: (5,10)-(5,11))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ │ ├── message_loc: (5,10)-(5,11) = "a"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ └── closing_loc: (5,11)-(5,12) = "}"
+ │ │ │ │ └── closing_loc: (5,12)-(5,13) = "\""
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (5,2)-(5,3) = "("
+ │ │ └── closing_loc: (5,13)-(5,14) = ")"
+ │ └── body: ∅
+ ├── @ LambdaNode (location: (7,0)-(7,15))
+ │ ├── locals: [:a]
+ │ ├── operator_loc: (7,0)-(7,2) = "->"
+ │ ├── opening_loc: (7,13)-(7,14) = "{"
+ │ ├── closing_loc: (7,14)-(7,15) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (7,2)-(7,12))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (7,3)-(7,11))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 1)
+ │ │ │ │ └── @ OptionalKeywordParameterNode (location: (7,3)-(7,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── name_loc: (7,3)-(7,5) = "a:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ CallNode (location: (7,6)-(7,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ CallNode (location: (7,6)-(7,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ ├── message_loc: (7,6)-(7,7) = "b"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :*
+ │ │ │ │ ├── message_loc: (7,8)-(7,9) = "*"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (7,10)-(7,11))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (7,10)-(7,11))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 3
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (7,2)-(7,3) = "("
+ │ │ └── closing_loc: (7,11)-(7,12) = ")"
+ │ └── body: ∅
+ ├── @ LambdaNode (location: (9,0)-(9,19))
+ │ ├── locals: [:foo]
+ │ ├── operator_loc: (9,0)-(9,2) = "->"
+ │ ├── opening_loc: (9,13)-(9,15) = "do"
+ │ ├── closing_loc: (9,16)-(9,19) = "end"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (9,3)-(9,12))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (9,3)-(9,12))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (9,3)-(9,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── name_loc: (9,3)-(9,6) = "foo"
+ │ │ │ │ ├── operator_loc: (9,7)-(9,8) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ CallNode (location: (9,9)-(9,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (9,9)-(9,12) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── body: ∅
+ └── @ LambdaNode (location: (11,0)-(11,18))
+ ├── locals: [:foo]
+ ├── operator_loc: (11,0)-(11,2) = "->"
+ ├── opening_loc: (11,12)-(11,14) = "do"
+ ├── closing_loc: (11,15)-(11,18) = "end"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (11,3)-(11,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (11,3)-(11,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (11,3)-(11,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── name_loc: (11,3)-(11,7) = "foo:"
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (11,8)-(11,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (11,8)-(11,11) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ └── body: ∅
diff --git a/test/prism/snapshots/method_calls.txt b/test/prism/snapshots/method_calls.txt
new file mode 100644
index 0000000000..de9ba71ae0
--- /dev/null
+++ b/test/prism/snapshots/method_calls.txt
@@ -0,0 +1,2459 @@
+@ ProgramNode (location: (1,0)-(156,19))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(156,19))
+ └── body: (length: 67)
+ ├── @ CallNode (location: (1,0)-(1,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (1,4)-(1,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,8)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,8)-(1,10) = "%{"
+ │ │ ├── content_loc: (1,10)-(1,13) = "baz"
+ │ │ ├── closing_loc: (1,13)-(1,14) = "}"
+ │ │ └── unescaped: "baz"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (3,0)-(3,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (3,1)-(3,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (3,2)-(3,3) = "b"
+ │ ├── opening_loc: (3,3)-(3,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,4)-(3,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (3,4)-(3,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (3,4)-(3,5) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (3,7)-(3,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (3,7)-(3,8) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (3,8)-(3,9) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (5,0)-(5,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (5,0)-(5,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (5,1)-(5,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (5,2)-(5,3) = "b"
+ │ ├── opening_loc: (5,3)-(5,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (5,4)-(5,5) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (7,0)-(9,7))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (7,0)-(8,6))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (7,0)-(7,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (8,2)-(8,3) = "."
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (8,3)-(8,6) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (9,2)-(9,4) = "&."
+ │ ├── name: :baz
+ │ ├── message_loc: (9,4)-(9,7) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (11,0)-(11,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a!
+ │ ├── message_loc: (11,0)-(11,2) = "a!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (13,0)-(13,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (13,0)-(13,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (13,0)-(13,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (13,1)-(13,2) = "."
+ │ ├── name: :call
+ │ ├── message_loc: ∅
+ │ ├── opening_loc: (13,2)-(13,3) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (13,3)-(13,4) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (15,0)-(15,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (15,0)-(15,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (15,0)-(15,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (15,1)-(15,2) = "."
+ │ ├── name: :call
+ │ ├── message_loc: ∅
+ │ ├── opening_loc: (15,2)-(15,3) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,3)-(15,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ IntegerNode (location: (15,3)-(15,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ IntegerNode (location: (15,6)-(15,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── @ IntegerNode (location: (15,9)-(15,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── closing_loc: (15,10)-(15,11) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (17,0)-(17,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (17,0)-(17,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (17,0)-(17,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (17,1)-(17,3) = "::"
+ │ ├── name: :b
+ │ ├── message_loc: (17,3)-(17,4) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (19,0)-(19,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (19,0)-(19,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (19,0)-(19,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (19,1)-(19,3) = "::"
+ │ ├── name: :b
+ │ ├── message_loc: (19,3)-(19,4) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (19,5)-(19,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (19,5)-(19,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (19,5)-(19,6) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (21,0)-(21,11))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ CallNode (location: (21,0)-(21,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (21,0)-(21,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (21,3)-(21,4) = "."
+ │ ├── name: :bar=
+ │ ├── message_loc: (21,4)-(21,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (21,10)-(21,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (21,10)-(21,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (23,0)-(23,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a?
+ │ ├── message_loc: (23,0)-(23,2) = "a?"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (25,0)-(25,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (25,0)-(25,1) = "a"
+ │ ├── opening_loc: (25,1)-(25,2) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (25,8)-(25,9) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (25,2)-(25,8))
+ │ ├── expression:
+ │ │ @ CallNode (location: (25,3)-(25,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :block
+ │ │ ├── message_loc: (25,3)-(25,8) = "block"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (25,2)-(25,3) = "&"
+ ├── @ CallNode (location: (27,0)-(27,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (27,0)-(27,1) = "a"
+ │ ├── opening_loc: (27,1)-(27,2) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,2)-(27,10))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (27,2)-(27,10))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (27,2)-(27,10))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (27,4)-(27,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :kwargs
+ │ │ │ ├── message_loc: (27,4)-(27,10) = "kwargs"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (27,2)-(27,4) = "**"
+ │ ├── closing_loc: (27,10)-(27,11) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (29,0)-(29,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (29,0)-(29,3))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (29,0)-(29,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (29,0)-(29,1) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (29,1)-(29,2) = "."
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (29,2)-(29,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (29,3)-(29,4) = "."
+ │ ├── name: :c
+ │ ├── message_loc: (29,4)-(29,5) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (31,0)-(31,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (31,0)-(31,1) = "a"
+ │ ├── opening_loc: (31,1)-(31,2) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,2)-(31,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (31,2)-(31,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (31,2)-(31,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (31,5)-(31,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (31,5)-(31,6) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (31,6)-(31,7) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (33,0)-(33,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (33,0)-(33,1) = "a"
+ │ ├── opening_loc: (33,1)-(33,2) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (33,2)-(33,3) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (35,0)-(35,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (35,0)-(35,1) = "a"
+ │ ├── opening_loc: (35,1)-(35,2) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,2)-(35,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (35,2)-(35,7))
+ │ │ ├── operator_loc: (35,2)-(35,3) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (35,3)-(35,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :args
+ │ │ ├── message_loc: (35,3)-(35,7) = "args"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (35,7)-(35,8) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (37,0)-(37,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (37,0)-(37,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (37,2)-(37,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (37,2)-(37,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (37,2)-(37,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (37,5)-(37,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (37,5)-(37,6) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (39,0)-(39,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (39,0)-(39,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (39,0)-(39,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (39,1)-(39,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (39,2)-(39,3) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (39,4)-(39,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (39,4)-(39,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (39,4)-(39,5) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (39,7)-(39,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (39,7)-(39,8) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (41,0)-(41,23))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ CallTargetNode (location: (41,0)-(41,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (41,0)-(41,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (41,0)-(41,3) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: (41,3)-(41,4) = "."
+ │ │ │ ├── name: :foo=
+ │ │ │ └── message_loc: (41,4)-(41,7) = "foo"
+ │ │ └── @ CallTargetNode (location: (41,9)-(41,16))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (41,9)-(41,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (41,9)-(41,12) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (41,12)-(41,13) = "."
+ │ │ ├── name: :bar=
+ │ │ └── message_loc: (41,13)-(41,16) = "bar"
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (41,17)-(41,18) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (41,19)-(41,23))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (41,19)-(41,20))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (41,22)-(41,23))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ CallNode (location: (43,0)-(43,4))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (43,0)-(43,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (43,0)-(43,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (43,1)-(43,3) = "&."
+ │ ├── name: :b
+ │ ├── message_loc: (43,3)-(43,4) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (45,0)-(45,5))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (45,0)-(45,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (45,0)-(45,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (45,1)-(45,3) = "&."
+ │ ├── name: :call
+ │ ├── message_loc: ∅
+ │ ├── opening_loc: (45,3)-(45,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (45,4)-(45,5) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (47,0)-(47,7))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (47,0)-(47,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (47,0)-(47,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (47,1)-(47,3) = "&."
+ │ ├── name: :b
+ │ ├── message_loc: (47,3)-(47,4) = "b"
+ │ ├── opening_loc: (47,4)-(47,5) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (47,5)-(47,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (47,5)-(47,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (47,5)-(47,6) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (47,6)-(47,7) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (49,0)-(49,6))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (49,0)-(49,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (49,0)-(49,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (49,1)-(49,3) = "&."
+ │ ├── name: :b
+ │ ├── message_loc: (49,3)-(49,4) = "b"
+ │ ├── opening_loc: (49,4)-(49,5) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (49,5)-(49,6) = ")"
+ │ └── block: ∅
+ ├── @ IfNode (location: (51,0)-(51,33))
+ │ ├── if_keyword_loc: (51,11)-(51,13) = "if"
+ │ ├── predicate:
+ │ │ @ AndNode (location: (51,14)-(51,33))
+ │ │ ├── left:
+ │ │ │ @ OrNode (location: (51,14)-(51,25))
+ │ │ │ ├── left:
+ │ │ │ │ @ CallNode (location: (51,14)-(51,18))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar?
+ │ │ │ │ ├── message_loc: (51,14)-(51,18) = "bar?"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ CallNode (location: (51,22)-(51,25))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (51,22)-(51,25) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (51,19)-(51,21) = "or"
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (51,30)-(51,33))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :qux
+ │ │ │ ├── message_loc: (51,30)-(51,33) = "qux"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (51,26)-(51,29) = "and"
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (51,0)-(51,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (51,0)-(51,10))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (51,0)-(51,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (51,4)-(51,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ SymbolNode (location: (51,4)-(51,6))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (51,4)-(51,5) = ":"
+ │ │ │ │ ├── value_loc: (51,5)-(51,6) = "a"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ └── @ SymbolNode (location: (51,8)-(51,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (51,8)-(51,9) = ":"
+ │ │ │ ├── value_loc: (51,9)-(51,10) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ CallNode (location: (53,0)-(56,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (53,0)-(53,3) = "foo"
+ │ ├── opening_loc: (53,3)-(53,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (53,4)-(55,4))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (53,4)-(53,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (53,4)-(53,5) = ":"
+ │ │ │ ├── value_loc: (53,5)-(53,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (55,2)-(55,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (55,2)-(55,3) = ":"
+ │ │ ├── value_loc: (55,3)-(55,4) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: (56,0)-(56,1) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (58,0)-(58,10))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (58,0)-(58,3) = "foo"
+ │ ├── opening_loc: (58,3)-(58,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (58,4)-(58,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (58,4)-(58,9))
+ │ │ ├── operator_loc: (58,4)-(58,5) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (58,5)-(58,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :rest
+ │ │ ├── message_loc: (58,5)-(58,9) = "rest"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (58,9)-(58,10) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (60,0)-(60,39))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (60,0)-(60,3) = "foo"
+ │ ├── opening_loc: (60,3)-(60,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (60,4)-(60,32))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (60,4)-(60,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (60,4)-(60,5) = ":"
+ │ │ │ ├── value_loc: (60,5)-(60,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ KeywordHashNode (location: (60,8)-(60,32))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (60,8)-(60,22))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (60,8)-(60,10))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (60,8)-(60,9) = ":"
+ │ │ │ │ ├── value_loc: (60,9)-(60,10) = "h"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "h"
+ │ │ │ ├── value:
+ │ │ │ │ @ ArrayNode (location: (60,14)-(60,22))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ │ ├── @ SymbolNode (location: (60,15)-(60,17))
+ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ ├── opening_loc: (60,15)-(60,16) = ":"
+ │ │ │ │ │ │ ├── value_loc: (60,16)-(60,17) = "x"
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── unescaped: "x"
+ │ │ │ │ │ └── @ SymbolNode (location: (60,19)-(60,21))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (60,19)-(60,20) = ":"
+ │ │ │ │ │ ├── value_loc: (60,20)-(60,21) = "y"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "y"
+ │ │ │ │ ├── opening_loc: (60,14)-(60,15) = "["
+ │ │ │ │ └── closing_loc: (60,21)-(60,22) = "]"
+ │ │ │ └── operator_loc: (60,11)-(60,13) = "=>"
+ │ │ └── @ AssocNode (location: (60,24)-(60,32))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (60,24)-(60,26))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (60,24)-(60,25) = ":"
+ │ │ │ ├── value_loc: (60,25)-(60,26) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (60,30)-(60,32))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (60,30)-(60,31) = ":"
+ │ │ │ ├── value_loc: (60,31)-(60,32) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── operator_loc: (60,27)-(60,29) = "=>"
+ │ ├── closing_loc: (60,39)-(60,40) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (60,34)-(60,39))
+ │ ├── expression:
+ │ │ @ SymbolNode (location: (60,35)-(60,39))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (60,35)-(60,36) = ":"
+ │ │ ├── value_loc: (60,36)-(60,39) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ └── operator_loc: (60,34)-(60,35) = "&"
+ ├── @ CallNode (location: (62,0)-(62,49))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :hi
+ │ ├── message_loc: (62,0)-(62,2) = "hi"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (62,3)-(62,49))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (62,3)-(62,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 123
+ │ │ └── @ HashNode (location: (62,8)-(62,49))
+ │ │ ├── opening_loc: (62,8)-(62,9) = "{"
+ │ │ ├── elements: (length: 3)
+ │ │ │ ├── @ AssocNode (location: (62,10)-(62,27))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (62,10)-(62,16))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (62,10)-(62,11) = ":"
+ │ │ │ │ │ ├── value_loc: (62,11)-(62,16) = "there"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "there"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ SymbolNode (location: (62,20)-(62,27))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (62,20)-(62,21) = ":"
+ │ │ │ │ │ ├── value_loc: (62,21)-(62,27) = "friend"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "friend"
+ │ │ │ │ └── operator_loc: (62,17)-(62,19) = "=>"
+ │ │ │ ├── @ AssocSplatNode (location: (62,29)-(62,33))
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ HashNode (location: (62,31)-(62,33))
+ │ │ │ │ │ ├── opening_loc: (62,31)-(62,32) = "{"
+ │ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ │ └── closing_loc: (62,32)-(62,33) = "}"
+ │ │ │ │ └── operator_loc: (62,29)-(62,31) = "**"
+ │ │ │ └── @ AssocNode (location: (62,35)-(62,47))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (62,35)-(62,42))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (62,35)-(62,41) = "whatup"
+ │ │ │ │ ├── closing_loc: (62,41)-(62,42) = ":"
+ │ │ │ │ └── unescaped: "whatup"
+ │ │ │ ├── value:
+ │ │ │ │ @ SymbolNode (location: (62,43)-(62,47))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (62,43)-(62,44) = ":"
+ │ │ │ │ ├── value_loc: (62,44)-(62,47) = "dog"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "dog"
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (62,48)-(62,49) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (64,0)-(64,36))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (64,0)-(64,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (64,4)-(64,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (64,4)-(64,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (64,4)-(64,5) = ":"
+ │ │ │ ├── value_loc: (64,5)-(64,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ KeywordHashNode (location: (64,8)-(64,15))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (64,8)-(64,15))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (64,8)-(64,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (64,8)-(64,9) = "b"
+ │ │ │ ├── closing_loc: (64,9)-(64,10) = ":"
+ │ │ │ └── unescaped: "b"
+ │ │ ├── value:
+ │ │ │ @ TrueNode (location: (64,11)-(64,15))
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (64,16)-(64,36))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (64,19)-(64,25))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (64,20)-(64,24))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (64,20)-(64,21))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (64,23)-(64,24))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (64,19)-(64,20) = "|"
+ │ │ └── closing_loc: (64,24)-(64,25) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (64,26)-(64,32))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (64,26)-(64,32))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (64,26)-(64,30) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (64,31)-(64,32))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (64,31)-(64,32))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (64,16)-(64,18) = "do"
+ │ └── closing_loc: (64,33)-(64,36) = "end"
+ ├── @ CallNode (location: (66,0)-(66,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :hi
+ │ ├── message_loc: (66,0)-(66,2) = "hi"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (66,3)-(66,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (66,3)-(66,17))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (66,3)-(66,17))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (66,3)-(66,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (66,3)-(66,8) = "there"
+ │ │ │ ├── closing_loc: (66,8)-(66,9) = ":"
+ │ │ │ └── unescaped: "there"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (66,10)-(66,17))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (66,10)-(66,11) = ":"
+ │ │ │ ├── value_loc: (66,11)-(66,17) = "friend"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "friend"
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (68,0)-(68,40))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :hi
+ │ ├── message_loc: (68,0)-(68,2) = "hi"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (68,3)-(68,40))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (68,3)-(68,40))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 3)
+ │ │ ├── @ AssocNode (location: (68,3)-(68,20))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (68,3)-(68,9))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (68,3)-(68,4) = ":"
+ │ │ │ │ ├── value_loc: (68,4)-(68,9) = "there"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "there"
+ │ │ │ ├── value:
+ │ │ │ │ @ SymbolNode (location: (68,13)-(68,20))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (68,13)-(68,14) = ":"
+ │ │ │ │ ├── value_loc: (68,14)-(68,20) = "friend"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "friend"
+ │ │ │ └── operator_loc: (68,10)-(68,12) = "=>"
+ │ │ ├── @ AssocSplatNode (location: (68,22)-(68,26))
+ │ │ │ ├── value:
+ │ │ │ │ @ HashNode (location: (68,24)-(68,26))
+ │ │ │ │ ├── opening_loc: (68,24)-(68,25) = "{"
+ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ └── closing_loc: (68,25)-(68,26) = "}"
+ │ │ │ └── operator_loc: (68,22)-(68,24) = "**"
+ │ │ └── @ AssocNode (location: (68,28)-(68,40))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (68,28)-(68,35))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (68,28)-(68,34) = "whatup"
+ │ │ │ ├── closing_loc: (68,34)-(68,35) = ":"
+ │ │ │ └── unescaped: "whatup"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (68,36)-(68,40))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (68,36)-(68,37) = ":"
+ │ │ │ ├── value_loc: (68,37)-(68,40) = "dog"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "dog"
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (70,0)-(70,41))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :hi
+ │ ├── message_loc: (70,0)-(70,2) = "hi"
+ │ ├── opening_loc: (70,2)-(70,3) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (70,3)-(70,40))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (70,3)-(70,40))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 3)
+ │ │ ├── @ AssocNode (location: (70,3)-(70,20))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (70,3)-(70,9))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (70,3)-(70,4) = ":"
+ │ │ │ │ ├── value_loc: (70,4)-(70,9) = "there"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "there"
+ │ │ │ ├── value:
+ │ │ │ │ @ SymbolNode (location: (70,13)-(70,20))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (70,13)-(70,14) = ":"
+ │ │ │ │ ├── value_loc: (70,14)-(70,20) = "friend"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "friend"
+ │ │ │ └── operator_loc: (70,10)-(70,12) = "=>"
+ │ │ ├── @ AssocSplatNode (location: (70,22)-(70,26))
+ │ │ │ ├── value:
+ │ │ │ │ @ HashNode (location: (70,24)-(70,26))
+ │ │ │ │ ├── opening_loc: (70,24)-(70,25) = "{"
+ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ └── closing_loc: (70,25)-(70,26) = "}"
+ │ │ │ └── operator_loc: (70,22)-(70,24) = "**"
+ │ │ └── @ AssocNode (location: (70,28)-(70,40))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (70,28)-(70,35))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (70,28)-(70,34) = "whatup"
+ │ │ │ ├── closing_loc: (70,34)-(70,35) = ":"
+ │ │ │ └── unescaped: "whatup"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (70,36)-(70,40))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (70,36)-(70,37) = ":"
+ │ │ │ ├── value_loc: (70,37)-(70,40) = "dog"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "dog"
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (70,40)-(70,41) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (72,0)-(72,35))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (72,0)-(72,3) = "foo"
+ │ ├── opening_loc: (72,3)-(72,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (72,4)-(72,26))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ HashNode (location: (72,4)-(72,26))
+ │ │ ├── opening_loc: (72,4)-(72,5) = "{"
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ AssocNode (location: (72,6)-(72,13))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (72,6)-(72,8))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (72,6)-(72,7) = "a"
+ │ │ │ │ │ ├── closing_loc: (72,7)-(72,8) = ":"
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ TrueNode (location: (72,9)-(72,13))
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ └── @ AssocNode (location: (72,15)-(72,23))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (72,15)-(72,17))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (72,15)-(72,16) = "b"
+ │ │ │ │ ├── closing_loc: (72,16)-(72,17) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ FalseNode (location: (72,18)-(72,23))
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (72,25)-(72,26) = "}"
+ │ ├── closing_loc: (72,35)-(72,36) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (72,28)-(72,35))
+ │ ├── expression:
+ │ │ @ SymbolNode (location: (72,29)-(72,35))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (72,29)-(72,30) = ":"
+ │ │ ├── value_loc: (72,30)-(72,35) = "block"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "block"
+ │ └── operator_loc: (72,28)-(72,29) = "&"
+ ├── @ CallNode (location: (74,0)-(74,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :hi
+ │ ├── message_loc: (74,0)-(74,2) = "hi"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (74,3)-(74,20))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (74,3)-(74,20))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (74,3)-(74,20))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (74,3)-(74,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (74,3)-(74,4) = ":"
+ │ │ │ ├── value_loc: (74,4)-(74,9) = "there"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "there"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (74,13)-(74,20))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (74,13)-(74,14) = ":"
+ │ │ │ ├── value_loc: (74,14)-(74,20) = "friend"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "friend"
+ │ │ └── operator_loc: (74,10)-(74,12) = "=>"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (76,0)-(78,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (76,0)-(76,3) = "foo"
+ │ ├── opening_loc: (76,3)-(76,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (76,4)-(77,2))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (76,4)-(76,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (76,4)-(76,5) = ":"
+ │ │ │ ├── value_loc: (76,5)-(76,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (77,0)-(77,2))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (77,0)-(77,1) = ":"
+ │ │ ├── value_loc: (77,1)-(77,2) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: (78,0)-(78,1) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (80,0)-(83,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (80,0)-(80,3) = "foo"
+ │ ├── opening_loc: (80,3)-(80,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (81,0)-(82,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (81,0)-(81,2))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (81,0)-(81,1) = ":"
+ │ │ │ ├── value_loc: (81,1)-(81,2) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ KeywordHashNode (location: (82,0)-(82,5))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (82,0)-(82,5))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (82,0)-(82,2))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (82,0)-(82,1) = "b"
+ │ │ │ ├── closing_loc: (82,1)-(82,2) = ":"
+ │ │ │ └── unescaped: "b"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (82,3)-(82,5))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (82,3)-(82,4) = ":"
+ │ │ │ ├── value_loc: (82,4)-(82,5) = "c"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "c"
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (83,0)-(83,1) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (85,0)-(85,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (85,0)-(85,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockArgumentNode (location: (85,4)-(85,11))
+ │ ├── expression:
+ │ │ @ SymbolNode (location: (85,5)-(85,11))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (85,5)-(85,6) = ":"
+ │ │ ├── value_loc: (85,6)-(85,11) = "block"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "block"
+ │ └── operator_loc: (85,4)-(85,5) = "&"
+ ├── @ CallNode (location: (87,0)-(87,30))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (87,0)-(87,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (87,4)-(87,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (87,4)-(87,21))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (87,4)-(87,11))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (87,4)-(87,6))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (87,4)-(87,5) = "a"
+ │ │ │ │ ├── closing_loc: (87,5)-(87,6) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ TrueNode (location: (87,7)-(87,11))
+ │ │ │ └── operator_loc: ∅
+ │ │ └── @ AssocNode (location: (87,13)-(87,21))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (87,13)-(87,15))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (87,13)-(87,14) = "b"
+ │ │ │ ├── closing_loc: (87,14)-(87,15) = ":"
+ │ │ │ └── unescaped: "b"
+ │ │ ├── value:
+ │ │ │ @ FalseNode (location: (87,16)-(87,21))
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockArgumentNode (location: (87,23)-(87,30))
+ │ ├── expression:
+ │ │ @ SymbolNode (location: (87,24)-(87,30))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (87,24)-(87,25) = ":"
+ │ │ ├── value_loc: (87,25)-(87,30) = "block"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "block"
+ │ └── operator_loc: (87,23)-(87,24) = "&"
+ ├── @ CallNode (location: (89,0)-(89,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :some_func
+ │ ├── message_loc: (89,0)-(89,9) = "some_func"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (89,10)-(89,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (89,10)-(89,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ KeywordHashNode (location: (89,13)-(89,21))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (89,13)-(89,21))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (89,13)-(89,19))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (89,13)-(89,18) = "kwarg"
+ │ │ │ ├── closing_loc: (89,18)-(89,19) = ":"
+ │ │ │ └── unescaped: "kwarg"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (89,20)-(89,21))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (91,0)-(91,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (91,0)-(91,6))
+ │ │ └── name: :Kernel
+ │ ├── call_operator_loc: (91,6)-(91,7) = "."
+ │ ├── name: :Integer
+ │ ├── message_loc: (91,7)-(91,14) = "Integer"
+ │ ├── opening_loc: (91,14)-(91,15) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (91,15)-(91,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (91,15)-(91,17))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ ├── closing_loc: (91,17)-(91,18) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (93,0)-(93,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (93,0)-(93,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :x
+ │ │ ├── message_loc: (93,0)-(93,1) = "x"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (93,1)-(93,2) = "."
+ │ ├── name: :each
+ │ ├── message_loc: (93,2)-(93,6) = "each"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (93,7)-(93,10))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (93,7)-(93,8) = "{"
+ │ └── closing_loc: (93,9)-(93,10) = "}"
+ ├── @ CallNode (location: (95,0)-(95,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (95,0)-(95,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (95,0)-(95,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (95,3)-(95,4) = "."
+ │ ├── name: :map
+ │ ├── message_loc: (95,4)-(95,7) = "map"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (95,8)-(95,14))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (95,10)-(95,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BackReferenceReadNode (location: (95,10)-(95,12))
+ │ │ └── name: :$&
+ │ ├── opening_loc: (95,8)-(95,9) = "{"
+ │ └── closing_loc: (95,13)-(95,14) = "}"
+ ├── @ CallNode (location: (97,0)-(97,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantPathNode (location: (97,0)-(97,4))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (97,0)-(97,1))
+ │ │ │ └── name: :A
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (97,3)-(97,4))
+ │ │ │ └── name: :B
+ │ │ └── delimiter_loc: (97,1)-(97,3) = "::"
+ │ ├── call_operator_loc: (97,4)-(97,6) = "::"
+ │ ├── name: :C
+ │ ├── message_loc: (97,6)-(97,7) = "C"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (97,8)-(97,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (97,8)-(97,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (97,8)-(97,9) = ":"
+ │ │ ├── value_loc: (97,9)-(97,12) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (99,0)-(99,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantPathNode (location: (99,0)-(99,4))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (99,0)-(99,1))
+ │ │ │ └── name: :A
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (99,3)-(99,4))
+ │ │ │ └── name: :B
+ │ │ └── delimiter_loc: (99,1)-(99,3) = "::"
+ │ ├── call_operator_loc: (99,4)-(99,6) = "::"
+ │ ├── name: :C
+ │ ├── message_loc: (99,6)-(99,7) = "C"
+ │ ├── opening_loc: (99,7)-(99,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (99,8)-(99,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (99,8)-(99,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (99,8)-(99,9) = ":"
+ │ │ ├── value_loc: (99,9)-(99,12) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── closing_loc: (99,12)-(99,13) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (101,0)-(101,17))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantPathNode (location: (101,0)-(101,4))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (101,0)-(101,1))
+ │ │ │ └── name: :A
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (101,3)-(101,4))
+ │ │ │ └── name: :B
+ │ │ └── delimiter_loc: (101,1)-(101,3) = "::"
+ │ ├── call_operator_loc: (101,4)-(101,6) = "::"
+ │ ├── name: :C
+ │ ├── message_loc: (101,6)-(101,7) = "C"
+ │ ├── opening_loc: (101,7)-(101,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (101,8)-(101,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (101,8)-(101,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (101,8)-(101,9) = ":"
+ │ │ ├── value_loc: (101,9)-(101,12) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── closing_loc: (101,12)-(101,13) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (101,14)-(101,17))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (101,14)-(101,15) = "{"
+ │ └── closing_loc: (101,16)-(101,17) = "}"
+ ├── @ CallNode (location: (103,0)-(103,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (103,0)-(103,3) = "foo"
+ │ ├── opening_loc: (103,3)-(103,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (103,4)-(103,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (103,4)-(103,11))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (103,4)-(103,11))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (103,4)-(103,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (103,4)-(103,5) = "\""
+ │ │ │ ├── value_loc: (103,5)-(103,6) = "a"
+ │ │ │ ├── closing_loc: (103,6)-(103,8) = "\":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (103,9)-(103,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: -1
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (103,11)-(103,12) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (105,0)-(105,28))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (105,0)-(105,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (105,4)-(105,28))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (105,4)-(105,28))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (105,4)-(105,28))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (105,4)-(105,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (105,4)-(105,7) = "bar"
+ │ │ │ ├── closing_loc: (105,7)-(105,8) = ":"
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── value:
+ │ │ │ @ HashNode (location: (105,9)-(105,28))
+ │ │ │ ├── opening_loc: (105,9)-(105,10) = "{"
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ AssocNode (location: (105,11)-(105,26))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (105,11)-(105,15))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (105,11)-(105,14) = "baz"
+ │ │ │ │ │ ├── closing_loc: (105,14)-(105,15) = ":"
+ │ │ │ │ │ └── unescaped: "baz"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (105,16)-(105,26))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :qux
+ │ │ │ │ │ ├── message_loc: (105,16)-(105,19) = "qux"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (105,20)-(105,26))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (105,20)-(105,22) = "do"
+ │ │ │ │ │ └── closing_loc: (105,23)-(105,26) = "end"
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ └── closing_loc: (105,27)-(105,28) = "}"
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (107,0)-(107,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (107,0)-(107,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (107,4)-(107,24))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (107,4)-(107,24))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (107,4)-(107,24))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (107,4)-(107,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (107,4)-(107,7) = "bar"
+ │ │ │ ├── closing_loc: (107,7)-(107,8) = ":"
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── value:
+ │ │ │ @ HashNode (location: (107,9)-(107,24))
+ │ │ │ ├── opening_loc: (107,9)-(107,10) = "{"
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ AssocSplatNode (location: (107,11)-(107,22))
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (107,13)-(107,22))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :kw
+ │ │ │ │ │ ├── message_loc: (107,13)-(107,15) = "kw"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (107,16)-(107,22))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (107,16)-(107,18) = "do"
+ │ │ │ │ │ └── closing_loc: (107,19)-(107,22) = "end"
+ │ │ │ │ └── operator_loc: (107,11)-(107,13) = "**"
+ │ │ │ └── closing_loc: (107,23)-(107,24) = "}"
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (109,0)-(109,36))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (109,0)-(109,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (109,4)-(109,29))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (109,4)-(109,29))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (109,4)-(109,5) = "\""
+ │ │ ├── parts: (length: 1)
+ │ │ │ └── @ EmbeddedStatementsNode (location: (109,5)-(109,28))
+ │ │ │ ├── opening_loc: (109,5)-(109,7) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (109,7)-(109,27))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (109,7)-(109,27))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ CallNode (location: (109,7)-(109,10))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :bar
+ │ │ │ │ │ ├── message_loc: (109,7)-(109,10) = "bar"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── call_operator_loc: (109,10)-(109,11) = "."
+ │ │ │ │ ├── name: :map
+ │ │ │ │ ├── message_loc: (109,11)-(109,14) = "map"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (109,15)-(109,27))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (109,18)-(109,23))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ StringNode (location: (109,18)-(109,23))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: (109,18)-(109,19) = "\""
+ │ │ │ │ │ ├── content_loc: (109,19)-(109,22) = "baz"
+ │ │ │ │ │ ├── closing_loc: (109,22)-(109,23) = "\""
+ │ │ │ │ │ └── unescaped: "baz"
+ │ │ │ │ ├── opening_loc: (109,15)-(109,17) = "do"
+ │ │ │ │ └── closing_loc: (109,24)-(109,27) = "end"
+ │ │ │ └── closing_loc: (109,27)-(109,28) = "}"
+ │ │ └── closing_loc: (109,28)-(109,29) = "\""
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (109,30)-(109,36))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (109,30)-(109,32) = "do"
+ │ └── closing_loc: (109,33)-(109,36) = "end"
+ ├── @ CallNode (location: (111,0)-(111,28))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (111,0)-(111,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (111,4)-(111,28))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ClassNode (location: (111,4)-(111,28))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (111,4)-(111,9) = "class"
+ │ │ ├── constant_path:
+ │ │ │ @ ConstantReadNode (location: (111,10)-(111,13))
+ │ │ │ └── name: :Bar
+ │ │ ├── inheritance_operator_loc: ∅
+ │ │ ├── superclass: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (111,14)-(111,24))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (111,14)-(111,24))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (111,14)-(111,17) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (111,18)-(111,24))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (111,18)-(111,20) = "do"
+ │ │ │ └── closing_loc: (111,21)-(111,24) = "end"
+ │ │ ├── end_keyword_loc: (111,25)-(111,28) = "end"
+ │ │ └── name: :Bar
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (113,0)-(113,29))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (113,0)-(113,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (113,4)-(113,29))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ModuleNode (location: (113,4)-(113,29))
+ │ │ ├── locals: []
+ │ │ ├── module_keyword_loc: (113,4)-(113,10) = "module"
+ │ │ ├── constant_path:
+ │ │ │ @ ConstantReadNode (location: (113,11)-(113,14))
+ │ │ │ └── name: :Bar
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (113,15)-(113,25))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (113,15)-(113,25))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (113,15)-(113,18) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (113,19)-(113,25))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (113,19)-(113,21) = "do"
+ │ │ │ └── closing_loc: (113,22)-(113,25) = "end"
+ │ │ ├── end_keyword_loc: (113,26)-(113,29) = "end"
+ │ │ └── name: :Bar
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (115,0)-(115,16))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (115,0)-(115,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (115,4)-(115,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ArrayNode (location: (115,4)-(115,16))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ CallNode (location: (115,5)-(115,15))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (115,5)-(115,8) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (115,9)-(115,15))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (115,9)-(115,11) = "do"
+ │ │ │ └── closing_loc: (115,12)-(115,15) = "end"
+ │ │ ├── opening_loc: (115,4)-(115,5) = "["
+ │ │ └── closing_loc: (115,15)-(115,16) = "]"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (117,0)-(117,28))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (117,0)-(117,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (117,2)-(117,28))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ BeginNode (location: (117,2)-(117,28))
+ │ │ ├── begin_keyword_loc: (117,2)-(117,7) = "begin"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (117,8)-(117,24))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (117,8)-(117,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ IntegerNode (location: (117,8)-(117,9))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── call_operator_loc: (117,9)-(117,10) = "."
+ │ │ │ ├── name: :times
+ │ │ │ ├── message_loc: (117,10)-(117,15) = "times"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (117,16)-(117,24))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (117,19)-(117,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (117,19)-(117,20))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── opening_loc: (117,16)-(117,18) = "do"
+ │ │ │ └── closing_loc: (117,21)-(117,24) = "end"
+ │ │ ├── rescue_clause: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (117,25)-(117,28) = "end"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (119,0)-(124,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (119,0)-(119,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (119,4)-(124,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (119,4)-(119,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (119,4)-(119,5) = ":"
+ │ │ │ ├── value_loc: (119,5)-(119,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ IfNode (location: (120,2)-(124,5))
+ │ │ ├── if_keyword_loc: (120,2)-(120,4) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (120,5)-(120,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── message_loc: (120,5)-(120,6) = "x"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (121,4)-(123,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (121,4)-(123,7))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (121,4)-(121,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (121,8)-(123,7))
+ │ │ │ ├── locals: [:a]
+ │ │ │ ├── parameters:
+ │ │ │ │ @ BlockParametersNode (location: (121,11)-(121,14))
+ │ │ │ │ ├── parameters:
+ │ │ │ │ │ @ ParametersNode (location: (121,12)-(121,13))
+ │ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (121,12)-(121,13))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :a
+ │ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── locals: (length: 0)
+ │ │ │ │ ├── opening_loc: (121,11)-(121,12) = "|"
+ │ │ │ │ └── closing_loc: (121,13)-(121,14) = "|"
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (122,6)-(122,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (122,6)-(122,7))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── opening_loc: (121,8)-(121,10) = "do"
+ │ │ │ └── closing_loc: (123,4)-(123,7) = "end"
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: (124,2)-(124,5) = "end"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (126,0)-(135,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (126,0)-(126,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (126,4)-(135,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ SymbolNode (location: (126,4)-(126,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (126,4)-(126,5) = ":"
+ │ │ │ ├── value_loc: (126,5)-(126,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ WhileNode (location: (127,2)-(131,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── keyword_loc: (127,2)-(127,7) = "while"
+ │ │ │ ├── closing_loc: (131,2)-(131,5) = "end"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ CallNode (location: (127,8)-(127,9))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :x
+ │ │ │ │ ├── message_loc: (127,8)-(127,9) = "x"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── statements:
+ │ │ │ @ StatementsNode (location: (128,4)-(130,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (128,4)-(130,7))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (128,4)-(128,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (128,8)-(130,7))
+ │ │ │ ├── locals: [:a]
+ │ │ │ ├── parameters:
+ │ │ │ │ @ BlockParametersNode (location: (128,11)-(128,14))
+ │ │ │ │ ├── parameters:
+ │ │ │ │ │ @ ParametersNode (location: (128,12)-(128,13))
+ │ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (128,12)-(128,13))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :a
+ │ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── locals: (length: 0)
+ │ │ │ │ ├── opening_loc: (128,11)-(128,12) = "|"
+ │ │ │ │ └── closing_loc: (128,13)-(128,14) = "|"
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (129,6)-(129,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (129,6)-(129,7))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── opening_loc: (128,8)-(128,10) = "do"
+ │ │ │ └── closing_loc: (130,4)-(130,7) = "end"
+ │ │ └── @ UntilNode (location: (132,2)-(135,5))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (132,2)-(132,7) = "until"
+ │ │ ├── closing_loc: (135,2)-(135,5) = "end"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (132,8)-(132,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── message_loc: (132,8)-(132,9) = "x"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (133,4)-(134,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (133,4)-(134,7))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (133,4)-(133,7) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (133,8)-(134,7))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (133,8)-(133,10) = "do"
+ │ │ └── closing_loc: (134,4)-(134,7) = "end"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (137,0)-(137,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ HashNode (location: (137,0)-(137,2))
+ │ │ ├── opening_loc: (137,0)-(137,1) = "{"
+ │ │ ├── elements: (length: 0)
+ │ │ └── closing_loc: (137,1)-(137,2) = "}"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (137,3)-(137,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (137,5)-(137,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (137,5)-(137,9))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :A
+ │ │ ├── message_loc: (137,5)-(137,6) = "A"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (137,7)-(137,9))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (137,7)-(137,8) = "{"
+ │ │ └── closing_loc: (137,8)-(137,9) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (139,0)-(139,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ HashNode (location: (139,0)-(139,2))
+ │ │ ├── opening_loc: (139,0)-(139,1) = "{"
+ │ │ ├── elements: (length: 0)
+ │ │ └── closing_loc: (139,1)-(139,2) = "}"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (139,3)-(139,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (139,5)-(139,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (139,5)-(139,16))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :A
+ │ │ ├── message_loc: (139,5)-(139,6) = "A"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (139,7)-(139,16))
+ │ │ ├── locals: [:a]
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (139,9)-(139,12))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (139,10)-(139,11))
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (139,10)-(139,11))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (139,9)-(139,10) = "|"
+ │ │ │ └── closing_loc: (139,11)-(139,12) = "|"
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (139,13)-(139,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (139,13)-(139,14))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (139,7)-(139,8) = "{"
+ │ │ └── closing_loc: (139,15)-(139,16) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (141,0)-(141,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (141,0)-(141,4))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :A
+ │ │ ├── message_loc: (141,0)-(141,1) = "A"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (141,2)-(141,4))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (141,2)-(141,3) = "{"
+ │ │ └── closing_loc: (141,3)-(141,4) = "}"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (141,5)-(141,6) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (141,7)-(141,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (141,7)-(141,11))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :A
+ │ │ ├── message_loc: (141,7)-(141,8) = "A"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (141,9)-(141,11))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (141,9)-(141,10) = "{"
+ │ │ └── closing_loc: (141,10)-(141,11) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (143,0)-(143,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (143,0)-(143,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :lst
+ │ │ ├── message_loc: (143,0)-(143,3) = "lst"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<<
+ │ ├── message_loc: (143,4)-(143,6) = "<<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (143,7)-(143,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (143,7)-(143,11))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :A
+ │ │ ├── message_loc: (143,7)-(143,8) = "A"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (143,9)-(143,11))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (143,9)-(143,10) = "{"
+ │ │ └── closing_loc: (143,10)-(143,11) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ InterpolatedStringNode (location: (145,0)-(145,17))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (145,0)-(145,1) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (145,1)-(145,16))
+ │ │ ├── opening_loc: (145,1)-(145,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (145,4)-(145,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (145,4)-(145,14))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :join
+ │ │ │ ├── message_loc: (145,4)-(145,8) = "join"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (145,9)-(145,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ ParenthesesNode (location: (145,9)-(145,14))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (145,10)-(145,13))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ StringNode (location: (145,10)-(145,13))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: (145,10)-(145,11) = "\""
+ │ │ │ │ │ ├── content_loc: (145,11)-(145,12) = " "
+ │ │ │ │ │ ├── closing_loc: (145,12)-(145,13) = "\""
+ │ │ │ │ │ └── unescaped: " "
+ │ │ │ │ ├── opening_loc: (145,9)-(145,10) = "("
+ │ │ │ │ └── closing_loc: (145,13)-(145,14) = ")"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (145,15)-(145,16) = "}"
+ │ └── closing_loc: (145,16)-(145,17) = "\""
+ ├── @ InterpolatedStringNode (location: (147,0)-(147,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (147,0)-(147,1) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (147,1)-(147,7))
+ │ │ ├── opening_loc: (147,1)-(147,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (147,3)-(147,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ ParenthesesNode (location: (147,3)-(147,6))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (147,4)-(147,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (147,4)-(147,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :v
+ │ │ │ │ ├── message_loc: (147,4)-(147,5) = "v"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (147,3)-(147,4) = "("
+ │ │ │ └── closing_loc: (147,5)-(147,6) = ")"
+ │ │ └── closing_loc: (147,6)-(147,7) = "}"
+ │ └── closing_loc: (147,7)-(147,8) = "\""
+ ├── @ DefNode (location: (149,0)-(149,18))
+ │ ├── name: :f
+ │ ├── name_loc: (149,4)-(149,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (149,6)-(149,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (149,6)-(149,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (149,6)-(149,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (149,10)-(149,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (149,10)-(149,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :p
+ │ │ ├── message_loc: (149,10)-(149,11) = "p"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (149,12)-(149,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SplatNode (location: (149,12)-(149,13))
+ │ │ │ ├── operator_loc: (149,12)-(149,13) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (149,0)-(149,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (149,5)-(149,6) = "("
+ │ ├── rparen_loc: (149,7)-(149,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (149,15)-(149,18) = "end"
+ ├── @ CallNode (location: (151,0)-(151,16))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (151,0)-(151,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (151,4)-(151,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (151,4)-(151,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ CallNode (location: (151,7)-(151,16))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :Bar
+ │ │ ├── message_loc: (151,7)-(151,10) = "Bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (151,11)-(151,16))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (151,13)-(151,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (151,13)-(151,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (151,11)-(151,12) = "{"
+ │ │ └── closing_loc: (151,15)-(151,16) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ LocalVariableWriteNode (location: (153,0)-(153,7))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (153,0)-(153,3) = "foo"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (153,6)-(153,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (153,4)-(153,5) = "="
+ ├── @ CallNode (location: (154,0)-(154,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (154,0)-(154,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (154,4)-(154,6))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (154,4)-(154,5) = "{"
+ │ └── closing_loc: (154,5)-(154,6) = "}"
+ └── @ CallNode (location: (156,0)-(156,19))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ InstanceVariableReadNode (location: (156,0)-(156,2))
+ │ └── name: :@a
+ ├── call_operator_loc: (156,2)-(156,3) = "."
+ ├── name: :b
+ ├── message_loc: (156,3)-(156,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (156,5)-(156,19))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (156,5)-(156,19))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (156,5)-(156,19))
+ │ ├── key:
+ │ │ @ InterpolatedSymbolNode (location: (156,5)-(156,16))
+ │ │ ├── opening_loc: (156,5)-(156,6) = "\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (156,6)-(156,7))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (156,6)-(156,7) = "c"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "c"
+ │ │ │ └── @ EmbeddedStatementsNode (location: (156,7)-(156,14))
+ │ │ │ ├── opening_loc: (156,7)-(156,9) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (156,9)-(156,13))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (156,9)-(156,13))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :name
+ │ │ │ │ ├── message_loc: (156,9)-(156,13) = "name"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (156,13)-(156,14) = "}"
+ │ │ └── closing_loc: (156,14)-(156,16) = "\":"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (156,17)-(156,19))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ └── operator_loc: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/methods.txt b/test/prism/snapshots/methods.txt
new file mode 100644
index 0000000000..22580494a4
--- /dev/null
+++ b/test/prism/snapshots/methods.txt
@@ -0,0 +1,2053 @@
+@ ProgramNode (location: (1,0)-(183,37))
+├── locals: [:a, :c, :foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(183,37))
+ └── body: (length: 69)
+ ├── @ DefNode (location: (1,0)-(2,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,8)-(1,18))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,18))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,12))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :bar
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :baz
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,17)-(1,18) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:bar, :baz]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ ├── rparen_loc: (1,18)-(1,19) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (2,0)-(2,3) = "end"
+ ├── @ DefNode (location: (4,0)-(5,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (4,4)-(4,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (4,8)-(4,44))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (4,8)-(4,18))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (4,9)-(4,12))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :bar
+ │ │ │ │ └── @ RequiredParameterNode (location: (4,14)-(4,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :baz
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (4,8)-(4,9) = "("
+ │ │ │ └── rparen_loc: (4,17)-(4,18) = ")"
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (4,20)-(4,32))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :optional
+ │ │ │ ├── name_loc: (4,20)-(4,28) = "optional"
+ │ │ │ ├── operator_loc: (4,29)-(4,30) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (4,31)-(4,32))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (4,34)-(4,44))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (4,35)-(4,38))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :bin
+ │ │ │ │ └── @ RequiredParameterNode (location: (4,40)-(4,43))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :bag
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (4,34)-(4,35) = "("
+ │ │ │ └── rparen_loc: (4,43)-(4,44) = ")"
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:bar, :baz, :optional, :bin, :bag]
+ │ ├── def_keyword_loc: (4,0)-(4,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (4,7)-(4,8) = "("
+ │ ├── rparen_loc: (4,44)-(4,45) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ DefNode (location: (8,0)-(8,18))
+ │ ├── name: :a
+ │ ├── name_loc: (8,4)-(8,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (8,0)-(8,18))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (8,7)-(8,18))
+ │ │ │ ├── ensure_keyword_loc: (8,7)-(8,13) = "ensure"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── end_keyword_loc: (8,15)-(8,18) = "end"
+ │ │ └── end_keyword_loc: (8,15)-(8,18) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (8,0)-(8,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (8,15)-(8,18) = "end"
+ ├── @ DefNode (location: (10,0)-(11,3))
+ │ ├── name: :a
+ │ ├── name_loc: (10,8)-(10,9) = "a"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (10,4)-(10,7))
+ │ │ ├── body:
+ │ │ │ @ CallNode (location: (10,5)-(10,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (10,5)-(10,6) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (10,4)-(10,5) = "("
+ │ │ └── closing_loc: (10,6)-(10,7) = ")"
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (10,0)-(10,3) = "def"
+ │ ├── operator_loc: (10,7)-(10,8) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ DefNode (location: (13,0)-(14,3))
+ │ ├── name: :b
+ │ ├── name_loc: (13,9)-(13,10) = "b"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (13,4)-(13,7))
+ │ │ ├── body:
+ │ │ │ @ CallNode (location: (13,5)-(13,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (13,5)-(13,6) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (13,4)-(13,5) = "("
+ │ │ └── closing_loc: (13,6)-(13,7) = ")"
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (13,0)-(13,3) = "def"
+ │ ├── operator_loc: (13,7)-(13,9) = "::"
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (14,0)-(14,3) = "end"
+ ├── @ DefNode (location: (16,0)-(17,3))
+ │ ├── name: :a
+ │ ├── name_loc: (16,10)-(16,11) = "a"
+ │ ├── receiver:
+ │ │ @ FalseNode (location: (16,4)-(16,9))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (16,0)-(16,3) = "def"
+ │ ├── operator_loc: (16,9)-(16,10) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (17,0)-(17,3) = "end"
+ ├── @ DefNode (location: (19,0)-(20,3))
+ │ ├── name: :a
+ │ ├── name_loc: (19,4)-(19,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (19,6)-(19,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (19,6)-(19,9))
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (19,0)-(19,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (19,5)-(19,6) = "("
+ │ ├── rparen_loc: (19,9)-(19,10) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (20,0)-(20,3) = "end"
+ ├── @ DefNode (location: (22,0)-(23,3))
+ │ ├── name: :a
+ │ ├── name_loc: (22,9)-(22,10) = "a"
+ │ ├── receiver:
+ │ │ @ GlobalVariableReadNode (location: (22,4)-(22,8))
+ │ │ └── name: :$var
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (22,0)-(22,3) = "def"
+ │ ├── operator_loc: (22,8)-(22,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (23,0)-(23,3) = "end"
+ ├── @ DefNode (location: (25,0)-(26,3))
+ │ ├── name: :b
+ │ ├── name_loc: (25,6)-(25,7) = "b"
+ │ ├── receiver:
+ │ │ @ CallNode (location: (25,4)-(25,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (25,4)-(25,5) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (25,0)-(25,3) = "def"
+ │ ├── operator_loc: (25,5)-(25,6) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (26,0)-(26,3) = "end"
+ ├── @ DefNode (location: (28,0)-(29,3))
+ │ ├── name: :a
+ │ ├── name_loc: (28,9)-(28,10) = "a"
+ │ ├── receiver:
+ │ │ @ InstanceVariableReadNode (location: (28,4)-(28,8))
+ │ │ └── name: :@var
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (28,0)-(28,3) = "def"
+ │ ├── operator_loc: (28,8)-(28,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (29,0)-(29,3) = "end"
+ ├── @ DefNode (location: (31,0)-(31,13))
+ │ ├── name: :a
+ │ ├── name_loc: (31,4)-(31,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (31,6)-(31,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (31,6)-(31,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ └── name_loc: (31,6)-(31,8) = "b:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (31,0)-(31,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (31,10)-(31,13) = "end"
+ ├── @ StringNode (location: (33,0)-(33,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (33,0)-(33,2) = "%,"
+ │ ├── content_loc: (33,2)-(33,5) = "abc"
+ │ ├── closing_loc: (33,5)-(33,6) = ","
+ │ └── unescaped: "abc"
+ ├── @ DefNode (location: (35,0)-(36,3))
+ │ ├── name: :a
+ │ ├── name_loc: (35,4)-(35,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (35,6)-(35,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (35,6)-(35,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ └── name_loc: (35,6)-(35,8) = "b:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (35,0)-(35,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (35,5)-(35,6) = "("
+ │ ├── rparen_loc: (35,8)-(35,9) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (36,0)-(36,3) = "end"
+ ├── @ DefNode (location: (38,0)-(39,3))
+ │ ├── name: :a
+ │ ├── name_loc: (38,4)-(38,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (38,6)-(38,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (38,6)-(38,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (38,8)-(38,9) = "b"
+ │ │ │ └── operator_loc: (38,6)-(38,8) = "**"
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (38,0)-(38,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (38,5)-(38,6) = "("
+ │ ├── rparen_loc: (38,9)-(38,10) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (39,0)-(39,3) = "end"
+ ├── @ DefNode (location: (41,0)-(42,3))
+ │ ├── name: :a
+ │ ├── name_loc: (41,4)-(41,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (41,6)-(41,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (41,6)-(41,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (41,6)-(41,8) = "**"
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (41,0)-(41,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (41,5)-(41,6) = "("
+ │ ├── rparen_loc: (41,8)-(41,9) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (42,0)-(42,3) = "end"
+ ├── @ LocalVariableWriteNode (location: (44,0)-(44,5))
+ │ ├── name: :a
+ │ ├── depth: 0
+ │ ├── name_loc: (44,0)-(44,1) = "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (44,4)-(44,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (44,2)-(44,3) = "="
+ ├── @ DefNode (location: (44,7)-(45,3))
+ │ ├── name: :a
+ │ ├── name_loc: (44,11)-(44,12) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (44,7)-(44,10) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (45,0)-(45,3) = "end"
+ ├── @ DefNode (location: (47,0)-(48,3))
+ │ ├── name: :a
+ │ ├── name_loc: (47,4)-(47,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (47,6)-(47,13))
+ │ │ ├── requireds: (length: 3)
+ │ │ │ ├── @ RequiredParameterNode (location: (47,6)-(47,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── @ RequiredParameterNode (location: (47,9)-(47,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ └── @ RequiredParameterNode (location: (47,12)-(47,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b, :c, :d]
+ │ ├── def_keyword_loc: (47,0)-(47,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (48,0)-(48,3) = "end"
+ ├── @ DefNode (location: (50,0)-(51,3))
+ │ ├── name: :a
+ │ ├── name_loc: (50,8)-(50,9) = "a"
+ │ ├── receiver:
+ │ │ @ NilNode (location: (50,4)-(50,7))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (50,0)-(50,3) = "def"
+ │ ├── operator_loc: (50,7)-(50,8) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (51,0)-(51,3) = "end"
+ ├── @ DefNode (location: (53,0)-(54,3))
+ │ ├── name: :a
+ │ ├── name_loc: (53,4)-(53,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (53,6)-(53,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ RequiredKeywordParameterNode (location: (53,6)-(53,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── name_loc: (53,6)-(53,8) = "b:"
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (53,10)-(53,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (53,10)-(53,12) = "c:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (53,13)-(53,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b, :c]
+ │ ├── def_keyword_loc: (53,0)-(53,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (54,0)-(54,3) = "end"
+ ├── @ DefNode (location: (56,0)-(57,3))
+ │ ├── name: :a
+ │ ├── name_loc: (56,4)-(56,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (56,6)-(56,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ RequiredKeywordParameterNode (location: (56,6)-(56,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── name_loc: (56,6)-(56,8) = "b:"
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (56,10)-(56,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (56,10)-(56,12) = "c:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (56,13)-(56,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b, :c]
+ │ ├── def_keyword_loc: (56,0)-(56,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (56,5)-(56,6) = "("
+ │ ├── rparen_loc: (56,14)-(56,15) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (57,0)-(57,3) = "end"
+ ├── @ DefNode (location: (59,0)-(61,3))
+ │ ├── name: :a
+ │ ├── name_loc: (59,4)-(59,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (59,6)-(60,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ OptionalKeywordParameterNode (location: (59,6)-(60,3))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (59,6)-(59,8) = "b:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (60,2)-(60,3))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (60,5)-(60,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ └── name_loc: (60,5)-(60,7) = "c:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b, :c]
+ │ ├── def_keyword_loc: (59,0)-(59,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (59,5)-(59,6) = "("
+ │ ├── rparen_loc: (60,7)-(60,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (61,0)-(61,3) = "end"
+ ├── @ StringNode (location: (63,0)-(63,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (63,0)-(63,2) = "%."
+ │ ├── content_loc: (63,2)-(63,5) = "abc"
+ │ ├── closing_loc: (63,5)-(63,6) = "."
+ │ └── unescaped: "abc"
+ ├── @ DefNode (location: (65,0)-(66,3))
+ │ ├── name: :a
+ │ ├── name_loc: (65,4)-(65,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (65,6)-(65,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 2)
+ │ │ │ ├── @ OptionalParameterNode (location: (65,6)-(65,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (65,6)-(65,7) = "b"
+ │ │ │ │ ├── operator_loc: (65,8)-(65,9) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (65,10)-(65,11))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ OptionalParameterNode (location: (65,13)-(65,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (65,13)-(65,14) = "c"
+ │ │ │ ├── operator_loc: (65,15)-(65,16) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (65,17)-(65,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b, :c]
+ │ ├── def_keyword_loc: (65,0)-(65,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (66,0)-(66,3) = "end"
+ ├── @ DefNode (location: (68,0)-(69,3))
+ │ ├── name: :a
+ │ ├── name_loc: (68,4)-(68,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (68,0)-(68,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (68,5)-(68,6) = "("
+ │ ├── rparen_loc: (68,6)-(68,7) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (69,0)-(69,3) = "end"
+ ├── @ DefNode (location: (71,0)-(72,3))
+ │ ├── name: :a
+ │ ├── name_loc: (71,4)-(71,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (71,6)-(71,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (71,6)-(71,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (71,9)-(71,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (71,9)-(71,10) = "c"
+ │ │ │ ├── operator_loc: (71,11)-(71,12) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (71,13)-(71,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b, :c]
+ │ ├── def_keyword_loc: (71,0)-(71,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (72,0)-(72,3) = "end"
+ ├── @ DefNode (location: (74,0)-(75,3))
+ │ ├── name: :a
+ │ ├── name_loc: (74,4)-(74,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (74,6)-(74,7))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (74,6)-(74,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (74,0)-(74,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (75,0)-(75,3) = "end"
+ ├── @ DefNode (location: (77,0)-(77,32))
+ │ ├── name: :a
+ │ ├── name_loc: (77,4)-(77,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (77,0)-(77,32))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (77,7)-(77,13))
+ │ │ │ ├── keyword_loc: (77,7)-(77,13) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause:
+ │ │ │ @ ElseNode (location: (77,15)-(77,27))
+ │ │ │ ├── else_keyword_loc: (77,15)-(77,19) = "else"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── end_keyword_loc: (77,21)-(77,27) = "ensure"
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (77,21)-(77,32))
+ │ │ │ ├── ensure_keyword_loc: (77,21)-(77,27) = "ensure"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── end_keyword_loc: (77,29)-(77,32) = "end"
+ │ │ └── end_keyword_loc: (77,29)-(77,32) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (77,0)-(77,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (77,29)-(77,32) = "end"
+ ├── @ DefNode (location: (79,0)-(80,3))
+ │ ├── name: :a
+ │ ├── name_loc: (79,4)-(79,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (79,6)-(79,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (79,6)-(79,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (79,7)-(79,8) = "b"
+ │ │ │ └── operator_loc: (79,6)-(79,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (79,0)-(79,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (80,0)-(80,3) = "end"
+ ├── @ DefNode (location: (82,0)-(83,3))
+ │ ├── name: :a
+ │ ├── name_loc: (82,4)-(82,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (82,6)-(82,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (82,6)-(82,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (82,6)-(82,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (82,0)-(82,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (82,5)-(82,6) = "("
+ │ ├── rparen_loc: (82,7)-(82,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (83,0)-(83,3) = "end"
+ ├── @ DefNode (location: (85,0)-(87,3))
+ │ ├── name: :a
+ │ ├── name_loc: (85,4)-(85,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (86,0)-(86,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (86,0)-(86,5))
+ │ │ ├── name: :b
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (86,0)-(86,1) = "b"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (86,4)-(86,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (86,2)-(86,3) = "="
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (85,0)-(85,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (87,0)-(87,3) = "end"
+ ├── @ DefNode (location: (89,0)-(90,3))
+ │ ├── name: :a
+ │ ├── name_loc: (89,9)-(89,10) = "a"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (89,4)-(89,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (89,0)-(89,3) = "def"
+ │ ├── operator_loc: (89,8)-(89,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (90,0)-(90,3) = "end"
+ ├── @ DefNode (location: (92,0)-(93,3))
+ │ ├── name: :a
+ │ ├── name_loc: (92,9)-(92,10) = "a"
+ │ ├── receiver:
+ │ │ @ TrueNode (location: (92,4)-(92,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (92,0)-(92,3) = "def"
+ │ ├── operator_loc: (92,8)-(92,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (93,0)-(93,3) = "end"
+ ├── @ DefNode (location: (95,0)-(96,3))
+ │ ├── name: :a
+ │ ├── name_loc: (95,4)-(95,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (95,0)-(95,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (96,0)-(96,3) = "end"
+ ├── @ DefNode (location: (98,0)-(101,3))
+ │ ├── name: :hi
+ │ ├── name_loc: (98,4)-(98,6) = "hi"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (99,0)-(100,4))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ IfNode (location: (99,0)-(99,18))
+ │ │ │ ├── if_keyword_loc: (99,11)-(99,13) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ TrueNode (location: (99,14)-(99,18))
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (99,0)-(99,10))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ ReturnNode (location: (99,0)-(99,10))
+ │ │ │ │ ├── keyword_loc: (99,0)-(99,6) = "return"
+ │ │ │ │ └── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (99,7)-(99,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (99,7)-(99,10))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (99,7)-(99,8) = ":"
+ │ │ │ │ ├── value_loc: (99,8)-(99,10) = "hi"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "hi"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ └── @ SymbolNode (location: (100,0)-(100,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (100,0)-(100,1) = ":"
+ │ │ ├── value_loc: (100,1)-(100,4) = "bye"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bye"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (98,0)-(98,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (101,0)-(101,3) = "end"
+ ├── @ DefNode (location: (103,0)-(103,11))
+ │ ├── name: :foo
+ │ ├── name_loc: (103,4)-(103,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (103,10)-(103,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (103,10)-(103,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (103,0)-(103,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (103,8)-(103,9) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (104,0)-(104,11))
+ │ ├── name: :bar
+ │ ├── name_loc: (104,4)-(104,7) = "bar"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (104,10)-(104,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (104,10)-(104,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (104,0)-(104,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (104,8)-(104,9) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (106,0)-(106,18))
+ │ ├── name: :foo
+ │ ├── name_loc: (106,4)-(106,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (106,8)-(106,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (106,8)-(106,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :bar
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (106,15)-(106,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (106,15)-(106,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 123
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (106,0)-(106,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (106,7)-(106,8) = "("
+ │ ├── rparen_loc: (106,11)-(106,12) = ")"
+ │ ├── equal_loc: (106,13)-(106,14) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (108,0)-(108,13))
+ │ ├── name: :foo
+ │ ├── name_loc: (108,4)-(108,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (108,10)-(108,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (108,10)-(108,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 123
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (108,0)-(108,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (108,8)-(108,9) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (110,0)-(110,19))
+ │ ├── name: :a
+ │ ├── name_loc: (110,4)-(110,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (110,6)-(110,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (110,6)-(110,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (110,6)-(110,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (110,10)-(110,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (110,10)-(110,14))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (110,10)-(110,11) = "b"
+ │ │ ├── opening_loc: (110,11)-(110,12) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (110,12)-(110,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SplatNode (location: (110,12)-(110,13))
+ │ │ │ ├── operator_loc: (110,12)-(110,13) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── closing_loc: (110,13)-(110,14) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (110,0)-(110,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (110,5)-(110,6) = "("
+ │ ├── rparen_loc: (110,7)-(110,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (110,16)-(110,19) = "end"
+ ├── @ DefNode (location: (112,0)-(112,23))
+ │ ├── name: :a
+ │ ├── name_loc: (112,4)-(112,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (112,6)-(112,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (112,6)-(112,9))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (112,12)-(112,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (112,12)-(112,18))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (112,12)-(112,13) = "b"
+ │ │ ├── opening_loc: (112,13)-(112,14) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (112,14)-(112,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ForwardingArgumentsNode (location: (112,14)-(112,17))
+ │ │ ├── closing_loc: (112,17)-(112,18) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (112,0)-(112,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (112,5)-(112,6) = "("
+ │ ├── rparen_loc: (112,9)-(112,10) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (112,20)-(112,23) = "end"
+ ├── @ DefNode (location: (114,0)-(114,29))
+ │ ├── name: :a
+ │ ├── name_loc: (114,4)-(114,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (114,6)-(114,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (114,6)-(114,9))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (114,12)-(114,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (114,12)-(114,24))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (114,12)-(114,13) = "b"
+ │ │ ├── opening_loc: (114,13)-(114,14) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (114,14)-(114,23))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (114,14)-(114,15))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ IntegerNode (location: (114,17)-(114,18))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ ForwardingArgumentsNode (location: (114,20)-(114,23))
+ │ │ ├── closing_loc: (114,23)-(114,24) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (114,0)-(114,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (114,5)-(114,6) = "("
+ │ ├── rparen_loc: (114,9)-(114,10) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (114,26)-(114,29) = "end"
+ ├── @ DefNode (location: (116,0)-(117,3))
+ │ ├── name: :a
+ │ ├── name_loc: (116,12)-(116,13) = "a"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (116,4)-(116,11))
+ │ │ ├── body:
+ │ │ │ @ LocalVariableWriteNode (location: (116,5)-(116,10))
+ │ │ │ ├── name: :c
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (116,5)-(116,6) = "c"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (116,9)-(116,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (116,9)-(116,10) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (116,7)-(116,8) = "="
+ │ │ ├── opening_loc: (116,4)-(116,5) = "("
+ │ │ └── closing_loc: (116,10)-(116,11) = ")"
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (116,0)-(116,3) = "def"
+ │ ├── operator_loc: (116,11)-(116,12) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (117,0)-(117,3) = "end"
+ ├── @ DefNode (location: (119,0)-(120,3))
+ │ ├── name: :a
+ │ ├── name_loc: (119,4)-(119,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (119,6)-(119,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (119,6)-(119,8))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (119,7)-(119,8) = "b"
+ │ │ └── operator_loc: (119,6)-(119,7) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (119,0)-(119,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (120,0)-(120,3) = "end"
+ ├── @ DefNode (location: (122,0)-(123,3))
+ │ ├── name: :a
+ │ ├── name_loc: (122,4)-(122,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (122,6)-(122,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (122,6)-(122,7))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (122,6)-(122,7) = "&"
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (122,0)-(122,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (122,5)-(122,6) = "("
+ │ ├── rparen_loc: (122,7)-(122,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (123,0)-(123,3) = "end"
+ ├── @ DefNode (location: (125,0)-(126,3))
+ │ ├── name: :a
+ │ ├── name_loc: (125,10)-(125,11) = "a"
+ │ ├── receiver:
+ │ │ @ ClassVariableReadNode (location: (125,4)-(125,9))
+ │ │ └── name: :@@var
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (125,0)-(125,3) = "def"
+ │ ├── operator_loc: (125,9)-(125,10) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (126,0)-(126,3) = "end"
+ ├── @ DefNode (location: (128,0)-(129,3))
+ │ ├── name: :C
+ │ ├── name_loc: (128,12)-(128,13) = "C"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (128,4)-(128,11))
+ │ │ ├── body:
+ │ │ │ @ LocalVariableWriteNode (location: (128,5)-(128,10))
+ │ │ │ ├── name: :a
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (128,5)-(128,6) = "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (128,9)-(128,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (128,9)-(128,10) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (128,7)-(128,8) = "="
+ │ │ ├── opening_loc: (128,4)-(128,5) = "("
+ │ │ └── closing_loc: (128,10)-(128,11) = ")"
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (128,0)-(128,3) = "def"
+ │ ├── operator_loc: (128,11)-(128,12) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (129,0)-(129,3) = "end"
+ ├── @ DefNode (location: (131,0)-(131,28))
+ │ ├── name: :Array_function
+ │ ├── name_loc: (131,9)-(131,23) = "Array_function"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (131,4)-(131,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (131,0)-(131,3) = "def"
+ │ ├── operator_loc: (131,8)-(131,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (131,25)-(131,28) = "end"
+ ├── @ ConstantWriteNode (location: (133,0)-(133,9))
+ │ ├── name: :Const
+ │ ├── name_loc: (133,0)-(133,5) = "Const"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (133,8)-(133,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (133,6)-(133,7) = "="
+ ├── @ DefNode (location: (133,11)-(134,3))
+ │ ├── name: :a
+ │ ├── name_loc: (133,21)-(133,22) = "a"
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (133,15)-(133,20))
+ │ │ └── name: :Const
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (133,11)-(133,14) = "def"
+ │ ├── operator_loc: (133,20)-(133,21) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (134,0)-(134,3) = "end"
+ ├── @ DefNode (location: (136,0)-(136,31))
+ │ ├── name: :a
+ │ ├── name_loc: (136,4)-(136,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (136,6)-(136,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (136,6)-(136,9))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (136,12)-(136,26))
+ │ │ └── body: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (136,12)-(136,26))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (136,12)-(136,13) = "\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (136,13)-(136,16))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (136,13)-(136,16) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ └── @ EmbeddedStatementsNode (location: (136,16)-(136,25))
+ │ │ │ ├── opening_loc: (136,16)-(136,18) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (136,18)-(136,24))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (136,18)-(136,24))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (136,18)-(136,19) = "b"
+ │ │ │ │ ├── opening_loc: (136,19)-(136,20) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (136,20)-(136,23))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ ForwardingArgumentsNode (location: (136,20)-(136,23))
+ │ │ │ │ ├── closing_loc: (136,23)-(136,24) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (136,24)-(136,25) = "}"
+ │ │ └── closing_loc: (136,25)-(136,26) = "\""
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (136,0)-(136,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (136,5)-(136,6) = "("
+ │ ├── rparen_loc: (136,9)-(136,10) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (136,28)-(136,31) = "end"
+ ├── @ DefNode (location: (138,0)-(140,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (138,4)-(138,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (139,2)-(139,30))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (139,2)-(139,30))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ HashNode (location: (139,2)-(139,4))
+ │ │ │ ├── opening_loc: (139,2)-(139,3) = "{"
+ │ │ │ ├── elements: (length: 0)
+ │ │ │ └── closing_loc: (139,3)-(139,4) = "}"
+ │ │ ├── call_operator_loc: (139,4)-(139,5) = "."
+ │ │ ├── name: :merge
+ │ │ ├── message_loc: (139,5)-(139,10) = "merge"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (139,11)-(139,30))
+ │ │ │ ├── flags: contains_keyword_splat
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ KeywordHashNode (location: (139,11)-(139,30))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── elements: (length: 3)
+ │ │ │ ├── @ AssocSplatNode (location: (139,11)-(139,16))
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (139,13)-(139,16))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :bar
+ │ │ │ │ │ ├── message_loc: (139,13)-(139,16) = "bar"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── operator_loc: (139,11)-(139,13) = "**"
+ │ │ │ ├── @ AssocSplatNode (location: (139,18)-(139,23))
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (139,20)-(139,23))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :baz
+ │ │ │ │ │ ├── message_loc: (139,20)-(139,23) = "baz"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── operator_loc: (139,18)-(139,20) = "**"
+ │ │ │ └── @ AssocSplatNode (location: (139,25)-(139,30))
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (139,27)-(139,30))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :qux
+ │ │ │ │ ├── message_loc: (139,27)-(139,30) = "qux"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (139,25)-(139,27) = "**"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (138,0)-(138,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (140,0)-(140,3) = "end"
+ ├── @ DefNode (location: (142,0)-(143,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (142,4)-(142,7) = "bar"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (142,8)-(142,19))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (142,8)-(142,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (142,8)-(142,10) = "a:"
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (142,11)-(142,19))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (142,12)-(142,18))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ RangeNode (location: (142,12)-(142,18))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (142,12)-(142,13))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (142,16)-(142,18))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 10
+ │ │ │ │ └── operator_loc: (142,13)-(142,16) = "..."
+ │ │ │ ├── opening_loc: (142,11)-(142,12) = "("
+ │ │ │ └── closing_loc: (142,18)-(142,19) = ")"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (142,0)-(142,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (142,7)-(142,8) = "("
+ │ ├── rparen_loc: (142,19)-(142,20) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (143,0)-(143,3) = "end"
+ ├── @ DefNode (location: (145,0)-(146,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (145,4)-(145,7) = "bar"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (145,8)-(145,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (145,8)-(145,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (145,8)-(145,10) = "a:"
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (145,11)-(145,18))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (145,12)-(145,17))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ RangeNode (location: (145,12)-(145,17))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left: ∅
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (145,15)-(145,17))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 10
+ │ │ │ │ └── operator_loc: (145,12)-(145,15) = "..."
+ │ │ │ ├── opening_loc: (145,11)-(145,12) = "("
+ │ │ │ └── closing_loc: (145,17)-(145,18) = ")"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (145,0)-(145,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (145,7)-(145,8) = "("
+ │ ├── rparen_loc: (145,18)-(145,19) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (146,0)-(146,3) = "end"
+ ├── @ DefNode (location: (148,0)-(149,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (148,4)-(148,7) = "bar"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (148,8)-(148,17))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (148,8)-(148,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (148,8)-(148,10) = "a:"
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (148,11)-(148,17))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (148,12)-(148,16))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ RangeNode (location: (148,12)-(148,16))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (148,12)-(148,13))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right: ∅
+ │ │ │ │ └── operator_loc: (148,13)-(148,16) = "..."
+ │ │ │ ├── opening_loc: (148,11)-(148,12) = "("
+ │ │ │ └── closing_loc: (148,16)-(148,17) = ")"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (148,0)-(148,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (148,7)-(148,8) = "("
+ │ ├── rparen_loc: (148,17)-(148,18) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (149,0)-(149,3) = "end"
+ ├── @ DefNode (location: (151,0)-(152,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (151,4)-(151,7) = "bar"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (151,8)-(151,20))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (151,8)-(151,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (151,8)-(151,9) = "a"
+ │ │ │ ├── operator_loc: (151,10)-(151,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (151,12)-(151,20))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (151,13)-(151,19))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ RangeNode (location: (151,13)-(151,19))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (151,13)-(151,14))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (151,17)-(151,19))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 10
+ │ │ │ │ └── operator_loc: (151,14)-(151,17) = "..."
+ │ │ │ ├── opening_loc: (151,12)-(151,13) = "("
+ │ │ │ └── closing_loc: (151,19)-(151,20) = ")"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (151,0)-(151,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (151,7)-(151,8) = "("
+ │ ├── rparen_loc: (151,20)-(151,21) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (152,0)-(152,3) = "end"
+ ├── @ DefNode (location: (154,0)-(155,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (154,4)-(154,7) = "bar"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (154,8)-(154,19))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (154,8)-(154,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (154,8)-(154,9) = "a"
+ │ │ │ ├── operator_loc: (154,10)-(154,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (154,12)-(154,19))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (154,13)-(154,18))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ RangeNode (location: (154,13)-(154,18))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left: ∅
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (154,16)-(154,18))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 10
+ │ │ │ │ └── operator_loc: (154,13)-(154,16) = "..."
+ │ │ │ ├── opening_loc: (154,12)-(154,13) = "("
+ │ │ │ └── closing_loc: (154,18)-(154,19) = ")"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (154,0)-(154,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (154,7)-(154,8) = "("
+ │ ├── rparen_loc: (154,19)-(154,20) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (155,0)-(155,3) = "end"
+ ├── @ DefNode (location: (157,0)-(158,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (157,4)-(157,7) = "bar"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (157,8)-(157,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (157,8)-(157,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (157,8)-(157,9) = "a"
+ │ │ │ ├── operator_loc: (157,10)-(157,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (157,12)-(157,18))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (157,13)-(157,17))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ RangeNode (location: (157,13)-(157,17))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (157,13)-(157,14))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right: ∅
+ │ │ │ │ └── operator_loc: (157,14)-(157,17) = "..."
+ │ │ │ ├── opening_loc: (157,12)-(157,13) = "("
+ │ │ │ └── closing_loc: (157,17)-(157,18) = ")"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (157,0)-(157,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (157,7)-(157,8) = "("
+ │ ├── rparen_loc: (157,18)-(157,19) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (158,0)-(158,3) = "end"
+ ├── @ DefNode (location: (160,0)-(162,3))
+ │ ├── name: :method
+ │ ├── name_loc: (160,4)-(160,10) = "method"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (160,11)-(160,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (160,11)-(160,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (161,2)-(161,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (161,2)-(161,14))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (161,2)-(161,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :item
+ │ │ │ ├── message_loc: (161,2)-(161,6) = "item"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :>>
+ │ │ ├── message_loc: (161,7)-(161,9) = ">>"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (161,10)-(161,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (161,10)-(161,14))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (161,10)-(161,11) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (161,12)-(161,14))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (161,12)-(161,13) = "{"
+ │ │ │ └── closing_loc: (161,13)-(161,14) = "}"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (160,0)-(160,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (160,10)-(160,11) = "("
+ │ ├── rparen_loc: (160,12)-(160,13) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (162,0)-(162,3) = "end"
+ ├── @ LocalVariableWriteNode (location: (164,0)-(164,7))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (164,0)-(164,3) = "foo"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (164,6)-(164,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (164,4)-(164,5) = "="
+ ├── @ DefNode (location: (165,0)-(165,16))
+ │ ├── name: :bar
+ │ ├── name_loc: (165,8)-(165,11) = "bar"
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (165,4)-(165,7))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (165,0)-(165,3) = "def"
+ │ ├── operator_loc: (165,7)-(165,8) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (165,13)-(165,16) = "end"
+ ├── @ DefNode (location: (167,0)-(167,18))
+ │ ├── name: :f
+ │ ├── name_loc: (167,4)-(167,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (167,6)-(167,7))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (167,6)-(167,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (167,6)-(167,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (167,10)-(167,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ArrayNode (location: (167,10)-(167,13))
+ │ │ ├── flags: contains_splat
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ SplatNode (location: (167,11)-(167,12))
+ │ │ │ ├── operator_loc: (167,11)-(167,12) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── opening_loc: (167,10)-(167,11) = "["
+ │ │ └── closing_loc: (167,12)-(167,13) = "]"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (167,0)-(167,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (167,5)-(167,6) = "("
+ │ ├── rparen_loc: (167,7)-(167,8) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (167,15)-(167,18) = "end"
+ ├── @ DefNode (location: (169,0)-(169,15))
+ │ ├── name: :f
+ │ ├── name_loc: (169,4)-(169,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (169,6)-(169,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (169,6)-(169,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── name_loc: (169,6)-(169,8) = "x:"
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (169,8)-(169,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (169,9)-(169,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (169,9)-(169,10) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :-@
+ │ │ │ ├── message_loc: (169,8)-(169,9) = "-"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (169,0)-(169,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (169,12)-(169,15) = "end"
+ ├── @ DefNode (location: (171,0)-(171,15))
+ │ ├── name: :f
+ │ ├── name_loc: (171,4)-(171,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (171,6)-(171,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (171,6)-(171,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── name_loc: (171,6)-(171,8) = "x:"
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (171,8)-(171,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (171,9)-(171,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (171,9)-(171,10) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+@
+ │ │ │ ├── message_loc: (171,8)-(171,9) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (171,0)-(171,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (171,12)-(171,15) = "end"
+ ├── @ DefNode (location: (173,0)-(173,15))
+ │ ├── name: :f
+ │ ├── name_loc: (173,4)-(173,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (173,6)-(173,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (173,6)-(173,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── name_loc: (173,6)-(173,8) = "x:"
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (173,8)-(173,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (173,9)-(173,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (173,9)-(173,10) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :!
+ │ │ │ ├── message_loc: (173,8)-(173,9) = "!"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (173,0)-(173,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (173,12)-(173,15) = "end"
+ ├── @ DefNode (location: (175,0)-(175,20))
+ │ ├── name: :foo
+ │ ├── name_loc: (175,4)-(175,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (175,8)-(175,15))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (175,8)-(175,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── name_loc: (175,8)-(175,10) = "x:"
+ │ │ │ └── value:
+ │ │ │ @ StringNode (location: (175,10)-(175,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (175,10)-(175,12) = "%("
+ │ │ │ ├── content_loc: (175,12)-(175,14) = "xx"
+ │ │ │ ├── closing_loc: (175,14)-(175,15) = ")"
+ │ │ │ └── unescaped: "xx"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (175,0)-(175,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (175,17)-(175,20) = "end"
+ ├── @ DefNode (location: (177,0)-(179,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (177,4)-(177,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (177,8)-(177,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (177,8)-(177,11))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (178,2)-(178,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (178,2)-(178,10))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (178,2)-(178,5) = "bar"
+ │ │ ├── opening_loc: (178,5)-(178,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (178,6)-(178,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ForwardingArgumentsNode (location: (178,6)-(178,9))
+ │ │ ├── closing_loc: (178,9)-(178,10) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (177,0)-(177,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (177,7)-(177,8) = "("
+ │ ├── rparen_loc: (177,11)-(177,12) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (179,0)-(179,3) = "end"
+ ├── @ DefNode (location: (181,0)-(181,42))
+ │ ├── name: :foo
+ │ ├── name_loc: (181,4)-(181,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (181,8)-(181,37))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (181,8)-(181,37))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (181,8)-(181,11) = "bar"
+ │ │ │ ├── operator_loc: (181,12)-(181,13) = "="
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (181,14)-(181,37))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (181,15)-(181,36))
+ │ │ │ │ └── body: (length: 2)
+ │ │ │ │ ├── @ DefNode (location: (181,15)-(181,33))
+ │ │ │ │ │ ├── name: :baz
+ │ │ │ │ │ ├── name_loc: (181,19)-(181,22) = "baz"
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── parameters:
+ │ │ │ │ │ │ @ ParametersNode (location: (181,23)-(181,26))
+ │ │ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (181,23)-(181,26))
+ │ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ │ └── name: :bar
+ │ │ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ ├── body:
+ │ │ │ │ │ │ @ StatementsNode (location: (181,30)-(181,33))
+ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ └── @ LocalVariableReadNode (location: (181,30)-(181,33))
+ │ │ │ │ │ │ ├── name: :bar
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ ├── locals: [:bar]
+ │ │ │ │ │ ├── def_keyword_loc: (181,15)-(181,18) = "def"
+ │ │ │ │ │ ├── operator_loc: ∅
+ │ │ │ │ │ ├── lparen_loc: (181,22)-(181,23) = "("
+ │ │ │ │ │ ├── rparen_loc: (181,26)-(181,27) = ")"
+ │ │ │ │ │ ├── equal_loc: (181,28)-(181,29) = "="
+ │ │ │ │ │ └── end_keyword_loc: ∅
+ │ │ │ │ └── @ IntegerNode (location: (181,35)-(181,36))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── opening_loc: (181,14)-(181,15) = "("
+ │ │ │ └── closing_loc: (181,36)-(181,37) = ")"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (181,41)-(181,42))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (181,41)-(181,42))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (181,0)-(181,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (181,7)-(181,8) = "("
+ │ ├── rparen_loc: (181,37)-(181,38) = ")"
+ │ ├── equal_loc: (181,39)-(181,40) = "="
+ │ └── end_keyword_loc: ∅
+ └── @ DefNode (location: (183,0)-(183,37))
+ ├── name: :foo
+ ├── name_loc: (183,21)-(183,24) = "foo"
+ ├── receiver:
+ │ @ ParenthesesNode (location: (183,4)-(183,20))
+ │ ├── body:
+ │ │ @ ClassNode (location: (183,5)-(183,19))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (183,5)-(183,10) = "class"
+ │ │ ├── constant_path:
+ │ │ │ @ ConstantReadNode (location: (183,11)-(183,14))
+ │ │ │ └── name: :Foo
+ │ │ ├── inheritance_operator_loc: ∅
+ │ │ ├── superclass: ∅
+ │ │ ├── body: ∅
+ │ │ ├── end_keyword_loc: (183,16)-(183,19) = "end"
+ │ │ └── name: :Foo
+ │ ├── opening_loc: (183,4)-(183,5) = "("
+ │ └── closing_loc: (183,19)-(183,20) = ")"
+ ├── parameters:
+ │ @ ParametersNode (location: (183,25)-(183,32))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 1)
+ │ │ └── @ OptionalParameterNode (location: (183,25)-(183,32))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :bar
+ │ │ ├── name_loc: (183,25)-(183,28) = "bar"
+ │ │ ├── operator_loc: (183,29)-(183,30) = "="
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (183,31)-(183,32))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (183,36)-(183,37))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (183,36)-(183,37))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── locals: [:bar]
+ ├── def_keyword_loc: (183,0)-(183,3) = "def"
+ ├── operator_loc: (183,20)-(183,21) = "."
+ ├── lparen_loc: (183,24)-(183,25) = "("
+ ├── rparen_loc: (183,32)-(183,33) = ")"
+ ├── equal_loc: (183,34)-(183,35) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/modules.txt b/test/prism/snapshots/modules.txt
new file mode 100644
index 0000000000..1a0eb6328a
--- /dev/null
+++ b/test/prism/snapshots/modules.txt
@@ -0,0 +1,184 @@
+@ ProgramNode (location: (1,0)-(18,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(18,3))
+ └── body: (length: 7)
+ ├── @ ModuleNode (location: (1,0)-(1,18))
+ │ ├── locals: [:a]
+ │ ├── module_keyword_loc: (1,0)-(1,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (1,7)-(1,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,9)-(1,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (1,9)-(1,14))
+ │ │ ├── name: :a
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (1,9)-(1,10) = "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (1,11)-(1,12) = "="
+ │ ├── end_keyword_loc: (1,15)-(1,18) = "end"
+ │ └── name: :A
+ ├── @ InterpolatedStringNode (location: (3,0)-(3,18))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (3,0)-(3,3) = "%Q{"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (3,3)-(3,7))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,3)-(3,7) = "aaa "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "aaa "
+ │ │ ├── @ EmbeddedStatementsNode (location: (3,7)-(3,13))
+ │ │ │ ├── opening_loc: (3,7)-(3,9) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (3,9)-(3,12))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (3,9)-(3,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bbb
+ │ │ │ │ ├── message_loc: (3,9)-(3,12) = "bbb"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (3,12)-(3,13) = "}"
+ │ │ └── @ StringNode (location: (3,13)-(3,17))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (3,13)-(3,17) = " ccc"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " ccc"
+ │ └── closing_loc: (3,17)-(3,18) = "}"
+ ├── @ ModuleNode (location: (5,0)-(6,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (5,0)-(5,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (5,7)-(5,11))
+ │ │ ├── parent:
+ │ │ │ @ CallNode (location: (5,7)-(5,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :m
+ │ │ │ ├── message_loc: (5,7)-(5,8) = "m"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (5,10)-(5,11))
+ │ │ │ └── name: :M
+ │ │ └── delimiter_loc: (5,8)-(5,10) = "::"
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (6,0)-(6,3) = "end"
+ │ └── name: :M
+ ├── @ ModuleNode (location: (8,0)-(9,19))
+ │ ├── locals: [:x]
+ │ ├── module_keyword_loc: (8,0)-(8,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (8,7)-(8,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ BeginNode (location: (8,0)-(9,19))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (9,1)-(9,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableWriteNode (location: (9,1)-(9,6))
+ │ │ │ ├── name: :x
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (9,1)-(9,2) = "x"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (9,5)-(9,6))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: (9,3)-(9,4) = "="
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (9,8)-(9,14))
+ │ │ │ ├── keyword_loc: (9,8)-(9,14) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (9,16)-(9,19) = "end"
+ │ ├── end_keyword_loc: (9,16)-(9,19) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (11,0)-(12,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (11,0)-(11,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (11,7)-(11,10))
+ │ │ ├── parent: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (11,9)-(11,10))
+ │ │ │ └── name: :A
+ │ │ └── delimiter_loc: (11,7)-(11,9) = "::"
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (12,0)-(12,3) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (14,0)-(15,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (14,0)-(14,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (14,7)-(14,13))
+ │ │ ├── parent:
+ │ │ │ @ CallNode (location: (14,7)-(14,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ ConstantReadNode (location: (14,7)-(14,8))
+ │ │ │ │ └── name: :A
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :[]
+ │ │ │ ├── message_loc: (14,8)-(14,10) = "[]"
+ │ │ │ ├── opening_loc: (14,8)-(14,9) = "["
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: (14,9)-(14,10) = "]"
+ │ │ │ └── block: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (14,12)-(14,13))
+ │ │ │ └── name: :B
+ │ │ └── delimiter_loc: (14,10)-(14,12) = "::"
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (15,0)-(15,3) = "end"
+ │ └── name: :B
+ └── @ ModuleNode (location: (17,0)-(18,3))
+ ├── locals: []
+ ├── module_keyword_loc: (17,0)-(17,6) = "module"
+ ├── constant_path:
+ │ @ ConstantPathNode (location: (17,7)-(17,14))
+ │ ├── parent:
+ │ │ @ CallNode (location: (17,7)-(17,11))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ ConstantReadNode (location: (17,7)-(17,8))
+ │ │ │ └── name: :A
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :[]
+ │ │ ├── message_loc: (17,8)-(17,11) = "[1]"
+ │ │ ├── opening_loc: (17,8)-(17,9) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (17,9)-(17,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (17,9)-(17,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: (17,10)-(17,11) = "]"
+ │ │ └── block: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (17,13)-(17,14))
+ │ │ └── name: :B
+ │ └── delimiter_loc: (17,11)-(17,13) = "::"
+ ├── body: ∅
+ ├── end_keyword_loc: (18,0)-(18,3) = "end"
+ └── name: :B
diff --git a/test/prism/snapshots/multi_write.txt b/test/prism/snapshots/multi_write.txt
new file mode 100644
index 0000000000..d313801fdb
--- /dev/null
+++ b/test/prism/snapshots/multi_write.txt
@@ -0,0 +1,93 @@
+@ ProgramNode (location: (1,0)-(4,26))
+├── locals: [:foo, :bar]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,26))
+ └── body: (length: 4)
+ ├── @ LocalVariableWriteNode (location: (1,0)-(1,18))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (1,0)-(1,3) = "foo"
+ │ ├── value:
+ │ │ @ RescueModifierNode (location: (1,6)-(1,18))
+ │ │ ├── expression:
+ │ │ │ @ IntegerNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── keyword_loc: (1,8)-(1,14) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (1,15)-(1,18))
+ │ └── operator_loc: (1,4)-(1,5) = "="
+ ├── @ MultiWriteNode (location: (2,0)-(2,23))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (2,0)-(2,3))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (2,5)-(2,8))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (2,9)-(2,10) = "="
+ │ └── value:
+ │ @ RescueModifierNode (location: (2,11)-(2,23))
+ │ ├── expression:
+ │ │ @ IntegerNode (location: (2,11)-(2,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_loc: (2,13)-(2,19) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (2,20)-(2,23))
+ ├── @ RescueModifierNode (location: (3,0)-(3,21))
+ │ ├── expression:
+ │ │ @ LocalVariableWriteNode (location: (3,0)-(3,10))
+ │ │ ├── name: :foo
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── value:
+ │ │ │ @ ArrayNode (location: (3,6)-(3,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ ├── @ IntegerNode (location: (3,6)-(3,7))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── @ IntegerNode (location: (3,9)-(3,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ └── closing_loc: ∅
+ │ │ └── operator_loc: (3,4)-(3,5) = "="
+ │ ├── keyword_loc: (3,11)-(3,17) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (3,18)-(3,21))
+ └── @ MultiWriteNode (location: (4,0)-(4,26))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (4,0)-(4,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (4,5)-(4,8))
+ │ ├── name: :bar
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (4,9)-(4,10) = "="
+ └── value:
+ @ RescueModifierNode (location: (4,11)-(4,26))
+ ├── expression:
+ │ @ ArrayNode (location: (4,11)-(4,15))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (4,11)-(4,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (4,14)-(4,15))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── keyword_loc: (4,16)-(4,22) = "rescue"
+ └── rescue_expression:
+ @ NilNode (location: (4,23)-(4,26))
diff --git a/test/prism/snapshots/newline_terminated.txt b/test/prism/snapshots/newline_terminated.txt
new file mode 100644
index 0000000000..6a3b28dba9
--- /dev/null
+++ b/test/prism/snapshots/newline_terminated.txt
@@ -0,0 +1,107 @@
+@ ProgramNode (location: (3,0)-(41,0))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (3,0)-(41,0))
+ └── body: (length: 17)
+ ├── @ StringNode (location: (3,0)-(3,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (3,0)-(3,2) = "% "
+ │ ├── content_loc: (3,2)-(3,5) = "abc"
+ │ ├── closing_loc: (3,5)-(3,6) = " "
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (4,0)-(4,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (4,0)-(4,2) = "%\t"
+ │ ├── content_loc: (4,2)-(4,5) = "abc"
+ │ ├── closing_loc: (4,5)-(4,6) = "\t"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (5,0)-(5,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (5,0)-(5,2) = "%\v"
+ │ ├── content_loc: (5,2)-(5,5) = "abc"
+ │ ├── closing_loc: (5,5)-(5,6) = "\v"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (6,0)-(6,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (6,0)-(6,2) = "%\r"
+ │ ├── content_loc: (6,2)-(6,5) = "abc"
+ │ ├── closing_loc: (6,5)-(6,6) = "\r"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (7,0)-(9,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(8,0) = "%\n"
+ │ ├── content_loc: (8,0)-(8,3) = "abc"
+ │ ├── closing_loc: (8,3)-(9,0) = "\n"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (10,0)-(10,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (10,0)-(10,2) = "%\u0000"
+ │ ├── content_loc: (10,2)-(10,5) = "abc"
+ │ ├── closing_loc: (10,5)-(10,6) = "\u0000"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (11,0)-(13,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (11,0)-(12,0) = "%\n"
+ │ ├── content_loc: (12,0)-(12,3) = "abc"
+ │ ├── closing_loc: (12,3)-(13,0) = "\n"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (14,0)-(16,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (14,0)-(15,0) = "%\n"
+ │ ├── content_loc: (15,0)-(15,4) = "\rabc"
+ │ ├── closing_loc: (15,4)-(16,0) = "\n"
+ │ └── unescaped: "\rabc"
+ ├── @ StringNode (location: (17,0)-(19,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (17,0)-(18,0) = "%\n"
+ │ ├── content_loc: (18,0)-(18,4) = "\rabc"
+ │ ├── closing_loc: (18,4)-(19,0) = "\n"
+ │ └── unescaped: "\rabc"
+ ├── @ StringNode (location: (20,0)-(22,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (20,0)-(21,0) = "%\n"
+ │ ├── content_loc: (21,0)-(21,3) = "abc"
+ │ ├── closing_loc: (21,3)-(22,0) = "\n"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (23,0)-(23,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (23,0)-(23,2) = "%\r"
+ │ ├── content_loc: (23,2)-(23,5) = "abc"
+ │ ├── closing_loc: (23,5)-(23,6) = "\r"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (24,0)-(26,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (24,0)-(25,0) = "%\n"
+ │ ├── content_loc: (25,0)-(25,3) = "abc"
+ │ ├── closing_loc: (25,3)-(26,0) = "\n"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (27,0)-(29,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (27,0)-(28,0) = "%\n"
+ │ ├── content_loc: (28,0)-(28,3) = "abc"
+ │ ├── closing_loc: (28,3)-(29,0) = "\n"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (30,0)-(32,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (30,0)-(31,0) = "%\n"
+ │ ├── content_loc: (31,0)-(31,3) = "foo"
+ │ ├── closing_loc: (31,3)-(32,0) = "\n"
+ │ └── unescaped: "foo"
+ ├── @ StringNode (location: (33,0)-(35,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (33,0)-(34,0) = "%q\n"
+ │ ├── content_loc: (34,0)-(34,3) = "foo"
+ │ ├── closing_loc: (34,3)-(35,0) = "\n"
+ │ └── unescaped: "foo"
+ ├── @ StringNode (location: (36,0)-(38,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (36,0)-(37,0) = "%Q\n"
+ │ ├── content_loc: (37,0)-(37,3) = "foo"
+ │ ├── closing_loc: (37,3)-(38,0) = "\n"
+ │ └── unescaped: "foo"
+ └── @ RegularExpressionNode (location: (39,0)-(41,0))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (39,0)-(40,0) = "%r\n"
+ ├── content_loc: (40,0)-(40,3) = "foo"
+ ├── closing_loc: (40,3)-(41,0) = "\n"
+ └── unescaped: "foo"
diff --git a/test/prism/snapshots/next.txt b/test/prism/snapshots/next.txt
new file mode 100644
index 0000000000..ce2e497de9
--- /dev/null
+++ b/test/prism/snapshots/next.txt
@@ -0,0 +1,329 @@
+@ ProgramNode (location: (1,0)-(24,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(24,15))
+ └── body: (length: 10)
+ ├── @ CallNode (location: (1,0)-(1,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (1,0)-(1,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,4)-(1,12))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,6)-(1,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (1,6)-(1,10))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (1,6)-(1,10) = "next"
+ │ ├── opening_loc: (1,4)-(1,5) = "{"
+ │ └── closing_loc: (1,11)-(1,12) = "}"
+ ├── @ CallNode (location: (3,0)-(3,26))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (3,0)-(3,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,4)-(3,26))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,6)-(3,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (3,6)-(3,24))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,11)-(3,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 3)
+ │ │ │ ├── @ ParenthesesNode (location: (3,11)-(3,14))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (3,12)-(3,13))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (3,12)-(3,13))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── opening_loc: (3,11)-(3,12) = "("
+ │ │ │ │ └── closing_loc: (3,13)-(3,14) = ")"
+ │ │ │ ├── @ ParenthesesNode (location: (3,16)-(3,19))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (3,17)-(3,18))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (3,17)-(3,18))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ ├── opening_loc: (3,16)-(3,17) = "("
+ │ │ │ │ └── closing_loc: (3,18)-(3,19) = ")"
+ │ │ │ └── @ ParenthesesNode (location: (3,21)-(3,24))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (3,22)-(3,23))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (3,22)-(3,23))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 3
+ │ │ │ ├── opening_loc: (3,21)-(3,22) = "("
+ │ │ │ └── closing_loc: (3,23)-(3,24) = ")"
+ │ │ └── keyword_loc: (3,6)-(3,10) = "next"
+ │ ├── opening_loc: (3,4)-(3,5) = "{"
+ │ └── closing_loc: (3,25)-(3,26) = "}"
+ ├── @ CallNode (location: (5,0)-(5,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (5,0)-(5,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,4)-(5,14))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,6)-(5,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (5,6)-(5,12))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,11)-(5,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,11)-(5,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── keyword_loc: (5,6)-(5,10) = "next"
+ │ ├── opening_loc: (5,4)-(5,5) = "{"
+ │ └── closing_loc: (5,13)-(5,14) = "}"
+ ├── @ CallNode (location: (7,0)-(8,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (7,0)-(7,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (7,4)-(8,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,6)-(8,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (7,6)-(8,1))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,11)-(8,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (7,11)-(7,12))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ IntegerNode (location: (7,14)-(7,15))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (8,0)-(8,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ └── keyword_loc: (7,6)-(7,10) = "next"
+ │ ├── opening_loc: (7,4)-(7,5) = "{"
+ │ └── closing_loc: (8,2)-(8,3) = "}"
+ ├── @ CallNode (location: (10,0)-(10,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (10,0)-(10,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (10,4)-(10,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (10,6)-(10,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (10,6)-(10,18))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (10,11)-(10,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (10,11)-(10,12))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ IntegerNode (location: (10,14)-(10,15))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (10,17)-(10,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ └── keyword_loc: (10,6)-(10,10) = "next"
+ │ ├── opening_loc: (10,4)-(10,5) = "{"
+ │ └── closing_loc: (10,19)-(10,20) = "}"
+ ├── @ CallNode (location: (12,0)-(12,22))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (12,0)-(12,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (12,4)-(12,22))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (12,6)-(12,20))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (12,6)-(12,20))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (12,11)-(12,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ArrayNode (location: (12,11)-(12,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 3)
+ │ │ │ │ ├── @ IntegerNode (location: (12,12)-(12,13))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── @ IntegerNode (location: (12,15)-(12,16))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ └── @ IntegerNode (location: (12,18)-(12,19))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 3
+ │ │ │ ├── opening_loc: (12,11)-(12,12) = "["
+ │ │ │ └── closing_loc: (12,19)-(12,20) = "]"
+ │ │ └── keyword_loc: (12,6)-(12,10) = "next"
+ │ ├── opening_loc: (12,4)-(12,5) = "{"
+ │ └── closing_loc: (12,21)-(12,22) = "}"
+ ├── @ CallNode (location: (14,0)-(17,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (14,0)-(14,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (14,4)-(17,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (14,6)-(17,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (14,6)-(17,1))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (14,10)-(17,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ParenthesesNode (location: (14,10)-(17,1))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (15,2)-(16,3))
+ │ │ │ │ └── body: (length: 2)
+ │ │ │ │ ├── @ IntegerNode (location: (15,2)-(15,3))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── @ IntegerNode (location: (16,2)-(16,3))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── opening_loc: (14,10)-(14,11) = "("
+ │ │ │ └── closing_loc: (17,0)-(17,1) = ")"
+ │ │ └── keyword_loc: (14,6)-(14,10) = "next"
+ │ ├── opening_loc: (14,4)-(14,5) = "{"
+ │ └── closing_loc: (17,2)-(17,3) = "}"
+ ├── @ CallNode (location: (19,0)-(20,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (19,0)-(19,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (19,4)-(20,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (19,6)-(20,1))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ NextNode (location: (19,6)-(19,10))
+ │ │ │ ├── arguments: ∅
+ │ │ │ └── keyword_loc: (19,6)-(19,10) = "next"
+ │ │ └── @ IntegerNode (location: (20,0)-(20,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (19,4)-(19,5) = "{"
+ │ └── closing_loc: (20,2)-(20,3) = "}"
+ ├── @ CallNode (location: (22,0)-(22,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (22,0)-(22,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (22,4)-(22,14))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (22,6)-(22,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (22,6)-(22,12))
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (22,10)-(22,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ParenthesesNode (location: (22,10)-(22,12))
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (22,10)-(22,11) = "("
+ │ │ │ └── closing_loc: (22,11)-(22,12) = ")"
+ │ │ └── keyword_loc: (22,6)-(22,10) = "next"
+ │ ├── opening_loc: (22,4)-(22,5) = "{"
+ │ └── closing_loc: (22,13)-(22,14) = "}"
+ └── @ CallNode (location: (24,0)-(24,15))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :tap
+ ├── message_loc: (24,0)-(24,3) = "tap"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (24,4)-(24,15))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (24,6)-(24,13))
+ │ └── body: (length: 1)
+ │ └── @ NextNode (location: (24,6)-(24,13))
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (24,10)-(24,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ParenthesesNode (location: (24,10)-(24,13))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (24,11)-(24,12))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (24,11)-(24,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (24,10)-(24,11) = "("
+ │ │ └── closing_loc: (24,12)-(24,13) = ")"
+ │ └── keyword_loc: (24,6)-(24,10) = "next"
+ ├── opening_loc: (24,4)-(24,5) = "{"
+ └── closing_loc: (24,14)-(24,15) = "}"
diff --git a/test/prism/snapshots/nils.txt b/test/prism/snapshots/nils.txt
new file mode 100644
index 0000000000..f72745560f
--- /dev/null
+++ b/test/prism/snapshots/nils.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(12,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(12,11))
+ └── body: (length: 5)
+ ├── @ NilNode (location: (1,0)-(1,3))
+ ├── @ ParenthesesNode (location: (3,0)-(3,2))
+ │ ├── body: ∅
+ │ ├── opening_loc: (3,0)-(3,1) = "("
+ │ └── closing_loc: (3,1)-(3,2) = ")"
+ ├── @ ParenthesesNode (location: (5,0)-(8,1))
+ │ ├── body: ∅
+ │ ├── opening_loc: (5,0)-(5,1) = "("
+ │ └── closing_loc: (8,0)-(8,1) = ")"
+ ├── @ PostExecutionNode (location: (10,0)-(10,9))
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (10,6)-(10,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (10,6)-(10,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_loc: (10,0)-(10,3) = "END"
+ │ ├── opening_loc: (10,4)-(10,5) = "{"
+ │ └── closing_loc: (10,8)-(10,9) = "}"
+ └── @ PreExecutionNode (location: (12,0)-(12,11))
+ ├── statements:
+ │ @ StatementsNode (location: (12,8)-(12,9))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (12,8)-(12,9))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── keyword_loc: (12,0)-(12,5) = "BEGIN"
+ ├── opening_loc: (12,6)-(12,7) = "{"
+ └── closing_loc: (12,10)-(12,11) = "}"
diff --git a/test/prism/snapshots/non_alphanumeric_methods.txt b/test/prism/snapshots/non_alphanumeric_methods.txt
new file mode 100644
index 0000000000..2ed66fe0e2
--- /dev/null
+++ b/test/prism/snapshots/non_alphanumeric_methods.txt
@@ -0,0 +1,503 @@
+@ ProgramNode (location: (1,0)-(105,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(105,3))
+ └── body: (length: 36)
+ ├── @ DefNode (location: (1,0)-(2,3))
+ │ ├── name: :!
+ │ ├── name_loc: (1,4)-(1,5) = "!"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (2,0)-(2,3) = "end"
+ ├── @ DefNode (location: (4,0)-(5,3))
+ │ ├── name: :!=
+ │ ├── name_loc: (4,4)-(4,6) = "!="
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (4,0)-(4,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ DefNode (location: (7,0)-(8,3))
+ │ ├── name: :!~
+ │ ├── name_loc: (7,4)-(7,6) = "!~"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (8,0)-(8,3) = "end"
+ ├── @ DefNode (location: (10,0)-(11,3))
+ │ ├── name: :%
+ │ ├── name_loc: (10,4)-(10,5) = "%"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (10,0)-(10,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ DefNode (location: (13,0)-(14,3))
+ │ ├── name: :+
+ │ ├── name_loc: (13,9)-(13,10) = "+"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (13,4)-(13,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (13,0)-(13,3) = "def"
+ │ ├── operator_loc: (13,8)-(13,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (14,0)-(14,3) = "end"
+ ├── @ DefNode (location: (16,0)-(17,3))
+ │ ├── name: :&
+ │ ├── name_loc: (16,4)-(16,5) = "&"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (16,0)-(16,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (17,0)-(17,3) = "end"
+ ├── @ DefNode (location: (19,0)-(20,3))
+ │ ├── name: :*
+ │ ├── name_loc: (19,4)-(19,5) = "*"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (19,0)-(19,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (20,0)-(20,3) = "end"
+ ├── @ DefNode (location: (22,0)-(23,3))
+ │ ├── name: :**
+ │ ├── name_loc: (22,4)-(22,6) = "**"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (22,0)-(22,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (23,0)-(23,3) = "end"
+ ├── @ StringNode (location: (25,0)-(25,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (25,0)-(25,2) = "%|"
+ │ ├── content_loc: (25,2)-(25,5) = "abc"
+ │ ├── closing_loc: (25,5)-(25,6) = "|"
+ │ └── unescaped: "abc"
+ ├── @ DefNode (location: (27,0)-(28,3))
+ │ ├── name: :+
+ │ ├── name_loc: (27,4)-(27,5) = "+"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (27,6)-(27,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (27,6)-(27,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (27,8)-(27,9) = "b"
+ │ │ │ └── operator_loc: (27,6)-(27,8) = "**"
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (27,0)-(27,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (28,0)-(28,3) = "end"
+ ├── @ DefNode (location: (30,0)-(31,3))
+ │ ├── name: :+
+ │ ├── name_loc: (30,4)-(30,5) = "+"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (30,0)-(30,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (30,5)-(30,6) = "("
+ │ ├── rparen_loc: (30,6)-(30,7) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (31,0)-(31,3) = "end"
+ ├── @ DefNode (location: (33,0)-(34,3))
+ │ ├── name: :+
+ │ ├── name_loc: (33,4)-(33,5) = "+"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (33,6)-(33,7))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (33,6)-(33,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (33,0)-(33,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (34,0)-(34,3) = "end"
+ ├── @ DefNode (location: (36,0)-(37,3))
+ │ ├── name: :+
+ │ ├── name_loc: (36,9)-(36,10) = "+"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (36,4)-(36,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (36,0)-(36,3) = "def"
+ │ ├── operator_loc: (36,8)-(36,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (37,0)-(37,3) = "end"
+ ├── @ DefNode (location: (39,0)-(40,3))
+ │ ├── name: :+
+ │ ├── name_loc: (39,4)-(39,5) = "+"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (39,0)-(39,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (40,0)-(40,3) = "end"
+ ├── @ DefNode (location: (42,0)-(43,3))
+ │ ├── name: :+@
+ │ ├── name_loc: (42,4)-(42,6) = "+@"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (42,0)-(42,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (43,0)-(43,3) = "end"
+ ├── @ DefNode (location: (45,0)-(46,3))
+ │ ├── name: :-
+ │ ├── name_loc: (45,4)-(45,5) = "-"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (45,0)-(45,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (46,0)-(46,3) = "end"
+ ├── @ DefNode (location: (48,0)-(48,11))
+ │ ├── name: :-
+ │ ├── name_loc: (48,6)-(48,7) = "-"
+ │ ├── receiver:
+ │ │ @ CallNode (location: (48,4)-(48,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (48,4)-(48,5) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (48,0)-(48,3) = "def"
+ │ ├── operator_loc: (48,5)-(48,6) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (48,8)-(48,11) = "end"
+ ├── @ DefNode (location: (50,0)-(51,3))
+ │ ├── name: :-@
+ │ ├── name_loc: (50,4)-(50,6) = "-@"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (50,0)-(50,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (51,0)-(51,3) = "end"
+ ├── @ DefNode (location: (53,0)-(54,3))
+ │ ├── name: :/
+ │ ├── name_loc: (53,4)-(53,5) = "/"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (53,0)-(53,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (54,0)-(54,3) = "end"
+ ├── @ DefNode (location: (56,0)-(57,3))
+ │ ├── name: :<
+ │ ├── name_loc: (56,4)-(56,5) = "<"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (56,0)-(56,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (57,0)-(57,3) = "end"
+ ├── @ DefNode (location: (59,0)-(60,3))
+ │ ├── name: :<<
+ │ ├── name_loc: (59,4)-(59,6) = "<<"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (59,0)-(59,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (60,0)-(60,3) = "end"
+ ├── @ DefNode (location: (62,0)-(63,3))
+ │ ├── name: :<=
+ │ ├── name_loc: (62,4)-(62,6) = "<="
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (62,0)-(62,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (63,0)-(63,3) = "end"
+ ├── @ DefNode (location: (65,0)-(66,3))
+ │ ├── name: :<=>
+ │ ├── name_loc: (65,4)-(65,7) = "<=>"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (65,0)-(65,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (66,0)-(66,3) = "end"
+ ├── @ DefNode (location: (68,0)-(69,3))
+ │ ├── name: :==
+ │ ├── name_loc: (68,4)-(68,6) = "=="
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (68,0)-(68,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (69,0)-(69,3) = "end"
+ ├── @ DefNode (location: (71,0)-(72,3))
+ │ ├── name: :===
+ │ ├── name_loc: (71,4)-(71,7) = "==="
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (71,0)-(71,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (72,0)-(72,3) = "end"
+ ├── @ DefNode (location: (74,0)-(75,3))
+ │ ├── name: :=~
+ │ ├── name_loc: (74,4)-(74,6) = "=~"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (74,0)-(74,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (75,0)-(75,3) = "end"
+ ├── @ DefNode (location: (77,0)-(78,3))
+ │ ├── name: :>
+ │ ├── name_loc: (77,4)-(77,5) = ">"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (77,0)-(77,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (78,0)-(78,3) = "end"
+ ├── @ DefNode (location: (80,0)-(81,3))
+ │ ├── name: :>=
+ │ ├── name_loc: (80,4)-(80,6) = ">="
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (80,0)-(80,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (81,0)-(81,3) = "end"
+ ├── @ DefNode (location: (83,0)-(84,3))
+ │ ├── name: :>>
+ │ ├── name_loc: (83,4)-(83,6) = ">>"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (83,0)-(83,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (84,0)-(84,3) = "end"
+ ├── @ DefNode (location: (86,0)-(87,3))
+ │ ├── name: :[]
+ │ ├── name_loc: (86,4)-(86,6) = "[]"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (86,0)-(86,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (87,0)-(87,3) = "end"
+ ├── @ DefNode (location: (89,0)-(90,3))
+ │ ├── name: :[]=
+ │ ├── name_loc: (89,4)-(89,7) = "[]="
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (89,0)-(89,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (90,0)-(90,3) = "end"
+ ├── @ DefNode (location: (92,0)-(93,3))
+ │ ├── name: :^
+ │ ├── name_loc: (92,4)-(92,5) = "^"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (92,0)-(92,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (93,0)-(93,3) = "end"
+ ├── @ DefNode (location: (95,0)-(96,3))
+ │ ├── name: :`
+ │ ├── name_loc: (95,4)-(95,5) = "`"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (95,0)-(95,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (96,0)-(96,3) = "end"
+ ├── @ DefNode (location: (98,0)-(99,3))
+ │ ├── name: :`
+ │ ├── name_loc: (98,9)-(98,10) = "`"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (98,4)-(98,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (98,0)-(98,3) = "def"
+ │ ├── operator_loc: (98,8)-(98,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (99,0)-(99,3) = "end"
+ ├── @ DefNode (location: (101,0)-(102,3))
+ │ ├── name: :|
+ │ ├── name_loc: (101,4)-(101,5) = "|"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (101,0)-(101,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (102,0)-(102,3) = "end"
+ └── @ DefNode (location: (104,0)-(105,3))
+ ├── name: :~
+ ├── name_loc: (104,4)-(104,5) = "~"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (104,0)-(104,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (105,0)-(105,3) = "end"
diff --git a/test/prism/snapshots/not.txt b/test/prism/snapshots/not.txt
new file mode 100644
index 0000000000..fda61bb4b5
--- /dev/null
+++ b/test/prism/snapshots/not.txt
@@ -0,0 +1,351 @@
+@ ProgramNode (location: (1,0)-(37,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(37,16))
+ └── body: (length: 10)
+ ├── @ AndNode (location: (1,0)-(1,19))
+ │ ├── left:
+ │ │ @ CallNode (location: (1,0)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,4)-(1,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (1,4)-(1,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (1,0)-(1,3) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (1,12)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,16)-(1,19))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,16)-(1,19) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (1,12)-(1,15) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,8)-(1,11) = "and"
+ ├── @ CallNode (location: (3,0)-(3,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ AndNode (location: (3,4)-(3,15))
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (3,4)-(3,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (3,4)-(3,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (3,12)-(3,15))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (3,12)-(3,15) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (3,8)-(3,11) = "and"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (3,0)-(3,3) = "not"
+ │ ├── opening_loc: (3,3)-(3,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (3,15)-(3,16) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (5,4)-(5,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (5,4)-(5,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (5,0)-(5,3) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ AndNode (location: (7,0)-(8,5))
+ │ ├── left:
+ │ │ @ CallNode (location: (7,0)-(7,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (7,4)-(7,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (7,4)-(7,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (7,0)-(7,3) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (7,12)-(8,5))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (8,2)-(8,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (8,2)-(8,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (7,12)-(7,15) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (7,8)-(7,11) = "and"
+ ├── @ AndNode (location: (11,0)-(13,5))
+ │ ├── left:
+ │ │ @ CallNode (location: (11,0)-(11,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (11,4)-(11,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (11,4)-(11,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (11,0)-(11,3) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (12,4)-(13,5))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (13,2)-(13,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (13,2)-(13,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (12,4)-(12,7) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (11,8)-(11,11) = "and"
+ ├── @ AndNode (location: (16,0)-(20,5))
+ │ ├── left:
+ │ │ @ CallNode (location: (16,0)-(16,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (16,4)-(16,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (16,4)-(16,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (16,0)-(16,3) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (17,2)-(20,5))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (20,2)-(20,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (20,2)-(20,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (17,2)-(17,5) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (16,8)-(16,11) = "and"
+ ├── @ CallNode (location: (22,0)-(25,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (22,4)-(22,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (22,4)-(22,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (22,0)-(22,3) = "not"
+ │ ├── opening_loc: (22,3)-(22,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (25,0)-(25,1) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (27,0)-(33,3))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (30,0)-(30,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (30,0)-(30,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (27,0)-(27,3) = "not"
+ │ ├── opening_loc: (27,3)-(27,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (33,2)-(33,3) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (35,0)-(35,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ FlipFlopNode (location: (35,4)-(35,14))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (35,4)-(35,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (35,4)-(35,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (35,11)-(35,14))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (35,11)-(35,14) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (35,8)-(35,10) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (35,0)-(35,3) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (37,0)-(37,16))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ ParenthesesNode (location: (37,4)-(37,16))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (37,5)-(37,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ FlipFlopNode (location: (37,5)-(37,15))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (37,5)-(37,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (37,5)-(37,8) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (37,12)-(37,15))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (37,12)-(37,15) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (37,9)-(37,11) = ".."
+ │ ├── opening_loc: (37,4)-(37,5) = "("
+ │ └── closing_loc: (37,15)-(37,16) = ")"
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (37,0)-(37,3) = "not"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/numbers.txt b/test/prism/snapshots/numbers.txt
new file mode 100644
index 0000000000..740f3f5a2a
--- /dev/null
+++ b/test/prism/snapshots/numbers.txt
@@ -0,0 +1,142 @@
+@ ProgramNode (location: (1,0)-(67,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(67,5))
+ └── body: (length: 34)
+ ├── @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 0
+ ├── @ IntegerNode (location: (3,0)-(3,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ FloatNode (location: (5,0)-(5,3))
+ │ └── value: 1.0
+ ├── @ IntegerNode (location: (7,0)-(7,1))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ IntegerNode (location: (9,0)-(9,3))
+ │ ├── flags: binary
+ │ └── value: 0
+ ├── @ IntegerNode (location: (11,0)-(11,3))
+ │ ├── flags: binary
+ │ └── value: 1
+ ├── @ IntegerNode (location: (13,0)-(13,4))
+ │ ├── flags: binary
+ │ └── value: 2
+ ├── @ IntegerNode (location: (15,0)-(15,3))
+ │ ├── flags: decimal
+ │ └── value: 0
+ ├── @ IntegerNode (location: (17,0)-(17,3))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IntegerNode (location: (19,0)-(19,3))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ IntegerNode (location: (21,0)-(21,2))
+ │ ├── flags: octal
+ │ └── value: 0
+ ├── @ IntegerNode (location: (23,0)-(23,2))
+ │ ├── flags: octal
+ │ └── value: 1
+ ├── @ IntegerNode (location: (25,0)-(25,2))
+ │ ├── flags: octal
+ │ └── value: 2
+ ├── @ IntegerNode (location: (27,0)-(27,3))
+ │ ├── flags: octal
+ │ └── value: 0
+ ├── @ IntegerNode (location: (29,0)-(29,3))
+ │ ├── flags: octal
+ │ └── value: 1
+ ├── @ IntegerNode (location: (31,0)-(31,3))
+ │ ├── flags: octal
+ │ └── value: 2
+ ├── @ IntegerNode (location: (33,0)-(33,3))
+ │ ├── flags: hexadecimal
+ │ └── value: 0
+ ├── @ IntegerNode (location: (35,0)-(35,3))
+ │ ├── flags: hexadecimal
+ │ └── value: 1
+ ├── @ IntegerNode (location: (37,0)-(37,3))
+ │ ├── flags: hexadecimal
+ │ └── value: 2
+ ├── @ ImaginaryNode (location: (39,0)-(39,2))
+ │ └── numeric:
+ │ @ IntegerNode (location: (39,0)-(39,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ RationalNode (location: (41,0)-(41,2))
+ │ └── numeric:
+ │ @ IntegerNode (location: (41,0)-(41,1))
+ │ ├── flags: decimal
+ │ └── value: 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
+ ├── @ RationalNode (location: (47,0)-(47,4))
+ │ └── numeric:
+ │ @ FloatNode (location: (47,0)-(47,3))
+ │ └── value: 1.2
+ ├── @ ImaginaryNode (location: (49,0)-(49,5))
+ │ └── numeric:
+ │ @ RationalNode (location: (49,0)-(49,4))
+ │ └── numeric:
+ │ @ FloatNode (location: (49,0)-(49,3))
+ │ └── value: 1.2
+ ├── @ ImaginaryNode (location: (51,0)-(51,4))
+ │ └── numeric:
+ │ @ RationalNode (location: (51,0)-(51,3))
+ │ └── numeric:
+ │ @ IntegerNode (location: (51,0)-(51,2))
+ │ ├── flags: decimal
+ │ └── value: -1
+ ├── @ RationalNode (location: (53,0)-(53,5))
+ │ └── numeric:
+ │ @ FloatNode (location: (53,0)-(53,4))
+ │ └── value: -1.2
+ ├── @ ImaginaryNode (location: (55,0)-(55,6))
+ │ └── numeric:
+ │ @ RationalNode (location: (55,0)-(55,5))
+ │ └── numeric:
+ │ @ FloatNode (location: (55,0)-(55,4))
+ │ └── value: -1.2
+ ├── @ RationalNode (location: (57,0)-(57,4))
+ │ └── numeric:
+ │ @ IntegerNode (location: (57,0)-(57,3))
+ │ ├── flags: octal
+ │ └── value: 1
+ ├── @ ImaginaryNode (location: (59,0)-(59,4))
+ │ └── numeric:
+ │ @ IntegerNode (location: (59,0)-(59,3))
+ │ ├── flags: octal
+ │ └── value: 1
+ ├── @ ImaginaryNode (location: (61,0)-(61,5))
+ │ └── numeric:
+ │ @ RationalNode (location: (61,0)-(61,4))
+ │ └── numeric:
+ │ @ IntegerNode (location: (61,0)-(61,3))
+ │ ├── flags: octal
+ │ └── value: 1
+ ├── @ RationalNode (location: (63,0)-(63,4))
+ │ └── numeric:
+ │ @ IntegerNode (location: (63,0)-(63,3))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ ImaginaryNode (location: (65,0)-(65,4))
+ │ └── numeric:
+ │ @ IntegerNode (location: (65,0)-(65,3))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── @ ImaginaryNode (location: (67,0)-(67,5))
+ └── numeric:
+ @ RationalNode (location: (67,0)-(67,4))
+ └── numeric:
+ @ IntegerNode (location: (67,0)-(67,3))
+ ├── flags: binary
+ └── value: 1
diff --git a/test/prism/snapshots/patterns.txt b/test/prism/snapshots/patterns.txt
new file mode 100644
index 0000000000..5662129dae
--- /dev/null
+++ b/test/prism/snapshots/patterns.txt
@@ -0,0 +1,4921 @@
+@ ProgramNode (location: (1,0)-(217,5))
+├── locals: [:bar, :baz, :qux, :b, :a, :foo, :x]
+└── statements:
+ @ StatementsNode (location: (1,0)-(217,5))
+ └── body: (length: 180)
+ ├── @ MatchRequiredNode (location: (1,0)-(1,10))
+ │ ├── value:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ LocalVariableTargetNode (location: (1,7)-(1,10))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ └── operator_loc: (1,4)-(1,6) = "=>"
+ ├── @ MatchRequiredNode (location: (2,0)-(2,8))
+ │ ├── value:
+ │ │ @ CallNode (location: (2,0)-(2,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (2,0)-(2,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ IntegerNode (location: (2,7)-(2,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (2,4)-(2,6) = "=>"
+ ├── @ MatchRequiredNode (location: (3,0)-(3,10))
+ │ ├── value:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ FloatNode (location: (3,7)-(3,10))
+ │ │ └── value: 1.0
+ │ └── operator_loc: (3,4)-(3,6) = "=>"
+ ├── @ MatchRequiredNode (location: (4,0)-(4,9))
+ │ ├── value:
+ │ │ @ CallNode (location: (4,0)-(4,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (4,0)-(4,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ImaginaryNode (location: (4,7)-(4,9))
+ │ │ └── numeric:
+ │ │ @ IntegerNode (location: (4,7)-(4,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (4,4)-(4,6) = "=>"
+ ├── @ MatchRequiredNode (location: (5,0)-(5,9))
+ │ ├── value:
+ │ │ @ CallNode (location: (5,0)-(5,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RationalNode (location: (5,7)-(5,9))
+ │ │ └── numeric:
+ │ │ @ IntegerNode (location: (5,7)-(5,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (5,4)-(5,6) = "=>"
+ ├── @ MatchRequiredNode (location: (6,0)-(6,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (6,0)-(6,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (6,0)-(6,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SymbolNode (location: (6,7)-(6,11))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (6,7)-(6,8) = ":"
+ │ │ ├── value_loc: (6,8)-(6,11) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (6,4)-(6,6) = "=>"
+ ├── @ MatchRequiredNode (location: (7,0)-(7,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (7,0)-(7,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SymbolNode (location: (7,7)-(7,14))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (7,7)-(7,10) = "%s["
+ │ │ ├── value_loc: (7,10)-(7,13) = "foo"
+ │ │ ├── closing_loc: (7,13)-(7,14) = "]"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (7,4)-(7,6) = "=>"
+ ├── @ MatchRequiredNode (location: (8,0)-(8,13))
+ │ ├── value:
+ │ │ @ CallNode (location: (8,0)-(8,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (8,0)-(8,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SymbolNode (location: (8,7)-(8,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (8,7)-(8,9) = ":\""
+ │ │ ├── value_loc: (8,9)-(8,12) = "foo"
+ │ │ ├── closing_loc: (8,12)-(8,13) = "\""
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (8,4)-(8,6) = "=>"
+ ├── @ MatchRequiredNode (location: (9,0)-(9,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (9,0)-(9,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (9,0)-(9,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RegularExpressionNode (location: (9,7)-(9,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (9,7)-(9,8) = "/"
+ │ │ ├── content_loc: (9,8)-(9,11) = "foo"
+ │ │ ├── closing_loc: (9,11)-(9,12) = "/"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (9,4)-(9,6) = "=>"
+ ├── @ MatchRequiredNode (location: (10,0)-(10,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (10,0)-(10,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (10,0)-(10,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ XStringNode (location: (10,7)-(10,12))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (10,7)-(10,8) = "`"
+ │ │ ├── content_loc: (10,8)-(10,11) = "foo"
+ │ │ ├── closing_loc: (10,11)-(10,12) = "`"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (10,4)-(10,6) = "=>"
+ ├── @ MatchRequiredNode (location: (11,0)-(11,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (11,0)-(11,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (11,0)-(11,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ XStringNode (location: (11,7)-(11,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (11,7)-(11,10) = "%x["
+ │ │ ├── content_loc: (11,10)-(11,13) = "foo"
+ │ │ ├── closing_loc: (11,13)-(11,14) = "]"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (11,4)-(11,6) = "=>"
+ ├── @ MatchRequiredNode (location: (12,0)-(12,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (12,0)-(12,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (12,0)-(12,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayNode (location: (12,7)-(12,14))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (12,10)-(12,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (12,10)-(12,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── opening_loc: (12,7)-(12,10) = "%i["
+ │ │ └── closing_loc: (12,13)-(12,14) = "]"
+ │ └── operator_loc: (12,4)-(12,6) = "=>"
+ ├── @ MatchRequiredNode (location: (13,0)-(13,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (13,0)-(13,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (13,0)-(13,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayNode (location: (13,7)-(13,14))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (13,10)-(13,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (13,10)-(13,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── opening_loc: (13,7)-(13,10) = "%I["
+ │ │ └── closing_loc: (13,13)-(13,14) = "]"
+ │ └── operator_loc: (13,4)-(13,6) = "=>"
+ ├── @ MatchRequiredNode (location: (14,0)-(14,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (14,0)-(14,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (14,0)-(14,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayNode (location: (14,7)-(14,14))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ StringNode (location: (14,10)-(14,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (14,10)-(14,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── opening_loc: (14,7)-(14,10) = "%w["
+ │ │ └── closing_loc: (14,13)-(14,14) = "]"
+ │ └── operator_loc: (14,4)-(14,6) = "=>"
+ ├── @ MatchRequiredNode (location: (15,0)-(15,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (15,0)-(15,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (15,0)-(15,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayNode (location: (15,7)-(15,14))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ StringNode (location: (15,10)-(15,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (15,10)-(15,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── opening_loc: (15,7)-(15,10) = "%W["
+ │ │ └── closing_loc: (15,13)-(15,14) = "]"
+ │ └── operator_loc: (15,4)-(15,6) = "=>"
+ ├── @ MatchRequiredNode (location: (16,0)-(16,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (16,0)-(16,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (16,0)-(16,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ StringNode (location: (16,7)-(16,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (16,7)-(16,10) = "%q["
+ │ │ ├── content_loc: (16,10)-(16,13) = "foo"
+ │ │ ├── closing_loc: (16,13)-(16,14) = "]"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (16,4)-(16,6) = "=>"
+ ├── @ MatchRequiredNode (location: (17,0)-(17,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (17,0)-(17,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (17,0)-(17,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ StringNode (location: (17,7)-(17,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (17,7)-(17,10) = "%Q["
+ │ │ ├── content_loc: (17,10)-(17,13) = "foo"
+ │ │ ├── closing_loc: (17,13)-(17,14) = "]"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (17,4)-(17,6) = "=>"
+ ├── @ MatchRequiredNode (location: (18,0)-(18,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (18,0)-(18,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (18,0)-(18,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ StringNode (location: (18,7)-(18,12))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (18,7)-(18,8) = "\""
+ │ │ ├── content_loc: (18,8)-(18,11) = "foo"
+ │ │ ├── closing_loc: (18,11)-(18,12) = "\""
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (18,4)-(18,6) = "=>"
+ ├── @ MatchRequiredNode (location: (19,0)-(19,10))
+ │ ├── value:
+ │ │ @ CallNode (location: (19,0)-(19,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (19,0)-(19,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ NilNode (location: (19,7)-(19,10))
+ │ └── operator_loc: (19,4)-(19,6) = "=>"
+ ├── @ MatchRequiredNode (location: (20,0)-(20,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (20,0)-(20,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (20,0)-(20,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SelfNode (location: (20,7)-(20,11))
+ │ └── operator_loc: (20,4)-(20,6) = "=>"
+ ├── @ MatchRequiredNode (location: (21,0)-(21,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (21,0)-(21,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (21,0)-(21,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ TrueNode (location: (21,7)-(21,11))
+ │ └── operator_loc: (21,4)-(21,6) = "=>"
+ ├── @ MatchRequiredNode (location: (22,0)-(22,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (22,0)-(22,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (22,0)-(22,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ FalseNode (location: (22,7)-(22,12))
+ │ └── operator_loc: (22,4)-(22,6) = "=>"
+ ├── @ MatchRequiredNode (location: (23,0)-(23,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (23,0)-(23,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (23,0)-(23,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SourceFileNode (location: (23,7)-(23,15))
+ │ │ ├── flags: ∅
+ │ │ └── filepath: "patterns.txt"
+ │ └── operator_loc: (23,4)-(23,6) = "=>"
+ ├── @ MatchRequiredNode (location: (24,0)-(24,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (24,0)-(24,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (24,0)-(24,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SourceLineNode (location: (24,7)-(24,15))
+ │ └── operator_loc: (24,4)-(24,6) = "=>"
+ ├── @ MatchRequiredNode (location: (25,0)-(25,19))
+ │ ├── value:
+ │ │ @ CallNode (location: (25,0)-(25,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (25,0)-(25,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SourceEncodingNode (location: (25,7)-(25,19))
+ │ └── operator_loc: (25,4)-(25,6) = "=>"
+ ├── @ MatchRequiredNode (location: (26,0)-(26,17))
+ │ ├── value:
+ │ │ @ CallNode (location: (26,0)-(26,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (26,0)-(26,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ LambdaNode (location: (26,7)-(26,17))
+ │ │ ├── locals: []
+ │ │ ├── operator_loc: (26,7)-(26,9) = "->"
+ │ │ ├── opening_loc: (26,10)-(26,11) = "{"
+ │ │ ├── closing_loc: (26,16)-(26,17) = "}"
+ │ │ ├── parameters: ∅
+ │ │ └── body:
+ │ │ @ StatementsNode (location: (26,12)-(26,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (26,12)-(26,15))
+ │ │ ├── name: :bar
+ │ │ └── depth: 1
+ │ └── operator_loc: (26,4)-(26,6) = "=>"
+ ├── @ MatchRequiredNode (location: (28,0)-(28,13))
+ │ ├── value:
+ │ │ @ CallNode (location: (28,0)-(28,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (28,0)-(28,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (28,7)-(28,13))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (28,7)-(28,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (28,12)-(28,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (28,9)-(28,11) = ".."
+ │ └── operator_loc: (28,4)-(28,6) = "=>"
+ ├── @ MatchRequiredNode (location: (29,0)-(29,17))
+ │ ├── value:
+ │ │ @ CallNode (location: (29,0)-(29,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (29,0)-(29,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (29,7)-(29,17))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ FloatNode (location: (29,7)-(29,10))
+ │ │ │ └── value: 1.0
+ │ │ ├── right:
+ │ │ │ @ FloatNode (location: (29,14)-(29,17))
+ │ │ │ └── value: 1.0
+ │ │ └── operator_loc: (29,11)-(29,13) = ".."
+ │ └── operator_loc: (29,4)-(29,6) = "=>"
+ ├── @ MatchRequiredNode (location: (30,0)-(30,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (30,0)-(30,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (30,0)-(30,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (30,7)-(30,15))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ ImaginaryNode (location: (30,7)-(30,9))
+ │ │ │ └── numeric:
+ │ │ │ @ IntegerNode (location: (30,7)-(30,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ ImaginaryNode (location: (30,13)-(30,15))
+ │ │ │ └── numeric:
+ │ │ │ @ IntegerNode (location: (30,13)-(30,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (30,10)-(30,12) = ".."
+ │ └── operator_loc: (30,4)-(30,6) = "=>"
+ ├── @ MatchRequiredNode (location: (31,0)-(31,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (31,0)-(31,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (31,0)-(31,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (31,7)-(31,15))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ RationalNode (location: (31,7)-(31,9))
+ │ │ │ └── numeric:
+ │ │ │ @ IntegerNode (location: (31,7)-(31,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right:
+ │ │ │ @ RationalNode (location: (31,13)-(31,15))
+ │ │ │ └── numeric:
+ │ │ │ @ IntegerNode (location: (31,13)-(31,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (31,10)-(31,12) = ".."
+ │ └── operator_loc: (31,4)-(31,6) = "=>"
+ ├── @ MatchRequiredNode (location: (32,0)-(32,19))
+ │ ├── value:
+ │ │ @ CallNode (location: (32,0)-(32,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (32,0)-(32,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (32,7)-(32,19))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ SymbolNode (location: (32,7)-(32,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (32,7)-(32,8) = ":"
+ │ │ │ ├── value_loc: (32,8)-(32,11) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ SymbolNode (location: (32,15)-(32,19))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (32,15)-(32,16) = ":"
+ │ │ │ ├── value_loc: (32,16)-(32,19) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (32,12)-(32,14) = ".."
+ │ └── operator_loc: (32,4)-(32,6) = "=>"
+ ├── @ MatchRequiredNode (location: (33,0)-(33,25))
+ │ ├── value:
+ │ │ @ CallNode (location: (33,0)-(33,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (33,0)-(33,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (33,7)-(33,25))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ SymbolNode (location: (33,7)-(33,14))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (33,7)-(33,10) = "%s["
+ │ │ │ ├── value_loc: (33,10)-(33,13) = "foo"
+ │ │ │ ├── closing_loc: (33,13)-(33,14) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ SymbolNode (location: (33,18)-(33,25))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (33,18)-(33,21) = "%s["
+ │ │ │ ├── value_loc: (33,21)-(33,24) = "foo"
+ │ │ │ ├── closing_loc: (33,24)-(33,25) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (33,15)-(33,17) = ".."
+ │ └── operator_loc: (33,4)-(33,6) = "=>"
+ ├── @ MatchRequiredNode (location: (34,0)-(34,23))
+ │ ├── value:
+ │ │ @ CallNode (location: (34,0)-(34,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (34,0)-(34,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (34,7)-(34,23))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ SymbolNode (location: (34,7)-(34,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (34,7)-(34,9) = ":\""
+ │ │ │ ├── value_loc: (34,9)-(34,12) = "foo"
+ │ │ │ ├── closing_loc: (34,12)-(34,13) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ SymbolNode (location: (34,17)-(34,23))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (34,17)-(34,19) = ":\""
+ │ │ │ ├── value_loc: (34,19)-(34,22) = "foo"
+ │ │ │ ├── closing_loc: (34,22)-(34,23) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (34,14)-(34,16) = ".."
+ │ └── operator_loc: (34,4)-(34,6) = "=>"
+ ├── @ MatchRequiredNode (location: (35,0)-(35,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (35,0)-(35,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (35,0)-(35,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (35,7)-(35,21))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ RegularExpressionNode (location: (35,7)-(35,12))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (35,7)-(35,8) = "/"
+ │ │ │ ├── content_loc: (35,8)-(35,11) = "foo"
+ │ │ │ ├── closing_loc: (35,11)-(35,12) = "/"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ RegularExpressionNode (location: (35,16)-(35,21))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (35,16)-(35,17) = "/"
+ │ │ │ ├── content_loc: (35,17)-(35,20) = "foo"
+ │ │ │ ├── closing_loc: (35,20)-(35,21) = "/"
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (35,13)-(35,15) = ".."
+ │ └── operator_loc: (35,4)-(35,6) = "=>"
+ ├── @ MatchRequiredNode (location: (36,0)-(36,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (36,0)-(36,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (36,0)-(36,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (36,7)-(36,21))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ XStringNode (location: (36,7)-(36,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (36,7)-(36,8) = "`"
+ │ │ │ ├── content_loc: (36,8)-(36,11) = "foo"
+ │ │ │ ├── closing_loc: (36,11)-(36,12) = "`"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ XStringNode (location: (36,16)-(36,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (36,16)-(36,17) = "`"
+ │ │ │ ├── content_loc: (36,17)-(36,20) = "foo"
+ │ │ │ ├── closing_loc: (36,20)-(36,21) = "`"
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (36,13)-(36,15) = ".."
+ │ └── operator_loc: (36,4)-(36,6) = "=>"
+ ├── @ MatchRequiredNode (location: (37,0)-(37,25))
+ │ ├── value:
+ │ │ @ CallNode (location: (37,0)-(37,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (37,0)-(37,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (37,7)-(37,25))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ XStringNode (location: (37,7)-(37,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (37,7)-(37,10) = "%x["
+ │ │ │ ├── content_loc: (37,10)-(37,13) = "foo"
+ │ │ │ ├── closing_loc: (37,13)-(37,14) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ XStringNode (location: (37,18)-(37,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (37,18)-(37,21) = "%x["
+ │ │ │ ├── content_loc: (37,21)-(37,24) = "foo"
+ │ │ │ ├── closing_loc: (37,24)-(37,25) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (37,15)-(37,17) = ".."
+ │ └── operator_loc: (37,4)-(37,6) = "=>"
+ ├── @ MatchRequiredNode (location: (38,0)-(38,25))
+ │ ├── value:
+ │ │ @ CallNode (location: (38,0)-(38,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (38,0)-(38,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (38,7)-(38,25))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ ArrayNode (location: (38,7)-(38,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (38,10)-(38,13))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (38,10)-(38,13) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (38,7)-(38,10) = "%i["
+ │ │ │ └── closing_loc: (38,13)-(38,14) = "]"
+ │ │ ├── right:
+ │ │ │ @ ArrayNode (location: (38,18)-(38,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (38,21)-(38,24))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (38,21)-(38,24) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (38,18)-(38,21) = "%i["
+ │ │ │ └── closing_loc: (38,24)-(38,25) = "]"
+ │ │ └── operator_loc: (38,15)-(38,17) = ".."
+ │ └── operator_loc: (38,4)-(38,6) = "=>"
+ ├── @ MatchRequiredNode (location: (39,0)-(39,25))
+ │ ├── value:
+ │ │ @ CallNode (location: (39,0)-(39,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (39,0)-(39,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (39,7)-(39,25))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ ArrayNode (location: (39,7)-(39,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (39,10)-(39,13))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (39,10)-(39,13) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (39,7)-(39,10) = "%I["
+ │ │ │ └── closing_loc: (39,13)-(39,14) = "]"
+ │ │ ├── right:
+ │ │ │ @ ArrayNode (location: (39,18)-(39,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (39,21)-(39,24))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (39,21)-(39,24) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (39,18)-(39,21) = "%I["
+ │ │ │ └── closing_loc: (39,24)-(39,25) = "]"
+ │ │ └── operator_loc: (39,15)-(39,17) = ".."
+ │ └── operator_loc: (39,4)-(39,6) = "=>"
+ ├── @ MatchRequiredNode (location: (40,0)-(40,25))
+ │ ├── value:
+ │ │ @ CallNode (location: (40,0)-(40,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (40,0)-(40,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (40,7)-(40,25))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ ArrayNode (location: (40,7)-(40,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (40,10)-(40,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (40,10)-(40,13) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (40,7)-(40,10) = "%w["
+ │ │ │ └── closing_loc: (40,13)-(40,14) = "]"
+ │ │ ├── right:
+ │ │ │ @ ArrayNode (location: (40,18)-(40,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (40,21)-(40,24))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (40,21)-(40,24) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (40,18)-(40,21) = "%w["
+ │ │ │ └── closing_loc: (40,24)-(40,25) = "]"
+ │ │ └── operator_loc: (40,15)-(40,17) = ".."
+ │ └── operator_loc: (40,4)-(40,6) = "=>"
+ ├── @ MatchRequiredNode (location: (41,0)-(41,25))
+ │ ├── value:
+ │ │ @ CallNode (location: (41,0)-(41,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (41,0)-(41,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (41,7)-(41,25))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ ArrayNode (location: (41,7)-(41,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (41,10)-(41,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (41,10)-(41,13) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (41,7)-(41,10) = "%W["
+ │ │ │ └── closing_loc: (41,13)-(41,14) = "]"
+ │ │ ├── right:
+ │ │ │ @ ArrayNode (location: (41,18)-(41,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (41,21)-(41,24))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (41,21)-(41,24) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (41,18)-(41,21) = "%W["
+ │ │ │ └── closing_loc: (41,24)-(41,25) = "]"
+ │ │ └── operator_loc: (41,15)-(41,17) = ".."
+ │ └── operator_loc: (41,4)-(41,6) = "=>"
+ ├── @ MatchRequiredNode (location: (42,0)-(42,25))
+ │ ├── value:
+ │ │ @ CallNode (location: (42,0)-(42,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (42,0)-(42,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (42,7)-(42,25))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ StringNode (location: (42,7)-(42,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (42,7)-(42,10) = "%q["
+ │ │ │ ├── content_loc: (42,10)-(42,13) = "foo"
+ │ │ │ ├── closing_loc: (42,13)-(42,14) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ StringNode (location: (42,18)-(42,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (42,18)-(42,21) = "%q["
+ │ │ │ ├── content_loc: (42,21)-(42,24) = "foo"
+ │ │ │ ├── closing_loc: (42,24)-(42,25) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (42,15)-(42,17) = ".."
+ │ └── operator_loc: (42,4)-(42,6) = "=>"
+ ├── @ MatchRequiredNode (location: (43,0)-(43,25))
+ │ ├── value:
+ │ │ @ CallNode (location: (43,0)-(43,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (43,0)-(43,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (43,7)-(43,25))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ StringNode (location: (43,7)-(43,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (43,7)-(43,10) = "%Q["
+ │ │ │ ├── content_loc: (43,10)-(43,13) = "foo"
+ │ │ │ ├── closing_loc: (43,13)-(43,14) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ StringNode (location: (43,18)-(43,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (43,18)-(43,21) = "%Q["
+ │ │ │ ├── content_loc: (43,21)-(43,24) = "foo"
+ │ │ │ ├── closing_loc: (43,24)-(43,25) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (43,15)-(43,17) = ".."
+ │ └── operator_loc: (43,4)-(43,6) = "=>"
+ ├── @ MatchRequiredNode (location: (44,0)-(44,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (44,0)-(44,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (44,0)-(44,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (44,7)-(44,21))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ StringNode (location: (44,7)-(44,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (44,7)-(44,8) = "\""
+ │ │ │ ├── content_loc: (44,8)-(44,11) = "foo"
+ │ │ │ ├── closing_loc: (44,11)-(44,12) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── right:
+ │ │ │ @ StringNode (location: (44,16)-(44,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (44,16)-(44,17) = "\""
+ │ │ │ ├── content_loc: (44,17)-(44,20) = "foo"
+ │ │ │ ├── closing_loc: (44,20)-(44,21) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (44,13)-(44,15) = ".."
+ │ └── operator_loc: (44,4)-(44,6) = "=>"
+ ├── @ MatchRequiredNode (location: (45,0)-(45,17))
+ │ ├── value:
+ │ │ @ CallNode (location: (45,0)-(45,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (45,0)-(45,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (45,7)-(45,17))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ NilNode (location: (45,7)-(45,10))
+ │ │ ├── right:
+ │ │ │ @ NilNode (location: (45,14)-(45,17))
+ │ │ └── operator_loc: (45,11)-(45,13) = ".."
+ │ └── operator_loc: (45,4)-(45,6) = "=>"
+ ├── @ MatchRequiredNode (location: (46,0)-(46,19))
+ │ ├── value:
+ │ │ @ CallNode (location: (46,0)-(46,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (46,0)-(46,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (46,7)-(46,19))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ SelfNode (location: (46,7)-(46,11))
+ │ │ ├── right:
+ │ │ │ @ SelfNode (location: (46,15)-(46,19))
+ │ │ └── operator_loc: (46,12)-(46,14) = ".."
+ │ └── operator_loc: (46,4)-(46,6) = "=>"
+ ├── @ MatchRequiredNode (location: (47,0)-(47,19))
+ │ ├── value:
+ │ │ @ CallNode (location: (47,0)-(47,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (47,0)-(47,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (47,7)-(47,19))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ TrueNode (location: (47,7)-(47,11))
+ │ │ ├── right:
+ │ │ │ @ TrueNode (location: (47,15)-(47,19))
+ │ │ └── operator_loc: (47,12)-(47,14) = ".."
+ │ └── operator_loc: (47,4)-(47,6) = "=>"
+ ├── @ MatchRequiredNode (location: (48,0)-(48,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (48,0)-(48,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (48,0)-(48,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (48,7)-(48,21))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ FalseNode (location: (48,7)-(48,12))
+ │ │ ├── right:
+ │ │ │ @ FalseNode (location: (48,16)-(48,21))
+ │ │ └── operator_loc: (48,13)-(48,15) = ".."
+ │ └── operator_loc: (48,4)-(48,6) = "=>"
+ ├── @ MatchRequiredNode (location: (49,0)-(49,27))
+ │ ├── value:
+ │ │ @ CallNode (location: (49,0)-(49,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (49,0)-(49,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (49,7)-(49,27))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ SourceFileNode (location: (49,7)-(49,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── filepath: "patterns.txt"
+ │ │ ├── right:
+ │ │ │ @ SourceFileNode (location: (49,19)-(49,27))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── filepath: "patterns.txt"
+ │ │ └── operator_loc: (49,16)-(49,18) = ".."
+ │ └── operator_loc: (49,4)-(49,6) = "=>"
+ ├── @ MatchRequiredNode (location: (50,0)-(50,27))
+ │ ├── value:
+ │ │ @ CallNode (location: (50,0)-(50,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (50,0)-(50,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (50,7)-(50,27))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ SourceLineNode (location: (50,7)-(50,15))
+ │ │ ├── right:
+ │ │ │ @ SourceLineNode (location: (50,19)-(50,27))
+ │ │ └── operator_loc: (50,16)-(50,18) = ".."
+ │ └── operator_loc: (50,4)-(50,6) = "=>"
+ ├── @ MatchRequiredNode (location: (51,0)-(51,35))
+ │ ├── value:
+ │ │ @ CallNode (location: (51,0)-(51,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (51,0)-(51,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (51,7)-(51,35))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ SourceEncodingNode (location: (51,7)-(51,19))
+ │ │ ├── right:
+ │ │ │ @ SourceEncodingNode (location: (51,23)-(51,35))
+ │ │ └── operator_loc: (51,20)-(51,22) = ".."
+ │ └── operator_loc: (51,4)-(51,6) = "=>"
+ ├── @ MatchRequiredNode (location: (52,0)-(52,31))
+ │ ├── value:
+ │ │ @ CallNode (location: (52,0)-(52,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (52,0)-(52,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (52,7)-(52,31))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ LambdaNode (location: (52,7)-(52,17))
+ │ │ │ ├── locals: []
+ │ │ │ ├── operator_loc: (52,7)-(52,9) = "->"
+ │ │ │ ├── opening_loc: (52,10)-(52,11) = "{"
+ │ │ │ ├── closing_loc: (52,16)-(52,17) = "}"
+ │ │ │ ├── parameters: ∅
+ │ │ │ └── body:
+ │ │ │ @ StatementsNode (location: (52,12)-(52,15))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (52,12)-(52,15))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 1
+ │ │ ├── right:
+ │ │ │ @ LambdaNode (location: (52,21)-(52,31))
+ │ │ │ ├── locals: []
+ │ │ │ ├── operator_loc: (52,21)-(52,23) = "->"
+ │ │ │ ├── opening_loc: (52,24)-(52,25) = "{"
+ │ │ │ ├── closing_loc: (52,30)-(52,31) = "}"
+ │ │ │ ├── parameters: ∅
+ │ │ │ └── body:
+ │ │ │ @ StatementsNode (location: (52,26)-(52,29))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (52,26)-(52,29))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 1
+ │ │ └── operator_loc: (52,18)-(52,20) = ".."
+ │ └── operator_loc: (52,4)-(52,6) = "=>"
+ ├── @ LocalVariableWriteNode (location: (54,0)-(54,7))
+ │ ├── name: :bar
+ │ ├── depth: 0
+ │ ├── name_loc: (54,0)-(54,3) = "bar"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (54,6)-(54,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (54,4)-(54,5) = "="
+ ├── @ MatchRequiredNode (location: (54,9)-(54,20))
+ │ ├── value:
+ │ │ @ CallNode (location: (54,9)-(54,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (54,9)-(54,12) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ PinnedVariableNode (location: (54,16)-(54,20))
+ │ │ ├── variable:
+ │ │ │ @ LocalVariableReadNode (location: (54,17)-(54,20))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ └── operator_loc: (54,16)-(54,17) = "^"
+ │ └── operator_loc: (54,13)-(54,15) = "=>"
+ ├── @ MatchRequiredNode (location: (55,0)-(55,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (55,0)-(55,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (55,0)-(55,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ PinnedVariableNode (location: (55,7)-(55,12))
+ │ │ ├── variable:
+ │ │ │ @ InstanceVariableReadNode (location: (55,8)-(55,12))
+ │ │ │ └── name: :@bar
+ │ │ └── operator_loc: (55,7)-(55,8) = "^"
+ │ └── operator_loc: (55,4)-(55,6) = "=>"
+ ├── @ MatchRequiredNode (location: (56,0)-(56,13))
+ │ ├── value:
+ │ │ @ CallNode (location: (56,0)-(56,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (56,0)-(56,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ PinnedVariableNode (location: (56,7)-(56,13))
+ │ │ ├── variable:
+ │ │ │ @ ClassVariableReadNode (location: (56,8)-(56,13))
+ │ │ │ └── name: :@@bar
+ │ │ └── operator_loc: (56,7)-(56,8) = "^"
+ │ └── operator_loc: (56,4)-(56,6) = "=>"
+ ├── @ MatchRequiredNode (location: (57,0)-(57,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (57,0)-(57,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (57,0)-(57,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ PinnedVariableNode (location: (57,7)-(57,12))
+ │ │ ├── variable:
+ │ │ │ @ GlobalVariableReadNode (location: (57,8)-(57,12))
+ │ │ │ └── name: :$bar
+ │ │ └── operator_loc: (57,7)-(57,8) = "^"
+ │ └── operator_loc: (57,4)-(57,6) = "=>"
+ ├── @ MatchRequiredNode (location: (59,0)-(59,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (59,0)-(59,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (59,0)-(59,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ PinnedExpressionNode (location: (59,7)-(59,11))
+ │ │ ├── expression:
+ │ │ │ @ IntegerNode (location: (59,9)-(59,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── operator_loc: (59,7)-(59,8) = "^"
+ │ │ ├── lparen_loc: (59,8)-(59,9) = "("
+ │ │ └── rparen_loc: (59,10)-(59,11) = ")"
+ │ └── operator_loc: (59,4)-(59,6) = "=>"
+ ├── @ MatchRequiredNode (location: (60,0)-(60,13))
+ │ ├── value:
+ │ │ @ CallNode (location: (60,0)-(60,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (60,0)-(60,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ PinnedExpressionNode (location: (60,7)-(60,13))
+ │ │ ├── expression:
+ │ │ │ @ NilNode (location: (60,9)-(60,12))
+ │ │ ├── operator_loc: (60,7)-(60,8) = "^"
+ │ │ ├── lparen_loc: (60,8)-(60,9) = "("
+ │ │ └── rparen_loc: (60,12)-(60,13) = ")"
+ │ └── operator_loc: (60,4)-(60,6) = "=>"
+ ├── @ MatchRequiredNode (location: (61,0)-(61,23))
+ │ ├── value:
+ │ │ @ CallNode (location: (61,0)-(61,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (61,0)-(61,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ PinnedExpressionNode (location: (61,7)-(61,23))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (61,9)-(61,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ StringNode (location: (61,9)-(61,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (61,9)-(61,10) = "\""
+ │ │ │ │ ├── content_loc: (61,10)-(61,13) = "bar"
+ │ │ │ │ ├── closing_loc: (61,13)-(61,14) = "\""
+ │ │ │ │ └── unescaped: "bar"
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+
+ │ │ │ ├── message_loc: (61,15)-(61,16) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (61,17)-(61,22))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (61,17)-(61,22))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (61,17)-(61,18) = "\""
+ │ │ │ │ ├── content_loc: (61,18)-(61,21) = "baz"
+ │ │ │ │ ├── closing_loc: (61,21)-(61,22) = "\""
+ │ │ │ │ └── unescaped: "baz"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── operator_loc: (61,7)-(61,8) = "^"
+ │ │ ├── lparen_loc: (61,8)-(61,9) = "("
+ │ │ └── rparen_loc: (61,22)-(61,23) = ")"
+ │ └── operator_loc: (61,4)-(61,6) = "=>"
+ ├── @ MatchRequiredNode (location: (63,0)-(63,10))
+ │ ├── value:
+ │ │ @ CallNode (location: (63,0)-(63,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (63,0)-(63,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ConstantReadNode (location: (63,7)-(63,10))
+ │ │ └── name: :Foo
+ │ └── operator_loc: (63,4)-(63,6) = "=>"
+ ├── @ MatchRequiredNode (location: (64,0)-(64,20))
+ │ ├── value:
+ │ │ @ CallNode (location: (64,0)-(64,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (64,0)-(64,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ConstantPathNode (location: (64,7)-(64,20))
+ │ │ ├── parent:
+ │ │ │ @ ConstantPathNode (location: (64,7)-(64,15))
+ │ │ │ ├── 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) = "::"
+ │ └── operator_loc: (64,4)-(64,6) = "=>"
+ ├── @ MatchRequiredNode (location: (65,0)-(65,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (65,0)-(65,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (65,0)-(65,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ConstantPathNode (location: (65,7)-(65,12))
+ │ │ ├── parent: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (65,9)-(65,12))
+ │ │ │ └── name: :Foo
+ │ │ └── delimiter_loc: (65,7)-(65,9) = "::"
+ │ └── operator_loc: (65,4)-(65,6) = "=>"
+ ├── @ MatchRequiredNode (location: (66,0)-(66,22))
+ │ ├── value:
+ │ │ @ CallNode (location: (66,0)-(66,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (66,0)-(66,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ConstantPathNode (location: (66,7)-(66,22))
+ │ │ ├── parent:
+ │ │ │ @ ConstantPathNode (location: (66,7)-(66,17))
+ │ │ │ ├── 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) = "::"
+ │ └── operator_loc: (66,4)-(66,6) = "=>"
+ ├── @ MatchRequiredNode (location: (68,0)-(68,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (68,0)-(68,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (68,0)-(68,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (68,7)-(68,12))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (68,7)-(68,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (68,10)-(68,11) = "("
+ │ │ └── closing_loc: (68,11)-(68,12) = ")"
+ │ └── operator_loc: (68,4)-(68,6) = "=>"
+ ├── @ MatchRequiredNode (location: (69,0)-(69,13))
+ │ ├── value:
+ │ │ @ CallNode (location: (69,0)-(69,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (69,0)-(69,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (69,7)-(69,13))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (69,7)-(69,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (69,11)-(69,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (69,10)-(69,11) = "("
+ │ │ └── closing_loc: (69,12)-(69,13) = ")"
+ │ └── operator_loc: (69,4)-(69,6) = "=>"
+ ├── @ MatchRequiredNode (location: (70,0)-(70,19))
+ │ ├── value:
+ │ │ @ CallNode (location: (70,0)-(70,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (70,0)-(70,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (70,7)-(70,19))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (70,7)-(70,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (70,11)-(70,12))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ IntegerNode (location: (70,14)-(70,15))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (70,17)-(70,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (70,10)-(70,11) = "("
+ │ │ └── closing_loc: (70,18)-(70,19) = ")"
+ │ └── operator_loc: (70,4)-(70,6) = "=>"
+ ├── @ MatchRequiredNode (location: (71,0)-(71,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (71,0)-(71,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (71,0)-(71,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (71,7)-(71,15))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (71,7)-(71,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (71,11)-(71,14))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (71,10)-(71,11) = "("
+ │ │ └── closing_loc: (71,14)-(71,15) = ")"
+ │ └── operator_loc: (71,4)-(71,6) = "=>"
+ ├── @ MatchRequiredNode (location: (72,0)-(72,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (72,0)-(72,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (72,0)-(72,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (72,7)-(72,21))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (72,7)-(72,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (72,11)-(72,15))
+ │ │ │ ├── operator_loc: (72,11)-(72,12) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (72,12)-(72,15))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (72,17)-(72,20))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (72,10)-(72,11) = "("
+ │ │ └── closing_loc: (72,20)-(72,21) = ")"
+ │ └── operator_loc: (72,4)-(72,6) = "=>"
+ ├── @ MatchRequiredNode (location: (73,0)-(73,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (73,0)-(73,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (73,0)-(73,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (73,7)-(73,21))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (73,7)-(73,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (73,11)-(73,14))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (73,16)-(73,20))
+ │ │ │ ├── operator_loc: (73,16)-(73,17) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (73,17)-(73,20))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (73,10)-(73,11) = "("
+ │ │ └── closing_loc: (73,20)-(73,21) = ")"
+ │ └── operator_loc: (73,4)-(73,6) = "=>"
+ ├── @ MatchRequiredNode (location: (74,0)-(74,27))
+ │ ├── value:
+ │ │ @ CallNode (location: (74,0)-(74,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (74,0)-(74,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ FindPatternNode (location: (74,7)-(74,27))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (74,7)-(74,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── left:
+ │ │ │ @ SplatNode (location: (74,11)-(74,15))
+ │ │ │ ├── operator_loc: (74,11)-(74,12) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (74,12)-(74,15))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (74,17)-(74,20))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── right:
+ │ │ │ @ SplatNode (location: (74,22)-(74,26))
+ │ │ │ ├── operator_loc: (74,22)-(74,23) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (74,23)-(74,26))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (74,10)-(74,11) = "("
+ │ │ └── closing_loc: (74,26)-(74,27) = ")"
+ │ └── operator_loc: (74,4)-(74,6) = "=>"
+ ├── @ MatchRequiredNode (location: (76,0)-(76,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (76,0)-(76,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (76,0)-(76,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (76,7)-(76,12))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (76,7)-(76,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (76,10)-(76,11) = "["
+ │ │ └── closing_loc: (76,11)-(76,12) = "]"
+ │ └── operator_loc: (76,4)-(76,6) = "=>"
+ ├── @ MatchRequiredNode (location: (77,0)-(77,13))
+ │ ├── value:
+ │ │ @ CallNode (location: (77,0)-(77,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (77,0)-(77,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (77,7)-(77,13))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (77,7)-(77,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (77,11)-(77,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (77,10)-(77,11) = "["
+ │ │ └── closing_loc: (77,12)-(77,13) = "]"
+ │ └── operator_loc: (77,4)-(77,6) = "=>"
+ ├── @ MatchRequiredNode (location: (78,0)-(78,19))
+ │ ├── value:
+ │ │ @ CallNode (location: (78,0)-(78,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (78,0)-(78,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (78,7)-(78,19))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (78,7)-(78,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 3)
+ │ │ │ ├── @ IntegerNode (location: (78,11)-(78,12))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── @ IntegerNode (location: (78,14)-(78,15))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (78,17)-(78,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (78,10)-(78,11) = "["
+ │ │ └── closing_loc: (78,18)-(78,19) = "]"
+ │ └── operator_loc: (78,4)-(78,6) = "=>"
+ ├── @ MatchRequiredNode (location: (79,0)-(79,17))
+ │ ├── value:
+ │ │ @ CallNode (location: (79,0)-(79,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (79,0)-(79,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (79,7)-(79,17))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (79,7)-(79,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ ArrayPatternNode (location: (79,11)-(79,16))
+ │ │ │ ├── constant:
+ │ │ │ │ @ ConstantReadNode (location: (79,11)-(79,14))
+ │ │ │ │ └── name: :Foo
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (79,14)-(79,15) = "["
+ │ │ │ └── closing_loc: (79,15)-(79,16) = "]"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (79,10)-(79,11) = "["
+ │ │ └── closing_loc: (79,16)-(79,17) = "]"
+ │ └── operator_loc: (79,4)-(79,6) = "=>"
+ ├── @ MatchRequiredNode (location: (80,0)-(80,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (80,0)-(80,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (80,0)-(80,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (80,7)-(80,15))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (80,7)-(80,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (80,11)-(80,14))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (80,10)-(80,11) = "["
+ │ │ └── closing_loc: (80,14)-(80,15) = "]"
+ │ └── operator_loc: (80,4)-(80,6) = "=>"
+ ├── @ MatchRequiredNode (location: (81,0)-(81,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (81,0)-(81,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (81,0)-(81,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (81,7)-(81,21))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (81,7)-(81,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (81,11)-(81,15))
+ │ │ │ ├── operator_loc: (81,11)-(81,12) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (81,12)-(81,15))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (81,17)-(81,20))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (81,10)-(81,11) = "["
+ │ │ └── closing_loc: (81,20)-(81,21) = "]"
+ │ └── operator_loc: (81,4)-(81,6) = "=>"
+ ├── @ MatchRequiredNode (location: (82,0)-(82,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (82,0)-(82,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (82,0)-(82,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (82,7)-(82,21))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (82,7)-(82,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (82,11)-(82,14))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (82,16)-(82,20))
+ │ │ │ ├── operator_loc: (82,16)-(82,17) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (82,17)-(82,20))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (82,10)-(82,11) = "["
+ │ │ └── closing_loc: (82,20)-(82,21) = "]"
+ │ └── operator_loc: (82,4)-(82,6) = "=>"
+ ├── @ MatchRequiredNode (location: (83,0)-(83,27))
+ │ ├── value:
+ │ │ @ CallNode (location: (83,0)-(83,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (83,0)-(83,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ FindPatternNode (location: (83,7)-(83,27))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (83,7)-(83,10))
+ │ │ │ └── name: :Foo
+ │ │ ├── left:
+ │ │ │ @ SplatNode (location: (83,11)-(83,15))
+ │ │ │ ├── operator_loc: (83,11)-(83,12) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (83,12)-(83,15))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (83,17)-(83,20))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── right:
+ │ │ │ @ SplatNode (location: (83,22)-(83,26))
+ │ │ │ ├── operator_loc: (83,22)-(83,23) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (83,23)-(83,26))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (83,10)-(83,11) = "["
+ │ │ └── closing_loc: (83,26)-(83,27) = "]"
+ │ └── operator_loc: (83,4)-(83,6) = "=>"
+ ├── @ MatchRequiredNode (location: (85,0)-(85,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (85,0)-(85,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (85,0)-(85,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (85,7)-(85,11))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (85,7)-(85,11))
+ │ │ │ ├── operator_loc: (85,7)-(85,8) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (85,8)-(85,11))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (85,4)-(85,6) = "=>"
+ ├── @ MatchRequiredNode (location: (86,0)-(86,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (86,0)-(86,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (86,0)-(86,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (86,7)-(86,21))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (86,7)-(86,11))
+ │ │ │ ├── operator_loc: (86,7)-(86,8) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (86,8)-(86,11))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (86,13)-(86,16))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (86,18)-(86,21))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (86,4)-(86,6) = "=>"
+ ├── @ MatchRequiredNode (location: (87,0)-(87,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (87,0)-(87,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (87,0)-(87,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (87,7)-(87,21))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (87,7)-(87,10))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (87,12)-(87,16))
+ │ │ │ ├── operator_loc: (87,12)-(87,13) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (87,13)-(87,16))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (87,18)-(87,21))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (87,4)-(87,6) = "=>"
+ ├── @ MatchRequiredNode (location: (88,0)-(88,21))
+ │ ├── value:
+ │ │ @ CallNode (location: (88,0)-(88,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (88,0)-(88,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (88,7)-(88,21))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (88,7)-(88,10))
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (88,12)-(88,15))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (88,17)-(88,21))
+ │ │ │ ├── operator_loc: (88,17)-(88,18) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (88,18)-(88,21))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (88,4)-(88,6) = "=>"
+ ├── @ MatchRequiredNode (location: (89,0)-(89,22))
+ │ ├── value:
+ │ │ @ CallNode (location: (89,0)-(89,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (89,0)-(89,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ FindPatternNode (location: (89,7)-(89,22))
+ │ │ ├── constant: ∅
+ │ │ ├── left:
+ │ │ │ @ SplatNode (location: (89,7)-(89,11))
+ │ │ │ ├── operator_loc: (89,7)-(89,8) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (89,8)-(89,11))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (89,13)-(89,16))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── right:
+ │ │ │ @ SplatNode (location: (89,18)-(89,22))
+ │ │ │ ├── operator_loc: (89,18)-(89,19) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (89,19)-(89,22))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (89,4)-(89,6) = "=>"
+ ├── @ MatchRequiredNode (location: (91,0)-(91,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (91,0)-(91,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (91,0)-(91,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (91,7)-(91,11))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (91,7)-(91,10))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ ImplicitRestNode (location: (91,10)-(91,11))
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (91,4)-(91,6) = "=>"
+ ├── @ MatchRequiredNode (location: (95,0)-(95,9))
+ │ ├── value:
+ │ │ @ CallNode (location: (95,0)-(95,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (95,0)-(95,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (95,7)-(95,9))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (95,7)-(95,8) = "["
+ │ │ └── closing_loc: (95,8)-(95,9) = "]"
+ │ └── operator_loc: (95,4)-(95,6) = "=>"
+ ├── @ MatchRequiredNode (location: (96,0)-(96,17))
+ │ ├── value:
+ │ │ @ CallNode (location: (96,0)-(96,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (96,0)-(96,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (96,7)-(96,17))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ ArrayPatternNode (location: (96,8)-(96,16))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ ArrayPatternNode (location: (96,9)-(96,15))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ ArrayPatternNode (location: (96,10)-(96,14))
+ │ │ │ │ │ ├── constant: ∅
+ │ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ │ └── @ ArrayPatternNode (location: (96,11)-(96,13))
+ │ │ │ │ │ │ ├── constant: ∅
+ │ │ │ │ │ │ ├── requireds: (length: 0)
+ │ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ │ ├── opening_loc: (96,11)-(96,12) = "["
+ │ │ │ │ │ │ └── closing_loc: (96,12)-(96,13) = "]"
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ ├── opening_loc: (96,10)-(96,11) = "["
+ │ │ │ │ │ └── closing_loc: (96,13)-(96,14) = "]"
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── opening_loc: (96,9)-(96,10) = "["
+ │ │ │ │ └── closing_loc: (96,14)-(96,15) = "]"
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (96,8)-(96,9) = "["
+ │ │ │ └── closing_loc: (96,15)-(96,16) = "]"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (96,7)-(96,8) = "["
+ │ │ └── closing_loc: (96,16)-(96,17) = "]"
+ │ └── operator_loc: (96,4)-(96,6) = "=>"
+ ├── @ MatchRequiredNode (location: (98,0)-(98,13))
+ │ ├── value:
+ │ │ @ CallNode (location: (98,0)-(98,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (98,0)-(98,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (98,7)-(98,13))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (98,8)-(98,12))
+ │ │ │ ├── operator_loc: (98,8)-(98,9) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (98,9)-(98,12))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (98,7)-(98,8) = "["
+ │ │ └── closing_loc: (98,12)-(98,13) = "]"
+ │ └── operator_loc: (98,4)-(98,6) = "=>"
+ ├── @ MatchRequiredNode (location: (99,0)-(99,23))
+ │ ├── value:
+ │ │ @ CallNode (location: (99,0)-(99,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (99,0)-(99,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (99,7)-(99,23))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (99,8)-(99,12))
+ │ │ │ ├── operator_loc: (99,8)-(99,9) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (99,9)-(99,12))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (99,14)-(99,17))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (99,19)-(99,22))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (99,7)-(99,8) = "["
+ │ │ └── closing_loc: (99,22)-(99,23) = "]"
+ │ └── operator_loc: (99,4)-(99,6) = "=>"
+ ├── @ MatchRequiredNode (location: (100,0)-(100,23))
+ │ ├── value:
+ │ │ @ CallNode (location: (100,0)-(100,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (100,0)-(100,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (100,7)-(100,23))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (100,8)-(100,11))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (100,13)-(100,17))
+ │ │ │ ├── operator_loc: (100,13)-(100,14) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (100,14)-(100,17))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (100,19)-(100,22))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (100,7)-(100,8) = "["
+ │ │ └── closing_loc: (100,22)-(100,23) = "]"
+ │ └── operator_loc: (100,4)-(100,6) = "=>"
+ ├── @ MatchRequiredNode (location: (101,0)-(101,23))
+ │ ├── value:
+ │ │ @ CallNode (location: (101,0)-(101,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (101,0)-(101,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (101,7)-(101,23))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (101,8)-(101,11))
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (101,13)-(101,16))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (101,18)-(101,22))
+ │ │ │ ├── operator_loc: (101,18)-(101,19) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (101,19)-(101,22))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (101,7)-(101,8) = "["
+ │ │ └── closing_loc: (101,22)-(101,23) = "]"
+ │ └── operator_loc: (101,4)-(101,6) = "=>"
+ ├── @ MatchRequiredNode (location: (102,0)-(102,24))
+ │ ├── value:
+ │ │ @ CallNode (location: (102,0)-(102,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (102,0)-(102,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ FindPatternNode (location: (102,7)-(102,24))
+ │ │ ├── constant: ∅
+ │ │ ├── left:
+ │ │ │ @ SplatNode (location: (102,8)-(102,12))
+ │ │ │ ├── operator_loc: (102,8)-(102,9) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (102,9)-(102,12))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (102,14)-(102,17))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── right:
+ │ │ │ @ SplatNode (location: (102,19)-(102,23))
+ │ │ │ ├── operator_loc: (102,19)-(102,20) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (102,20)-(102,23))
+ │ │ │ ├── name: :qux
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (102,7)-(102,8) = "["
+ │ │ └── closing_loc: (102,23)-(102,24) = "]"
+ │ └── operator_loc: (102,4)-(102,6) = "=>"
+ ├── @ MatchPredicateNode (location: (104,0)-(104,10))
+ │ ├── value:
+ │ │ @ CallNode (location: (104,0)-(104,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (104,0)-(104,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ LocalVariableTargetNode (location: (104,7)-(104,10))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ └── operator_loc: (104,4)-(104,6) = "in"
+ ├── @ MatchPredicateNode (location: (105,0)-(105,8))
+ │ ├── value:
+ │ │ @ CallNode (location: (105,0)-(105,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (105,0)-(105,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ IntegerNode (location: (105,7)-(105,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (105,4)-(105,6) = "in"
+ ├── @ MatchPredicateNode (location: (106,0)-(106,10))
+ │ ├── value:
+ │ │ @ CallNode (location: (106,0)-(106,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (106,0)-(106,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ FloatNode (location: (106,7)-(106,10))
+ │ │ └── value: 1.0
+ │ └── operator_loc: (106,4)-(106,6) = "in"
+ ├── @ MatchPredicateNode (location: (107,0)-(107,9))
+ │ ├── value:
+ │ │ @ CallNode (location: (107,0)-(107,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (107,0)-(107,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ImaginaryNode (location: (107,7)-(107,9))
+ │ │ └── numeric:
+ │ │ @ IntegerNode (location: (107,7)-(107,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (107,4)-(107,6) = "in"
+ ├── @ MatchPredicateNode (location: (108,0)-(108,9))
+ │ ├── value:
+ │ │ @ CallNode (location: (108,0)-(108,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (108,0)-(108,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RationalNode (location: (108,7)-(108,9))
+ │ │ └── numeric:
+ │ │ @ IntegerNode (location: (108,7)-(108,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (108,4)-(108,6) = "in"
+ ├── @ MatchPredicateNode (location: (109,0)-(109,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (109,0)-(109,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (109,0)-(109,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SymbolNode (location: (109,7)-(109,11))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (109,7)-(109,8) = ":"
+ │ │ ├── value_loc: (109,8)-(109,11) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (109,4)-(109,6) = "in"
+ ├── @ MatchPredicateNode (location: (110,0)-(110,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (110,0)-(110,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (110,0)-(110,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SymbolNode (location: (110,7)-(110,14))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (110,7)-(110,10) = "%s["
+ │ │ ├── value_loc: (110,10)-(110,13) = "foo"
+ │ │ ├── closing_loc: (110,13)-(110,14) = "]"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (110,4)-(110,6) = "in"
+ ├── @ MatchPredicateNode (location: (111,0)-(111,13))
+ │ ├── value:
+ │ │ @ CallNode (location: (111,0)-(111,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (111,0)-(111,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SymbolNode (location: (111,7)-(111,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (111,7)-(111,9) = ":\""
+ │ │ ├── value_loc: (111,9)-(111,12) = "foo"
+ │ │ ├── closing_loc: (111,12)-(111,13) = "\""
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (111,4)-(111,6) = "in"
+ ├── @ MatchPredicateNode (location: (112,0)-(112,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (112,0)-(112,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (112,0)-(112,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ RegularExpressionNode (location: (112,7)-(112,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (112,7)-(112,8) = "/"
+ │ │ ├── content_loc: (112,8)-(112,11) = "foo"
+ │ │ ├── closing_loc: (112,11)-(112,12) = "/"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (112,4)-(112,6) = "in"
+ ├── @ MatchPredicateNode (location: (113,0)-(113,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (113,0)-(113,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (113,0)-(113,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ XStringNode (location: (113,7)-(113,12))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (113,7)-(113,8) = "`"
+ │ │ ├── content_loc: (113,8)-(113,11) = "foo"
+ │ │ ├── closing_loc: (113,11)-(113,12) = "`"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (113,4)-(113,6) = "in"
+ ├── @ MatchPredicateNode (location: (114,0)-(114,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (114,0)-(114,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (114,0)-(114,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ XStringNode (location: (114,7)-(114,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (114,7)-(114,10) = "%x["
+ │ │ ├── content_loc: (114,10)-(114,13) = "foo"
+ │ │ ├── closing_loc: (114,13)-(114,14) = "]"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (114,4)-(114,6) = "in"
+ ├── @ MatchPredicateNode (location: (115,0)-(115,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (115,0)-(115,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (115,0)-(115,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayNode (location: (115,7)-(115,14))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (115,10)-(115,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (115,10)-(115,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── opening_loc: (115,7)-(115,10) = "%i["
+ │ │ └── closing_loc: (115,13)-(115,14) = "]"
+ │ └── operator_loc: (115,4)-(115,6) = "in"
+ ├── @ MatchPredicateNode (location: (116,0)-(116,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (116,0)-(116,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (116,0)-(116,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayNode (location: (116,7)-(116,14))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (116,10)-(116,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (116,10)-(116,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── opening_loc: (116,7)-(116,10) = "%I["
+ │ │ └── closing_loc: (116,13)-(116,14) = "]"
+ │ └── operator_loc: (116,4)-(116,6) = "in"
+ ├── @ MatchPredicateNode (location: (117,0)-(117,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (117,0)-(117,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (117,0)-(117,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayNode (location: (117,7)-(117,14))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ StringNode (location: (117,10)-(117,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (117,10)-(117,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── opening_loc: (117,7)-(117,10) = "%w["
+ │ │ └── closing_loc: (117,13)-(117,14) = "]"
+ │ └── operator_loc: (117,4)-(117,6) = "in"
+ ├── @ MatchPredicateNode (location: (118,0)-(118,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (118,0)-(118,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (118,0)-(118,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayNode (location: (118,7)-(118,14))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ StringNode (location: (118,10)-(118,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (118,10)-(118,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── opening_loc: (118,7)-(118,10) = "%W["
+ │ │ └── closing_loc: (118,13)-(118,14) = "]"
+ │ └── operator_loc: (118,4)-(118,6) = "in"
+ ├── @ MatchPredicateNode (location: (119,0)-(119,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (119,0)-(119,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (119,0)-(119,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ StringNode (location: (119,7)-(119,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (119,7)-(119,10) = "%q["
+ │ │ ├── content_loc: (119,10)-(119,13) = "foo"
+ │ │ ├── closing_loc: (119,13)-(119,14) = "]"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (119,4)-(119,6) = "in"
+ ├── @ MatchPredicateNode (location: (120,0)-(120,14))
+ │ ├── value:
+ │ │ @ CallNode (location: (120,0)-(120,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (120,0)-(120,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ StringNode (location: (120,7)-(120,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (120,7)-(120,10) = "%Q["
+ │ │ ├── content_loc: (120,10)-(120,13) = "foo"
+ │ │ ├── closing_loc: (120,13)-(120,14) = "]"
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (120,4)-(120,6) = "in"
+ ├── @ MatchPredicateNode (location: (121,0)-(121,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (121,0)-(121,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (121,0)-(121,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ StringNode (location: (121,7)-(121,12))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (121,7)-(121,8) = "\""
+ │ │ ├── content_loc: (121,8)-(121,11) = "foo"
+ │ │ ├── closing_loc: (121,11)-(121,12) = "\""
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (121,4)-(121,6) = "in"
+ ├── @ MatchPredicateNode (location: (122,0)-(122,10))
+ │ ├── value:
+ │ │ @ CallNode (location: (122,0)-(122,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (122,0)-(122,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ NilNode (location: (122,7)-(122,10))
+ │ └── operator_loc: (122,4)-(122,6) = "in"
+ ├── @ MatchPredicateNode (location: (123,0)-(123,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (123,0)-(123,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (123,0)-(123,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SelfNode (location: (123,7)-(123,11))
+ │ └── operator_loc: (123,4)-(123,6) = "in"
+ ├── @ MatchPredicateNode (location: (124,0)-(124,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (124,0)-(124,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (124,0)-(124,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ TrueNode (location: (124,7)-(124,11))
+ │ └── operator_loc: (124,4)-(124,6) = "in"
+ ├── @ MatchPredicateNode (location: (125,0)-(125,12))
+ │ ├── value:
+ │ │ @ CallNode (location: (125,0)-(125,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (125,0)-(125,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ FalseNode (location: (125,7)-(125,12))
+ │ └── operator_loc: (125,4)-(125,6) = "in"
+ ├── @ MatchPredicateNode (location: (126,0)-(126,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (126,0)-(126,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (126,0)-(126,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SourceFileNode (location: (126,7)-(126,15))
+ │ │ ├── flags: ∅
+ │ │ └── filepath: "patterns.txt"
+ │ └── operator_loc: (126,4)-(126,6) = "in"
+ ├── @ MatchPredicateNode (location: (127,0)-(127,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (127,0)-(127,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (127,0)-(127,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SourceLineNode (location: (127,7)-(127,15))
+ │ └── operator_loc: (127,4)-(127,6) = "in"
+ ├── @ MatchPredicateNode (location: (128,0)-(128,19))
+ │ ├── value:
+ │ │ @ CallNode (location: (128,0)-(128,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (128,0)-(128,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ SourceEncodingNode (location: (128,7)-(128,19))
+ │ └── operator_loc: (128,4)-(128,6) = "in"
+ ├── @ MatchPredicateNode (location: (129,0)-(129,17))
+ │ ├── value:
+ │ │ @ CallNode (location: (129,0)-(129,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (129,0)-(129,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ LambdaNode (location: (129,7)-(129,17))
+ │ │ ├── locals: []
+ │ │ ├── operator_loc: (129,7)-(129,9) = "->"
+ │ │ ├── opening_loc: (129,10)-(129,11) = "{"
+ │ │ ├── closing_loc: (129,16)-(129,17) = "}"
+ │ │ ├── parameters: ∅
+ │ │ └── body:
+ │ │ @ StatementsNode (location: (129,12)-(129,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (129,12)-(129,15))
+ │ │ ├── name: :bar
+ │ │ └── depth: 1
+ │ └── operator_loc: (129,4)-(129,6) = "in"
+ ├── @ MatchPredicateNode (location: (131,0)-(131,11))
+ │ ├── value:
+ │ │ @ CallNode (location: (131,0)-(131,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (131,0)-(131,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (131,7)-(131,11))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (131,7)-(131,10))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ ImplicitRestNode (location: (131,10)-(131,11))
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (131,4)-(131,6) = "in"
+ ├── @ CaseMatchNode (location: (135,0)-(135,25))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (135,5)-(135,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (135,5)-(135,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (135,10)-(135,21))
+ │ │ ├── pattern:
+ │ │ │ @ LocalVariableTargetNode (location: (135,13)-(135,16))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (135,10)-(135,12) = "in"
+ │ │ └── then_loc: (135,17)-(135,21) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (135,0)-(135,4) = "case"
+ │ └── end_keyword_loc: (135,22)-(135,25) = "end"
+ ├── @ CaseMatchNode (location: (136,0)-(136,23))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (136,5)-(136,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (136,5)-(136,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (136,10)-(136,19))
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (136,13)-(136,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (136,10)-(136,12) = "in"
+ │ │ └── then_loc: (136,15)-(136,19) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (136,0)-(136,4) = "case"
+ │ └── end_keyword_loc: (136,20)-(136,23) = "end"
+ ├── @ CaseMatchNode (location: (137,0)-(137,25))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (137,5)-(137,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (137,5)-(137,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (137,10)-(137,21))
+ │ │ ├── pattern:
+ │ │ │ @ FloatNode (location: (137,13)-(137,16))
+ │ │ │ └── value: 1.0
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (137,10)-(137,12) = "in"
+ │ │ └── then_loc: (137,17)-(137,21) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (137,0)-(137,4) = "case"
+ │ └── end_keyword_loc: (137,22)-(137,25) = "end"
+ ├── @ CaseMatchNode (location: (138,0)-(138,24))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (138,5)-(138,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (138,5)-(138,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (138,10)-(138,20))
+ │ │ ├── pattern:
+ │ │ │ @ ImaginaryNode (location: (138,13)-(138,15))
+ │ │ │ └── numeric:
+ │ │ │ @ IntegerNode (location: (138,13)-(138,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (138,10)-(138,12) = "in"
+ │ │ └── then_loc: (138,16)-(138,20) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (138,0)-(138,4) = "case"
+ │ └── end_keyword_loc: (138,21)-(138,24) = "end"
+ ├── @ CaseMatchNode (location: (139,0)-(139,24))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (139,5)-(139,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (139,5)-(139,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (139,10)-(139,20))
+ │ │ ├── pattern:
+ │ │ │ @ RationalNode (location: (139,13)-(139,15))
+ │ │ │ └── numeric:
+ │ │ │ @ IntegerNode (location: (139,13)-(139,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (139,10)-(139,12) = "in"
+ │ │ └── then_loc: (139,16)-(139,20) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (139,0)-(139,4) = "case"
+ │ └── end_keyword_loc: (139,21)-(139,24) = "end"
+ ├── @ CaseMatchNode (location: (140,0)-(140,26))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (140,5)-(140,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (140,5)-(140,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (140,10)-(140,22))
+ │ │ ├── pattern:
+ │ │ │ @ SymbolNode (location: (140,13)-(140,17))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (140,13)-(140,14) = ":"
+ │ │ │ ├── value_loc: (140,14)-(140,17) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (140,10)-(140,12) = "in"
+ │ │ └── then_loc: (140,18)-(140,22) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (140,0)-(140,4) = "case"
+ │ └── end_keyword_loc: (140,23)-(140,26) = "end"
+ ├── @ CaseMatchNode (location: (141,0)-(141,29))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (141,5)-(141,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (141,5)-(141,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (141,10)-(141,25))
+ │ │ ├── pattern:
+ │ │ │ @ SymbolNode (location: (141,13)-(141,20))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (141,13)-(141,16) = "%s["
+ │ │ │ ├── value_loc: (141,16)-(141,19) = "foo"
+ │ │ │ ├── closing_loc: (141,19)-(141,20) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (141,10)-(141,12) = "in"
+ │ │ └── then_loc: (141,21)-(141,25) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (141,0)-(141,4) = "case"
+ │ └── end_keyword_loc: (141,26)-(141,29) = "end"
+ ├── @ CaseMatchNode (location: (142,0)-(142,28))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (142,5)-(142,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (142,5)-(142,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (142,10)-(142,24))
+ │ │ ├── pattern:
+ │ │ │ @ SymbolNode (location: (142,13)-(142,19))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (142,13)-(142,15) = ":\""
+ │ │ │ ├── value_loc: (142,15)-(142,18) = "foo"
+ │ │ │ ├── closing_loc: (142,18)-(142,19) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (142,10)-(142,12) = "in"
+ │ │ └── then_loc: (142,20)-(142,24) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (142,0)-(142,4) = "case"
+ │ └── end_keyword_loc: (142,25)-(142,28) = "end"
+ ├── @ CaseMatchNode (location: (143,0)-(143,27))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (143,5)-(143,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (143,5)-(143,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (143,10)-(143,23))
+ │ │ ├── pattern:
+ │ │ │ @ RegularExpressionNode (location: (143,13)-(143,18))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (143,13)-(143,14) = "/"
+ │ │ │ ├── content_loc: (143,14)-(143,17) = "foo"
+ │ │ │ ├── closing_loc: (143,17)-(143,18) = "/"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (143,10)-(143,12) = "in"
+ │ │ └── then_loc: (143,19)-(143,23) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (143,0)-(143,4) = "case"
+ │ └── end_keyword_loc: (143,24)-(143,27) = "end"
+ ├── @ CaseMatchNode (location: (144,0)-(144,27))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (144,5)-(144,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (144,5)-(144,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (144,10)-(144,23))
+ │ │ ├── pattern:
+ │ │ │ @ XStringNode (location: (144,13)-(144,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (144,13)-(144,14) = "`"
+ │ │ │ ├── content_loc: (144,14)-(144,17) = "foo"
+ │ │ │ ├── closing_loc: (144,17)-(144,18) = "`"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (144,10)-(144,12) = "in"
+ │ │ └── then_loc: (144,19)-(144,23) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (144,0)-(144,4) = "case"
+ │ └── end_keyword_loc: (144,24)-(144,27) = "end"
+ ├── @ CaseMatchNode (location: (145,0)-(145,29))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (145,5)-(145,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (145,5)-(145,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (145,10)-(145,25))
+ │ │ ├── pattern:
+ │ │ │ @ XStringNode (location: (145,13)-(145,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (145,13)-(145,16) = "%x["
+ │ │ │ ├── content_loc: (145,16)-(145,19) = "foo"
+ │ │ │ ├── closing_loc: (145,19)-(145,20) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (145,10)-(145,12) = "in"
+ │ │ └── then_loc: (145,21)-(145,25) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (145,0)-(145,4) = "case"
+ │ └── end_keyword_loc: (145,26)-(145,29) = "end"
+ ├── @ CaseMatchNode (location: (146,0)-(146,29))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (146,5)-(146,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (146,5)-(146,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (146,10)-(146,25))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayNode (location: (146,13)-(146,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (146,16)-(146,19))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (146,16)-(146,19) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (146,13)-(146,16) = "%i["
+ │ │ │ └── closing_loc: (146,19)-(146,20) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (146,10)-(146,12) = "in"
+ │ │ └── then_loc: (146,21)-(146,25) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (146,0)-(146,4) = "case"
+ │ └── end_keyword_loc: (146,26)-(146,29) = "end"
+ ├── @ CaseMatchNode (location: (147,0)-(147,29))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (147,5)-(147,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (147,5)-(147,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (147,10)-(147,25))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayNode (location: (147,13)-(147,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (147,16)-(147,19))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (147,16)-(147,19) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (147,13)-(147,16) = "%I["
+ │ │ │ └── closing_loc: (147,19)-(147,20) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (147,10)-(147,12) = "in"
+ │ │ └── then_loc: (147,21)-(147,25) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (147,0)-(147,4) = "case"
+ │ └── end_keyword_loc: (147,26)-(147,29) = "end"
+ ├── @ CaseMatchNode (location: (148,0)-(148,29))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (148,5)-(148,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (148,5)-(148,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (148,10)-(148,25))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayNode (location: (148,13)-(148,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (148,16)-(148,19))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (148,16)-(148,19) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (148,13)-(148,16) = "%w["
+ │ │ │ └── closing_loc: (148,19)-(148,20) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (148,10)-(148,12) = "in"
+ │ │ └── then_loc: (148,21)-(148,25) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (148,0)-(148,4) = "case"
+ │ └── end_keyword_loc: (148,26)-(148,29) = "end"
+ ├── @ CaseMatchNode (location: (149,0)-(149,29))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (149,5)-(149,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (149,5)-(149,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (149,10)-(149,25))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayNode (location: (149,13)-(149,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (149,16)-(149,19))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (149,16)-(149,19) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── opening_loc: (149,13)-(149,16) = "%W["
+ │ │ │ └── closing_loc: (149,19)-(149,20) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (149,10)-(149,12) = "in"
+ │ │ └── then_loc: (149,21)-(149,25) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (149,0)-(149,4) = "case"
+ │ └── end_keyword_loc: (149,26)-(149,29) = "end"
+ ├── @ CaseMatchNode (location: (150,0)-(150,29))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (150,5)-(150,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (150,5)-(150,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (150,10)-(150,25))
+ │ │ ├── pattern:
+ │ │ │ @ StringNode (location: (150,13)-(150,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (150,13)-(150,16) = "%q["
+ │ │ │ ├── content_loc: (150,16)-(150,19) = "foo"
+ │ │ │ ├── closing_loc: (150,19)-(150,20) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (150,10)-(150,12) = "in"
+ │ │ └── then_loc: (150,21)-(150,25) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (150,0)-(150,4) = "case"
+ │ └── end_keyword_loc: (150,26)-(150,29) = "end"
+ ├── @ CaseMatchNode (location: (151,0)-(151,29))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (151,5)-(151,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (151,5)-(151,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (151,10)-(151,25))
+ │ │ ├── pattern:
+ │ │ │ @ StringNode (location: (151,13)-(151,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (151,13)-(151,16) = "%Q["
+ │ │ │ ├── content_loc: (151,16)-(151,19) = "foo"
+ │ │ │ ├── closing_loc: (151,19)-(151,20) = "]"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (151,10)-(151,12) = "in"
+ │ │ └── then_loc: (151,21)-(151,25) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (151,0)-(151,4) = "case"
+ │ └── end_keyword_loc: (151,26)-(151,29) = "end"
+ ├── @ CaseMatchNode (location: (152,0)-(152,27))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (152,5)-(152,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (152,5)-(152,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (152,10)-(152,23))
+ │ │ ├── pattern:
+ │ │ │ @ StringNode (location: (152,13)-(152,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (152,13)-(152,14) = "\""
+ │ │ │ ├── content_loc: (152,14)-(152,17) = "foo"
+ │ │ │ ├── closing_loc: (152,17)-(152,18) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (152,10)-(152,12) = "in"
+ │ │ └── then_loc: (152,19)-(152,23) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (152,0)-(152,4) = "case"
+ │ └── end_keyword_loc: (152,24)-(152,27) = "end"
+ ├── @ CaseMatchNode (location: (153,0)-(153,25))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (153,5)-(153,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (153,5)-(153,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (153,10)-(153,21))
+ │ │ ├── pattern:
+ │ │ │ @ NilNode (location: (153,13)-(153,16))
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (153,10)-(153,12) = "in"
+ │ │ └── then_loc: (153,17)-(153,21) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (153,0)-(153,4) = "case"
+ │ └── end_keyword_loc: (153,22)-(153,25) = "end"
+ ├── @ CaseMatchNode (location: (154,0)-(154,26))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (154,5)-(154,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (154,5)-(154,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (154,10)-(154,22))
+ │ │ ├── pattern:
+ │ │ │ @ SelfNode (location: (154,13)-(154,17))
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (154,10)-(154,12) = "in"
+ │ │ └── then_loc: (154,18)-(154,22) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (154,0)-(154,4) = "case"
+ │ └── end_keyword_loc: (154,23)-(154,26) = "end"
+ ├── @ CaseMatchNode (location: (155,0)-(155,26))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (155,5)-(155,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (155,5)-(155,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (155,10)-(155,22))
+ │ │ ├── pattern:
+ │ │ │ @ TrueNode (location: (155,13)-(155,17))
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (155,10)-(155,12) = "in"
+ │ │ └── then_loc: (155,18)-(155,22) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (155,0)-(155,4) = "case"
+ │ └── end_keyword_loc: (155,23)-(155,26) = "end"
+ ├── @ CaseMatchNode (location: (156,0)-(156,27))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (156,5)-(156,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (156,5)-(156,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (156,10)-(156,23))
+ │ │ ├── pattern:
+ │ │ │ @ FalseNode (location: (156,13)-(156,18))
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (156,10)-(156,12) = "in"
+ │ │ └── then_loc: (156,19)-(156,23) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (156,0)-(156,4) = "case"
+ │ └── end_keyword_loc: (156,24)-(156,27) = "end"
+ ├── @ CaseMatchNode (location: (157,0)-(157,30))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (157,5)-(157,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (157,5)-(157,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (157,10)-(157,26))
+ │ │ ├── pattern:
+ │ │ │ @ SourceFileNode (location: (157,13)-(157,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── filepath: "patterns.txt"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (157,10)-(157,12) = "in"
+ │ │ └── then_loc: (157,22)-(157,26) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (157,0)-(157,4) = "case"
+ │ └── end_keyword_loc: (157,27)-(157,30) = "end"
+ ├── @ CaseMatchNode (location: (158,0)-(158,30))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (158,5)-(158,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (158,5)-(158,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (158,10)-(158,26))
+ │ │ ├── pattern:
+ │ │ │ @ SourceLineNode (location: (158,13)-(158,21))
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (158,10)-(158,12) = "in"
+ │ │ └── then_loc: (158,22)-(158,26) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (158,0)-(158,4) = "case"
+ │ └── end_keyword_loc: (158,27)-(158,30) = "end"
+ ├── @ CaseMatchNode (location: (159,0)-(159,34))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (159,5)-(159,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (159,5)-(159,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (159,10)-(159,30))
+ │ │ ├── pattern:
+ │ │ │ @ SourceEncodingNode (location: (159,13)-(159,25))
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (159,10)-(159,12) = "in"
+ │ │ └── then_loc: (159,26)-(159,30) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (159,0)-(159,4) = "case"
+ │ └── end_keyword_loc: (159,31)-(159,34) = "end"
+ ├── @ CaseMatchNode (location: (160,0)-(160,32))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (160,5)-(160,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (160,5)-(160,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (160,10)-(160,28))
+ │ │ ├── pattern:
+ │ │ │ @ LambdaNode (location: (160,13)-(160,23))
+ │ │ │ ├── locals: []
+ │ │ │ ├── operator_loc: (160,13)-(160,15) = "->"
+ │ │ │ ├── opening_loc: (160,16)-(160,17) = "{"
+ │ │ │ ├── closing_loc: (160,22)-(160,23) = "}"
+ │ │ │ ├── parameters: ∅
+ │ │ │ └── body:
+ │ │ │ @ StatementsNode (location: (160,18)-(160,21))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (160,18)-(160,21))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 1
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (160,10)-(160,12) = "in"
+ │ │ └── then_loc: (160,24)-(160,28) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (160,0)-(160,4) = "case"
+ │ └── end_keyword_loc: (160,29)-(160,32) = "end"
+ ├── @ CaseMatchNode (location: (162,0)-(162,32))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (162,5)-(162,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (162,5)-(162,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (162,10)-(162,28))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (162,13)-(162,23))
+ │ │ │ ├── if_keyword_loc: (162,17)-(162,19) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (162,20)-(162,23))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (162,13)-(162,16))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableTargetNode (location: (162,13)-(162,16))
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (162,10)-(162,12) = "in"
+ │ │ └── then_loc: (162,24)-(162,28) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (162,0)-(162,4) = "case"
+ │ └── end_keyword_loc: (162,29)-(162,32) = "end"
+ ├── @ CaseMatchNode (location: (163,0)-(163,30))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (163,5)-(163,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (163,5)-(163,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (163,10)-(163,26))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (163,13)-(163,21))
+ │ │ │ ├── if_keyword_loc: (163,15)-(163,17) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (163,18)-(163,21))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (163,13)-(163,14))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (163,13)-(163,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (163,10)-(163,12) = "in"
+ │ │ └── then_loc: (163,22)-(163,26) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (163,0)-(163,4) = "case"
+ │ └── end_keyword_loc: (163,27)-(163,30) = "end"
+ ├── @ CaseMatchNode (location: (164,0)-(164,32))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (164,5)-(164,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (164,5)-(164,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (164,10)-(164,28))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (164,13)-(164,23))
+ │ │ │ ├── if_keyword_loc: (164,17)-(164,19) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (164,20)-(164,23))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (164,13)-(164,16))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ FloatNode (location: (164,13)-(164,16))
+ │ │ │ │ └── value: 1.0
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (164,10)-(164,12) = "in"
+ │ │ └── then_loc: (164,24)-(164,28) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (164,0)-(164,4) = "case"
+ │ └── end_keyword_loc: (164,29)-(164,32) = "end"
+ ├── @ CaseMatchNode (location: (165,0)-(165,31))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (165,5)-(165,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (165,5)-(165,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (165,10)-(165,27))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (165,13)-(165,22))
+ │ │ │ ├── if_keyword_loc: (165,16)-(165,18) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (165,19)-(165,22))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (165,13)-(165,15))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ ImaginaryNode (location: (165,13)-(165,15))
+ │ │ │ │ └── numeric:
+ │ │ │ │ @ IntegerNode (location: (165,13)-(165,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (165,10)-(165,12) = "in"
+ │ │ └── then_loc: (165,23)-(165,27) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (165,0)-(165,4) = "case"
+ │ └── end_keyword_loc: (165,28)-(165,31) = "end"
+ ├── @ CaseMatchNode (location: (166,0)-(166,31))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (166,5)-(166,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (166,5)-(166,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (166,10)-(166,27))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (166,13)-(166,22))
+ │ │ │ ├── if_keyword_loc: (166,16)-(166,18) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (166,19)-(166,22))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ 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
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (166,10)-(166,12) = "in"
+ │ │ └── then_loc: (166,23)-(166,27) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (166,0)-(166,4) = "case"
+ │ └── end_keyword_loc: (166,28)-(166,31) = "end"
+ ├── @ CaseMatchNode (location: (167,0)-(167,33))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (167,5)-(167,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (167,5)-(167,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (167,10)-(167,29))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (167,13)-(167,24))
+ │ │ │ ├── if_keyword_loc: (167,18)-(167,20) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (167,21)-(167,24))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (167,13)-(167,17))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (167,13)-(167,17))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (167,13)-(167,14) = ":"
+ │ │ │ │ ├── value_loc: (167,14)-(167,17) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (167,10)-(167,12) = "in"
+ │ │ └── then_loc: (167,25)-(167,29) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (167,0)-(167,4) = "case"
+ │ └── end_keyword_loc: (167,30)-(167,33) = "end"
+ ├── @ CaseMatchNode (location: (168,0)-(168,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (168,5)-(168,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (168,5)-(168,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (168,10)-(168,32))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (168,13)-(168,27))
+ │ │ │ ├── if_keyword_loc: (168,21)-(168,23) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (168,24)-(168,27))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (168,13)-(168,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (168,13)-(168,20))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (168,13)-(168,16) = "%s["
+ │ │ │ │ ├── value_loc: (168,16)-(168,19) = "foo"
+ │ │ │ │ ├── closing_loc: (168,19)-(168,20) = "]"
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (168,10)-(168,12) = "in"
+ │ │ └── then_loc: (168,28)-(168,32) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (168,0)-(168,4) = "case"
+ │ └── end_keyword_loc: (168,33)-(168,36) = "end"
+ ├── @ CaseMatchNode (location: (169,0)-(169,35))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (169,5)-(169,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (169,5)-(169,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (169,10)-(169,31))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (169,13)-(169,26))
+ │ │ │ ├── if_keyword_loc: (169,20)-(169,22) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (169,23)-(169,26))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (169,13)-(169,19))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (169,13)-(169,19))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (169,13)-(169,15) = ":\""
+ │ │ │ │ ├── value_loc: (169,15)-(169,18) = "foo"
+ │ │ │ │ ├── closing_loc: (169,18)-(169,19) = "\""
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (169,10)-(169,12) = "in"
+ │ │ └── then_loc: (169,27)-(169,31) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (169,0)-(169,4) = "case"
+ │ └── end_keyword_loc: (169,32)-(169,35) = "end"
+ ├── @ CaseMatchNode (location: (170,0)-(170,34))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (170,5)-(170,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (170,5)-(170,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (170,10)-(170,30))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (170,13)-(170,25))
+ │ │ │ ├── if_keyword_loc: (170,19)-(170,21) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (170,22)-(170,25))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (170,13)-(170,18))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ RegularExpressionNode (location: (170,13)-(170,18))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (170,13)-(170,14) = "/"
+ │ │ │ │ ├── content_loc: (170,14)-(170,17) = "foo"
+ │ │ │ │ ├── closing_loc: (170,17)-(170,18) = "/"
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (170,10)-(170,12) = "in"
+ │ │ └── then_loc: (170,26)-(170,30) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (170,0)-(170,4) = "case"
+ │ └── end_keyword_loc: (170,31)-(170,34) = "end"
+ ├── @ CaseMatchNode (location: (171,0)-(171,34))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (171,5)-(171,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (171,5)-(171,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (171,10)-(171,30))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (171,13)-(171,25))
+ │ │ │ ├── if_keyword_loc: (171,19)-(171,21) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (171,22)-(171,25))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (171,13)-(171,18))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ XStringNode (location: (171,13)-(171,18))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (171,13)-(171,14) = "`"
+ │ │ │ │ ├── content_loc: (171,14)-(171,17) = "foo"
+ │ │ │ │ ├── closing_loc: (171,17)-(171,18) = "`"
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (171,10)-(171,12) = "in"
+ │ │ └── then_loc: (171,26)-(171,30) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (171,0)-(171,4) = "case"
+ │ └── end_keyword_loc: (171,31)-(171,34) = "end"
+ ├── @ CaseMatchNode (location: (172,0)-(172,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (172,5)-(172,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (172,5)-(172,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (172,10)-(172,32))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (172,13)-(172,27))
+ │ │ │ ├── if_keyword_loc: (172,21)-(172,23) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (172,24)-(172,27))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (172,13)-(172,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ XStringNode (location: (172,13)-(172,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (172,13)-(172,16) = "%x["
+ │ │ │ │ ├── content_loc: (172,16)-(172,19) = "foo"
+ │ │ │ │ ├── closing_loc: (172,19)-(172,20) = "]"
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (172,10)-(172,12) = "in"
+ │ │ └── then_loc: (172,28)-(172,32) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (172,0)-(172,4) = "case"
+ │ └── end_keyword_loc: (172,33)-(172,36) = "end"
+ ├── @ CaseMatchNode (location: (173,0)-(173,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (173,5)-(173,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (173,5)-(173,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (173,10)-(173,32))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (173,13)-(173,27))
+ │ │ │ ├── if_keyword_loc: (173,21)-(173,23) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (173,24)-(173,27))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (173,13)-(173,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ ArrayNode (location: (173,13)-(173,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ │ └── @ SymbolNode (location: (173,16)-(173,19))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (173,16)-(173,19) = "foo"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "foo"
+ │ │ │ │ ├── opening_loc: (173,13)-(173,16) = "%i["
+ │ │ │ │ └── closing_loc: (173,19)-(173,20) = "]"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (173,10)-(173,12) = "in"
+ │ │ └── then_loc: (173,28)-(173,32) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (173,0)-(173,4) = "case"
+ │ └── end_keyword_loc: (173,33)-(173,36) = "end"
+ ├── @ CaseMatchNode (location: (174,0)-(174,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (174,5)-(174,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (174,5)-(174,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (174,10)-(174,32))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (174,13)-(174,27))
+ │ │ │ ├── if_keyword_loc: (174,21)-(174,23) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (174,24)-(174,27))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (174,13)-(174,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ ArrayNode (location: (174,13)-(174,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ │ └── @ SymbolNode (location: (174,16)-(174,19))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (174,16)-(174,19) = "foo"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "foo"
+ │ │ │ │ ├── opening_loc: (174,13)-(174,16) = "%I["
+ │ │ │ │ └── closing_loc: (174,19)-(174,20) = "]"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (174,10)-(174,12) = "in"
+ │ │ └── then_loc: (174,28)-(174,32) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (174,0)-(174,4) = "case"
+ │ └── end_keyword_loc: (174,33)-(174,36) = "end"
+ ├── @ CaseMatchNode (location: (175,0)-(175,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (175,5)-(175,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (175,5)-(175,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (175,10)-(175,32))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (175,13)-(175,27))
+ │ │ │ ├── if_keyword_loc: (175,21)-(175,23) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (175,24)-(175,27))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (175,13)-(175,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ ArrayNode (location: (175,13)-(175,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ │ └── @ StringNode (location: (175,16)-(175,19))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (175,16)-(175,19) = "foo"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "foo"
+ │ │ │ │ ├── opening_loc: (175,13)-(175,16) = "%w["
+ │ │ │ │ └── closing_loc: (175,19)-(175,20) = "]"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (175,10)-(175,12) = "in"
+ │ │ └── then_loc: (175,28)-(175,32) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (175,0)-(175,4) = "case"
+ │ └── end_keyword_loc: (175,33)-(175,36) = "end"
+ ├── @ CaseMatchNode (location: (176,0)-(176,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (176,5)-(176,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (176,5)-(176,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (176,10)-(176,32))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (176,13)-(176,27))
+ │ │ │ ├── if_keyword_loc: (176,21)-(176,23) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (176,24)-(176,27))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (176,13)-(176,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ ArrayNode (location: (176,13)-(176,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ │ └── @ StringNode (location: (176,16)-(176,19))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (176,16)-(176,19) = "foo"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "foo"
+ │ │ │ │ ├── opening_loc: (176,13)-(176,16) = "%W["
+ │ │ │ │ └── closing_loc: (176,19)-(176,20) = "]"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (176,10)-(176,12) = "in"
+ │ │ └── then_loc: (176,28)-(176,32) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (176,0)-(176,4) = "case"
+ │ └── end_keyword_loc: (176,33)-(176,36) = "end"
+ ├── @ CaseMatchNode (location: (177,0)-(177,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (177,5)-(177,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (177,5)-(177,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (177,10)-(177,32))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (177,13)-(177,27))
+ │ │ │ ├── if_keyword_loc: (177,21)-(177,23) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (177,24)-(177,27))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (177,13)-(177,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (177,13)-(177,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (177,13)-(177,16) = "%q["
+ │ │ │ │ ├── content_loc: (177,16)-(177,19) = "foo"
+ │ │ │ │ ├── closing_loc: (177,19)-(177,20) = "]"
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (177,10)-(177,12) = "in"
+ │ │ └── then_loc: (177,28)-(177,32) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (177,0)-(177,4) = "case"
+ │ └── end_keyword_loc: (177,33)-(177,36) = "end"
+ ├── @ CaseMatchNode (location: (178,0)-(178,36))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (178,5)-(178,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (178,5)-(178,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (178,10)-(178,32))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (178,13)-(178,27))
+ │ │ │ ├── if_keyword_loc: (178,21)-(178,23) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (178,24)-(178,27))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (178,13)-(178,20))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (178,13)-(178,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (178,13)-(178,16) = "%Q["
+ │ │ │ │ ├── content_loc: (178,16)-(178,19) = "foo"
+ │ │ │ │ ├── closing_loc: (178,19)-(178,20) = "]"
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (178,10)-(178,12) = "in"
+ │ │ └── then_loc: (178,28)-(178,32) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (178,0)-(178,4) = "case"
+ │ └── end_keyword_loc: (178,33)-(178,36) = "end"
+ ├── @ CaseMatchNode (location: (179,0)-(179,34))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (179,5)-(179,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (179,5)-(179,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (179,10)-(179,30))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (179,13)-(179,25))
+ │ │ │ ├── if_keyword_loc: (179,19)-(179,21) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (179,22)-(179,25))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (179,13)-(179,18))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (179,13)-(179,18))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (179,13)-(179,14) = "\""
+ │ │ │ │ ├── content_loc: (179,14)-(179,17) = "foo"
+ │ │ │ │ ├── closing_loc: (179,17)-(179,18) = "\""
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (179,10)-(179,12) = "in"
+ │ │ └── then_loc: (179,26)-(179,30) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (179,0)-(179,4) = "case"
+ │ └── end_keyword_loc: (179,31)-(179,34) = "end"
+ ├── @ CaseMatchNode (location: (180,0)-(180,32))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (180,5)-(180,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (180,5)-(180,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (180,10)-(180,28))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (180,13)-(180,23))
+ │ │ │ ├── if_keyword_loc: (180,17)-(180,19) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (180,20)-(180,23))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (180,13)-(180,16))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ NilNode (location: (180,13)-(180,16))
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (180,10)-(180,12) = "in"
+ │ │ └── then_loc: (180,24)-(180,28) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (180,0)-(180,4) = "case"
+ │ └── end_keyword_loc: (180,29)-(180,32) = "end"
+ ├── @ CaseMatchNode (location: (181,0)-(181,33))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (181,5)-(181,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (181,5)-(181,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (181,10)-(181,29))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (181,13)-(181,24))
+ │ │ │ ├── if_keyword_loc: (181,18)-(181,20) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (181,21)-(181,24))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (181,13)-(181,17))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ SelfNode (location: (181,13)-(181,17))
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (181,10)-(181,12) = "in"
+ │ │ └── then_loc: (181,25)-(181,29) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (181,0)-(181,4) = "case"
+ │ └── end_keyword_loc: (181,30)-(181,33) = "end"
+ ├── @ CaseMatchNode (location: (182,0)-(182,33))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (182,5)-(182,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (182,5)-(182,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (182,10)-(182,29))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (182,13)-(182,24))
+ │ │ │ ├── if_keyword_loc: (182,18)-(182,20) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (182,21)-(182,24))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (182,13)-(182,17))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (182,13)-(182,17))
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (182,10)-(182,12) = "in"
+ │ │ └── then_loc: (182,25)-(182,29) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (182,0)-(182,4) = "case"
+ │ └── end_keyword_loc: (182,30)-(182,33) = "end"
+ ├── @ CaseMatchNode (location: (183,0)-(183,34))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (183,5)-(183,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (183,5)-(183,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (183,10)-(183,30))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (183,13)-(183,25))
+ │ │ │ ├── if_keyword_loc: (183,19)-(183,21) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (183,22)-(183,25))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (183,13)-(183,18))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ FalseNode (location: (183,13)-(183,18))
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (183,10)-(183,12) = "in"
+ │ │ └── then_loc: (183,26)-(183,30) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (183,0)-(183,4) = "case"
+ │ └── end_keyword_loc: (183,31)-(183,34) = "end"
+ ├── @ CaseMatchNode (location: (184,0)-(184,37))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (184,5)-(184,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (184,5)-(184,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (184,10)-(184,33))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (184,13)-(184,28))
+ │ │ │ ├── if_keyword_loc: (184,22)-(184,24) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (184,25)-(184,28))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (184,13)-(184,21))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ SourceFileNode (location: (184,13)-(184,21))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── filepath: "patterns.txt"
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (184,10)-(184,12) = "in"
+ │ │ └── then_loc: (184,29)-(184,33) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (184,0)-(184,4) = "case"
+ │ └── end_keyword_loc: (184,34)-(184,37) = "end"
+ ├── @ CaseMatchNode (location: (185,0)-(185,37))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (185,5)-(185,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (185,5)-(185,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (185,10)-(185,33))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (185,13)-(185,28))
+ │ │ │ ├── if_keyword_loc: (185,22)-(185,24) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (185,25)-(185,28))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (185,13)-(185,21))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ SourceLineNode (location: (185,13)-(185,21))
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (185,10)-(185,12) = "in"
+ │ │ └── then_loc: (185,29)-(185,33) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (185,0)-(185,4) = "case"
+ │ └── end_keyword_loc: (185,34)-(185,37) = "end"
+ ├── @ CaseMatchNode (location: (186,0)-(186,41))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (186,5)-(186,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (186,5)-(186,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (186,10)-(186,37))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (186,13)-(186,32))
+ │ │ │ ├── if_keyword_loc: (186,26)-(186,28) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (186,29)-(186,32))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (186,13)-(186,25))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ SourceEncodingNode (location: (186,13)-(186,25))
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (186,10)-(186,12) = "in"
+ │ │ └── then_loc: (186,33)-(186,37) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (186,0)-(186,4) = "case"
+ │ └── end_keyword_loc: (186,38)-(186,41) = "end"
+ ├── @ CaseMatchNode (location: (187,0)-(187,39))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (187,5)-(187,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (187,5)-(187,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (187,10)-(187,35))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (187,13)-(187,30))
+ │ │ │ ├── if_keyword_loc: (187,24)-(187,26) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (187,27)-(187,30))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (187,13)-(187,23))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LambdaNode (location: (187,13)-(187,23))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── operator_loc: (187,13)-(187,15) = "->"
+ │ │ │ │ ├── opening_loc: (187,16)-(187,17) = "{"
+ │ │ │ │ ├── closing_loc: (187,22)-(187,23) = "}"
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ └── body:
+ │ │ │ │ @ StatementsNode (location: (187,18)-(187,21))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (187,18)-(187,21))
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── depth: 1
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (187,10)-(187,12) = "in"
+ │ │ └── then_loc: (187,31)-(187,35) = "then"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (187,0)-(187,4) = "case"
+ │ └── end_keyword_loc: (187,36)-(187,39) = "end"
+ ├── @ IfNode (location: (189,0)-(190,3))
+ │ ├── if_keyword_loc: (189,0)-(189,2) = "if"
+ │ ├── predicate:
+ │ │ @ MatchPredicateNode (location: (189,3)-(189,10))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (189,3)-(189,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (189,3)-(189,4) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (189,8)-(189,10))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (189,8)-(189,9) = "["
+ │ │ │ └── closing_loc: (189,9)-(189,10) = "]"
+ │ │ └── operator_loc: (189,5)-(189,7) = "in"
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (190,0)-(190,3) = "end"
+ ├── @ MatchRequiredNode (location: (192,0)-(194,1))
+ │ ├── value:
+ │ │ @ CallNode (location: (192,0)-(192,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (192,0)-(192,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (192,5)-(194,1))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (193,2)-(193,3))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (192,5)-(192,6) = "["
+ │ │ └── closing_loc: (194,0)-(194,1) = "]"
+ │ └── operator_loc: (192,2)-(192,4) = "=>"
+ ├── @ MatchPredicateNode (location: (196,0)-(200,1))
+ │ ├── value:
+ │ │ @ CallNode (location: (196,0)-(196,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (196,0)-(196,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (196,7)-(200,1))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (196,7)-(196,8))
+ │ │ │ └── name: :A
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (197,2)-(199,3))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (197,2)-(197,6))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (197,2)-(197,5) = "bar"
+ │ │ │ │ ├── closing_loc: (197,5)-(197,6) = ":"
+ │ │ │ │ └── unescaped: "bar"
+ │ │ │ ├── value:
+ │ │ │ │ @ HashPatternNode (location: (197,7)-(199,3))
+ │ │ │ │ ├── constant:
+ │ │ │ │ │ @ ConstantReadNode (location: (197,7)-(197,8))
+ │ │ │ │ │ └── name: :B
+ │ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ │ └── @ AssocNode (location: (198,4)-(198,12))
+ │ │ │ │ │ ├── key:
+ │ │ │ │ │ │ @ SymbolNode (location: (198,4)-(198,10))
+ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── value_loc: (198,4)-(198,9) = "value"
+ │ │ │ │ │ │ ├── closing_loc: (198,9)-(198,10) = ":"
+ │ │ │ │ │ │ └── unescaped: "value"
+ │ │ │ │ │ ├── value:
+ │ │ │ │ │ │ @ LocalVariableTargetNode (location: (198,11)-(198,12))
+ │ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ └── operator_loc: ∅
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── opening_loc: (197,8)-(197,9) = "["
+ │ │ │ │ └── closing_loc: (199,2)-(199,3) = "]"
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: (196,8)-(196,9) = "["
+ │ │ └── closing_loc: (200,0)-(200,1) = "]"
+ │ └── operator_loc: (196,4)-(196,6) = "in"
+ ├── @ MatchPredicateNode (location: (202,0)-(202,17))
+ │ ├── value:
+ │ │ @ CallNode (location: (202,0)-(202,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (202,0)-(202,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ CapturePatternNode (location: (202,7)-(202,17))
+ │ │ ├── value:
+ │ │ │ @ LocalVariableTargetNode (location: (202,7)-(202,10))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── target:
+ │ │ │ @ LocalVariableTargetNode (location: (202,14)-(202,17))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ └── operator_loc: (202,11)-(202,13) = "=>"
+ │ └── operator_loc: (202,4)-(202,6) = "in"
+ ├── @ MatchRequiredNode (location: (203,0)-(203,17))
+ │ ├── value:
+ │ │ @ CallNode (location: (203,0)-(203,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (203,0)-(203,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ CapturePatternNode (location: (203,7)-(203,17))
+ │ │ ├── value:
+ │ │ │ @ LocalVariableTargetNode (location: (203,7)-(203,10))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── target:
+ │ │ │ @ LocalVariableTargetNode (location: (203,14)-(203,17))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ └── operator_loc: (203,11)-(203,13) = "=>"
+ │ └── operator_loc: (203,4)-(203,6) = "=>"
+ ├── @ MultiWriteNode (location: (205,0)-(205,20))
+ │ ├── lefts: (length: 3)
+ │ │ ├── @ LocalVariableTargetNode (location: (205,0)-(205,3))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ ├── @ LocalVariableTargetNode (location: (205,5)-(205,8))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (205,10)-(205,13))
+ │ │ ├── name: :baz
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (205,14)-(205,15) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (205,16)-(205,20))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (205,16)-(205,17))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (205,19)-(205,20))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ CallNode (location: (206,0)-(208,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (206,0)-(206,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (206,4)-(208,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (207,2)-(207,29))
+ │ │ └── body: (length: 1)
+ │ │ └── @ MatchRequiredNode (location: (207,2)-(207,29))
+ │ │ ├── value:
+ │ │ │ @ ArrayNode (location: (207,2)-(207,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ ├── @ IntegerNode (location: (207,3)-(207,4))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── @ IntegerNode (location: (207,6)-(207,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── opening_loc: (207,2)-(207,3) = "["
+ │ │ │ └── closing_loc: (207,7)-(207,8) = "]"
+ │ │ ├── pattern:
+ │ │ │ @ CapturePatternNode (location: (207,12)-(207,29))
+ │ │ │ ├── value:
+ │ │ │ │ @ ArrayPatternNode (location: (207,12)-(207,22))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ │ ├── @ LocalVariableTargetNode (location: (207,13)-(207,16))
+ │ │ │ │ │ │ ├── name: :foo
+ │ │ │ │ │ │ └── depth: 1
+ │ │ │ │ │ └── @ LocalVariableTargetNode (location: (207,18)-(207,21))
+ │ │ │ │ │ ├── name: :bar
+ │ │ │ │ │ └── depth: 1
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── opening_loc: (207,12)-(207,13) = "["
+ │ │ │ │ └── closing_loc: (207,21)-(207,22) = "]"
+ │ │ │ ├── target:
+ │ │ │ │ @ LocalVariableTargetNode (location: (207,26)-(207,29))
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ └── depth: 1
+ │ │ │ └── operator_loc: (207,23)-(207,25) = "=>"
+ │ │ └── operator_loc: (207,9)-(207,11) = "=>"
+ │ ├── opening_loc: (206,4)-(206,6) = "do"
+ │ └── closing_loc: (208,0)-(208,3) = "end"
+ ├── @ MatchRequiredNode (location: (210,0)-(210,19))
+ │ ├── value:
+ │ │ @ LocalVariableReadNode (location: (210,0)-(210,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (210,7)-(210,19))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (210,7)-(210,13))
+ │ │ │ └── name: :Object
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ HashPatternNode (location: (210,14)-(210,18))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ AssocNode (location: (210,15)-(210,17))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (210,15)-(210,17))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (210,15)-(210,16) = "x"
+ │ │ │ │ │ ├── closing_loc: (210,16)-(210,17) = ":"
+ │ │ │ │ │ └── unescaped: "x"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ ImplicitNode (location: (210,15)-(210,16))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ LocalVariableTargetNode (location: (210,15)-(210,16))
+ │ │ │ │ │ ├── name: :x
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── opening_loc: (210,14)-(210,15) = "{"
+ │ │ │ └── closing_loc: (210,17)-(210,18) = "}"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (210,13)-(210,14) = "["
+ │ │ └── closing_loc: (210,18)-(210,19) = "]"
+ │ └── operator_loc: (210,4)-(210,6) = "=>"
+ ├── @ CallNode (location: (212,0)-(212,19))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (212,0)-(212,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: (212,1)-(212,2) = "."
+ │ ├── name: :then
+ │ ├── message_loc: (212,2)-(212,6) = "then"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (212,7)-(212,19))
+ │ ├── locals: [:_1]
+ │ ├── parameters:
+ │ │ @ NumberedParametersNode (location: (212,7)-(212,19))
+ │ │ └── maximum: 1
+ │ ├── body:
+ │ │ @ StatementsNode (location: (212,9)-(212,17))
+ │ │ └── body: (length: 1)
+ │ │ └── @ MatchPredicateNode (location: (212,9)-(212,17))
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (212,9)-(212,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── pattern:
+ │ │ │ @ PinnedVariableNode (location: (212,14)-(212,17))
+ │ │ │ ├── variable:
+ │ │ │ │ @ LocalVariableReadNode (location: (212,15)-(212,17))
+ │ │ │ │ ├── name: :_1
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: (212,14)-(212,15) = "^"
+ │ │ └── operator_loc: (212,11)-(212,13) = "in"
+ │ ├── opening_loc: (212,7)-(212,8) = "{"
+ │ └── closing_loc: (212,18)-(212,19) = "}"
+ └── @ MultiWriteNode (location: (214,0)-(217,5))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (215,2)-(215,3))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (216,2)-(216,3))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: (214,0)-(214,1) = "("
+ ├── rparen_loc: (217,0)-(217,1) = ")"
+ ├── operator_loc: (217,2)-(217,3) = "="
+ └── value:
+ @ CallNode (location: (217,4)-(217,5))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (217,4)-(217,5) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/procs.txt b/test/prism/snapshots/procs.txt
new file mode 100644
index 0000000000..1329ae6a5f
--- /dev/null
+++ b/test/prism/snapshots/procs.txt
@@ -0,0 +1,403 @@
+@ ProgramNode (location: (1,0)-(27,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(27,19))
+ └── body: (length: 10)
+ ├── @ LambdaNode (location: (1,0)-(1,21))
+ │ ├── locals: [:a, :b, :c, :d]
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (1,16)-(1,17) = "{"
+ │ ├── closing_loc: (1,20)-(1,21) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,3)-(1,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,4)-(1,5))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,4)-(1,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 3)
+ │ │ │ ├── @ BlockLocalVariableNode (location: (1,7)-(1,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── @ BlockLocalVariableNode (location: (1,10)-(1,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ └── @ BlockLocalVariableNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ │ └── closing_loc: (1,14)-(1,15) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (1,18)-(1,19))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (1,18)-(1,19))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── @ LambdaNode (location: (3,0)-(5,3))
+ │ ├── locals: []
+ │ ├── operator_loc: (3,0)-(3,2) = "->"
+ │ ├── opening_loc: (3,3)-(3,5) = "do"
+ │ ├── closing_loc: (5,0)-(5,3) = "end"
+ │ ├── parameters: ∅
+ │ └── body:
+ │ @ BeginNode (location: (3,3)-(5,3))
+ │ ├── begin_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (4,0)-(5,3))
+ │ │ ├── ensure_keyword_loc: (4,0)-(4,6) = "ensure"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ LambdaNode (location: (7,0)-(11,3))
+ │ ├── locals: []
+ │ ├── operator_loc: (7,0)-(7,2) = "->"
+ │ ├── opening_loc: (7,3)-(7,5) = "do"
+ │ ├── closing_loc: (11,0)-(11,3) = "end"
+ │ ├── parameters: ∅
+ │ └── body:
+ │ @ BeginNode (location: (7,3)-(11,3))
+ │ ├── begin_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (8,0)-(8,6))
+ │ │ ├── keyword_loc: (8,0)-(8,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause:
+ │ │ @ ElseNode (location: (9,0)-(10,6))
+ │ │ ├── else_keyword_loc: (9,0)-(9,4) = "else"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (10,0)-(10,6) = "ensure"
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (10,0)-(11,3))
+ │ │ ├── ensure_keyword_loc: (10,0)-(10,6) = "ensure"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ LambdaNode (location: (13,0)-(13,10))
+ │ ├── locals: []
+ │ ├── operator_loc: (13,0)-(13,2) = "->"
+ │ ├── opening_loc: (13,3)-(13,4) = "{"
+ │ ├── closing_loc: (13,9)-(13,10) = "}"
+ │ ├── parameters: ∅
+ │ └── body:
+ │ @ StatementsNode (location: (13,5)-(13,8))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (13,5)-(13,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (13,5)-(13,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ LambdaNode (location: (15,0)-(15,15))
+ │ ├── locals: []
+ │ ├── operator_loc: (15,0)-(15,2) = "->"
+ │ ├── opening_loc: (15,3)-(15,5) = "do"
+ │ ├── closing_loc: (15,12)-(15,15) = "end"
+ │ ├── parameters: ∅
+ │ └── body:
+ │ @ StatementsNode (location: (15,7)-(15,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (15,7)-(15,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (15,7)-(15,10) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ LambdaNode (location: (17,0)-(17,29))
+ │ ├── locals: [:a, :b, :c, :d, :e]
+ │ ├── operator_loc: (17,0)-(17,2) = "->"
+ │ ├── opening_loc: (17,24)-(17,25) = "{"
+ │ ├── closing_loc: (17,28)-(17,29) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (17,3)-(17,23))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (17,3)-(17,23))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (17,3)-(17,4))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (17,6)-(17,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (17,6)-(17,7) = "b"
+ │ │ │ │ ├── operator_loc: (17,8)-(17,9) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (17,10)-(17,11))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 2)
+ │ │ │ │ ├── @ RequiredKeywordParameterNode (location: (17,13)-(17,15))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── name: :c
+ │ │ │ │ │ └── name_loc: (17,13)-(17,15) = "c:"
+ │ │ │ │ └── @ RequiredKeywordParameterNode (location: (17,17)-(17,19))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :d
+ │ │ │ │ └── name_loc: (17,17)-(17,19) = "d:"
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (17,21)-(17,23))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :e
+ │ │ │ ├── name_loc: (17,22)-(17,23) = "e"
+ │ │ │ └── operator_loc: (17,21)-(17,22) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── body:
+ │ @ StatementsNode (location: (17,26)-(17,27))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (17,26)-(17,27))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ LambdaNode (location: (19,0)-(19,40))
+ │ ├── locals: [:a, :b, :c, :d, :e, :f, :g]
+ │ ├── operator_loc: (19,0)-(19,2) = "->"
+ │ ├── opening_loc: (19,35)-(19,36) = "{"
+ │ ├── closing_loc: (19,39)-(19,40) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (19,3)-(19,34))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (19,4)-(19,33))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (19,4)-(19,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (19,7)-(19,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (19,7)-(19,8) = "b"
+ │ │ │ │ ├── operator_loc: (19,9)-(19,10) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (19,11)-(19,12))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (19,14)-(19,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── name_loc: (19,15)-(19,16) = "c"
+ │ │ │ │ └── operator_loc: (19,14)-(19,15) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 2)
+ │ │ │ │ ├── @ RequiredKeywordParameterNode (location: (19,18)-(19,20))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ └── name_loc: (19,18)-(19,20) = "d:"
+ │ │ │ │ └── @ RequiredKeywordParameterNode (location: (19,22)-(19,24))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :e
+ │ │ │ │ └── name_loc: (19,22)-(19,24) = "e:"
+ │ │ │ ├── keyword_rest:
+ │ │ │ │ @ KeywordRestParameterNode (location: (19,26)-(19,29))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :f
+ │ │ │ │ ├── name_loc: (19,28)-(19,29) = "f"
+ │ │ │ │ └── operator_loc: (19,26)-(19,28) = "**"
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (19,31)-(19,33))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :g
+ │ │ │ ├── name_loc: (19,32)-(19,33) = "g"
+ │ │ │ └── operator_loc: (19,31)-(19,32) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (19,3)-(19,4) = "("
+ │ │ └── closing_loc: (19,33)-(19,34) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (19,37)-(19,38))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (19,37)-(19,38))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ LambdaNode (location: (21,0)-(23,3))
+ │ ├── locals: [:a, :b, :c, :d, :e, :f, :g]
+ │ ├── operator_loc: (21,0)-(21,2) = "->"
+ │ ├── opening_loc: (21,35)-(21,37) = "do"
+ │ ├── closing_loc: (23,0)-(23,3) = "end"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (21,3)-(21,34))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (21,4)-(21,33))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (21,4)-(21,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (21,7)-(21,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (21,7)-(21,8) = "b"
+ │ │ │ │ ├── operator_loc: (21,9)-(21,10) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (21,11)-(21,12))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (21,14)-(21,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── name_loc: (21,15)-(21,16) = "c"
+ │ │ │ │ └── operator_loc: (21,14)-(21,15) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 2)
+ │ │ │ │ ├── @ RequiredKeywordParameterNode (location: (21,18)-(21,20))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ └── name_loc: (21,18)-(21,20) = "d:"
+ │ │ │ │ └── @ RequiredKeywordParameterNode (location: (21,22)-(21,24))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :e
+ │ │ │ │ └── name_loc: (21,22)-(21,24) = "e:"
+ │ │ │ ├── keyword_rest:
+ │ │ │ │ @ KeywordRestParameterNode (location: (21,26)-(21,29))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :f
+ │ │ │ │ ├── name_loc: (21,28)-(21,29) = "f"
+ │ │ │ │ └── operator_loc: (21,26)-(21,28) = "**"
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (21,31)-(21,33))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :g
+ │ │ │ ├── name_loc: (21,32)-(21,33) = "g"
+ │ │ │ └── operator_loc: (21,31)-(21,32) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (21,3)-(21,4) = "("
+ │ │ └── closing_loc: (21,33)-(21,34) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (22,2)-(22,3))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (22,2)-(22,3))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ LambdaNode (location: (25,0)-(25,25))
+ │ ├── locals: [:a]
+ │ ├── operator_loc: (25,0)-(25,2) = "->"
+ │ ├── opening_loc: (25,7)-(25,8) = "{"
+ │ ├── closing_loc: (25,24)-(25,25) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (25,3)-(25,6))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (25,4)-(25,5))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (25,4)-(25,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (25,3)-(25,4) = "("
+ │ │ └── closing_loc: (25,5)-(25,6) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (25,9)-(25,23))
+ │ └── body: (length: 1)
+ │ └── @ LambdaNode (location: (25,9)-(25,23))
+ │ ├── locals: [:b]
+ │ ├── operator_loc: (25,9)-(25,11) = "->"
+ │ ├── opening_loc: (25,14)-(25,15) = "{"
+ │ ├── closing_loc: (25,22)-(25,23) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (25,12)-(25,13))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (25,12)-(25,13))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (25,12)-(25,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── body:
+ │ @ StatementsNode (location: (25,16)-(25,21))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (25,16)-(25,21))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (25,16)-(25,17))
+ │ │ ├── name: :a
+ │ │ └── depth: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :*
+ │ ├── message_loc: (25,18)-(25,19) = "*"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (25,20)-(25,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (25,20)-(25,21))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ LambdaNode (location: (27,0)-(27,19))
+ ├── locals: [:a, :b, :c]
+ ├── operator_loc: (27,0)-(27,2) = "->"
+ ├── opening_loc: (27,16)-(27,17) = "{"
+ ├── closing_loc: (27,18)-(27,19) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (27,3)-(27,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (27,4)-(27,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (27,4)-(27,10))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (27,5)-(27,6))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (27,8)-(27,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (27,4)-(27,5) = "("
+ │ │ │ └── rparen_loc: (27,9)-(27,10) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (27,12)-(27,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (27,13)-(27,14) = "c"
+ │ │ │ └── operator_loc: (27,12)-(27,13) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (27,3)-(27,4) = "("
+ │ └── closing_loc: (27,14)-(27,15) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/range_begin_open_exclusive.txt b/test/prism/snapshots/range_begin_open_exclusive.txt
new file mode 100644
index 0000000000..a630b01ef1
--- /dev/null
+++ b/test/prism/snapshots/range_begin_open_exclusive.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ RangeNode (location: (1,0)-(1,4))
+ ├── flags: exclude_end
+ ├── left: ∅
+ ├── right:
+ │ @ IntegerNode (location: (1,3)-(1,4))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── operator_loc: (1,0)-(1,3) = "..."
diff --git a/test/prism/snapshots/range_begin_open_inclusive.txt b/test/prism/snapshots/range_begin_open_inclusive.txt
new file mode 100644
index 0000000000..dc8ef0d2db
--- /dev/null
+++ b/test/prism/snapshots/range_begin_open_inclusive.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ RangeNode (location: (1,0)-(1,3))
+ ├── flags: ∅
+ ├── left: ∅
+ ├── right:
+ │ @ IntegerNode (location: (1,2)-(1,3))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── operator_loc: (1,0)-(1,2) = ".."
diff --git a/test/prism/snapshots/range_end_open_exclusive.txt b/test/prism/snapshots/range_end_open_exclusive.txt
new file mode 100644
index 0000000000..17a75f8945
--- /dev/null
+++ b/test/prism/snapshots/range_end_open_exclusive.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ RangeNode (location: (1,0)-(1,4))
+ ├── flags: exclude_end
+ ├── left:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── right: ∅
+ └── operator_loc: (1,1)-(1,4) = "..."
diff --git a/test/prism/snapshots/range_end_open_inclusive.txt b/test/prism/snapshots/range_end_open_inclusive.txt
new file mode 100644
index 0000000000..b49272d8cd
--- /dev/null
+++ b/test/prism/snapshots/range_end_open_inclusive.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ RangeNode (location: (1,0)-(1,3))
+ ├── flags: ∅
+ ├── left:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── right: ∅
+ └── operator_loc: (1,1)-(1,3) = ".."
diff --git a/test/prism/snapshots/ranges.txt b/test/prism/snapshots/ranges.txt
new file mode 100644
index 0000000000..2fffe80537
--- /dev/null
+++ b/test/prism/snapshots/ranges.txt
@@ -0,0 +1,533 @@
+@ ProgramNode (location: (1,0)-(49,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(49,7))
+ └── body: (length: 25)
+ ├── @ ParenthesesNode (location: (1,0)-(1,6))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,1)-(1,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RangeNode (location: (1,1)-(1,5))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left: ∅
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (1,1)-(1,4) = "..."
+ │ ├── opening_loc: (1,0)-(1,1) = "("
+ │ └── closing_loc: (1,5)-(1,6) = ")"
+ ├── @ ParenthesesNode (location: (3,0)-(3,5))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,1)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RangeNode (location: (3,1)-(3,4))
+ │ │ ├── flags: ∅
+ │ │ ├── left: ∅
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (3,3)-(3,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (3,1)-(3,3) = ".."
+ │ ├── opening_loc: (3,0)-(3,1) = "("
+ │ └── closing_loc: (3,4)-(3,5) = ")"
+ ├── @ RangeNode (location: (5,0)-(5,5))
+ │ ├── flags: exclude_end
+ │ ├── left:
+ │ │ @ IntegerNode (location: (5,0)-(5,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ IntegerNode (location: (5,4)-(5,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (5,1)-(5,4) = "..."
+ ├── @ CallNode (location: (7,0)-(7,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (7,0)-(7,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (7,3)-(7,9) = "[...2]"
+ │ ├── opening_loc: (7,3)-(7,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,4)-(7,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ RangeNode (location: (7,4)-(7,8))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left: ∅
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (7,7)-(7,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (7,4)-(7,7) = "..."
+ │ ├── closing_loc: (7,8)-(7,9) = "]"
+ │ └── block: ∅
+ ├── @ HashNode (location: (9,0)-(9,15))
+ │ ├── opening_loc: (9,0)-(9,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (9,2)-(9,13))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (9,2)-(9,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (9,2)-(9,5) = "foo"
+ │ │ │ ├── closing_loc: (9,5)-(9,6) = ":"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ RangeNode (location: (9,7)-(9,13))
+ │ │ │ ├── flags: exclude_end
+ │ │ │ ├── left: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ CallNode (location: (9,10)-(9,13))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (9,10)-(9,13) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (9,7)-(9,10) = "..."
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (9,14)-(9,15) = "}"
+ ├── @ ParenthesesNode (location: (11,0)-(11,6))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (11,1)-(11,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RangeNode (location: (11,1)-(11,5))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (11,1)-(11,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (11,2)-(11,5) = "..."
+ │ ├── opening_loc: (11,0)-(11,1) = "("
+ │ └── closing_loc: (11,5)-(11,6) = ")"
+ ├── @ RangeNode (location: (13,0)-(13,4))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (13,0)-(13,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ IntegerNode (location: (13,3)-(13,4))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (13,1)-(13,3) = ".."
+ ├── @ HashNode (location: (15,0)-(15,14))
+ │ ├── opening_loc: (15,0)-(15,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (15,2)-(15,12))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (15,2)-(15,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (15,2)-(15,5) = "foo"
+ │ │ │ ├── closing_loc: (15,5)-(15,6) = ":"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ RangeNode (location: (15,7)-(15,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── left: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ CallNode (location: (15,9)-(15,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (15,9)-(15,12) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (15,7)-(15,9) = ".."
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (15,13)-(15,14) = "}"
+ ├── @ ParenthesesNode (location: (17,0)-(17,5))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (17,1)-(17,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RangeNode (location: (17,1)-(17,4))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (17,1)-(17,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (17,2)-(17,4) = ".."
+ │ ├── opening_loc: (17,0)-(17,1) = "("
+ │ └── closing_loc: (17,4)-(17,5) = ")"
+ ├── @ RangeNode (location: (19,0)-(19,8))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (19,0)-(19,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ RangeNode (location: (19,5)-(19,8))
+ │ │ ├── flags: ∅
+ │ │ ├── left: ∅
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (19,7)-(19,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (19,5)-(19,7) = ".."
+ │ └── operator_loc: (19,2)-(19,4) = ".."
+ ├── @ AndNode (location: (21,0)-(21,8))
+ │ ├── left:
+ │ │ @ RangeNode (location: (21,0)-(21,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (21,0)-(21,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (21,1)-(21,3) = ".."
+ │ ├── right:
+ │ │ @ IntegerNode (location: (21,7)-(21,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (21,4)-(21,6) = "&&"
+ ├── @ CallNode (location: (23,0)-(23,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (23,0)-(23,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (23,0)-(23,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (23,1)-(23,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :==
+ │ ├── message_loc: (23,4)-(23,6) = "=="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (23,7)-(23,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (23,7)-(23,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (25,0)-(25,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (25,0)-(25,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (25,0)-(25,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (25,1)-(25,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!=
+ │ ├── message_loc: (25,4)-(25,6) = "!="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (25,7)-(25,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (25,7)-(25,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (27,0)-(27,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (27,0)-(27,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (27,0)-(27,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (27,1)-(27,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :===
+ │ ├── message_loc: (27,4)-(27,7) = "==="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,8)-(27,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (27,8)-(27,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (29,0)-(29,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (29,0)-(29,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (29,0)-(29,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (29,1)-(29,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<=>
+ │ ├── message_loc: (29,4)-(29,7) = "<=>"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (29,8)-(29,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (29,8)-(29,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (31,0)-(31,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (31,0)-(31,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (31,0)-(31,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (31,1)-(31,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (31,4)-(31,6) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,7)-(31,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (31,7)-(31,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (33,0)-(33,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (33,0)-(33,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (33,0)-(33,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (33,1)-(33,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!~
+ │ ├── message_loc: (33,4)-(33,6) = "!~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (33,7)-(33,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (33,7)-(33,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (35,0)-(35,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (35,0)-(35,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (35,0)-(35,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (35,1)-(35,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<
+ │ ├── message_loc: (35,4)-(35,5) = "<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,6)-(35,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (35,6)-(35,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (37,0)-(37,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (37,0)-(37,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (37,0)-(37,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (37,1)-(37,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>
+ │ ├── message_loc: (37,4)-(37,5) = ">"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (37,6)-(37,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (37,6)-(37,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (39,0)-(39,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (39,0)-(39,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (39,0)-(39,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (39,1)-(39,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<=
+ │ ├── message_loc: (39,4)-(39,6) = "<="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (39,7)-(39,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (39,7)-(39,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (41,0)-(41,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (41,0)-(41,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (41,0)-(41,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (41,1)-(41,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>=
+ │ ├── message_loc: (41,4)-(41,6) = ">="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (41,7)-(41,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (41,7)-(41,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (43,0)-(43,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (43,0)-(43,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (43,0)-(43,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (43,1)-(43,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<<
+ │ ├── message_loc: (43,4)-(43,6) = "<<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (43,7)-(43,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (43,7)-(43,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (45,0)-(45,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RangeNode (location: (45,0)-(45,3))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (45,0)-(45,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (45,1)-(45,3) = ".."
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>>
+ │ ├── message_loc: (45,4)-(45,6) = ">>"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (45,7)-(45,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (45,7)-(45,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ RangeNode (location: (47,0)-(47,7))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (47,0)-(47,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ CallNode (location: (47,4)-(47,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (47,6)-(47,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :+@
+ │ │ ├── message_loc: (47,4)-(47,5) = "+"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (47,1)-(47,3) = ".."
+ └── @ RangeNode (location: (49,0)-(49,7))
+ ├── flags: ∅
+ ├── left:
+ │ @ IntegerNode (location: (49,0)-(49,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── right:
+ │ @ CallNode (location: (49,4)-(49,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (49,6)-(49,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :-@
+ │ ├── message_loc: (49,4)-(49,5) = "-"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (49,1)-(49,3) = ".."
diff --git a/test/prism/snapshots/regex.txt b/test/prism/snapshots/regex.txt
new file mode 100644
index 0000000000..d4d153e8d5
--- /dev/null
+++ b/test/prism/snapshots/regex.txt
@@ -0,0 +1,510 @@
+@ ProgramNode (location: (1,0)-(46,32))
+├── locals: [:foo, :ab, :abc, :a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(46,32))
+ └── body: (length: 25)
+ ├── @ CallNode (location: (1,0)-(1,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ RegularExpressionNode (location: (1,4)-(1,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,4)-(1,5) = "/"
+ │ │ ├── content_loc: (1,5)-(1,8) = "bar"
+ │ │ ├── closing_loc: (1,8)-(1,9) = "/"
+ │ │ └── unescaped: "bar"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ RegularExpressionNode (location: (3,0)-(3,8))
+ │ ├── flags: ignore_case, forced_us_ascii_encoding
+ │ ├── opening_loc: (3,0)-(3,3) = "%r{"
+ │ ├── content_loc: (3,3)-(3,6) = "abc"
+ │ ├── closing_loc: (3,6)-(3,8) = "}i"
+ │ └── unescaped: "abc"
+ ├── @ RegularExpressionNode (location: (5,0)-(5,5))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (5,0)-(5,1) = "/"
+ │ ├── content_loc: (5,1)-(5,4) = "a\\b"
+ │ ├── closing_loc: (5,4)-(5,5) = "/"
+ │ └── unescaped: "a\\b"
+ ├── @ InterpolatedRegularExpressionNode (location: (7,0)-(7,11))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(7,1) = "/"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (7,1)-(7,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (7,1)-(7,5) = "aaa "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "aaa "
+ │ │ └── @ EmbeddedVariableNode (location: (7,5)-(7,10))
+ │ │ ├── operator_loc: (7,5)-(7,6) = "#"
+ │ │ └── variable:
+ │ │ @ GlobalVariableReadNode (location: (7,6)-(7,10))
+ │ │ └── name: :$bbb
+ │ └── closing_loc: (7,10)-(7,11) = "/"
+ ├── @ InterpolatedRegularExpressionNode (location: (9,0)-(9,16))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (9,0)-(9,1) = "/"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (9,1)-(9,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (9,1)-(9,5) = "aaa "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "aaa "
+ │ │ ├── @ EmbeddedStatementsNode (location: (9,5)-(9,11))
+ │ │ │ ├── opening_loc: (9,5)-(9,7) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (9,7)-(9,10))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (9,7)-(9,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bbb
+ │ │ │ │ ├── message_loc: (9,7)-(9,10) = "bbb"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (9,10)-(9,11) = "}"
+ │ │ └── @ StringNode (location: (9,11)-(9,15))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (9,11)-(9,15) = " ccc"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " ccc"
+ │ └── closing_loc: (9,15)-(9,16) = "/"
+ ├── @ ArrayNode (location: (11,0)-(11,27))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ MatchWriteNode (location: (11,1)-(11,21))
+ │ │ │ ├── call:
+ │ │ │ │ @ CallNode (location: (11,1)-(11,21))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ RegularExpressionNode (location: (11,1)-(11,14))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (11,1)-(11,2) = "/"
+ │ │ │ │ │ ├── content_loc: (11,2)-(11,13) = "(?<foo>bar)"
+ │ │ │ │ │ ├── closing_loc: (11,13)-(11,14) = "/"
+ │ │ │ │ │ └── unescaped: "(?<foo>bar)"
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :=~
+ │ │ │ │ ├── message_loc: (11,15)-(11,17) = "=~"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (11,18)-(11,21))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (11,18)-(11,21))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :baz
+ │ │ │ │ │ ├── message_loc: (11,18)-(11,21) = "baz"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── targets: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (11,5)-(11,8))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableReadNode (location: (11,23)-(11,26))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── opening_loc: (11,0)-(11,1) = "["
+ │ └── closing_loc: (11,26)-(11,27) = "]"
+ ├── @ RegularExpressionNode (location: (13,0)-(13,6))
+ │ ├── flags: ignore_case, forced_us_ascii_encoding
+ │ ├── opening_loc: (13,0)-(13,1) = "/"
+ │ ├── content_loc: (13,1)-(13,4) = "abc"
+ │ ├── closing_loc: (13,4)-(13,6) = "/i"
+ │ └── unescaped: "abc"
+ ├── @ RegularExpressionNode (location: (15,0)-(15,26))
+ │ ├── flags: ignore_case, forced_us_ascii_encoding
+ │ ├── opening_loc: (15,0)-(15,3) = "%r/"
+ │ ├── content_loc: (15,3)-(15,24) = "[a-z$._?][\\w$.?\#@~]*:"
+ │ ├── closing_loc: (15,24)-(15,26) = "/i"
+ │ └── unescaped: "[a-z$._?][\\w$.?\#@~]*:"
+ ├── @ RegularExpressionNode (location: (17,0)-(17,37))
+ │ ├── flags: ignore_case, forced_us_ascii_encoding
+ │ ├── opening_loc: (17,0)-(17,3) = "%r/"
+ │ ├── content_loc: (17,3)-(17,35) = "([a-z$._?][\\w$.?\#@~]*)(\\s+)(equ)"
+ │ ├── closing_loc: (17,35)-(17,37) = "/i"
+ │ └── unescaped: "([a-z$._?][\\w$.?\#@~]*)(\\s+)(equ)"
+ ├── @ RegularExpressionNode (location: (19,0)-(19,25))
+ │ ├── flags: ignore_case, forced_us_ascii_encoding
+ │ ├── opening_loc: (19,0)-(19,3) = "%r/"
+ │ ├── content_loc: (19,3)-(19,23) = "[a-z$._?][\\w$.?\#@~]*"
+ │ ├── closing_loc: (19,23)-(19,25) = "/i"
+ │ └── unescaped: "[a-z$._?][\\w$.?\#@~]*"
+ ├── @ RegularExpressionNode (location: (21,0)-(24,1))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (21,0)-(21,3) = "%r("
+ │ ├── content_loc: (21,3)-(24,0) = "\n(?:[\#$%_']|\\(\\)|\\(,\\)|\\[\\]|[0-9])*\n (?:[\#$%_']+)\n"
+ │ ├── closing_loc: (24,0)-(24,1) = ")"
+ │ └── unescaped: "\n(?:[\#$%_']|\\(\\)|\\(,\\)|\\[\\]|[0-9])*\n (?:[\#$%_']+)\n"
+ ├── @ CallNode (location: (26,0)-(26,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RegularExpressionNode (location: (26,0)-(26,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (26,0)-(26,1) = "/"
+ │ │ ├── content_loc: (26,1)-(26,7) = "(?#\\))"
+ │ │ ├── closing_loc: (26,7)-(26,8) = "/"
+ │ │ └── unescaped: "(?#\\))"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (26,9)-(26,11) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (26,12)-(26,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (26,12)-(26,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (26,12)-(26,13) = "\""
+ │ │ ├── content_loc: (26,13)-(26,15) = "hi"
+ │ │ ├── closing_loc: (26,15)-(26,16) = "\""
+ │ │ └── unescaped: "hi"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ RegularExpressionNode (location: (28,0)-(28,9))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (28,0)-(28,3) = "%r#"
+ │ ├── content_loc: (28,3)-(28,8) = "pound"
+ │ ├── closing_loc: (28,8)-(28,9) = "#"
+ │ └── unescaped: "pound"
+ ├── @ InterpolatedRegularExpressionNode (location: (30,0)-(30,13))
+ │ ├── flags: once
+ │ ├── opening_loc: (30,0)-(30,1) = "/"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (30,1)-(30,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (30,1)-(30,5) = "aaa "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "aaa "
+ │ │ └── @ EmbeddedStatementsNode (location: (30,5)-(30,11))
+ │ │ ├── opening_loc: (30,5)-(30,7) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (30,7)-(30,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (30,7)-(30,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bbb
+ │ │ │ ├── message_loc: (30,7)-(30,10) = "bbb"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (30,10)-(30,11) = "}"
+ │ └── closing_loc: (30,11)-(30,13) = "/o"
+ ├── @ MatchWriteNode (location: (32,0)-(33,10))
+ │ ├── call:
+ │ │ @ CallNode (location: (32,0)-(33,10))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ RegularExpressionNode (location: (32,0)-(33,4))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (32,0)-(32,1) = "/"
+ │ │ │ ├── content_loc: (32,1)-(33,3) = "(?<a\\\nb>)"
+ │ │ │ ├── closing_loc: (33,3)-(33,4) = "/"
+ │ │ │ └── unescaped: "(?<ab>)"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (33,5)-(33,7) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (33,8)-(33,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (33,8)-(33,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (33,8)-(33,9) = "\""
+ │ │ │ ├── content_loc: (33,9)-(33,9) = ""
+ │ │ │ ├── closing_loc: (33,9)-(33,10) = "\""
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── targets: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (32,0)-(33,4))
+ │ ├── name: :ab
+ │ └── depth: 0
+ ├── @ LocalVariableReadNode (location: (33,12)-(33,14))
+ │ ├── name: :ab
+ │ └── depth: 0
+ ├── @ MatchWriteNode (location: (35,0)-(35,24))
+ │ ├── call:
+ │ │ @ CallNode (location: (35,0)-(35,24))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ RegularExpressionNode (location: (35,0)-(35,18))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (35,0)-(35,1) = "/"
+ │ │ │ ├── content_loc: (35,1)-(35,17) = "(?<abc>)(?<abc>)"
+ │ │ │ ├── closing_loc: (35,17)-(35,18) = "/"
+ │ │ │ └── unescaped: "(?<abc>)(?<abc>)"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (35,19)-(35,21) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (35,22)-(35,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (35,22)-(35,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (35,22)-(35,23) = "\""
+ │ │ │ ├── content_loc: (35,23)-(35,23) = ""
+ │ │ │ ├── closing_loc: (35,23)-(35,24) = "\""
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── targets: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (35,4)-(35,7))
+ │ ├── name: :abc
+ │ └── depth: 0
+ ├── @ LocalVariableReadNode (location: (35,26)-(35,29))
+ │ ├── name: :abc
+ │ └── depth: 0
+ ├── @ CallNode (location: (37,0)-(37,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RegularExpressionNode (location: (37,0)-(37,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (37,0)-(37,1) = "/"
+ │ │ ├── content_loc: (37,1)-(37,9) = "(?<a b>)"
+ │ │ ├── closing_loc: (37,9)-(37,10) = "/"
+ │ │ └── unescaped: "(?<a b>)"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (37,11)-(37,13) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (37,14)-(37,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (37,14)-(37,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (37,14)-(37,15) = "\""
+ │ │ ├── content_loc: (37,15)-(37,15) = ""
+ │ │ ├── closing_loc: (37,15)-(37,16) = "\""
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ LocalVariableWriteNode (location: (39,0)-(39,5))
+ │ ├── name: :a
+ │ ├── depth: 0
+ │ ├── name_loc: (39,0)-(39,1) = "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (39,4)-(39,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (39,2)-(39,3) = "="
+ ├── @ CallNode (location: (40,0)-(40,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (40,0)-(40,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (40,4)-(40,24))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (40,6)-(40,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ MatchWriteNode (location: (40,6)-(40,22))
+ │ │ ├── call:
+ │ │ │ @ CallNode (location: (40,6)-(40,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ RegularExpressionNode (location: (40,6)-(40,14))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (40,6)-(40,7) = "/"
+ │ │ │ │ ├── content_loc: (40,7)-(40,13) = "(?<a>)"
+ │ │ │ │ ├── closing_loc: (40,13)-(40,14) = "/"
+ │ │ │ │ └── unescaped: "(?<a>)"
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :=~
+ │ │ │ ├── message_loc: (40,15)-(40,17) = "=~"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (40,18)-(40,22))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (40,18)-(40,22))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :to_s
+ │ │ │ │ ├── message_loc: (40,18)-(40,22) = "to_s"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── targets: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (40,10)-(40,11))
+ │ │ ├── name: :a
+ │ │ └── depth: 1
+ │ ├── opening_loc: (40,4)-(40,5) = "{"
+ │ └── closing_loc: (40,23)-(40,24) = "}"
+ ├── @ MatchWriteNode (location: (42,0)-(42,16))
+ │ ├── call:
+ │ │ @ CallNode (location: (42,0)-(42,16))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ RegularExpressionNode (location: (42,0)-(42,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (42,0)-(42,1) = "/"
+ │ │ │ ├── content_loc: (42,1)-(42,9) = "(?<foo>)"
+ │ │ │ ├── closing_loc: (42,9)-(42,10) = "/"
+ │ │ │ └── unescaped: "(?<foo>)"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (42,11)-(42,13) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (42,14)-(42,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (42,14)-(42,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (42,14)-(42,15) = "\""
+ │ │ │ ├── content_loc: (42,15)-(42,15) = ""
+ │ │ │ ├── closing_loc: (42,15)-(42,16) = "\""
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── targets: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (42,4)-(42,7))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── @ CallNode (location: (43,0)-(43,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RegularExpressionNode (location: (43,0)-(43,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (43,0)-(43,1) = "/"
+ │ │ ├── content_loc: (43,1)-(43,9) = "(?<Foo>)"
+ │ │ ├── closing_loc: (43,9)-(43,10) = "/"
+ │ │ └── unescaped: "(?<Foo>)"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (43,11)-(43,13) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (43,14)-(43,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (43,14)-(43,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (43,14)-(43,15) = "\""
+ │ │ ├── content_loc: (43,15)-(43,15) = ""
+ │ │ ├── closing_loc: (43,15)-(43,16) = "\""
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (45,0)-(45,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RegularExpressionNode (location: (45,0)-(45,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (45,0)-(45,1) = "/"
+ │ │ ├── content_loc: (45,1)-(45,9) = "(?<nil>)"
+ │ │ ├── closing_loc: (45,9)-(45,10) = "/"
+ │ │ └── unescaped: "(?<nil>)"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (45,11)-(45,13) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (45,14)-(45,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (45,14)-(45,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (45,14)-(45,15) = "\""
+ │ │ ├── content_loc: (45,15)-(45,15) = ""
+ │ │ ├── closing_loc: (45,15)-(45,16) = "\""
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ DefNode (location: (46,0)-(46,32))
+ ├── name: :foo
+ ├── name_loc: (46,4)-(46,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (46,8)-(46,12))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ RequiredKeywordParameterNode (location: (46,8)-(46,12))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :nil
+ │ │ └── name_loc: (46,8)-(46,12) = "nil:"
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (46,16)-(46,32))
+ │ └── body: (length: 1)
+ │ └── @ MatchWriteNode (location: (46,16)-(46,32))
+ │ ├── call:
+ │ │ @ CallNode (location: (46,16)-(46,32))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ RegularExpressionNode (location: (46,16)-(46,26))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (46,16)-(46,17) = "/"
+ │ │ │ ├── content_loc: (46,17)-(46,25) = "(?<nil>)"
+ │ │ │ ├── closing_loc: (46,25)-(46,26) = "/"
+ │ │ │ └── unescaped: "(?<nil>)"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (46,27)-(46,29) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (46,30)-(46,32))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (46,30)-(46,32))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (46,30)-(46,31) = "\""
+ │ │ │ ├── content_loc: (46,31)-(46,31) = ""
+ │ │ │ ├── closing_loc: (46,31)-(46,32) = "\""
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── targets: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (46,20)-(46,23))
+ │ ├── name: :nil
+ │ └── depth: 0
+ ├── locals: [:nil]
+ ├── def_keyword_loc: (46,0)-(46,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (46,7)-(46,8) = "("
+ ├── rparen_loc: (46,12)-(46,13) = ")"
+ ├── equal_loc: (46,14)-(46,15) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/regex_char_width.txt b/test/prism/snapshots/regex_char_width.txt
new file mode 100644
index 0000000000..6bf2169b2f
--- /dev/null
+++ b/test/prism/snapshots/regex_char_width.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (2,0)-(3,6))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (2,0)-(3,6))
+ └── body: (length: 2)
+ ├── @ MatchWriteNode (location: (2,0)-(2,36))
+ │ ├── call:
+ │ │ @ CallNode (location: (2,0)-(2,36))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ RegularExpressionNode (location: (2,0)-(2,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (2,0)-(2,1) = "/"
+ │ │ │ ├── content_loc: (2,1)-(2,21) = "\x{E285}\xA7(?<a>.)\x{E285}\xA9(?<b>.)"
+ │ │ │ ├── closing_loc: (2,21)-(2,22) = "/"
+ │ │ │ └── unescaped: "\x{E285}\xA7(?<a>.)\x{E285}\xA9(?<b>.)"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (2,23)-(2,25) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (2,26)-(2,36))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (2,26)-(2,36))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (2,26)-(2,27) = "'"
+ │ │ │ ├── content_loc: (2,27)-(2,35) = "\x{E285}\xA7a\x{E285}\xA9b"
+ │ │ │ ├── closing_loc: (2,35)-(2,36) = "'"
+ │ │ │ └── unescaped: "\x{E285}\xA7a\x{E285}\xA9b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── targets: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (2,7)-(2,8))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (2,17)-(2,18))
+ │ ├── name: :b
+ │ └── depth: 0
+ └── @ ArrayNode (location: (3,0)-(3,6))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ LocalVariableReadNode (location: (3,1)-(3,2))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ LocalVariableReadNode (location: (3,4)-(3,5))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── opening_loc: (3,0)-(3,1) = "["
+ └── closing_loc: (3,5)-(3,6) = "]"
diff --git a/test/prism/snapshots/repeat_parameters.txt b/test/prism/snapshots/repeat_parameters.txt
new file mode 100644
index 0000000000..fd98294ce6
--- /dev/null
+++ b/test/prism/snapshots/repeat_parameters.txt
@@ -0,0 +1,473 @@
+@ ProgramNode (location: (1,0)-(38,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(38,3))
+ └── body: (length: 13)
+ ├── @ DefNode (location: (1,0)-(2,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,8)-(1,12))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,8)-(1,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :_
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :_]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ ├── rparen_loc: (1,12)-(1,13) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (2,0)-(2,3) = "end"
+ ├── @ DefNode (location: (4,0)-(5,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (4,4)-(4,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (4,8)-(4,15))
+ │ │ ├── requireds: (length: 3)
+ │ │ │ ├── @ RequiredParameterNode (location: (4,8)-(4,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── @ RequiredParameterNode (location: (4,11)-(4,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :_
+ │ │ │ └── @ RequiredParameterNode (location: (4,14)-(4,15))
+ │ │ │ ├── flags: repeated_parameter
+ │ │ │ └── name: :_
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :_]
+ │ ├── def_keyword_loc: (4,0)-(4,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (4,7)-(4,8) = "("
+ │ ├── rparen_loc: (4,15)-(4,16) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ DefNode (location: (7,0)-(8,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (7,4)-(7,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (7,8)-(7,19))
+ │ │ ├── requireds: (length: 4)
+ │ │ │ ├── @ RequiredParameterNode (location: (7,8)-(7,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── @ RequiredParameterNode (location: (7,11)-(7,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :_
+ │ │ │ ├── @ RequiredParameterNode (location: (7,14)-(7,15))
+ │ │ │ │ ├── flags: repeated_parameter
+ │ │ │ │ └── name: :_
+ │ │ │ └── @ RequiredParameterNode (location: (7,17)-(7,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :_b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :_, :_b]
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (7,7)-(7,8) = "("
+ │ ├── rparen_loc: (7,19)-(7,20) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (8,0)-(8,3) = "end"
+ ├── @ DefNode (location: (10,0)-(11,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (10,4)-(10,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (10,8)-(10,23))
+ │ │ ├── requireds: (length: 5)
+ │ │ │ ├── @ RequiredParameterNode (location: (10,8)-(10,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── @ RequiredParameterNode (location: (10,11)-(10,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :_
+ │ │ │ ├── @ RequiredParameterNode (location: (10,14)-(10,15))
+ │ │ │ │ ├── flags: repeated_parameter
+ │ │ │ │ └── name: :_
+ │ │ │ ├── @ RequiredParameterNode (location: (10,17)-(10,19))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :_b
+ │ │ │ └── @ RequiredParameterNode (location: (10,21)-(10,23))
+ │ │ │ ├── flags: repeated_parameter
+ │ │ │ └── name: :_b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :_, :_b]
+ │ ├── def_keyword_loc: (10,0)-(10,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (10,7)-(10,8) = "("
+ │ ├── rparen_loc: (10,23)-(10,24) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ DefNode (location: (13,0)-(14,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (13,4)-(13,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (13,8)-(13,35))
+ │ │ ├── requireds: (length: 3)
+ │ │ │ ├── @ RequiredParameterNode (location: (13,8)-(13,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── @ MultiTargetNode (location: (13,11)-(13,22))
+ │ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (13,12)-(13,13))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :b
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ SplatNode (location: (13,15)-(13,18))
+ │ │ │ │ │ ├── operator_loc: (13,15)-(13,16) = "*"
+ │ │ │ │ │ └── expression:
+ │ │ │ │ │ @ RequiredParameterNode (location: (13,16)-(13,18))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :_c
+ │ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (13,20)-(13,21))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :d
+ │ │ │ │ ├── lparen_loc: (13,11)-(13,12) = "("
+ │ │ │ │ └── rparen_loc: (13,21)-(13,22) = ")"
+ │ │ │ └── @ MultiTargetNode (location: (13,24)-(13,35))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (13,25)-(13,26))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :e
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (13,28)-(13,31))
+ │ │ │ │ ├── operator_loc: (13,28)-(13,29) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (13,29)-(13,31))
+ │ │ │ │ ├── flags: repeated_parameter
+ │ │ │ │ └── name: :_c
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (13,33)-(13,34))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :f
+ │ │ │ ├── lparen_loc: (13,24)-(13,25) = "("
+ │ │ │ └── rparen_loc: (13,34)-(13,35) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :b, :_c, :d, :e, :f]
+ │ ├── def_keyword_loc: (13,0)-(13,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (13,7)-(13,8) = "("
+ │ ├── rparen_loc: (13,35)-(13,36) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (14,0)-(14,3) = "end"
+ ├── @ DefNode (location: (16,0)-(17,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (16,4)-(16,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (16,8)-(16,20))
+ │ │ ├── requireds: (length: 4)
+ │ │ │ ├── @ RequiredParameterNode (location: (16,8)-(16,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :_a
+ │ │ │ ├── @ RequiredParameterNode (location: (16,12)-(16,14))
+ │ │ │ │ ├── flags: repeated_parameter
+ │ │ │ │ └── name: :_a
+ │ │ │ ├── @ RequiredParameterNode (location: (16,16)-(16,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ └── @ RequiredParameterNode (location: (16,19)-(16,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:_a, :b, :c]
+ │ ├── def_keyword_loc: (16,0)-(16,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (16,7)-(16,8) = "("
+ │ ├── rparen_loc: (16,20)-(16,21) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (17,0)-(17,3) = "end"
+ ├── @ DefNode (location: (19,0)-(20,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (19,4)-(19,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (19,8)-(19,32))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ MultiTargetNode (location: (19,8)-(19,19))
+ │ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (19,9)-(19,10))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ SplatNode (location: (19,12)-(19,15))
+ │ │ │ │ │ ├── operator_loc: (19,12)-(19,13) = "*"
+ │ │ │ │ │ └── expression:
+ │ │ │ │ │ @ RequiredParameterNode (location: (19,13)-(19,15))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :_b
+ │ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (19,17)-(19,18))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :c
+ │ │ │ │ ├── lparen_loc: (19,8)-(19,9) = "("
+ │ │ │ │ └── rparen_loc: (19,18)-(19,19) = ")"
+ │ │ │ └── @ MultiTargetNode (location: (19,21)-(19,32))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (19,22)-(19,23))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :d
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (19,25)-(19,28))
+ │ │ │ │ ├── operator_loc: (19,25)-(19,26) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (19,26)-(19,28))
+ │ │ │ │ ├── flags: repeated_parameter
+ │ │ │ │ └── name: :_b
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (19,30)-(19,31))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :e
+ │ │ │ ├── lparen_loc: (19,21)-(19,22) = "("
+ │ │ │ └── rparen_loc: (19,31)-(19,32) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :_b, :c, :d, :e]
+ │ ├── def_keyword_loc: (19,0)-(19,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (19,7)-(19,8) = "("
+ │ ├── rparen_loc: (19,32)-(19,33) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (20,0)-(20,3) = "end"
+ ├── @ DefNode (location: (22,0)-(23,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (22,4)-(22,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (22,8)-(22,22))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 2)
+ │ │ │ ├── @ OptionalParameterNode (location: (22,8)-(22,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :_a
+ │ │ │ │ ├── name_loc: (22,8)-(22,10) = "_a"
+ │ │ │ │ ├── operator_loc: (22,11)-(22,12) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (22,13)-(22,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ OptionalParameterNode (location: (22,16)-(22,22))
+ │ │ │ ├── flags: repeated_parameter
+ │ │ │ ├── name: :_a
+ │ │ │ ├── name_loc: (22,16)-(22,18) = "_a"
+ │ │ │ ├── operator_loc: (22,19)-(22,20) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (22,21)-(22,22))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:_a]
+ │ ├── def_keyword_loc: (22,0)-(22,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (22,7)-(22,8) = "("
+ │ ├── rparen_loc: (22,22)-(22,23) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (23,0)-(23,3) = "end"
+ ├── @ DefNode (location: (25,0)-(26,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (25,4)-(25,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (25,8)-(25,16))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ RequiredKeywordParameterNode (location: (25,8)-(25,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :_a
+ │ │ │ │ └── name_loc: (25,8)-(25,11) = "_a:"
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (25,13)-(25,16))
+ │ │ │ ├── flags: repeated_parameter
+ │ │ │ ├── name: :_a
+ │ │ │ └── name_loc: (25,13)-(25,16) = "_a:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:_a]
+ │ ├── def_keyword_loc: (25,0)-(25,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (25,7)-(25,8) = "("
+ │ ├── rparen_loc: (25,16)-(25,17) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (26,0)-(26,3) = "end"
+ ├── @ DefNode (location: (28,0)-(29,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (28,4)-(28,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (28,8)-(28,20))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ OptionalKeywordParameterNode (location: (28,8)-(28,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :_a
+ │ │ │ │ ├── name_loc: (28,8)-(28,11) = "_a:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (28,12)-(28,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (28,15)-(28,20))
+ │ │ │ ├── flags: repeated_parameter
+ │ │ │ ├── name: :_a
+ │ │ │ ├── name_loc: (28,15)-(28,18) = "_a:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (28,19)-(28,20))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:_a]
+ │ ├── def_keyword_loc: (28,0)-(28,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (28,7)-(28,8) = "("
+ │ ├── rparen_loc: (28,20)-(28,21) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (29,0)-(29,3) = "end"
+ ├── @ DefNode (location: (31,0)-(32,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (31,4)-(31,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (31,8)-(31,16))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (31,8)-(31,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :_a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (31,12)-(31,16))
+ │ │ │ ├── flags: repeated_parameter
+ │ │ │ ├── name: :_a
+ │ │ │ ├── name_loc: (31,14)-(31,16) = "_a"
+ │ │ │ └── operator_loc: (31,12)-(31,14) = "**"
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:_a]
+ │ ├── def_keyword_loc: (31,0)-(31,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (31,7)-(31,8) = "("
+ │ ├── rparen_loc: (31,16)-(31,17) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (32,0)-(32,3) = "end"
+ ├── @ DefNode (location: (34,0)-(35,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (34,4)-(34,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (34,8)-(34,15))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (34,8)-(34,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :_a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (34,12)-(34,15))
+ │ │ ├── flags: repeated_parameter
+ │ │ ├── name: :_a
+ │ │ ├── name_loc: (34,13)-(34,15) = "_a"
+ │ │ └── operator_loc: (34,12)-(34,13) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:_a]
+ │ ├── def_keyword_loc: (34,0)-(34,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (34,7)-(34,8) = "("
+ │ ├── rparen_loc: (34,15)-(34,16) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (35,0)-(35,3) = "end"
+ └── @ DefNode (location: (37,0)-(38,3))
+ ├── name: :foo
+ ├── name_loc: (37,4)-(37,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (37,8)-(37,15))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (37,8)-(37,10))
+ │ │ ├── flags: ∅
+ │ │ └── name: :_a
+ │ ├── optionals: (length: 0)
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (37,12)-(37,15))
+ │ │ ├── flags: repeated_parameter
+ │ │ ├── name: :_a
+ │ │ ├── name_loc: (37,13)-(37,15) = "_a"
+ │ │ └── operator_loc: (37,12)-(37,13) = "*"
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:_a]
+ ├── def_keyword_loc: (37,0)-(37,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (37,7)-(37,8) = "("
+ ├── rparen_loc: (37,15)-(37,16) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (38,0)-(38,3) = "end"
diff --git a/test/prism/snapshots/rescue.txt b/test/prism/snapshots/rescue.txt
new file mode 100644
index 0000000000..57cafde5a6
--- /dev/null
+++ b/test/prism/snapshots/rescue.txt
@@ -0,0 +1,527 @@
+@ ProgramNode (location: (1,0)-(35,18))
+├── locals: [:a, :z]
+└── statements:
+ @ StatementsNode (location: (1,0)-(35,18))
+ └── body: (length: 14)
+ ├── @ RescueModifierNode (location: (1,0)-(1,14))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,4)-(1,10) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (1,11)-(1,14))
+ ├── @ RescueModifierNode (location: (3,0)-(4,3))
+ │ ├── expression:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (3,4)-(3,10) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (4,0)-(4,3))
+ ├── @ CallNode (location: (6,0)-(6,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (6,0)-(6,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (6,4)-(6,24))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (6,6)-(6,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (6,6)-(6,22))
+ │ │ ├── expression:
+ │ │ │ @ BreakNode (location: (6,6)-(6,11))
+ │ │ │ ├── arguments: ∅
+ │ │ │ └── keyword_loc: (6,6)-(6,11) = "break"
+ │ │ ├── keyword_loc: (6,12)-(6,18) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (6,19)-(6,22))
+ │ ├── opening_loc: (6,4)-(6,5) = "{"
+ │ └── closing_loc: (6,23)-(6,24) = "}"
+ ├── @ CallNode (location: (8,0)-(8,23))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (8,0)-(8,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (8,4)-(8,23))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (8,6)-(8,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (8,6)-(8,21))
+ │ │ ├── expression:
+ │ │ │ @ NextNode (location: (8,6)-(8,10))
+ │ │ │ ├── arguments: ∅
+ │ │ │ └── keyword_loc: (8,6)-(8,10) = "next"
+ │ │ ├── keyword_loc: (8,11)-(8,17) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (8,18)-(8,21))
+ │ ├── opening_loc: (8,4)-(8,5) = "{"
+ │ └── closing_loc: (8,22)-(8,23) = "}"
+ ├── @ RescueModifierNode (location: (10,0)-(10,17))
+ │ ├── expression:
+ │ │ @ ReturnNode (location: (10,0)-(10,6))
+ │ │ ├── keyword_loc: (10,0)-(10,6) = "return"
+ │ │ └── arguments: ∅
+ │ ├── keyword_loc: (10,7)-(10,13) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (10,14)-(10,17))
+ ├── @ RescueModifierNode (location: (12,0)-(12,19))
+ │ ├── expression:
+ │ │ @ CallNode (location: (12,0)-(12,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (12,0)-(12,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (12,4)-(12,10) = "rescue"
+ │ └── rescue_expression:
+ │ @ OrNode (location: (12,11)-(12,19))
+ │ ├── left:
+ │ │ @ NilNode (location: (12,11)-(12,14))
+ │ ├── right:
+ │ │ @ IntegerNode (location: (12,18)-(12,19))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (12,15)-(12,17) = "||"
+ ├── @ RescueModifierNode (location: (14,0)-(14,22))
+ │ ├── expression:
+ │ │ @ CallNode (location: (14,0)-(14,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (14,0)-(14,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (14,4)-(14,10) = "rescue"
+ │ └── rescue_expression:
+ │ @ IfNode (location: (14,11)-(14,22))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ NilNode (location: (14,11)-(14,14))
+ │ ├── then_keyword_loc: (14,15)-(14,16) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (14,17)-(14,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (14,17)-(14,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (14,19)-(14,22))
+ │ │ ├── else_keyword_loc: (14,19)-(14,20) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (14,21)-(14,22))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (14,21)-(14,22))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ BeginNode (location: (16,0)-(16,24))
+ │ ├── begin_keyword_loc: (16,0)-(16,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (16,7)-(16,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (16,7)-(16,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (16,7)-(16,8) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (16,10)-(16,19))
+ │ │ ├── keyword_loc: (16,10)-(16,16) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ SplatNode (location: (16,17)-(16,19))
+ │ │ │ ├── operator_loc: (16,17)-(16,18) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (16,18)-(16,19))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (16,18)-(16,19) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (16,21)-(16,24) = "end"
+ ├── @ CallNode (location: (18,0)-(20,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (18,0)-(18,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (18,4)-(20,3))
+ │ ├── locals: [:x]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (18,7)-(18,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (18,8)-(18,9))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (18,8)-(18,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :x
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (18,7)-(18,8) = "|"
+ │ │ └── closing_loc: (18,9)-(18,10) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (19,2)-(19,40))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (19,2)-(19,40))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (19,2)-(19,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (19,2)-(19,5) = "bar"
+ │ │ │ ├── opening_loc: (19,5)-(19,6) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (19,6)-(19,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (19,6)-(19,7))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :y
+ │ │ │ │ ├── message_loc: (19,6)-(19,7) = "y"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (19,7)-(19,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (19,9)-(19,15) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ CallNode (location: (19,16)-(19,40))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :ArgumentError
+ │ │ ├── message_loc: (19,16)-(19,29) = "ArgumentError"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (19,30)-(19,40))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (19,30)-(19,40))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :fail
+ │ │ │ ├── message_loc: (19,30)-(19,34) = "fail"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (19,35)-(19,40))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (19,35)-(19,40))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (19,35)-(19,36) = "\""
+ │ │ │ │ ├── content_loc: (19,36)-(19,39) = "baz"
+ │ │ │ │ ├── closing_loc: (19,39)-(19,40) = "\""
+ │ │ │ │ └── unescaped: "baz"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (18,4)-(18,6) = "do"
+ │ └── closing_loc: (20,0)-(20,3) = "end"
+ ├── @ IfNode (location: (22,0)-(24,3))
+ │ ├── if_keyword_loc: (22,0)-(22,2) = "if"
+ │ ├── predicate:
+ │ │ @ LocalVariableWriteNode (location: (22,3)-(22,21))
+ │ │ ├── name: :a
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (22,3)-(22,4) = "a"
+ │ │ ├── value:
+ │ │ │ @ RescueModifierNode (location: (22,7)-(22,21))
+ │ │ │ ├── expression:
+ │ │ │ │ @ CallNode (location: (22,7)-(22,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (22,7)-(22,10) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── keyword_loc: (22,11)-(22,17) = "rescue"
+ │ │ │ └── rescue_expression:
+ │ │ │ @ NilNode (location: (22,18)-(22,21))
+ │ │ └── operator_loc: (22,5)-(22,6) = "="
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (23,2)-(23,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (23,2)-(23,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (23,2)-(23,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (24,0)-(24,3) = "end"
+ ├── @ DefNode (location: (26,0)-(26,44))
+ │ ├── name: :some_method
+ │ ├── name_loc: (26,4)-(26,15) = "some_method"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (26,18)-(26,44))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (26,18)-(26,44))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (26,18)-(26,33))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :other_method
+ │ │ │ ├── message_loc: (26,18)-(26,30) = "other_method"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (26,31)-(26,33))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (26,31)-(26,33))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (26,34)-(26,40) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (26,41)-(26,44))
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (26,0)-(26,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (26,16)-(26,17) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (28,0)-(31,3))
+ │ ├── name: :a
+ │ ├── name_loc: (28,4)-(28,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (28,0)-(31,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (29,2)-(29,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (29,2)-(29,6))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (29,2)-(29,3) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (29,4)-(29,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ KeywordHashNode (location: (29,4)-(29,6))
+ │ │ │ │ ├── flags: symbol_keys
+ │ │ │ │ └── elements: (length: 1)
+ │ │ │ │ └── @ AssocNode (location: (29,4)-(29,6))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (29,4)-(29,6))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (29,4)-(29,5) = "b"
+ │ │ │ │ │ ├── closing_loc: (29,5)-(29,6) = ":"
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ ImplicitNode (location: (29,4)-(29,6))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ CallNode (location: (29,4)-(29,6))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ ├── message_loc: (29,4)-(29,5) = "b"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (30,0)-(30,6))
+ │ │ │ ├── keyword_loc: (30,0)-(30,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (31,0)-(31,3) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (28,0)-(28,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (31,0)-(31,3) = "end"
+ ├── @ RescueModifierNode (location: (33,0)-(33,21))
+ │ ├── expression:
+ │ │ @ IfNode (location: (33,0)-(33,10))
+ │ │ ├── if_keyword_loc: (33,4)-(33,6) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (33,7)-(33,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (33,7)-(33,10) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (33,0)-(33,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (33,0)-(33,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (33,0)-(33,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── keyword_loc: (33,11)-(33,17) = "rescue"
+ │ └── rescue_expression:
+ │ @ CallNode (location: (33,18)-(33,21))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :baz
+ │ ├── message_loc: (33,18)-(33,21) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ LocalVariableWriteNode (location: (35,0)-(35,18))
+ ├── name: :z
+ ├── depth: 0
+ ├── name_loc: (35,0)-(35,1) = "z"
+ ├── value:
+ │ @ RescueModifierNode (location: (35,4)-(35,18))
+ │ ├── expression:
+ │ │ @ CallNode (location: (35,4)-(35,7))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :x
+ │ │ ├── message_loc: (35,4)-(35,5) = "x"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (35,6)-(35,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (35,6)-(35,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :y
+ │ │ │ ├── message_loc: (35,6)-(35,7) = "y"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (35,8)-(35,14) = "rescue"
+ │ └── rescue_expression:
+ │ @ CallNode (location: (35,15)-(35,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :c
+ │ ├── message_loc: (35,15)-(35,16) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,17)-(35,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (35,17)-(35,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (35,17)-(35,18) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (35,2)-(35,3) = "="
diff --git a/test/prism/snapshots/return.txt b/test/prism/snapshots/return.txt
new file mode 100644
index 0000000000..9a33076193
--- /dev/null
+++ b/test/prism/snapshots/return.txt
@@ -0,0 +1,155 @@
+@ ProgramNode (location: (1,0)-(23,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(23,9))
+ └── body: (length: 10)
+ ├── @ ReturnNode (location: (1,0)-(1,6))
+ │ ├── keyword_loc: (1,0)-(1,6) = "return"
+ │ └── arguments: ∅
+ ├── @ ReturnNode (location: (3,0)-(3,20))
+ │ ├── keyword_loc: (3,0)-(3,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (3,7)-(3,20))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 3)
+ │ ├── @ ParenthesesNode (location: (3,7)-(3,10))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (3,8)-(3,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,8)-(3,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (3,7)-(3,8) = "("
+ │ │ └── closing_loc: (3,9)-(3,10) = ")"
+ │ ├── @ ParenthesesNode (location: (3,12)-(3,15))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (3,13)-(3,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,13)-(3,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: (3,12)-(3,13) = "("
+ │ │ └── closing_loc: (3,14)-(3,15) = ")"
+ │ └── @ ParenthesesNode (location: (3,17)-(3,20))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,18)-(3,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (3,18)-(3,19))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── opening_loc: (3,17)-(3,18) = "("
+ │ └── closing_loc: (3,19)-(3,20) = ")"
+ ├── @ ReturnNode (location: (5,0)-(5,9))
+ │ ├── keyword_loc: (5,0)-(5,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (5,7)-(5,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ SplatNode (location: (5,7)-(5,9))
+ │ ├── operator_loc: (5,7)-(5,8) = "*"
+ │ └── expression:
+ │ @ IntegerNode (location: (5,8)-(5,9))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ ReturnNode (location: (7,0)-(7,8))
+ │ ├── keyword_loc: (7,0)-(7,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (7,7)-(7,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (7,7)-(7,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ ReturnNode (location: (9,0)-(10,1))
+ │ ├── keyword_loc: (9,0)-(9,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (9,7)-(10,1))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 3)
+ │ ├── @ IntegerNode (location: (9,7)-(9,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── @ IntegerNode (location: (9,10)-(9,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── @ IntegerNode (location: (10,0)-(10,1))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── @ ReturnNode (location: (12,0)-(12,14))
+ │ ├── keyword_loc: (12,0)-(12,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (12,7)-(12,14))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 3)
+ │ ├── @ IntegerNode (location: (12,7)-(12,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── @ IntegerNode (location: (12,10)-(12,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── @ IntegerNode (location: (12,13)-(12,14))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── @ ReturnNode (location: (14,0)-(14,16))
+ │ ├── keyword_loc: (14,0)-(14,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (14,7)-(14,16))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ArrayNode (location: (14,7)-(14,16))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ IntegerNode (location: (14,8)-(14,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ IntegerNode (location: (14,11)-(14,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── @ IntegerNode (location: (14,14)-(14,15))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── opening_loc: (14,7)-(14,8) = "["
+ │ └── closing_loc: (14,15)-(14,16) = "]"
+ ├── @ ReturnNode (location: (16,0)-(19,1))
+ │ ├── keyword_loc: (16,0)-(16,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (16,6)-(19,1))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (16,6)-(19,1))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (17,2)-(18,3))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ IntegerNode (location: (17,2)-(17,3))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (18,2)-(18,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (16,6)-(16,7) = "("
+ │ └── closing_loc: (19,0)-(19,1) = ")"
+ ├── @ ReturnNode (location: (21,0)-(21,8))
+ │ ├── keyword_loc: (21,0)-(21,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (21,6)-(21,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (21,6)-(21,8))
+ │ ├── body: ∅
+ │ ├── opening_loc: (21,6)-(21,7) = "("
+ │ └── closing_loc: (21,7)-(21,8) = ")"
+ └── @ ReturnNode (location: (23,0)-(23,9))
+ ├── keyword_loc: (23,0)-(23,6) = "return"
+ └── arguments:
+ @ ArgumentsNode (location: (23,6)-(23,9))
+ ├── flags: ∅
+ └── arguments: (length: 1)
+ └── @ ParenthesesNode (location: (23,6)-(23,9))
+ ├── body:
+ │ @ StatementsNode (location: (23,7)-(23,8))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (23,7)-(23,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── opening_loc: (23,6)-(23,7) = "("
+ └── closing_loc: (23,8)-(23,9) = ")"
diff --git a/test/prism/snapshots/seattlerb/BEGIN.txt b/test/prism/snapshots/seattlerb/BEGIN.txt
new file mode 100644
index 0000000000..246f39cbba
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/BEGIN.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ PreExecutionNode (location: (1,0)-(1,12))
+ ├── statements:
+ │ @ StatementsNode (location: (1,8)-(1,10))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,8)-(1,10))
+ │ ├── flags: decimal
+ │ └── value: 42
+ ├── keyword_loc: (1,0)-(1,5) = "BEGIN"
+ ├── opening_loc: (1,6)-(1,7) = "{"
+ └── closing_loc: (1,11)-(1,12) = "}"
diff --git a/test/prism/snapshots/seattlerb/TestRubyParserShared.txt b/test/prism/snapshots/seattlerb/TestRubyParserShared.txt
new file mode 100644
index 0000000000..fabc92e477
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/TestRubyParserShared.txt
@@ -0,0 +1,361 @@
+@ ProgramNode (location: (1,0)-(92,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(92,1))
+ └── body: (length: 16)
+ ├── @ ArrayNode (location: (1,0)-(4,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (1,0)-(1,3) = "%I["
+ │ └── closing_loc: (4,0)-(4,1) = "]"
+ ├── @ ArrayNode (location: (6,0)-(9,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (7,0)-(7,5))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (7,0)-(7,5) = "line2"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "line2"
+ │ │ └── @ SymbolNode (location: (8,0)-(8,5))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (8,0)-(8,5) = "line3"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "line3"
+ │ ├── opening_loc: (6,0)-(6,3) = "%I["
+ │ └── closing_loc: (9,0)-(9,1) = "]"
+ ├── @ ArrayNode (location: (11,0)-(14,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (11,0)-(11,3) = "%W["
+ │ └── closing_loc: (14,0)-(14,1) = "]"
+ ├── @ ArrayNode (location: (16,0)-(19,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (17,0)-(17,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (17,0)-(17,5) = "line2"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "line2"
+ │ │ └── @ StringNode (location: (18,0)-(18,5))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (18,0)-(18,5) = "line3"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "line3"
+ │ ├── opening_loc: (16,0)-(16,3) = "%W["
+ │ └── closing_loc: (19,0)-(19,1) = "]"
+ ├── @ ArrayNode (location: (21,0)-(24,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (21,0)-(21,3) = "%i["
+ │ └── closing_loc: (24,0)-(24,1) = "]"
+ ├── @ ArrayNode (location: (26,0)-(29,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (27,0)-(27,5))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (27,0)-(27,5) = "line2"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "line2"
+ │ │ └── @ SymbolNode (location: (28,0)-(28,5))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (28,0)-(28,5) = "line3"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "line3"
+ │ ├── opening_loc: (26,0)-(26,3) = "%i["
+ │ └── closing_loc: (29,0)-(29,1) = "]"
+ ├── @ RegularExpressionNode (location: (31,0)-(34,1))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (31,0)-(31,3) = "%r["
+ │ ├── content_loc: (31,3)-(34,0) = "\n\n\n"
+ │ ├── closing_loc: (34,0)-(34,1) = "]"
+ │ └── unescaped: "\n\n\n"
+ ├── @ ArrayNode (location: (36,0)-(39,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (36,0)-(36,3) = "%w["
+ │ └── closing_loc: (39,0)-(39,1) = "]"
+ ├── @ ArrayNode (location: (41,0)-(44,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (42,0)-(42,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (42,0)-(42,5) = "line2"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "line2"
+ │ │ └── @ StringNode (location: (43,0)-(43,5))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (43,0)-(43,5) = "line3"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "line3"
+ │ ├── opening_loc: (41,0)-(41,3) = "%w["
+ │ └── closing_loc: (44,0)-(44,1) = "]"
+ ├── @ ArrayNode (location: (46,0)-(49,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (47,0)-(47,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (47,0)-(47,1) = ":"
+ │ │ │ ├── value_loc: (47,1)-(47,6) = "line2"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "line2"
+ │ │ └── @ SymbolNode (location: (48,0)-(48,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (48,0)-(48,1) = ":"
+ │ │ ├── value_loc: (48,1)-(48,6) = "line3"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "line3"
+ │ ├── opening_loc: (46,0)-(46,1) = "["
+ │ └── closing_loc: (49,0)-(49,1) = "]"
+ ├── @ ClassNode (location: (51,0)-(56,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (51,0)-(51,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (51,6)-(51,7))
+ │ │ └── name: :X
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (52,2)-(55,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ DefNode (location: (52,2)-(55,5))
+ │ │ ├── name: :y
+ │ │ ├── name_loc: (52,11)-(52,12) = "y"
+ │ │ ├── receiver:
+ │ │ │ @ SelfNode (location: (52,6)-(52,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (52,13)-(53,9))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (52,13)-(52,14))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (53,8)-(53,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (54,4)-(54,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (54,4)-(54,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ LocalVariableReadNode (location: (54,4)-(54,5))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+
+ │ │ │ ├── message_loc: (54,6)-(54,7) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (54,8)-(54,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (54,8)-(54,9))
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: [:a, :b]
+ │ │ ├── def_keyword_loc: (52,2)-(52,5) = "def"
+ │ │ ├── operator_loc: (52,10)-(52,11) = "."
+ │ │ ├── lparen_loc: (52,12)-(52,13) = "("
+ │ │ ├── rparen_loc: (53,9)-(53,10) = ")"
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (55,2)-(55,5) = "end"
+ │ ├── end_keyword_loc: (56,0)-(56,3) = "end"
+ │ └── name: :X
+ ├── @ ClassNode (location: (59,0)-(63,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (59,0)-(59,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (59,6)-(59,7))
+ │ │ └── name: :X
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (60,2)-(62,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ClassNode (location: (60,2)-(62,5))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (60,2)-(60,7) = "class"
+ │ │ ├── constant_path:
+ │ │ │ @ ConstantReadNode (location: (60,8)-(60,9))
+ │ │ │ └── name: :Y
+ │ │ ├── inheritance_operator_loc: ∅
+ │ │ ├── superclass: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (61,4)-(61,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ ConstantWriteNode (location: (61,4)-(61,10))
+ │ │ │ ├── name: :Z
+ │ │ │ ├── name_loc: (61,4)-(61,5) = "Z"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (61,8)-(61,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── operator_loc: (61,6)-(61,7) = "="
+ │ │ ├── end_keyword_loc: (62,2)-(62,5) = "end"
+ │ │ └── name: :Y
+ │ ├── end_keyword_loc: (63,0)-(63,3) = "end"
+ │ └── name: :X
+ ├── @ ClassNode (location: (66,0)-(71,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (66,0)-(66,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (66,6)-(66,7))
+ │ │ └── name: :X
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (67,2)-(70,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ DefNode (location: (67,2)-(70,5))
+ │ │ ├── name: :y
+ │ │ ├── name_loc: (67,6)-(67,7) = "y"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (67,8)-(68,9))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (67,8)-(67,9))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (68,8)-(68,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (69,4)-(69,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (69,4)-(69,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ LocalVariableReadNode (location: (69,4)-(69,5))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+
+ │ │ │ ├── message_loc: (69,6)-(69,7) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (69,8)-(69,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (69,8)-(69,9))
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: [:a, :b]
+ │ │ ├── def_keyword_loc: (67,2)-(67,5) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: (67,7)-(67,8) = "("
+ │ │ ├── rparen_loc: (68,9)-(68,10) = ")"
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (70,2)-(70,5) = "end"
+ │ ├── end_keyword_loc: (71,0)-(71,3) = "end"
+ │ └── name: :X
+ ├── @ ModuleNode (location: (74,0)-(79,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (74,0)-(74,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (74,7)-(74,8))
+ │ │ └── name: :X
+ │ ├── body:
+ │ │ @ StatementsNode (location: (75,2)-(78,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ConstantWriteNode (location: (75,2)-(78,3))
+ │ │ ├── name: :X
+ │ │ ├── name_loc: (75,2)-(75,3) = "X"
+ │ │ ├── value:
+ │ │ │ @ ArrayNode (location: (75,6)-(78,3))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ ├── @ SymbolNode (location: (76,4)-(76,10))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (76,4)-(76,5) = ":"
+ │ │ │ │ │ ├── value_loc: (76,5)-(76,10) = "line3"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "line3"
+ │ │ │ │ └── @ SymbolNode (location: (77,4)-(77,10))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (77,4)-(77,5) = ":"
+ │ │ │ │ ├── value_loc: (77,5)-(77,10) = "line4"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "line4"
+ │ │ │ ├── opening_loc: (75,6)-(75,7) = "["
+ │ │ │ └── closing_loc: (78,2)-(78,3) = "]"
+ │ │ └── operator_loc: (75,4)-(75,5) = "="
+ │ ├── end_keyword_loc: (79,0)-(79,3) = "end"
+ │ └── name: :X
+ ├── @ ModuleNode (location: (82,0)-(86,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (82,0)-(82,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (82,7)-(82,8))
+ │ │ └── name: :X
+ │ ├── body:
+ │ │ @ StatementsNode (location: (83,2)-(85,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ModuleNode (location: (83,2)-(85,5))
+ │ │ ├── locals: []
+ │ │ ├── module_keyword_loc: (83,2)-(83,8) = "module"
+ │ │ ├── constant_path:
+ │ │ │ @ ConstantReadNode (location: (83,9)-(83,10))
+ │ │ │ └── name: :Y
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (84,4)-(84,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ ConstantWriteNode (location: (84,4)-(84,10))
+ │ │ │ ├── name: :Z
+ │ │ │ ├── name_loc: (84,4)-(84,5) = "Z"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (84,8)-(84,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── operator_loc: (84,6)-(84,7) = "="
+ │ │ ├── end_keyword_loc: (85,2)-(85,5) = "end"
+ │ │ └── name: :Y
+ │ ├── end_keyword_loc: (86,0)-(86,3) = "end"
+ │ └── name: :X
+ └── @ CallNode (location: (89,0)-(92,1))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (89,0)-(89,1) = "x"
+ ├── opening_loc: (89,1)-(89,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (90,0)-(91,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ SymbolNode (location: (90,0)-(90,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (90,0)-(90,1) = ":"
+ │ │ ├── value_loc: (90,1)-(90,6) = "line2"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "line2"
+ │ └── @ SymbolNode (location: (91,0)-(91,6))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (91,0)-(91,1) = ":"
+ │ ├── value_loc: (91,1)-(91,6) = "line3"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "line3"
+ ├── closing_loc: (92,0)-(92,1) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/__ENCODING__.txt b/test/prism/snapshots/seattlerb/__ENCODING__.txt
new file mode 100644
index 0000000000..1b223bd8fe
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/__ENCODING__.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ SourceEncodingNode (location: (1,0)-(1,12))
diff --git a/test/prism/snapshots/seattlerb/alias_gvar_backref.txt b/test/prism/snapshots/seattlerb/alias_gvar_backref.txt
new file mode 100644
index 0000000000..a2586423d7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/alias_gvar_backref.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ AliasGlobalVariableNode (location: (1,0)-(1,15))
+ ├── new_name:
+ │ @ GlobalVariableReadNode (location: (1,6)-(1,12))
+ │ └── name: :$MATCH
+ ├── old_name:
+ │ @ BackReferenceReadNode (location: (1,13)-(1,15))
+ │ └── name: :$&
+ └── keyword_loc: (1,0)-(1,5) = "alias"
diff --git a/test/prism/snapshots/seattlerb/alias_resword.txt b/test/prism/snapshots/seattlerb/alias_resword.txt
new file mode 100644
index 0000000000..99ed696c68
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/alias_resword.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ AliasMethodNode (location: (1,0)-(1,12))
+ ├── new_name:
+ │ @ SymbolNode (location: (1,6)-(1,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (1,6)-(1,8) = "in"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "in"
+ ├── old_name:
+ │ @ SymbolNode (location: (1,9)-(1,12))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (1,9)-(1,12) = "out"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "out"
+ └── keyword_loc: (1,0)-(1,5) = "alias"
diff --git a/test/prism/snapshots/seattlerb/and_multi.txt b/test/prism/snapshots/seattlerb/and_multi.txt
new file mode 100644
index 0000000000..b60b131fd2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/and_multi.txt
@@ -0,0 +1,26 @@
+@ ProgramNode (location: (1,0)-(3,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,4))
+ └── body: (length: 1)
+ └── @ AndNode (location: (1,0)-(3,4))
+ ├── left:
+ │ @ AndNode (location: (1,0)-(2,9))
+ │ ├── left:
+ │ │ @ TrueNode (location: (1,0)-(1,4))
+ │ ├── right:
+ │ │ @ CallNode (location: (2,0)-(2,9))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ FalseNode (location: (2,4)-(2,9))
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :!
+ │ │ ├── message_loc: (2,0)-(2,3) = "not"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,5)-(1,8) = "and"
+ ├── right:
+ │ @ TrueNode (location: (3,0)-(3,4))
+ └── operator_loc: (2,10)-(2,13) = "and"
diff --git a/test/prism/snapshots/seattlerb/aref_args_assocs.txt b/test/prism/snapshots/seattlerb/aref_args_assocs.txt
new file mode 100644
index 0000000000..b729186dc5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/aref_args_assocs.txt
@@ -0,0 +1,23 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── elements: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,1)-(1,7))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,1)-(1,7))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (1,1)-(1,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,6)-(1,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (1,3)-(1,5) = "=>"
+ ├── opening_loc: (1,0)-(1,1) = "["
+ └── closing_loc: (1,7)-(1,8) = "]"
diff --git a/test/prism/snapshots/seattlerb/aref_args_lit_assocs.txt b/test/prism/snapshots/seattlerb/aref_args_lit_assocs.txt
new file mode 100644
index 0000000000..0e9454d780
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/aref_args_lit_assocs.txt
@@ -0,0 +1,26 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,11))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ IntegerNode (location: (1,1)-(1,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ KeywordHashNode (location: (1,4)-(1,10))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,4)-(1,10))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: (1,6)-(1,8) = "=>"
+ ├── opening_loc: (1,0)-(1,1) = "["
+ └── closing_loc: (1,10)-(1,11) = "]"
diff --git a/test/prism/snapshots/seattlerb/args_kw_block.txt b/test/prism/snapshots/seattlerb/args_kw_block.txt
new file mode 100644
index 0000000000..1ad933c74e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/args_kw_block.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,20))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,14))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,6)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :a
+ │ │ ├── name_loc: (1,6)-(1,8) = "a:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_rest: ∅
+ │ └── block:
+ │ @ BlockParameterNode (location: (1,12)-(1,14))
+ │ ├── flags: ∅
+ │ ├── name: :b
+ │ ├── name_loc: (1,13)-(1,14) = "b"
+ │ └── operator_loc: (1,12)-(1,13) = "&"
+ ├── body: ∅
+ ├── locals: [:a, :b]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,14)-(1,15) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,17)-(1,20) = "end"
diff --git a/test/prism/snapshots/seattlerb/array_line_breaks.txt b/test/prism/snapshots/seattlerb/array_line_breaks.txt
new file mode 100644
index 0000000000..880fedf933
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/array_line_breaks.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(4,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,1))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(3,4))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (2,0)-(2,3))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (2,0)-(2,1) = "'"
+ │ │ │ ├── content_loc: (2,1)-(2,2) = "a"
+ │ │ │ ├── closing_loc: (2,2)-(2,3) = "'"
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ StringNode (location: (3,0)-(3,3))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (3,0)-(3,1) = "'"
+ │ │ ├── content_loc: (3,1)-(3,2) = "b"
+ │ │ ├── closing_loc: (3,2)-(3,3) = "'"
+ │ │ └── unescaped: "b"
+ │ ├── opening_loc: (1,0)-(1,1) = "["
+ │ └── closing_loc: (3,3)-(3,4) = "]"
+ └── @ IntegerNode (location: (4,0)-(4,1))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/array_lits_trailing_calls.txt b/test/prism/snapshots/seattlerb/array_lits_trailing_calls.txt
new file mode 100644
index 0000000000..d46a181fc7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/array_lits_trailing_calls.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(3,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,4))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ArrayNode (location: (1,0)-(1,4))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 0)
+ │ │ ├── opening_loc: (1,0)-(1,3) = "%w["
+ │ │ └── closing_loc: (1,3)-(1,4) = "]"
+ │ ├── call_operator_loc: (1,4)-(1,5) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (1,5)-(1,6) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,4))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ ArrayNode (location: (3,0)-(3,2))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (3,0)-(3,1) = "["
+ │ └── closing_loc: (3,1)-(3,2) = "]"
+ ├── call_operator_loc: (3,2)-(3,3) = "."
+ ├── name: :b
+ ├── message_loc: (3,3)-(3,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/assoc__bare.txt b/test/prism/snapshots/seattlerb/assoc__bare.txt
new file mode 100644
index 0000000000..28e4f713c5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/assoc__bare.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,0)-(1,6))
+ ├── opening_loc: (1,0)-(1,1) = "{"
+ ├── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,4))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,2)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,2)-(1,3) = "y"
+ │ │ ├── closing_loc: (1,3)-(1,4) = ":"
+ │ │ └── unescaped: "y"
+ │ ├── value:
+ │ │ @ ImplicitNode (location: (1,2)-(1,4))
+ │ │ └── value:
+ │ │ @ CallNode (location: (1,2)-(1,4))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :y
+ │ │ ├── message_loc: (1,2)-(1,3) = "y"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: ∅
+ └── closing_loc: (1,5)-(1,6) = "}"
diff --git a/test/prism/snapshots/seattlerb/assoc_label.txt b/test/prism/snapshots/seattlerb/assoc_label.txt
new file mode 100644
index 0000000000..923f5450f4
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/assoc_label.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,2)-(1,5))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,5))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,2)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,2)-(1,3) = "b"
+ │ │ ├── closing_loc: (1,3)-(1,4) = ":"
+ │ │ └── unescaped: "b"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: ∅
+ ├── closing_loc: (1,5)-(1,6) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt b/test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt
new file mode 100644
index 0000000000..589433eda8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt
@@ -0,0 +1,23 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ ConstantReadNode (location: (1,0)-(1,1))
+ │ └── name: :A
+ ├── call_operator_loc: (1,1)-(1,3) = "::"
+ ├── name: :b=
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,7)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt b/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt
new file mode 100644
index 0000000000..9b04ae9656
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]=
+ ├── message_loc: (1,1)-(1,9) = "[[1, 2]]"
+ ├── opening_loc: (1,1)-(1,2) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ ArrayNode (location: (1,2)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (1,3)-(1,4))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: (1,2)-(1,3) = "["
+ │ │ └── closing_loc: (1,7)-(1,8) = "]"
+ │ └── @ IntegerNode (location: (1,12)-(1,13))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── closing_loc: (1,8)-(1,9) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt b/test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt
new file mode 100644
index 0000000000..39544e98da
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt
@@ -0,0 +1,83 @@
+@ ProgramNode (location: (1,0)-(1,42))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,42))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,42))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ ArrayNode (location: (1,0)-(1,12))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 4)
+ │ │ ├── @ IntegerNode (location: (1,1)-(1,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── @ IntegerNode (location: (1,7)-(1,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 4
+ │ ├── opening_loc: (1,0)-(1,1) = "["
+ │ └── closing_loc: (1,11)-(1,12) = "]"
+ ├── call_operator_loc: ∅
+ ├── name: :[]=
+ ├── message_loc: (1,12)-(1,24) = "[from .. to]"
+ ├── opening_loc: (1,12)-(1,13) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,13)-(1,42))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ RangeNode (location: (1,13)-(1,23))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (1,13)-(1,17))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :from
+ │ │ │ ├── message_loc: (1,13)-(1,17) = "from"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (1,21)-(1,23))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :to
+ │ │ │ ├── message_loc: (1,21)-(1,23) = "to"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (1,18)-(1,20) = ".."
+ │ └── @ ArrayNode (location: (1,27)-(1,42))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (1,28)-(1,31))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,28)-(1,29) = "\""
+ │ │ │ ├── content_loc: (1,29)-(1,30) = "a"
+ │ │ │ ├── closing_loc: (1,30)-(1,31) = "\""
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ StringNode (location: (1,33)-(1,36))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,33)-(1,34) = "\""
+ │ │ │ ├── content_loc: (1,34)-(1,35) = "b"
+ │ │ │ ├── closing_loc: (1,35)-(1,36) = "\""
+ │ │ │ └── unescaped: "b"
+ │ │ └── @ StringNode (location: (1,38)-(1,41))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,38)-(1,39) = "\""
+ │ │ ├── content_loc: (1,39)-(1,40) = "c"
+ │ │ ├── closing_loc: (1,40)-(1,41) = "\""
+ │ │ └── unescaped: "c"
+ │ ├── opening_loc: (1,27)-(1,28) = "["
+ │ └── closing_loc: (1,41)-(1,42) = "]"
+ ├── closing_loc: (1,23)-(1,24) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt b/test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt
new file mode 100644
index 0000000000..d4c4fe1070
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :B=
+ ├── message_loc: (1,2)-(1,3) = "B"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt b/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt
new file mode 100644
index 0000000000..67c8be034e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (1,0)-(1,1) = "x"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedXStringNode (location: (1,2)-(1,8))
+ │ ├── opening_loc: (1,2)-(1,3) = "`"
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (1,3)-(1,7))
+ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :y
+ │ │ │ ├── message_loc: (1,5)-(1,6) = "y"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,6)-(1,7) = "}"
+ │ └── closing_loc: (1,7)-(1,8) = "`"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bang_eq.txt b/test/prism/snapshots/seattlerb/bang_eq.txt
new file mode 100644
index 0000000000..ec3dd888b2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bang_eq.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :!=
+ ├── message_loc: (1,2)-(1,4) = "!="
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bdot2.txt b/test/prism/snapshots/seattlerb/bdot2.txt
new file mode 100644
index 0000000000..d4fb86fbe6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bdot2.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 3)
+ ├── @ RangeNode (location: (1,0)-(1,4))
+ │ ├── flags: ∅
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ IntegerNode (location: (1,2)-(1,4))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ └── operator_loc: (1,0)-(1,2) = ".."
+ ├── @ RangeNode (location: (2,2)-(2,5))
+ │ ├── flags: ∅
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (2,4)-(2,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (2,4)-(2,5) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (2,2)-(2,4) = ".."
+ └── @ CallNode (location: (3,2)-(3,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (3,2)-(3,3) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bdot3.txt b/test/prism/snapshots/seattlerb/bdot3.txt
new file mode 100644
index 0000000000..0c960f0458
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bdot3.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 3)
+ ├── @ RangeNode (location: (1,0)-(1,5))
+ │ ├── flags: exclude_end
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ IntegerNode (location: (1,3)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ └── operator_loc: (1,0)-(1,3) = "..."
+ ├── @ RangeNode (location: (2,2)-(2,6))
+ │ ├── flags: exclude_end
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (2,5)-(2,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (2,5)-(2,6) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (2,2)-(2,5) = "..."
+ └── @ CallNode (location: (3,2)-(3,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (3,2)-(3,3) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt b/test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt
new file mode 100644
index 0000000000..e1698d0bae
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt
@@ -0,0 +1,16 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(3,3))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements: ∅
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (2,0)-(3,3))
+ │ ├── ensure_keyword_loc: (2,0)-(2,6) = "ensure"
+ │ ├── statements: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt b/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt
new file mode 100644
index 0000000000..6603e5c894
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(9,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,3))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(9,3))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (2,2)-(2,3))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (2,2)-(2,3))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── rescue_clause:
+ │ @ RescueNode (location: (3,0)-(4,3))
+ │ ├── keyword_loc: (3,0)-(3,6) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (4,2)-(4,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (4,2)-(4,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── consequent: ∅
+ ├── else_clause:
+ │ @ ElseNode (location: (5,0)-(7,6))
+ │ ├── else_keyword_loc: (5,0)-(5,4) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (6,2)-(6,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (6,2)-(6,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── end_keyword_loc: (7,0)-(7,6) = "ensure"
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (7,0)-(9,3))
+ │ ├── ensure_keyword_loc: (7,0)-(7,6) = "ensure"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (8,2)-(8,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (8,2)-(8,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 4
+ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ └── end_keyword_loc: (9,0)-(9,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt b/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt
new file mode 100644
index 0000000000..02e1f097ac
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(9,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,3))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(9,3))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (3,0)-(3,6))
+ │ ├── keyword_loc: (3,0)-(3,6) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements: ∅
+ │ └── consequent: ∅
+ ├── else_clause:
+ │ @ ElseNode (location: (5,0)-(7,6))
+ │ ├── else_keyword_loc: (5,0)-(5,4) = "else"
+ │ ├── statements: ∅
+ │ └── end_keyword_loc: (7,0)-(7,6) = "ensure"
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (7,0)-(9,3))
+ │ ├── ensure_keyword_loc: (7,0)-(7,6) = "ensure"
+ │ ├── statements: ∅
+ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ └── end_keyword_loc: (9,0)-(9,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt b/test/prism/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt
new file mode 100644
index 0000000000..b36fe5c1fe
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt
@@ -0,0 +1,23 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(4,3))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (2,0)-(2,6))
+ │ ├── keyword_loc: (2,0)-(2,6) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (3,0)-(4,3))
+ │ ├── ensure_keyword_loc: (3,0)-(3,6) = "ensure"
+ │ ├── statements: ∅
+ │ └── end_keyword_loc: (4,0)-(4,3) = "end"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/block_arg__bare.txt b/test/prism/snapshots/seattlerb/block_arg__bare.txt
new file mode 100644
index 0000000000..165c2980be
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg__bare.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,13))
+ ├── name: :x
+ ├── name_loc: (1,4)-(1,5) = "x"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,7))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block:
+ │ @ BlockParameterNode (location: (1,6)-(1,7))
+ │ ├── flags: ∅
+ │ ├── name: ∅
+ │ ├── name_loc: ∅
+ │ └── operator_loc: (1,6)-(1,7) = "&"
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,7)-(1,8) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,10)-(1,13) = "end"
diff --git a/test/prism/snapshots/seattlerb/block_arg_kwsplat.txt b/test/prism/snapshots/seattlerb/block_arg_kwsplat.txt
new file mode 100644
index 0000000000..392de8559b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg_kwsplat.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,11))
+ ├── locals: [:b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,9))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (1,5)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,7)-(1,8) = "b"
+ │ │ │ └── operator_loc: (1,5)-(1,7) = "**"
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,8)-(1,9) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,10)-(1,11) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_arg_opt_arg_block.txt b/test/prism/snapshots/seattlerb/block_arg_opt_arg_block.txt
new file mode 100644
index 0000000000..ee9644d59d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg_opt_arg_block.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(1,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,21))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,21))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,21))
+ ├── locals: [:b, :c, :d, :e]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,19))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,18))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "c"
+ │ │ │ ├── operator_loc: (1,9)-(1,10) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,16)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :e
+ │ │ ├── name_loc: (1,17)-(1,18) = "e"
+ │ │ └── operator_loc: (1,16)-(1,17) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,18)-(1,19) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,20)-(1,21) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_arg_opt_splat.txt b/test/prism/snapshots/seattlerb/block_arg_opt_splat.txt
new file mode 100644
index 0000000000..799bd21057
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg_opt_splat.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,20))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,20))
+ ├── locals: [:b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,18))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,17))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "c"
+ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,15)-(1,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── name_loc: (1,16)-(1,17) = "d"
+ │ │ │ └── operator_loc: (1,15)-(1,16) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,17)-(1,18) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,19)-(1,20) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt b/test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt
new file mode 100644
index 0000000000..b5df136a62
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,25))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,25))
+ ├── locals: [:b, :c, :d, :e, :f]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,23))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,22))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "c"
+ │ │ │ ├── operator_loc: (1,9)-(1,10) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── name_loc: (1,14)-(1,15) = "d"
+ │ │ │ └── operator_loc: (1,13)-(1,14) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,17)-(1,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :e
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,20)-(1,22))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :f
+ │ │ ├── name_loc: (1,21)-(1,22) = "f"
+ │ │ └── operator_loc: (1,20)-(1,21) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,22)-(1,23) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,24)-(1,25) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_arg_optional.txt b/test/prism/snapshots/seattlerb/block_arg_optional.txt
new file mode 100644
index 0000000000..8a850e9a21
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg_optional.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,13))
+ ├── locals: [:b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,10)-(1,11) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,12)-(1,13) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_arg_scope.txt b/test/prism/snapshots/seattlerb/block_arg_scope.txt
new file mode 100644
index 0000000000..b99cc5e45c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg_scope.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,12))
+ ├── locals: [:b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,10))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,6))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 1)
+ │ │ └── @ BlockLocalVariableNode (location: (1,8)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── name: :c
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,9)-(1,10) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,11)-(1,12) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_arg_scope2.txt b/test/prism/snapshots/seattlerb/block_arg_scope2.txt
new file mode 100644
index 0000000000..98b3a7da3a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg_scope2.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,14))
+ ├── locals: [:b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,3)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,4)-(1,5))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,4)-(1,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 2)
+ │ │ ├── @ BlockLocalVariableNode (location: (1,7)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ └── @ BlockLocalVariableNode (location: (1,10)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── name: :d
+ │ ├── opening_loc: (1,3)-(1,4) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,13)-(1,14) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_arg_splat_arg.txt b/test/prism/snapshots/seattlerb/block_arg_splat_arg.txt
new file mode 100644
index 0000000000..fd5813c983
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_arg_splat_arg.txt
@@ -0,0 +1,45 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,16))
+ ├── locals: [:b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,14))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,13))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,8)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,9)-(1,10) = "c"
+ │ │ │ └── operator_loc: (1,8)-(1,9) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,13)-(1,14) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,15)-(1,16) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_args_kwargs.txt b/test/prism/snapshots/seattlerb/block_args_kwargs.txt
new file mode 100644
index 0000000000..0975ce3367
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_args_kwargs.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,23))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,23))
+ ├── locals: [:kwargs]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,14))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,13))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (1,5)-(1,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :kwargs
+ │ │ │ ├── name_loc: (1,7)-(1,13) = "kwargs"
+ │ │ │ └── operator_loc: (1,5)-(1,7) = "**"
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,13)-(1,14) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,15)-(1,21))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (1,15)-(1,21))
+ │ ├── name: :kwargs
+ │ └── depth: 0
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,22)-(1,23) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_args_no_kwargs.txt b/test/prism/snapshots/seattlerb/block_args_no_kwargs.txt
new file mode 100644
index 0000000000..d47349defb
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_args_no_kwargs.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,13))
+ ├── locals: []
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ NoKeywordsParameterNode (location: (1,5)-(1,10))
+ │ │ │ ├── operator_loc: (1,5)-(1,7) = "**"
+ │ │ │ └── keyword_loc: (1,7)-(1,10) = "nil"
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,10)-(1,11) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,12)-(1,13) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_args_opt1.txt b/test/prism/snapshots/seattlerb/block_args_opt1.txt
new file mode 100644
index 0000000000..1f21c0a477
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_args_opt1.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,24))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,24))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
+ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,16)-(1,22))
+ │ └── body: (length: 1)
+ │ └── @ ArrayNode (location: (1,16)-(1,22))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ LocalVariableReadNode (location: (1,17)-(1,18))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableReadNode (location: (1,20)-(1,21))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── opening_loc: (1,16)-(1,17) = "["
+ │ └── closing_loc: (1,21)-(1,22) = "]"
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,23)-(1,24) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_args_opt2.txt b/test/prism/snapshots/seattlerb/block_args_opt2.txt
new file mode 100644
index 0000000000..a8d736dde7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_args_opt2.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,18))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,18))
+ ├── locals: [:b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,16))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 2)
+ │ │ │ ├── @ OptionalParameterNode (location: (1,6)-(1,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (1,6)-(1,7) = "b"
+ │ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ OptionalParameterNode (location: (1,11)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,11)-(1,12) = "c"
+ │ │ │ ├── operator_loc: (1,12)-(1,13) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,15)-(1,16) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,17)-(1,18) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_args_opt2_2.txt b/test/prism/snapshots/seattlerb/block_args_opt2_2.txt
new file mode 100644
index 0000000000..0403851ed7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_args_opt2_2.txt
@@ -0,0 +1,71 @@
+@ ProgramNode (location: (1,0)-(1,35))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,35))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,35))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,35))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,23))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,22))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 2)
+ │ │ │ ├── @ OptionalParameterNode (location: (1,8)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
+ │ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── @ OptionalParameterNode (location: (1,16)-(1,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,16)-(1,17) = "c"
+ │ │ │ ├── operator_loc: (1,18)-(1,19) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,20)-(1,22))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 24
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,22)-(1,23) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,24)-(1,33))
+ │ └── body: (length: 1)
+ │ └── @ ArrayNode (location: (1,24)-(1,33))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ LocalVariableReadNode (location: (1,25)-(1,26))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── @ LocalVariableReadNode (location: (1,28)-(1,29))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableReadNode (location: (1,31)-(1,32))
+ │ │ ├── name: :c
+ │ │ └── depth: 0
+ │ ├── opening_loc: (1,24)-(1,25) = "["
+ │ └── closing_loc: (1,32)-(1,33) = "]"
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,34)-(1,35) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_args_opt3.txt b/test/prism/snapshots/seattlerb/block_args_opt3.txt
new file mode 100644
index 0000000000..ff4495019c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_args_opt3.txt
@@ -0,0 +1,79 @@
+@ ProgramNode (location: (1,0)-(1,42))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,42))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,42))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,42))
+ ├── locals: [:a, :b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,27))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,26))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 2)
+ │ │ │ ├── @ OptionalParameterNode (location: (1,8)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
+ │ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── @ OptionalParameterNode (location: (1,16)-(1,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,16)-(1,17) = "c"
+ │ │ │ ├── operator_loc: (1,18)-(1,19) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,20)-(1,22))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 24
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,24)-(1,26))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :d
+ │ │ ├── name_loc: (1,25)-(1,26) = "d"
+ │ │ └── operator_loc: (1,24)-(1,25) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,26)-(1,27) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,28)-(1,40))
+ │ └── body: (length: 1)
+ │ └── @ ArrayNode (location: (1,28)-(1,40))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 4)
+ │ │ ├── @ LocalVariableReadNode (location: (1,29)-(1,30))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── @ LocalVariableReadNode (location: (1,32)-(1,33))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── @ LocalVariableReadNode (location: (1,35)-(1,36))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableReadNode (location: (1,38)-(1,39))
+ │ │ ├── name: :d
+ │ │ └── depth: 0
+ │ ├── opening_loc: (1,28)-(1,29) = "["
+ │ └── closing_loc: (1,39)-(1,40) = "]"
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,41)-(1,42) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_call_defn_call_block_call.txt b/test/prism/snapshots/seattlerb/block_call_defn_call_block_call.txt
new file mode 100644
index 0000000000..2e634dc937
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_call_defn_call_block_call.txt
@@ -0,0 +1,80 @@
+@ ProgramNode (location: (1,0)-(4,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,11))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(3,4))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(3,4))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ DefNode (location: (1,2)-(3,4))
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,6)-(1,7) = "b"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,8)-(1,9))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,8)-(1,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (2,1)-(2,2))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,1)-(2,2))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (2,1)-(2,2) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: [:c]
+ │ │ ├── def_keyword_loc: (1,2)-(1,5) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ │ ├── rparen_loc: (1,9)-(1,10) = ")"
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (3,1)-(3,4) = "end"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (4,1)-(4,11))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (4,1)-(4,2))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :e
+ │ ├── message_loc: (4,1)-(4,2) = "e"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (4,2)-(4,3) = "."
+ ├── name: :f
+ ├── message_loc: (4,3)-(4,4) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (4,5)-(4,11))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (4,5)-(4,7) = "do"
+ └── closing_loc: (4,8)-(4,11) = "end"
diff --git a/test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt b/test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt
new file mode 100644
index 0000000000..e46104b868
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt
@@ -0,0 +1,100 @@
+@ ProgramNode (location: (1,0)-(1,31))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,31))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,31))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,1)-(1,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (1,2)-(1,3) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,7))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (1,4)-(1,5) = "c"
+ │ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: (1,6)-(1,7) = ")"
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,8)-(1,16))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,11)-(1,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,11)-(1,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (1,11)-(1,12) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,8)-(1,10) = "do"
+ │ └── closing_loc: (1,13)-(1,16) = "end"
+ ├── call_operator_loc: (1,16)-(1,17) = "."
+ ├── name: :e
+ ├── message_loc: (1,17)-(1,18) = "e"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,19)-(1,31))
+ ├── locals: [:f]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,22)-(1,25))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,23)-(1,24))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,23)-(1,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :f
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,22)-(1,23) = "|"
+ │ └── closing_loc: (1,24)-(1,25) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,26)-(1,27))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,26)-(1,27))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :g
+ │ ├── message_loc: (1,26)-(1,27) = "g"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (1,19)-(1,21) = "do"
+ └── closing_loc: (1,28)-(1,31) = "end"
diff --git a/test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt b/test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt
new file mode 100644
index 0000000000..05d076f8d6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt
@@ -0,0 +1,113 @@
+@ ProgramNode (location: (1,0)-(1,33))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,33))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,33))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,1)-(1,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (1,2)-(1,3) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,7))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (1,4)-(1,5) = "c"
+ │ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: (1,6)-(1,7) = ")"
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,8)-(1,16))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,11)-(1,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,11)-(1,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (1,11)-(1,12) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,8)-(1,10) = "do"
+ │ └── closing_loc: (1,13)-(1,16) = "end"
+ ├── call_operator_loc: (1,16)-(1,17) = "."
+ ├── name: :e
+ ├── message_loc: (1,17)-(1,18) = "e"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,19)-(1,20))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,19)-(1,20))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (1,19)-(1,20) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,21)-(1,33))
+ ├── locals: [:g]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,24)-(1,27))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,25)-(1,26))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,25)-(1,26))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :g
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,24)-(1,25) = "|"
+ │ └── closing_loc: (1,26)-(1,27) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,28)-(1,29))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,28)-(1,29))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :h
+ │ ├── message_loc: (1,28)-(1,29) = "h"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (1,21)-(1,23) = "do"
+ └── closing_loc: (1,30)-(1,33) = "end"
diff --git a/test/prism/snapshots/seattlerb/block_call_operation_colon.txt b/test/prism/snapshots/seattlerb/block_call_operation_colon.txt
new file mode 100644
index 0000000000..9fd13b0dfc
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_call_operation_colon.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,15))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,1)-(1,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (1,2)-(1,3) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (1,4)-(1,5) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,6)-(1,12))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,6)-(1,8) = "do"
+ │ └── closing_loc: (1,9)-(1,12) = "end"
+ ├── call_operator_loc: (1,12)-(1,14) = "::"
+ ├── name: :d
+ ├── message_loc: (1,14)-(1,15) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/block_call_operation_dot.txt b/test/prism/snapshots/seattlerb/block_call_operation_dot.txt
new file mode 100644
index 0000000000..43c19d3318
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_call_operation_dot.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,1)-(1,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (1,2)-(1,3) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (1,4)-(1,5) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,6)-(1,12))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,6)-(1,8) = "do"
+ │ └── closing_loc: (1,9)-(1,12) = "end"
+ ├── call_operator_loc: (1,12)-(1,13) = "."
+ ├── name: :d
+ ├── message_loc: (1,13)-(1,14) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt b/test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt
new file mode 100644
index 0000000000..10c1780d37
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt
@@ -0,0 +1,60 @@
+@ ProgramNode (location: (1,0)-(2,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,10))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ParenthesesNode (location: (1,2)-(1,5))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,3)-(1,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,3)-(1,4) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ │ └── closing_loc: (1,4)-(1,5) = ")"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (2,0)-(2,10))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (2,0)-(2,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :c
+ │ ├── message_loc: (2,0)-(2,1) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (2,1)-(2,2) = "."
+ ├── name: :d
+ ├── message_loc: (2,2)-(2,3) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (2,4)-(2,10))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (2,4)-(2,6) = "do"
+ └── closing_loc: (2,7)-(2,10) = "end"
diff --git a/test/prism/snapshots/seattlerb/block_command_operation_colon.txt b/test/prism/snapshots/seattlerb/block_command_operation_colon.txt
new file mode 100644
index 0000000000..30fd6dafa0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_command_operation_colon.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,4))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,2)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,2)-(1,3) = ":"
+ │ │ ├── value_loc: (1,3)-(1,4) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,5)-(1,11))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,5)-(1,7) = "do"
+ │ └── closing_loc: (1,8)-(1,11) = "end"
+ ├── call_operator_loc: (1,11)-(1,13) = "::"
+ ├── name: :c
+ ├── message_loc: (1,13)-(1,14) = "c"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,15)-(1,17))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ SymbolNode (location: (1,15)-(1,17))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,15)-(1,16) = ":"
+ │ ├── value_loc: (1,16)-(1,17) = "d"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "d"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/block_command_operation_dot.txt b/test/prism/snapshots/seattlerb/block_command_operation_dot.txt
new file mode 100644
index 0000000000..e4f69d3604
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_command_operation_dot.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,4))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,2)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,2)-(1,3) = ":"
+ │ │ ├── value_loc: (1,3)-(1,4) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,5)-(1,11))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,5)-(1,7) = "do"
+ │ └── closing_loc: (1,8)-(1,11) = "end"
+ ├── call_operator_loc: (1,11)-(1,12) = "."
+ ├── name: :c
+ ├── message_loc: (1,12)-(1,13) = "c"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,14)-(1,16))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ SymbolNode (location: (1,14)-(1,16))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,14)-(1,15) = ":"
+ │ ├── value_loc: (1,15)-(1,16) = "d"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "d"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt b/test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt
new file mode 100644
index 0000000000..e309ec1f98
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,14))
+ ├── locals: [:a]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,11))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,6)-(1,7))
+ │ │ │ │ ├── operator_loc: (1,6)-(1,7) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ └── rparen_loc: (1,10)-(1,11) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,13)-(1,14) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt b/test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt
new file mode 100644
index 0000000000..8d28fa7e02
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,14))
+ ├── locals: [:b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,11))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ └── rparen_loc: (1,10)-(1,11) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,13)-(1,14) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_decomp_arg_splat_arg.txt b/test/prism/snapshots/seattlerb/block_decomp_arg_splat_arg.txt
new file mode 100644
index 0000000000..4f4a82acf5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_decomp_arg_splat_arg.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,18))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,18))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,16))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,15))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,15))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,9)-(1,11))
+ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ └── rparen_loc: (1,14)-(1,15) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,15)-(1,16) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,17)-(1,18) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_decomp_splat.txt b/test/prism/snapshots/seattlerb/block_decomp_splat.txt
new file mode 100644
index 0000000000..09d3440126
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_decomp_splat.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,12))
+ ├── locals: [:a]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,10))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,9))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,9))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,6)-(1,8))
+ │ │ │ │ ├── operator_loc: (1,6)-(1,7) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (1,7)-(1,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ └── rparen_loc: (1,8)-(1,9) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,9)-(1,10) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,11)-(1,12) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_kw.txt b/test/prism/snapshots/seattlerb/block_kw.txt
new file mode 100644
index 0000000000..f022637dae
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_kw.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,15))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :blah
+ ├── message_loc: (1,0)-(1,4) = "blah"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,5)-(1,15))
+ ├── locals: [:k]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,7)-(1,13))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,8)-(1,12))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (1,8)-(1,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :k
+ │ │ │ ├── name_loc: (1,8)-(1,10) = "k:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,10)-(1,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,7)-(1,8) = "|"
+ │ └── closing_loc: (1,12)-(1,13) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,5)-(1,6) = "{"
+ └── closing_loc: (1,14)-(1,15) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_kw__required.txt b/test/prism/snapshots/seattlerb/block_kw__required.txt
new file mode 100644
index 0000000000..8a49c8bec7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_kw__required.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :blah
+ ├── message_loc: (1,0)-(1,4) = "blah"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,5)-(1,16))
+ ├── locals: [:k]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,8)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,9)-(1,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :k
+ │ │ │ └── name_loc: (1,9)-(1,11) = "k:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,8)-(1,9) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,5)-(1,7) = "do"
+ └── closing_loc: (1,13)-(1,16) = "end"
diff --git a/test/prism/snapshots/seattlerb/block_kwarg_lvar.txt b/test/prism/snapshots/seattlerb/block_kwarg_lvar.txt
new file mode 100644
index 0000000000..e77bf90a27
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_kwarg_lvar.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,20))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :bl
+ ├── message_loc: (1,0)-(1,2) = "bl"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,3)-(1,20))
+ ├── locals: [:kw]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,5)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (1,6)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :kw
+ │ │ │ ├── name_loc: (1,6)-(1,9) = "kw:"
+ │ │ │ └── value:
+ │ │ │ @ SymbolNode (location: (1,10)-(1,14))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,10)-(1,11) = ":"
+ │ │ │ ├── value_loc: (1,11)-(1,14) = "val"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "val"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,5)-(1,6) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,16)-(1,18))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (1,16)-(1,18))
+ │ ├── name: :kw
+ │ └── depth: 0
+ ├── opening_loc: (1,3)-(1,4) = "{"
+ └── closing_loc: (1,19)-(1,20) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_kwarg_lvar_multiple.txt b/test/prism/snapshots/seattlerb/block_kwarg_lvar_multiple.txt
new file mode 100644
index 0000000000..a527c8c993
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_kwarg_lvar_multiple.txt
@@ -0,0 +1,61 @@
+@ ProgramNode (location: (1,0)-(1,33))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,33))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,33))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :bl
+ ├── message_loc: (1,0)-(1,2) = "bl"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,3)-(1,33))
+ ├── locals: [:kw, :kw2]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,5)-(1,28))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,26))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ OptionalKeywordParameterNode (location: (1,6)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :kw
+ │ │ │ │ ├── name_loc: (1,6)-(1,9) = "kw:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ SymbolNode (location: (1,10)-(1,14))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (1,10)-(1,11) = ":"
+ │ │ │ │ ├── value_loc: (1,11)-(1,14) = "val"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "val"
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (1,16)-(1,26))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :kw2
+ │ │ │ ├── name_loc: (1,16)-(1,20) = "kw2:"
+ │ │ │ └── value:
+ │ │ │ @ SymbolNode (location: (1,21)-(1,26))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,21)-(1,22) = ":"
+ │ │ │ ├── value_loc: (1,22)-(1,26) = "val2"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "val2"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,5)-(1,6) = "|"
+ │ └── closing_loc: (1,27)-(1,28) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,29)-(1,31))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (1,29)-(1,31))
+ │ ├── name: :kw
+ │ └── depth: 0
+ ├── opening_loc: (1,3)-(1,4) = "{"
+ └── closing_loc: (1,32)-(1,33) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_opt_arg.txt b/test/prism/snapshots/seattlerb/block_opt_arg.txt
new file mode 100644
index 0000000000..64dc928f14
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_opt_arg.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,14))
+ ├── locals: [:b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
+ │ │ │ ├── operator_loc: (1,6)-(1,7) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,13)-(1,14) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_opt_splat.txt b/test/prism/snapshots/seattlerb/block_opt_splat.txt
new file mode 100644
index 0000000000..c18df9c27d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_opt_splat.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,12)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,13)-(1,14) = "c"
+ │ │ │ └── operator_loc: (1,12)-(1,13) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt b/test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt
new file mode 100644
index 0000000000..3806809d2b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(1,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,22))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,22))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,22))
+ ├── locals: [:b, :c, :d, :e]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,20))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,19))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
+ │ │ │ ├── operator_loc: (1,6)-(1,7) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,10)-(1,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,11)-(1,12) = "c"
+ │ │ │ └── operator_loc: (1,10)-(1,11) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,17)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :e
+ │ │ ├── name_loc: (1,18)-(1,19) = "e"
+ │ │ └── operator_loc: (1,17)-(1,18) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,19)-(1,20) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,21)-(1,22) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_optarg.txt b/test/prism/snapshots/seattlerb/block_optarg.txt
new file mode 100644
index 0000000000..5da99aec79
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_optarg.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,14))
+ ├── locals: [:b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "b"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ SymbolNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,9)-(1,10) = ":"
+ │ │ │ ├── value_loc: (1,10)-(1,11) = "c"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "c"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,13)-(1,14) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_paren_splat.txt b/test/prism/snapshots/seattlerb/block_paren_splat.txt
new file mode 100644
index 0000000000..ebd937904c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_paren_splat.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,15))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,15))
+ ├── locals: [:b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,13))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,12))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,9)-(1,11))
+ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ └── rparen_loc: (1,11)-(1,12) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,12)-(1,13) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,14)-(1,15) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_reg_optarg.txt b/test/prism/snapshots/seattlerb/block_reg_optarg.txt
new file mode 100644
index 0000000000..53c43603a7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_reg_optarg.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "c"
+ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ SymbolNode (location: (1,12)-(1,14))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,12)-(1,13) = ":"
+ │ │ │ ├── value_loc: (1,13)-(1,14) = "d"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "d"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_return.txt b/test/prism/snapshots/seattlerb/block_return.txt
new file mode 100644
index 0000000000..e91f5f2592
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_return.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(1,27))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,27))
+ └── body: (length: 1)
+ └── @ ReturnNode (location: (1,0)-(1,27))
+ ├── keyword_loc: (1,0)-(1,6) = "return"
+ └── arguments:
+ @ ArgumentsNode (location: (1,7)-(1,27))
+ ├── flags: ∅
+ └── arguments: (length: 1)
+ └── @ CallNode (location: (1,7)-(1,27))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (1,7)-(1,10) = "foo"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,11)-(1,14))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,11)-(1,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :arg
+ │ ├── message_loc: (1,11)-(1,14) = "arg"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,15)-(1,27))
+ ├── locals: [:bar]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,18)-(1,23))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,19)-(1,22))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,19)-(1,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :bar
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,18)-(1,19) = "|"
+ │ └── closing_loc: (1,22)-(1,23) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,15)-(1,17) = "do"
+ └── closing_loc: (1,24)-(1,27) = "end"
diff --git a/test/prism/snapshots/seattlerb/block_scope.txt b/test/prism/snapshots/seattlerb/block_scope.txt
new file mode 100644
index 0000000000..a21a28b993
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_scope.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,10))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,10))
+ ├── locals: [:b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,8))
+ │ ├── parameters: ∅
+ │ ├── locals: (length: 1)
+ │ │ └── @ BlockLocalVariableNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── name: :b
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,7)-(1,8) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,9)-(1,10) = "}"
diff --git a/test/prism/snapshots/seattlerb/block_splat_reg.txt b/test/prism/snapshots/seattlerb/block_splat_reg.txt
new file mode 100644
index 0000000000..617ff88622
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/block_splat_reg.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,13))
+ ├── locals: [:b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,5)-(1,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,6)-(1,7) = "b"
+ │ │ │ └── operator_loc: (1,5)-(1,6) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,10)-(1,11) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,12)-(1,13) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug169.txt b/test/prism/snapshots/seattlerb/bug169.txt
new file mode 100644
index 0000000000..e4fb47a6de
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug169.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (1,0)-(1,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,4))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,2)-(1,4))
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,3)-(1,4) = ")"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,5)-(1,7))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,5)-(1,6) = "{"
+ └── closing_loc: (1,6)-(1,7) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug179.txt b/test/prism/snapshots/seattlerb/bug179.txt
new file mode 100644
index 0000000000..d7695bc7a7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug179.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ RangeNode (location: (1,2)-(1,9))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ ParenthesesNode (location: (1,2)-(1,4))
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ │ └── closing_loc: (1,3)-(1,4) = ")"
+ │ ├── right:
+ │ │ @ NilNode (location: (1,6)-(1,9))
+ │ └── operator_loc: (1,4)-(1,6) = ".."
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bug190.txt b/test/prism/snapshots/seattlerb/bug190.txt
new file mode 100644
index 0000000000..b261a166cf
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug190.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ RegularExpressionNode (location: (1,0)-(1,6))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,3) = "%r'"
+ ├── content_loc: (1,3)-(1,5) = "\\'"
+ ├── closing_loc: (1,5)-(1,6) = "'"
+ └── unescaped: "'"
diff --git a/test/prism/snapshots/seattlerb/bug191.txt b/test/prism/snapshots/seattlerb/bug191.txt
new file mode 100644
index 0000000000..69835ab1d0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug191.txt
@@ -0,0 +1,87 @@
+@ ProgramNode (location: (1,0)-(3,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,9))
+ └── body: (length: 2)
+ ├── @ IfNode (location: (1,0)-(1,9))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (1,2)-(1,3) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,4)-(1,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ StringNode (location: (1,4)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,4)-(1,5) = "\""
+ │ │ ├── content_loc: (1,5)-(1,5) = ""
+ │ │ ├── closing_loc: (1,5)-(1,6) = "\""
+ │ │ └── unescaped: ""
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (1,6)-(1,9))
+ │ │ ├── else_keyword_loc: (1,6)-(1,7) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,8)-(1,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,8)-(1,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,8)-(1,9) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ └── @ IfNode (location: (3,0)-(3,9))
+ ├── if_keyword_loc: ∅
+ ├── predicate:
+ │ @ CallNode (location: (3,0)-(3,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (3,0)-(3,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: (3,2)-(3,3) = "?"
+ ├── statements:
+ │ @ StatementsNode (location: (3,4)-(3,6))
+ │ └── body: (length: 1)
+ │ └── @ StringNode (location: (3,4)-(3,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (3,4)-(3,5) = "'"
+ │ ├── content_loc: (3,5)-(3,5) = ""
+ │ ├── closing_loc: (3,5)-(3,6) = "'"
+ │ └── unescaped: ""
+ ├── consequent:
+ │ @ ElseNode (location: (3,6)-(3,9))
+ │ ├── else_keyword_loc: (3,6)-(3,7) = ":"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,8)-(3,9))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,8)-(3,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (3,8)-(3,9) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/bug202.txt b/test/prism/snapshots/seattlerb/bug202.txt
new file mode 100644
index 0000000000..377b53727e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug202.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(2,10))
+├── locals: [:测试]
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,10))
+ └── body: (length: 2)
+ ├── @ GlobalVariableWriteNode (location: (1,0)-(1,11))
+ │ ├── name: :$测试
+ │ ├── name_loc: (1,0)-(1,7) = "$测试"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,10)-(1,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,8)-(1,9) = "="
+ └── @ LocalVariableWriteNode (location: (2,0)-(2,10))
+ ├── name: :测试
+ ├── depth: 0
+ ├── name_loc: (2,0)-(2,6) = "测试"
+ ├── value:
+ │ @ IntegerNode (location: (2,9)-(2,10))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── operator_loc: (2,7)-(2,8) = "="
diff --git a/test/prism/snapshots/seattlerb/bug236.txt b/test/prism/snapshots/seattlerb/bug236.txt
new file mode 100644
index 0000000000..203a39a793
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug236.txt
@@ -0,0 +1,70 @@
+@ ProgramNode (location: (1,0)-(3,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,6))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :x
+ │ ├── message_loc: (1,0)-(1,1) = "x"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,1)-(1,7))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,2)-(1,6))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,3)-(1,5))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ ImplicitRestNode (location: (1,4)-(1,5))
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,2)-(1,3) = "|"
+ │ │ └── closing_loc: (1,5)-(1,6) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,1)-(1,2) = "{"
+ │ └── closing_loc: (1,6)-(1,7) = "}"
+ └── @ CallNode (location: (3,0)-(3,6))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (3,0)-(3,1) = "x"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (3,1)-(3,6))
+ ├── locals: [:a]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (3,2)-(3,5))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,3)-(3,4))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (3,3)-(3,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (3,2)-(3,3) = "|"
+ │ └── closing_loc: (3,4)-(3,5) = "|"
+ ├── body: ∅
+ ├── opening_loc: (3,1)-(3,2) = "{"
+ └── closing_loc: (3,5)-(3,6) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug290.txt b/test/prism/snapshots/seattlerb/bug290.txt
new file mode 100644
index 0000000000..4f1e673c4b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug290.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(3,3))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (2,2)-(2,5))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,2)-(2,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (2,2)-(2,5) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/bug_187.txt b/test/prism/snapshots/seattlerb/bug_187.txt
new file mode 100644
index 0000000000..ae72675e5c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_187.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :private
+ ├── message_loc: (1,0)-(1,7) = "private"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,8)-(3,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ DefNode (location: (1,8)-(3,3))
+ │ ├── name: :f
+ │ ├── name_loc: (1,12)-(1,13) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,0)-(2,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,0)-(2,10))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (2,0)-(2,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (2,0)-(2,1) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (2,1)-(2,2) = "."
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (2,2)-(2,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (2,4)-(2,10))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (2,4)-(2,6) = "do"
+ │ │ └── closing_loc: (2,7)-(2,10) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,8)-(1,11) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bug_215.txt b/test/prism/snapshots/seattlerb/bug_215.txt
new file mode 100644
index 0000000000..de7716335e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_215.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ UndefNode (location: (1,0)-(1,13))
+ ├── names: (length: 1)
+ │ └── @ SymbolNode (location: (1,6)-(1,13))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,6)-(1,9) = "%s("
+ │ ├── value_loc: (1,9)-(1,12) = "foo"
+ │ ├── closing_loc: (1,12)-(1,13) = ")"
+ │ └── unescaped: "foo"
+ └── keyword_loc: (1,0)-(1,5) = "undef"
diff --git a/test/prism/snapshots/seattlerb/bug_249.txt b/test/prism/snapshots/seattlerb/bug_249.txt
new file mode 100644
index 0000000000..569bea14c5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_249.txt
@@ -0,0 +1,86 @@
+@ ProgramNode (location: (1,0)-(4,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,28))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(4,28))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :mount
+ ├── message_loc: (1,0)-(1,5) = "mount"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,6)-(4,28))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (1,6)-(4,9))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ ParenthesesNode (location: (1,6)-(4,5))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (1,7)-(4,4))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,7)-(4,4))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ ConstantReadNode (location: (1,7)-(1,12))
+ │ │ │ │ │ └── name: :Class
+ │ │ │ │ ├── call_operator_loc: (1,12)-(1,13) = "."
+ │ │ │ │ ├── name: :new
+ │ │ │ │ ├── message_loc: (1,13)-(1,16) = "new"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (1,17)-(4,4))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (2,0)-(3,3))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ DefNode (location: (2,0)-(3,3))
+ │ │ │ │ │ ├── name: :initialize
+ │ │ │ │ │ ├── name_loc: (2,4)-(2,14) = "initialize"
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── def_keyword_loc: (2,0)-(2,3) = "def"
+ │ │ │ │ │ ├── operator_loc: ∅
+ │ │ │ │ │ ├── lparen_loc: ∅
+ │ │ │ │ │ ├── rparen_loc: ∅
+ │ │ │ │ │ ├── equal_loc: ∅
+ │ │ │ │ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ │ │ │ │ ├── opening_loc: (1,17)-(1,19) = "do"
+ │ │ │ │ └── closing_loc: (4,1)-(4,4) = "end"
+ │ │ │ ├── opening_loc: (1,6)-(1,7) = "("
+ │ │ │ └── closing_loc: (4,4)-(4,5) = ")"
+ │ │ ├── call_operator_loc: (4,5)-(4,6) = "."
+ │ │ ├── name: :new
+ │ │ ├── message_loc: (4,6)-(4,9) = "new"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ KeywordHashNode (location: (4,11)-(4,28))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (4,11)-(4,28))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (4,11)-(4,14))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (4,11)-(4,12) = ":"
+ │ │ ├── value_loc: (4,12)-(4,14) = "at"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "at"
+ │ ├── value:
+ │ │ @ StringNode (location: (4,18)-(4,28))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (4,18)-(4,19) = "'"
+ │ │ ├── content_loc: (4,19)-(4,27) = "endpoint"
+ │ │ ├── closing_loc: (4,27)-(4,28) = "'"
+ │ │ └── unescaped: "endpoint"
+ │ └── operator_loc: (4,15)-(4,17) = "=>"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bug_and.txt b/test/prism/snapshots/seattlerb/bug_and.txt
new file mode 100644
index 0000000000..3daf505e5f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_and.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(4,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,11))
+ └── body: (length: 2)
+ ├── @ AndNode (location: (1,0)-(2,4))
+ │ ├── left:
+ │ │ @ TrueNode (location: (1,0)-(1,4))
+ │ ├── right:
+ │ │ @ TrueNode (location: (2,0)-(2,4))
+ │ └── operator_loc: (1,5)-(1,8) = "and"
+ └── @ AndNode (location: (4,0)-(4,11))
+ ├── left:
+ │ @ TrueNode (location: (4,0)-(4,4))
+ ├── right:
+ │ @ ArrayNode (location: (4,9)-(4,11))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (4,9)-(4,10) = "["
+ │ └── closing_loc: (4,10)-(4,11) = "]"
+ └── operator_loc: (4,5)-(4,8) = "and"
diff --git a/test/prism/snapshots/seattlerb/bug_args__19.txt b/test/prism/snapshots/seattlerb/bug_args__19.txt
new file mode 100644
index 0000000000..f451bd0172
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_args__19.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,16))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,11))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ └── rparen_loc: (1,10)-(1,11) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,13)-(1,14))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,13)-(1,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :d
+ │ ├── message_loc: (1,13)-(1,14) = "d"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,15)-(1,16) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug_args_masgn.txt b/test/prism/snapshots/seattlerb/bug_args_masgn.txt
new file mode 100644
index 0000000000..297979c182
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_args_masgn.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ MultiTargetNode (location: (1,5)-(1,11))
+ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :a
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :b
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ │ └── rparen_loc: (1,10)-(1,11) = ")"
+ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug_args_masgn2.txt b/test/prism/snapshots/seattlerb/bug_args_masgn2.txt
new file mode 100644
index 0000000000..6bec9187b3
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_args_masgn2.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(1,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,22))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,22))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,22))
+ ├── locals: [:a, :b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,20))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,19))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ MultiTargetNode (location: (1,5)-(1,16))
+ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ ├── @ MultiTargetNode (location: (1,6)-(1,12))
+ │ │ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,7)-(1,8))
+ │ │ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ │ │ └── name: :a
+ │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,10)-(1,11))
+ │ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ │ └── name: :b
+ │ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ │ │ ├── lparen_loc: (1,6)-(1,7) = "("
+ │ │ │ │ │ │ └── rparen_loc: (1,11)-(1,12) = ")"
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :c
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ │ └── rparen_loc: (1,15)-(1,16) = ")"
+ │ │ │ └── @ RequiredParameterNode (location: (1,18)-(1,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,19)-(1,20) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,21)-(1,22) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt b/test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt
new file mode 100644
index 0000000000..42a060d02a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,19))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,19))
+ ├── locals: [:k, :v, :i]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,17))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,16))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,16))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ MultiTargetNode (location: (1,6)-(1,12))
+ │ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,7)-(1,8))
+ │ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ │ └── name: :k
+ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,10)-(1,11))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :v
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ │ ├── lparen_loc: (1,6)-(1,7) = "("
+ │ │ │ │ │ └── rparen_loc: (1,11)-(1,12) = ")"
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :i
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ └── rparen_loc: (1,15)-(1,16) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,16)-(1,17) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,18)-(1,19) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt b/test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt
new file mode 100644
index 0000000000..53d6f9220b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt
@@ -0,0 +1,110 @@
+@ ProgramNode (location: (1,6)-(11,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,6)-(11,9))
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,6)-(3,9))
+ │ ├── name: :f
+ │ ├── name_loc: (1,10)-(1,11) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,8)-(2,17))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,8)-(2,17))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :g
+ │ │ ├── message_loc: (2,8)-(2,9) = "g"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (2,10)-(2,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ ParenthesesNode (location: (2,10)-(2,14))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (2,12)-(2,13))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (2,12)-(2,13))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── opening_loc: (2,10)-(2,11) = "("
+ │ │ │ │ └── closing_loc: (2,13)-(2,14) = ")"
+ │ │ │ └── @ IntegerNode (location: (2,16)-(2,17))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,6)-(1,9) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,6)-(3,9) = "end"
+ ├── @ DefNode (location: (6,6)-(8,9))
+ │ ├── name: :f
+ │ ├── name_loc: (6,10)-(6,11) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,8)-(7,16))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (7,8)-(7,16))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :g
+ │ │ ├── message_loc: (7,8)-(7,9) = "g"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,10)-(7,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ ParenthesesNode (location: (7,10)-(7,13))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (7,11)-(7,12))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (7,11)-(7,12))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── opening_loc: (7,10)-(7,11) = "("
+ │ │ │ │ └── closing_loc: (7,12)-(7,13) = ")"
+ │ │ │ └── @ IntegerNode (location: (7,15)-(7,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (6,6)-(6,9) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (6,11)-(6,12) = "("
+ │ ├── rparen_loc: (6,12)-(6,13) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (8,6)-(8,9) = "end"
+ └── @ CallNode (location: (11,0)-(11,9))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :g
+ ├── message_loc: (11,0)-(11,1) = "g"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (11,2)-(11,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ ParenthesesNode (location: (11,2)-(11,6))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (11,4)-(11,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (11,4)-(11,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (11,2)-(11,3) = "("
+ │ │ └── closing_loc: (11,5)-(11,6) = ")"
+ │ └── @ IntegerNode (location: (11,8)-(11,9))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bug_case_when_regexp.txt b/test/prism/snapshots/seattlerb/bug_case_when_regexp.txt
new file mode 100644
index 0000000000..0cc1ca05e1
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_case_when_regexp.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,26))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,26))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,26))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "x"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "x"
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,9)-(1,22))
+ │ ├── keyword_loc: (1,9)-(1,13) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ RegularExpressionNode (location: (1,14)-(1,17))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,14)-(1,15) = "/"
+ │ │ ├── content_loc: (1,15)-(1,16) = "x"
+ │ │ ├── closing_loc: (1,16)-(1,17) = "/"
+ │ │ └── unescaped: "x"
+ │ ├── then_keyword_loc: (1,18)-(1,22) = "then"
+ │ └── statements: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,23)-(1,26) = "end"
diff --git a/test/prism/snapshots/seattlerb/bug_comma.txt b/test/prism/snapshots/seattlerb/bug_comma.txt
new file mode 100644
index 0000000000..af886999b5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_comma.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,24))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (1,3)-(1,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :test
+ │ ├── message_loc: (1,3)-(1,7) = "test"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (1,8)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,8)-(1,9) = "?"
+ │ │ │ ├── content_loc: (1,9)-(1,10) = "d"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "d"
+ │ │ └── @ CallNode (location: (1,12)-(1,15))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :dir
+ │ │ ├── message_loc: (1,12)-(1,15) = "dir"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: (1,16)-(1,20) = "then"
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,21)-(1,24) = "end"
diff --git a/test/prism/snapshots/seattlerb/bug_cond_pct.txt b/test/prism/snapshots/seattlerb/bug_cond_pct.txt
new file mode 100644
index 0000000000..cbf3bc3ef0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_cond_pct.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(1,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,28))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,28))
+ ├── predicate: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,6)-(1,23))
+ │ ├── keyword_loc: (1,6)-(1,10) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ RegularExpressionNode (location: (1,11)-(1,23))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,11)-(1,14) = "%r%"
+ │ │ ├── content_loc: (1,14)-(1,22) = "blahblah"
+ │ │ ├── closing_loc: (1,22)-(1,23) = "%"
+ │ │ └── unescaped: "blahblah"
+ │ ├── then_keyword_loc: ∅
+ │ └── statements: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,25)-(1,28) = "end"
diff --git a/test/prism/snapshots/seattlerb/bug_hash_args.txt b/test/prism/snapshots/seattlerb/bug_hash_args.txt
new file mode 100644
index 0000000000..6f17e88714
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_hash_args.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,19))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (1,0)-(1,3) = "foo"
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,18))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ SymbolNode (location: (1,4)-(1,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,4)-(1,5) = ":"
+ │ │ ├── value_loc: (1,5)-(1,8) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ └── @ KeywordHashNode (location: (1,10)-(1,18))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,10)-(1,18))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,10)-(1,14))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,10)-(1,13) = "baz"
+ │ │ ├── closing_loc: (1,13)-(1,14) = ":"
+ │ │ └── unescaped: "baz"
+ │ ├── value:
+ │ │ @ NilNode (location: (1,15)-(1,18))
+ │ └── operator_loc: ∅
+ ├── closing_loc: (1,18)-(1,19) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt b/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt
new file mode 100644
index 0000000000..e7256b337b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,20))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (1,0)-(1,3) = "foo"
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,18))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ SymbolNode (location: (1,4)-(1,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,4)-(1,5) = ":"
+ │ │ ├── value_loc: (1,5)-(1,8) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ └── @ KeywordHashNode (location: (1,10)-(1,18))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,10)-(1,18))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,10)-(1,14))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,10)-(1,13) = "baz"
+ │ │ ├── closing_loc: (1,13)-(1,14) = ":"
+ │ │ └── unescaped: "baz"
+ │ ├── value:
+ │ │ @ NilNode (location: (1,15)-(1,18))
+ │ └── operator_loc: ∅
+ ├── closing_loc: (1,19)-(1,20) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bug_hash_interp_array.txt b/test/prism/snapshots/seattlerb/bug_hash_interp_array.txt
new file mode 100644
index 0000000000..433fb02411
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_hash_interp_array.txt
@@ -0,0 +1,26 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,0)-(1,13))
+ ├── opening_loc: (1,0)-(1,1) = "{"
+ ├── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,11))
+ │ ├── key:
+ │ │ @ InterpolatedSymbolNode (location: (1,2)-(1,8))
+ │ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ │ ├── parts: (length: 1)
+ │ │ │ └── @ EmbeddedStatementsNode (location: (1,3)-(1,6))
+ │ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (1,5)-(1,6) = "}"
+ │ │ └── closing_loc: (1,6)-(1,8) = "\":"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (1,9)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 0)
+ │ │ ├── opening_loc: (1,9)-(1,10) = "["
+ │ │ └── closing_loc: (1,10)-(1,11) = "]"
+ │ └── operator_loc: ∅
+ └── closing_loc: (1,12)-(1,13) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug_masgn_right.txt b/test/prism/snapshots/seattlerb/bug_masgn_right.txt
new file mode 100644
index 0000000000..b4c75c4607
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_masgn_right.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,14))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :b
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,13)-(1,14) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/bug_not_parens.txt b/test/prism/snapshots/seattlerb/bug_not_parens.txt
new file mode 100644
index 0000000000..9e4a416d4a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_not_parens.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,4)-(1,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,4)-(1,5) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,3) = "not"
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments: ∅
+ ├── closing_loc: (1,5)-(1,6) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/bug_op_asgn_rescue.txt b/test/prism/snapshots/seattlerb/bug_op_asgn_rescue.txt
new file mode 100644
index 0000000000..33016f32f8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/bug_op_asgn_rescue.txt
@@ -0,0 +1,26 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ LocalVariableOrWriteNode (location: (1,0)-(1,18))
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── operator_loc: (1,2)-(1,5) = "||="
+ ├── value:
+ │ @ RescueModifierNode (location: (1,6)-(1,18))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,6)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,6)-(1,7) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,8)-(1,14) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (1,15)-(1,18))
+ ├── name: :a
+ └── depth: 0
diff --git a/test/prism/snapshots/seattlerb/call_and.txt b/test/prism/snapshots/seattlerb/call_and.txt
new file mode 100644
index 0000000000..d3e88b3f9e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_and.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :&
+ ├── message_loc: (1,2)-(1,3) = "&"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc.txt b/test/prism/snapshots/seattlerb/call_arg_assoc.txt
new file mode 100644
index 0000000000..27c19fd339
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_arg_assoc.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,10))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,2)-(1,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ KeywordHashNode (location: (1,5)-(1,9))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,5)-(1,9))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: (1,6)-(1,8) = "=>"
+ ├── closing_loc: (1,9)-(1,10) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt b/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt
new file mode 100644
index 0000000000..0193eb1dfc
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,15))
+ │ ├── flags: contains_keyword_splat
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,2)-(1,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ KeywordHashNode (location: (1,5)-(1,15))
+ │ ├── flags: ∅
+ │ └── elements: (length: 2)
+ │ ├── @ AssocNode (location: (1,5)-(1,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,5)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,5)-(1,7) = "kw"
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = ":"
+ │ │ │ └── unescaped: "kw"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: ∅
+ │ └── @ AssocSplatNode (location: (1,12)-(1,15))
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,14)-(1,15))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: (1,12)-(1,14) = "**"
+ ├── closing_loc: (1,15)-(1,16) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt b/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt
new file mode 100644
index 0000000000..91c7725525
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,8))
+ │ ├── flags: contains_keyword_splat
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (1,2)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,2)-(1,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ KeywordHashNode (location: (1,5)-(1,8))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocSplatNode (location: (1,5)-(1,8))
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,5)-(1,7) = "**"
+ ├── closing_loc: (1,8)-(1,9) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt b/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt
new file mode 100644
index 0000000000..2d6f81c818
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt
@@ -0,0 +1,106 @@
+@ ProgramNode (location: (1,0)-(5,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,8))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :x
+ │ ├── message_loc: (1,0)-(1,1) = "x"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,2)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,2)-(1,11))
+ │ │ ├── key:
+ │ │ │ @ InterpolatedSymbolNode (location: (1,2)-(1,9))
+ │ │ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ │ │ ├── parts: (length: 1)
+ │ │ │ │ └── @ EmbeddedStatementsNode (location: (1,3)-(1,7))
+ │ │ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (1,5)-(1,6))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :k
+ │ │ │ │ │ ├── message_loc: (1,5)-(1,6) = "k"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── closing_loc: (1,6)-(1,7) = "}"
+ │ │ │ └── closing_loc: (1,7)-(1,9) = "\":"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :x
+ │ ├── message_loc: (3,0)-(3,1) = "x"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,2)-(3,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (3,2)-(3,8))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (3,2)-(3,8))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (3,2)-(3,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,2)-(3,3) = "\""
+ │ │ │ ├── value_loc: (3,3)-(3,4) = "k"
+ │ │ │ ├── closing_loc: (3,4)-(3,6) = "\":"
+ │ │ │ └── unescaped: "k"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,6)-(3,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,8))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (5,0)-(5,1) = "x"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (5,2)-(5,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (5,2)-(5,8))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (5,2)-(5,8))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (5,2)-(5,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,2)-(5,3) = "'"
+ │ │ ├── value_loc: (5,3)-(5,4) = "k"
+ │ │ ├── closing_loc: (5,4)-(5,6) = "':"
+ │ │ └── unescaped: "k"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (5,6)-(5,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ └── operator_loc: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt
new file mode 100644
index 0000000000..312a1981a0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,2)-(1,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ KeywordHashNode (location: (1,5)-(1,9))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,5)-(1,9))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: (1,6)-(1,8) = "=>"
+ ├── closing_loc: (1,10)-(1,11) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_args_command.txt b/test/prism/snapshots/seattlerb/call_args_command.txt
new file mode 100644
index 0000000000..f4a55ff58c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_args_command.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :b
+ ├── message_loc: (1,2)-(1,3) = "b"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,4)-(1,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,4)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (1,4)-(1,5) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,5)-(1,6) = "."
+ │ ├── name: :d
+ │ ├── message_loc: (1,6)-(1,7) = "d"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,8)-(1,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_array_arg.txt b/test/prism/snapshots/seattlerb/call_array_arg.txt
new file mode 100644
index 0000000000..95d2f4859d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_array_arg.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :==
+ ├── message_loc: (1,2)-(1,4) = "=="
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ArrayNode (location: (1,5)-(1,13))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,6)-(1,7) = ":"
+ │ │ │ ├── value_loc: (1,7)-(1,8) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── @ SymbolNode (location: (1,10)-(1,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,10)-(1,11) = ":"
+ │ │ ├── value_loc: (1,11)-(1,12) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── opening_loc: (1,5)-(1,6) = "["
+ │ └── closing_loc: (1,12)-(1,13) = "]"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_array_block_call.txt b/test/prism/snapshots/seattlerb/call_array_block_call.txt
new file mode 100644
index 0000000000..e02740e7f5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_array_block_call.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,19))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,19))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ArrayNode (location: (1,2)-(1,19))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ NilNode (location: (1,4)-(1,7))
+ │ │ └── @ CallNode (location: (1,9)-(1,17))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,9)-(1,10) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,11)-(1,17))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (1,11)-(1,13) = "do"
+ │ │ └── closing_loc: (1,14)-(1,17) = "end"
+ │ ├── opening_loc: (1,2)-(1,3) = "["
+ │ └── closing_loc: (1,18)-(1,19) = "]"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt b/test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt
new file mode 100644
index 0000000000..c6aa722812
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(2,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ArrayNode (location: (1,2)-(1,11))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ LambdaNode (location: (1,3)-(1,10))
+ │ │ ├── locals: []
+ │ │ ├── operator_loc: (1,3)-(1,5) = "->"
+ │ │ ├── opening_loc: (1,8)-(1,9) = "{"
+ │ │ ├── closing_loc: (1,9)-(1,10) = "}"
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (1,5)-(1,7))
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ │ │ └── closing_loc: (1,6)-(1,7) = ")"
+ │ │ └── body: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "["
+ │ └── closing_loc: (1,10)-(1,11) = "]"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,12)-(2,3))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,12)-(1,14) = "do"
+ └── closing_loc: (2,0)-(2,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt b/test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt
new file mode 100644
index 0000000000..091e21c00a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt
@@ -0,0 +1,45 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,15))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ArrayNode (location: (1,2)-(1,15))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (1,3)-(1,5))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,3)-(1,4) = ":"
+ │ │ │ ├── value_loc: (1,4)-(1,5) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── @ KeywordHashNode (location: (1,7)-(1,14))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,7)-(1,14))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,7)-(1,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,7)-(1,8) = ":"
+ │ │ │ ├── value_loc: (1,8)-(1,9) = "c"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "c"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (1,10)-(1,12) = "=>"
+ │ ├── opening_loc: (1,2)-(1,3) = "["
+ │ └── closing_loc: (1,14)-(1,15) = "]"
+ ├── closing_loc: (1,15)-(1,16) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_assoc.txt b/test/prism/snapshots/seattlerb/call_assoc.txt
new file mode 100644
index 0000000000..438c256553
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_assoc.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,2)-(1,6))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,6))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (1,2)-(1,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: (1,3)-(1,5) = "=>"
+ ├── closing_loc: (1,6)-(1,7) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_assoc_new.txt b/test/prism/snapshots/seattlerb/call_assoc_new.txt
new file mode 100644
index 0000000000..b4d7e0bf83
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_assoc_new.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,2)-(1,5))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,5))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,2)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,2)-(1,3) = "a"
+ │ │ ├── closing_loc: (1,3)-(1,4) = ":"
+ │ │ └── unescaped: "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: ∅
+ ├── closing_loc: (1,5)-(1,6) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt b/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt
new file mode 100644
index 0000000000..9587e2e074
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(5,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(5,4))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(5,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,2)-(5,3))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(5,3))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,2)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,2)-(1,3) = "b"
+ │ │ ├── closing_loc: (1,3)-(1,4) = ":"
+ │ │ └── unescaped: "b"
+ │ ├── value:
+ │ │ @ IfNode (location: (1,5)-(5,3))
+ │ │ ├── if_keyword_loc: (1,5)-(1,7) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ SymbolNode (location: (1,8)-(1,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,8)-(1,9) = ":"
+ │ │ │ ├── value_loc: (1,9)-(1,10) = "c"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "c"
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (2,0)-(2,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (2,0)-(2,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── consequent:
+ │ │ │ @ ElseNode (location: (3,0)-(5,3))
+ │ │ │ ├── else_keyword_loc: (3,0)-(3,4) = "else"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (4,0)-(4,1))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (4,0)-(4,1))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ └── operator_loc: ∅
+ ├── closing_loc: (5,3)-(5,4) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt
new file mode 100644
index 0000000000..8d0b285172
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,2)-(1,6))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,6))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (1,2)-(1,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (1,3)-(1,5) = "=>"
+ ├── closing_loc: (1,7)-(1,8) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_bang_command_call.txt b/test/prism/snapshots/seattlerb/call_bang_command_call.txt
new file mode 100644
index 0000000000..5e4e10d953
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_bang_command_call.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,2)-(1,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,2)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,2)-(1,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,1) = "!"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_bang_squiggle.txt b/test/prism/snapshots/seattlerb/call_bang_squiggle.txt
new file mode 100644
index 0000000000..bf11bc0136
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_bang_squiggle.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :!~
+ ├── message_loc: (1,2)-(1,4) = "!~"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_begin_call_block_call.txt b/test/prism/snapshots/seattlerb/call_begin_call_block_call.txt
new file mode 100644
index 0000000000..1aa994c8e6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_begin_call_block_call.txt
@@ -0,0 +1,53 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(3,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ BeginNode (location: (1,2)-(3,3))
+ │ ├── begin_keyword_loc: (1,2)-(1,7) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,0)-(2,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,0)-(2,10))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (2,0)-(2,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (2,0)-(2,1) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (2,1)-(2,2) = "."
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (2,2)-(2,3) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (2,4)-(2,10))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (2,4)-(2,6) = "do"
+ │ │ └── closing_loc: (2,7)-(2,10) = "end"
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_block_arg_named.txt b/test/prism/snapshots/seattlerb/call_block_arg_named.txt
new file mode 100644
index 0000000000..f87c29cf2e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_block_arg_named.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (1,0)-(1,1) = "x"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments: ∅
+ ├── closing_loc: (1,6)-(1,7) = ")"
+ └── block:
+ @ BlockArgumentNode (location: (1,2)-(1,6))
+ ├── expression:
+ │ @ CallNode (location: (1,3)-(1,6))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :blk
+ │ ├── message_loc: (1,3)-(1,6) = "blk"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (1,2)-(1,3) = "&"
diff --git a/test/prism/snapshots/seattlerb/call_carat.txt b/test/prism/snapshots/seattlerb/call_carat.txt
new file mode 100644
index 0000000000..856e9a7847
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_carat.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :^
+ ├── message_loc: (1,2)-(1,3) = "^"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_colon2.txt b/test/prism/snapshots/seattlerb/call_colon2.txt
new file mode 100644
index 0000000000..98bfc63126
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_colon2.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ ConstantReadNode (location: (1,0)-(1,1))
+ │ └── name: :A
+ ├── call_operator_loc: (1,1)-(1,3) = "::"
+ ├── name: :b
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_colon_parens.txt b/test/prism/snapshots/seattlerb/call_colon_parens.txt
new file mode 100644
index 0000000000..6d10171a2b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_colon_parens.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: (1,1)-(1,3) = "::"
+ ├── name: :call
+ ├── message_loc: ∅
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments: ∅
+ ├── closing_loc: (1,4)-(1,5) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_div.txt b/test/prism/snapshots/seattlerb/call_div.txt
new file mode 100644
index 0000000000..ba62fb87bd
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_div.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :/
+ ├── message_loc: (1,2)-(1,3) = "/"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_dot_parens.txt b/test/prism/snapshots/seattlerb/call_dot_parens.txt
new file mode 100644
index 0000000000..c9b7084699
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_dot_parens.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :call
+ ├── message_loc: ∅
+ ├── opening_loc: (1,2)-(1,3) = "("
+ ├── arguments: ∅
+ ├── closing_loc: (1,3)-(1,4) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_env.txt b/test/prism/snapshots/seattlerb/call_env.txt
new file mode 100644
index 0000000000..fd1f95388e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_env.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :happy
+ ├── message_loc: (1,2)-(1,7) = "happy"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_eq3.txt b/test/prism/snapshots/seattlerb/call_eq3.txt
new file mode 100644
index 0000000000..e636e15725
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_eq3.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :===
+ ├── message_loc: (1,2)-(1,5) = "==="
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_gt.txt b/test/prism/snapshots/seattlerb/call_gt.txt
new file mode 100644
index 0000000000..a6f19e5adf
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_gt.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :>
+ ├── message_loc: (1,2)-(1,3) = ">"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_kwsplat.txt b/test/prism/snapshots/seattlerb/call_kwsplat.txt
new file mode 100644
index 0000000000..4199e97a44
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_kwsplat.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,5))
+ │ ├── flags: contains_keyword_splat
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,2)-(1,5))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocSplatNode (location: (1,2)-(1,5))
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,2)-(1,4) = "**"
+ ├── closing_loc: (1,5)-(1,6) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_leading_dots.txt b/test/prism/snapshots/seattlerb/call_leading_dots.txt
new file mode 100644
index 0000000000..e8435d7e7a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_leading_dots.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(3,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,2))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,2))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(2,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (2,0)-(2,1) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (2,1)-(2,2) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (3,0)-(3,1) = "."
+ ├── name: :c
+ ├── message_loc: (3,1)-(3,2) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_leading_dots_comment.txt b/test/prism/snapshots/seattlerb/call_leading_dots_comment.txt
new file mode 100644
index 0000000000..e5dfb72372
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_leading_dots_comment.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(4,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,2))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(4,2))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(2,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (2,0)-(2,1) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (2,1)-(2,2) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (4,0)-(4,1) = "."
+ ├── name: :d
+ ├── message_loc: (4,1)-(4,2) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_lt.txt b/test/prism/snapshots/seattlerb/call_lt.txt
new file mode 100644
index 0000000000..14f50585d9
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_lt.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :<
+ ├── message_loc: (1,2)-(1,3) = "<"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_lte.txt b/test/prism/snapshots/seattlerb/call_lte.txt
new file mode 100644
index 0000000000..665a99d60a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_lte.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :<=
+ ├── message_loc: (1,2)-(1,4) = "<="
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_not.txt b/test/prism/snapshots/seattlerb/call_not.txt
new file mode 100644
index 0000000000..86c6892303
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_not.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,4)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 42
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,3) = "not"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_pipe.txt b/test/prism/snapshots/seattlerb/call_pipe.txt
new file mode 100644
index 0000000000..855e986ef6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_pipe.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :|
+ ├── message_loc: (1,2)-(1,3) = "|"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_rshift.txt b/test/prism/snapshots/seattlerb/call_rshift.txt
new file mode 100644
index 0000000000..26e593db18
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_rshift.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :>>
+ ├── message_loc: (1,2)-(1,4) = ">>"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_self_brackets.txt b/test/prism/snapshots/seattlerb/call_self_brackets.txt
new file mode 100644
index 0000000000..16ca69b5c2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_self_brackets.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ignore_visibility
+ ├── receiver:
+ │ @ SelfNode (location: (1,0)-(1,4))
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,4)-(1,7) = "[1]"
+ ├── opening_loc: (1,4)-(1,5) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (1,6)-(1,7) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_spaceship.txt b/test/prism/snapshots/seattlerb/call_spaceship.txt
new file mode 100644
index 0000000000..8d43c3f971
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_spaceship.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :<=>
+ ├── message_loc: (1,2)-(1,5) = "<=>"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_stabby_do_end_with_block.txt b/test/prism/snapshots/seattlerb/call_stabby_do_end_with_block.txt
new file mode 100644
index 0000000000..242db9e9cb
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_stabby_do_end_with_block.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,22))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,22))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LambdaNode (location: (1,2)-(1,13))
+ │ ├── locals: []
+ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ ├── opening_loc: (1,5)-(1,7) = "do"
+ │ ├── closing_loc: (1,10)-(1,13) = "end"
+ │ ├── parameters: ∅
+ │ └── body:
+ │ @ StatementsNode (location: (1,8)-(1,9))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,8)-(1,9))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,14)-(1,22))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,17)-(1,18))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,17)-(1,18))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── opening_loc: (1,14)-(1,16) = "do"
+ └── closing_loc: (1,19)-(1,22) = "end"
diff --git a/test/prism/snapshots/seattlerb/call_stabby_with_braces_block.txt b/test/prism/snapshots/seattlerb/call_stabby_with_braces_block.txt
new file mode 100644
index 0000000000..7c3ab8dad8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_stabby_with_braces_block.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,19))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LambdaNode (location: (1,2)-(1,10))
+ │ ├── locals: []
+ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ ├── opening_loc: (1,5)-(1,6) = "{"
+ │ ├── closing_loc: (1,9)-(1,10) = "}"
+ │ ├── parameters: ∅
+ │ └── body:
+ │ @ StatementsNode (location: (1,7)-(1,8))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,11)-(1,19))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,14)-(1,15))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,14)-(1,15))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── opening_loc: (1,11)-(1,13) = "do"
+ └── closing_loc: (1,16)-(1,19) = "end"
diff --git a/test/prism/snapshots/seattlerb/call_star.txt b/test/prism/snapshots/seattlerb/call_star.txt
new file mode 100644
index 0000000000..49aee1672c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_star.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :*
+ ├── message_loc: (1,2)-(1,3) = "*"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_star2.txt b/test/prism/snapshots/seattlerb/call_star2.txt
new file mode 100644
index 0000000000..cc2532cc7c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_star2.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :**
+ ├── message_loc: (1,2)-(1,4) = "**"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_trailing_comma.txt
new file mode 100644
index 0000000000..fe28a3ad3e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_trailing_comma.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,2)-(1,3))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (1,4)-(1,5) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_trailing_dots.txt b/test/prism/snapshots/seattlerb/call_trailing_dots.txt
new file mode 100644
index 0000000000..b0e23eb27b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_trailing_dots.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(3,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,1))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,1))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(2,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,1)-(1,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (2,0)-(2,1) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (2,1)-(2,2) = "."
+ ├── name: :c
+ ├── message_loc: (3,0)-(3,1) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/call_unary_bang.txt b/test/prism/snapshots/seattlerb/call_unary_bang.txt
new file mode 100644
index 0000000000..782cc83b10
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/call_unary_bang.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,2))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,2))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,1)-(1,2))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,1) = "!"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/case_in.txt b/test/prism/snapshots/seattlerb/case_in.txt
new file mode 100644
index 0000000000..950d66647e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in.txt
@@ -0,0 +1,976 @@
+@ ProgramNode (location: (1,0)-(111,3))
+├── locals: [:b, :_, :lhs, :x, :rhs, :c, :e]
+└── statements:
+ @ StatementsNode (location: (1,0)-(111,3))
+ └── body: (length: 28)
+ ├── @ CaseMatchNode (location: (1,0)-(3,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (2,0)-(2,8))
+ │ │ ├── pattern:
+ │ │ │ @ HashPatternNode (location: (2,4)-(2,8))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ AssocNode (location: (2,4)-(2,8))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (2,4)-(2,8))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (2,4)-(2,5) = "\""
+ │ │ │ │ │ ├── value_loc: (2,5)-(2,6) = "b"
+ │ │ │ │ │ ├── closing_loc: (2,6)-(2,8) = "\":"
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ ImplicitNode (location: (2,5)-(2,6))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ LocalVariableTargetNode (location: (2,5)-(2,6))
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ CaseMatchNode (location: (5,0)-(7,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (5,5)-(5,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,5)-(5,6) = ":"
+ │ │ ├── value_loc: (5,6)-(5,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (6,0)-(6,10))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayNode (location: (6,3)-(6,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ ├── @ SymbolNode (location: (6,6)-(6,7))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (6,6)-(6,7) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ └── @ SymbolNode (location: (6,8)-(6,9))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (6,8)-(6,9) = "b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── opening_loc: (6,3)-(6,6) = "%I["
+ │ │ │ └── closing_loc: (6,9)-(6,10) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (6,0)-(6,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (5,0)-(5,4) = "case"
+ │ └── end_keyword_loc: (7,0)-(7,3) = "end"
+ ├── @ CaseMatchNode (location: (9,0)-(11,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (9,5)-(9,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (9,5)-(9,6) = ":"
+ │ │ ├── value_loc: (9,6)-(9,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (10,0)-(10,10))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayNode (location: (10,3)-(10,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (10,6)-(10,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (10,6)-(10,7) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ └── @ StringNode (location: (10,8)-(10,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (10,8)-(10,9) = "b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── opening_loc: (10,3)-(10,6) = "%W["
+ │ │ │ └── closing_loc: (10,9)-(10,10) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (10,0)-(10,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (9,0)-(9,4) = "case"
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ CaseMatchNode (location: (13,0)-(15,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (13,5)-(13,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (13,5)-(13,6) = ":"
+ │ │ ├── value_loc: (13,6)-(13,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (14,0)-(14,10))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayNode (location: (14,3)-(14,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ ├── @ SymbolNode (location: (14,6)-(14,7))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (14,6)-(14,7) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ └── @ SymbolNode (location: (14,8)-(14,9))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (14,8)-(14,9) = "b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── opening_loc: (14,3)-(14,6) = "%i["
+ │ │ │ └── closing_loc: (14,9)-(14,10) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (14,0)-(14,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (13,0)-(13,4) = "case"
+ │ └── end_keyword_loc: (15,0)-(15,3) = "end"
+ ├── @ CaseMatchNode (location: (17,0)-(19,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (17,5)-(17,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (17,5)-(17,6) = ":"
+ │ │ ├── value_loc: (17,6)-(17,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (18,0)-(18,10))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayNode (location: (18,3)-(18,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (18,6)-(18,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (18,6)-(18,7) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ └── @ StringNode (location: (18,8)-(18,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (18,8)-(18,9) = "b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── opening_loc: (18,3)-(18,6) = "%w["
+ │ │ │ └── closing_loc: (18,9)-(18,10) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (18,0)-(18,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (17,0)-(17,4) = "case"
+ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ ├── @ CaseMatchNode (location: (21,0)-(23,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (21,5)-(21,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (21,5)-(21,6) = ":"
+ │ │ ├── value_loc: (21,6)-(21,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (22,0)-(22,10))
+ │ │ ├── pattern:
+ │ │ │ @ ParenthesesNode (location: (22,3)-(22,10))
+ │ │ │ ├── body:
+ │ │ │ │ @ RangeNode (location: (22,4)-(22,9))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left: ∅
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (22,7)-(22,9))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 10
+ │ │ │ │ └── operator_loc: (22,4)-(22,7) = "..."
+ │ │ │ ├── opening_loc: (22,3)-(22,4) = "("
+ │ │ │ └── closing_loc: (22,9)-(22,10) = ")"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (22,0)-(22,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (21,0)-(21,4) = "case"
+ │ └── end_keyword_loc: (23,0)-(23,3) = "end"
+ ├── @ CaseMatchNode (location: (25,0)-(27,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (25,5)-(25,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (25,5)-(25,6) = ":"
+ │ │ ├── value_loc: (25,6)-(25,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (26,0)-(26,9))
+ │ │ ├── pattern:
+ │ │ │ @ ParenthesesNode (location: (26,3)-(26,9))
+ │ │ │ ├── body:
+ │ │ │ │ @ RangeNode (location: (26,4)-(26,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── left: ∅
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (26,6)-(26,8))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 10
+ │ │ │ │ └── operator_loc: (26,4)-(26,6) = ".."
+ │ │ │ ├── opening_loc: (26,3)-(26,4) = "("
+ │ │ │ └── closing_loc: (26,8)-(26,9) = ")"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (26,0)-(26,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (25,0)-(25,4) = "case"
+ │ └── end_keyword_loc: (27,0)-(27,3) = "end"
+ ├── @ CaseMatchNode (location: (29,0)-(31,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (29,5)-(29,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (29,5)-(29,6) = ":"
+ │ │ ├── value_loc: (29,6)-(29,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (30,0)-(30,9))
+ │ │ ├── pattern:
+ │ │ │ @ ParenthesesNode (location: (30,3)-(30,9))
+ │ │ │ ├── body:
+ │ │ │ │ @ RangeNode (location: (30,4)-(30,8))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (30,4)-(30,5))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right: ∅
+ │ │ │ │ └── operator_loc: (30,5)-(30,8) = "..."
+ │ │ │ ├── opening_loc: (30,3)-(30,4) = "("
+ │ │ │ └── closing_loc: (30,8)-(30,9) = ")"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (30,0)-(30,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (29,0)-(29,4) = "case"
+ │ └── end_keyword_loc: (31,0)-(31,3) = "end"
+ ├── @ CaseMatchNode (location: (33,0)-(35,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (33,5)-(33,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (33,5)-(33,6) = ":"
+ │ │ ├── value_loc: (33,6)-(33,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (34,0)-(34,10))
+ │ │ ├── pattern:
+ │ │ │ @ ParenthesesNode (location: (34,3)-(34,10))
+ │ │ │ ├── body:
+ │ │ │ │ @ RangeNode (location: (34,4)-(34,9))
+ │ │ │ │ ├── flags: exclude_end
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (34,4)-(34,5))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (34,8)-(34,9))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 3
+ │ │ │ │ └── operator_loc: (34,5)-(34,8) = "..."
+ │ │ │ ├── opening_loc: (34,3)-(34,4) = "("
+ │ │ │ └── closing_loc: (34,9)-(34,10) = ")"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (34,0)-(34,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (33,0)-(33,4) = "case"
+ │ └── end_keyword_loc: (35,0)-(35,3) = "end"
+ ├── @ CaseMatchNode (location: (37,0)-(39,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (37,5)-(37,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (37,5)-(37,6) = ":"
+ │ │ ├── value_loc: (37,6)-(37,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (38,0)-(38,7))
+ │ │ ├── pattern:
+ │ │ │ @ ParenthesesNode (location: (38,3)-(38,7))
+ │ │ │ ├── body:
+ │ │ │ │ @ IntegerNode (location: (38,4)-(38,6))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ ├── opening_loc: (38,3)-(38,4) = "("
+ │ │ │ └── closing_loc: (38,6)-(38,7) = ")"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (38,0)-(38,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (37,0)-(37,4) = "case"
+ │ └── end_keyword_loc: (39,0)-(39,3) = "end"
+ ├── @ CaseMatchNode (location: (41,0)-(43,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (41,5)-(41,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (41,5)-(41,6) = ":"
+ │ │ ├── value_loc: (41,6)-(41,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (42,0)-(42,8))
+ │ │ ├── pattern:
+ │ │ │ @ HashPatternNode (location: (42,3)-(42,8))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── elements: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ NoKeywordsParameterNode (location: (42,3)-(42,8))
+ │ │ │ │ ├── operator_loc: (42,3)-(42,5) = "**"
+ │ │ │ │ └── keyword_loc: (42,5)-(42,8) = "nil"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (42,0)-(42,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (41,0)-(41,4) = "case"
+ │ └── end_keyword_loc: (43,0)-(43,3) = "end"
+ ├── @ CaseMatchNode (location: (45,0)-(47,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (45,5)-(45,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (45,5)-(45,6) = ":"
+ │ │ ├── value_loc: (45,6)-(45,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (46,0)-(46,11))
+ │ │ ├── pattern:
+ │ │ │ @ RegularExpressionNode (location: (46,3)-(46,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (46,3)-(46,4) = "/"
+ │ │ │ ├── content_loc: (46,4)-(46,10) = "regexp"
+ │ │ │ ├── closing_loc: (46,10)-(46,11) = "/"
+ │ │ │ └── unescaped: "regexp"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (46,0)-(46,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (45,0)-(45,4) = "case"
+ │ └── end_keyword_loc: (47,0)-(47,3) = "end"
+ ├── @ CaseMatchNode (location: (49,0)-(51,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (49,5)-(49,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (49,5)-(49,6) = ":"
+ │ │ ├── value_loc: (49,6)-(49,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (50,0)-(50,13))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (50,3)-(50,13))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (50,3)-(50,5))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (50,3)-(50,4) = ":"
+ │ │ │ │ ├── value_loc: (50,4)-(50,5) = "b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (50,7)-(50,9))
+ │ │ │ │ ├── operator_loc: (50,7)-(50,8) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ LocalVariableTargetNode (location: (50,8)-(50,9))
+ │ │ │ │ ├── name: :_
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (50,11)-(50,13))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (50,11)-(50,12) = ":"
+ │ │ │ │ ├── value_loc: (50,12)-(50,13) = "c"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (50,0)-(50,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (49,0)-(49,4) = "case"
+ │ └── end_keyword_loc: (51,0)-(51,3) = "end"
+ ├── @ CaseMatchNode (location: (53,0)-(55,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (53,5)-(53,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (53,5)-(53,6) = ":"
+ │ │ ├── value_loc: (53,6)-(53,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (54,0)-(54,11))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (54,3)-(54,11))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ SymbolNode (location: (54,3)-(54,5))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (54,3)-(54,4) = ":"
+ │ │ │ │ │ ├── value_loc: (54,4)-(54,5) = "b"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ └── @ ArrayPatternNode (location: (54,7)-(54,11))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ SymbolNode (location: (54,8)-(54,10))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (54,8)-(54,9) = ":"
+ │ │ │ │ │ ├── value_loc: (54,9)-(54,10) = "c"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "c"
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── opening_loc: (54,7)-(54,8) = "["
+ │ │ │ │ └── closing_loc: (54,10)-(54,11) = "]"
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (54,0)-(54,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (53,0)-(53,4) = "case"
+ │ └── end_keyword_loc: (55,0)-(55,3) = "end"
+ ├── @ CaseMatchNode (location: (57,0)-(59,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (57,5)-(57,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (57,5)-(57,6) = ":"
+ │ │ ├── value_loc: (57,6)-(57,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (58,0)-(58,11))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (58,3)-(58,11))
+ │ │ │ ├── constant:
+ │ │ │ │ @ ConstantReadNode (location: (58,3)-(58,9))
+ │ │ │ │ └── name: :Symbol
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (58,9)-(58,10) = "("
+ │ │ │ └── closing_loc: (58,10)-(58,11) = ")"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (58,0)-(58,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (57,0)-(57,4) = "case"
+ │ └── end_keyword_loc: (59,0)-(59,3) = "end"
+ ├── @ CaseMatchNode (location: (61,0)-(63,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (61,5)-(61,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (61,5)-(61,6) = ":"
+ │ │ ├── value_loc: (61,6)-(61,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (62,0)-(62,24))
+ │ │ ├── pattern:
+ │ │ │ @ FindPatternNode (location: (62,3)-(62,24))
+ │ │ │ ├── constant:
+ │ │ │ │ @ ConstantReadNode (location: (62,3)-(62,9))
+ │ │ │ │ └── name: :Symbol
+ │ │ │ ├── left:
+ │ │ │ │ @ SplatNode (location: (62,10)-(62,14))
+ │ │ │ │ ├── operator_loc: (62,10)-(62,11) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ LocalVariableTargetNode (location: (62,11)-(62,14))
+ │ │ │ │ ├── name: :lhs
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ LocalVariableTargetNode (location: (62,16)-(62,17))
+ │ │ │ │ ├── name: :x
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── right:
+ │ │ │ │ @ SplatNode (location: (62,19)-(62,23))
+ │ │ │ │ ├── operator_loc: (62,19)-(62,20) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ LocalVariableTargetNode (location: (62,20)-(62,23))
+ │ │ │ │ ├── name: :rhs
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── opening_loc: (62,9)-(62,10) = "("
+ │ │ │ └── closing_loc: (62,23)-(62,24) = ")"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (62,0)-(62,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (61,0)-(61,4) = "case"
+ │ └── end_keyword_loc: (63,0)-(63,3) = "end"
+ ├── @ CaseMatchNode (location: (65,0)-(67,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (65,5)-(65,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (65,5)-(65,6) = ":"
+ │ │ ├── value_loc: (65,6)-(65,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (66,0)-(66,24))
+ │ │ ├── pattern:
+ │ │ │ @ FindPatternNode (location: (66,3)-(66,24))
+ │ │ │ ├── constant:
+ │ │ │ │ @ ConstantReadNode (location: (66,3)-(66,9))
+ │ │ │ │ └── name: :Symbol
+ │ │ │ ├── left:
+ │ │ │ │ @ SplatNode (location: (66,10)-(66,14))
+ │ │ │ │ ├── operator_loc: (66,10)-(66,11) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ LocalVariableTargetNode (location: (66,11)-(66,14))
+ │ │ │ │ ├── name: :lhs
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ LocalVariableTargetNode (location: (66,16)-(66,17))
+ │ │ │ │ ├── name: :x
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── right:
+ │ │ │ │ @ SplatNode (location: (66,19)-(66,23))
+ │ │ │ │ ├── operator_loc: (66,19)-(66,20) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ LocalVariableTargetNode (location: (66,20)-(66,23))
+ │ │ │ │ ├── name: :rhs
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── opening_loc: (66,9)-(66,10) = "["
+ │ │ │ └── closing_loc: (66,23)-(66,24) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (66,0)-(66,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (65,0)-(65,4) = "case"
+ │ └── end_keyword_loc: (67,0)-(67,3) = "end"
+ ├── @ CaseMatchNode (location: (69,0)-(71,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (69,5)-(69,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (69,5)-(69,6) = ":"
+ │ │ ├── value_loc: (69,6)-(69,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (70,0)-(70,22))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (70,3)-(70,22))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ LambdaNode (location: (70,4)-(70,18))
+ │ │ │ │ │ ├── locals: [:b]
+ │ │ │ │ │ ├── operator_loc: (70,4)-(70,6) = "->"
+ │ │ │ │ │ ├── opening_loc: (70,10)-(70,11) = "{"
+ │ │ │ │ │ ├── closing_loc: (70,17)-(70,18) = "}"
+ │ │ │ │ │ ├── parameters:
+ │ │ │ │ │ │ @ BlockParametersNode (location: (70,6)-(70,9))
+ │ │ │ │ │ │ ├── parameters:
+ │ │ │ │ │ │ │ @ ParametersNode (location: (70,7)-(70,8))
+ │ │ │ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (70,7)-(70,8))
+ │ │ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ │ │ └── name: :b
+ │ │ │ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ │ ├── locals: (length: 0)
+ │ │ │ │ │ │ ├── opening_loc: (70,6)-(70,7) = "("
+ │ │ │ │ │ │ └── closing_loc: (70,8)-(70,9) = ")"
+ │ │ │ │ │ └── body:
+ │ │ │ │ │ @ StatementsNode (location: (70,12)-(70,16))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ TrueNode (location: (70,12)-(70,16))
+ │ │ │ │ └── @ LocalVariableTargetNode (location: (70,20)-(70,21))
+ │ │ │ │ ├── name: :c
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (70,3)-(70,4) = "["
+ │ │ │ └── closing_loc: (70,21)-(70,22) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (70,0)-(70,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (69,0)-(69,4) = "case"
+ │ └── end_keyword_loc: (71,0)-(71,3) = "end"
+ ├── @ CaseMatchNode (location: (73,0)-(75,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (73,5)-(73,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (73,5)-(73,6) = ":"
+ │ │ ├── value_loc: (73,6)-(73,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (74,0)-(74,28))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (74,3)-(74,28))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 4)
+ │ │ │ │ ├── @ SymbolNode (location: (74,4)-(74,6))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (74,4)-(74,5) = ":"
+ │ │ │ │ │ ├── value_loc: (74,5)-(74,6) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ ├── @ LocalVariableTargetNode (location: (74,8)-(74,9))
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ ├── @ LocalVariableTargetNode (location: (74,11)-(74,12))
+ │ │ │ │ │ ├── name: :c
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── @ ArrayPatternNode (location: (74,14)-(74,27))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ SymbolNode (location: (74,15)-(74,17))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (74,15)-(74,16) = ":"
+ │ │ │ │ │ ├── value_loc: (74,16)-(74,17) = "d"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "d"
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ SplatNode (location: (74,19)-(74,21))
+ │ │ │ │ │ ├── operator_loc: (74,19)-(74,20) = "*"
+ │ │ │ │ │ └── expression:
+ │ │ │ │ │ @ LocalVariableTargetNode (location: (74,20)-(74,21))
+ │ │ │ │ │ ├── name: :e
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ │ └── @ NilNode (location: (74,23)-(74,26))
+ │ │ │ │ ├── opening_loc: (74,14)-(74,15) = "["
+ │ │ │ │ └── closing_loc: (74,26)-(74,27) = "]"
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (74,3)-(74,4) = "["
+ │ │ │ └── closing_loc: (74,27)-(74,28) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (74,0)-(74,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (73,0)-(73,4) = "case"
+ │ └── end_keyword_loc: (75,0)-(75,3) = "end"
+ ├── @ CaseMatchNode (location: (77,0)-(79,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (77,5)-(77,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (77,5)-(77,6) = ":"
+ │ │ ├── value_loc: (77,6)-(77,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (78,0)-(78,12))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (78,3)-(78,12))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ ConstantReadNode (location: (78,4)-(78,5))
+ │ │ │ │ └── name: :A
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (78,7)-(78,8))
+ │ │ │ │ ├── operator_loc: (78,7)-(78,8) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ ConstantReadNode (location: (78,10)-(78,11))
+ │ │ │ │ └── name: :B
+ │ │ │ ├── opening_loc: (78,3)-(78,4) = "["
+ │ │ │ └── closing_loc: (78,11)-(78,12) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (78,0)-(78,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (77,0)-(77,4) = "case"
+ │ └── end_keyword_loc: (79,0)-(79,3) = "end"
+ ├── @ CaseMatchNode (location: (81,0)-(83,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (81,5)-(81,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (81,5)-(81,6) = ":"
+ │ │ ├── value_loc: (81,6)-(81,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (82,0)-(82,22))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (82,3)-(82,22))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ ArrayPatternNode (location: (82,4)-(82,11))
+ │ │ │ │ │ ├── constant: ∅
+ │ │ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ │ │ ├── @ SymbolNode (location: (82,5)-(82,7))
+ │ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ │ ├── opening_loc: (82,5)-(82,6) = ":"
+ │ │ │ │ │ │ │ ├── value_loc: (82,6)-(82,7) = "b"
+ │ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ │ │ └── @ LocalVariableTargetNode (location: (82,9)-(82,10))
+ │ │ │ │ │ │ ├── name: :c
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ ├── opening_loc: (82,4)-(82,5) = "["
+ │ │ │ │ │ └── closing_loc: (82,10)-(82,11) = "]"
+ │ │ │ │ └── @ ArrayPatternNode (location: (82,13)-(82,21))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ │ ├── @ SymbolNode (location: (82,14)-(82,16))
+ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ ├── opening_loc: (82,14)-(82,15) = ":"
+ │ │ │ │ │ │ ├── value_loc: (82,15)-(82,16) = "d"
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── unescaped: "d"
+ │ │ │ │ │ └── @ PinnedVariableNode (location: (82,18)-(82,20))
+ │ │ │ │ │ ├── variable:
+ │ │ │ │ │ │ @ LocalVariableReadNode (location: (82,19)-(82,20))
+ │ │ │ │ │ │ ├── name: :e
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ └── operator_loc: (82,18)-(82,19) = "^"
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── opening_loc: (82,13)-(82,14) = "["
+ │ │ │ │ └── closing_loc: (82,20)-(82,21) = "]"
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (82,3)-(82,4) = "["
+ │ │ │ └── closing_loc: (82,21)-(82,22) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (82,0)-(82,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (81,0)-(81,4) = "case"
+ │ └── end_keyword_loc: (83,0)-(83,3) = "end"
+ ├── @ CaseMatchNode (location: (85,0)-(87,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (85,5)-(85,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (85,5)-(85,6) = ":"
+ │ │ ├── value_loc: (85,6)-(85,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (86,0)-(86,5))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (86,3)-(86,5))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (86,3)-(86,4) = "["
+ │ │ │ └── closing_loc: (86,4)-(86,5) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (86,0)-(86,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (85,0)-(85,4) = "case"
+ │ └── end_keyword_loc: (87,0)-(87,3) = "end"
+ ├── @ CaseMatchNode (location: (89,0)-(91,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (89,5)-(89,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (89,5)-(89,6) = ":"
+ │ │ ├── value_loc: (89,6)-(89,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (90,0)-(90,9))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (90,3)-(90,9))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ PinnedExpressionNode (location: (90,4)-(90,8))
+ │ │ │ │ ├── expression:
+ │ │ │ │ │ @ CallNode (location: (90,6)-(90,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ ├── message_loc: (90,6)-(90,7) = "a"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── operator_loc: (90,4)-(90,5) = "^"
+ │ │ │ │ ├── lparen_loc: (90,5)-(90,6) = "("
+ │ │ │ │ └── rparen_loc: (90,7)-(90,8) = ")"
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (90,3)-(90,4) = "["
+ │ │ │ └── closing_loc: (90,8)-(90,9) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (90,0)-(90,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (89,0)-(89,4) = "case"
+ │ └── end_keyword_loc: (91,0)-(91,3) = "end"
+ ├── @ CaseMatchNode (location: (93,0)-(95,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (93,5)-(93,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (93,5)-(93,6) = ":"
+ │ │ ├── value_loc: (93,6)-(93,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (94,0)-(94,19))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (94,3)-(94,19))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 3)
+ │ │ │ │ ├── @ PinnedVariableNode (location: (94,4)-(94,7))
+ │ │ │ │ │ ├── variable:
+ │ │ │ │ │ │ @ InstanceVariableReadNode (location: (94,5)-(94,7))
+ │ │ │ │ │ │ └── name: :@a
+ │ │ │ │ │ └── operator_loc: (94,4)-(94,5) = "^"
+ │ │ │ │ ├── @ PinnedVariableNode (location: (94,9)-(94,12))
+ │ │ │ │ │ ├── variable:
+ │ │ │ │ │ │ @ GlobalVariableReadNode (location: (94,10)-(94,12))
+ │ │ │ │ │ │ └── name: :$b
+ │ │ │ │ │ └── operator_loc: (94,9)-(94,10) = "^"
+ │ │ │ │ └── @ PinnedVariableNode (location: (94,14)-(94,18))
+ │ │ │ │ ├── variable:
+ │ │ │ │ │ @ ClassVariableReadNode (location: (94,15)-(94,18))
+ │ │ │ │ │ └── name: :@@c
+ │ │ │ │ └── operator_loc: (94,14)-(94,15) = "^"
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: (94,3)-(94,4) = "["
+ │ │ │ └── closing_loc: (94,18)-(94,19) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (94,0)-(94,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (93,0)-(93,4) = "case"
+ │ └── end_keyword_loc: (95,0)-(95,3) = "end"
+ ├── @ CaseMatchNode (location: (97,0)-(99,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (97,5)-(97,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (97,5)-(97,6) = ":"
+ │ │ ├── value_loc: (97,6)-(97,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (98,0)-(98,12))
+ │ │ ├── pattern:
+ │ │ │ @ XStringNode (location: (98,3)-(98,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (98,3)-(98,4) = "`"
+ │ │ │ ├── content_loc: (98,4)-(98,11) = "echo hi"
+ │ │ │ ├── closing_loc: (98,11)-(98,12) = "`"
+ │ │ │ └── unescaped: "echo hi"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (98,0)-(98,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (97,0)-(97,4) = "case"
+ │ └── end_keyword_loc: (99,0)-(99,3) = "end"
+ ├── @ CaseMatchNode (location: (101,0)-(103,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (101,5)-(101,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (101,5)-(101,6) = ":"
+ │ │ ├── value_loc: (101,6)-(101,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (102,0)-(102,16))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (102,3)-(102,16))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── requireds: (length: 3)
+ │ │ │ │ ├── @ NilNode (location: (102,3)-(102,6))
+ │ │ │ │ ├── @ NilNode (location: (102,8)-(102,11))
+ │ │ │ │ └── @ NilNode (location: (102,13)-(102,16))
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (102,0)-(102,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (101,0)-(101,4) = "case"
+ │ └── end_keyword_loc: (103,0)-(103,3) = "end"
+ ├── @ CaseMatchNode (location: (105,0)-(107,3))
+ │ ├── predicate:
+ │ │ @ SymbolNode (location: (105,5)-(105,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (105,5)-(105,6) = ":"
+ │ │ ├── value_loc: (105,6)-(105,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (106,0)-(106,11))
+ │ │ ├── pattern:
+ │ │ │ @ HashPatternNode (location: (106,3)-(106,11))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ AssocNode (location: (106,5)-(106,9))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (106,5)-(106,9))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (106,5)-(106,6) = "\""
+ │ │ │ │ │ ├── value_loc: (106,6)-(106,7) = "b"
+ │ │ │ │ │ ├── closing_loc: (106,7)-(106,9) = "\":"
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ ImplicitNode (location: (106,6)-(106,7))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ LocalVariableTargetNode (location: (106,6)-(106,7))
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── opening_loc: (106,3)-(106,4) = "{"
+ │ │ │ └── closing_loc: (106,10)-(106,11) = "}"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (106,0)-(106,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (105,0)-(105,4) = "case"
+ │ └── end_keyword_loc: (107,0)-(107,3) = "end"
+ └── @ CaseMatchNode (location: (109,0)-(111,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (109,5)-(109,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (109,5)-(109,6) = ":"
+ │ ├── value_loc: (109,6)-(109,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (110,0)-(110,5))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (110,3)-(110,5))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: (110,3)-(110,4) = "{"
+ │ │ └── closing_loc: (110,4)-(110,5) = "}"
+ │ ├── statements: ∅
+ │ ├── in_loc: (110,0)-(110,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (109,0)-(109,4) = "case"
+ └── end_keyword_loc: (111,0)-(111,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_31.txt b/test/prism/snapshots/seattlerb/case_in_31.txt
new file mode 100644
index 0000000000..fdf5ce2a29
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_31.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: [:c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,11))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (2,4)-(2,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (2,4)-(2,5) = ":"
+ │ │ │ ├── value_loc: (2,5)-(2,6) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (2,8)-(2,10))
+ │ │ │ ├── operator_loc: (2,8)-(2,9) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (2,9)-(2,10))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,3)-(2,4) = "["
+ │ │ └── closing_loc: (2,10)-(2,11) = "]"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_37.txt b/test/prism/snapshots/seattlerb/case_in_37.txt
new file mode 100644
index 0000000000..1a1d887b4f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_37.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,19))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,5)-(2,17))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,5)-(2,7))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,5)-(2,6) = "b"
+ │ │ │ │ ├── closing_loc: (2,6)-(2,7) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ ArrayPatternNode (location: (2,8)-(2,17))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ ConstantReadNode (location: (2,9)-(2,13))
+ │ │ │ │ │ └── name: :Hash
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ SplatNode (location: (2,15)-(2,16))
+ │ │ │ │ │ ├── operator_loc: (2,15)-(2,16) = "*"
+ │ │ │ │ │ └── expression: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── opening_loc: (2,8)-(2,9) = "["
+ │ │ │ │ └── closing_loc: (2,16)-(2,17) = "]"
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: (2,3)-(2,4) = "{"
+ │ │ └── closing_loc: (2,18)-(2,19) = "}"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_42.txt b/test/prism/snapshots/seattlerb/case_in_42.txt
new file mode 100644
index 0000000000..f985d6bc8d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_42.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: [:_]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(2,18))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,9))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (2,3)-(2,5))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (2,3)-(2,4) = ":"
+ │ │ │ ├── value_loc: (2,4)-(2,5) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (2,7)-(2,9))
+ │ │ │ ├── operator_loc: (2,7)-(2,8) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (2,8)-(2,9))
+ │ │ │ ├── name: :_
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,15)-(2,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (2,15)-(2,18))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,10)-(2,14) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_42_2.txt b/test/prism/snapshots/seattlerb/case_in_42_2.txt
new file mode 100644
index 0000000000..c399ba1bfa
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_42_2.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: [:list]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(2,20))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,11))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ └── name: :A
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (2,5)-(2,10))
+ │ │ │ ├── operator_loc: (2,5)-(2,6) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (2,6)-(2,10))
+ │ │ │ ├── name: :list
+ │ │ │ └── depth: 0
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,4)-(2,5) = "("
+ │ │ └── closing_loc: (2,10)-(2,11) = ")"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,17)-(2,20))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (2,17)-(2,20))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,12)-(2,16) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_47.txt b/test/prism/snapshots/seattlerb/case_in_47.txt
new file mode 100644
index 0000000000..99baebce05
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_47.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,14))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (2,4)-(2,5))
+ │ │ │ ├── operator_loc: (2,4)-(2,5) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── posts: (length: 2)
+ │ │ │ ├── @ SymbolNode (location: (2,7)-(2,9))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (2,7)-(2,8) = ":"
+ │ │ │ │ ├── value_loc: (2,8)-(2,9) = "b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ └── @ SymbolNode (location: (2,11)-(2,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (2,11)-(2,12) = ":"
+ │ │ │ ├── value_loc: (2,12)-(2,13) = "c"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "c"
+ │ │ ├── opening_loc: (2,3)-(2,4) = "["
+ │ │ └── closing_loc: (2,13)-(2,14) = "]"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_67.txt b/test/prism/snapshots/seattlerb/case_in_67.txt
new file mode 100644
index 0000000000..4bab417d57
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_67.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(2,15))
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (2,3)-(2,6))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (2,3)-(2,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (2,4)-(2,6) = ".."
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,12)-(2,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (2,12)-(2,15))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,7)-(2,11) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_86.txt b/test/prism/snapshots/seattlerb/case_in_86.txt
new file mode 100644
index 0000000000..5889137844
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_86.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ ArrayNode (location: (1,5)-(1,13))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,6)-(1,7) = ":"
+ │ │ │ ├── value_loc: (1,7)-(1,8) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (1,10)-(1,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,10)-(1,11) = ":"
+ │ │ ├── value_loc: (1,11)-(1,12) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── opening_loc: (1,5)-(1,6) = "["
+ │ └── closing_loc: (1,12)-(1,13) = "]"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(2,25))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,16))
+ │ │ ├── constant: ∅
+ │ │ ├── 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) = "::"
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (2,15)-(2,16))
+ │ │ │ ├── operator_loc: (2,15)-(2,16) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,22)-(2,25))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (2,22)-(2,25))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,17)-(2,21) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_86_2.txt b/test/prism/snapshots/seattlerb/case_in_86_2.txt
new file mode 100644
index 0000000000..18ce70ae93
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_86_2.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ ArrayNode (location: (1,5)-(1,13))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,6)-(1,7) = ":"
+ │ │ │ ├── value_loc: (1,7)-(1,8) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (1,10)-(1,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,10)-(1,11) = ":"
+ │ │ ├── value_loc: (1,11)-(1,12) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── opening_loc: (1,5)-(1,6) = "["
+ │ └── closing_loc: (1,12)-(1,13) = "]"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(2,25))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,16))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (2,3)-(2,4))
+ │ │ │ ├── operator_loc: (2,3)-(2,4) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── 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) = "::"
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,22)-(2,25))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (2,22)-(2,25))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,17)-(2,21) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_array_pat_const.txt b/test/prism/snapshots/seattlerb/case_in_array_pat_const.txt
new file mode 100644
index 0000000000..f361e8d458
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_array_pat_const.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: [:c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,7))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ └── name: :B
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (2,5)-(2,6))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,4)-(2,5) = "["
+ │ │ └── closing_loc: (2,6)-(2,7) = "]"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt b/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt
new file mode 100644
index 0000000000..c783af9ce5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: [:d]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,10))
+ │ │ ├── constant:
+ │ │ │ @ ConstantPathNode (location: (2,3)-(2,7))
+ │ │ │ ├── parent:
+ │ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ │ └── name: :B
+ │ │ │ ├── child:
+ │ │ │ │ @ ConstantReadNode (location: (2,6)-(2,7))
+ │ │ │ │ └── name: :C
+ │ │ │ └── delimiter_loc: (2,4)-(2,6) = "::"
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (2,8)-(2,9))
+ │ │ │ ├── name: :d
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,7)-(2,8) = "["
+ │ │ └── closing_loc: (2,9)-(2,10) = "]"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "e"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "e"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_array_pat_paren_assign.txt b/test/prism/snapshots/seattlerb/case_in_array_pat_paren_assign.txt
new file mode 100644
index 0000000000..8d185b250a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_array_pat_paren_assign.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: [:d]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,12))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ └── name: :B
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ CapturePatternNode (location: (2,5)-(2,11))
+ │ │ │ ├── value:
+ │ │ │ │ @ ConstantReadNode (location: (2,5)-(2,6))
+ │ │ │ │ └── name: :C
+ │ │ │ ├── target:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,10)-(2,11))
+ │ │ │ │ ├── name: :d
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: (2,7)-(2,9) = "=>"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,4)-(2,5) = "("
+ │ │ └── closing_loc: (2,11)-(2,12) = ")"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_const.txt b/test/prism/snapshots/seattlerb/case_in_const.txt
new file mode 100644
index 0000000000..c4b838aa1d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_const.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ ConstantReadNode (location: (1,5)-(1,10))
+ │ └── name: :Array
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ ConstantReadNode (location: (2,3)-(2,8))
+ │ │ └── name: :Class
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_else.txt b/test/prism/snapshots/seattlerb/case_in_else.txt
new file mode 100644
index 0000000000..5eae7fc1ea
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_else.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(6,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(6,3))
+ ├── predicate:
+ │ @ ConstantReadNode (location: (1,5)-(1,10))
+ │ └── name: :Array
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ ConstantReadNode (location: (2,3)-(2,8))
+ │ │ └── name: :Class
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent:
+ │ @ ElseNode (location: (4,0)-(6,3))
+ │ ├── else_keyword_loc: (4,0)-(4,4) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,2)-(5,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (5,2)-(5,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,2)-(5,3) = ":"
+ │ │ ├── value_loc: (5,3)-(5,4) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ └── end_keyword_loc: (6,0)-(6,3) = "end"
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (6,0)-(6,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_find.txt b/test/prism/snapshots/seattlerb/case_in_find.txt
new file mode 100644
index 0000000000..f84c4c30d0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_find.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,2)-(2,15))
+ │ ├── pattern:
+ │ │ @ FindPatternNode (location: (2,5)-(2,15))
+ │ │ ├── constant: ∅
+ │ │ ├── left:
+ │ │ │ @ SplatNode (location: (2,5)-(2,7))
+ │ │ │ ├── operator_loc: (2,5)-(2,6) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (2,6)-(2,7))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (2,9)-(2,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (2,9)-(2,10) = ":"
+ │ │ │ ├── value_loc: (2,10)-(2,11) = "+"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "+"
+ │ │ ├── right:
+ │ │ │ @ SplatNode (location: (2,13)-(2,15))
+ │ │ │ ├── operator_loc: (2,13)-(2,14) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (2,14)-(2,15))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ ├── statements: ∅
+ │ ├── in_loc: (2,2)-(2,4) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_find_array.txt b/test/prism/snapshots/seattlerb/case_in_find_array.txt
new file mode 100644
index 0000000000..a757f80346
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_find_array.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: [:c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(2,16))
+ │ ├── pattern:
+ │ │ @ FindPatternNode (location: (2,3)-(2,16))
+ │ │ ├── constant: ∅
+ │ │ ├── left:
+ │ │ │ @ SplatNode (location: (2,4)-(2,5))
+ │ │ │ ├── operator_loc: (2,4)-(2,5) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ SymbolNode (location: (2,7)-(2,9))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (2,7)-(2,8) = ":"
+ │ │ │ │ ├── value_loc: (2,8)-(2,9) = "b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ └── @ LocalVariableTargetNode (location: (2,11)-(2,12))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ ├── right:
+ │ │ │ @ SplatNode (location: (2,14)-(2,15))
+ │ │ │ ├── operator_loc: (2,14)-(2,15) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── opening_loc: (2,3)-(2,4) = "["
+ │ │ └── closing_loc: (2,15)-(2,16) = "]"
+ │ ├── statements: ∅
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat.txt
new file mode 100644
index 0000000000..e813efa9ee
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_hash_pat.txt
@@ -0,0 +1,68 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,21))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ AssocNode (location: (2,5)-(2,11))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (2,5)-(2,7))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (2,5)-(2,6) = "b"
+ │ │ │ │ │ ├── closing_loc: (2,6)-(2,7) = ":"
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ StringNode (location: (2,8)-(2,11))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: (2,8)-(2,9) = "'"
+ │ │ │ │ │ ├── content_loc: (2,9)-(2,10) = "c"
+ │ │ │ │ │ ├── closing_loc: (2,10)-(2,11) = "'"
+ │ │ │ │ │ └── unescaped: "c"
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ └── @ AssocNode (location: (2,13)-(2,19))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,13)-(2,15))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,13)-(2,14) = "d"
+ │ │ │ │ ├── closing_loc: (2,14)-(2,15) = ":"
+ │ │ │ │ └── unescaped: "d"
+ │ │ │ ├── value:
+ │ │ │ │ @ StringNode (location: (2,16)-(2,19))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (2,16)-(2,17) = "\""
+ │ │ │ │ ├── content_loc: (2,17)-(2,18) = "e"
+ │ │ │ │ ├── closing_loc: (2,18)-(2,19) = "\""
+ │ │ │ │ └── unescaped: "e"
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: (2,3)-(2,4) = "{"
+ │ │ └── closing_loc: (2,20)-(2,21) = "}"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "f"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "f"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,22)-(2,26) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_assign.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_assign.txt
new file mode 100644
index 0000000000..790d9d63ff
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_assign.txt
@@ -0,0 +1,86 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: [:x, :f]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,34))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 3)
+ │ │ │ ├── @ AssocNode (location: (2,5)-(2,20))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (2,5)-(2,7))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (2,5)-(2,6) = "b"
+ │ │ │ │ │ ├── closing_loc: (2,6)-(2,7) = ":"
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CapturePatternNode (location: (2,8)-(2,20))
+ │ │ │ │ │ ├── value:
+ │ │ │ │ │ │ @ ConstantReadNode (location: (2,8)-(2,15))
+ │ │ │ │ │ │ └── name: :Integer
+ │ │ │ │ │ ├── target:
+ │ │ │ │ │ │ @ LocalVariableTargetNode (location: (2,19)-(2,20))
+ │ │ │ │ │ │ ├── name: :x
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ └── operator_loc: (2,16)-(2,18) = "=>"
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ ├── @ AssocNode (location: (2,22)-(2,28))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (2,22)-(2,24))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (2,22)-(2,23) = "d"
+ │ │ │ │ │ ├── closing_loc: (2,23)-(2,24) = ":"
+ │ │ │ │ │ └── unescaped: "d"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ StringNode (location: (2,25)-(2,28))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: (2,25)-(2,26) = "\""
+ │ │ │ │ │ ├── content_loc: (2,26)-(2,27) = "e"
+ │ │ │ │ │ ├── closing_loc: (2,27)-(2,28) = "\""
+ │ │ │ │ │ └── unescaped: "e"
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ └── @ AssocNode (location: (2,30)-(2,32))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,30)-(2,32))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,30)-(2,31) = "f"
+ │ │ │ │ ├── closing_loc: (2,31)-(2,32) = ":"
+ │ │ │ │ └── unescaped: "f"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (2,30)-(2,31))
+ │ │ │ │ └── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,30)-(2,31))
+ │ │ │ │ ├── name: :f
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: (2,3)-(2,4) = "{"
+ │ │ └── closing_loc: (2,33)-(2,34) = "}"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "g"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "g"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,35)-(2,39) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt
new file mode 100644
index 0000000000..4c8cfd0e54
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,11))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ └── name: :B
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,5)-(2,10))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,5)-(2,7))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,5)-(2,6) = "a"
+ │ │ │ │ ├── closing_loc: (2,6)-(2,7) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (2,8)-(2,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: (2,4)-(2,5) = "("
+ │ │ └── closing_loc: (2,10)-(2,11) = ")"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_true.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_true.txt
new file mode 100644
index 0000000000..8ff95a161f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_true.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,10))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,3)-(2,10))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,3)-(2,5))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,3)-(2,4) = "b"
+ │ │ │ │ ├── closing_loc: (2,4)-(2,5) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ TrueNode (location: (2,6)-(2,10))
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,11)-(2,15) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_rest.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_rest.txt
new file mode 100644
index 0000000000..b93b889ec5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_rest.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: [:c, :rest]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(2,23))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,15))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,3)-(2,7))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,3)-(2,5))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,3)-(2,4) = "b"
+ │ │ │ │ ├── closing_loc: (2,4)-(2,5) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,6)-(2,7))
+ │ │ │ │ ├── name: :c
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest:
+ │ │ │ @ AssocSplatNode (location: (2,9)-(2,15))
+ │ │ │ ├── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,11)-(2,15))
+ │ │ │ │ ├── name: :rest
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: (2,9)-(2,11) = "**"
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,21)-(2,23))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (2,21)-(2,23))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (2,21)-(2,22) = ":"
+ │ │ ├── value_loc: (2,22)-(2,23) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,16)-(2,20) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt
new file mode 100644
index 0000000000..956e93faa0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: [:rest]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(3,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(2,17))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,9))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ AssocSplatNode (location: (2,3)-(2,9))
+ │ │ │ ├── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,5)-(2,9))
+ │ │ │ │ ├── name: :rest
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: (2,3)-(2,5) = "**"
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,15)-(2,17))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (2,15)-(2,17))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (2,15)-(2,16) = ":"
+ │ │ ├── value_loc: (2,16)-(2,17) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: (2,10)-(2,14) = "then"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_if_unless_post_mod.txt b/test/prism/snapshots/seattlerb/case_in_if_unless_post_mod.txt
new file mode 100644
index 0000000000..a21d3e15dd
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_if_unless_post_mod.txt
@@ -0,0 +1,67 @@
+@ ProgramNode (location: (1,0)-(6,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(6,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 2)
+ │ ├── @ InNode (location: (2,0)-(3,4))
+ │ │ ├── pattern:
+ │ │ │ @ IfNode (location: (2,3)-(2,12))
+ │ │ │ ├── if_keyword_loc: (2,5)-(2,7) = "if"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ TrueNode (location: (2,8)-(2,12))
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (2,3)-(2,4))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ │ └── name: :A
+ │ │ │ ├── consequent: ∅
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ │ ├── value_loc: (3,3)-(3,4) = "C"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "C"
+ │ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ │ └── then_loc: ∅
+ │ └── @ InNode (location: (4,0)-(5,4))
+ │ ├── pattern:
+ │ │ @ UnlessNode (location: (4,3)-(4,17))
+ │ │ ├── keyword_loc: (4,5)-(4,11) = "unless"
+ │ │ ├── predicate:
+ │ │ │ @ FalseNode (location: (4,12)-(4,17))
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (4,3)-(4,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (4,3)-(4,4))
+ │ │ │ └── name: :D
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,2)-(5,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (5,2)-(5,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,2)-(5,3) = ":"
+ │ │ ├── value_loc: (5,3)-(5,4) = "E"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "E"
+ │ ├── in_loc: (4,0)-(4,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (6,0)-(6,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_multiple.txt b/test/prism/snapshots/seattlerb/case_in_multiple.txt
new file mode 100644
index 0000000000..d8597c4bfa
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_multiple.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(6,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(6,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 2)
+ │ ├── @ InNode (location: (2,0)-(3,4))
+ │ │ ├── pattern:
+ │ │ │ @ ConstantPathNode (location: (2,3)-(2,7))
+ │ │ │ ├── parent:
+ │ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ │ └── name: :A
+ │ │ │ ├── child:
+ │ │ │ │ @ ConstantReadNode (location: (2,6)-(2,7))
+ │ │ │ │ └── name: :B
+ │ │ │ └── delimiter_loc: (2,4)-(2,6) = "::"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ │ ├── value_loc: (3,3)-(3,4) = "C"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "C"
+ │ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ │ └── then_loc: ∅
+ │ └── @ InNode (location: (4,0)-(5,4))
+ │ ├── pattern:
+ │ │ @ ConstantPathNode (location: (4,3)-(4,7))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (4,3)-(4,4))
+ │ │ │ └── name: :D
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (4,6)-(4,7))
+ │ │ │ └── name: :E
+ │ │ └── delimiter_loc: (4,4)-(4,6) = "::"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,2)-(5,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (5,2)-(5,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,2)-(5,3) = ":"
+ │ │ ├── value_loc: (5,3)-(5,4) = "F"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "F"
+ │ ├── in_loc: (4,0)-(4,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (6,0)-(6,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/case_in_or.txt b/test/prism/snapshots/seattlerb/case_in_or.txt
new file mode 100644
index 0000000000..7ac6617608
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/case_in_or.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,4))
+ │ ├── pattern:
+ │ │ @ AlternationPatternNode (location: (2,3)-(2,8))
+ │ │ ├── left:
+ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ └── name: :B
+ │ │ ├── right:
+ │ │ │ @ ConstantReadNode (location: (2,7)-(2,8))
+ │ │ │ └── name: :C
+ │ │ └── operator_loc: (2,5)-(2,6) = "|"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (3,2)-(3,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ ├── value_loc: (3,3)-(3,4) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/class_comments.txt b/test/prism/snapshots/seattlerb/class_comments.txt
new file mode 100644
index 0000000000..5ac05b6be6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/class_comments.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (4,0)-(9,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (4,0)-(9,3))
+ └── body: (length: 1)
+ └── @ ClassNode (location: (4,0)-(9,3))
+ ├── locals: []
+ ├── class_keyword_loc: (4,0)-(4,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (4,6)-(4,7))
+ │ └── name: :X
+ ├── inheritance_operator_loc: ∅
+ ├── superclass: ∅
+ ├── body:
+ │ @ StatementsNode (location: (6,2)-(8,5))
+ │ └── body: (length: 1)
+ │ └── @ DefNode (location: (6,2)-(8,5))
+ │ ├── name: :blah
+ │ ├── name_loc: (6,6)-(6,10) = "blah"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (6,2)-(6,5) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (8,2)-(8,5) = "end"
+ ├── end_keyword_loc: (9,0)-(9,3) = "end"
+ └── name: :X
diff --git a/test/prism/snapshots/seattlerb/cond_unary_minus.txt b/test/prism/snapshots/seattlerb/cond_unary_minus.txt
new file mode 100644
index 0000000000..b6e12dfb15
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/cond_unary_minus.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,10))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ IntegerNode (location: (1,3)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: -1
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,7)-(1,10) = "end"
diff --git a/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt b/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt
new file mode 100644
index 0000000000..b018ac48d4
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ ConstantPathOrWriteNode (location: (1,0)-(1,12))
+ ├── target:
+ │ @ ConstantPathNode (location: (1,0)-(1,6))
+ │ ├── 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) = "::"
+ ├── operator_loc: (1,7)-(1,10) = "||="
+ └── value:
+ @ IntegerNode (location: (1,11)-(1,12))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt b/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt
new file mode 100644
index 0000000000..8d9d94931b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ ConstantPathOrWriteNode (location: (1,0)-(1,9))
+ ├── 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,7) = "||="
+ └── value:
+ @ IntegerNode (location: (1,8)-(1,9))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
new file mode 100644
index 0000000000..b1d61b3752
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
@@ -0,0 +1,19 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ ConstantPathOperatorWriteNode (location: (1,0)-(1,8))
+ ├── 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) = "&="
+ ├── value:
+ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── operator: :&
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt
new file mode 100644
index 0000000000..22f6682534
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ ConstantPathAndWriteNode (location: (1,0)-(1,9))
+ ├── 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,7) = "&&="
+ └── value:
+ @ IntegerNode (location: (1,8)-(1,9))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_or.txt b/test/prism/snapshots/seattlerb/const_op_asgn_or.txt
new file mode 100644
index 0000000000..067e0fbb93
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/const_op_asgn_or.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ ConstantPathOrWriteNode (location: (1,0)-(1,10))
+ ├── target:
+ │ @ ConstantPathNode (location: (1,0)-(1,4))
+ │ ├── parent:
+ │ │ @ ConstantReadNode (location: (1,0)-(1,1))
+ │ │ └── name: :X
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (1,3)-(1,4))
+ │ │ └── name: :Y
+ │ └── delimiter_loc: (1,1)-(1,3) = "::"
+ ├── operator_loc: (1,5)-(1,8) = "||="
+ └── value:
+ @ IntegerNode (location: (1,9)-(1,10))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/dasgn_icky2.txt b/test/prism/snapshots/seattlerb/dasgn_icky2.txt
new file mode 100644
index 0000000000..e118362f87
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dasgn_icky2.txt
@@ -0,0 +1,61 @@
+@ ProgramNode (location: (1,0)-(8,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(8,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(8,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(8,3))
+ ├── locals: [:v]
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (2,2)-(7,5))
+ │ └── body: (length: 2)
+ │ ├── @ LocalVariableWriteNode (location: (2,2)-(2,9))
+ │ │ ├── name: :v
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (2,2)-(2,3) = "v"
+ │ │ ├── value:
+ │ │ │ @ NilNode (location: (2,6)-(2,9))
+ │ │ └── operator_loc: (2,4)-(2,5) = "="
+ │ └── @ BeginNode (location: (3,2)-(7,5))
+ │ ├── begin_keyword_loc: (3,2)-(3,7) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (4,4)-(4,9))
+ │ │ └── body: (length: 1)
+ │ │ └── @ YieldNode (location: (4,4)-(4,9))
+ │ │ ├── keyword_loc: (4,4)-(4,9) = "yield"
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ └── rparen_loc: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (5,2)-(6,9))
+ │ │ ├── keyword_loc: (5,2)-(5,8) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (5,9)-(5,18))
+ │ │ │ └── name: :Exception
+ │ │ ├── operator_loc: (5,19)-(5,21) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (5,22)-(5,23))
+ │ │ │ ├── name: :v
+ │ │ │ └── depth: 0
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (6,4)-(6,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ BreakNode (location: (6,4)-(6,9))
+ │ │ │ ├── arguments: ∅
+ │ │ │ └── keyword_loc: (6,4)-(6,9) = "break"
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (7,2)-(7,5) = "end"
+ ├── opening_loc: (1,2)-(1,4) = "do"
+ └── closing_loc: (8,0)-(8,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/defined_eh_parens.txt b/test/prism/snapshots/seattlerb/defined_eh_parens.txt
new file mode 100644
index 0000000000..49b577fcd1
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defined_eh_parens.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ DefinedNode (location: (1,0)-(1,12))
+ ├── lparen_loc: (1,8)-(1,9) = "("
+ ├── value:
+ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ ├── flags: decimal
+ │ └── value: 42
+ ├── rparen_loc: (1,11)-(1,12) = ")"
+ └── keyword_loc: (1,0)-(1,8) = "defined?"
diff --git a/test/prism/snapshots/seattlerb/defn_arg_asplat_arg.txt b/test/prism/snapshots/seattlerb/defn_arg_asplat_arg.txt
new file mode 100644
index 0000000000..3f2bdf44a4
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_arg_asplat_arg.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,29))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,29))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,29))
+ ├── name: :call
+ ├── name_loc: (1,4)-(1,8) = "call"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,9)-(1,24))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ └── name: :interp
+ │ ├── optionals: (length: 0)
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (1,17)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,17)-(1,18) = "*"
+ │ ├── posts: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,20)-(1,24))
+ │ │ ├── flags: ∅
+ │ │ └── name: :args
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:interp, :args]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,8)-(1,9) = "("
+ ├── rparen_loc: (1,24)-(1,25) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,26)-(1,29) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_arg_forward_args.txt b/test/prism/snapshots/seattlerb/defn_arg_forward_args.txt
new file mode 100644
index 0000000000..4121770c5c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_arg_forward_args.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,29))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,29))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,29))
+ ├── name: :a
+ ├── name_loc: (1,4)-(1,5) = "a"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,12))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── name: :x
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (1,9)-(1,12))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,15)-(1,24))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,15)-(1,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (1,15)-(1,16) = "b"
+ │ ├── opening_loc: (1,16)-(1,17) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,17)-(1,23))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ LocalVariableReadNode (location: (1,17)-(1,18))
+ │ │ │ ├── name: :x
+ │ │ │ └── depth: 0
+ │ │ └── @ ForwardingArgumentsNode (location: (1,20)-(1,23))
+ │ ├── closing_loc: (1,23)-(1,24) = ")"
+ │ └── block: ∅
+ ├── locals: [:x]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,12)-(1,13) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,26)-(1,29) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_args_forward_args.txt b/test/prism/snapshots/seattlerb/defn_args_forward_args.txt
new file mode 100644
index 0000000000..178b6ccde7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_args_forward_args.txt
@@ -0,0 +1,61 @@
+@ ProgramNode (location: (1,0)-(1,41))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,41))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,41))
+ ├── name: :a
+ ├── name_loc: (1,4)-(1,5) = "a"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,18))
+ │ ├── requireds: (length: 3)
+ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :x
+ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :y
+ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ └── name: :z
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (1,15)-(1,18))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,21)-(1,36))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,21)-(1,36))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (1,21)-(1,22) = "b"
+ │ ├── opening_loc: (1,22)-(1,23) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,23)-(1,35))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ SymbolNode (location: (1,23)-(1,27))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,23)-(1,24) = ":"
+ │ │ │ ├── value_loc: (1,24)-(1,27) = "get"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "get"
+ │ │ ├── @ LocalVariableReadNode (location: (1,29)-(1,30))
+ │ │ │ ├── name: :z
+ │ │ │ └── depth: 0
+ │ │ └── @ ForwardingArgumentsNode (location: (1,32)-(1,35))
+ │ ├── closing_loc: (1,35)-(1,36) = ")"
+ │ └── block: ∅
+ ├── locals: [:x, :y, :z]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,18)-(1,19) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,38)-(1,41) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_comments.txt b/test/prism/snapshots/seattlerb/defn_comments.txt
new file mode 100644
index 0000000000..585aa65c9a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_comments.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (4,0)-(5,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (4,0)-(5,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (4,0)-(5,3))
+ ├── name: :blah
+ ├── name_loc: (4,4)-(4,8) = "blah"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (4,0)-(4,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (5,0)-(5,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_endless_command.txt b/test/prism/snapshots/seattlerb/defn_endless_command.txt
new file mode 100644
index 0000000000..c3ea59282a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_endless_command.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,33))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,33))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,33))
+ ├── name: :some_method
+ ├── name_loc: (1,4)-(1,15) = "some_method"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,18)-(1,33))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,18)-(1,33))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :other_method
+ │ ├── message_loc: (1,18)-(1,30) = "other_method"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,31)-(1,33))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,31)-(1,33))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: (1,16)-(1,17) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt b/test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt
new file mode 100644
index 0000000000..dfd1d01ba8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,43))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,43))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,43))
+ ├── name: :some_method
+ ├── name_loc: (1,4)-(1,15) = "some_method"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,18)-(1,43))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (1,18)-(1,43))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,18)-(1,33))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :other_method
+ │ │ ├── message_loc: (1,18)-(1,30) = "other_method"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,31)-(1,33))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,31)-(1,33))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,34)-(1,40) = "rescue"
+ │ └── rescue_expression:
+ │ @ IntegerNode (location: (1,41)-(1,43))
+ │ ├── flags: decimal
+ │ └── value: 24
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: (1,16)-(1,17) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defn_forward_args.txt b/test/prism/snapshots/seattlerb/defn_forward_args.txt
new file mode 100644
index 0000000000..71a984c811
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_forward_args.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,23))
+ ├── name: :a
+ ├── name_loc: (1,4)-(1,5) = "a"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,9))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (1,6)-(1,9))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,12)-(1,18))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,12)-(1,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (1,12)-(1,13) = "b"
+ │ ├── opening_loc: (1,13)-(1,14) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,14)-(1,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ForwardingArgumentsNode (location: (1,14)-(1,17))
+ │ ├── closing_loc: (1,17)-(1,18) = ")"
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,9)-(1,10) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,20)-(1,23) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt b/test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt
new file mode 100644
index 0000000000..4a4d69e4d0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(3,3))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,9))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (1,6)-(1,9))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (2,2)-(2,8))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,2)-(2,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (2,2)-(2,3) = "m"
+ │ ├── opening_loc: (2,3)-(2,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (2,4)-(2,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ForwardingArgumentsNode (location: (2,4)-(2,7))
+ │ ├── closing_loc: (2,7)-(2,8) = ")"
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_env.txt b/test/prism/snapshots/seattlerb/defn_kwarg_env.txt
new file mode 100644
index 0000000000..f420420fc3
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_kwarg_env.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,45))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,45))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,45))
+ ├── name: :test
+ ├── name_loc: (1,4)-(1,8) = "test"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,9)-(1,18))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,9)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :testing
+ │ │ ├── name_loc: (1,11)-(1,18) = "testing"
+ │ │ └── operator_loc: (1,9)-(1,11) = "**"
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,20)-(1,41))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,20)-(1,41))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :test_splat
+ │ ├── message_loc: (1,20)-(1,30) = "test_splat"
+ │ ├── opening_loc: (1,30)-(1,31) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,31)-(1,40))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,31)-(1,40))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (1,31)-(1,40))
+ │ │ ├── value:
+ │ │ │ @ LocalVariableReadNode (location: (1,33)-(1,40))
+ │ │ │ ├── name: :testing
+ │ │ │ └── depth: 0
+ │ │ └── operator_loc: (1,31)-(1,33) = "**"
+ │ ├── closing_loc: (1,40)-(1,41) = ")"
+ │ └── block: ∅
+ ├── locals: [:testing]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,8)-(1,9) = "("
+ ├── rparen_loc: (1,18)-(1,19) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,42)-(1,45) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt b/test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt
new file mode 100644
index 0000000000..8a5022ff37
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt
@@ -0,0 +1,45 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,24))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,19))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── name: :a
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 2)
+ │ │ ├── @ OptionalKeywordParameterNode (location: (1,9)-(1,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,9)-(1,11) = "b:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,15)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :c
+ │ │ ├── name_loc: (1,15)-(1,17) = "c:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,18)-(1,19))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a, :b, :c]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,19)-(1,20) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,21)-(1,24) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt b/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt
new file mode 100644
index 0000000000..4c980bc27f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,20))
+ ├── name: :a
+ ├── name_loc: (1,4)-(1,5) = "a"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,15))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,6)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,6)-(1,8) = "b:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,12)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :c
+ │ │ ├── name_loc: (1,14)-(1,15) = "c"
+ │ │ └── operator_loc: (1,12)-(1,14) = "**"
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:b, :c]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,15)-(1,16) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,17)-(1,20) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt b/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt
new file mode 100644
index 0000000000..40afacc2a7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,19))
+ ├── name: :a
+ ├── name_loc: (1,4)-(1,5) = "a"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,14))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,6)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,6)-(1,8) = "b:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,12)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,12)-(1,14) = "**"
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:b]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,14)-(1,15) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,16)-(1,19) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt b/test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt
new file mode 100644
index 0000000000..0eae56924c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,26))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,26))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,26))
+ ├── name: :fun
+ ├── name_loc: (1,4)-(1,7) = "fun"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,16))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,8)-(1,16))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :kw
+ │ │ ├── name_loc: (1,8)-(1,11) = "kw:"
+ │ │ └── value:
+ │ │ @ SymbolNode (location: (1,12)-(1,16))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,12)-(1,13) = ":"
+ │ │ ├── value_loc: (1,13)-(1,16) = "val"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "val"
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,19)-(1,21))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (1,19)-(1,21))
+ │ ├── name: :kw
+ │ └── depth: 0
+ ├── locals: [:kw]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,16)-(1,17) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,23)-(1,26) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt b/test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt
new file mode 100644
index 0000000000..bc5747ad02
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(2,3))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,10))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,6)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :a
+ │ │ ├── name_loc: (1,6)-(1,8) = "a:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (2,0)-(2,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_val.txt b/test/prism/snapshots/seattlerb/defn_kwarg_val.txt
new file mode 100644
index 0000000000..82527f7875
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_kwarg_val.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,17))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,12))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── name: :a
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,9)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,9)-(1,11) = "b:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,11)-(1,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a, :b]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,12)-(1,13) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,14)-(1,17) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_no_kwargs.txt b/test/prism/snapshots/seattlerb/defn_no_kwargs.txt
new file mode 100644
index 0000000000..0ef0634a53
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_no_kwargs.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,17))
+ ├── name: :x
+ ├── name_loc: (1,4)-(1,5) = "x"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,11))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ NoKeywordsParameterNode (location: (1,6)-(1,11))
+ │ │ ├── operator_loc: (1,6)-(1,8) = "**"
+ │ │ └── keyword_loc: (1,8)-(1,11) = "nil"
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,11)-(1,12) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,14)-(1,17) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_oneliner.txt b/test/prism/snapshots/seattlerb/defn_oneliner.txt
new file mode 100644
index 0000000000..e700499809
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_oneliner.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(1,27))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,27))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,27))
+ ├── name: :exec
+ ├── name_loc: (1,4)-(1,8) = "exec"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,9)-(1,12))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ └── name: :cmd
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,16)-(1,27))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,16)-(1,27))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :system
+ │ ├── message_loc: (1,16)-(1,22) = "system"
+ │ ├── opening_loc: (1,22)-(1,23) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,23)-(1,26))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (1,23)-(1,26))
+ │ │ ├── name: :cmd
+ │ │ └── depth: 0
+ │ ├── closing_loc: (1,26)-(1,27) = ")"
+ │ └── block: ∅
+ ├── locals: [:cmd]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,8)-(1,9) = "("
+ ├── rparen_loc: (1,12)-(1,13) = ")"
+ ├── equal_loc: (1,14)-(1,15) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt b/test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt
new file mode 100644
index 0000000000..2708351ede
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ ClassNode (location: (1,0)-(3,3))
+ ├── locals: []
+ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (1,6)-(1,7))
+ │ └── name: :X
+ ├── inheritance_operator_loc: ∅
+ ├── superclass: ∅
+ ├── body:
+ │ @ StatementsNode (location: (2,2)-(2,16))
+ │ └── body: (length: 1)
+ │ └── @ DefNode (location: (2,2)-(2,16))
+ │ ├── name: :==
+ │ ├── name_loc: (2,6)-(2,8) = "=="
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (2,9)-(2,10))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (2,9)-(2,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :o
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,14)-(2,16))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (2,14)-(2,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── locals: [:o]
+ │ ├── def_keyword_loc: (2,2)-(2,5) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (2,8)-(2,9) = "("
+ │ ├── rparen_loc: (2,10)-(2,11) = ")"
+ │ ├── equal_loc: (2,12)-(2,13) = "="
+ │ └── end_keyword_loc: ∅
+ ├── end_keyword_loc: (3,0)-(3,3) = "end"
+ └── name: :X
diff --git a/test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt b/test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt
new file mode 100644
index 0000000000..54555b1a23
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,17))
+ ├── name: :exec
+ ├── name_loc: (1,4)-(1,8) = "exec"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,11)-(1,17))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,11)-(1,17))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :system
+ │ ├── message_loc: (1,11)-(1,17) = "system"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: (1,9)-(1,10) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt b/test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt
new file mode 100644
index 0000000000..e0fc4636f1
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,19))
+ ├── name: :exec
+ ├── name_loc: (1,4)-(1,8) = "exec"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,13)-(1,19))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,13)-(1,19))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :system
+ │ ├── message_loc: (1,13)-(1,19) = "system"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,8)-(1,9) = "("
+ ├── rparen_loc: (1,9)-(1,10) = ")"
+ ├── equal_loc: (1,11)-(1,12) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defn_oneliner_rescue.txt b/test/prism/snapshots/seattlerb/defn_oneliner_rescue.txt
new file mode 100644
index 0000000000..b5b5dbe6ac
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_oneliner_rescue.txt
@@ -0,0 +1,158 @@
+@ ProgramNode (location: (1,0)-(13,38))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(13,38))
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,0)-(5,3))
+ │ ├── name: :exec
+ │ ├── name_loc: (1,4)-(1,8) = "exec"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,9)-(1,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :cmd
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (1,0)-(5,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (2,2)-(2,13))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,2)-(2,13))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :system
+ │ │ │ ├── message_loc: (2,2)-(2,8) = "system"
+ │ │ │ ├── opening_loc: (2,8)-(2,9) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (2,9)-(2,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (2,9)-(2,12))
+ │ │ │ │ ├── name: :cmd
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: (2,12)-(2,13) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (3,0)-(4,5))
+ │ │ │ ├── keyword_loc: (3,0)-(3,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (4,2)-(4,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ NilNode (location: (4,2)-(4,5))
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ ├── locals: [:cmd]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ ├── rparen_loc: (1,12)-(1,13) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ DefNode (location: (8,0)-(10,3))
+ │ ├── name: :exec
+ │ ├── name_loc: (8,4)-(8,8) = "exec"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (8,9)-(8,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (8,9)-(8,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :cmd
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (9,2)-(9,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (9,2)-(9,24))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (9,2)-(9,13))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :system
+ │ │ │ ├── message_loc: (9,2)-(9,8) = "system"
+ │ │ │ ├── opening_loc: (9,8)-(9,9) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (9,9)-(9,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (9,9)-(9,12))
+ │ │ │ │ ├── name: :cmd
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: (9,12)-(9,13) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (9,14)-(9,20) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (9,21)-(9,24))
+ │ ├── locals: [:cmd]
+ │ ├── def_keyword_loc: (8,0)-(8,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (8,8)-(8,9) = "("
+ │ ├── rparen_loc: (8,12)-(8,13) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (10,0)-(10,3) = "end"
+ └── @ DefNode (location: (13,0)-(13,38))
+ ├── name: :exec
+ ├── name_loc: (13,4)-(13,8) = "exec"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (13,9)-(13,12))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (13,9)-(13,12))
+ │ │ ├── flags: ∅
+ │ │ └── name: :cmd
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (13,16)-(13,38))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (13,16)-(13,38))
+ │ ├── expression:
+ │ │ @ CallNode (location: (13,16)-(13,27))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :system
+ │ │ ├── message_loc: (13,16)-(13,22) = "system"
+ │ │ ├── opening_loc: (13,22)-(13,23) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (13,23)-(13,26))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (13,23)-(13,26))
+ │ │ │ ├── name: :cmd
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: (13,26)-(13,27) = ")"
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (13,28)-(13,34) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (13,35)-(13,38))
+ ├── locals: [:cmd]
+ ├── def_keyword_loc: (13,0)-(13,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (13,8)-(13,9) = "("
+ ├── rparen_loc: (13,12)-(13,13) = ")"
+ ├── equal_loc: (13,14)-(13,15) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defn_opt_last_arg.txt b/test/prism/snapshots/seattlerb/defn_opt_last_arg.txt
new file mode 100644
index 0000000000..569bc23078
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_opt_last_arg.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(2,3))
+ ├── name: :m
+ ├── name_loc: (1,4)-(1,5) = "m"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,17))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 1)
+ │ │ └── @ OptionalParameterNode (location: (1,6)-(1,17))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :arg
+ │ │ ├── name_loc: (1,6)-(1,9) = "arg"
+ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ └── value:
+ │ │ @ FalseNode (location: (1,12)-(1,17))
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:arg]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (2,0)-(2,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_opt_reg.txt b/test/prism/snapshots/seattlerb/defn_opt_reg.txt
new file mode 100644
index 0000000000..f86168513a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_opt_reg.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,19))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,14))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 1)
+ │ │ └── @ OptionalParameterNode (location: (1,6)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :a
+ │ │ ├── name_loc: (1,6)-(1,7) = "a"
+ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ └── value:
+ │ │ @ NilNode (location: (1,8)-(1,11))
+ │ ├── rest: ∅
+ │ ├── posts: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ └── name: :b
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a, :b]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,14)-(1,15) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,16)-(1,19) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt b/test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt
new file mode 100644
index 0000000000..3019e9b73e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,24))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,7)-(1,19))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 1)
+ │ │ └── @ OptionalParameterNode (location: (1,7)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :a
+ │ │ ├── name_loc: (1,7)-(1,8) = "a"
+ │ │ ├── operator_loc: (1,9)-(1,10) = "="
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,11)-(1,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (1,14)-(1,16))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,15)-(1,16) = "b"
+ │ │ └── operator_loc: (1,14)-(1,15) = "*"
+ │ ├── posts: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,18)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ └── name: :c
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a, :b, :c]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,6)-(1,7) = "("
+ ├── rparen_loc: (1,19)-(1,20) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,21)-(1,24) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_powarg.txt b/test/prism/snapshots/seattlerb/defn_powarg.txt
new file mode 100644
index 0000000000..bce131ad18
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_powarg.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,17))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,12))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,6)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :opts
+ │ │ ├── name_loc: (1,8)-(1,12) = "opts"
+ │ │ └── operator_loc: (1,6)-(1,8) = "**"
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:opts]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,12)-(1,13) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,14)-(1,17) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt b/test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt
new file mode 100644
index 0000000000..d079e1b5f3
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,23))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,18))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── name: :a
+ │ ├── optionals: (length: 1)
+ │ │ └── @ OptionalParameterNode (location: (1,9)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,9)-(1,10) = "b"
+ │ │ ├── operator_loc: (1,11)-(1,12) = "="
+ │ │ └── value:
+ │ │ @ SymbolNode (location: (1,13)-(1,15))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,13)-(1,14) = ":"
+ │ │ ├── value_loc: (1,14)-(1,15) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── rest: ∅
+ │ ├── posts: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,17)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ └── name: :d
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a, :b, :d]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,18)-(1,19) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,20)-(1,23) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_splat_arg.txt b/test/prism/snapshots/seattlerb/defn_splat_arg.txt
new file mode 100644
index 0000000000..109fac495a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_splat_arg.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,15))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,10))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,6)-(1,7) = "*"
+ │ ├── posts: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ └── name: :a
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,10)-(1,11) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,12)-(1,15) = "end"
diff --git a/test/prism/snapshots/seattlerb/defn_unary_not.txt b/test/prism/snapshots/seattlerb/defn_unary_not.txt
new file mode 100644
index 0000000000..231a3c0da9
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defn_unary_not.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,17))
+ ├── name: :!
+ ├── name_loc: (1,4)-(1,6) = "!@"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,8)-(1,12))
+ │ └── body: (length: 1)
+ │ └── @ TrueNode (location: (1,8)-(1,12))
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,14)-(1,17) = "end"
diff --git a/test/prism/snapshots/seattlerb/defns_reserved.txt b/test/prism/snapshots/seattlerb/defns_reserved.txt
new file mode 100644
index 0000000000..96860b49ce
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defns_reserved.txt
@@ -0,0 +1,19 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,20))
+ ├── name: :return
+ ├── name_loc: (1,9)-(1,15) = "return"
+ ├── receiver:
+ │ @ SelfNode (location: (1,4)-(1,8))
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: (1,8)-(1,9) = "."
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,17)-(1,20) = "end"
diff --git a/test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt b/test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt
new file mode 100644
index 0000000000..24bb14f8e1
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt
@@ -0,0 +1,60 @@
+@ ProgramNode (location: (1,0)-(1,30))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,30))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,30))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,30))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ DefNode (location: (1,2)-(1,30))
+ │ ├── name: :b
+ │ ├── name_loc: (1,11)-(1,12) = "b"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (1,6)-(1,10))
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,14)-(1,25))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,14)-(1,25))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,14)-(1,15))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── message_loc: (1,14)-(1,15) = "x"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (1,15)-(1,16) = "."
+ │ │ ├── name: :y
+ │ │ ├── message_loc: (1,16)-(1,17) = "y"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,18)-(1,25))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (1,18)-(1,20) = "do"
+ │ │ └── closing_loc: (1,22)-(1,25) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,2)-(1,5) = "def"
+ │ ├── operator_loc: (1,10)-(1,11) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,27)-(1,30) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/defs_comments.txt b/test/prism/snapshots/seattlerb/defs_comments.txt
new file mode 100644
index 0000000000..a2976e7ee2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defs_comments.txt
@@ -0,0 +1,19 @@
+@ ProgramNode (location: (4,0)-(5,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (4,0)-(5,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (4,0)-(5,3))
+ ├── name: :blah
+ ├── name_loc: (4,9)-(4,13) = "blah"
+ ├── receiver:
+ │ @ SelfNode (location: (4,4)-(4,8))
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (4,0)-(4,3) = "def"
+ ├── operator_loc: (4,8)-(4,9) = "."
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (5,0)-(5,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/defs_endless_command.txt b/test/prism/snapshots/seattlerb/defs_endless_command.txt
new file mode 100644
index 0000000000..f3c4e79417
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defs_endless_command.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,35))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,35))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,35))
+ ├── name: :some_method
+ ├── name_loc: (1,6)-(1,17) = "some_method"
+ ├── receiver:
+ │ @ CallNode (location: (1,4)-(1,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :x
+ │ ├── message_loc: (1,4)-(1,5) = "x"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,20)-(1,35))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,20)-(1,35))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :other_method
+ │ ├── message_loc: (1,20)-(1,32) = "other_method"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,33)-(1,35))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,33)-(1,35))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: (1,5)-(1,6) = "."
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: (1,18)-(1,19) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt b/test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt
new file mode 100644
index 0000000000..b0cd34a9c8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt
@@ -0,0 +1,53 @@
+@ ProgramNode (location: (1,0)-(1,45))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,45))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,45))
+ ├── name: :some_method
+ ├── name_loc: (1,6)-(1,17) = "some_method"
+ ├── receiver:
+ │ @ CallNode (location: (1,4)-(1,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :x
+ │ ├── message_loc: (1,4)-(1,5) = "x"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,20)-(1,45))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (1,20)-(1,45))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,20)-(1,35))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :other_method
+ │ │ ├── message_loc: (1,20)-(1,32) = "other_method"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,33)-(1,35))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,33)-(1,35))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,36)-(1,42) = "rescue"
+ │ └── rescue_expression:
+ │ @ IntegerNode (location: (1,43)-(1,45))
+ │ ├── flags: decimal
+ │ └── value: 24
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: (1,5)-(1,6) = "."
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: (1,18)-(1,19) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defs_kwarg.txt b/test/prism/snapshots/seattlerb/defs_kwarg.txt
new file mode 100644
index 0000000000..53235c9bb8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defs_kwarg.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(2,3))
+ ├── name: :a
+ ├── name_loc: (1,9)-(1,10) = "a"
+ ├── receiver:
+ │ @ SelfNode (location: (1,4)-(1,8))
+ ├── parameters:
+ │ @ ParametersNode (location: (1,11)-(1,15))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,11)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,11)-(1,13) = "b:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,14)-(1,15))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:b]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: (1,8)-(1,9) = "."
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (2,0)-(2,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/defs_oneliner.txt b/test/prism/snapshots/seattlerb/defs_oneliner.txt
new file mode 100644
index 0000000000..d32975354d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defs_oneliner.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(1,32))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,32))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,32))
+ ├── name: :exec
+ ├── name_loc: (1,9)-(1,13) = "exec"
+ ├── receiver:
+ │ @ SelfNode (location: (1,4)-(1,8))
+ ├── parameters:
+ │ @ ParametersNode (location: (1,14)-(1,17))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,17))
+ │ │ ├── flags: ∅
+ │ │ └── name: :cmd
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,21)-(1,32))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,21)-(1,32))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :system
+ │ ├── message_loc: (1,21)-(1,27) = "system"
+ │ ├── opening_loc: (1,27)-(1,28) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,28)-(1,31))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (1,28)-(1,31))
+ │ │ ├── name: :cmd
+ │ │ └── depth: 0
+ │ ├── closing_loc: (1,31)-(1,32) = ")"
+ │ └── block: ∅
+ ├── locals: [:cmd]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: (1,8)-(1,9) = "."
+ ├── lparen_loc: (1,13)-(1,14) = "("
+ ├── rparen_loc: (1,17)-(1,18) = ")"
+ ├── equal_loc: (1,19)-(1,20) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt b/test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt
new file mode 100644
index 0000000000..fcc5c63cf0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ ClassNode (location: (1,0)-(3,3))
+ ├── locals: []
+ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (1,6)-(1,7))
+ │ └── name: :X
+ ├── inheritance_operator_loc: ∅
+ ├── superclass: ∅
+ ├── body:
+ │ @ StatementsNode (location: (2,2)-(2,21))
+ │ └── body: (length: 1)
+ │ └── @ DefNode (location: (2,2)-(2,21))
+ │ ├── name: :==
+ │ ├── name_loc: (2,11)-(2,13) = "=="
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (2,6)-(2,10))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (2,14)-(2,15))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (2,14)-(2,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :o
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,19)-(2,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (2,19)-(2,21))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── locals: [:o]
+ │ ├── def_keyword_loc: (2,2)-(2,5) = "def"
+ │ ├── operator_loc: (2,10)-(2,11) = "."
+ │ ├── lparen_loc: (2,13)-(2,14) = "("
+ │ ├── rparen_loc: (2,15)-(2,16) = ")"
+ │ ├── equal_loc: (2,17)-(2,18) = "="
+ │ └── end_keyword_loc: ∅
+ ├── end_keyword_loc: (3,0)-(3,3) = "end"
+ └── name: :X
diff --git a/test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt b/test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt
new file mode 100644
index 0000000000..f776210768
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt
@@ -0,0 +1,161 @@
+@ ProgramNode (location: (1,0)-(13,43))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(13,43))
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,0)-(5,3))
+ │ ├── name: :exec
+ │ ├── name_loc: (1,9)-(1,13) = "exec"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (1,4)-(1,8))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,14)-(1,17))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :cmd
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (1,0)-(5,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (2,2)-(2,13))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,2)-(2,13))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :system
+ │ │ │ ├── message_loc: (2,2)-(2,8) = "system"
+ │ │ │ ├── opening_loc: (2,8)-(2,9) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (2,9)-(2,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (2,9)-(2,12))
+ │ │ │ │ ├── name: :cmd
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: (2,12)-(2,13) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (3,0)-(4,5))
+ │ │ │ ├── keyword_loc: (3,0)-(3,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (4,2)-(4,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ NilNode (location: (4,2)-(4,5))
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ ├── locals: [:cmd]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: (1,8)-(1,9) = "."
+ │ ├── lparen_loc: (1,13)-(1,14) = "("
+ │ ├── rparen_loc: (1,17)-(1,18) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ DefNode (location: (8,0)-(10,3))
+ │ ├── name: :exec
+ │ ├── name_loc: (8,9)-(8,13) = "exec"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (8,4)-(8,8))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (8,14)-(8,17))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (8,14)-(8,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :cmd
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (9,2)-(9,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (9,2)-(9,24))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (9,2)-(9,13))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :system
+ │ │ │ ├── message_loc: (9,2)-(9,8) = "system"
+ │ │ │ ├── opening_loc: (9,8)-(9,9) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (9,9)-(9,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (9,9)-(9,12))
+ │ │ │ │ ├── name: :cmd
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: (9,12)-(9,13) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (9,14)-(9,20) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (9,21)-(9,24))
+ │ ├── locals: [:cmd]
+ │ ├── def_keyword_loc: (8,0)-(8,3) = "def"
+ │ ├── operator_loc: (8,8)-(8,9) = "."
+ │ ├── lparen_loc: (8,13)-(8,14) = "("
+ │ ├── rparen_loc: (8,17)-(8,18) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (10,0)-(10,3) = "end"
+ └── @ DefNode (location: (13,0)-(13,43))
+ ├── name: :exec
+ ├── name_loc: (13,9)-(13,13) = "exec"
+ ├── receiver:
+ │ @ SelfNode (location: (13,4)-(13,8))
+ ├── parameters:
+ │ @ ParametersNode (location: (13,14)-(13,17))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (13,14)-(13,17))
+ │ │ ├── flags: ∅
+ │ │ └── name: :cmd
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (13,21)-(13,43))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (13,21)-(13,43))
+ │ ├── expression:
+ │ │ @ CallNode (location: (13,21)-(13,32))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :system
+ │ │ ├── message_loc: (13,21)-(13,27) = "system"
+ │ │ ├── opening_loc: (13,27)-(13,28) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (13,28)-(13,31))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (13,28)-(13,31))
+ │ │ │ ├── name: :cmd
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: (13,31)-(13,32) = ")"
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (13,33)-(13,39) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (13,40)-(13,43))
+ ├── locals: [:cmd]
+ ├── def_keyword_loc: (13,0)-(13,3) = "def"
+ ├── operator_loc: (13,8)-(13,9) = "."
+ ├── lparen_loc: (13,13)-(13,14) = "("
+ ├── rparen_loc: (13,17)-(13,18) = ")"
+ ├── equal_loc: (13,19)-(13,20) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult0_.txt b/test/prism/snapshots/seattlerb/difficult0_.txt
new file mode 100644
index 0000000000..8ba30ccf85
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult0_.txt
@@ -0,0 +1,73 @@
+@ ProgramNode (location: (1,0)-(4,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(4,8))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(4,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,2)-(4,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,2)-(4,4))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ StringNode (location: (1,2)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,2)-(1,8) = "<<-END"
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " a\n"
+ │ │ │ ├── closing_loc: (3,0)-(4,0) = " END\n"
+ │ │ │ └── unescaped: " a\n"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :+
+ │ │ ├── message_loc: (1,8)-(1,9) = "+"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,9)-(4,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ InterpolatedStringNode (location: (1,9)-(4,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,9)-(1,10) = "'"
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (1,10)-(2,0))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (1,10)-(2,0) = "b\n"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "b\n"
+ │ │ │ │ └── @ StringNode (location: (4,0)-(4,3))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (4,0)-(4,3) = " c"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " c"
+ │ │ │ └── closing_loc: (4,3)-(4,4) = "'"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (4,4)-(4,5) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (4,5)-(4,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (4,5)-(4,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (4,5)-(4,6) = "'"
+ │ │ ├── content_loc: (4,6)-(4,7) = "d"
+ │ │ ├── closing_loc: (4,7)-(4,8) = "'"
+ │ │ └── unescaped: "d"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult1_line_numbers.txt b/test/prism/snapshots/seattlerb/difficult1_line_numbers.txt
new file mode 100644
index 0000000000..da2306312c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult1_line_numbers.txt
@@ -0,0 +1,267 @@
+@ ProgramNode (location: (1,0)-(12,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(12,3))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(12,3))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ TrueNode (location: (1,3)-(1,7))
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (2,2)-(11,11))
+ │ └── body: (length: 10)
+ │ ├── @ CallNode (location: (2,2)-(2,5))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :p
+ │ │ ├── message_loc: (2,2)-(2,3) = "p"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (2,4)-(2,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (2,4)-(2,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── @ CallNode (location: (3,2)-(3,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (3,2)-(3,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (3,2)-(3,3) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (3,3)-(3,4) = "."
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (3,4)-(3,5) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,6)-(3,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,6)-(3,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── @ CallNode (location: (4,2)-(4,10))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (4,2)-(4,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (4,2)-(4,3) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (4,3)-(4,4) = "."
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (4,4)-(4,5) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (4,6)-(4,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (4,6)-(4,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 3
+ │ │ │ └── @ IntegerNode (location: (4,9)-(4,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 4
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── @ CallNode (location: (5,2)-(5,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (5,2)-(5,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :e
+ │ │ │ ├── message_loc: (5,2)-(5,3) = "e"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (5,3)-(5,4) = "."
+ │ │ ├── name: :f
+ │ │ ├── message_loc: (5,4)-(5,5) = "f"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,6)-(5,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,6)-(5,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 5
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── @ CallNode (location: (6,2)-(6,10))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (6,2)-(6,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :g
+ │ │ │ ├── message_loc: (6,2)-(6,3) = "g"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (6,3)-(6,4) = "."
+ │ │ ├── name: :h
+ │ │ ├── message_loc: (6,4)-(6,5) = "h"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (6,6)-(6,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (6,6)-(6,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 6
+ │ │ │ └── @ IntegerNode (location: (6,9)-(6,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 7
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── @ CallNode (location: (7,2)-(7,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :p
+ │ │ ├── message_loc: (7,2)-(7,3) = "p"
+ │ │ ├── opening_loc: (7,3)-(7,4) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,4)-(7,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (7,4)-(7,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: (7,5)-(7,6) = ")"
+ │ │ └── block: ∅
+ │ ├── @ CallNode (location: (8,2)-(8,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (8,2)-(8,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (8,2)-(8,3) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (8,3)-(8,4) = "."
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (8,4)-(8,5) = "b"
+ │ │ ├── opening_loc: (8,5)-(8,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (8,6)-(8,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (8,6)-(8,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: (8,7)-(8,8) = ")"
+ │ │ └── block: ∅
+ │ ├── @ CallNode (location: (9,2)-(9,11))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (9,2)-(9,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (9,2)-(9,3) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (9,3)-(9,4) = "."
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (9,4)-(9,5) = "d"
+ │ │ ├── opening_loc: (9,5)-(9,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (9,6)-(9,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (9,6)-(9,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 3
+ │ │ │ └── @ IntegerNode (location: (9,9)-(9,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 4
+ │ │ ├── closing_loc: (9,10)-(9,11) = ")"
+ │ │ └── block: ∅
+ │ ├── @ CallNode (location: (10,2)-(10,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (10,2)-(10,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :e
+ │ │ │ ├── message_loc: (10,2)-(10,3) = "e"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (10,3)-(10,4) = "."
+ │ │ ├── name: :f
+ │ │ ├── message_loc: (10,4)-(10,5) = "f"
+ │ │ ├── opening_loc: (10,5)-(10,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (10,6)-(10,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (10,6)-(10,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 5
+ │ │ ├── closing_loc: (10,7)-(10,8) = ")"
+ │ │ └── block: ∅
+ │ └── @ CallNode (location: (11,2)-(11,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (11,2)-(11,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :g
+ │ │ ├── message_loc: (11,2)-(11,3) = "g"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (11,3)-(11,4) = "."
+ │ ├── name: :h
+ │ ├── message_loc: (11,4)-(11,5) = "h"
+ │ ├── opening_loc: (11,5)-(11,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,6)-(11,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (11,6)-(11,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 6
+ │ │ └── @ IntegerNode (location: (11,9)-(11,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 7
+ │ ├── closing_loc: (11,10)-(11,11) = ")"
+ │ └── block: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (12,0)-(12,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt b/test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt
new file mode 100644
index 0000000000..f586634c59
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt
@@ -0,0 +1,78 @@
+@ ProgramNode (location: (1,0)-(7,1))
+├── locals: [:b, :c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,1))
+ └── body: (length: 2)
+ ├── @ IfNode (location: (1,0)-(6,3))
+ │ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (1,3)-(1,7))
+ │ ├── then_keyword_loc: (1,8)-(1,12) = "then"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,2)-(5,6))
+ │ │ └── body: (length: 4)
+ │ │ ├── @ CallNode (location: (2,2)-(2,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :p
+ │ │ │ ├── message_loc: (2,2)-(2,3) = "p"
+ │ │ │ ├── opening_loc: (2,3)-(2,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (2,4)-(2,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (2,4)-(2,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (2,4)-(2,5) = "\""
+ │ │ │ │ ├── content_loc: (2,5)-(2,6) = "a"
+ │ │ │ │ ├── closing_loc: (2,6)-(2,7) = "\""
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── closing_loc: (2,7)-(2,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── @ LocalVariableWriteNode (location: (3,2)-(3,7))
+ │ │ │ ├── name: :b
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (3,2)-(3,3) = "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (3,6)-(3,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: (3,4)-(3,5) = "="
+ │ │ ├── @ CallNode (location: (4,2)-(4,5))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :p
+ │ │ │ ├── message_loc: (4,2)-(4,3) = "p"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (4,4)-(4,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (4,4)-(4,5))
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ LocalVariableWriteNode (location: (5,2)-(5,6))
+ │ │ ├── name: :c
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (5,2)-(5,3) = "c"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (5,5)-(5,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (5,4)-(5,5) = "="
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (6,0)-(6,3) = "end"
+ └── @ CallNode (location: (7,0)-(7,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (7,0)-(7,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult2_.txt b/test/prism/snapshots/seattlerb/difficult2_.txt
new file mode 100644
index 0000000000..a9b3736fe3
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult2_.txt
@@ -0,0 +1,74 @@
+@ ProgramNode (location: (1,0)-(2,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,6))
+ └── body: (length: 2)
+ ├── @ IfNode (location: (1,0)-(1,13))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── then_keyword_loc: (1,2)-(1,3) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,4)-(1,9))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,9))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,6)-(1,7) = "'"
+ │ │ │ ├── content_loc: (1,7)-(1,7) = ""
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = "'"
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: (1,8)-(1,9) = ")"
+ │ │ └── block: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (1,10)-(1,13))
+ │ │ ├── else_keyword_loc: (1,10)-(1,11) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,12)-(1,13))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ └── @ CallNode (location: (2,0)-(2,6))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (2,0)-(2,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (2,2)-(2,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (2,2)-(2,6))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (2,2)-(2,6))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (2,2)-(2,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (2,2)-(2,3) = "d"
+ │ │ ├── closing_loc: (2,3)-(2,4) = ":"
+ │ │ └── unescaped: "d"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (2,5)-(2,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult3_.txt b/test/prism/snapshots/seattlerb/difficult3_.txt
new file mode 100644
index 0000000000..f074c49a9f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3_.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,18))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,18))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,16))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,15))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,15))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,12)-(1,14))
+ │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,14)-(1,15) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,15)-(1,16) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,17)-(1,18) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3_2.txt b/test/prism/snapshots/seattlerb/difficult3_2.txt
new file mode 100644
index 0000000000..af1a649171
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3_2.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,13))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,5)-(1,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (1,6)-(1,7) = "a"
+ │ │ │ └── operator_loc: (1,5)-(1,6) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,10)-(1,11) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,12)-(1,13) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3_3.txt b/test/prism/snapshots/seattlerb/difficult3_3.txt
new file mode 100644
index 0000000000..e49bbcd55a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3_3.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,5)-(1,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (1,6)-(1,7) = "a"
+ │ │ │ └── operator_loc: (1,5)-(1,6) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,12)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :c
+ │ │ ├── name_loc: (1,13)-(1,14) = "c"
+ │ │ └── operator_loc: (1,12)-(1,13) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3_4.txt b/test/prism/snapshots/seattlerb/difficult3_4.txt
new file mode 100644
index 0000000000..73afffb4cb
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3_4.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,17))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ IfNode (location: (1,2)-(1,17))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,2)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,2)-(1,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (1,4)-(1,5) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,6)-(1,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ TrueNode (location: (1,6)-(1,10))
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (1,10)-(1,17))
+ │ │ ├── else_keyword_loc: (1,10)-(1,11) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,12)-(1,17))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ FalseNode (location: (1,12)-(1,17))
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ └── operator_loc: (1,1)-(1,2) = "="
diff --git a/test/prism/snapshots/seattlerb/difficult3_5.txt b/test/prism/snapshots/seattlerb/difficult3_5.txt
new file mode 100644
index 0000000000..793c3f1e11
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3_5.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,19))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,19))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LambdaNode (location: (1,2)-(1,19))
+ │ ├── locals: []
+ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ ├── opening_loc: (1,7)-(1,8) = "{"
+ │ ├── closing_loc: (1,18)-(1,19) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,4)-(1,6))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ │ └── closing_loc: (1,5)-(1,6) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (1,9)-(1,17))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,9)-(1,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :g
+ │ ├── message_loc: (1,9)-(1,10) = "g"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,11)-(1,17))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,11)-(1,13) = "do"
+ │ └── closing_loc: (1,14)-(1,17) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult3__10.txt b/test/prism/snapshots/seattlerb/difficult3__10.txt
new file mode 100644
index 0000000000..0131e44d44
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3__10.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,18))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,18))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,16))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,15))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,15))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,9)-(1,11))
+ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,14)-(1,15) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,15)-(1,16) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,17)-(1,18) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3__11.txt b/test/prism/snapshots/seattlerb/difficult3__11.txt
new file mode 100644
index 0000000000..a658b091c2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3__11.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,14))
+ ├── locals: [:a]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,11))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,11))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,10)-(1,11) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,13)-(1,14) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3__12.txt b/test/prism/snapshots/seattlerb/difficult3__12.txt
new file mode 100644
index 0000000000..5aa252fe6a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3__12.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,14))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,13)-(1,14) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3__6.txt b/test/prism/snapshots/seattlerb/difficult3__6.txt
new file mode 100644
index 0000000000..a42a625be7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3__6.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,21))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,21))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,21))
+ ├── locals: [:a, :b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,19))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,18))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,18))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,12)-(1,14))
+ │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,16)-(1,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :d
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,17)-(1,18) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,18)-(1,19) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,20)-(1,21) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3__7.txt b/test/prism/snapshots/seattlerb/difficult3__7.txt
new file mode 100644
index 0000000000..b08025804c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3__7.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,14))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,12)-(1,13))
+ │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,13)-(1,14) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3__8.txt b/test/prism/snapshots/seattlerb/difficult3__8.txt
new file mode 100644
index 0000000000..b2b118faef
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3__8.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,20))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,20))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,18))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,17))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,17))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,12)-(1,13))
+ │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,15)-(1,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,16)-(1,17) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,17)-(1,18) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,19)-(1,20) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult3__9.txt b/test/prism/snapshots/seattlerb/difficult3__9.txt
new file mode 100644
index 0000000000..85c10a4432
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult3__9.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,15))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,15))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,13))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,12))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ MultiTargetNode (location: (1,8)-(1,12))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (1,9)-(1,11))
+ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ └── rparen_loc: (1,11)-(1,12) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,12)-(1,13) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,14)-(1,15) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult4__leading_dots.txt b/test/prism/snapshots/seattlerb/difficult4__leading_dots.txt
new file mode 100644
index 0000000000..8307c806e6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult4__leading_dots.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(2,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,2))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(2,2))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (2,0)-(2,1) = "."
+ ├── name: :b
+ ├── message_loc: (2,1)-(2,2) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt b/test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt
new file mode 100644
index 0000000000..ee4370c0f0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt
@@ -0,0 +1,16 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 2)
+ ├── @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── @ RangeNode (location: (2,0)-(2,3))
+ ├── flags: ∅
+ ├── left: ∅
+ ├── right:
+ │ @ IntegerNode (location: (2,2)-(2,3))
+ │ ├── flags: decimal
+ │ └── value: 3
+ └── operator_loc: (2,0)-(2,2) = ".."
diff --git a/test/prism/snapshots/seattlerb/difficult6_.txt b/test/prism/snapshots/seattlerb/difficult6_.txt
new file mode 100644
index 0000000000..bf80034fe9
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult6_.txt
@@ -0,0 +1,61 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,25))
+ ├── locals: [:a, :b]
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,13)-(1,14) = "{"
+ ├── closing_loc: (1,24)-(1,25) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,2)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,3)-(1,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,6)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,6)-(1,7) = "b"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ NilNode (location: (1,8)-(1,11))
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,11)-(1,12) = ")"
+ └── body:
+ @ StatementsNode (location: (1,15)-(1,23))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,15)-(1,23))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,15)-(1,16) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,17)-(1,23))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ArrayNode (location: (1,17)-(1,23))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ LocalVariableReadNode (location: (1,18)-(1,19))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableReadNode (location: (1,21)-(1,22))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── opening_loc: (1,17)-(1,18) = "["
+ │ └── closing_loc: (1,22)-(1,23) = "]"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/difficult6__7.txt b/test/prism/snapshots/seattlerb/difficult6__7.txt
new file mode 100644
index 0000000000..7fe70c7033
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult6__7.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,11))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :b
+ ├── message_loc: (1,2)-(1,3) = "b"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,4)-(1,7))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (1,6)-(1,7) = ")"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,8)-(1,11))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,9)-(1,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,9)-(1,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :c
+ │ ├── message_loc: (1,9)-(1,10) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (1,8)-(1,9) = "{"
+ └── closing_loc: (1,10)-(1,11) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult6__8.txt b/test/prism/snapshots/seattlerb/difficult6__8.txt
new file mode 100644
index 0000000000..7f915e283c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult6__8.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "::"
+ ├── name: :b
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,5)-(1,8))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,6)-(1,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ └── closing_loc: (1,7)-(1,8) = ")"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,9)-(1,12))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,10)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,10)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :c
+ │ ├── message_loc: (1,10)-(1,11) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (1,9)-(1,10) = "{"
+ └── closing_loc: (1,11)-(1,12) = "}"
diff --git a/test/prism/snapshots/seattlerb/difficult7_.txt b/test/prism/snapshots/seattlerb/difficult7_.txt
new file mode 100644
index 0000000000..40c778cf6c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/difficult7_.txt
@@ -0,0 +1,93 @@
+@ ProgramNode (location: (1,6)-(4,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,6)-(4,7))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,6)-(4,7))
+ ├── opening_loc: (1,6)-(1,7) = "{"
+ ├── elements: (length: 2)
+ │ ├── @ AssocNode (location: (2,8)-(2,33))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (2,8)-(2,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (2,8)-(2,9) = "a"
+ │ │ │ ├── closing_loc: (2,9)-(2,10) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (2,11)-(2,33))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :lambda
+ │ │ │ ├── message_loc: (2,11)-(2,17) = "lambda"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (2,18)-(2,33))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (2,20)-(2,31))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IfNode (location: (2,20)-(2,31))
+ │ │ │ │ ├── if_keyword_loc: ∅
+ │ │ │ │ ├── predicate:
+ │ │ │ │ │ @ CallNode (location: (2,20)-(2,21))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ ├── message_loc: (2,20)-(2,21) = "b"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── then_keyword_loc: (2,22)-(2,23) = "?"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (2,24)-(2,27))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (2,24)-(2,27))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :c
+ │ │ │ │ │ ├── message_loc: (2,24)-(2,25) = "c"
+ │ │ │ │ │ ├── opening_loc: (2,25)-(2,26) = "("
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: (2,26)-(2,27) = ")"
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── consequent:
+ │ │ │ │ │ @ ElseNode (location: (2,28)-(2,31))
+ │ │ │ │ │ ├── else_keyword_loc: (2,28)-(2,29) = ":"
+ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ @ StatementsNode (location: (2,30)-(2,31))
+ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ └── @ CallNode (location: (2,30)-(2,31))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ │ ├── message_loc: (2,30)-(2,31) = "d"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ └── end_keyword_loc: ∅
+ │ │ │ │ └── end_keyword_loc: ∅
+ │ │ │ ├── opening_loc: (2,18)-(2,19) = "{"
+ │ │ │ └── closing_loc: (2,32)-(2,33) = "}"
+ │ │ └── operator_loc: ∅
+ │ └── @ AssocNode (location: (3,8)-(3,14))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (3,8)-(3,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (3,8)-(3,9) = "e"
+ │ │ ├── closing_loc: (3,9)-(3,10) = ":"
+ │ │ └── unescaped: "e"
+ │ ├── value:
+ │ │ @ NilNode (location: (3,11)-(3,14))
+ │ └── operator_loc: ∅
+ └── closing_loc: (4,6)-(4,7) = "}"
diff --git a/test/prism/snapshots/seattlerb/do_bug.txt b/test/prism/snapshots/seattlerb/do_bug.txt
new file mode 100644
index 0000000000..5877b18d68
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/do_bug.txt
@@ -0,0 +1,63 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,2)-(1,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (2,0)-(4,3))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (2,0)-(2,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (2,0)-(2,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (2,1)-(2,2) = "."
+ ├── name: :b
+ ├── message_loc: (2,2)-(2,3) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (2,4)-(4,3))
+ ├── locals: [:c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (2,7)-(2,10))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (2,8)-(2,9))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (2,8)-(2,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (2,7)-(2,8) = "|"
+ │ └── closing_loc: (2,9)-(2,10) = "|"
+ ├── body: ∅
+ ├── opening_loc: (2,4)-(2,6) = "do"
+ └── closing_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/do_lambda.txt b/test/prism/snapshots/seattlerb/do_lambda.txt
new file mode 100644
index 0000000000..4713fb3e4b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/do_lambda.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,11))
+ ├── locals: []
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,5)-(1,7) = "do"
+ ├── closing_loc: (1,8)-(1,11) = "end"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,2)-(1,4))
+ │ ├── parameters: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,3)-(1,4) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/seattlerb/dot2_nil__26.txt b/test/prism/snapshots/seattlerb/dot2_nil__26.txt
new file mode 100644
index 0000000000..104515ac3a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dot2_nil__26.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ RangeNode (location: (1,0)-(1,3))
+ ├── flags: ∅
+ ├── left:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── right: ∅
+ └── operator_loc: (1,1)-(1,3) = ".."
diff --git a/test/prism/snapshots/seattlerb/dot3_nil__26.txt b/test/prism/snapshots/seattlerb/dot3_nil__26.txt
new file mode 100644
index 0000000000..ec7f57cd96
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dot3_nil__26.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ RangeNode (location: (1,0)-(1,4))
+ ├── flags: exclude_end
+ ├── left:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── right: ∅
+ └── operator_loc: (1,1)-(1,4) = "..."
diff --git a/test/prism/snapshots/seattlerb/dstr_evstr.txt b/test/prism/snapshots/seattlerb/dstr_evstr.txt
new file mode 100644
index 0000000000..8d771e88c2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dstr_evstr.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,12))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 2)
+ │ ├── @ EmbeddedStatementsNode (location: (1,1)-(1,7))
+ │ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,3)-(1,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ StringNode (location: (1,3)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,3)-(1,4) = "'"
+ │ │ │ ├── content_loc: (1,4)-(1,5) = "a"
+ │ │ │ ├── closing_loc: (1,5)-(1,6) = "'"
+ │ │ │ └── unescaped: "a"
+ │ │ └── closing_loc: (1,6)-(1,7) = "}"
+ │ └── @ EmbeddedStatementsNode (location: (1,7)-(1,11))
+ │ ├── opening_loc: (1,7)-(1,9) = "\#{"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,9)-(1,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,9)-(1,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,9)-(1,10) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── closing_loc: (1,10)-(1,11) = "}"
+ └── closing_loc: (1,11)-(1,12) = "\""
diff --git a/test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt b/test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt
new file mode 100644
index 0000000000..53f97e4b36
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ InterpolatedSymbolNode (location: (1,0)-(1,11))
+ ├── opening_loc: (1,0)-(1,2) = ":\""
+ ├── parts: (length: 1)
+ │ └── @ EmbeddedStatementsNode (location: (1,2)-(1,10))
+ │ ├── opening_loc: (1,2)-(1,4) = "\#{"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,4)-(1,9))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :field
+ │ │ ├── message_loc: (1,4)-(1,9) = "field"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── closing_loc: (1,9)-(1,10) = "}"
+ └── closing_loc: (1,10)-(1,11) = "\""
diff --git a/test/prism/snapshots/seattlerb/dstr_lex_state.txt b/test/prism/snapshots/seattlerb/dstr_lex_state.txt
new file mode 100644
index 0000000000..c4c0ef0437
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dstr_lex_state.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 1)
+ │ └── @ EmbeddedStatementsNode (location: (1,1)-(1,7))
+ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,3)-(1,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,3)-(1,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :p
+ │ │ ├── message_loc: (1,3)-(1,4) = "p"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,4)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (1,4)-(1,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,4)-(1,5) = ":"
+ │ │ │ ├── value_loc: (1,5)-(1,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── closing_loc: (1,6)-(1,7) = "}"
+ └── closing_loc: (1,7)-(1,8) = "\""
diff --git a/test/prism/snapshots/seattlerb/dstr_str.txt b/test/prism/snapshots/seattlerb/dstr_str.txt
new file mode 100644
index 0000000000..70b5752ce3
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dstr_str.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,10))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 2)
+ │ ├── @ EmbeddedStatementsNode (location: (1,1)-(1,7))
+ │ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,3)-(1,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ StringNode (location: (1,3)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,3)-(1,4) = "'"
+ │ │ │ ├── content_loc: (1,4)-(1,5) = "a"
+ │ │ │ ├── closing_loc: (1,5)-(1,6) = "'"
+ │ │ │ └── unescaped: "a"
+ │ │ └── closing_loc: (1,6)-(1,7) = "}"
+ │ └── @ StringNode (location: (1,7)-(1,9))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,7)-(1,9) = " b"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: " b"
+ └── closing_loc: (1,9)-(1,10) = "\""
diff --git a/test/prism/snapshots/seattlerb/dsym_esc_to_sym.txt b/test/prism/snapshots/seattlerb/dsym_esc_to_sym.txt
new file mode 100644
index 0000000000..7b1b68131e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dsym_esc_to_sym.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ SymbolNode (location: (1,0)-(1,17))
+ ├── flags: forced_utf8_encoding
+ ├── opening_loc: (1,0)-(1,2) = ":\""
+ ├── value_loc: (1,2)-(1,16) = "Variet\\303\\240"
+ ├── closing_loc: (1,16)-(1,17) = "\""
+ └── unescaped: "Varietà"
diff --git a/test/prism/snapshots/seattlerb/dsym_to_sym.txt b/test/prism/snapshots/seattlerb/dsym_to_sym.txt
new file mode 100644
index 0000000000..eb7e435c63
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/dsym_to_sym.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(3,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,13))
+ └── body: (length: 2)
+ ├── @ AliasMethodNode (location: (1,0)-(1,17))
+ │ ├── new_name:
+ │ │ @ SymbolNode (location: (1,6)-(1,11))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,6)-(1,8) = ":\""
+ │ │ ├── value_loc: (1,8)-(1,10) = "<<"
+ │ │ ├── closing_loc: (1,10)-(1,11) = "\""
+ │ │ └── unescaped: "<<"
+ │ ├── old_name:
+ │ │ @ SymbolNode (location: (1,12)-(1,17))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,12)-(1,14) = ":\""
+ │ │ ├── value_loc: (1,14)-(1,16) = ">>"
+ │ │ ├── closing_loc: (1,16)-(1,17) = "\""
+ │ │ └── unescaped: ">>"
+ │ └── keyword_loc: (1,0)-(1,5) = "alias"
+ └── @ AliasMethodNode (location: (3,0)-(3,13))
+ ├── new_name:
+ │ @ SymbolNode (location: (3,6)-(3,9))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (3,6)-(3,7) = ":"
+ │ ├── value_loc: (3,7)-(3,9) = "<<"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "<<"
+ ├── old_name:
+ │ @ SymbolNode (location: (3,10)-(3,13))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (3,10)-(3,11) = ":"
+ │ ├── value_loc: (3,11)-(3,13) = ">>"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: ">>"
+ └── keyword_loc: (3,0)-(3,5) = "alias"
diff --git a/test/prism/snapshots/seattlerb/eq_begin_line_numbers.txt b/test/prism/snapshots/seattlerb/eq_begin_line_numbers.txt
new file mode 100644
index 0000000000..a5fc3951d6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/eq_begin_line_numbers.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(6,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,1))
+ └── body: (length: 2)
+ ├── @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── @ IntegerNode (location: (6,0)-(6,1))
+ ├── flags: decimal
+ └── value: 2
diff --git a/test/prism/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt b/test/prism/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt
new file mode 100644
index 0000000000..2103bde8cb
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (1,0)-(3,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,8))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :h
+ │ ├── message_loc: (1,0)-(1,1) = "h"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]=
+ ├── message_loc: (1,1)-(1,4) = "[k]"
+ ├── opening_loc: (1,1)-(1,2) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(3,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (1,2)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :k
+ │ │ ├── message_loc: (1,2)-(1,3) = "k"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ BeginNode (location: (1,5)-(3,8))
+ │ ├── begin_keyword_loc: (1,5)-(1,10) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,7)-(2,9))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (2,7)-(2,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (3,5)-(3,8) = "end"
+ ├── closing_loc: (1,3)-(1,4) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/evstr_evstr.txt b/test/prism/snapshots/seattlerb/evstr_evstr.txt
new file mode 100644
index 0000000000..9c801299f8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/evstr_evstr.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,10))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 2)
+ │ ├── @ EmbeddedStatementsNode (location: (1,1)-(1,5))
+ │ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,3)-(1,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (1,3)-(1,4) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,4)-(1,5) = "}"
+ │ └── @ EmbeddedStatementsNode (location: (1,5)-(1,9))
+ │ ├── opening_loc: (1,5)-(1,7) = "\#{"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,7)-(1,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,7)-(1,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,7)-(1,8) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── closing_loc: (1,8)-(1,9) = "}"
+ └── closing_loc: (1,9)-(1,10) = "\""
diff --git a/test/prism/snapshots/seattlerb/evstr_str.txt b/test/prism/snapshots/seattlerb/evstr_str.txt
new file mode 100644
index 0000000000..54319e613c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/evstr_str.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 2)
+ │ ├── @ EmbeddedStatementsNode (location: (1,1)-(1,5))
+ │ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,3)-(1,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (1,3)-(1,4) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,4)-(1,5) = "}"
+ │ └── @ StringNode (location: (1,5)-(1,7))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,5)-(1,7) = " b"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: " b"
+ └── closing_loc: (1,7)-(1,8) = "\""
diff --git a/test/prism/snapshots/seattlerb/expr_not_bang.txt b/test/prism/snapshots/seattlerb/expr_not_bang.txt
new file mode 100644
index 0000000000..0a289ab7be
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/expr_not_bang.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,2)-(1,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,2)-(1,3) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,1) = "!"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/f_kw.txt b/test/prism/snapshots/seattlerb/f_kw.txt
new file mode 100644
index 0000000000..4226137925
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/f_kw.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,15))
+ ├── name: :x
+ ├── name_loc: (1,4)-(1,5) = "x"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,10))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,6)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :k
+ │ │ ├── name_loc: (1,6)-(1,8) = "k:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,8)-(1,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:k]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,12)-(1,15) = "end"
diff --git a/test/prism/snapshots/seattlerb/f_kw__required.txt b/test/prism/snapshots/seattlerb/f_kw__required.txt
new file mode 100644
index 0000000000..f72f43e034
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/f_kw__required.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,13))
+ ├── name: :x
+ ├── name_loc: (1,4)-(1,5) = "x"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,8))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ RequiredKeywordParameterNode (location: (1,6)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :k
+ │ │ └── name_loc: (1,6)-(1,8) = "k:"
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:k]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,10)-(1,13) = "end"
diff --git a/test/prism/snapshots/seattlerb/flip2_env_lvar.txt b/test/prism/snapshots/seattlerb/flip2_env_lvar.txt
new file mode 100644
index 0000000000..5a71ab6cda
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/flip2_env_lvar.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,16))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (1,3)-(1,7))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ CallNode (location: (1,3)-(1,4))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,3)-(1,4) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (1,6)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,6)-(1,7) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,4)-(1,6) = ".."
+ ├── then_keyword_loc: (1,8)-(1,12) = "then"
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,13)-(1,16) = "end"
diff --git a/test/prism/snapshots/seattlerb/float_with_if_modifier.txt b/test/prism/snapshots/seattlerb/float_with_if_modifier.txt
new file mode 100644
index 0000000000..9c1da70f24
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/float_with_if_modifier.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,10))
+ ├── if_keyword_loc: (1,3)-(1,5) = "if"
+ ├── predicate:
+ │ @ TrueNode (location: (1,6)-(1,10))
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (1,0)-(1,3))
+ │ └── body: (length: 1)
+ │ └── @ FloatNode (location: (1,0)-(1,3))
+ │ └── value: 1.0
+ ├── consequent: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/heredoc__backslash_dos_format.txt b/test/prism/snapshots/seattlerb/heredoc__backslash_dos_format.txt
new file mode 100644
index 0000000000..353e4c6964
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc__backslash_dos_format.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:str]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,12))
+ ├── name: :str
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,3) = "str"
+ ├── value:
+ │ @ StringNode (location: (1,6)-(1,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,6)-(1,12) = "<<-XXX"
+ │ ├── content_loc: (2,0)-(4,0) = "before\\\r\nafter\r\n"
+ │ ├── closing_loc: (4,0)-(5,0) = "XXX\r\n"
+ │ └── unescaped: "beforeafter\n"
+ └── operator_loc: (1,4)-(1,5) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_backslash_nl.txt b/test/prism/snapshots/seattlerb/heredoc_backslash_nl.txt
new file mode 100644
index 0000000000..fc4c1784fe
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_backslash_nl.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(5,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,7))
+ └── body: (length: 2)
+ ├── @ StringNode (location: (1,0)-(3,1))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── content_loc: (1,1)-(3,0) = " why would someone do this? \\\n blah\n"
+ │ ├── closing_loc: (3,0)-(3,1) = "\""
+ │ └── unescaped: " why would someone do this? blah\n"
+ └── @ StringNode (location: (5,0)-(5,7))
+ ├── flags: ∅
+ ├── opening_loc: (5,0)-(5,7) = "<<-DESC"
+ ├── content_loc: (6,0)-(8,0) = " why would someone do this? \\\n blah\n"
+ ├── closing_loc: (8,0)-(9,0) = "DESC\n"
+ └── unescaped: " why would someone do this? blah\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_bad_hex_escape.txt b/test/prism/snapshots/seattlerb/heredoc_bad_hex_escape.txt
new file mode 100644
index 0000000000..2b1d776404
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_bad_hex_escape.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: [:s]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,9))
+ ├── name: :s
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "s"
+ ├── value:
+ │ @ StringNode (location: (1,4)-(1,9))
+ │ ├── flags: forced_utf8_encoding
+ │ ├── opening_loc: (1,4)-(1,9) = "<<eos"
+ │ ├── content_loc: (2,0)-(3,0) = "a\\xE9b\n"
+ │ ├── closing_loc: (3,0)-(4,0) = "eos\n"
+ │ └── unescaped: "a\xE9b\n"
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_bad_oct_escape.txt b/test/prism/snapshots/seattlerb/heredoc_bad_oct_escape.txt
new file mode 100644
index 0000000000..7a01f8d6d1
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_bad_oct_escape.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: [:s]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,10))
+ ├── name: :s
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "s"
+ ├── value:
+ │ @ StringNode (location: (1,4)-(1,10))
+ │ ├── flags: forced_utf8_encoding
+ │ ├── opening_loc: (1,4)-(1,10) = "<<-EOS"
+ │ ├── content_loc: (2,0)-(4,0) = "a\\247b\ncöd\n"
+ │ ├── closing_loc: (4,0)-(5,0) = "EOS\n"
+ │ └── unescaped: "a\xA7b\ncöd\n"
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_comma_arg.txt b/test/prism/snapshots/seattlerb/heredoc_comma_arg.txt
new file mode 100644
index 0000000000..888ebc809a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_comma_arg.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(7,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,1))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(2,3))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (1,1)-(2,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,1)-(1,2) = "\""
+ │ │ ├── content_loc: (1,2)-(2,0) = " some text\n"
+ │ │ ├── closing_loc: (2,0)-(2,1) = "\""
+ │ │ └── unescaped: " some text\n"
+ │ ├── opening_loc: (1,0)-(1,1) = "["
+ │ └── closing_loc: (2,2)-(2,3) = "]"
+ └── @ ArrayNode (location: (4,0)-(7,1))
+ ├── flags: ∅
+ ├── elements: (length: 1)
+ │ └── @ StringNode (location: (4,1)-(4,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (4,1)-(4,8) = "<<-FILE"
+ │ ├── content_loc: (5,0)-(6,0) = " some text\n"
+ │ ├── closing_loc: (6,0)-(7,0) = "FILE\n"
+ │ └── unescaped: " some text\n"
+ ├── opening_loc: (4,0)-(4,1) = "["
+ └── closing_loc: (7,0)-(7,1) = "]"
diff --git a/test/prism/snapshots/seattlerb/heredoc_lineno.txt b/test/prism/snapshots/seattlerb/heredoc_lineno.txt
new file mode 100644
index 0000000000..a51ce71afe
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_lineno.txt
@@ -0,0 +1,26 @@
+@ ProgramNode (location: (1,0)-(7,6))
+├── locals: [:c, :d]
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,6))
+ └── body: (length: 2)
+ ├── @ LocalVariableWriteNode (location: (1,0)-(1,11))
+ │ ├── name: :c
+ │ ├── depth: 0
+ │ ├── name_loc: (1,0)-(1,1) = "c"
+ │ ├── value:
+ │ │ @ StringNode (location: (1,4)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,4)-(1,11) = "<<'CCC'"
+ │ │ ├── content_loc: (2,0)-(5,0) = "line2\nline3\nline4\n"
+ │ │ ├── closing_loc: (5,0)-(6,0) = "CCC\n"
+ │ │ └── unescaped: "line2\nline3\nline4\n"
+ │ └── operator_loc: (1,2)-(1,3) = "="
+ └── @ LocalVariableWriteNode (location: (7,0)-(7,6))
+ ├── name: :d
+ ├── depth: 0
+ ├── name_loc: (7,0)-(7,1) = "d"
+ ├── value:
+ │ @ IntegerNode (location: (7,4)-(7,6))
+ │ ├── flags: decimal
+ │ └── value: 42
+ └── operator_loc: (7,2)-(7,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_nested.txt b/test/prism/snapshots/seattlerb/heredoc_nested.txt
new file mode 100644
index 0000000000..26d533a33d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_nested.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(7,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,2))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(7,2))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ InterpolatedStringNode (location: (1,1)-(1,4))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,1)-(1,4) = "<<A"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (2,0)-(2,6))
+ │ │ │ │ ├── opening_loc: (2,0)-(2,2) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (2,2)-(2,5))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ StringNode (location: (2,2)-(2,5))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: (2,2)-(2,5) = "<<B"
+ │ │ │ │ │ ├── content_loc: (3,0)-(4,0) = "b\n"
+ │ │ │ │ │ ├── closing_loc: (4,0)-(5,0) = "B\n"
+ │ │ │ │ │ └── unescaped: "b\n"
+ │ │ │ │ └── closing_loc: (2,5)-(2,6) = "}"
+ │ │ │ ├── @ StringNode (location: (2,6)-(3,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (2,6)-(3,0) = "\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "\n"
+ │ │ │ └── @ StringNode (location: (5,0)-(6,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (5,0)-(6,0) = "a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── closing_loc: (6,0)-(7,0) = "A\n"
+ │ └── @ IntegerNode (location: (7,0)-(7,1))
+ │ ├── flags: decimal
+ │ └── value: 0
+ ├── opening_loc: (1,0)-(1,1) = "["
+ └── closing_loc: (7,1)-(7,2) = "]"
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly.txt
new file mode 100644
index 0000000000..9bab044ace
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,12))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ InterpolatedStringNode (location: (1,4)-(1,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,4)-(1,12) = "<<~\"EOF\""
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " x\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "x\n"
+ │ │ ├── @ StringNode (location: (3,0)-(4,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,0)-(4,0) = " y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "y\n"
+ │ │ └── @ StringNode (location: (4,0)-(5,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (4,0)-(5,0) = " z\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "z\n"
+ │ └── closing_loc: (5,0)-(6,0) = " EOF\n"
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
new file mode 100644
index 0000000000..e12014afa5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
@@ -0,0 +1,67 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,20))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ CallNode (location: (1,4)-(1,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,4)-(1,7) = "foo"
+ │ ├── opening_loc: (1,7)-(1,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,8)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ InterpolatedStringNode (location: (1,8)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,8)-(1,14) = "<<~EOF"
+ │ │ │ ├── parts: (length: 3)
+ │ │ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (2,0)-(3,0) = "\n"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "\n"
+ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (3,4)-(3,10))
+ │ │ │ │ │ ├── opening_loc: (3,4)-(3,6) = "\#{"
+ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ @ StatementsNode (location: (3,6)-(3,9))
+ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ └── @ CallNode (location: (3,6)-(3,9))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :bar
+ │ │ │ │ │ │ ├── message_loc: (3,6)-(3,9) = "bar"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ └── closing_loc: (3,9)-(3,10) = "}"
+ │ │ │ │ └── @ StringNode (location: (3,10)-(4,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (3,10)-(4,0) = "baz\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "baz\n"
+ │ │ │ └── closing_loc: (4,0)-(5,0) = " EOF\n"
+ │ │ ├── call_operator_loc: (1,14)-(1,15) = "."
+ │ │ ├── name: :chop
+ │ │ ├── message_loc: (1,15)-(1,19) = "chop"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (1,19)-(1,20) = ")"
+ │ └── block: ∅
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt
new file mode 100644
index 0000000000..8596647e72
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,10))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ InterpolatedStringNode (location: (1,4)-(1,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,4)-(1,10) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " x\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "x\n"
+ │ │ ├── @ StringNode (location: (3,0)-(4,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,0)-(4,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (4,0)-(5,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (4,0)-(5,0) = " z\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "z\n"
+ │ └── closing_loc: (5,0)-(6,0) = "EOF\n"
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly_empty.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly_empty.txt
new file mode 100644
index 0000000000..c998f19984
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly_empty.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,4) = "<<~A"
+ ├── content_loc: (2,0)-(2,0) = ""
+ ├── closing_loc: (2,0)-(3,0) = "A\n"
+ └── unescaped: ""
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly_interp.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly_interp.txt
new file mode 100644
index 0000000000..d34f89ff9c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly_interp.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,10))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ InterpolatedStringNode (location: (1,4)-(1,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,4)-(1,10) = "<<~EOF"
+ │ ├── parts: (length: 5)
+ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " w\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " w\n"
+ │ │ ├── @ StringNode (location: (3,0)-(3,3))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,0)-(3,3) = " x"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "x"
+ │ │ ├── @ EmbeddedStatementsNode (location: (3,3)-(3,8))
+ │ │ │ ├── opening_loc: (3,3)-(3,5) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (3,5)-(3,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (3,5)-(3,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── closing_loc: (3,7)-(3,8) = "}"
+ │ │ ├── @ StringNode (location: (3,8)-(4,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,8)-(4,0) = " y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " y\n"
+ │ │ └── @ StringNode (location: (4,0)-(5,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (4,0)-(5,0) = " z\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " z\n"
+ │ └── closing_loc: (5,0)-(6,0) = " EOF\n"
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly_no_indent.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly_no_indent.txt
new file mode 100644
index 0000000000..7c17bc4820
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly_no_indent.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,4) = "<<~A"
+ ├── content_loc: (2,0)-(3,0) = "a\n"
+ ├── closing_loc: (3,0)-(4,0) = "A\n"
+ └── unescaped: "a\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly_tabs.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly_tabs.txt
new file mode 100644
index 0000000000..311d7bc1b7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly_tabs.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,12))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ InterpolatedStringNode (location: (1,4)-(1,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,4)-(1,12) = "<<~\"EOF\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " blah blah\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "blah blah\n"
+ │ │ └── @ StringNode (location: (3,0)-(4,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (3,0)-(4,0) = "\t blah blah\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " blah blah\n"
+ │ └── closing_loc: (4,0)-(5,0) = " EOF\n"
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt
new file mode 100644
index 0000000000..3150f807a2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,12))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ InterpolatedStringNode (location: (1,4)-(1,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,4)-(1,12) = "<<~\"EOF\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " blah blah\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "blah blah\n"
+ │ │ └── @ StringNode (location: (3,0)-(4,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (3,0)-(4,0) = " \tblah blah\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\tblah blah\n"
+ │ └── closing_loc: (4,0)-(5,0) = " EOF\n"
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt b/test/prism/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt
new file mode 100644
index 0000000000..85c3d2df6d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,10))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ InterpolatedStringNode (location: (1,4)-(1,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,4)-(1,10) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " x\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "x\n"
+ │ │ ├── @ StringNode (location: (3,0)-(4,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,0)-(4,0) = " \n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (4,0)-(5,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (4,0)-(5,0) = " z\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "z\n"
+ │ └── closing_loc: (5,0)-(6,0) = "EOF\n"
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/heredoc_trailing_slash_continued_call.txt b/test/prism/snapshots/seattlerb/heredoc_trailing_slash_continued_call.txt
new file mode 100644
index 0000000000..bc05047b40
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_trailing_slash_continued_call.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(4,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(4,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ StringNode (location: (1,0)-(1,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,5) = "<<END"
+ │ ├── content_loc: (2,0)-(3,0) = "blah\n"
+ │ ├── closing_loc: (3,0)-(4,0) = "END\n"
+ │ └── unescaped: "blah\n"
+ ├── call_operator_loc: (4,0)-(4,1) = "."
+ ├── name: :strip
+ ├── message_loc: (4,1)-(4,6) = "strip"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/heredoc_unicode.txt b/test/prism/snapshots/seattlerb/heredoc_unicode.txt
new file mode 100644
index 0000000000..2c72854324
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_unicode.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,9) = "<<OOTPÜT"
+ ├── content_loc: (2,0)-(3,0) = ".\n"
+ ├── closing_loc: (3,0)-(4,0) = "OOTPÜT\n"
+ └── unescaped: ".\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes.txt b/test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes.txt
new file mode 100644
index 0000000000..43bb8d5ea8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,5) = "<<EOS"
+ ├── content_loc: (2,0)-(4,0) = "foo\\rbar\nbaz\\r\n"
+ ├── closing_loc: (4,0)-(5,0) = "EOS\n"
+ └── unescaped: "foo\rbar\nbaz\r\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes_windows.txt b/test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes_windows.txt
new file mode 100644
index 0000000000..2ef6763389
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_carriage_return_escapes_windows.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,5) = "<<EOS"
+ ├── content_loc: (2,0)-(4,0) = "foo\\rbar\r\nbaz\\r\r\n"
+ ├── closing_loc: (4,0)-(5,0) = "EOS\r\n"
+ └── unescaped: "foo\rbar\nbaz\r\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt b/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt
new file mode 100644
index 0000000000..fbee030100
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,7))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,7) = "<<'eot'"
+ ├── content_loc: (2,0)-(3,0) = "body\r\n"
+ ├── closing_loc: (3,0)-(4,0) = "eot\n"
+ └── unescaped: "body\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns.txt b/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns.txt
new file mode 100644
index 0000000000..b59203bc4e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,5) = "<<EOS"
+ ├── content_loc: (2,0)-(4,0) = "foo\rbar\r\nbaz\n"
+ ├── closing_loc: (4,0)-(5,0) = "EOS\n"
+ └── unescaped: "foo\rbar\nbaz\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns_windows.txt b/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns_windows.txt
new file mode 100644
index 0000000000..36bc4c6560
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_extra_carriage_returns_windows.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,5) = "<<EOS"
+ ├── content_loc: (2,0)-(4,0) = "foo\rbar\r\r\nbaz\r\n"
+ ├── closing_loc: (4,0)-(5,0) = "EOS\r\n"
+ └── unescaped: "foo\rbar\r\nbaz\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt b/test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt
new file mode 100644
index 0000000000..c4be1244dc
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,5) = "<<EOS"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (2,0)-(2,5))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (2,0)-(2,5) = "foo\\r"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo\r"
+ │ ├── @ EmbeddedVariableNode (location: (2,5)-(2,10))
+ │ │ ├── operator_loc: (2,5)-(2,6) = "#"
+ │ │ └── variable:
+ │ │ @ InstanceVariableReadNode (location: (2,6)-(2,10))
+ │ │ └── name: :@bar
+ │ └── @ StringNode (location: (2,10)-(3,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (2,10)-(3,0) = "\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\n"
+ └── closing_loc: (3,0)-(4,0) = "EOS\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt b/test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt
new file mode 100644
index 0000000000..c2290cec13
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,5) = "<<EOS"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (2,0)-(2,5))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (2,0)-(2,5) = "foo\\r"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo\r"
+ │ ├── @ EmbeddedVariableNode (location: (2,5)-(2,10))
+ │ │ ├── operator_loc: (2,5)-(2,6) = "#"
+ │ │ └── variable:
+ │ │ @ InstanceVariableReadNode (location: (2,6)-(2,10))
+ │ │ └── name: :@bar
+ │ └── @ StringNode (location: (2,10)-(3,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (2,10)-(3,0) = "\r\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\n"
+ └── closing_loc: (3,0)-(4,0) = "EOS\r\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_not_global_interpolation.txt b/test/prism/snapshots/seattlerb/heredoc_with_not_global_interpolation.txt
new file mode 100644
index 0000000000..6e1648f659
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_not_global_interpolation.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,10))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,10) = "<<-HEREDOC"
+ ├── content_loc: (2,0)-(3,0) = "\#${\n"
+ ├── closing_loc: (3,0)-(4,0) = "HEREDOC\n"
+ └── unescaped: "\#${\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns.txt b/test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns.txt
new file mode 100644
index 0000000000..6a535c6472
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,5) = "<<EOS"
+ ├── content_loc: (2,0)-(5,0) = "\r\n\r\r\n\\r\n"
+ ├── closing_loc: (5,0)-(6,0) = "EOS\n"
+ └── unescaped: "\n\r\n\r\n"
diff --git a/test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns_windows.txt b/test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns_windows.txt
new file mode 100644
index 0000000000..6539846ff1
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/heredoc_with_only_carriage_returns_windows.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,5) = "<<EOS"
+ ├── content_loc: (2,0)-(5,0) = "\r\r\n\r\r\r\n\\r\r\n"
+ ├── closing_loc: (5,0)-(6,0) = "EOS\r\n"
+ └── unescaped: "\r\n\r\r\n\r\n"
diff --git a/test/prism/snapshots/seattlerb/if_elsif.txt b/test/prism/snapshots/seattlerb/if_elsif.txt
new file mode 100644
index 0000000000..034850158c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/if_elsif.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,18))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ IntegerNode (location: (1,3)-(1,4))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent:
+ │ @ IfNode (location: (1,6)-(1,18))
+ │ ├── if_keyword_loc: (1,6)-(1,11) = "elsif"
+ │ ├── predicate:
+ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (1,15)-(1,18) = "end"
+ └── end_keyword_loc: (1,15)-(1,18) = "end"
diff --git a/test/prism/snapshots/seattlerb/if_symbol.txt b/test/prism/snapshots/seattlerb/if_symbol.txt
new file mode 100644
index 0000000000..85ec52b4c8
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/if_symbol.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,12))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (1,3)-(1,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (1,3)-(1,4) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,5)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,5)-(1,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ │ ├── value_loc: (1,6)-(1,7) = "x"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,9)-(1,12) = "end"
diff --git a/test/prism/snapshots/seattlerb/in_expr_no_case.txt b/test/prism/snapshots/seattlerb/in_expr_no_case.txt
new file mode 100644
index 0000000000..0a026c08db
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/in_expr_no_case.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ MatchPredicateNode (location: (1,0)-(1,16))
+ ├── value:
+ │ @ StringNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "'"
+ │ ├── content_loc: (1,1)-(1,5) = "woot"
+ │ ├── closing_loc: (1,5)-(1,6) = "'"
+ │ └── unescaped: "woot"
+ ├── pattern:
+ │ @ ConstantReadNode (location: (1,10)-(1,16))
+ │ └── name: :String
+ └── operator_loc: (1,7)-(1,9) = "in"
diff --git a/test/prism/snapshots/seattlerb/index_0.txt b/test/prism/snapshots/seattlerb/index_0.txt
new file mode 100644
index 0000000000..9771e9c2bd
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/index_0.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]=
+ ├── message_loc: (1,1)-(1,3) = "[]"
+ ├── opening_loc: (1,1)-(1,2) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,6)-(1,7))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (1,6)-(1,7) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (1,2)-(1,3) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/index_0_opasgn.txt b/test/prism/snapshots/seattlerb/index_0_opasgn.txt
new file mode 100644
index 0000000000..239a549253
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/index_0_opasgn.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ IndexOperatorWriteNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── opening_loc: (1,1)-(1,2) = "["
+ ├── arguments: ∅
+ ├── closing_loc: (1,2)-(1,3) = "]"
+ ├── block: ∅
+ ├── operator: :+
+ ├── operator_loc: (1,4)-(1,6) = "+="
+ └── value:
+ @ CallNode (location: (1,7)-(1,8))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (1,7)-(1,8) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/integer_with_if_modifier.txt b/test/prism/snapshots/seattlerb/integer_with_if_modifier.txt
new file mode 100644
index 0000000000..2108c1f0a0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/integer_with_if_modifier.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,12))
+ ├── if_keyword_loc: (1,5)-(1,7) = "if"
+ ├── predicate:
+ │ @ TrueNode (location: (1,8)-(1,12))
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (1,0)-(1,5))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,0)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 1234
+ ├── consequent: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt b/test/prism/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt
new file mode 100644
index 0000000000..ab231cf539
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(5,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,1))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(4,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (2,0)-(2,1))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (2,0)-(2,1) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (3,0)-(3,1))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (3,0)-(3,1) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── opening_loc: (1,0)-(1,3) = "%I("
+ │ └── closing_loc: (4,0)-(4,1) = ")"
+ └── @ IntegerNode (location: (5,0)-(5,1))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/interpolated_word_array_line_breaks.txt b/test/prism/snapshots/seattlerb/interpolated_word_array_line_breaks.txt
new file mode 100644
index 0000000000..933e5de627
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/interpolated_word_array_line_breaks.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(5,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,1))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(4,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (2,0)-(2,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(2,1) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ StringNode (location: (3,0)-(3,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (3,0)-(3,1) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── opening_loc: (1,0)-(1,3) = "%W("
+ │ └── closing_loc: (4,0)-(4,1) = ")"
+ └── @ IntegerNode (location: (5,0)-(5,1))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/iter_args_1.txt b/test/prism/snapshots/seattlerb/iter_args_1.txt
new file mode 100644
index 0000000000..f76bbfc559
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_1.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,11))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,9))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,8))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ RequiredParameterNode (location: (1,7)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,8)-(1,9) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,10)-(1,11) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_10_1.txt b/test/prism/snapshots/seattlerb/iter_args_10_1.txt
new file mode 100644
index 0000000000..b8aaae800a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_10_1.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(1,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,21))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,21))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,21))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,19))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,18))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
+ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,16)-(1,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,17)-(1,18) = "c"
+ │ │ │ └── operator_loc: (1,16)-(1,17) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,18)-(1,19) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,20)-(1,21) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_10_2.txt b/test/prism/snapshots/seattlerb/iter_args_10_2.txt
new file mode 100644
index 0000000000..833f6429dc
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_10_2.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,25))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,25))
+ ├── locals: [:a, :b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,23))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,22))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
+ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,16)-(1,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,17)-(1,18) = "c"
+ │ │ │ └── operator_loc: (1,16)-(1,17) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,20)-(1,22))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :d
+ │ │ ├── name_loc: (1,21)-(1,22) = "d"
+ │ │ └── operator_loc: (1,20)-(1,21) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,22)-(1,23) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,24)-(1,25) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_11_1.txt b/test/prism/snapshots/seattlerb/iter_args_11_1.txt
new file mode 100644
index 0000000000..e4d2f79474
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_11_1.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,24))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,24))
+ ├── locals: [:a, :b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,22))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,21))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
+ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,16)-(1,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,17)-(1,18) = "c"
+ │ │ │ └── operator_loc: (1,16)-(1,17) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,20)-(1,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,21)-(1,22) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,23)-(1,24) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_11_2.txt b/test/prism/snapshots/seattlerb/iter_args_11_2.txt
new file mode 100644
index 0000000000..07a0e5ed9d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_11_2.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(1,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,28))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,28))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,28))
+ ├── locals: [:a, :b, :c, :d, :e]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,26))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,25))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
+ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,16)-(1,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,17)-(1,18) = "c"
+ │ │ │ └── operator_loc: (1,16)-(1,17) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,20)-(1,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,23)-(1,25))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :e
+ │ │ ├── name_loc: (1,24)-(1,25) = "e"
+ │ │ └── operator_loc: (1,23)-(1,24) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,25)-(1,26) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,27)-(1,28) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_2__19.txt b/test/prism/snapshots/seattlerb/iter_args_2__19.txt
new file mode 100644
index 0000000000..a905286f47
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_2__19.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,14))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,12))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,11))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ └── rparen_loc: (1,10)-(1,11) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,11)-(1,12) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,13)-(1,14) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_3.txt b/test/prism/snapshots/seattlerb/iter_args_3.txt
new file mode 100644
index 0000000000..66782f0793
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_3.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,20))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,20))
+ ├── locals: [:a, :b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,18))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,17))
+ │ │ ├── requireds: (length: 3)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── @ MultiTargetNode (location: (1,8)-(1,14))
+ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :b
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :c
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ │ │ │ └── rparen_loc: (1,13)-(1,14) = ")"
+ │ │ │ └── @ RequiredParameterNode (location: (1,16)-(1,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :d
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,17)-(1,18) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,19)-(1,20) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_4.txt b/test/prism/snapshots/seattlerb/iter_args_4.txt
new file mode 100644
index 0000000000..c4f2b47a03
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_4.txt
@@ -0,0 +1,45 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,16))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,14))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,13))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,8)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,9)-(1,10) = "b"
+ │ │ │ └── operator_loc: (1,8)-(1,9) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,13)-(1,14) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,15)-(1,16) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_5.txt b/test/prism/snapshots/seattlerb/iter_args_5.txt
new file mode 100644
index 0000000000..44940629b4
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_5.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,13))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,10))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,8)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,9)-(1,10) = "b"
+ │ │ └── operator_loc: (1,8)-(1,9) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,10)-(1,11) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,12)-(1,13) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_6.txt b/test/prism/snapshots/seattlerb/iter_args_6.txt
new file mode 100644
index 0000000000..df3a405dff
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_6.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,18))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,18))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,16))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,15))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,8)-(1,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,8)-(1,9) = "b"
+ │ │ │ ├── operator_loc: (1,9)-(1,10) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,10)-(1,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,15)-(1,16) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,17)-(1,18) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_7_1.txt b/test/prism/snapshots/seattlerb/iter_args_7_1.txt
new file mode 100644
index 0000000000..3f65fb8dc0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_7_1.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,18))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,18))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,16))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,15))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,14)-(1,15) = "b"
+ │ │ │ └── operator_loc: (1,13)-(1,14) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,15)-(1,16) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,17)-(1,18) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_7_2.txt b/test/prism/snapshots/seattlerb/iter_args_7_2.txt
new file mode 100644
index 0000000000..112a5a1b6b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_7_2.txt
@@ -0,0 +1,53 @@
+@ ProgramNode (location: (1,0)-(1,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,22))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,22))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,22))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,20))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,19))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,14)-(1,15) = "b"
+ │ │ │ └── operator_loc: (1,13)-(1,14) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,17)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :c
+ │ │ ├── name_loc: (1,18)-(1,19) = "c"
+ │ │ └── operator_loc: (1,17)-(1,18) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,19)-(1,20) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,21)-(1,22) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_8_1.txt b/test/prism/snapshots/seattlerb/iter_args_8_1.txt
new file mode 100644
index 0000000000..5591fcfc69
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_8_1.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(1,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,21))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,21))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,21))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,19))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,14)-(1,15) = "b"
+ │ │ │ └── operator_loc: (1,13)-(1,14) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,17)-(1,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,18)-(1,19) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,20)-(1,21) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_8_2.txt b/test/prism/snapshots/seattlerb/iter_args_8_2.txt
new file mode 100644
index 0000000000..8cb061d5a7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_8_2.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,25))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,25))
+ ├── locals: [:a, :b, :c, :d]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,23))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,22))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,13)-(1,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,14)-(1,15) = "b"
+ │ │ │ └── operator_loc: (1,13)-(1,14) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,17)-(1,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,20)-(1,22))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :d
+ │ │ ├── name_loc: (1,21)-(1,22) = "d"
+ │ │ └── operator_loc: (1,20)-(1,21) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,22)-(1,23) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,24)-(1,25) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_9_1.txt b/test/prism/snapshots/seattlerb/iter_args_9_1.txt
new file mode 100644
index 0000000000..70b2a6cb19
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_9_1.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:a, :b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_args_9_2.txt b/test/prism/snapshots/seattlerb/iter_args_9_2.txt
new file mode 100644
index 0000000000..cad8b47e7f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_args_9_2.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(1,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,21))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,21))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,21))
+ ├── locals: [:a, :b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,19))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,16)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :c
+ │ │ ├── name_loc: (1,17)-(1,18) = "c"
+ │ │ └── operator_loc: (1,16)-(1,17) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,18)-(1,19) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,20)-(1,21) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_kwarg.txt b/test/prism/snapshots/seattlerb/iter_kwarg.txt
new file mode 100644
index 0000000000..13b9027661
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_kwarg.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,12))
+ ├── locals: [:b]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,10))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (1,5)-(1,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,5)-(1,7) = "b:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,9)-(1,10) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,11)-(1,12) = "}"
diff --git a/test/prism/snapshots/seattlerb/iter_kwarg_kwsplat.txt b/test/prism/snapshots/seattlerb/iter_kwarg_kwsplat.txt
new file mode 100644
index 0000000000..321e15cb2b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/iter_kwarg_kwsplat.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,17))
+ ├── locals: [:b, :c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,4)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,5)-(1,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (1,5)-(1,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (1,5)-(1,7) = "b:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (1,11)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,13)-(1,14) = "c"
+ │ │ │ └── operator_loc: (1,11)-(1,13) = "**"
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ └── closing_loc: (1,14)-(1,15) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/seattlerb/label_vs_string.txt b/test/prism/snapshots/seattlerb/label_vs_string.txt
new file mode 100644
index 0000000000..c8d7af8f48
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/label_vs_string.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(2,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,1))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(2,1))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,4))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :_buf
+ │ ├── message_loc: (1,0)-(1,4) = "_buf"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :<<
+ ├── message_loc: (1,5)-(1,7) = "<<"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,8)-(2,1))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ StringNode (location: (1,8)-(2,1))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,8)-(1,9) = "'"
+ │ ├── content_loc: (1,9)-(2,0) = ":\n"
+ │ ├── closing_loc: (2,0)-(2,1) = "'"
+ │ └── unescaped: ":\n"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/lambda_do_vs_brace.txt b/test/prism/snapshots/seattlerb/lambda_do_vs_brace.txt
new file mode 100644
index 0000000000..afc0d3d56f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lambda_do_vs_brace.txt
@@ -0,0 +1,95 @@
+@ ProgramNode (location: (1,0)-(7,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,9))
+ └── body: (length: 4)
+ ├── @ CallNode (location: (1,0)-(1,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (1,0)-(1,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LambdaNode (location: (1,2)-(1,11))
+ │ │ ├── locals: []
+ │ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ │ ├── opening_loc: (1,5)-(1,7) = "do"
+ │ │ ├── closing_loc: (1,8)-(1,11) = "end"
+ │ │ ├── parameters: ∅
+ │ │ └── body: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (3,0)-(3,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,2)-(3,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LambdaNode (location: (3,2)-(3,7))
+ │ │ ├── locals: []
+ │ │ ├── operator_loc: (3,2)-(3,4) = "->"
+ │ │ ├── opening_loc: (3,5)-(3,6) = "{"
+ │ │ ├── closing_loc: (3,6)-(3,7) = "}"
+ │ │ ├── parameters: ∅
+ │ │ └── body: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,13))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (5,0)-(5,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,2)-(5,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LambdaNode (location: (5,2)-(5,13))
+ │ │ ├── locals: []
+ │ │ ├── operator_loc: (5,2)-(5,4) = "->"
+ │ │ ├── opening_loc: (5,7)-(5,9) = "do"
+ │ │ ├── closing_loc: (5,10)-(5,13) = "end"
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (5,4)-(5,6))
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (5,4)-(5,5) = "("
+ │ │ │ └── closing_loc: (5,5)-(5,6) = ")"
+ │ │ └── body: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (7,0)-(7,9))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (7,0)-(7,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (7,2)-(7,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LambdaNode (location: (7,2)-(7,9))
+ │ ├── locals: []
+ │ ├── operator_loc: (7,2)-(7,4) = "->"
+ │ ├── opening_loc: (7,7)-(7,8) = "{"
+ │ ├── closing_loc: (7,8)-(7,9) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (7,4)-(7,6))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (7,4)-(7,5) = "("
+ │ │ └── closing_loc: (7,5)-(7,6) = ")"
+ │ └── body: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/lasgn_arg_rescue_arg.txt b/test/prism/snapshots/seattlerb/lasgn_arg_rescue_arg.txt
new file mode 100644
index 0000000000..7bbef7055a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lasgn_arg_rescue_arg.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,14))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ RescueModifierNode (location: (1,4)-(1,14))
+ │ ├── expression:
+ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_loc: (1,6)-(1,12) = "rescue"
+ │ └── rescue_expression:
+ │ @ IntegerNode (location: (1,13)-(1,14))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt b/test/prism/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt
new file mode 100644
index 0000000000..521fceaf1b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,17))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ RescueModifierNode (location: (1,4)-(1,17))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,4)-(1,8))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: (1,7)-(1,8) = ")"
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,9)-(1,15) = "rescue"
+ │ └── rescue_expression:
+ │ @ IntegerNode (location: (1,16)-(1,17))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt b/test/prism/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt
new file mode 100644
index 0000000000..d730fb51cb
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,16))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ RescueModifierNode (location: (1,4)-(1,16))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,4)-(1,7))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,8)-(1,14) = "rescue"
+ │ └── rescue_expression:
+ │ @ IntegerNode (location: (1,15)-(1,16))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/lasgn_command.txt b/test/prism/snapshots/seattlerb/lasgn_command.txt
new file mode 100644
index 0000000000..d6ed787b26
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lasgn_command.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,9))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ CallNode (location: (1,4)-(1,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,4)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,5)-(1,6) = "."
+ │ ├── name: :c
+ │ ├── message_loc: (1,6)-(1,7) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,8)-(1,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/lasgn_env.txt b/test/prism/snapshots/seattlerb/lasgn_env.txt
new file mode 100644
index 0000000000..a0ada99a9b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lasgn_env.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,6))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ IntegerNode (location: (1,4)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 42
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/lasgn_ivar_env.txt b/test/prism/snapshots/seattlerb/lasgn_ivar_env.txt
new file mode 100644
index 0000000000..5675730477
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lasgn_ivar_env.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ InstanceVariableWriteNode (location: (1,0)-(1,7))
+ ├── name: :@a
+ ├── name_loc: (1,0)-(1,2) = "@a"
+ ├── value:
+ │ @ IntegerNode (location: (1,5)-(1,7))
+ │ ├── flags: decimal
+ │ └── value: 42
+ └── operator_loc: (1,3)-(1,4) = "="
diff --git a/test/prism/snapshots/seattlerb/lasgn_lasgn_command_call.txt b/test/prism/snapshots/seattlerb/lasgn_lasgn_command_call.txt
new file mode 100644
index 0000000000..bb4b64e88c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lasgn_lasgn_command_call.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,11))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ LocalVariableWriteNode (location: (1,4)-(1,11))
+ │ ├── name: :b
+ │ ├── depth: 0
+ │ ├── name_loc: (1,4)-(1,5) = "b"
+ │ ├── value:
+ │ │ @ CallNode (location: (1,8)-(1,11))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (1,8)-(1,9) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,6)-(1,7) = "="
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/lasgn_middle_splat.txt b/test/prism/snapshots/seattlerb/lasgn_middle_splat.txt
new file mode 100644
index 0000000000..c113fef13f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/lasgn_middle_splat.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,12))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── value:
+ │ @ ArrayNode (location: (1,4)-(1,12))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 3)
+ │ │ ├── @ CallNode (location: (1,4)-(1,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── @ SplatNode (location: (1,7)-(1,9))
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (1,8)-(1,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (1,8)-(1,9) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (1,11)-(1,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (1,11)-(1,12) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/magic_encoding_comment.txt b/test/prism/snapshots/seattlerb/magic_encoding_comment.txt
new file mode 100644
index 0000000000..9c4ca884d2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/magic_encoding_comment.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (2,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (2,0)-(3,3))
+ └── body: (length: 1)
+ └── @ ClassNode (location: (2,0)-(3,3))
+ ├── locals: []
+ ├── class_keyword_loc: (2,0)-(2,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (2,6)-(2,34))
+ │ └── name: :ExampleUTF8ClassNameVarietà
+ ├── inheritance_operator_loc: ∅
+ ├── superclass: ∅
+ ├── body:
+ │ @ StatementsNode (location: (2,36)-(2,68))
+ │ └── body: (length: 1)
+ │ └── @ DefNode (location: (2,36)-(2,68))
+ │ ├── name: :è
+ │ ├── name_loc: (2,45)-(2,47) = "è"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (2,40)-(2,44))
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,49)-(2,63))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (2,49)-(2,63))
+ │ │ ├── name: :così
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (2,49)-(2,54) = "così"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (2,57)-(2,63))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (2,57)-(2,58) = ":"
+ │ │ │ ├── value_loc: (2,58)-(2,63) = "però"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "però"
+ │ │ └── operator_loc: (2,55)-(2,56) = "="
+ │ ├── locals: [:così]
+ │ ├── def_keyword_loc: (2,36)-(2,39) = "def"
+ │ ├── operator_loc: (2,44)-(2,45) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (2,65)-(2,68) = "end"
+ ├── end_keyword_loc: (3,0)-(3,3) = "end"
+ └── name: :ExampleUTF8ClassNameVarietà
diff --git a/test/prism/snapshots/seattlerb/masgn_anon_splat_arg.txt b/test/prism/snapshots/seattlerb/masgn_anon_splat_arg.txt
new file mode 100644
index 0000000000..9ebcab3095
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_anon_splat_arg.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,8))
+ ├── lefts: (length: 0)
+ ├── rest:
+ │ @ SplatNode (location: (1,0)-(1,1))
+ │ ├── operator_loc: (1,0)-(1,1) = "*"
+ │ └── expression: ∅
+ ├── rights: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (1,3)-(1,4))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,5)-(1,6) = "="
+ └── value:
+ @ CallNode (location: (1,7)-(1,8))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (1,7)-(1,8) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_arg_colon_arg.txt b/test/prism/snapshots/seattlerb/masgn_arg_colon_arg.txt
new file mode 100644
index 0000000000..83613c42d1
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_arg_colon_arg.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,11))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ CallTargetNode (location: (1,3)-(1,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,3)-(1,4))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,3)-(1,4) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,4)-(1,6) = "::"
+ │ ├── name: :c=
+ │ └── message_loc: (1,6)-(1,7) = "c"
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,8)-(1,9) = "="
+ └── value:
+ @ CallNode (location: (1,10)-(1,11))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :d
+ ├── message_loc: (1,10)-(1,11) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_arg_ident.txt b/test/prism/snapshots/seattlerb/masgn_arg_ident.txt
new file mode 100644
index 0000000000..f4c99648f0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_arg_ident.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,10))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ CallTargetNode (location: (1,3)-(1,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,3)-(1,4))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,3)-(1,4) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,4)-(1,5) = "."
+ │ ├── name: :C=
+ │ └── message_loc: (1,5)-(1,6) = "C"
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,7)-(1,8) = "="
+ └── value:
+ @ CallNode (location: (1,9)-(1,10))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :d
+ ├── message_loc: (1,9)-(1,10) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_arg_splat_arg.txt b/test/prism/snapshots/seattlerb/masgn_arg_splat_arg.txt
new file mode 100644
index 0000000000..48e58de076
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_arg_splat_arg.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:a, :b, :c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,12))
+ ├── lefts: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── rest:
+ │ @ SplatNode (location: (1,3)-(1,5))
+ │ ├── operator_loc: (1,3)-(1,4) = "*"
+ │ └── expression:
+ │ @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── rights: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (1,7)-(1,8))
+ │ ├── name: :c
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,9)-(1,10) = "="
+ └── value:
+ @ CallNode (location: (1,11)-(1,12))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :d
+ ├── message_loc: (1,11)-(1,12) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_colon2.txt b/test/prism/snapshots/seattlerb/masgn_colon2.txt
new file mode 100644
index 0000000000..73ce8a71da
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_colon2.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,14))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ ConstantPathTargetNode (location: (1,3)-(1,7))
+ │ ├── parent:
+ │ │ @ CallNode (location: (1,3)-(1,4))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,3)-(1,4) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (1,6)-(1,7))
+ │ │ └── name: :C
+ │ └── delimiter_loc: (1,4)-(1,6) = "::"
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,8)-(1,9) = "="
+ └── value:
+ @ ArrayNode (location: (1,10)-(1,14))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ IntegerNode (location: (1,13)-(1,14))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── opening_loc: ∅
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_colon3.txt b/test/prism/snapshots/seattlerb/masgn_colon3.txt
new file mode 100644
index 0000000000..0cf4f8626d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_colon3.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,15))
+ ├── 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) = "::"
+ │ └── @ ConstantPathTargetNode (location: (1,5)-(1,8))
+ │ ├── parent: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (1,7)-(1,8))
+ │ │ └── name: :B
+ │ └── delimiter_loc: (1,5)-(1,7) = "::"
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,9)-(1,10) = "="
+ └── value:
+ @ ArrayNode (location: (1,11)-(1,15))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ IntegerNode (location: (1,11)-(1,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ IntegerNode (location: (1,14)-(1,15))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── opening_loc: ∅
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_command_call.txt b/test/prism/snapshots/seattlerb/masgn_command_call.txt
new file mode 100644
index 0000000000..687ea38243
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_command_call.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,10))
+ ├── lefts: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── rest:
+ │ @ ImplicitRestNode (location: (1,1)-(1,2))
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,3)-(1,4) = "="
+ └── value:
+ @ CallNode (location: (1,5)-(1,10))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,5)-(1,6))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (1,5)-(1,6) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,6)-(1,7) = "."
+ ├── name: :c
+ ├── message_loc: (1,7)-(1,8) = "c"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,9)-(1,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,9)-(1,10))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_double_paren.txt b/test/prism/snapshots/seattlerb/masgn_double_paren.txt
new file mode 100644
index 0000000000..590df8fa07
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_double_paren.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,9))
+ ├── lefts: (length: 1)
+ │ └── @ MultiTargetNode (location: (1,1)-(1,6))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (1,2)-(1,3))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (1,1)-(1,2) = "("
+ │ └── rparen_loc: (1,5)-(1,6) = ")"
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: (1,0)-(1,1) = "("
+ ├── rparen_loc: (1,6)-(1,7) = ")"
+ ├── operator_loc: (1,7)-(1,8) = "="
+ └── value:
+ @ CallNode (location: (1,8)-(1,9))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (1,8)-(1,9) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_lhs_splat.txt b/test/prism/snapshots/seattlerb/masgn_lhs_splat.txt
new file mode 100644
index 0000000000..771dd7c040
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_lhs_splat.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,12))
+ ├── lefts: (length: 0)
+ ├── rest:
+ │ @ SplatNode (location: (1,0)-(1,2))
+ │ ├── operator_loc: (1,0)-(1,1) = "*"
+ │ └── expression:
+ │ @ LocalVariableTargetNode (location: (1,1)-(1,2))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,3)-(1,4) = "="
+ └── value:
+ @ ArrayNode (location: (1,5)-(1,12))
+ ├── flags: ∅
+ ├── elements: (length: 3)
+ │ ├── @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── @ IntegerNode (location: (1,8)-(1,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── @ IntegerNode (location: (1,11)-(1,12))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── opening_loc: ∅
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_paren.txt b/test/prism/snapshots/seattlerb/masgn_paren.txt
new file mode 100644
index 0000000000..5d79774d5e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_paren.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,12))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (1,1)-(1,2))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: (1,0)-(1,1) = "("
+ ├── rparen_loc: (1,5)-(1,6) = ")"
+ ├── operator_loc: (1,7)-(1,8) = "="
+ └── value:
+ @ CallNode (location: (1,9)-(1,12))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,9)-(1,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :c
+ │ ├── message_loc: (1,9)-(1,10) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,10)-(1,11) = "."
+ ├── name: :d
+ ├── message_loc: (1,11)-(1,12) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_splat_arg.txt b/test/prism/snapshots/seattlerb/masgn_splat_arg.txt
new file mode 100644
index 0000000000..b8113b126f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_splat_arg.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,9))
+ ├── lefts: (length: 0)
+ ├── rest:
+ │ @ SplatNode (location: (1,0)-(1,2))
+ │ ├── operator_loc: (1,0)-(1,1) = "*"
+ │ └── expression:
+ │ @ LocalVariableTargetNode (location: (1,1)-(1,2))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── rights: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,6)-(1,7) = "="
+ └── value:
+ @ CallNode (location: (1,8)-(1,9))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (1,8)-(1,9) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_splat_arg_arg.txt b/test/prism/snapshots/seattlerb/masgn_splat_arg_arg.txt
new file mode 100644
index 0000000000..a832aef1e0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_splat_arg_arg.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:a, :b, :c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,12))
+ ├── lefts: (length: 0)
+ ├── rest:
+ │ @ SplatNode (location: (1,0)-(1,2))
+ │ ├── operator_loc: (1,0)-(1,1) = "*"
+ │ └── expression:
+ │ @ LocalVariableTargetNode (location: (1,1)-(1,2))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── rights: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,7)-(1,8))
+ │ ├── name: :c
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,9)-(1,10) = "="
+ └── value:
+ @ CallNode (location: (1,11)-(1,12))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :d
+ ├── message_loc: (1,11)-(1,12) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/masgn_star.txt b/test/prism/snapshots/seattlerb/masgn_star.txt
new file mode 100644
index 0000000000..3e01eef8a7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_star.txt
@@ -0,0 +1,19 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,5))
+ ├── lefts: (length: 0)
+ ├── rest:
+ │ @ SplatNode (location: (1,0)-(1,1))
+ │ ├── operator_loc: (1,0)-(1,1) = "*"
+ │ └── expression: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,2)-(1,3) = "="
+ └── value:
+ @ IntegerNode (location: (1,4)-(1,5))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/masgn_var_star_var.txt b/test/prism/snapshots/seattlerb/masgn_var_star_var.txt
new file mode 100644
index 0000000000..37851efd6f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/masgn_var_star_var.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,11))
+ ├── lefts: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── rest:
+ │ @ SplatNode (location: (1,3)-(1,4))
+ │ ├── operator_loc: (1,3)-(1,4) = "*"
+ │ └── expression: ∅
+ ├── rights: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,8)-(1,9) = "="
+ └── value:
+ @ CallNode (location: (1,10)-(1,11))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (1,10)-(1,11) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt b/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
new file mode 100644
index 0000000000..7a3e9affb5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
@@ -0,0 +1,60 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,15))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,15))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,2)-(1,15))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,3)-(1,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ConstantPathOperatorWriteNode (location: (1,3)-(1,14))
+ │ │ ├── target:
+ │ │ │ @ ConstantPathNode (location: (1,3)-(1,7))
+ │ │ │ ├── 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) = "*="
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (1,11)-(1,14))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (1,11)-(1,12) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,13)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,13)-(1,14))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :e
+ │ │ │ │ ├── message_loc: (1,13)-(1,14) = "e"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator: :*
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,14)-(1,15) = ")"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt
new file mode 100644
index 0000000000..da10a474c3
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/method_call_assoc_trailing_comma.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,10))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :f
+ ├── message_loc: (1,2)-(1,3) = "f"
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,4)-(1,8))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,4)-(1,8))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (1,5)-(1,7) = "=>"
+ ├── closing_loc: (1,9)-(1,10) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/method_call_trailing_comma.txt b/test/prism/snapshots/seattlerb/method_call_trailing_comma.txt
new file mode 100644
index 0000000000..edf79062cf
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/method_call_trailing_comma.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :f
+ ├── message_loc: (1,2)-(1,3) = "f"
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (1,6)-(1,7) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/mlhs_back_anonsplat.txt b/test/prism/snapshots/seattlerb/mlhs_back_anonsplat.txt
new file mode 100644
index 0000000000..600f7f717b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/mlhs_back_anonsplat.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: [:a, :b, :c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,14))
+ ├── lefts: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (1,3)-(1,4))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ ├── name: :c
+ │ └── depth: 0
+ ├── rest:
+ │ @ SplatNode (location: (1,9)-(1,10))
+ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ └── expression: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,11)-(1,12) = "="
+ └── value:
+ @ CallNode (location: (1,13)-(1,14))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,13)-(1,14) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/mlhs_back_splat.txt b/test/prism/snapshots/seattlerb/mlhs_back_splat.txt
new file mode 100644
index 0000000000..f5d3fe5ae9
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/mlhs_back_splat.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: [:a, :b, :c, :s]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,15))
+ ├── lefts: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (1,3)-(1,4))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ ├── name: :c
+ │ └── depth: 0
+ ├── rest:
+ │ @ SplatNode (location: (1,9)-(1,11))
+ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ └── expression:
+ │ @ LocalVariableTargetNode (location: (1,10)-(1,11))
+ │ ├── name: :s
+ │ └── depth: 0
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,12)-(1,13) = "="
+ └── value:
+ @ CallNode (location: (1,14)-(1,15))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,14)-(1,15) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/mlhs_front_anonsplat.txt b/test/prism/snapshots/seattlerb/mlhs_front_anonsplat.txt
new file mode 100644
index 0000000000..d4797031a5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/mlhs_front_anonsplat.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: [:x, :y, :z]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,14))
+ ├── lefts: (length: 0)
+ ├── rest:
+ │ @ SplatNode (location: (1,0)-(1,1))
+ │ ├── operator_loc: (1,0)-(1,1) = "*"
+ │ └── expression: ∅
+ ├── rights: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (1,3)-(1,4))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ │ ├── name: :y
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,9)-(1,10))
+ │ ├── name: :z
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,11)-(1,12) = "="
+ └── value:
+ @ CallNode (location: (1,13)-(1,14))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,13)-(1,14) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/mlhs_front_splat.txt b/test/prism/snapshots/seattlerb/mlhs_front_splat.txt
new file mode 100644
index 0000000000..47a7b8da7c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/mlhs_front_splat.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: [:s, :x, :y, :z]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,15))
+ ├── lefts: (length: 0)
+ ├── rest:
+ │ @ SplatNode (location: (1,0)-(1,2))
+ │ ├── operator_loc: (1,0)-(1,1) = "*"
+ │ └── expression:
+ │ @ LocalVariableTargetNode (location: (1,1)-(1,2))
+ │ ├── name: :s
+ │ └── depth: 0
+ ├── rights: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (1,7)-(1,8))
+ │ │ ├── name: :y
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,10)-(1,11))
+ │ ├── name: :z
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,12)-(1,13) = "="
+ └── value:
+ @ CallNode (location: (1,14)-(1,15))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,14)-(1,15) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/mlhs_keyword.txt b/test/prism/snapshots/seattlerb/mlhs_keyword.txt
new file mode 100644
index 0000000000..6142640b2c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/mlhs_keyword.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :!=
+ ├── message_loc: (1,2)-(1,4) = "!="
+ ├── opening_loc: (1,4)-(1,5) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,15))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ TrueNode (location: (1,5)-(1,9))
+ │ └── @ TrueNode (location: (1,11)-(1,15))
+ ├── closing_loc: (1,15)-(1,16) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/mlhs_mid_anonsplat.txt b/test/prism/snapshots/seattlerb/mlhs_mid_anonsplat.txt
new file mode 100644
index 0000000000..b6306e1674
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/mlhs_mid_anonsplat.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: [:a, :b, :c, :x, :y, :z]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,23))
+ ├── lefts: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (1,3)-(1,4))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ ├── name: :c
+ │ └── depth: 0
+ ├── rest:
+ │ @ SplatNode (location: (1,9)-(1,10))
+ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ └── expression: ∅
+ ├── rights: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (1,12)-(1,13))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (1,15)-(1,16))
+ │ │ ├── name: :y
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,18)-(1,19))
+ │ ├── name: :z
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,20)-(1,21) = "="
+ └── value:
+ @ CallNode (location: (1,22)-(1,23))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,22)-(1,23) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/mlhs_mid_splat.txt b/test/prism/snapshots/seattlerb/mlhs_mid_splat.txt
new file mode 100644
index 0000000000..1dae24d911
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/mlhs_mid_splat.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: [:a, :b, :c, :s, :x, :y, :z]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,24))
+ ├── lefts: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (1,3)-(1,4))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ ├── name: :c
+ │ └── depth: 0
+ ├── rest:
+ │ @ SplatNode (location: (1,9)-(1,11))
+ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ └── expression:
+ │ @ LocalVariableTargetNode (location: (1,10)-(1,11))
+ │ ├── name: :s
+ │ └── depth: 0
+ ├── rights: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (1,13)-(1,14))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (1,16)-(1,17))
+ │ │ ├── name: :y
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,19)-(1,20))
+ │ ├── name: :z
+ │ └── depth: 0
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,21)-(1,22) = "="
+ └── value:
+ @ CallNode (location: (1,23)-(1,24))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,23)-(1,24) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/mlhs_rescue.txt b/test/prism/snapshots/seattlerb/mlhs_rescue.txt
new file mode 100644
index 0000000000..bd983cd3f9
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/mlhs_rescue.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,18))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,3)-(1,4))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,5)-(1,6) = "="
+ └── value:
+ @ RescueModifierNode (location: (1,7)-(1,18))
+ ├── expression:
+ │ @ CallNode (location: (1,7)-(1,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (1,7)-(1,8) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── keyword_loc: (1,9)-(1,15) = "rescue"
+ └── rescue_expression:
+ @ IntegerNode (location: (1,16)-(1,18))
+ ├── flags: decimal
+ └── value: 42
diff --git a/test/prism/snapshots/seattlerb/module_comments.txt b/test/prism/snapshots/seattlerb/module_comments.txt
new file mode 100644
index 0000000000..2785187a29
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/module_comments.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (5,0)-(10,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (5,0)-(10,3))
+ └── body: (length: 1)
+ └── @ ModuleNode (location: (5,0)-(10,3))
+ ├── locals: []
+ ├── module_keyword_loc: (5,0)-(5,6) = "module"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (5,7)-(5,8))
+ │ └── name: :X
+ ├── body:
+ │ @ StatementsNode (location: (7,2)-(9,5))
+ │ └── body: (length: 1)
+ │ └── @ DefNode (location: (7,2)-(9,5))
+ │ ├── name: :blah
+ │ ├── name_loc: (7,6)-(7,10) = "blah"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (7,2)-(7,5) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (9,2)-(9,5) = "end"
+ ├── end_keyword_loc: (10,0)-(10,3) = "end"
+ └── name: :X
diff --git a/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt b/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt
new file mode 100644
index 0000000000..79b0ef5d23
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/multiline_hash_declaration.txt
@@ -0,0 +1,95 @@
+@ ProgramNode (location: (1,0)-(8,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(8,12))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(3,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (1,0)-(1,1) = "f"
+ │ ├── opening_loc: (1,1)-(1,2) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(3,1))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,2)-(3,1))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,2)-(3,1))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,2)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,2)-(1,7) = "state"
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = ":"
+ │ │ │ └── unescaped: "state"
+ │ │ ├── value:
+ │ │ │ @ HashNode (location: (2,1)-(3,1))
+ │ │ │ ├── opening_loc: (2,1)-(2,2) = "{"
+ │ │ │ ├── elements: (length: 0)
+ │ │ │ └── closing_loc: (3,0)-(3,1) = "}"
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (3,1)-(3,2) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(6,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (5,0)-(5,1) = "f"
+ │ ├── opening_loc: (5,1)-(5,2) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,2)-(6,1))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (5,2)-(6,1))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (5,2)-(6,1))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (5,2)-(5,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (5,2)-(5,7) = "state"
+ │ │ │ ├── closing_loc: (5,7)-(5,8) = ":"
+ │ │ │ └── unescaped: "state"
+ │ │ ├── value:
+ │ │ │ @ HashNode (location: (5,9)-(6,1))
+ │ │ │ ├── opening_loc: (5,9)-(5,10) = "{"
+ │ │ │ ├── elements: (length: 0)
+ │ │ │ └── closing_loc: (6,0)-(6,1) = "}"
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (6,1)-(6,2) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (8,0)-(8,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (8,0)-(8,1) = "f"
+ ├── opening_loc: (8,1)-(8,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (8,2)-(8,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (8,2)-(8,11))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (8,2)-(8,11))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (8,2)-(8,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (8,2)-(8,7) = "state"
+ │ │ ├── closing_loc: (8,7)-(8,8) = ":"
+ │ │ └── unescaped: "state"
+ │ ├── value:
+ │ │ @ HashNode (location: (8,9)-(8,11))
+ │ │ ├── opening_loc: (8,9)-(8,10) = "{"
+ │ │ ├── elements: (length: 0)
+ │ │ └── closing_loc: (8,10)-(8,11) = "}"
+ │ └── operator_loc: ∅
+ ├── closing_loc: (8,11)-(8,12) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt b/test/prism/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt
new file mode 100644
index 0000000000..cbf4ec4a08
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(5,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,1))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(4,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (2,0)-(2,1))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (2,0)-(2,1) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (3,0)-(3,1))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (3,0)-(3,1) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── opening_loc: (1,0)-(1,3) = "%i("
+ │ └── closing_loc: (4,0)-(4,1) = ")"
+ └── @ IntegerNode (location: (5,0)-(5,1))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt b/test/prism/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt
new file mode 100644
index 0000000000..e82f250098
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(5,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,1))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(4,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (2,0)-(2,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(2,1) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ StringNode (location: (3,0)-(3,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (3,0)-(3,1) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── opening_loc: (1,0)-(1,3) = "%w("
+ │ └── closing_loc: (4,0)-(4,1) = ")"
+ └── @ IntegerNode (location: (5,0)-(5,1))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/op_asgn_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_command_call.txt
new file mode 100644
index 0000000000..54aa06214f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/op_asgn_command_call.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ LocalVariableOrWriteNode (location: (1,0)-(1,11))
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── operator_loc: (1,2)-(1,5) = "||="
+ ├── value:
+ │ @ CallNode (location: (1,6)-(1,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,6)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,6)-(1,7) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,7)-(1,8) = "."
+ │ ├── name: :c
+ │ ├── message_loc: (1,8)-(1,9) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── name: :a
+ └── depth: 0
diff --git a/test/prism/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt
new file mode 100644
index 0000000000..324c042b00
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallOrWriteNode (location: (1,0)-(1,11))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ ConstantReadNode (location: (1,0)-(1,1))
+ │ └── name: :A
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── message_loc: (1,2)-(1,3) = "B"
+ ├── read_name: :B
+ ├── write_name: :B=
+ ├── operator_loc: (1,4)-(1,7) = "||="
+ └── value:
+ @ CallNode (location: (1,8)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (1,8)-(1,9) = "c"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/op_asgn_index_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_index_command_call.txt
new file mode 100644
index 0000000000..ddee4cde49
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/op_asgn_index_command_call.txt
@@ -0,0 +1,53 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ IndexOrWriteNode (location: (1,0)-(1,16))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── opening_loc: (1,1)-(1,2) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,4))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ SymbolNode (location: (1,2)-(1,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,2)-(1,3) = ":"
+ │ ├── value_loc: (1,3)-(1,4) = "b"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "b"
+ ├── closing_loc: (1,4)-(1,5) = "]"
+ ├── block: ∅
+ ├── operator_loc: (1,6)-(1,9) = "||="
+ └── value:
+ @ CallNode (location: (1,10)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (1,10)-(1,11) = "c"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,12)-(1,16))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,12)-(1,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ IntegerNode (location: (1,15)-(1,16))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: ∅
+ └── block: ∅
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
new file mode 100644
index 0000000000..8e6df3e812
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ ConstantPathOperatorWriteNode (location: (1,0)-(1,11))
+ ├── target:
+ │ @ ConstantPathNode (location: (1,0)-(1,4))
+ │ ├── 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) = "*="
+ ├── value:
+ │ @ CallNode (location: (1,8)-(1,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :c
+ │ ├── message_loc: (1,8)-(1,9) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,10)-(1,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (1,10)-(1,11) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── 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
new file mode 100644
index 0000000000..0daadcf6ff
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallOperatorWriteNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ ConstantReadNode (location: (1,0)-(1,1))
+ │ └── name: :A
+ ├── call_operator_loc: (1,1)-(1,3) = "::"
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── read_name: :b
+ ├── write_name: :b=
+ ├── operator: :+
+ ├── operator_loc: (1,5)-(1,7) = "+="
+ └── value:
+ @ IntegerNode (location: (1,8)-(1,9))
+ ├── flags: decimal
+ └── value: 1
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
new file mode 100644
index 0000000000..ea8603165b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallOperatorWriteNode (location: (1,0)-(1,11))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ ConstantReadNode (location: (1,0)-(1,1))
+ │ └── name: :A
+ ├── call_operator_loc: (1,1)-(1,3) = "::"
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── read_name: :b
+ ├── write_name: :b=
+ ├── operator: :*
+ ├── operator_loc: (1,5)-(1,7) = "*="
+ └── value:
+ @ CallNode (location: (1,8)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (1,8)-(1,9) = "c"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,10)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :d
+ │ ├── message_loc: (1,10)-(1,11) = "d"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/op_asgn_val_dot_ident_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_val_dot_ident_command_call.txt
new file mode 100644
index 0000000000..b3b5709193
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/op_asgn_val_dot_ident_command_call.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallOrWriteNode (location: (1,0)-(1,11))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── message_loc: (1,2)-(1,3) = "b"
+ ├── read_name: :b
+ ├── write_name: :b=
+ ├── operator_loc: (1,4)-(1,7) = "||="
+ └── value:
+ @ CallNode (location: (1,8)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (1,8)-(1,9) = "c"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_def_special_name.txt b/test/prism/snapshots/seattlerb/parse_def_special_name.txt
new file mode 100644
index 0000000000..dfbfe8a391
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_def_special_name.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,13))
+ ├── name: :next
+ ├── name_loc: (1,4)-(1,8) = "next"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,10)-(1,13) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_if_not_canonical.txt b/test/prism/snapshots/seattlerb/parse_if_not_canonical.txt
new file mode 100644
index 0000000000..763bd24efd
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_if_not_canonical.txt
@@ -0,0 +1,62 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(2,3))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (1,3)-(1,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,7)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,7)-(1,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :var
+ │ │ │ ├── message_loc: (1,7)-(1,10) = "var"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (1,10)-(1,11) = "."
+ │ │ ├── name: :nil?
+ │ │ ├── message_loc: (1,11)-(1,15) = "nil?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,3)-(1,6) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: (1,16)-(1,20) = "then"
+ ├── statements:
+ │ @ StatementsNode (location: (1,21)-(1,26))
+ │ └── body: (length: 1)
+ │ └── @ StringNode (location: (1,21)-(1,26))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,21)-(1,22) = "'"
+ │ ├── content_loc: (1,22)-(1,25) = "foo"
+ │ ├── closing_loc: (1,25)-(1,26) = "'"
+ │ └── unescaped: "foo"
+ ├── consequent:
+ │ @ ElseNode (location: (1,27)-(2,3))
+ │ ├── else_keyword_loc: (1,27)-(1,31) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,32)-(1,37))
+ │ │ └── body: (length: 1)
+ │ │ └── @ StringNode (location: (1,32)-(1,37))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,32)-(1,33) = "'"
+ │ │ ├── content_loc: (1,33)-(1,36) = "bar"
+ │ │ ├── closing_loc: (1,36)-(1,37) = "'"
+ │ │ └── unescaped: "bar"
+ │ └── end_keyword_loc: (2,0)-(2,3) = "end"
+ └── end_keyword_loc: (2,0)-(2,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_if_not_noncanonical.txt b/test/prism/snapshots/seattlerb/parse_if_not_noncanonical.txt
new file mode 100644
index 0000000000..763bd24efd
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_if_not_noncanonical.txt
@@ -0,0 +1,62 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(2,3))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (1,3)-(1,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,7)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,7)-(1,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :var
+ │ │ │ ├── message_loc: (1,7)-(1,10) = "var"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (1,10)-(1,11) = "."
+ │ │ ├── name: :nil?
+ │ │ ├── message_loc: (1,11)-(1,15) = "nil?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,3)-(1,6) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: (1,16)-(1,20) = "then"
+ ├── statements:
+ │ @ StatementsNode (location: (1,21)-(1,26))
+ │ └── body: (length: 1)
+ │ └── @ StringNode (location: (1,21)-(1,26))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,21)-(1,22) = "'"
+ │ ├── content_loc: (1,22)-(1,25) = "foo"
+ │ ├── closing_loc: (1,25)-(1,26) = "'"
+ │ └── unescaped: "foo"
+ ├── consequent:
+ │ @ ElseNode (location: (1,27)-(2,3))
+ │ ├── else_keyword_loc: (1,27)-(1,31) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,32)-(1,37))
+ │ │ └── body: (length: 1)
+ │ │ └── @ StringNode (location: (1,32)-(1,37))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,32)-(1,33) = "'"
+ │ │ ├── content_loc: (1,33)-(1,36) = "bar"
+ │ │ ├── closing_loc: (1,36)-(1,37) = "'"
+ │ │ └── unescaped: "bar"
+ │ └── end_keyword_loc: (2,0)-(2,3) = "end"
+ └── end_keyword_loc: (2,0)-(2,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_block.txt b/test/prism/snapshots/seattlerb/parse_line_block.txt
new file mode 100644
index 0000000000..623c08d50e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_block.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 2)
+ ├── @ LocalVariableWriteNode (location: (1,0)-(1,6))
+ │ ├── name: :a
+ │ ├── depth: 0
+ │ ├── name_loc: (1,0)-(1,1) = "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,4)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ └── operator_loc: (1,2)-(1,3) = "="
+ └── @ CallNode (location: (2,0)-(2,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (2,0)-(2,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (2,2)-(2,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (2,2)-(2,3))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_block_inline_comment.txt b/test/prism/snapshots/seattlerb/parse_line_block_inline_comment.txt
new file mode 100644
index 0000000000..8495527cf4
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_block_inline_comment.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(3,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,1))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (2,0)-(2,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (2,0)-(2,1) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (3,0)-(3,1) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_block_inline_comment_leading_newlines.txt b/test/prism/snapshots/seattlerb/parse_line_block_inline_comment_leading_newlines.txt
new file mode 100644
index 0000000000..f531a73a58
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_block_inline_comment_leading_newlines.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (4,0)-(7,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (4,0)-(7,1))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (4,0)-(4,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (4,0)-(4,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (5,0)-(5,1) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (7,0)-(7,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (7,0)-(7,1) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_block_inline_multiline_comment.txt b/test/prism/snapshots/seattlerb/parse_line_block_inline_multiline_comment.txt
new file mode 100644
index 0000000000..d4e962b355
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_block_inline_multiline_comment.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(4,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,1))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (2,0)-(2,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (2,0)-(2,1) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (4,0)-(4,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (4,0)-(4,1) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt b/test/prism/snapshots/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt
new file mode 100644
index 0000000000..a08f5419f1
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,4))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InstanceVariableReadNode (location: (1,2)-(1,4))
+ │ └── name: :@b
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_call_ivar_line_break_paren.txt b/test/prism/snapshots/seattlerb/parse_line_call_ivar_line_break_paren.txt
new file mode 100644
index 0000000000..dd58d92d3a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_call_ivar_line_break_paren.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(2,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,1))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(2,1))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,4))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InstanceVariableReadNode (location: (1,2)-(1,4))
+ │ └── name: :@b
+ ├── closing_loc: (2,0)-(2,1) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_call_no_args.txt b/test/prism/snapshots/seattlerb/parse_line_call_no_args.txt
new file mode 100644
index 0000000000..8a0fcd63af
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_call_no_args.txt
@@ -0,0 +1,61 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(3,3))
+ ├── locals: [:x, :y]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,5)-(1,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,10))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :x
+ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :y
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,5)-(1,6) = "|"
+ │ └── closing_loc: (1,10)-(1,11) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (2,2)-(2,7))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,2)-(2,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (2,2)-(2,3))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (2,4)-(2,5) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (2,6)-(2,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (2,6)-(2,7))
+ │ │ ├── name: :y
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (1,2)-(1,4) = "do"
+ └── closing_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
new file mode 100644
index 0000000000..50ccb762be
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
@@ -0,0 +1,66 @@
+@ ProgramNode (location: (1,0)-(5,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(5,3))
+ ├── name: :x
+ ├── name_loc: (1,4)-(1,5) = "x"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,7))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── name: :y
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (2,2)-(4,10))
+ │ └── body: (length: 3)
+ │ ├── @ CallNode (location: (2,2)-(2,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :p
+ │ │ ├── message_loc: (2,2)-(2,3) = "p"
+ │ │ ├── opening_loc: (2,3)-(2,4) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (2,4)-(2,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (2,4)-(2,5))
+ │ │ │ ├── name: :y
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: (2,5)-(2,6) = ")"
+ │ │ └── block: ∅
+ │ ├── @ LocalVariableOperatorWriteNode (location: (3,2)-(3,8))
+ │ │ ├── name_loc: (3,2)-(3,3) = "y"
+ │ │ ├── operator_loc: (3,4)-(3,6) = "*="
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,7)-(3,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── name: :y
+ │ │ ├── operator: :*
+ │ │ └── depth: 0
+ │ └── @ ReturnNode (location: (4,2)-(4,10))
+ │ ├── keyword_loc: (4,2)-(4,8) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (4,9)-(4,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (4,9)-(4,10))
+ │ ├── name: :y
+ │ └── depth: 0
+ ├── locals: [:y]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,7)-(1,8) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (5,0)-(5,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_defn_no_parens.txt b/test/prism/snapshots/seattlerb/parse_line_defn_no_parens.txt
new file mode 100644
index 0000000000..74240322ac
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_defn_no_parens.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(6,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,3))
+ └── body: (length: 2)
+ ├── @ DefNode (location: (1,0)-(3,3))
+ │ ├── name: :f
+ │ ├── name_loc: (1,4)-(1,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ └── @ DefNode (location: (5,0)-(6,3))
+ ├── name: :f
+ ├── name_loc: (5,4)-(5,5) = "f"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (6,0)-(6,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_defn_no_parens_args.txt b/test/prism/snapshots/seattlerb/parse_line_defn_no_parens_args.txt
new file mode 100644
index 0000000000..8445743293
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_defn_no_parens_args.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(2,3))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,7))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── name: :a
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (2,0)-(2,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_dot2.txt b/test/prism/snapshots/seattlerb/parse_line_dot2.txt
new file mode 100644
index 0000000000..9ccf5bdc99
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_dot2.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(5,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,1))
+ └── body: (length: 3)
+ ├── @ RangeNode (location: (1,0)-(2,1))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ ├── right:
+ │ │ @ IntegerNode (location: (2,0)-(2,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 4
+ │ └── operator_loc: (1,1)-(1,3) = ".."
+ ├── @ RangeNode (location: (3,0)-(4,1))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ CallNode (location: (3,0)-(3,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (3,0)-(3,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (4,0)-(4,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (4,0)-(4,1) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (3,1)-(3,3) = ".."
+ └── @ CallNode (location: (5,0)-(5,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (5,0)-(5,1) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_dot2_open.txt b/test/prism/snapshots/seattlerb/parse_line_dot2_open.txt
new file mode 100644
index 0000000000..f85fdd6d4b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_dot2_open.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 3)
+ ├── @ RangeNode (location: (1,0)-(1,3))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ ├── right: ∅
+ │ └── operator_loc: (1,1)-(1,3) = ".."
+ ├── @ RangeNode (location: (2,2)-(2,5))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ CallNode (location: (2,2)-(2,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (2,2)-(2,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right: ∅
+ │ └── operator_loc: (2,3)-(2,5) = ".."
+ └── @ CallNode (location: (3,2)-(3,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (3,2)-(3,3) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_dot3.txt b/test/prism/snapshots/seattlerb/parse_line_dot3.txt
new file mode 100644
index 0000000000..6364c1f136
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_dot3.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(5,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,1))
+ └── body: (length: 3)
+ ├── @ RangeNode (location: (1,0)-(2,1))
+ │ ├── flags: exclude_end
+ │ ├── left:
+ │ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ ├── right:
+ │ │ @ IntegerNode (location: (2,0)-(2,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 4
+ │ └── operator_loc: (1,1)-(1,4) = "..."
+ ├── @ RangeNode (location: (3,0)-(4,1))
+ │ ├── flags: exclude_end
+ │ ├── left:
+ │ │ @ CallNode (location: (3,0)-(3,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (3,0)-(3,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (4,0)-(4,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (4,0)-(4,1) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (3,1)-(3,4) = "..."
+ └── @ CallNode (location: (5,0)-(5,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (5,0)-(5,1) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_dot3_open.txt b/test/prism/snapshots/seattlerb/parse_line_dot3_open.txt
new file mode 100644
index 0000000000..35759d12e3
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_dot3_open.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 3)
+ ├── @ RangeNode (location: (1,0)-(1,4))
+ │ ├── flags: exclude_end
+ │ ├── left:
+ │ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ ├── right: ∅
+ │ └── operator_loc: (1,1)-(1,4) = "..."
+ ├── @ RangeNode (location: (2,2)-(2,6))
+ │ ├── flags: exclude_end
+ │ ├── left:
+ │ │ @ CallNode (location: (2,2)-(2,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (2,2)-(2,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right: ∅
+ │ └── operator_loc: (2,3)-(2,6) = "..."
+ └── @ CallNode (location: (3,2)-(3,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :c
+ ├── message_loc: (3,2)-(3,3) = "c"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt b/test/prism/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt
new file mode 100644
index 0000000000..aada5a9477
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(3,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,4))
+ └── body: (length: 2)
+ ├── @ InterpolatedStringNode (location: (1,0)-(2,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (1,1)-(1,4))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (1,1)-(1,4) = "a\\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ EmbeddedStatementsNode (location: (1,4)-(2,1))
+ │ │ ├── opening_loc: (1,4)-(1,6) = "\#{"
+ │ │ ├── statements: ∅
+ │ │ └── closing_loc: (2,0)-(2,1) = "}"
+ │ └── closing_loc: (2,1)-(2,2) = "\""
+ └── @ TrueNode (location: (3,0)-(3,4))
diff --git a/test/prism/snapshots/seattlerb/parse_line_dstr_soft_newline.txt b/test/prism/snapshots/seattlerb/parse_line_dstr_soft_newline.txt
new file mode 100644
index 0000000000..7ef56acb76
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_dstr_soft_newline.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(4,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,4))
+ └── body: (length: 2)
+ ├── @ InterpolatedStringNode (location: (1,0)-(3,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (1,1)-(2,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (1,1)-(2,0) = "a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ EmbeddedStatementsNode (location: (2,0)-(3,1))
+ │ │ ├── opening_loc: (2,0)-(2,2) = "\#{"
+ │ │ ├── statements: ∅
+ │ │ └── closing_loc: (3,0)-(3,1) = "}"
+ │ └── closing_loc: (3,1)-(3,2) = "\""
+ └── @ TrueNode (location: (4,0)-(4,4))
diff --git a/test/prism/snapshots/seattlerb/parse_line_evstr_after_break.txt b/test/prism/snapshots/seattlerb/parse_line_evstr_after_break.txt
new file mode 100644
index 0000000000..82f461e340
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_evstr_after_break.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(2,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,6))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(2,6))
+ ├── flags: ∅
+ ├── opening_loc: ∅
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (1,0)-(1,3))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ │ ├── content_loc: (1,1)-(1,2) = "a"
+ │ │ ├── closing_loc: (1,2)-(1,3) = "\""
+ │ │ └── unescaped: "a"
+ │ └── @ InterpolatedStringNode (location: (2,0)-(2,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (2,0)-(2,1) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (2,1)-(2,5))
+ │ │ ├── opening_loc: (2,1)-(2,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (2,3)-(2,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,3)-(2,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (2,3)-(2,4) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (2,4)-(2,5) = "}"
+ │ └── closing_loc: (2,5)-(2,6) = "\""
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_hash_lit.txt b/test/prism/snapshots/seattlerb/parse_line_hash_lit.txt
new file mode 100644
index 0000000000..0f95a607aa
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_hash_lit.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(3,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,1))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,0)-(3,1))
+ ├── opening_loc: (1,0)-(1,1) = "{"
+ ├── elements: (length: 1)
+ │ └── @ AssocNode (location: (2,0)-(2,8))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (2,0)-(2,3))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (2,0)-(2,1) = ":"
+ │ │ ├── value_loc: (2,1)-(2,3) = "s1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "s1"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (2,7)-(2,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (2,4)-(2,6) = "=>"
+ └── closing_loc: (3,0)-(3,1) = "}"
diff --git a/test/prism/snapshots/seattlerb/parse_line_heredoc.txt b/test/prism/snapshots/seattlerb/parse_line_heredoc.txt
new file mode 100644
index 0000000000..ba00f01504
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_heredoc.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,6)-(4,17))
+├── locals: [:string]
+└── statements:
+ @ StatementsNode (location: (1,6)-(4,17))
+ └── body: (length: 2)
+ ├── @ LocalVariableWriteNode (location: (1,6)-(1,31))
+ │ ├── name: :string
+ │ ├── depth: 0
+ │ ├── name_loc: (1,6)-(1,12) = "string"
+ │ ├── value:
+ │ │ @ CallNode (location: (1,15)-(1,31))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ StringNode (location: (1,15)-(1,25))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,15)-(1,25) = "<<-HEREDOC"
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " very long string\n"
+ │ │ │ ├── closing_loc: (3,0)-(4,0) = " HEREDOC\n"
+ │ │ │ └── unescaped: " very long string\n"
+ │ │ ├── call_operator_loc: (1,25)-(1,26) = "."
+ │ │ ├── name: :strip
+ │ │ ├── message_loc: (1,26)-(1,31) = "strip"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,13)-(1,14) = "="
+ └── @ CallNode (location: (4,6)-(4,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :puts
+ ├── message_loc: (4,6)-(4,10) = "puts"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (4,11)-(4,17))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (4,11)-(4,17))
+ │ ├── name: :string
+ │ └── depth: 0
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_heredoc_evstr.txt b/test/prism/snapshots/seattlerb/parse_line_heredoc_evstr.txt
new file mode 100644
index 0000000000..b251b2b344
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_heredoc_evstr.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,4) = "<<-A"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (2,0)-(3,0) = "a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\n"
+ │ ├── @ EmbeddedStatementsNode (location: (3,0)-(3,4))
+ │ │ ├── opening_loc: (3,0)-(3,2) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,2)-(3,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,2)-(3,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (3,2)-(3,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (3,3)-(3,4) = "}"
+ │ └── @ StringNode (location: (3,4)-(4,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (3,4)-(4,0) = "\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\n"
+ └── closing_loc: (4,0)-(5,0) = "A\n"
diff --git a/test/prism/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt b/test/prism/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt
new file mode 100644
index 0000000000..ad0f0dfd99
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(6,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,3))
+ └── body: (length: 2)
+ ├── @ StringNode (location: (1,0)-(1,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,8) = "<<-EOFOO"
+ │ ├── content_loc: (2,0)-(3,0) = "\\n\\n\\n\\n\\n\\n\\n\\n\\n\n"
+ │ ├── closing_loc: (3,0)-(4,0) = "EOFOO\n"
+ │ └── unescaped: "\n\n\n\n\n\n\n\n\n\n"
+ └── @ ClassNode (location: (5,0)-(6,3))
+ ├── locals: []
+ ├── class_keyword_loc: (5,0)-(5,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (5,6)-(5,9))
+ │ └── name: :Foo
+ ├── inheritance_operator_loc: ∅
+ ├── superclass: ∅
+ ├── body: ∅
+ ├── end_keyword_loc: (6,0)-(6,3) = "end"
+ └── name: :Foo
diff --git a/test/prism/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt b/test/prism/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt
new file mode 100644
index 0000000000..fdac30fab7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,6)-(4,17))
+├── locals: [:string]
+└── statements:
+ @ StatementsNode (location: (1,6)-(4,17))
+ └── body: (length: 2)
+ ├── @ LocalVariableWriteNode (location: (1,6)-(1,22))
+ │ ├── name: :string
+ │ ├── depth: 0
+ │ ├── name_loc: (1,6)-(1,12) = "string"
+ │ ├── value:
+ │ │ @ StringNode (location: (1,15)-(1,22))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,15)-(1,22) = "<<-\"^D\""
+ │ │ ├── content_loc: (2,0)-(3,0) = " very long string\n"
+ │ │ ├── closing_loc: (3,0)-(4,0) = " ^D\n"
+ │ │ └── unescaped: " very long string\n"
+ │ └── operator_loc: (1,13)-(1,14) = "="
+ └── @ CallNode (location: (4,6)-(4,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :puts
+ ├── message_loc: (4,6)-(4,10) = "puts"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (4,11)-(4,17))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (4,11)-(4,17))
+ │ ├── name: :string
+ │ └── depth: 0
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_iter_call_no_parens.txt b/test/prism/snapshots/seattlerb/parse_line_iter_call_no_parens.txt
new file mode 100644
index 0000000000..8d9dbf24ab
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_iter_call_no_parens.txt
@@ -0,0 +1,74 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,2)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,2)-(1,3) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,4)-(3,3))
+ ├── locals: [:x, :y]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,7)-(1,13))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,8)-(1,12))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,8)-(1,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :x
+ │ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :y
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,7)-(1,8) = "|"
+ │ └── closing_loc: (1,12)-(1,13) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (2,2)-(2,7))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,2)-(2,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (2,2)-(2,3))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (2,4)-(2,5) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (2,6)-(2,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (2,6)-(2,7))
+ │ │ ├── name: :y
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (1,4)-(1,6) = "do"
+ └── closing_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_iter_call_parens.txt b/test/prism/snapshots/seattlerb/parse_line_iter_call_parens.txt
new file mode 100644
index 0000000000..663d870137
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_iter_call_parens.txt
@@ -0,0 +1,74 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,2)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,2)-(1,3) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (1,3)-(1,4) = ")"
+ └── block:
+ @ BlockNode (location: (1,5)-(3,3))
+ ├── locals: [:x, :y]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,8)-(1,14))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,9)-(1,13))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :x
+ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :y
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,8)-(1,9) = "|"
+ │ └── closing_loc: (1,13)-(1,14) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (2,2)-(2,7))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,2)-(2,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (2,2)-(2,3))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (2,4)-(2,5) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (2,6)-(2,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (2,6)-(2,7))
+ │ │ ├── name: :y
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (1,5)-(1,7) = "do"
+ └── closing_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_multiline_str.txt b/test/prism/snapshots/seattlerb/parse_line_multiline_str.txt
new file mode 100644
index 0000000000..8d4578eaec
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_multiline_str.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(3,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,1))
+ └── body: (length: 2)
+ ├── @ StringNode (location: (1,0)-(2,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── content_loc: (1,1)-(2,1) = "a\nb"
+ │ ├── closing_loc: (2,1)-(2,2) = "\""
+ │ └── unescaped: "a\nb"
+ └── @ IntegerNode (location: (3,0)-(3,1))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt b/test/prism/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt
new file mode 100644
index 0000000000..49d31f5b1b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(2,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,1))
+ └── body: (length: 2)
+ ├── @ StringNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── content_loc: (1,1)-(1,5) = "a\\nb"
+ │ ├── closing_loc: (1,5)-(1,6) = "\""
+ │ └── unescaped: "a\nb"
+ └── @ IntegerNode (location: (2,0)-(2,1))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/parse_line_newlines.txt b/test/prism/snapshots/seattlerb/parse_line_newlines.txt
new file mode 100644
index 0000000000..3e1ceef586
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_newlines.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ TrueNode (location: (1,0)-(1,4))
diff --git a/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt b/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
new file mode 100644
index 0000000000..5c2eb2da3c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,6)-(3,9))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,6)-(3,9))
+ └── body: (length: 2)
+ ├── @ LocalVariableOperatorWriteNode (location: (1,6)-(2,11))
+ │ ├── name_loc: (1,6)-(1,9) = "foo"
+ │ ├── operator_loc: (1,10)-(1,12) = "+="
+ │ ├── value:
+ │ │ @ CallNode (location: (2,8)-(2,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (2,8)-(2,11) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── name: :foo
+ │ ├── operator: :+
+ │ └── depth: 0
+ └── @ CallNode (location: (3,6)-(3,9))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :baz
+ ├── message_loc: (3,6)-(3,9) = "baz"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_postexe.txt b/test/prism/snapshots/seattlerb/parse_line_postexe.txt
new file mode 100644
index 0000000000..68b5f02fe0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_postexe.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(3,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,1))
+ └── body: (length: 1)
+ └── @ PostExecutionNode (location: (1,0)-(3,1))
+ ├── statements:
+ │ @ StatementsNode (location: (2,0)-(2,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,0)-(2,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (2,0)-(2,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── keyword_loc: (1,0)-(1,3) = "END"
+ ├── opening_loc: (1,4)-(1,5) = "{"
+ └── closing_loc: (3,0)-(3,1) = "}"
diff --git a/test/prism/snapshots/seattlerb/parse_line_preexe.txt b/test/prism/snapshots/seattlerb/parse_line_preexe.txt
new file mode 100644
index 0000000000..65ea22cf7d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_preexe.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(3,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,1))
+ └── body: (length: 1)
+ └── @ PreExecutionNode (location: (1,0)-(3,1))
+ ├── statements:
+ │ @ StatementsNode (location: (2,0)-(2,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,0)-(2,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (2,0)-(2,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── keyword_loc: (1,0)-(1,5) = "BEGIN"
+ ├── opening_loc: (1,6)-(1,7) = "{"
+ └── closing_loc: (3,0)-(3,1) = "}"
diff --git a/test/prism/snapshots/seattlerb/parse_line_rescue.txt b/test/prism/snapshots/seattlerb/parse_line_rescue.txt
new file mode 100644
index 0000000000..cb20d5403b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_rescue.txt
@@ -0,0 +1,62 @@
+@ ProgramNode (location: (1,0)-(7,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,3))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(7,3))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (2,2)-(2,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,2)-(2,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (2,2)-(2,3) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (3,0)-(6,3))
+ │ ├── keyword_loc: (3,0)-(3,6) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (4,2)-(4,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (4,2)-(4,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (4,2)-(4,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent:
+ │ @ RescueNode (location: (5,0)-(6,3))
+ │ ├── keyword_loc: (5,0)-(5,6) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (6,2)-(6,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (6,2)-(6,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (6,2)-(6,3) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (7,0)-(7,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_return.txt b/test/prism/snapshots/seattlerb/parse_line_return.txt
new file mode 100644
index 0000000000..9194ae13ee
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_return.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,6)-(5,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,6)-(5,9))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,6)-(5,9))
+ ├── name: :blah
+ ├── name_loc: (1,10)-(1,14) = "blah"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (2,8)-(4,11))
+ │ └── body: (length: 1)
+ │ └── @ IfNode (location: (2,8)-(4,11))
+ │ ├── if_keyword_loc: (2,8)-(2,10) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (2,11)-(2,15))
+ │ ├── then_keyword_loc: (2,16)-(2,20) = "then"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,10)-(3,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ReturnNode (location: (3,10)-(3,19))
+ │ │ ├── keyword_loc: (3,10)-(3,16) = "return"
+ │ │ └── arguments:
+ │ │ @ ArgumentsNode (location: (3,17)-(3,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (3,17)-(3,19))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (4,8)-(4,11) = "end"
+ ├── locals: []
+ ├── def_keyword_loc: (1,6)-(1,9) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (5,6)-(5,9) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_line_str_with_newline_escape.txt b/test/prism/snapshots/seattlerb/parse_line_str_with_newline_escape.txt
new file mode 100644
index 0000000000..4a675d67c4
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_str_with_newline_escape.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: (1,1)-(1,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,12))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ StringNode (location: (1,2)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ │ ├── content_loc: (1,3)-(1,5) = "\\n"
+ │ │ ├── closing_loc: (1,5)-(1,6) = "\""
+ │ │ └── unescaped: "\n"
+ │ └── @ TrueNode (location: (1,8)-(1,12))
+ ├── closing_loc: (1,12)-(1,13) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_to_ary.txt b/test/prism/snapshots/seattlerb/parse_line_to_ary.txt
new file mode 100644
index 0000000000..0485b0d2e3
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_to_ary.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(3,1))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,1))
+ └── body: (length: 2)
+ ├── @ MultiWriteNode (location: (1,0)-(2,5))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,1))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (2,0)-(2,1))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (2,2)-(2,3) = "="
+ │ └── value:
+ │ @ CallNode (location: (2,4)-(2,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :c
+ │ ├── message_loc: (2,4)-(2,5) = "c"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :d
+ ├── message_loc: (3,0)-(3,1) = "d"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_line_trailing_newlines.txt b/test/prism/snapshots/seattlerb/parse_line_trailing_newlines.txt
new file mode 100644
index 0000000000..5cd7702847
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_line_trailing_newlines.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(2,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,1))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (2,0)-(2,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (2,0)-(2,1) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
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
new file mode 100644
index 0000000000..b767a5c17e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,1)-(1,8) = "[2=>3,]"
+ ├── opening_loc: (1,1)-(1,2) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,2)-(1,6))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,6))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (1,2)-(1,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: (1,3)-(1,5) = "=>"
+ ├── closing_loc: (1,7)-(1,8) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt b/test/prism/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt
new file mode 100644
index 0000000000..d1d3d9335f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,1)-(1,5) = "[2,]"
+ ├── opening_loc: (1,1)-(1,2) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,2)-(1,3))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: (1,4)-(1,5) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/parse_pattern_019.txt b/test/prism/snapshots/seattlerb/parse_pattern_019.txt
new file mode 100644
index 0000000000..9e2500fbde
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_pattern_019.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 0
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,6))
+ │ ├── pattern:
+ │ │ @ RangeNode (location: (2,3)-(2,8))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (2,3)-(2,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: -1
+ │ │ ├── right:
+ │ │ │ @ IntegerNode (location: (2,7)-(2,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (2,5)-(2,7) = ".."
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ TrueNode (location: (3,2)-(3,6))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_pattern_044.txt b/test/prism/snapshots/seattlerb/parse_pattern_044.txt
new file mode 100644
index 0000000000..951a5100b6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_pattern_044.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ CallNode (location: (1,5)-(1,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :obj
+ │ ├── message_loc: (1,5)-(1,8) = "obj"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,6))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,11))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (2,3)-(2,9))
+ │ │ │ └── name: :Object
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,9)-(2,10) = "["
+ │ │ └── closing_loc: (2,10)-(2,11) = "]"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ TrueNode (location: (3,2)-(3,6))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_pattern_051.txt b/test/prism/snapshots/seattlerb/parse_pattern_051.txt
new file mode 100644
index 0000000000..6c366e559f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_pattern_051.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ ArrayNode (location: (1,5)-(1,14))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ IntegerNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 0
+ │ │ ├── @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (1,12)-(1,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (1,5)-(1,6) = "["
+ │ └── closing_loc: (1,13)-(1,14) = "]"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,6))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,3)-(2,10))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (2,4)-(2,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 0
+ │ │ │ └── @ IntegerNode (location: (2,7)-(2,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ ImplicitRestNode (location: (2,8)-(2,9))
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,3)-(2,4) = "["
+ │ │ └── closing_loc: (2,9)-(2,10) = "]"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ TrueNode (location: (3,2)-(3,6))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_pattern_058.txt b/test/prism/snapshots/seattlerb/parse_pattern_058.txt
new file mode 100644
index 0000000000..8a4f8f8a68
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_pattern_058.txt
@@ -0,0 +1,73 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: [:a, :rest]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ HashNode (location: (1,5)-(1,11))
+ │ ├── opening_loc: (1,5)-(1,6) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,6)-(1,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 0
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (1,10)-(1,11) = "}"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,11))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,15))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,4)-(2,6))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,4)-(2,6))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,4)-(2,5) = "a"
+ │ │ │ │ ├── closing_loc: (2,5)-(2,6) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (2,4)-(2,5))
+ │ │ │ │ └── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,4)-(2,5))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest:
+ │ │ │ @ AssocSplatNode (location: (2,8)-(2,14))
+ │ │ │ ├── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,10)-(2,14))
+ │ │ │ │ ├── name: :rest
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: (2,8)-(2,10) = "**"
+ │ │ ├── opening_loc: (2,3)-(2,4) = "{"
+ │ │ └── closing_loc: (2,14)-(2,15) = "}"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ArrayNode (location: (3,2)-(3,11))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ LocalVariableReadNode (location: (3,3)-(3,4))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableReadNode (location: (3,6)-(3,10))
+ │ │ │ ├── name: :rest
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (3,2)-(3,3) = "["
+ │ │ └── closing_loc: (3,10)-(3,11) = "]"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_pattern_058_2.txt b/test/prism/snapshots/seattlerb/parse_pattern_058_2.txt
new file mode 100644
index 0000000000..3507d0f2cf
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_pattern_058_2.txt
@@ -0,0 +1,67 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ HashNode (location: (1,5)-(1,11))
+ │ ├── opening_loc: (1,5)-(1,6) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,6)-(1,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 0
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (1,10)-(1,11) = "}"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,5))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,11))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,4)-(2,6))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,4)-(2,6))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,4)-(2,5) = "a"
+ │ │ │ │ ├── closing_loc: (2,5)-(2,6) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (2,4)-(2,5))
+ │ │ │ │ └── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,4)-(2,5))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest:
+ │ │ │ @ AssocSplatNode (location: (2,8)-(2,10))
+ │ │ │ ├── value: ∅
+ │ │ │ └── operator_loc: (2,8)-(2,10) = "**"
+ │ │ ├── opening_loc: (2,3)-(2,4) = "{"
+ │ │ └── closing_loc: (2,10)-(2,11) = "}"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ArrayNode (location: (3,2)-(3,5))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (3,3)-(3,4))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (3,2)-(3,3) = "["
+ │ │ └── closing_loc: (3,4)-(3,5) = "]"
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_pattern_069.txt b/test/prism/snapshots/seattlerb/parse_pattern_069.txt
new file mode 100644
index 0000000000..09ac7653c6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_pattern_069.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ SymbolNode (location: (1,5)-(1,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,3))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,15))
+ │ │ ├── constant:
+ │ │ │ @ ConstantReadNode (location: (2,3)-(2,9))
+ │ │ │ └── name: :Object
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,10)-(2,14))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,10)-(2,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,10)-(2,11) = "b"
+ │ │ │ │ ├── closing_loc: (2,11)-(2,12) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (2,13)-(2,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: (2,9)-(2,10) = "["
+ │ │ └── closing_loc: (2,14)-(2,15) = "]"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (3,2)-(3,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_pattern_076.txt b/test/prism/snapshots/seattlerb/parse_pattern_076.txt
new file mode 100644
index 0000000000..60e71cd6fe
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_pattern_076.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(4,3))
+ ├── predicate:
+ │ @ HashNode (location: (1,5)-(1,11))
+ │ ├── opening_loc: (1,5)-(1,6) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,6)-(1,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (1,10)-(1,11) = "}"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,0)-(3,6))
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,3)-(2,16))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,4)-(2,8))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,4)-(2,6))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,4)-(2,5) = "a"
+ │ │ │ │ ├── closing_loc: (2,5)-(2,6) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (2,7)-(2,8))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest:
+ │ │ │ @ NoKeywordsParameterNode (location: (2,10)-(2,15))
+ │ │ │ ├── operator_loc: (2,10)-(2,12) = "**"
+ │ │ │ └── keyword_loc: (2,12)-(2,15) = "nil"
+ │ │ ├── opening_loc: (2,3)-(2,4) = "{"
+ │ │ └── closing_loc: (2,15)-(2,16) = "}"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,2)-(3,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ TrueNode (location: (3,2)-(3,6))
+ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/parse_until_not_canonical.txt b/test/prism/snapshots/seattlerb/parse_until_not_canonical.txt
new file mode 100644
index 0000000000..7d5ef19a05
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_until_not_canonical.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ UntilNode (location: (1,0)-(3,3))
+ ├── flags: ∅
+ ├── keyword_loc: (1,0)-(1,5) = "until"
+ ├── closing_loc: (3,0)-(3,3) = "end"
+ ├── predicate:
+ │ @ CallNode (location: (1,6)-(1,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,10)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,10)-(1,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :var
+ │ │ │ ├── message_loc: (1,10)-(1,13) = "var"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (1,13)-(1,14) = "."
+ │ │ ├── name: :nil?
+ │ │ ├── message_loc: (1,14)-(1,18) = "nil?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,6)-(1,9) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (2,2)-(2,7))
+ └── body: (length: 1)
+ └── @ StringNode (location: (2,2)-(2,7))
+ ├── flags: ∅
+ ├── opening_loc: (2,2)-(2,3) = "'"
+ ├── content_loc: (2,3)-(2,6) = "foo"
+ ├── closing_loc: (2,6)-(2,7) = "'"
+ └── unescaped: "foo"
diff --git a/test/prism/snapshots/seattlerb/parse_until_not_noncanonical.txt b/test/prism/snapshots/seattlerb/parse_until_not_noncanonical.txt
new file mode 100644
index 0000000000..7d5ef19a05
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_until_not_noncanonical.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ UntilNode (location: (1,0)-(3,3))
+ ├── flags: ∅
+ ├── keyword_loc: (1,0)-(1,5) = "until"
+ ├── closing_loc: (3,0)-(3,3) = "end"
+ ├── predicate:
+ │ @ CallNode (location: (1,6)-(1,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,10)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,10)-(1,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :var
+ │ │ │ ├── message_loc: (1,10)-(1,13) = "var"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (1,13)-(1,14) = "."
+ │ │ ├── name: :nil?
+ │ │ ├── message_loc: (1,14)-(1,18) = "nil?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,6)-(1,9) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (2,2)-(2,7))
+ └── body: (length: 1)
+ └── @ StringNode (location: (2,2)-(2,7))
+ ├── flags: ∅
+ ├── opening_loc: (2,2)-(2,3) = "'"
+ ├── content_loc: (2,3)-(2,6) = "foo"
+ ├── closing_loc: (2,6)-(2,7) = "'"
+ └── unescaped: "foo"
diff --git a/test/prism/snapshots/seattlerb/parse_while_not_canonical.txt b/test/prism/snapshots/seattlerb/parse_while_not_canonical.txt
new file mode 100644
index 0000000000..91eb88a70f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_while_not_canonical.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ WhileNode (location: (1,0)-(3,3))
+ ├── flags: ∅
+ ├── keyword_loc: (1,0)-(1,5) = "while"
+ ├── closing_loc: (3,0)-(3,3) = "end"
+ ├── predicate:
+ │ @ CallNode (location: (1,6)-(1,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,10)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,10)-(1,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :var
+ │ │ │ ├── message_loc: (1,10)-(1,13) = "var"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (1,13)-(1,14) = "."
+ │ │ ├── name: :nil?
+ │ │ ├── message_loc: (1,14)-(1,18) = "nil?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,6)-(1,9) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (2,2)-(2,7))
+ └── body: (length: 1)
+ └── @ StringNode (location: (2,2)-(2,7))
+ ├── flags: ∅
+ ├── opening_loc: (2,2)-(2,3) = "'"
+ ├── content_loc: (2,3)-(2,6) = "foo"
+ ├── closing_loc: (2,6)-(2,7) = "'"
+ └── unescaped: "foo"
diff --git a/test/prism/snapshots/seattlerb/parse_while_not_noncanonical.txt b/test/prism/snapshots/seattlerb/parse_while_not_noncanonical.txt
new file mode 100644
index 0000000000..91eb88a70f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/parse_while_not_noncanonical.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ WhileNode (location: (1,0)-(3,3))
+ ├── flags: ∅
+ ├── keyword_loc: (1,0)-(1,5) = "while"
+ ├── closing_loc: (3,0)-(3,3) = "end"
+ ├── predicate:
+ │ @ CallNode (location: (1,6)-(1,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,10)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (1,10)-(1,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :var
+ │ │ │ ├── message_loc: (1,10)-(1,13) = "var"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (1,13)-(1,14) = "."
+ │ │ ├── name: :nil?
+ │ │ ├── message_loc: (1,14)-(1,18) = "nil?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,6)-(1,9) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (2,2)-(2,7))
+ └── body: (length: 1)
+ └── @ StringNode (location: (2,2)-(2,7))
+ ├── flags: ∅
+ ├── opening_loc: (2,2)-(2,3) = "'"
+ ├── content_loc: (2,3)-(2,6) = "foo"
+ ├── closing_loc: (2,6)-(2,7) = "'"
+ └── unescaped: "foo"
diff --git a/test/prism/snapshots/seattlerb/pctW_lineno.txt b/test/prism/snapshots/seattlerb/pctW_lineno.txt
new file mode 100644
index 0000000000..58efa9c59a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/pctW_lineno.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(5,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,11))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(5,11))
+ ├── flags: ∅
+ ├── elements: (length: 7)
+ │ ├── @ StringNode (location: (1,3)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,3)-(1,7) = "a\\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\nb"
+ │ ├── @ StringNode (location: (2,0)-(2,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (2,0)-(2,1) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── @ StringNode (location: (2,2)-(2,3))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (2,2)-(2,3) = "d"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d"
+ │ ├── @ StringNode (location: (3,0)-(4,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (3,0)-(4,1) = "e\\\nf"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "e\nf"
+ │ ├── @ StringNode (location: (5,0)-(5,2))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (5,0)-(5,2) = "gy"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "gy"
+ │ ├── @ StringNode (location: (5,3)-(5,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (5,3)-(5,6) = "h\\y"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "hy"
+ │ └── @ StringNode (location: (5,7)-(5,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (5,7)-(5,10) = "i\\y"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "iy"
+ ├── opening_loc: (1,0)-(1,3) = "%W("
+ └── closing_loc: (5,10)-(5,11) = ")"
diff --git a/test/prism/snapshots/seattlerb/pct_Q_backslash_nl.txt b/test/prism/snapshots/seattlerb/pct_Q_backslash_nl.txt
new file mode 100644
index 0000000000..c8a990c672
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/pct_Q_backslash_nl.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(2,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,1))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(2,1))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,3) = "%Q{"
+ ├── content_loc: (1,3)-(2,0) = " \\\n"
+ ├── closing_loc: (2,0)-(2,1) = "}"
+ └── unescaped: " "
diff --git a/test/prism/snapshots/seattlerb/pct_nl.txt b/test/prism/snapshots/seattlerb/pct_nl.txt
new file mode 100644
index 0000000000..1009fcb51d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/pct_nl.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(3,0))
+├── locals: [:x]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,0))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(3,0))
+ ├── name: :x
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "x"
+ ├── value:
+ │ @ StringNode (location: (1,4)-(3,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,4)-(2,0) = "%\n"
+ │ ├── content_loc: (2,0)-(2,0) = ""
+ │ ├── closing_loc: (2,0)-(3,0) = "\n"
+ │ └── unescaped: ""
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt b/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt
new file mode 100644
index 0000000000..c4bc53b723
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(4,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,11))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(4,11))
+ ├── flags: ∅
+ ├── elements: (length: 5)
+ │ ├── @ StringNode (location: (1,4)-(1,5))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,4)-(1,5) = "1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "1"
+ │ ├── @ InterpolatedStringNode (location: (1,6)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── parts: (length: 1)
+ │ │ │ └── @ EmbeddedStatementsNode (location: (1,6)-(1,12))
+ │ │ │ ├── opening_loc: (1,6)-(1,8) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,8)-(1,11))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (1,8)-(1,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (1,8)-(1,11) = "<<A"
+ │ │ │ │ ├── content_loc: (2,0)-(3,0) = "2\n"
+ │ │ │ │ ├── closing_loc: (3,0)-(4,0) = "A\n"
+ │ │ │ │ └── unescaped: "2\n"
+ │ │ │ └── closing_loc: (1,11)-(1,12) = "}"
+ │ │ └── closing_loc: ∅
+ │ ├── @ StringNode (location: (1,13)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,13)-(1,14) = "3"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "3"
+ │ ├── @ StringNode (location: (4,6)-(4,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (4,6)-(4,7) = "4"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "4"
+ │ └── @ StringNode (location: (4,8)-(4,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (4,8)-(4,9) = "5"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "5"
+ ├── opening_loc: (1,0)-(1,3) = "%W("
+ └── closing_loc: (4,10)-(4,11) = ")"
diff --git a/test/prism/snapshots/seattlerb/pipe_semicolon.txt b/test/prism/snapshots/seattlerb/pipe_semicolon.txt
new file mode 100644
index 0000000000..71fb4fbed5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/pipe_semicolon.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,18))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :b
+ ├── message_loc: (1,2)-(1,3) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,4)-(1,18))
+ ├── locals: [:c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,7)-(1,14))
+ │ ├── parameters: ∅
+ │ ├── locals: (length: 1)
+ │ │ └── @ BlockLocalVariableNode (location: (1,11)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ └── name: :c
+ │ ├── opening_loc: (1,7)-(1,8) = "|"
+ │ └── closing_loc: (1,13)-(1,14) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,4)-(1,6) = "do"
+ └── closing_loc: (1,15)-(1,18) = "end"
diff --git a/test/prism/snapshots/seattlerb/pipe_space.txt b/test/prism/snapshots/seattlerb/pipe_space.txt
new file mode 100644
index 0000000000..302d225337
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/pipe_space.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,2) = "."
+ ├── name: :b
+ ├── message_loc: (1,2)-(1,3) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,4)-(1,14))
+ ├── locals: []
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,7)-(1,10))
+ │ ├── parameters: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,7)-(1,8) = "|"
+ │ └── closing_loc: (1,9)-(1,10) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,4)-(1,6) = "do"
+ └── closing_loc: (1,11)-(1,14) = "end"
diff --git a/test/prism/snapshots/seattlerb/qWords_space.txt b/test/prism/snapshots/seattlerb/qWords_space.txt
new file mode 100644
index 0000000000..95ae6d4075
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/qWords_space.txt
@@ -0,0 +1,10 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (1,0)-(1,3) = "%W("
+ └── closing_loc: (1,4)-(1,5) = ")"
diff --git a/test/prism/snapshots/seattlerb/qsymbols.txt b/test/prism/snapshots/seattlerb/qsymbols.txt
new file mode 100644
index 0000000000..8ba68638c5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/qsymbols.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── elements: (length: 3)
+ │ ├── @ SymbolNode (location: (1,3)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,3)-(1,4) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── @ SymbolNode (location: (1,5)-(1,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,5)-(1,6) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ └── @ SymbolNode (location: (1,7)-(1,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (1,7)-(1,8) = "c"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "c"
+ ├── opening_loc: (1,0)-(1,3) = "%I("
+ └── closing_loc: (1,8)-(1,9) = ")"
diff --git a/test/prism/snapshots/seattlerb/qsymbols_empty.txt b/test/prism/snapshots/seattlerb/qsymbols_empty.txt
new file mode 100644
index 0000000000..54aa3f77d7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/qsymbols_empty.txt
@@ -0,0 +1,10 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (1,0)-(1,3) = "%I("
+ └── closing_loc: (1,3)-(1,4) = ")"
diff --git a/test/prism/snapshots/seattlerb/qsymbols_empty_space.txt b/test/prism/snapshots/seattlerb/qsymbols_empty_space.txt
new file mode 100644
index 0000000000..624b922ce6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/qsymbols_empty_space.txt
@@ -0,0 +1,10 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (1,0)-(1,3) = "%I("
+ └── closing_loc: (1,4)-(1,5) = ")"
diff --git a/test/prism/snapshots/seattlerb/qsymbols_interp.txt b/test/prism/snapshots/seattlerb/qsymbols_interp.txt
new file mode 100644
index 0000000000..97bc6754ff
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/qsymbols_interp.txt
@@ -0,0 +1,57 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,15))
+ ├── flags: ∅
+ ├── elements: (length: 3)
+ │ ├── @ SymbolNode (location: (1,3)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,3)-(1,4) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── @ InterpolatedSymbolNode (location: (1,5)-(1,12))
+ │ │ ├── opening_loc: ∅
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (1,5)-(1,6) = "b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ └── @ EmbeddedStatementsNode (location: (1,6)-(1,12))
+ │ │ │ ├── opening_loc: (1,6)-(1,8) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,8)-(1,11))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,8)-(1,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :+
+ │ │ │ │ ├── message_loc: (1,9)-(1,10) = "+"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (1,11)-(1,12) = "}"
+ │ │ └── closing_loc: ∅
+ │ └── @ SymbolNode (location: (1,13)-(1,14))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (1,13)-(1,14) = "c"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "c"
+ ├── opening_loc: (1,0)-(1,3) = "%I("
+ └── closing_loc: (1,14)-(1,15) = ")"
diff --git a/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt b/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt
new file mode 100644
index 0000000000..64caf51bcb
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/quoted_symbol_hash_arg.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :puts
+ ├── message_loc: (1,0)-(1,4) = "puts"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,12))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,5)-(1,12))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,5)-(1,12))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,5)-(1,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,5)-(1,6) = "'"
+ │ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ │ ├── closing_loc: (1,7)-(1,9) = "':"
+ │ │ └── unescaped: "a"
+ │ ├── value:
+ │ │ @ HashNode (location: (1,10)-(1,12))
+ │ │ ├── opening_loc: (1,10)-(1,11) = "{"
+ │ │ ├── elements: (length: 0)
+ │ │ └── closing_loc: (1,11)-(1,12) = "}"
+ │ └── operator_loc: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/quoted_symbol_keys.txt b/test/prism/snapshots/seattlerb/quoted_symbol_keys.txt
new file mode 100644
index 0000000000..96e6af51a4
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/quoted_symbol_keys.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,0)-(1,11))
+ ├── opening_loc: (1,0)-(1,1) = "{"
+ ├── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,9))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,2)-(1,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,2)-(1,3) = "'"
+ │ │ ├── value_loc: (1,3)-(1,4) = "a"
+ │ │ ├── closing_loc: (1,4)-(1,6) = "':"
+ │ │ └── unescaped: "a"
+ │ ├── value:
+ │ │ @ SymbolNode (location: (1,7)-(1,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,7)-(1,8) = ":"
+ │ │ ├── value_loc: (1,8)-(1,9) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ └── operator_loc: ∅
+ └── closing_loc: (1,10)-(1,11) = "}"
diff --git a/test/prism/snapshots/seattlerb/qw_escape.txt b/test/prism/snapshots/seattlerb/qw_escape.txt
new file mode 100644
index 0000000000..d92c1da7a6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/qw_escape.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,7))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,3) = "%q("
+ ├── content_loc: (1,3)-(1,6) = "\u0001\\'"
+ ├── closing_loc: (1,6)-(1,7) = ")"
+ └── unescaped: "\u0001\\'"
diff --git a/test/prism/snapshots/seattlerb/qw_escape_term.txt b/test/prism/snapshots/seattlerb/qw_escape_term.txt
new file mode 100644
index 0000000000..e935b7eb68
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/qw_escape_term.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,26))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,26))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,26))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,3) = "%q|"
+ ├── content_loc: (1,3)-(1,25) = "blah blah \\| blah blah"
+ ├── closing_loc: (1,25)-(1,26) = "|"
+ └── unescaped: "blah blah | blah blah"
diff --git a/test/prism/snapshots/seattlerb/qwords_empty.txt b/test/prism/snapshots/seattlerb/qwords_empty.txt
new file mode 100644
index 0000000000..f9915c97c9
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/qwords_empty.txt
@@ -0,0 +1,10 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (1,0)-(1,3) = "%w("
+ └── closing_loc: (1,3)-(1,4) = ")"
diff --git a/test/prism/snapshots/seattlerb/read_escape_unicode_curlies.txt b/test/prism/snapshots/seattlerb/read_escape_unicode_curlies.txt
new file mode 100644
index 0000000000..3ea5604b69
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/read_escape_unicode_curlies.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,9))
+ ├── flags: forced_utf8_encoding
+ ├── opening_loc: (1,0)-(1,1) = "?"
+ ├── content_loc: (1,1)-(1,9) = "\\u{00a0}"
+ ├── closing_loc: ∅
+ └── unescaped: " "
diff --git a/test/prism/snapshots/seattlerb/read_escape_unicode_h4.txt b/test/prism/snapshots/seattlerb/read_escape_unicode_h4.txt
new file mode 100644
index 0000000000..1eba1396fd
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/read_escape_unicode_h4.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,7))
+ ├── flags: forced_utf8_encoding
+ ├── opening_loc: (1,0)-(1,1) = "?"
+ ├── content_loc: (1,1)-(1,7) = "\\u00a0"
+ ├── closing_loc: ∅
+ └── unescaped: " "
diff --git a/test/prism/snapshots/seattlerb/regexp.txt b/test/prism/snapshots/seattlerb/regexp.txt
new file mode 100644
index 0000000000..06cf99264e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/regexp.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(9,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,13))
+ └── body: (length: 5)
+ ├── @ RegularExpressionNode (location: (1,0)-(1,5))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,0)-(1,1) = "/"
+ │ ├── content_loc: (1,1)-(1,4) = "wtf"
+ │ ├── closing_loc: (1,4)-(1,5) = "/"
+ │ └── unescaped: "wtf"
+ ├── @ RegularExpressionNode (location: (3,0)-(3,6))
+ │ ├── flags: multi_line, forced_us_ascii_encoding
+ │ ├── opening_loc: (3,0)-(3,1) = "/"
+ │ ├── content_loc: (3,1)-(3,4) = "wtf"
+ │ ├── closing_loc: (3,4)-(3,6) = "/m"
+ │ └── unescaped: "wtf"
+ ├── @ RegularExpressionNode (location: (5,0)-(5,6))
+ │ ├── flags: ascii_8bit, forced_us_ascii_encoding
+ │ ├── opening_loc: (5,0)-(5,1) = "/"
+ │ ├── content_loc: (5,1)-(5,4) = "wtf"
+ │ ├── closing_loc: (5,4)-(5,6) = "/n"
+ │ └── unescaped: "wtf"
+ ├── @ RegularExpressionNode (location: (7,0)-(7,7))
+ │ ├── flags: multi_line, ascii_8bit, forced_us_ascii_encoding
+ │ ├── opening_loc: (7,0)-(7,1) = "/"
+ │ ├── content_loc: (7,1)-(7,4) = "wtf"
+ │ ├── closing_loc: (7,4)-(7,7) = "/nm"
+ │ └── unescaped: "wtf"
+ └── @ RegularExpressionNode (location: (9,0)-(9,13))
+ ├── flags: multi_line, ascii_8bit, forced_us_ascii_encoding
+ ├── opening_loc: (9,0)-(9,1) = "/"
+ ├── content_loc: (9,1)-(9,4) = "wtf"
+ ├── closing_loc: (9,4)-(9,13) = "/nmnmnmnm"
+ └── unescaped: "wtf"
diff --git a/test/prism/snapshots/seattlerb/regexp_esc_C_slash.txt b/test/prism/snapshots/seattlerb/regexp_esc_C_slash.txt
new file mode 100644
index 0000000000..4dbedc44ca
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/regexp_esc_C_slash.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ RegularExpressionNode (location: (1,0)-(1,7))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,1) = "/"
+ ├── content_loc: (1,1)-(1,6) = "\\cC\\d"
+ ├── closing_loc: (1,6)-(1,7) = "/"
+ └── unescaped: "\\x03\\d"
diff --git a/test/prism/snapshots/seattlerb/regexp_esc_u.txt b/test/prism/snapshots/seattlerb/regexp_esc_u.txt
new file mode 100644
index 0000000000..bca451eb3b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/regexp_esc_u.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ RegularExpressionNode (location: (1,0)-(1,17))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,1) = "/"
+ ├── content_loc: (1,1)-(1,16) = "[\\u0021-\\u0027]"
+ ├── closing_loc: (1,16)-(1,17) = "/"
+ └── unescaped: "[\\u0021-\\u0027]"
diff --git a/test/prism/snapshots/seattlerb/regexp_escape_extended.txt b/test/prism/snapshots/seattlerb/regexp_escape_extended.txt
new file mode 100644
index 0000000000..6568d2bd92
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/regexp_escape_extended.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ RegularExpressionNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "/"
+ ├── content_loc: (1,1)-(1,5) = "\\“"
+ ├── closing_loc: (1,5)-(1,6) = "/"
+ └── unescaped: "“"
diff --git a/test/prism/snapshots/seattlerb/regexp_unicode_curlies.txt b/test/prism/snapshots/seattlerb/regexp_unicode_curlies.txt
new file mode 100644
index 0000000000..487161b4d0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/regexp_unicode_curlies.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(3,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,8))
+ └── body: (length: 2)
+ ├── @ RegularExpressionNode (location: (1,0)-(1,15))
+ │ ├── flags: forced_utf8_encoding
+ │ ├── opening_loc: (1,0)-(1,1) = "/"
+ │ ├── content_loc: (1,1)-(1,14) = "\\u{c0de babe}"
+ │ ├── closing_loc: (1,14)-(1,15) = "/"
+ │ └── unescaped: "\\u{c0de babe}"
+ └── @ RegularExpressionNode (location: (3,0)-(3,8))
+ ├── flags: forced_utf8_encoding
+ ├── opening_loc: (3,0)-(3,1) = "/"
+ ├── content_loc: (3,1)-(3,7) = "\\u{df}"
+ ├── closing_loc: (3,7)-(3,8) = "/"
+ └── unescaped: "\\u{df}"
diff --git a/test/prism/snapshots/seattlerb/required_kwarg_no_value.txt b/test/prism/snapshots/seattlerb/required_kwarg_no_value.txt
new file mode 100644
index 0000000000..54595ac5cb
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/required_kwarg_no_value.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(2,3))
+ ├── name: :x
+ ├── name_loc: (1,4)-(1,5) = "x"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,12))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 2)
+ │ │ ├── @ RequiredKeywordParameterNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ └── name_loc: (1,6)-(1,8) = "a:"
+ │ │ └── @ RequiredKeywordParameterNode (location: (1,10)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ └── name_loc: (1,10)-(1,12) = "b:"
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:a, :b]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (2,0)-(2,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/rescue_do_end_ensure_result.txt b/test/prism/snapshots/seattlerb/rescue_do_end_ensure_result.txt
new file mode 100644
index 0000000000..21f8bb08a5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/rescue_do_end_ensure_result.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(5,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(5,8))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(5,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :proc
+ │ ├── message_loc: (1,0)-(1,4) = "proc"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,5)-(5,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (1,5)-(5,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (2,2)-(2,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (2,2)-(2,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (2,2)-(2,3) = ":"
+ │ │ │ ├── value_loc: (2,3)-(2,8) = "begin"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "begin"
+ │ │ ├── rescue_clause: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (3,0)-(5,3))
+ │ │ │ ├── ensure_keyword_loc: (3,0)-(3,6) = "ensure"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (4,2)-(4,9))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (4,2)-(4,9))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (4,2)-(4,3) = ":"
+ │ │ │ │ ├── value_loc: (4,3)-(4,9) = "ensure"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "ensure"
+ │ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ ├── opening_loc: (1,5)-(1,7) = "do"
+ │ └── closing_loc: (5,0)-(5,3) = "end"
+ ├── call_operator_loc: (5,3)-(5,4) = "."
+ ├── name: :call
+ ├── message_loc: (5,4)-(5,8) = "call"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/rescue_do_end_no_raise.txt b/test/prism/snapshots/seattlerb/rescue_do_end_no_raise.txt
new file mode 100644
index 0000000000..aa4e85c171
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/rescue_do_end_no_raise.txt
@@ -0,0 +1,75 @@
+@ ProgramNode (location: (1,0)-(9,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(9,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :tap
+ ├── message_loc: (1,0)-(1,3) = "tap"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,4)-(9,3))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ BeginNode (location: (1,4)-(9,3))
+ │ ├── begin_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,2)-(2,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (2,2)-(2,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (2,2)-(2,3) = ":"
+ │ │ ├── value_loc: (2,3)-(2,8) = "begin"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "begin"
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (3,0)-(4,9))
+ │ │ ├── keyword_loc: (3,0)-(3,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (4,2)-(4,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (4,2)-(4,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (4,2)-(4,3) = ":"
+ │ │ │ ├── value_loc: (4,3)-(4,9) = "rescue"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "rescue"
+ │ │ └── consequent: ∅
+ │ ├── else_clause:
+ │ │ @ ElseNode (location: (5,0)-(7,6))
+ │ │ ├── else_keyword_loc: (5,0)-(5,4) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (6,2)-(6,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (6,2)-(6,7))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (6,2)-(6,3) = ":"
+ │ │ │ ├── value_loc: (6,3)-(6,7) = "else"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "else"
+ │ │ └── end_keyword_loc: (7,0)-(7,6) = "ensure"
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (7,0)-(9,3))
+ │ │ ├── ensure_keyword_loc: (7,0)-(7,6) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (8,2)-(8,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (8,2)-(8,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (8,2)-(8,3) = ":"
+ │ │ │ ├── value_loc: (8,3)-(8,9) = "ensure"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "ensure"
+ │ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ ├── opening_loc: (1,4)-(1,6) = "do"
+ └── closing_loc: (9,0)-(9,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/rescue_do_end_raised.txt b/test/prism/snapshots/seattlerb/rescue_do_end_raised.txt
new file mode 100644
index 0000000000..06f67fae69
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/rescue_do_end_raised.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(5,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(5,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :tap
+ ├── message_loc: (1,0)-(1,3) = "tap"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,4)-(5,3))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ BeginNode (location: (1,4)-(5,3))
+ │ ├── begin_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,2)-(2,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,2)-(2,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (2,2)-(2,7) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (3,0)-(5,3))
+ │ │ ├── ensure_keyword_loc: (3,0)-(3,6) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (4,2)-(4,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (4,2)-(4,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (4,2)-(4,3) = ":"
+ │ │ │ ├── value_loc: (4,3)-(4,9) = "ensure"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "ensure"
+ │ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── opening_loc: (1,4)-(1,6) = "do"
+ └── closing_loc: (5,0)-(5,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/rescue_do_end_rescued.txt b/test/prism/snapshots/seattlerb/rescue_do_end_rescued.txt
new file mode 100644
index 0000000000..b4576c3bb2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/rescue_do_end_rescued.txt
@@ -0,0 +1,79 @@
+@ ProgramNode (location: (1,0)-(9,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(9,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :tap
+ ├── message_loc: (1,0)-(1,3) = "tap"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,4)-(9,3))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ BeginNode (location: (1,4)-(9,3))
+ │ ├── begin_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,2)-(2,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,2)-(2,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (2,2)-(2,7) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (3,0)-(4,9))
+ │ │ ├── keyword_loc: (3,0)-(3,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (4,2)-(4,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (4,2)-(4,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (4,2)-(4,3) = ":"
+ │ │ │ ├── value_loc: (4,3)-(4,9) = "rescue"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "rescue"
+ │ │ └── consequent: ∅
+ │ ├── else_clause:
+ │ │ @ ElseNode (location: (5,0)-(7,6))
+ │ │ ├── else_keyword_loc: (5,0)-(5,4) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (6,2)-(6,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (6,2)-(6,7))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (6,2)-(6,3) = ":"
+ │ │ │ ├── value_loc: (6,3)-(6,7) = "else"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "else"
+ │ │ └── end_keyword_loc: (7,0)-(7,6) = "ensure"
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (7,0)-(9,3))
+ │ │ ├── ensure_keyword_loc: (7,0)-(7,6) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (8,2)-(8,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (8,2)-(8,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (8,2)-(8,3) = ":"
+ │ │ │ ├── value_loc: (8,3)-(8,9) = "ensure"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "ensure"
+ │ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ ├── opening_loc: (1,4)-(1,6) = "do"
+ └── closing_loc: (9,0)-(9,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/rescue_in_block.txt b/test/prism/snapshots/seattlerb/rescue_in_block.txt
new file mode 100644
index 0000000000..daac2b6776
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/rescue_in_block.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(4,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :blah
+ ├── message_loc: (1,0)-(1,4) = "blah"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,5)-(4,3))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ BeginNode (location: (1,5)-(4,3))
+ │ ├── begin_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (2,0)-(3,7))
+ │ │ ├── keyword_loc: (2,0)-(2,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,2)-(3,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,2)-(3,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :stuff
+ │ │ │ ├── message_loc: (3,2)-(3,7) = "stuff"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (4,0)-(4,3) = "end"
+ ├── opening_loc: (1,5)-(1,7) = "do"
+ └── closing_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/seattlerb/rescue_parens.txt b/test/prism/snapshots/seattlerb/rescue_parens.txt
new file mode 100644
index 0000000000..d086095e7a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/rescue_parens.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,14))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,2)-(1,14))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,3)-(1,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (1,3)-(1,13))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,3)-(1,4) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (1,5)-(1,11) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ CallNode (location: (1,12)-(1,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (1,12)-(1,13) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,13)-(1,14) = ")"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/return_call_assocs.txt b/test/prism/snapshots/seattlerb/return_call_assocs.txt
new file mode 100644
index 0000000000..69aae7b205
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/return_call_assocs.txt
@@ -0,0 +1,212 @@
+@ ProgramNode (location: (1,0)-(11,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,14))
+ └── body: (length: 6)
+ ├── @ ReturnNode (location: (1,0)-(1,17))
+ │ ├── keyword_loc: (1,0)-(1,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (1,7)-(1,17))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,7)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ KeywordHashNode (location: (1,10)-(1,17))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,10)-(1,17))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,10)-(1,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,10)-(1,11) = ":"
+ │ │ ├── value_loc: (1,11)-(1,12) = "z"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "z"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,16)-(1,17))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,13)-(1,15) = "=>"
+ ├── @ ReturnNode (location: (3,0)-(3,26))
+ │ ├── keyword_loc: (3,0)-(3,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (3,7)-(3,26))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (3,7)-(3,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ KeywordHashNode (location: (3,10)-(3,26))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 2)
+ │ ├── @ AssocNode (location: (3,10)-(3,17))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (3,10)-(3,12))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,10)-(3,11) = ":"
+ │ │ │ ├── value_loc: (3,11)-(3,12) = "z"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "z"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,16)-(3,17))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (3,13)-(3,15) = "=>"
+ │ └── @ AssocNode (location: (3,19)-(3,26))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (3,19)-(3,21))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,19)-(3,20) = ":"
+ │ │ ├── value_loc: (3,20)-(3,21) = "w"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "w"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,25)-(3,26))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (3,22)-(3,24) = "=>"
+ ├── @ ReturnNode (location: (5,0)-(5,14))
+ │ ├── keyword_loc: (5,0)-(5,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (5,7)-(5,14))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (5,7)-(5,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :y
+ │ ├── message_loc: (5,7)-(5,8) = "y"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,9)-(5,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (5,9)-(5,14))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (5,9)-(5,14))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (5,9)-(5,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (5,9)-(5,10) = ":"
+ │ │ │ ├── value_loc: (5,10)-(5,11) = "z"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "z"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (5,13)-(5,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (5,11)-(5,13) = "=>"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ReturnNode (location: (7,0)-(7,12))
+ │ ├── keyword_loc: (7,0)-(7,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (7,7)-(7,12))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (7,7)-(7,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :y
+ │ ├── message_loc: (7,7)-(7,8) = "y"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,9)-(7,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (7,9)-(7,12))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (7,9)-(7,12))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (7,9)-(7,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (7,9)-(7,10) = "z"
+ │ │ │ ├── closing_loc: (7,10)-(7,11) = ":"
+ │ │ │ └── unescaped: "z"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (7,11)-(7,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ReturnNode (location: (9,0)-(9,13))
+ │ ├── keyword_loc: (9,0)-(9,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (9,7)-(9,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (9,7)-(9,13))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :y
+ │ ├── message_loc: (9,7)-(9,8) = "y"
+ │ ├── opening_loc: (9,8)-(9,9) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,9)-(9,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (9,9)-(9,12))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (9,9)-(9,12))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (9,9)-(9,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (9,9)-(9,10) = "z"
+ │ │ │ ├── closing_loc: (9,10)-(9,11) = ":"
+ │ │ │ └── unescaped: "z"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (9,11)-(9,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (9,12)-(9,13) = ")"
+ │ └── block: ∅
+ └── @ ReturnNode (location: (11,0)-(11,14))
+ ├── keyword_loc: (11,0)-(11,6) = "return"
+ └── arguments:
+ @ ArgumentsNode (location: (11,7)-(11,14))
+ ├── flags: ∅
+ └── arguments: (length: 1)
+ └── @ CallNode (location: (11,7)-(11,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :y
+ ├── message_loc: (11,7)-(11,8) = "y"
+ ├── opening_loc: (11,8)-(11,9) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (11,9)-(11,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (11,9)-(11,13))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (11,9)-(11,13))
+ │ ├── key:
+ │ │ @ CallNode (location: (11,9)-(11,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :z
+ │ │ ├── message_loc: (11,9)-(11,10) = "z"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── value:
+ │ │ @ IntegerNode (location: (11,12)-(11,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (11,10)-(11,12) = "=>"
+ ├── closing_loc: (11,13)-(11,14) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/rhs_asgn.txt b/test/prism/snapshots/seattlerb/rhs_asgn.txt
new file mode 100644
index 0000000000..9ee187218b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/rhs_asgn.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: [:n]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ MatchRequiredNode (location: (1,0)-(1,7))
+ ├── value:
+ │ @ IntegerNode (location: (1,0)-(1,2))
+ │ ├── flags: decimal
+ │ └── value: 42
+ ├── pattern:
+ │ @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ ├── name: :n
+ │ └── depth: 0
+ └── operator_loc: (1,3)-(1,5) = "=>"
diff --git a/test/prism/snapshots/seattlerb/ruby21_numbers.txt b/test/prism/snapshots/seattlerb/ruby21_numbers.txt
new file mode 100644
index 0000000000..34a3452d1b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/ruby21_numbers.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,13))
+ ├── flags: ∅
+ ├── elements: (length: 3)
+ │ ├── @ ImaginaryNode (location: (1,1)-(1,3))
+ │ │ └── numeric:
+ │ │ @ IntegerNode (location: (1,1)-(1,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── @ RationalNode (location: (1,5)-(1,7))
+ │ │ └── numeric:
+ │ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── @ ImaginaryNode (location: (1,9)-(1,12))
+ │ └── numeric:
+ │ @ RationalNode (location: (1,9)-(1,11))
+ │ └── numeric:
+ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── opening_loc: (1,0)-(1,1) = "["
+ └── closing_loc: (1,12)-(1,13) = "]"
diff --git a/test/prism/snapshots/seattlerb/safe_attrasgn.txt b/test/prism/snapshots/seattlerb/safe_attrasgn.txt
new file mode 100644
index 0000000000..3cec95ae7c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_attrasgn.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: safe_navigation, attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── name: :b=
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,7)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_attrasgn_constant.txt b/test/prism/snapshots/seattlerb/safe_attrasgn_constant.txt
new file mode 100644
index 0000000000..baea063186
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_attrasgn_constant.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: safe_navigation, attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── name: :B=
+ ├── message_loc: (1,3)-(1,4) = "B"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,7)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_call.txt b/test/prism/snapshots/seattlerb/safe_call.txt
new file mode 100644
index 0000000000..7b402d9ef2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_call.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── name: :b
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_call_after_newline.txt b/test/prism/snapshots/seattlerb/safe_call_after_newline.txt
new file mode 100644
index 0000000000..0a69cbc9e5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_call_after_newline.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(2,3))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (2,0)-(2,2) = "&."
+ ├── name: :b
+ ├── message_loc: (2,2)-(2,3) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_call_dot_parens.txt b/test/prism/snapshots/seattlerb/safe_call_dot_parens.txt
new file mode 100644
index 0000000000..1d6ba9e49e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_call_dot_parens.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,5))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── name: :call
+ ├── message_loc: ∅
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments: ∅
+ ├── closing_loc: (1,4)-(1,5) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_call_newline.txt b/test/prism/snapshots/seattlerb/safe_call_newline.txt
new file mode 100644
index 0000000000..7b402d9ef2
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_call_newline.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── name: :b
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_call_operator.txt b/test/prism/snapshots/seattlerb/safe_call_operator.txt
new file mode 100644
index 0000000000..d1f9b1ea9e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_call_operator.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── name: :>
+ ├── message_loc: (1,3)-(1,4) = ">"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt b/test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt
new file mode 100644
index 0000000000..34790ebb33
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: [:c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,8))
+ ├── name: :c
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "c"
+ ├── value:
+ │ @ CallNode (location: (1,4)-(1,8))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,4)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,4)-(1,5) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,5)-(1,7) = "&."
+ │ ├── name: :b
+ │ ├── message_loc: (1,7)-(1,8) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/seattlerb/safe_calls.txt b/test/prism/snapshots/seattlerb/safe_calls.txt
new file mode 100644
index 0000000000..54e591d9c0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_calls.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,10))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,4))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ │ ├── name: :b
+ │ ├── message_loc: (1,3)-(1,4) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,4)-(1,6) = "&."
+ ├── name: :c
+ ├── message_loc: (1,6)-(1,7) = "c"
+ ├── opening_loc: (1,7)-(1,8) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,8)-(1,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,8)-(1,9))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (1,9)-(1,10) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_op_asgn.txt b/test/prism/snapshots/seattlerb/safe_op_asgn.txt
new file mode 100644
index 0000000000..7a9fd2b7f7
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_op_asgn.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallOperatorWriteNode (location: (1,0)-(1,11))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── read_name: :b
+ ├── write_name: :b=
+ ├── operator: :+
+ ├── operator_loc: (1,5)-(1,7) = "+="
+ └── value:
+ @ CallNode (location: (1,8)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (1,8)-(1,9) = "x"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/safe_op_asgn2.txt b/test/prism/snapshots/seattlerb/safe_op_asgn2.txt
new file mode 100644
index 0000000000..bdb0e06156
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/safe_op_asgn2.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(2,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,1))
+ └── body: (length: 1)
+ └── @ CallOrWriteNode (location: (1,0)-(2,1))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── read_name: :b
+ ├── write_name: :b=
+ ├── operator_loc: (1,5)-(1,8) = "||="
+ └── value:
+ @ CallNode (location: (2,0)-(2,1))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (2,0)-(2,1) = "x"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/slashy_newlines_within_string.txt b/test/prism/snapshots/seattlerb/slashy_newlines_within_string.txt
new file mode 100644
index 0000000000..f9be33ffdd
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/slashy_newlines_within_string.txt
@@ -0,0 +1,57 @@
+@ ProgramNode (location: (1,0)-(6,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,5))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(4,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :puts
+ │ ├── message_loc: (1,0)-(1,4) = "puts"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,5)-(4,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,5)-(4,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,5)-(1,6) = "\""
+ │ │ ├── content_loc: (1,6)-(4,7) = "hello\\\n my\\\n dear\\\n friend"
+ │ │ ├── closing_loc: (4,7)-(4,8) = "\""
+ │ │ └── unescaped: "hello my dear friend"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (6,0)-(6,5))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (6,0)-(6,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (6,0)-(6,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :+
+ ├── message_loc: (6,2)-(6,3) = "+"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (6,4)-(6,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (6,4)-(6,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (6,4)-(6,5) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/stabby_arg_no_paren.txt b/test/prism/snapshots/seattlerb/stabby_arg_no_paren.txt
new file mode 100644
index 0000000000..e665565d38
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/stabby_arg_no_paren.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,5))
+ ├── locals: [:a]
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,3)-(1,4) = "{"
+ ├── closing_loc: (1,4)-(1,5) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,2)-(1,3))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,2)-(1,3))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,2)-(1,3))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ └── body: ∅
diff --git a/test/prism/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt b/test/prism/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt
new file mode 100644
index 0000000000..0b0000ef33
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,23))
+ ├── locals: [:b, :c, :d, :e, :f]
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,21)-(1,22) = "{"
+ ├── closing_loc: (1,22)-(1,23) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,2)-(1,21))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,3)-(1,20))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,6)-(1,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── name_loc: (1,6)-(1,7) = "c"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (1,11)-(1,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── name_loc: (1,12)-(1,13) = "d"
+ │ │ │ └── operator_loc: (1,11)-(1,12) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,15)-(1,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :e
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,18)-(1,20))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :f
+ │ │ ├── name_loc: (1,19)-(1,20) = "f"
+ │ │ └── operator_loc: (1,18)-(1,19) = "&"
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,20)-(1,21) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/seattlerb/stabby_block_iter_call.txt b/test/prism/snapshots/seattlerb/stabby_block_iter_call.txt
new file mode 100644
index 0000000000..e51c7d97ed
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/stabby_block_iter_call.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(4,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (1,0)-(1,1) = "x"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(4,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LambdaNode (location: (1,2)-(4,3))
+ │ ├── locals: []
+ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ ├── opening_loc: (1,8)-(1,10) = "do"
+ │ ├── closing_loc: (4,0)-(4,3) = "end"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,5)-(1,7))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ │ └── closing_loc: (1,6)-(1,7) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (2,0)-(3,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,0)-(3,3))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (2,0)-(2,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (2,0)-(2,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (2,1)-(2,2) = "."
+ │ ├── name: :b
+ │ ├── message_loc: (2,2)-(2,3) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (2,4)-(3,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (2,4)-(2,6) = "do"
+ │ └── closing_loc: (3,0)-(3,3) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt b/test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt
new file mode 100644
index 0000000000..d7a268a5d5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(4,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (1,0)-(1,1) = "x"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(4,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LambdaNode (location: (1,2)-(4,3))
+ │ ├── locals: []
+ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ ├── opening_loc: (1,8)-(1,10) = "do"
+ │ ├── closing_loc: (4,0)-(4,3) = "end"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,5)-(1,7))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ │ └── closing_loc: (1,6)-(1,7) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (2,0)-(3,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,0)-(3,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (2,0)-(2,1) = "a"
+ │ ├── opening_loc: (2,1)-(2,2) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (2,2)-(2,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (2,2)-(2,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: (2,3)-(2,4) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (2,5)-(3,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (2,5)-(2,7) = "do"
+ │ └── closing_loc: (3,0)-(3,3) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/stabby_block_kw.txt b/test/prism/snapshots/seattlerb/stabby_block_kw.txt
new file mode 100644
index 0000000000..7addbb8b28
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/stabby_block_kw.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,13))
+ ├── locals: [:k]
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,10)-(1,11) = "{"
+ ├── closing_loc: (1,12)-(1,13) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,3)-(1,9))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,4)-(1,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (1,4)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :k
+ │ │ │ ├── name_loc: (1,4)-(1,6) = "k:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ └── closing_loc: (1,8)-(1,9) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/seattlerb/stabby_block_kw__required.txt b/test/prism/snapshots/seattlerb/stabby_block_kw__required.txt
new file mode 100644
index 0000000000..b5040d91db
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/stabby_block_kw__required.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,11))
+ ├── locals: [:k]
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,8)-(1,9) = "{"
+ ├── closing_loc: (1,10)-(1,11) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,3)-(1,7))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,4)-(1,6))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (1,4)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :k
+ │ │ │ └── name_loc: (1,4)-(1,6) = "k:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ └── closing_loc: (1,6)-(1,7) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/seattlerb/stabby_proc_scope.txt b/test/prism/snapshots/seattlerb/stabby_proc_scope.txt
new file mode 100644
index 0000000000..898f823f24
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/stabby_proc_scope.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,11))
+ ├── locals: [:a, :b]
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,9)-(1,10) = "{"
+ ├── closing_loc: (1,10)-(1,11) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,2)-(1,8))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,3)-(1,4))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 1)
+ │ │ └── @ BlockLocalVariableNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── name: :b
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,7)-(1,8) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/seattlerb/str_backslashes.txt b/test/prism/snapshots/seattlerb/str_backslashes.txt
new file mode 100644
index 0000000000..ec41a89c38
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_backslashes.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,204))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,204))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,204))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :x
+ ├── message_loc: (1,0)-(1,1) = "x"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,204))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ StringNode (location: (1,2)-(1,204))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "'"
+ │ ├── content_loc: (1,3)-(1,203) = "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ │ ├── closing_loc: (1,203)-(1,204) = "'"
+ │ └── unescaped: "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/str_double_double_escaped_newline.txt b/test/prism/snapshots/seattlerb/str_double_double_escaped_newline.txt
new file mode 100644
index 0000000000..620b43f631
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_double_double_escaped_newline.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,2)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ │ ├── content_loc: (1,3)-(1,6) = "\\\\n"
+ │ │ ├── closing_loc: (1,6)-(1,7) = "\""
+ │ │ └── unescaped: "\\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (1,8)-(1,9))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (1,8)-(1,9) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/str_double_escaped_newline.txt b/test/prism/snapshots/seattlerb/str_double_escaped_newline.txt
new file mode 100644
index 0000000000..2aee91b75c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_double_escaped_newline.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,2)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ │ ├── content_loc: (1,3)-(1,5) = "\\n"
+ │ │ ├── closing_loc: (1,5)-(1,6) = "\""
+ │ │ └── unescaped: "\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (1,7)-(1,8))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (1,7)-(1,8) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/str_double_newline.txt b/test/prism/snapshots/seattlerb/str_double_newline.txt
new file mode 100644
index 0000000000..eb249cde8a
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_double_newline.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(2,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(2,1))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,2)-(2,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ │ ├── content_loc: (1,3)-(2,0) = "\n"
+ │ │ ├── closing_loc: (2,0)-(2,1) = "\""
+ │ │ └── unescaped: "\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (2,2)-(2,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (2,2)-(2,3) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/str_evstr.txt b/test/prism/snapshots/seattlerb/str_evstr.txt
new file mode 100644
index 0000000000..7010ad0a68
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_evstr.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (1,1)-(1,3))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,1)-(1,3) = "a "
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a "
+ │ └── @ EmbeddedStatementsNode (location: (1,3)-(1,7))
+ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,5)-(1,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,5)-(1,6) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── closing_loc: (1,6)-(1,7) = "}"
+ └── closing_loc: (1,7)-(1,8) = "\""
diff --git a/test/prism/snapshots/seattlerb/str_evstr_escape.txt b/test/prism/snapshots/seattlerb/str_evstr_escape.txt
new file mode 100644
index 0000000000..3867574c7c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_evstr_escape.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,16))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (1,1)-(1,3))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,1)-(1,3) = "a "
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a "
+ │ ├── @ EmbeddedStatementsNode (location: (1,3)-(1,7))
+ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,5)-(1,6) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,6)-(1,7) = "}"
+ │ └── @ StringNode (location: (1,7)-(1,15))
+ │ ├── flags: forced_utf8_encoding, frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,7)-(1,15) = "\\302\\275"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "½"
+ └── closing_loc: (1,15)-(1,16) = "\""
diff --git a/test/prism/snapshots/seattlerb/str_heredoc_interp.txt b/test/prism/snapshots/seattlerb/str_heredoc_interp.txt
new file mode 100644
index 0000000000..bb7bbba259
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_heredoc_interp.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,4) = "<<\"\""
+ ├── parts: (length: 2)
+ │ ├── @ EmbeddedStatementsNode (location: (2,0)-(2,4))
+ │ │ ├── opening_loc: (2,0)-(2,2) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (2,2)-(2,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,2)-(2,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :x
+ │ │ │ ├── message_loc: (2,2)-(2,3) = "x"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (2,3)-(2,4) = "}"
+ │ └── @ StringNode (location: (2,4)-(4,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (2,4)-(4,0) = "\nblah2\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\nblah2\n"
+ └── closing_loc: (4,0)-(5,0) = "\n"
diff --git a/test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt b/test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt
new file mode 100644
index 0000000000..5a2f435e0e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt
@@ -0,0 +1,105 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,23))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 1)
+ │ └── @ EmbeddedStatementsNode (location: (1,1)-(1,22))
+ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,3)-(1,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IfNode (location: (1,3)-(1,21))
+ │ │ ├── if_keyword_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (1,3)-(1,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (1,3)-(1,4))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (1,3)-(1,4) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: (1,4)-(1,5) = "."
+ │ │ │ ├── name: :b?
+ │ │ │ ├── message_loc: (1,5)-(1,7) = "b?"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: (1,8)-(1,9) = "?"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,10)-(1,17))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,10)-(1,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (1,10)-(1,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ StringNode (location: (1,10)-(1,12))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: (1,10)-(1,11) = "\""
+ │ │ │ │ │ ├── content_loc: (1,11)-(1,11) = ""
+ │ │ │ │ │ ├── closing_loc: (1,11)-(1,12) = "\""
+ │ │ │ │ │ └── unescaped: ""
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :+
+ │ │ │ │ ├── message_loc: (1,12)-(1,13) = "+"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (1,13)-(1,14))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (1,13)-(1,14))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ ├── message_loc: (1,13)-(1,14) = "a"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+
+ │ │ │ ├── message_loc: (1,14)-(1,15) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,15)-(1,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (1,15)-(1,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (1,15)-(1,16) = "\""
+ │ │ │ │ ├── content_loc: (1,16)-(1,16) = ""
+ │ │ │ │ ├── closing_loc: (1,16)-(1,17) = "\""
+ │ │ │ │ └── unescaped: ""
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── consequent:
+ │ │ │ @ ElseNode (location: (1,17)-(1,21))
+ │ │ │ ├── else_keyword_loc: (1,17)-(1,18) = ":"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,19)-(1,21))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (1,19)-(1,21))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (1,19)-(1,20) = "\""
+ │ │ │ │ ├── content_loc: (1,20)-(1,20) = ""
+ │ │ │ │ ├── closing_loc: (1,20)-(1,21) = "\""
+ │ │ │ │ └── unescaped: ""
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ └── closing_loc: (1,21)-(1,22) = "}"
+ └── closing_loc: (1,22)-(1,23) = "\""
diff --git a/test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt b/test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt
new file mode 100644
index 0000000000..0066f66e84
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(2,66))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,66))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(2,66))
+ ├── flags: ∅
+ ├── opening_loc: ∅
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (1,0)-(1,62))
+ │ │ ├── flags: forced_utf8_encoding, frozen
+ │ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ │ ├── content_loc: (1,1)-(1,61) = "\\xE3\\xD3\\x8B\\xE3\\x83\\xBC\\x83\\xE3\\x83\\xE3\\x82\\xB3\\xA3\\x82\\x99"
+ │ │ ├── closing_loc: (1,61)-(1,62) = "\""
+ │ │ └── unescaped: "\xE3Ӌー\x83\xE3\x83コ\xA3\x82\x99"
+ │ └── @ StringNode (location: (2,8)-(2,66))
+ │ ├── flags: forced_utf8_encoding, frozen
+ │ ├── opening_loc: (2,8)-(2,9) = "\""
+ │ ├── content_loc: (2,9)-(2,65) = "\\xE3\\x83\\xB3\\xE3\\x83\\x8F\\xE3\\x82\\x9A\\xC3\\xBD;foo@bar.com"
+ │ ├── closing_loc: (2,65)-(2,66) = "\""
+ │ └── unescaped: "ンパý;foo@bar.com"
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt b/test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt
new file mode 100644
index 0000000000..d55d965068
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(2,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,1))
+ └── body: (length: 2)
+ ├── @ StringNode (location: (1,0)-(1,11))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── content_loc: (1,1)-(1,10) = "\\n\\n\\n\\n#"
+ │ ├── closing_loc: (1,10)-(1,11) = "\""
+ │ └── unescaped: "\n\n\n\n#"
+ └── @ IntegerNode (location: (2,0)-(2,1))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/seattlerb/str_pct_Q_nested.txt b/test/prism/snapshots/seattlerb/str_pct_Q_nested.txt
new file mode 100644
index 0000000000..1db0e76270
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_pct_Q_nested.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,26))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,26))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,26))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,3) = "%Q["
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (1,3)-(1,11))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,3)-(1,11) = "before ["
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "before ["
+ │ ├── @ EmbeddedStatementsNode (location: (1,11)-(1,18))
+ │ │ ├── opening_loc: (1,11)-(1,13) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,13)-(1,17))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,13)-(1,17))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :nest
+ │ │ │ ├── message_loc: (1,13)-(1,17) = "nest"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,17)-(1,18) = "}"
+ │ └── @ StringNode (location: (1,18)-(1,25))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,18)-(1,25) = "] after"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "] after"
+ └── closing_loc: (1,25)-(1,26) = "]"
diff --git a/test/prism/snapshots/seattlerb/str_pct_nested_nested.txt b/test/prism/snapshots/seattlerb/str_pct_nested_nested.txt
new file mode 100644
index 0000000000..22c3031832
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_pct_nested_nested.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,20))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,2) = "%{"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (1,2)-(1,5))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,2)-(1,5) = " { "
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " { "
+ │ ├── @ EmbeddedStatementsNode (location: (1,5)-(1,16))
+ │ │ ├── opening_loc: (1,5)-(1,7) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,8)-(1,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ InterpolatedStringNode (location: (1,8)-(1,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,8)-(1,9) = "\""
+ │ │ │ ├── parts: (length: 1)
+ │ │ │ │ └── @ EmbeddedStatementsNode (location: (1,9)-(1,13))
+ │ │ │ │ ├── opening_loc: (1,9)-(1,11) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (1,11)-(1,12))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (1,11)-(1,12))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── closing_loc: (1,12)-(1,13) = "}"
+ │ │ │ └── closing_loc: (1,13)-(1,14) = "\""
+ │ │ └── closing_loc: (1,15)-(1,16) = "}"
+ │ └── @ StringNode (location: (1,16)-(1,19))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,16)-(1,19) = " } "
+ │ ├── closing_loc: ∅
+ │ └── unescaped: " } "
+ └── closing_loc: (1,19)-(1,20) = "}"
diff --git a/test/prism/snapshots/seattlerb/str_pct_q.txt b/test/prism/snapshots/seattlerb/str_pct_q.txt
new file mode 100644
index 0000000000..c4dd5bacae
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_pct_q.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,3) = "%q{"
+ ├── content_loc: (1,3)-(1,8) = "a b c"
+ ├── closing_loc: (1,8)-(1,9) = "}"
+ └── unescaped: "a b c"
diff --git a/test/prism/snapshots/seattlerb/str_single_double_escaped_newline.txt b/test/prism/snapshots/seattlerb/str_single_double_escaped_newline.txt
new file mode 100644
index 0000000000..8fa8886029
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_single_double_escaped_newline.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,2)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "'"
+ │ │ ├── content_loc: (1,3)-(1,6) = "\\\\n"
+ │ │ ├── closing_loc: (1,6)-(1,7) = "'"
+ │ │ └── unescaped: "\\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (1,8)-(1,9))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (1,8)-(1,9) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/str_single_escaped_newline.txt b/test/prism/snapshots/seattlerb/str_single_escaped_newline.txt
new file mode 100644
index 0000000000..c840c7688b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_single_escaped_newline.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,2)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "'"
+ │ │ ├── content_loc: (1,3)-(1,5) = "\\n"
+ │ │ ├── closing_loc: (1,5)-(1,6) = "'"
+ │ │ └── unescaped: "\\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (1,7)-(1,8))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (1,7)-(1,8) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/str_single_newline.txt b/test/prism/snapshots/seattlerb/str_single_newline.txt
new file mode 100644
index 0000000000..15b0f2ff72
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_single_newline.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(2,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(2,1))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,2)-(2,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,2)-(1,3) = "'"
+ │ │ ├── content_loc: (1,3)-(2,0) = "\n"
+ │ │ ├── closing_loc: (2,0)-(2,1) = "'"
+ │ │ └── unescaped: "\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (2,2)-(2,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :b
+ ├── message_loc: (2,2)-(2,3) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/str_str.txt b/test/prism/snapshots/seattlerb/str_str.txt
new file mode 100644
index 0000000000..f3f1213a0c
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_str.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,10))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (1,1)-(1,3))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,1)-(1,3) = "a "
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a "
+ │ └── @ EmbeddedStatementsNode (location: (1,3)-(1,9))
+ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,5)-(1,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ StringNode (location: (1,5)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,5)-(1,6) = "'"
+ │ │ ├── content_loc: (1,6)-(1,7) = "b"
+ │ │ ├── closing_loc: (1,7)-(1,8) = "'"
+ │ │ └── unescaped: "b"
+ │ └── closing_loc: (1,8)-(1,9) = "}"
+ └── closing_loc: (1,9)-(1,10) = "\""
diff --git a/test/prism/snapshots/seattlerb/str_str_str.txt b/test/prism/snapshots/seattlerb/str_str_str.txt
new file mode 100644
index 0000000000..b01f2b5794
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/str_str_str.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,12))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (1,1)-(1,3))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,1)-(1,3) = "a "
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a "
+ │ ├── @ EmbeddedStatementsNode (location: (1,3)-(1,9))
+ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,5)-(1,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ StringNode (location: (1,5)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,5)-(1,6) = "'"
+ │ │ │ ├── content_loc: (1,6)-(1,7) = "b"
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = "'"
+ │ │ │ └── unescaped: "b"
+ │ │ └── closing_loc: (1,8)-(1,9) = "}"
+ │ └── @ StringNode (location: (1,9)-(1,11))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,9)-(1,11) = " c"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: " c"
+ └── closing_loc: (1,11)-(1,12) = "\""
diff --git a/test/prism/snapshots/seattlerb/super_arg.txt b/test/prism/snapshots/seattlerb/super_arg.txt
new file mode 100644
index 0000000000..61b5f0b631
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/super_arg.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ SuperNode (location: (1,0)-(1,8))
+ ├── keyword_loc: (1,0)-(1,5) = "super"
+ ├── lparen_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,6)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,6)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 42
+ ├── rparen_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/symbol_empty.txt b/test/prism/snapshots/seattlerb/symbol_empty.txt
new file mode 100644
index 0000000000..e95543e925
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/symbol_empty.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ SymbolNode (location: (1,0)-(1,3))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,2) = ":'"
+ ├── value_loc: (1,2)-(1,2) = ""
+ ├── closing_loc: (1,2)-(1,3) = "'"
+ └── unescaped: ""
diff --git a/test/prism/snapshots/seattlerb/symbol_list.txt b/test/prism/snapshots/seattlerb/symbol_list.txt
new file mode 100644
index 0000000000..6750160d50
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/symbol_list.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,13))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ InterpolatedSymbolNode (location: (1,3)-(1,7))
+ │ │ ├── opening_loc: ∅
+ │ │ ├── parts: (length: 1)
+ │ │ │ └── @ EmbeddedStatementsNode (location: (1,3)-(1,7))
+ │ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (1,5)-(1,6) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (1,6)-(1,7) = "}"
+ │ │ └── closing_loc: ∅
+ │ └── @ InterpolatedSymbolNode (location: (1,8)-(1,12))
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (1,8)-(1,12))
+ │ │ ├── opening_loc: (1,8)-(1,10) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,10)-(1,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,10)-(1,11) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,11)-(1,12) = "}"
+ │ └── closing_loc: ∅
+ ├── opening_loc: (1,0)-(1,3) = "%I["
+ └── closing_loc: (1,12)-(1,13) = "]"
diff --git a/test/prism/snapshots/seattlerb/symbols.txt b/test/prism/snapshots/seattlerb/symbols.txt
new file mode 100644
index 0000000000..30cf57c528
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/symbols.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── elements: (length: 3)
+ │ ├── @ SymbolNode (location: (1,3)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,3)-(1,4) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── @ SymbolNode (location: (1,5)-(1,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,5)-(1,6) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ └── @ SymbolNode (location: (1,7)-(1,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (1,7)-(1,8) = "c"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "c"
+ ├── opening_loc: (1,0)-(1,3) = "%i("
+ └── closing_loc: (1,8)-(1,9) = ")"
diff --git a/test/prism/snapshots/seattlerb/symbols_empty.txt b/test/prism/snapshots/seattlerb/symbols_empty.txt
new file mode 100644
index 0000000000..dc743e2be5
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/symbols_empty.txt
@@ -0,0 +1,10 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (1,0)-(1,3) = "%i("
+ └── closing_loc: (1,3)-(1,4) = ")"
diff --git a/test/prism/snapshots/seattlerb/symbols_empty_space.txt b/test/prism/snapshots/seattlerb/symbols_empty_space.txt
new file mode 100644
index 0000000000..ea7ada9446
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/symbols_empty_space.txt
@@ -0,0 +1,10 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,5))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (1,0)-(1,3) = "%i("
+ └── closing_loc: (1,4)-(1,5) = ")"
diff --git a/test/prism/snapshots/seattlerb/symbols_interp.txt b/test/prism/snapshots/seattlerb/symbols_interp.txt
new file mode 100644
index 0000000000..2ad3cc502d
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/symbols_interp.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,15))
+ ├── flags: ∅
+ ├── elements: (length: 3)
+ │ ├── @ SymbolNode (location: (1,3)-(1,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,3)-(1,4) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── @ SymbolNode (location: (1,5)-(1,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,5)-(1,12) = "b\#{1+1}"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\#{1+1}"
+ │ └── @ SymbolNode (location: (1,13)-(1,14))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (1,13)-(1,14) = "c"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "c"
+ ├── opening_loc: (1,0)-(1,3) = "%i("
+ └── closing_loc: (1,14)-(1,15) = ")"
diff --git a/test/prism/snapshots/seattlerb/thingy.txt b/test/prism/snapshots/seattlerb/thingy.txt
new file mode 100644
index 0000000000..4dd2ac44a6
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/thingy.txt
@@ -0,0 +1,57 @@
+@ ProgramNode (location: (1,0)-(3,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,7))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :f
+ │ │ ├── message_loc: (1,0)-(1,1) = "f"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,1)-(1,2) = "."
+ │ ├── name: :call
+ │ ├── message_loc: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,3)-(1,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,3)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── closing_loc: (1,5)-(1,6) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,7))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (3,0)-(3,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (3,0)-(3,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (3,1)-(3,3) = "::"
+ ├── name: :call
+ ├── message_loc: ∅
+ ├── opening_loc: (3,3)-(3,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,4)-(3,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (3,4)-(3,6))
+ │ ├── flags: decimal
+ │ └── value: 42
+ ├── closing_loc: (3,6)-(3,7) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/uminus_float.txt b/test/prism/snapshots/seattlerb/uminus_float.txt
new file mode 100644
index 0000000000..0578dbbd68
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/uminus_float.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ FloatNode (location: (1,0)-(1,4))
+ └── value: -0.0
diff --git a/test/prism/snapshots/seattlerb/unary_minus.txt b/test/prism/snapshots/seattlerb/unary_minus.txt
new file mode 100644
index 0000000000..79889bffb0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/unary_minus.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,2))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,2))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,1)-(1,2))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,1)-(1,2) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :-@
+ ├── message_loc: (1,0)-(1,1) = "-"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/unary_plus.txt b/test/prism/snapshots/seattlerb/unary_plus.txt
new file mode 100644
index 0000000000..b570cbf73b
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/unary_plus.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,2))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,2))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,1)-(1,2))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,1)-(1,2) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :+@
+ ├── message_loc: (1,0)-(1,1) = "+"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/unary_plus_on_literal.txt b/test/prism/snapshots/seattlerb/unary_plus_on_literal.txt
new file mode 100644
index 0000000000..4deb857536
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/unary_plus_on_literal.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,3))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ SymbolNode (location: (1,1)-(1,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,1)-(1,2) = ":"
+ │ ├── value_loc: (1,2)-(1,3) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── call_operator_loc: ∅
+ ├── name: :+@
+ ├── message_loc: (1,0)-(1,1) = "+"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/unary_tilde.txt b/test/prism/snapshots/seattlerb/unary_tilde.txt
new file mode 100644
index 0000000000..5fd1a5d00e
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/unary_tilde.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,2))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,2))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,1)-(1,2))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,1)-(1,2) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :~
+ ├── message_loc: (1,0)-(1,1) = "~"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/utf8_bom.txt b/test/prism/snapshots/seattlerb/utf8_bom.txt
new file mode 100644
index 0000000000..9f0eb83b05
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/utf8_bom.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (2,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (2,0)-(2,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (2,0)-(2,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (2,0)-(2,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (2,2)-(2,3))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (2,2)-(2,3))
+ │ ├── flags: decimal
+ │ └── value: 0
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/seattlerb/when_splat.txt b/test/prism/snapshots/seattlerb/when_splat.txt
new file mode 100644
index 0000000000..19e70019c0
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/when_splat.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,25))
+ ├── predicate:
+ │ @ CallNode (location: (1,5)-(1,6))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,5)-(1,6) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,8)-(1,20))
+ │ ├── keyword_loc: (1,8)-(1,12) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ SplatNode (location: (1,13)-(1,15))
+ │ │ ├── operator_loc: (1,13)-(1,14) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (1,14)-(1,15))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,14)-(1,15) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (1,16)-(1,20) = "then"
+ │ └── statements: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,22)-(1,25) = "end"
diff --git a/test/prism/snapshots/seattlerb/words_interp.txt b/test/prism/snapshots/seattlerb/words_interp.txt
new file mode 100644
index 0000000000..1175a6f476
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/words_interp.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── elements: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (1,3)-(1,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (1,3)-(1,7))
+ │ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (1,6)-(1,7) = "}"
+ │ │ └── @ StringNode (location: (1,7)-(1,8))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,7)-(1,8) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ └── closing_loc: ∅
+ ├── opening_loc: (1,0)-(1,3) = "%W("
+ └── closing_loc: (1,8)-(1,9) = ")"
diff --git a/test/prism/snapshots/seattlerb/yield_arg.txt b/test/prism/snapshots/seattlerb/yield_arg.txt
new file mode 100644
index 0000000000..22e0c14f83
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/yield_arg.txt
@@ -0,0 +1,16 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ YieldNode (location: (1,0)-(1,8))
+ ├── keyword_loc: (1,0)-(1,5) = "yield"
+ ├── lparen_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,6)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,6)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 42
+ └── rparen_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/yield_call_assocs.txt b/test/prism/snapshots/seattlerb/yield_call_assocs.txt
new file mode 100644
index 0000000000..c04273f5aa
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/yield_call_assocs.txt
@@ -0,0 +1,224 @@
+@ ProgramNode (location: (1,0)-(11,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,13))
+ └── body: (length: 6)
+ ├── @ YieldNode (location: (1,0)-(1,16))
+ │ ├── keyword_loc: (1,0)-(1,5) = "yield"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,6)-(1,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (1,6)-(1,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ KeywordHashNode (location: (1,9)-(1,16))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,9)-(1,16))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,9)-(1,10) = ":"
+ │ │ │ ├── value_loc: (1,10)-(1,11) = "z"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "z"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,15)-(1,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (1,12)-(1,14) = "=>"
+ │ └── rparen_loc: ∅
+ ├── @ YieldNode (location: (3,0)-(3,25))
+ │ ├── keyword_loc: (3,0)-(3,5) = "yield"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,6)-(3,25))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (3,6)-(3,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ KeywordHashNode (location: (3,9)-(3,25))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (3,9)-(3,16))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (3,9)-(3,11))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (3,9)-(3,10) = ":"
+ │ │ │ │ ├── value_loc: (3,10)-(3,11) = "z"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "z"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (3,15)-(3,16))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: (3,12)-(3,14) = "=>"
+ │ │ └── @ AssocNode (location: (3,18)-(3,25))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (3,18)-(3,20))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,18)-(3,19) = ":"
+ │ │ │ ├── value_loc: (3,19)-(3,20) = "w"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "w"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,24)-(3,25))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (3,21)-(3,23) = "=>"
+ │ └── rparen_loc: ∅
+ ├── @ YieldNode (location: (5,0)-(5,13))
+ │ ├── keyword_loc: (5,0)-(5,5) = "yield"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,6)-(5,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (5,6)-(5,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :y
+ │ │ ├── message_loc: (5,6)-(5,7) = "y"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,8)-(5,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ KeywordHashNode (location: (5,8)-(5,13))
+ │ │ │ ├── flags: symbol_keys
+ │ │ │ └── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (5,8)-(5,13))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (5,8)-(5,10))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (5,8)-(5,9) = ":"
+ │ │ │ │ ├── value_loc: (5,9)-(5,10) = "z"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "z"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (5,12)-(5,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: (5,10)-(5,12) = "=>"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── rparen_loc: ∅
+ ├── @ YieldNode (location: (7,0)-(7,11))
+ │ ├── keyword_loc: (7,0)-(7,5) = "yield"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,6)-(7,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (7,6)-(7,11))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :y
+ │ │ ├── message_loc: (7,6)-(7,7) = "y"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,8)-(7,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ KeywordHashNode (location: (7,8)-(7,11))
+ │ │ │ ├── flags: symbol_keys
+ │ │ │ └── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (7,8)-(7,11))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (7,8)-(7,10))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (7,8)-(7,9) = "z"
+ │ │ │ │ ├── closing_loc: (7,9)-(7,10) = ":"
+ │ │ │ │ └── unescaped: "z"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (7,10)-(7,11))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── rparen_loc: ∅
+ ├── @ YieldNode (location: (9,0)-(9,12))
+ │ ├── keyword_loc: (9,0)-(9,5) = "yield"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,6)-(9,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (9,6)-(9,12))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :y
+ │ │ ├── message_loc: (9,6)-(9,7) = "y"
+ │ │ ├── opening_loc: (9,7)-(9,8) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (9,8)-(9,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ KeywordHashNode (location: (9,8)-(9,11))
+ │ │ │ ├── flags: symbol_keys
+ │ │ │ └── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (9,8)-(9,11))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (9,8)-(9,10))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (9,8)-(9,9) = "z"
+ │ │ │ │ ├── closing_loc: (9,9)-(9,10) = ":"
+ │ │ │ │ └── unescaped: "z"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (9,10)-(9,11))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── closing_loc: (9,11)-(9,12) = ")"
+ │ │ └── block: ∅
+ │ └── rparen_loc: ∅
+ └── @ YieldNode (location: (11,0)-(11,13))
+ ├── keyword_loc: (11,0)-(11,5) = "yield"
+ ├── lparen_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (11,6)-(11,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (11,6)-(11,13))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :y
+ │ ├── message_loc: (11,6)-(11,7) = "y"
+ │ ├── opening_loc: (11,7)-(11,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,8)-(11,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (11,8)-(11,12))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (11,8)-(11,12))
+ │ │ ├── key:
+ │ │ │ @ CallNode (location: (11,8)-(11,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :z
+ │ │ │ ├── message_loc: (11,8)-(11,9) = "z"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (11,11)-(11,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (11,9)-(11,11) = "=>"
+ │ ├── closing_loc: (11,12)-(11,13) = ")"
+ │ └── block: ∅
+ └── rparen_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/yield_empty_parens.txt b/test/prism/snapshots/seattlerb/yield_empty_parens.txt
new file mode 100644
index 0000000000..5ecd89823f
--- /dev/null
+++ b/test/prism/snapshots/seattlerb/yield_empty_parens.txt
@@ -0,0 +1,10 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ YieldNode (location: (1,0)-(1,7))
+ ├── keyword_loc: (1,0)-(1,5) = "yield"
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── arguments: ∅
+ └── rparen_loc: (1,6)-(1,7) = ")"
diff --git a/test/prism/snapshots/single_method_call_with_bang.txt b/test/prism/snapshots/single_method_call_with_bang.txt
new file mode 100644
index 0000000000..4c68e0adac
--- /dev/null
+++ b/test/prism/snapshots/single_method_call_with_bang.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo!
+ ├── message_loc: (1,0)-(1,4) = "foo!"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/single_quote_heredocs.txt b/test/prism/snapshots/single_quote_heredocs.txt
new file mode 100644
index 0000000000..429c9daf11
--- /dev/null
+++ b/test/prism/snapshots/single_quote_heredocs.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,8) = "<<-'EOS'"
+ ├── content_loc: (2,0)-(3,0) = " cd L:\\Work\\MG3710IQPro\\Develop\n"
+ ├── closing_loc: (3,0)-(4,0) = "EOS\n"
+ └── unescaped: " cd L:\\Work\\MG3710IQPro\\Develop\n"
diff --git a/test/prism/snapshots/spanning_heredoc.txt b/test/prism/snapshots/spanning_heredoc.txt
new file mode 100644
index 0000000000..c89daaed09
--- /dev/null
+++ b/test/prism/snapshots/spanning_heredoc.txt
@@ -0,0 +1,413 @@
+@ ProgramNode (location: (4,0)-(63,2))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (4,0)-(63,2))
+ └── body: (length: 14)
+ ├── @ CallNode (location: (4,0)-(7,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :pp
+ │ ├── message_loc: (4,0)-(4,2) = "pp"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (4,3)-(7,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (4,3)-(7,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ StringNode (location: (4,3)-(4,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (4,3)-(4,7) = "<<-A"
+ │ │ │ ├── content_loc: (5,0)-(6,0) = "a\n"
+ │ │ │ ├── closing_loc: (6,0)-(7,0) = "A\n"
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── call_operator_loc: (4,7)-(4,8) = "."
+ │ │ ├── name: :gsub
+ │ │ ├── message_loc: (4,8)-(4,12) = "gsub"
+ │ │ ├── opening_loc: (4,12)-(4,13) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (4,13)-(7,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ InterpolatedRegularExpressionNode (location: (4,13)-(7,2))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (4,13)-(4,14) = "/"
+ │ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ │ ├── @ StringNode (location: (4,14)-(4,16))
+ │ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── content_loc: (4,14)-(4,16) = "b\\"
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ │ └── @ StringNode (location: (7,0)-(7,1))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (7,0)-(7,1) = "b"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ └── closing_loc: (7,1)-(7,2) = "/"
+ │ │ │ └── @ StringNode (location: (7,4)-(7,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (7,4)-(7,5) = "\""
+ │ │ │ ├── content_loc: (7,5)-(7,5) = ""
+ │ │ │ ├── closing_loc: (7,5)-(7,6) = "\""
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: (7,6)-(7,7) = ")"
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (10,0)-(13,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :pp
+ │ ├── message_loc: (10,0)-(10,2) = "pp"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (10,3)-(13,2))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (10,3)-(10,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (10,3)-(10,7) = "<<-A"
+ │ │ │ ├── content_loc: (11,0)-(12,0) = "c\n"
+ │ │ │ ├── closing_loc: (12,0)-(13,0) = "A\n"
+ │ │ │ └── unescaped: "c\n"
+ │ │ └── @ InterpolatedStringNode (location: (10,9)-(13,2))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (10,9)-(10,10) = "\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (10,10)-(10,12))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (10,10)-(10,12) = "d\\"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "d"
+ │ │ │ └── @ StringNode (location: (13,0)-(13,1))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (13,0)-(13,1) = "d"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "d"
+ │ │ └── closing_loc: (13,1)-(13,2) = "\""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (16,0)-(19,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :pp
+ │ ├── message_loc: (16,0)-(16,2) = "pp"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (16,3)-(19,2))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (16,3)-(16,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (16,3)-(16,7) = "<<-A"
+ │ │ │ ├── content_loc: (17,0)-(18,0) = "e\n"
+ │ │ │ ├── closing_loc: (18,0)-(19,0) = "A\n"
+ │ │ │ └── unescaped: "e\n"
+ │ │ └── @ InterpolatedStringNode (location: (16,9)-(19,2))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (16,9)-(16,12) = "%q["
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (16,12)-(16,14))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (16,12)-(16,14) = "f\\"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "f\\\n"
+ │ │ │ └── @ StringNode (location: (19,0)-(19,1))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (19,0)-(19,1) = "f"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "f"
+ │ │ └── closing_loc: (19,1)-(19,2) = "]"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (22,0)-(25,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :pp
+ │ ├── message_loc: (22,0)-(22,2) = "pp"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (22,3)-(25,2))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (22,3)-(22,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (22,3)-(22,7) = "<<-A"
+ │ │ │ ├── content_loc: (23,0)-(24,0) = "g\n"
+ │ │ │ ├── closing_loc: (24,0)-(25,0) = "A\n"
+ │ │ │ └── unescaped: "g\n"
+ │ │ └── @ InterpolatedStringNode (location: (22,9)-(25,2))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (22,9)-(22,12) = "%Q["
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (22,12)-(22,14))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (22,12)-(22,14) = "h\\"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "h"
+ │ │ │ └── @ StringNode (location: (25,0)-(25,1))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (25,0)-(25,1) = "h"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "h"
+ │ │ └── closing_loc: (25,1)-(25,2) = "]"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (28,0)-(31,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :pp
+ │ ├── message_loc: (28,0)-(28,2) = "pp"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (28,3)-(31,2))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (28,3)-(28,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (28,3)-(28,7) = "<<-A"
+ │ │ │ ├── content_loc: (29,0)-(30,0) = "i\n"
+ │ │ │ ├── closing_loc: (30,0)-(31,0) = "A\n"
+ │ │ │ └── unescaped: "i\n"
+ │ │ └── @ ArrayNode (location: (28,9)-(31,2))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ StringNode (location: (28,12)-(28,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (28,12)-(28,14) = "j\\"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "j\n"
+ │ │ │ └── @ StringNode (location: (31,0)-(31,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (31,0)-(31,1) = "j"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "j"
+ │ │ ├── opening_loc: (28,9)-(28,12) = "%w["
+ │ │ └── closing_loc: (31,1)-(31,2) = "]"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (35,0)-(38,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :pp
+ │ ├── message_loc: (35,0)-(35,2) = "pp"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,3)-(38,2))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (35,3)-(35,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (35,3)-(35,7) = "<<-A"
+ │ │ │ ├── content_loc: (36,0)-(37,0) = "k\n"
+ │ │ │ ├── closing_loc: (37,0)-(38,0) = "A\n"
+ │ │ │ └── unescaped: "k\n"
+ │ │ └── @ ArrayNode (location: (35,9)-(38,2))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ InterpolatedStringNode (location: (35,12)-(38,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (35,12)-(35,14))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (35,12)-(35,14) = "l\\"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "l\n"
+ │ │ │ │ └── @ StringNode (location: (38,0)-(38,1))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (38,0)-(38,1) = "l"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "l"
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── opening_loc: (35,9)-(35,12) = "%W["
+ │ │ └── closing_loc: (38,1)-(38,2) = "]"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (41,0)-(44,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :pp
+ │ ├── message_loc: (41,0)-(41,2) = "pp"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (41,3)-(44,2))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (41,3)-(41,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (41,3)-(41,7) = "<<-A"
+ │ │ │ ├── content_loc: (42,0)-(43,0) = "m\n"
+ │ │ │ ├── closing_loc: (43,0)-(44,0) = "A\n"
+ │ │ │ └── unescaped: "m\n"
+ │ │ └── @ ArrayNode (location: (41,9)-(44,2))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ SymbolNode (location: (41,12)-(41,14))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (41,12)-(41,14) = "n\\"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "n\n"
+ │ │ │ └── @ SymbolNode (location: (44,0)-(44,1))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (44,0)-(44,1) = "n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "n"
+ │ │ ├── opening_loc: (41,9)-(41,12) = "%i["
+ │ │ └── closing_loc: (44,1)-(44,2) = "]"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (48,0)-(51,2))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :pp
+ │ ├── message_loc: (48,0)-(48,2) = "pp"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (48,3)-(51,2))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (48,3)-(48,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (48,3)-(48,7) = "<<-A"
+ │ │ │ ├── content_loc: (49,0)-(50,0) = "o\n"
+ │ │ │ ├── closing_loc: (50,0)-(51,0) = "A\n"
+ │ │ │ └── unescaped: "o\n"
+ │ │ └── @ ArrayNode (location: (48,9)-(51,2))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ InterpolatedSymbolNode (location: (48,12)-(48,14))
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (48,12)-(48,14))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (48,12)-(48,14) = "p\\"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "p\n"
+ │ │ │ │ └── @ StringNode (location: (48,12)-(48,14))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (48,12)-(48,14) = "p\\"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "p"
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── opening_loc: (48,9)-(48,12) = "%I["
+ │ │ └── closing_loc: (51,1)-(51,2) = "]"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ StringNode (location: (53,0)-(53,3))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (53,0)-(53,3) = "<<A"
+ │ ├── content_loc: (54,0)-(54,0) = ""
+ │ ├── closing_loc: (54,0)-(55,0) = "A\n"
+ │ └── unescaped: ""
+ ├── @ MatchWriteNode (location: (53,5)-(55,13))
+ │ ├── call:
+ │ │ @ CallNode (location: (53,5)-(55,13))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ InterpolatedRegularExpressionNode (location: (53,5)-(55,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (53,5)-(53,6) = "/"
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (53,6)-(53,7))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (53,6)-(53,7) = "\\"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: ""
+ │ │ │ │ └── @ StringNode (location: (55,0)-(55,6))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (55,0)-(55,6) = "(?<a>)"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "(?<a>)"
+ │ │ │ └── closing_loc: (55,6)-(55,7) = "/"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (55,8)-(55,10) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (55,11)-(55,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (55,11)-(55,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (55,11)-(55,12) = "'"
+ │ │ │ ├── content_loc: (55,12)-(55,12) = ""
+ │ │ │ ├── closing_loc: (55,12)-(55,13) = "'"
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── targets: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (53,5)-(55,7))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ StringNode (location: (57,0)-(57,3))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (57,0)-(57,3) = "<<A"
+ │ ├── content_loc: (58,0)-(58,0) = ""
+ │ ├── closing_loc: (58,0)-(59,0) = "A\n"
+ │ └── unescaped: ""
+ ├── @ InterpolatedSymbolNode (location: (57,5)-(59,2))
+ │ ├── opening_loc: (57,5)-(57,7) = ":'"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (57,7)-(58,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (57,7)-(58,0) = "a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ StringNode (location: (59,0)-(59,1))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (59,0)-(59,1) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ └── closing_loc: (59,1)-(59,2) = "'"
+ ├── @ StringNode (location: (61,0)-(61,3))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (61,0)-(61,3) = "<<A"
+ │ ├── content_loc: (62,0)-(62,0) = ""
+ │ ├── closing_loc: (62,0)-(63,0) = "A\n"
+ │ └── unescaped: ""
+ └── @ InterpolatedSymbolNode (location: (61,5)-(63,2))
+ ├── opening_loc: (61,5)-(61,7) = ":\""
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (61,7)-(62,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (61,7)-(62,0) = "a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\n"
+ │ └── @ StringNode (location: (63,0)-(63,1))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (63,0)-(63,1) = "b"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "b"
+ └── closing_loc: (63,1)-(63,2) = "\""
diff --git a/test/prism/snapshots/spanning_heredoc_newlines.txt b/test/prism/snapshots/spanning_heredoc_newlines.txt
new file mode 100644
index 0000000000..e3609ddbba
--- /dev/null
+++ b/test/prism/snapshots/spanning_heredoc_newlines.txt
@@ -0,0 +1,155 @@
+@ ProgramNode (location: (1,0)-(24,0))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(24,0))
+ └── body: (length: 6)
+ ├── @ CallNode (location: (1,0)-(4,0))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (1,0)-(1,3))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,0)-(1,3) = "<<A"
+ │ │ ├── content_loc: (2,0)-(2,0) = ""
+ │ │ ├── closing_loc: (2,0)-(3,0) = "A\n"
+ │ │ └── unescaped: ""
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (1,3)-(1,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(4,0))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,4)-(4,0))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,4)-(2,0) = "%\n"
+ │ │ ├── content_loc: (3,0)-(3,0) = ""
+ │ │ ├── closing_loc: (3,0)-(4,0) = "\n"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(8,0))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (5,0)-(5,3))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (5,0)-(5,3) = "<<A"
+ │ │ ├── content_loc: (6,0)-(6,0) = ""
+ │ │ ├── closing_loc: (6,0)-(7,0) = "A\n"
+ │ │ └── unescaped: ""
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (5,3)-(5,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,4)-(8,0))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ RegularExpressionNode (location: (5,4)-(8,0))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,4)-(6,0) = "%r\n"
+ │ │ ├── content_loc: (6,0)-(6,0) = ""
+ │ │ ├── closing_loc: (7,0)-(8,0) = "\n"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (9,0)-(12,0))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (9,0)-(9,3))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (9,0)-(9,3) = "<<A"
+ │ │ ├── content_loc: (10,0)-(10,0) = ""
+ │ │ ├── closing_loc: (10,0)-(11,0) = "A\n"
+ │ │ └── unescaped: ""
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (9,3)-(9,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,4)-(12,0))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (9,4)-(12,0))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (9,4)-(10,0) = "%q\n"
+ │ │ ├── content_loc: (11,0)-(11,0) = ""
+ │ │ ├── closing_loc: (11,0)-(12,0) = "\n"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (13,0)-(16,0))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (13,0)-(13,3))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (13,0)-(13,3) = "<<A"
+ │ │ ├── content_loc: (14,0)-(14,0) = ""
+ │ │ ├── closing_loc: (14,0)-(15,0) = "A\n"
+ │ │ └── unescaped: ""
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (13,3)-(13,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,4)-(16,0))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (13,4)-(16,0))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (13,4)-(14,0) = "%Q\n"
+ │ │ ├── content_loc: (15,0)-(15,0) = ""
+ │ │ ├── closing_loc: (15,0)-(16,0) = "\n"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (17,0)-(20,0))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (17,0)-(17,3))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (17,0)-(17,3) = "<<A"
+ │ │ ├── content_loc: (18,0)-(18,0) = ""
+ │ │ ├── closing_loc: (18,0)-(19,0) = "A\n"
+ │ │ └── unescaped: ""
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (17,3)-(17,4) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (17,4)-(20,0))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (17,4)-(20,0))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (17,4)-(18,0) = "%s\n"
+ │ │ ├── value_loc: (18,0)-(18,0) = ""
+ │ │ ├── closing_loc: (19,0)-(20,0) = "\n"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (21,0)-(24,0))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ StringNode (location: (21,0)-(21,3))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (21,0)-(21,3) = "<<A"
+ │ ├── content_loc: (22,0)-(22,0) = ""
+ │ ├── closing_loc: (22,0)-(23,0) = "A\n"
+ │ └── unescaped: ""
+ ├── call_operator_loc: ∅
+ ├── name: :+
+ ├── message_loc: (21,3)-(21,4) = "+"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (21,4)-(24,0))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ XStringNode (location: (21,4)-(24,0))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (21,4)-(22,0) = "%x\n"
+ │ ├── content_loc: (22,0)-(22,0) = ""
+ │ ├── closing_loc: (23,0)-(24,0) = "\n"
+ │ └── unescaped: ""
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/strings.txt b/test/prism/snapshots/strings.txt
new file mode 100644
index 0000000000..632d2ac3b5
--- /dev/null
+++ b/test/prism/snapshots/strings.txt
@@ -0,0 +1,534 @@
+@ ProgramNode (location: (1,0)-(105,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(105,4))
+ └── body: (length: 50)
+ ├── @ StringNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,2) = "%%"
+ │ ├── content_loc: (1,2)-(1,5) = "abc"
+ │ ├── closing_loc: (1,5)-(1,6) = "%"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (3,0)-(3,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (3,0)-(3,2) = "%^"
+ │ ├── content_loc: (3,2)-(3,5) = "abc"
+ │ ├── closing_loc: (3,5)-(3,6) = "^"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (5,0)-(5,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (5,0)-(5,2) = "%&"
+ │ ├── content_loc: (5,2)-(5,5) = "abc"
+ │ ├── closing_loc: (5,5)-(5,6) = "&"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (7,0)-(7,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(7,2) = "%*"
+ │ ├── content_loc: (7,2)-(7,5) = "abc"
+ │ ├── closing_loc: (7,5)-(7,6) = "*"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (9,0)-(9,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (9,0)-(9,2) = "%_"
+ │ ├── content_loc: (9,2)-(9,5) = "abc"
+ │ ├── closing_loc: (9,5)-(9,6) = "_"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (11,0)-(11,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (11,0)-(11,2) = "%+"
+ │ ├── content_loc: (11,2)-(11,5) = "abc"
+ │ ├── closing_loc: (11,5)-(11,6) = "+"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (13,0)-(13,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (13,0)-(13,2) = "%-"
+ │ ├── content_loc: (13,2)-(13,5) = "abc"
+ │ ├── closing_loc: (13,5)-(13,6) = "-"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (15,0)-(15,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (15,0)-(15,2) = "%:"
+ │ ├── content_loc: (15,2)-(15,5) = "abc"
+ │ ├── closing_loc: (15,5)-(15,6) = ":"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (17,0)-(17,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (17,0)-(17,2) = "%;"
+ │ ├── content_loc: (17,2)-(17,5) = "abc"
+ │ ├── closing_loc: (17,5)-(17,6) = ";"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (19,0)-(19,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (19,0)-(19,2) = "%'"
+ │ ├── content_loc: (19,2)-(19,5) = "abc"
+ │ ├── closing_loc: (19,5)-(19,6) = "'"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (21,0)-(21,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (21,0)-(21,2) = "%~"
+ │ ├── content_loc: (21,2)-(21,5) = "abc"
+ │ ├── closing_loc: (21,5)-(21,6) = "~"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (23,0)-(23,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (23,0)-(23,2) = "%?"
+ │ ├── content_loc: (23,2)-(23,5) = "abc"
+ │ ├── closing_loc: (23,5)-(23,6) = "?"
+ │ └── unescaped: "abc"
+ ├── @ ArrayNode (location: (25,0)-(25,8))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (25,0)-(25,3) = "%w{"
+ │ └── closing_loc: (25,7)-(25,8) = "}"
+ ├── @ StringNode (location: (27,0)-(27,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (27,0)-(27,2) = "%/"
+ │ ├── content_loc: (27,2)-(27,5) = "abc"
+ │ ├── closing_loc: (27,5)-(27,6) = "/"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (29,0)-(29,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (29,0)-(29,2) = "%`"
+ │ ├── content_loc: (29,2)-(29,5) = "abc"
+ │ ├── closing_loc: (29,5)-(29,6) = "`"
+ │ └── unescaped: "abc"
+ ├── @ InterpolatedStringNode (location: (31,0)-(31,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (31,0)-(31,1) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedVariableNode (location: (31,1)-(31,7))
+ │ │ ├── operator_loc: (31,1)-(31,2) = "#"
+ │ │ └── variable:
+ │ │ @ ClassVariableReadNode (location: (31,2)-(31,7))
+ │ │ └── name: :@@foo
+ │ └── closing_loc: (31,7)-(31,8) = "\""
+ ├── @ StringNode (location: (33,0)-(33,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (33,0)-(33,2) = "%\\"
+ │ ├── content_loc: (33,2)-(33,5) = "abc"
+ │ ├── closing_loc: (33,5)-(33,6) = "\\"
+ │ └── unescaped: "abc"
+ ├── @ InterpolatedStringNode (location: (35,0)-(35,17))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (35,0)-(35,2) = "%{"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (35,2)-(35,6))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (35,2)-(35,6) = "aaa "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "aaa "
+ │ │ ├── @ EmbeddedStatementsNode (location: (35,6)-(35,12))
+ │ │ │ ├── opening_loc: (35,6)-(35,8) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (35,8)-(35,11))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (35,8)-(35,11))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bbb
+ │ │ │ │ ├── message_loc: (35,8)-(35,11) = "bbb"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (35,11)-(35,12) = "}"
+ │ │ └── @ StringNode (location: (35,12)-(35,16))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (35,12)-(35,16) = " ccc"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " ccc"
+ │ └── closing_loc: (35,16)-(35,17) = "}"
+ ├── @ StringNode (location: (37,0)-(37,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (37,0)-(37,2) = "%["
+ │ ├── content_loc: (37,2)-(37,7) = "foo[]"
+ │ ├── closing_loc: (37,7)-(37,8) = "]"
+ │ └── unescaped: "foo[]"
+ ├── @ CallNode (location: (39,0)-(41,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ StringNode (location: (39,0)-(39,5))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (39,0)-(39,1) = "\""
+ │ │ ├── content_loc: (39,1)-(39,4) = "foo"
+ │ │ ├── closing_loc: (39,4)-(39,5) = "\""
+ │ │ └── unescaped: "foo"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (39,6)-(39,7) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (41,0)-(41,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (41,0)-(41,5))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (41,0)-(41,1) = "\""
+ │ │ ├── content_loc: (41,1)-(41,4) = "bar"
+ │ │ ├── closing_loc: (41,4)-(41,5) = "\""
+ │ │ └── unescaped: "bar"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ StringNode (location: (43,0)-(43,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (43,0)-(43,3) = "%q{"
+ │ ├── content_loc: (43,3)-(43,6) = "abc"
+ │ ├── closing_loc: (43,6)-(43,7) = "}"
+ │ └── unescaped: "abc"
+ ├── @ SymbolNode (location: (45,0)-(45,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (45,0)-(45,3) = "%s["
+ │ ├── value_loc: (45,3)-(45,6) = "abc"
+ │ ├── closing_loc: (45,6)-(45,7) = "]"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (47,0)-(47,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (47,0)-(47,2) = "%{"
+ │ ├── content_loc: (47,2)-(47,5) = "abc"
+ │ ├── closing_loc: (47,5)-(47,6) = "}"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (49,0)-(49,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (49,0)-(49,1) = "'"
+ │ ├── content_loc: (49,1)-(49,1) = ""
+ │ ├── closing_loc: (49,1)-(49,2) = "'"
+ │ └── unescaped: ""
+ ├── @ StringNode (location: (51,0)-(51,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (51,0)-(51,1) = "\""
+ │ ├── content_loc: (51,1)-(51,4) = "abc"
+ │ ├── closing_loc: (51,4)-(51,5) = "\""
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (53,0)-(53,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (53,0)-(53,1) = "\""
+ │ ├── content_loc: (53,1)-(53,6) = "\#@---"
+ │ ├── closing_loc: (53,6)-(53,7) = "\""
+ │ └── unescaped: "\#@---"
+ ├── @ InterpolatedStringNode (location: (55,0)-(55,16))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (55,0)-(55,1) = "\""
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (55,1)-(55,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (55,1)-(55,5) = "aaa "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "aaa "
+ │ │ ├── @ EmbeddedStatementsNode (location: (55,5)-(55,11))
+ │ │ │ ├── opening_loc: (55,5)-(55,7) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (55,7)-(55,10))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (55,7)-(55,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bbb
+ │ │ │ │ ├── message_loc: (55,7)-(55,10) = "bbb"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (55,10)-(55,11) = "}"
+ │ │ └── @ StringNode (location: (55,11)-(55,15))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (55,11)-(55,15) = " ccc"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " ccc"
+ │ └── closing_loc: (55,15)-(55,16) = "\""
+ ├── @ StringNode (location: (57,0)-(57,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (57,0)-(57,1) = "'"
+ │ ├── content_loc: (57,1)-(57,4) = "abc"
+ │ ├── closing_loc: (57,4)-(57,5) = "'"
+ │ └── unescaped: "abc"
+ ├── @ ArrayNode (location: (59,0)-(59,9))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (59,3)-(59,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (59,3)-(59,4) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ StringNode (location: (59,5)-(59,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (59,5)-(59,6) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── @ StringNode (location: (59,7)-(59,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (59,7)-(59,8) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── opening_loc: (59,0)-(59,3) = "%w["
+ │ └── closing_loc: (59,8)-(59,9) = "]"
+ ├── @ ArrayNode (location: (61,0)-(61,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (61,3)-(61,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (61,3)-(61,6) = "a[]"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a[]"
+ │ │ ├── @ StringNode (location: (61,7)-(61,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (61,7)-(61,12) = "b[[]]"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b[[]]"
+ │ │ └── @ StringNode (location: (61,13)-(61,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (61,13)-(61,16) = "c[]"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c[]"
+ │ ├── opening_loc: (61,0)-(61,3) = "%w["
+ │ └── closing_loc: (61,16)-(61,17) = "]"
+ ├── @ ArrayNode (location: (63,0)-(63,18))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (63,3)-(63,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (63,3)-(63,11) = "foo\\ bar"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo bar"
+ │ │ └── @ StringNode (location: (63,12)-(63,17))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (63,12)-(63,17) = "\\\#{1}"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\\\#{1}"
+ │ ├── opening_loc: (63,0)-(63,3) = "%w["
+ │ └── closing_loc: (63,17)-(63,18) = "]"
+ ├── @ ArrayNode (location: (65,0)-(65,16))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (65,3)-(65,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (65,3)-(65,11) = "foo\\ bar"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo bar"
+ │ │ └── @ StringNode (location: (65,12)-(65,15))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (65,12)-(65,15) = "baz"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz"
+ │ ├── opening_loc: (65,0)-(65,3) = "%w["
+ │ └── closing_loc: (65,15)-(65,16) = "]"
+ ├── @ ArrayNode (location: (67,0)-(67,14))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (67,3)-(67,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (67,3)-(67,4) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ InterpolatedStringNode (location: (67,5)-(67,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── parts: (length: 3)
+ │ │ │ │ ├── @ StringNode (location: (67,5)-(67,6))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (67,5)-(67,6) = "b"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (67,6)-(67,10))
+ │ │ │ │ │ ├── opening_loc: (67,6)-(67,8) = "\#{"
+ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ @ StatementsNode (location: (67,8)-(67,9))
+ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ └── @ CallNode (location: (67,8)-(67,9))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :c
+ │ │ │ │ │ │ ├── message_loc: (67,8)-(67,9) = "c"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ └── closing_loc: (67,9)-(67,10) = "}"
+ │ │ │ │ └── @ StringNode (location: (67,10)-(67,11))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (67,10)-(67,11) = "d"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "d"
+ │ │ │ └── closing_loc: ∅
+ │ │ └── @ StringNode (location: (67,12)-(67,13))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (67,12)-(67,13) = "e"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "e"
+ │ ├── opening_loc: (67,0)-(67,3) = "%W["
+ │ └── closing_loc: (67,13)-(67,14) = "]"
+ ├── @ ArrayNode (location: (69,0)-(69,9))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (69,3)-(69,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (69,3)-(69,4) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ StringNode (location: (69,5)-(69,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (69,5)-(69,6) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── @ StringNode (location: (69,7)-(69,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (69,7)-(69,8) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── opening_loc: (69,0)-(69,3) = "%W["
+ │ └── closing_loc: (69,8)-(69,9) = "]"
+ ├── @ ArrayNode (location: (71,0)-(75,1))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ StringNode (location: (72,2)-(72,3))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (72,2)-(72,3) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ StringNode (location: (73,2)-(73,3))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (73,2)-(73,3) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── @ StringNode (location: (74,2)-(74,3))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (74,2)-(74,3) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── opening_loc: (71,0)-(71,3) = "%w["
+ │ └── closing_loc: (75,0)-(75,1) = "]"
+ ├── @ StringNode (location: (77,0)-(77,15))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (77,0)-(77,1) = "'"
+ │ ├── content_loc: (77,1)-(77,14) = "\\' foo \\' bar"
+ │ ├── closing_loc: (77,14)-(77,15) = "'"
+ │ └── unescaped: "' foo ' bar"
+ ├── @ StringNode (location: (79,0)-(79,15))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (79,0)-(79,1) = "'"
+ │ ├── content_loc: (79,1)-(79,14) = "\\\\ foo \\\\ bar"
+ │ ├── closing_loc: (79,14)-(79,15) = "'"
+ │ └── unescaped: "\\ foo \\ bar"
+ ├── @ InterpolatedStringNode (location: (81,0)-(81,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (81,0)-(81,1) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedVariableNode (location: (81,1)-(81,6))
+ │ │ ├── operator_loc: (81,1)-(81,2) = "#"
+ │ │ └── variable:
+ │ │ @ GlobalVariableReadNode (location: (81,2)-(81,6))
+ │ │ └── name: :$foo
+ │ └── closing_loc: (81,6)-(81,7) = "\""
+ ├── @ InterpolatedStringNode (location: (83,0)-(83,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (83,0)-(83,1) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedVariableNode (location: (83,1)-(83,6))
+ │ │ ├── operator_loc: (83,1)-(83,2) = "#"
+ │ │ └── variable:
+ │ │ @ InstanceVariableReadNode (location: (83,2)-(83,6))
+ │ │ └── name: :@foo
+ │ └── closing_loc: (83,6)-(83,7) = "\""
+ ├── @ StringNode (location: (85,0)-(85,15))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (85,0)-(85,1) = "\""
+ │ ├── content_loc: (85,1)-(85,14) = "\\x7 \\x23 \\x61"
+ │ ├── closing_loc: (85,14)-(85,15) = "\""
+ │ └── unescaped: "\a # a"
+ ├── @ StringNode (location: (87,0)-(87,13))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (87,0)-(87,1) = "\""
+ │ ├── content_loc: (87,1)-(87,12) = "\\7 \\43 \\141"
+ │ ├── closing_loc: (87,12)-(87,13) = "\""
+ │ └── unescaped: "\a # a"
+ ├── @ StringNode (location: (89,0)-(89,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (89,0)-(89,2) = "%["
+ │ ├── content_loc: (89,2)-(89,5) = "abc"
+ │ ├── closing_loc: (89,5)-(89,6) = "]"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (91,0)-(91,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (91,0)-(91,2) = "%("
+ │ ├── content_loc: (91,2)-(91,5) = "abc"
+ │ ├── closing_loc: (91,5)-(91,6) = ")"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (93,0)-(93,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (93,0)-(93,2) = "%@"
+ │ ├── content_loc: (93,2)-(93,5) = "abc"
+ │ ├── closing_loc: (93,5)-(93,6) = "@"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (95,0)-(95,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (95,0)-(95,2) = "%$"
+ │ ├── content_loc: (95,2)-(95,5) = "abc"
+ │ ├── closing_loc: (95,5)-(95,6) = "$"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (97,0)-(97,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (97,0)-(97,1) = "?"
+ │ ├── content_loc: (97,1)-(97,2) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── @ InterpolatedStringNode (location: (99,0)-(99,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (99,0)-(99,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (99,0)-(99,1) = "?"
+ │ │ │ ├── content_loc: (99,1)-(99,2) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ StringNode (location: (99,3)-(99,6))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (99,3)-(99,4) = "\""
+ │ │ ├── content_loc: (99,4)-(99,5) = "a"
+ │ │ ├── closing_loc: (99,5)-(99,6) = "\""
+ │ │ └── unescaped: "a"
+ │ └── closing_loc: ∅
+ ├── @ StringNode (location: (101,0)-(101,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (101,0)-(101,3) = "%Q{"
+ │ ├── content_loc: (101,3)-(101,6) = "abc"
+ │ ├── closing_loc: (101,6)-(101,7) = "}"
+ │ └── unescaped: "abc"
+ ├── @ StringNode (location: (103,0)-(103,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (103,0)-(103,2) = "%^"
+ │ ├── content_loc: (103,2)-(103,4) = "\#$"
+ │ ├── closing_loc: (103,4)-(103,5) = "^"
+ │ └── unescaped: "\#$"
+ └── @ StringNode (location: (105,0)-(105,4))
+ ├── flags: ∅
+ ├── opening_loc: (105,0)-(105,2) = "%@"
+ ├── content_loc: (105,2)-(105,3) = "#"
+ ├── closing_loc: (105,3)-(105,4) = "@"
+ └── unescaped: "#"
diff --git a/test/prism/snapshots/super.txt b/test/prism/snapshots/super.txt
new file mode 100644
index 0000000000..79f9a5d5a5
--- /dev/null
+++ b/test/prism/snapshots/super.txt
@@ -0,0 +1,132 @@
+@ ProgramNode (location: (1,0)-(17,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(17,21))
+ └── body: (length: 9)
+ ├── @ ForwardingSuperNode (location: (1,0)-(1,5))
+ │ └── block: ∅
+ ├── @ SuperNode (location: (3,0)-(3,7))
+ │ ├── keyword_loc: (3,0)-(3,5) = "super"
+ │ ├── lparen_loc: (3,5)-(3,6) = "("
+ │ ├── arguments: ∅
+ │ ├── rparen_loc: (3,6)-(3,7) = ")"
+ │ └── block: ∅
+ ├── @ SuperNode (location: (5,0)-(5,8))
+ │ ├── keyword_loc: (5,0)-(5,5) = "super"
+ │ ├── lparen_loc: (5,5)-(5,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,6)-(5,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,6)-(5,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── rparen_loc: (5,7)-(5,8) = ")"
+ │ └── block: ∅
+ ├── @ SuperNode (location: (7,0)-(7,14))
+ │ ├── keyword_loc: (7,0)-(7,5) = "super"
+ │ ├── lparen_loc: (7,5)-(7,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,6)-(7,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ IntegerNode (location: (7,6)-(7,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ IntegerNode (location: (7,9)-(7,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── @ IntegerNode (location: (7,12)-(7,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── rparen_loc: (7,13)-(7,14) = ")"
+ │ └── block: ∅
+ ├── @ SuperNode (location: (9,0)-(9,11))
+ │ ├── keyword_loc: (9,0)-(9,5) = "super"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── rparen_loc: ∅
+ │ └── block:
+ │ @ BlockArgumentNode (location: (9,6)-(9,11))
+ │ ├── expression:
+ │ │ @ SymbolNode (location: (9,7)-(9,11))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (9,7)-(9,8) = ":"
+ │ │ ├── value_loc: (9,8)-(9,11) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (9,6)-(9,7) = "&"
+ ├── @ SuperNode (location: (11,0)-(11,12))
+ │ ├── keyword_loc: (11,0)-(11,5) = "super"
+ │ ├── lparen_loc: (11,5)-(11,6) = "("
+ │ ├── arguments: ∅
+ │ ├── rparen_loc: (11,11)-(11,12) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (11,6)-(11,11))
+ │ ├── expression:
+ │ │ @ SymbolNode (location: (11,7)-(11,11))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (11,7)-(11,8) = ":"
+ │ │ ├── value_loc: (11,8)-(11,11) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── operator_loc: (11,6)-(11,7) = "&"
+ ├── @ ForwardingSuperNode (location: (13,0)-(13,8))
+ │ └── block:
+ │ @ BlockNode (location: (13,6)-(13,8))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (13,6)-(13,7) = "{"
+ │ └── closing_loc: (13,7)-(13,8) = "}"
+ ├── @ SuperNode (location: (15,0)-(15,17))
+ │ ├── keyword_loc: (15,0)-(15,5) = "super"
+ │ ├── lparen_loc: (15,5)-(15,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,6)-(15,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ IntegerNode (location: (15,6)-(15,7))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ IntegerNode (location: (15,9)-(15,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── @ IntegerNode (location: (15,12)-(15,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── rparen_loc: (15,13)-(15,14) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (15,15)-(15,17))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (15,15)-(15,16) = "{"
+ │ └── closing_loc: (15,16)-(15,17) = "}"
+ └── @ SuperNode (location: (17,0)-(17,21))
+ ├── keyword_loc: (17,0)-(17,5) = "super"
+ ├── lparen_loc: (17,5)-(17,6) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (17,6)-(17,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 3)
+ │ ├── @ IntegerNode (location: (17,6)-(17,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── @ IntegerNode (location: (17,9)-(17,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── @ IntegerNode (location: (17,12)-(17,13))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── rparen_loc: (17,20)-(17,21) = ")"
+ └── block:
+ @ BlockArgumentNode (location: (17,15)-(17,20))
+ ├── expression:
+ │ @ SymbolNode (location: (17,16)-(17,20))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (17,16)-(17,17) = ":"
+ │ ├── value_loc: (17,17)-(17,20) = "foo"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "foo"
+ └── operator_loc: (17,15)-(17,16) = "&"
diff --git a/test/prism/snapshots/symbols.txt b/test/prism/snapshots/symbols.txt
new file mode 100644
index 0000000000..dbd3a4d030
--- /dev/null
+++ b/test/prism/snapshots/symbols.txt
@@ -0,0 +1,464 @@
+@ ProgramNode (location: (1,0)-(93,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(93,13))
+ └── body: (length: 47)
+ ├── @ SymbolNode (location: (1,0)-(1,6))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,0)-(1,2) = ":'"
+ │ ├── value_loc: (1,2)-(1,5) = "abc"
+ │ ├── closing_loc: (1,5)-(1,6) = "'"
+ │ └── unescaped: "abc"
+ ├── @ InterpolatedSymbolNode (location: (3,0)-(3,9))
+ │ ├── opening_loc: (3,0)-(3,2) = ":\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (3,2)-(3,8))
+ │ │ ├── opening_loc: (3,2)-(3,4) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,4)-(3,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,4)-(3,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :var
+ │ │ │ ├── message_loc: (3,4)-(3,7) = "var"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (3,7)-(3,8) = "}"
+ │ └── closing_loc: (3,8)-(3,9) = "\""
+ ├── @ InterpolatedSymbolNode (location: (5,0)-(5,10))
+ │ ├── opening_loc: (5,0)-(5,2) = ":\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (5,2)-(5,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (5,2)-(5,5) = "abc"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "abc"
+ │ │ └── @ EmbeddedStatementsNode (location: (5,5)-(5,9))
+ │ │ ├── opening_loc: (5,5)-(5,7) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (5,7)-(5,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,7)-(5,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── closing_loc: (5,8)-(5,9) = "}"
+ │ └── closing_loc: (5,9)-(5,10) = "\""
+ ├── @ ArrayNode (location: (7,0)-(7,20))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 4)
+ │ │ ├── @ SymbolNode (location: (7,1)-(7,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (7,1)-(7,2) = ":"
+ │ │ │ ├── value_loc: (7,2)-(7,4) = "Υ"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "Υ"
+ │ │ ├── @ SymbolNode (location: (7,6)-(7,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (7,6)-(7,7) = ":"
+ │ │ │ ├── value_loc: (7,7)-(7,9) = "ά"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "ά"
+ │ │ ├── @ SymbolNode (location: (7,11)-(7,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (7,11)-(7,12) = ":"
+ │ │ │ ├── value_loc: (7,12)-(7,14) = "ŗ"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "ŗ"
+ │ │ └── @ SymbolNode (location: (7,16)-(7,19))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (7,16)-(7,17) = ":"
+ │ │ ├── value_loc: (7,17)-(7,19) = "ρ"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "ρ"
+ │ ├── opening_loc: (7,0)-(7,1) = "["
+ │ └── closing_loc: (7,19)-(7,20) = "]"
+ ├── @ SymbolNode (location: (9,0)-(9,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (9,0)-(9,1) = ":"
+ │ ├── value_loc: (9,1)-(9,3) = "-@"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "-@"
+ ├── @ SymbolNode (location: (11,0)-(11,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (11,0)-(11,1) = ":"
+ │ ├── value_loc: (11,1)-(11,2) = "-"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "-"
+ ├── @ SymbolNode (location: (13,0)-(13,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (13,0)-(13,1) = ":"
+ │ ├── value_loc: (13,1)-(13,2) = "%"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "%"
+ ├── @ SymbolNode (location: (15,0)-(15,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (15,0)-(15,1) = ":"
+ │ ├── value_loc: (15,1)-(15,2) = "|"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "|"
+ ├── @ SymbolNode (location: (17,0)-(17,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (17,0)-(17,1) = ":"
+ │ ├── value_loc: (17,1)-(17,3) = "+@"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "+@"
+ ├── @ SymbolNode (location: (19,0)-(19,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (19,0)-(19,1) = ":"
+ │ ├── value_loc: (19,1)-(19,2) = "+"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "+"
+ ├── @ SymbolNode (location: (21,0)-(21,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (21,0)-(21,1) = ":"
+ │ ├── value_loc: (21,1)-(21,2) = "/"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "/"
+ ├── @ SymbolNode (location: (23,0)-(23,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (23,0)-(23,1) = ":"
+ │ ├── value_loc: (23,1)-(23,3) = "**"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "**"
+ ├── @ SymbolNode (location: (25,0)-(25,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (25,0)-(25,1) = ":"
+ │ ├── value_loc: (25,1)-(25,2) = "*"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "*"
+ ├── @ SymbolNode (location: (27,0)-(27,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (27,0)-(27,1) = ":"
+ │ ├── value_loc: (27,1)-(27,3) = "~@"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "~"
+ ├── @ ArrayNode (location: (29,0)-(29,16))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 4)
+ │ │ ├── @ IntegerNode (location: (29,1)-(29,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ 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
+ │ │ └── @ ImaginaryNode (location: (29,13)-(29,15))
+ │ │ └── numeric:
+ │ │ @ IntegerNode (location: (29,13)-(29,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (29,0)-(29,1) = "["
+ │ └── closing_loc: (29,15)-(29,16) = "]"
+ ├── @ SymbolNode (location: (31,0)-(31,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (31,0)-(31,1) = ":"
+ │ ├── value_loc: (31,1)-(31,2) = "~"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "~"
+ ├── @ SymbolNode (location: (33,0)-(33,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (33,0)-(33,1) = ":"
+ │ ├── value_loc: (33,1)-(33,2) = "a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "a"
+ ├── @ ArrayNode (location: (35,0)-(35,9))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ SymbolNode (location: (35,3)-(35,4))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (35,3)-(35,4) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ SymbolNode (location: (35,5)-(35,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (35,5)-(35,6) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── @ SymbolNode (location: (35,7)-(35,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (35,7)-(35,8) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ ├── opening_loc: (35,0)-(35,3) = "%i["
+ │ └── closing_loc: (35,8)-(35,9) = "]"
+ ├── @ ArrayNode (location: (37,0)-(37,24))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 4)
+ │ │ ├── @ SymbolNode (location: (37,3)-(37,4))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (37,3)-(37,4) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ SymbolNode (location: (37,5)-(37,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (37,5)-(37,10) = "b\#{1}"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b\#{1}"
+ │ │ ├── @ SymbolNode (location: (37,11)-(37,16))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (37,11)-(37,16) = "\#{2}c"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\#{2}c"
+ │ │ └── @ SymbolNode (location: (37,17)-(37,23))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (37,17)-(37,23) = "d\#{3}f"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "d\#{3}f"
+ │ ├── opening_loc: (37,0)-(37,3) = "%i["
+ │ └── closing_loc: (37,23)-(37,24) = "]"
+ ├── @ ArrayNode (location: (39,0)-(39,24))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 4)
+ │ │ ├── @ SymbolNode (location: (39,3)-(39,4))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (39,3)-(39,4) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ InterpolatedSymbolNode (location: (39,5)-(39,10))
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (39,5)-(39,6))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (39,5)-(39,6) = "b"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ └── @ EmbeddedStatementsNode (location: (39,6)-(39,10))
+ │ │ │ │ ├── opening_loc: (39,6)-(39,8) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (39,8)-(39,9))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (39,8)-(39,9))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── closing_loc: (39,9)-(39,10) = "}"
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── @ InterpolatedSymbolNode (location: (39,11)-(39,16))
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (39,11)-(39,15))
+ │ │ │ │ │ ├── opening_loc: (39,11)-(39,13) = "\#{"
+ │ │ │ │ │ ├── statements:
+ │ │ │ │ │ │ @ StatementsNode (location: (39,13)-(39,14))
+ │ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ │ └── @ IntegerNode (location: (39,13)-(39,14))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 2
+ │ │ │ │ │ └── closing_loc: (39,14)-(39,15) = "}"
+ │ │ │ │ └── @ StringNode (location: (39,15)-(39,16))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (39,15)-(39,16) = "c"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "c"
+ │ │ │ └── closing_loc: ∅
+ │ │ └── @ InterpolatedSymbolNode (location: (39,17)-(39,23))
+ │ │ ├── opening_loc: ∅
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (39,17)-(39,18))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (39,17)-(39,18) = "d"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "d"
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (39,18)-(39,22))
+ │ │ │ │ ├── opening_loc: (39,18)-(39,20) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (39,20)-(39,21))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (39,20)-(39,21))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 3
+ │ │ │ │ └── closing_loc: (39,21)-(39,22) = "}"
+ │ │ │ └── @ StringNode (location: (39,22)-(39,23))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (39,22)-(39,23) = "f"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "f"
+ │ │ └── closing_loc: ∅
+ │ ├── opening_loc: (39,0)-(39,3) = "%I["
+ │ └── closing_loc: (39,23)-(39,24) = "]"
+ ├── @ SymbolNode (location: (41,0)-(41,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (41,0)-(41,1) = ":"
+ │ ├── value_loc: (41,1)-(41,4) = "@@a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "@@a"
+ ├── @ SymbolNode (location: (43,0)-(43,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (43,0)-(43,1) = ":"
+ │ ├── value_loc: (43,1)-(43,5) = "👍"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "👍"
+ ├── @ ArrayNode (location: (45,0)-(45,7))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ SymbolNode (location: (45,3)-(45,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (45,3)-(45,6) = "a\\b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\\b"
+ │ ├── opening_loc: (45,0)-(45,3) = "%i["
+ │ └── closing_loc: (45,6)-(45,7) = "]"
+ ├── @ SymbolNode (location: (47,0)-(47,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (47,0)-(47,1) = ":"
+ │ ├── value_loc: (47,1)-(47,3) = "$a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "$a"
+ ├── @ SymbolNode (location: (49,0)-(49,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (49,0)-(49,1) = ":"
+ │ ├── value_loc: (49,1)-(49,3) = "@a"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "@a"
+ ├── @ SymbolNode (location: (51,0)-(51,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (51,0)-(51,1) = ":"
+ │ ├── value_loc: (51,1)-(51,3) = "do"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "do"
+ ├── @ SymbolNode (location: (53,0)-(53,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (53,0)-(53,1) = ":"
+ │ ├── value_loc: (53,1)-(53,2) = "&"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "&"
+ ├── @ SymbolNode (location: (55,0)-(55,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (55,0)-(55,1) = ":"
+ │ ├── value_loc: (55,1)-(55,2) = "`"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "`"
+ ├── @ SymbolNode (location: (57,0)-(57,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (57,0)-(57,1) = ":"
+ │ ├── value_loc: (57,1)-(57,3) = "!@"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "!"
+ ├── @ SymbolNode (location: (59,0)-(59,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (59,0)-(59,1) = ":"
+ │ ├── value_loc: (59,1)-(59,3) = "!~"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "!~"
+ ├── @ SymbolNode (location: (61,0)-(61,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (61,0)-(61,1) = ":"
+ │ ├── value_loc: (61,1)-(61,2) = "!"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "!"
+ ├── @ SymbolNode (location: (63,0)-(63,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (63,0)-(63,1) = ":"
+ │ ├── value_loc: (63,1)-(63,3) = "[]"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "[]"
+ ├── @ SymbolNode (location: (65,0)-(65,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (65,0)-(65,1) = ":"
+ │ ├── value_loc: (65,1)-(65,4) = "[]="
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "[]="
+ ├── @ SymbolNode (location: (67,0)-(67,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (67,0)-(67,1) = ":"
+ │ ├── value_loc: (67,1)-(67,2) = "^"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "^"
+ ├── @ SymbolNode (location: (69,0)-(69,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (69,0)-(69,1) = ":"
+ │ ├── value_loc: (69,1)-(69,3) = "=="
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "=="
+ ├── @ SymbolNode (location: (71,0)-(71,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (71,0)-(71,1) = ":"
+ │ ├── value_loc: (71,1)-(71,4) = "==="
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "==="
+ ├── @ SymbolNode (location: (73,0)-(73,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (73,0)-(73,1) = ":"
+ │ ├── value_loc: (73,1)-(73,3) = "=~"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "=~"
+ ├── @ SymbolNode (location: (75,0)-(75,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (75,0)-(75,1) = ":"
+ │ ├── value_loc: (75,1)-(75,3) = ">="
+ │ ├── closing_loc: ∅
+ │ └── unescaped: ">="
+ ├── @ SymbolNode (location: (77,0)-(77,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (77,0)-(77,1) = ":"
+ │ ├── value_loc: (77,1)-(77,3) = ">>"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: ">>"
+ ├── @ SymbolNode (location: (79,0)-(79,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (79,0)-(79,1) = ":"
+ │ ├── value_loc: (79,1)-(79,2) = ">"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: ">"
+ ├── @ SymbolNode (location: (81,0)-(81,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (81,0)-(81,1) = ":"
+ │ ├── value_loc: (81,1)-(81,4) = "<=>"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "<=>"
+ ├── @ SymbolNode (location: (83,0)-(83,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (83,0)-(83,1) = ":"
+ │ ├── value_loc: (83,1)-(83,3) = "<="
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "<="
+ ├── @ SymbolNode (location: (85,0)-(85,3))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (85,0)-(85,1) = ":"
+ │ ├── value_loc: (85,1)-(85,3) = "<<"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "<<"
+ ├── @ SymbolNode (location: (87,0)-(87,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (87,0)-(87,1) = ":"
+ │ ├── value_loc: (87,1)-(87,2) = "<"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "<"
+ ├── @ SymbolNode (location: (89,0)-(89,9))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (89,0)-(89,1) = ":"
+ │ ├── value_loc: (89,1)-(89,9) = "__LINE__"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "__LINE__"
+ ├── @ SymbolNode (location: (91,0)-(91,9))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (91,0)-(91,1) = ":"
+ │ ├── value_loc: (91,1)-(91,9) = "__FILE__"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "__FILE__"
+ └── @ SymbolNode (location: (93,0)-(93,13))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (93,0)-(93,1) = ":"
+ ├── value_loc: (93,1)-(93,13) = "__ENCODING__"
+ ├── closing_loc: ∅
+ └── unescaped: "__ENCODING__"
diff --git a/test/prism/snapshots/ternary_operator.txt b/test/prism/snapshots/ternary_operator.txt
new file mode 100644
index 0000000000..0277ac88f0
--- /dev/null
+++ b/test/prism/snapshots/ternary_operator.txt
@@ -0,0 +1,295 @@
+@ ProgramNode (location: (1,0)-(15,12))
+├── locals: [:_a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(15,12))
+ └── body: (length: 8)
+ ├── @ IfNode (location: (1,0)-(1,9))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (1,2)-(1,3) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,4)-(1,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (1,6)-(1,9))
+ │ │ ├── else_keyword_loc: (1,6)-(1,7) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,8)-(1,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,8)-(1,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (1,8)-(1,9) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ IfNode (location: (3,0)-(3,27))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (3,0)-(3,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (3,0)-(3,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (3,2)-(3,3) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,4)-(3,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ DefinedNode (location: (3,4)-(3,14))
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (3,13)-(3,14))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (3,13)-(3,14) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ └── keyword_loc: (3,4)-(3,12) = "defined?"
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (3,15)-(3,27))
+ │ │ ├── else_keyword_loc: (3,15)-(3,16) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,17)-(3,27))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ DefinedNode (location: (3,17)-(3,27))
+ │ │ │ ├── lparen_loc: ∅
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (3,26)-(3,27))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (3,26)-(3,27) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── rparen_loc: ∅
+ │ │ │ └── keyword_loc: (3,17)-(3,25) = "defined?"
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ IfNode (location: (5,0)-(5,15))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (5,0)-(5,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :empty?
+ │ │ ├── message_loc: (5,0)-(5,6) = "empty?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (5,6)-(5,7) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,7)-(5,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ TrueNode (location: (5,7)-(5,11))
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (5,11)-(5,15))
+ │ │ ├── else_keyword_loc: (5,11)-(5,12) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (5,12)-(5,15))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ NilNode (location: (5,12)-(5,15))
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ IfNode (location: (7,0)-(7,16))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (7,0)-(7,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :empty?
+ │ │ ├── message_loc: (7,0)-(7,6) = "empty?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (7,6)-(7,7) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (7,7)-(7,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ FalseNode (location: (7,7)-(7,12))
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (7,12)-(7,16))
+ │ │ ├── else_keyword_loc: (7,12)-(7,13) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (7,13)-(7,16))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ NilNode (location: (7,13)-(7,16))
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ IfNode (location: (9,0)-(9,14))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (9,0)-(9,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :empty?
+ │ │ ├── message_loc: (9,0)-(9,6) = "empty?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (9,6)-(9,7) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (9,7)-(9,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (9,7)-(9,10))
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (9,10)-(9,14))
+ │ │ ├── else_keyword_loc: (9,10)-(9,11) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (9,11)-(9,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ NilNode (location: (9,11)-(9,14))
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ IfNode (location: (11,0)-(11,10))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (11,0)-(11,2))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a?
+ │ │ ├── message_loc: (11,0)-(11,2) = "a?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (11,2)-(11,3) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (11,3)-(11,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (11,3)-(11,6))
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (11,6)-(11,10))
+ │ │ ├── else_keyword_loc: (11,6)-(11,7) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (11,7)-(11,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ NilNode (location: (11,7)-(11,10))
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ IfNode (location: (13,0)-(13,14))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (13,0)-(13,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (13,0)-(13,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (13,2)-(13,3) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (13,3)-(13,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (13,3)-(13,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :var1
+ │ │ ├── message_loc: (13,3)-(13,7) = "var1"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (13,8)-(13,14))
+ │ │ ├── else_keyword_loc: (13,8)-(13,9) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (13,10)-(13,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (13,10)-(13,14))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :var2
+ │ │ │ ├── message_loc: (13,10)-(13,14) = "var2"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ └── @ IfNode (location: (15,0)-(15,12))
+ ├── if_keyword_loc: ∅
+ ├── predicate:
+ │ @ CallNode (location: (15,0)-(15,4))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :nil?
+ │ ├── message_loc: (15,0)-(15,4) = "nil?"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: (15,4)-(15,5) = "?"
+ ├── statements:
+ │ @ StatementsNode (location: (15,5)-(15,10))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableWriteNode (location: (15,5)-(15,10))
+ │ ├── name: :_a
+ │ ├── depth: 0
+ │ ├── name_loc: (15,5)-(15,7) = "_a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (15,9)-(15,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (15,8)-(15,9) = "="
+ ├── consequent:
+ │ @ ElseNode (location: (15,10)-(15,12))
+ │ ├── else_keyword_loc: (15,10)-(15,11) = ":"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (15,11)-(15,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (15,11)-(15,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── end_keyword_loc: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/tilde_heredocs.txt b/test/prism/snapshots/tilde_heredocs.txt
new file mode 100644
index 0000000000..f50f915a64
--- /dev/null
+++ b/test/prism/snapshots/tilde_heredocs.txt
@@ -0,0 +1,405 @@
+@ ProgramNode (location: (1,0)-(94,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(94,6))
+ └── body: (length: 19)
+ ├── @ InterpolatedStringNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,6) = "<<~EOF"
+ │ ├── parts: (length: 4)
+ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (3,0)-(3,4))
+ │ │ │ ├── opening_loc: (3,0)-(3,2) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (3,2)-(3,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (3,2)-(3,3))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (3,3)-(3,4) = "}"
+ │ │ ├── @ StringNode (location: (3,4)-(4,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,4)-(4,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (4,0)-(5,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (4,0)-(5,0) = " a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " a\n"
+ │ └── closing_loc: (5,0)-(6,0) = "EOF\n"
+ ├── @ StringNode (location: (7,0)-(7,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(7,6) = "<<~EOF"
+ │ ├── content_loc: (8,0)-(9,0) = " a\n"
+ │ ├── closing_loc: (9,0)-(10,0) = "EOF\n"
+ │ └── unescaped: "a\n"
+ ├── @ InterpolatedStringNode (location: (11,0)-(11,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (11,0)-(11,6) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (12,0)-(13,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (12,0)-(13,0) = "\ta\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\ta\n"
+ │ │ ├── @ StringNode (location: (13,0)-(14,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (13,0)-(14,0) = " b\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b\n"
+ │ │ └── @ StringNode (location: (14,0)-(15,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (14,0)-(15,0) = "\t\tc\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\t\tc\n"
+ │ └── closing_loc: (15,0)-(16,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (17,0)-(17,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (17,0)-(17,6) = "<<~EOF"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (18,2)-(18,6))
+ │ │ │ ├── opening_loc: (18,2)-(18,4) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (18,4)-(18,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (18,4)-(18,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (18,5)-(18,6) = "}"
+ │ │ └── @ StringNode (location: (18,6)-(19,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (18,6)-(19,0) = " a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " a\n"
+ │ └── closing_loc: (19,0)-(20,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (21,0)-(21,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (21,0)-(21,6) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (22,0)-(22,4))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (22,0)-(22,4) = " a "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a "
+ │ │ ├── @ EmbeddedStatementsNode (location: (22,4)-(22,8))
+ │ │ │ ├── opening_loc: (22,4)-(22,6) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (22,6)-(22,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (22,6)-(22,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (22,7)-(22,8) = "}"
+ │ │ └── @ StringNode (location: (22,8)-(23,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (22,8)-(23,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (23,0)-(24,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (25,0)-(25,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (25,0)-(25,6) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (26,0)-(27,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (26,0)-(27,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (27,1)-(27,5))
+ │ │ │ ├── opening_loc: (27,1)-(27,3) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (27,3)-(27,4))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (27,3)-(27,4))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (27,4)-(27,5) = "}"
+ │ │ └── @ StringNode (location: (27,5)-(28,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (27,5)-(28,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (28,0)-(29,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (30,0)-(30,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (30,0)-(30,6) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (31,0)-(32,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (31,0)-(32,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (32,2)-(32,6))
+ │ │ │ ├── opening_loc: (32,2)-(32,4) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (32,4)-(32,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (32,4)-(32,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (32,5)-(32,6) = "}"
+ │ │ └── @ StringNode (location: (32,6)-(33,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (32,6)-(33,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (33,0)-(34,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (35,0)-(35,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (35,0)-(35,6) = "<<~EOF"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (36,0)-(37,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (36,0)-(37,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ StringNode (location: (37,0)-(38,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (37,0)-(38,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (38,0)-(39,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (40,0)-(40,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (40,0)-(40,6) = "<<~EOF"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (41,0)-(42,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (41,0)-(42,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ StringNode (location: (42,0)-(43,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (42,0)-(43,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " b\n"
+ │ └── closing_loc: (43,0)-(44,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (45,0)-(45,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (45,0)-(45,6) = "<<~EOF"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (46,0)-(47,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (46,0)-(47,0) = "\t\t\ta\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\ta\n"
+ │ │ └── @ StringNode (location: (47,0)-(48,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (47,0)-(48,0) = "\t\tb\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (48,0)-(49,0) = "EOF\n"
+ ├── @ StringNode (location: (50,0)-(50,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (50,0)-(50,8) = "<<~'EOF'"
+ │ ├── content_loc: (51,0)-(52,0) = " a \#{1}\n"
+ │ ├── closing_loc: (52,0)-(53,0) = "EOF\n"
+ │ └── unescaped: "a \#{1}\n"
+ ├── @ InterpolatedStringNode (location: (54,0)-(54,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (54,0)-(54,6) = "<<~EOF"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (55,0)-(56,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (55,0)-(56,0) = "\ta\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ StringNode (location: (56,0)-(57,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (56,0)-(57,0) = "\t b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " b\n"
+ │ └── closing_loc: (57,0)-(58,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (59,0)-(59,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (59,0)-(59,6) = "<<~EOF"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (60,0)-(61,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (60,0)-(61,0) = "\t a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a\n"
+ │ │ └── @ StringNode (location: (61,0)-(62,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (61,0)-(62,0) = "\tb\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (62,0)-(63,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (64,0)-(64,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (64,0)-(64,6) = "<<~EOF"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (65,0)-(66,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (65,0)-(66,0) = " \ta\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ StringNode (location: (66,0)-(67,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (66,0)-(67,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (67,0)-(68,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (69,0)-(69,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (69,0)-(69,6) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (70,0)-(71,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (70,0)-(71,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ StringNode (location: (71,0)-(72,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (71,0)-(72,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (72,0)-(73,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (72,0)-(73,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (73,0)-(74,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (75,0)-(75,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (75,0)-(75,6) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (76,0)-(77,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (76,0)-(77,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ StringNode (location: (77,0)-(78,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (77,0)-(78,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (78,0)-(79,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (78,0)-(79,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (79,0)-(80,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (81,0)-(81,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (81,0)-(81,6) = "<<~EOF"
+ │ ├── parts: (length: 5)
+ │ │ ├── @ StringNode (location: (82,0)-(83,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (82,0)-(83,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ StringNode (location: (83,0)-(84,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (83,0)-(84,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ ├── @ StringNode (location: (84,0)-(85,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (84,0)-(85,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ ├── @ StringNode (location: (85,0)-(86,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (85,0)-(86,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (86,0)-(87,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (86,0)-(87,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (87,0)-(88,0) = "EOF\n"
+ ├── @ InterpolatedStringNode (location: (89,0)-(89,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (89,0)-(89,6) = "<<~EOF"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (90,0)-(91,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (90,0)-(91,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (91,2)-(91,6))
+ │ │ │ ├── opening_loc: (91,2)-(91,4) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (91,4)-(91,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (91,4)-(91,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (91,5)-(91,6) = "}"
+ │ │ └── @ StringNode (location: (91,6)-(92,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (91,6)-(92,0) = "a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\n"
+ │ └── closing_loc: (92,0)-(93,0) = " EOF\n"
+ └── @ InterpolatedStringNode (location: (94,0)-(94,6))
+ ├── flags: ∅
+ ├── opening_loc: (94,0)-(94,6) = "<<~EOT"
+ ├── parts: (length: 3)
+ │ ├── @ EmbeddedStatementsNode (location: (95,2)-(95,6))
+ │ │ ├── opening_loc: (95,2)-(95,4) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (95,4)-(95,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (95,4)-(95,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── closing_loc: (95,5)-(95,6) = "}"
+ │ ├── @ StringNode (location: (95,6)-(96,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (95,6)-(96,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── @ StringNode (location: (96,0)-(97,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (96,0)-(97,0) = "\tb\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\tb\n"
+ └── closing_loc: (97,0)-(98,0) = "EOT\n"
diff --git a/test/prism/snapshots/undef.txt b/test/prism/snapshots/undef.txt
new file mode 100644
index 0000000000..e59ace92f5
--- /dev/null
+++ b/test/prism/snapshots/undef.txt
@@ -0,0 +1,117 @@
+@ ProgramNode (location: (1,0)-(17,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(17,14))
+ └── body: (length: 9)
+ ├── @ UndefNode (location: (1,0)-(1,7))
+ │ ├── names: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,6)-(1,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ └── keyword_loc: (1,0)-(1,5) = "undef"
+ ├── @ UndefNode (location: (3,0)-(3,10))
+ │ ├── names: (length: 2)
+ │ │ ├── @ SymbolNode (location: (3,6)-(3,7))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (3,6)-(3,7) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (3,9)-(3,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (3,9)-(3,10) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ └── keyword_loc: (3,0)-(3,5) = "undef"
+ ├── @ UndefNode (location: (5,0)-(5,8))
+ │ ├── names: (length: 1)
+ │ │ └── @ SymbolNode (location: (5,6)-(5,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (5,6)-(5,8) = "if"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "if"
+ │ └── keyword_loc: (5,0)-(5,5) = "undef"
+ ├── @ UndefNode (location: (7,0)-(7,9))
+ │ ├── names: (length: 1)
+ │ │ └── @ SymbolNode (location: (7,6)-(7,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (7,6)-(7,9) = "<=>"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "<=>"
+ │ └── keyword_loc: (7,0)-(7,5) = "undef"
+ ├── @ UndefNode (location: (9,0)-(9,8))
+ │ ├── names: (length: 1)
+ │ │ └── @ SymbolNode (location: (9,6)-(9,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (9,6)-(9,7) = ":"
+ │ │ ├── value_loc: (9,7)-(9,8) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ └── keyword_loc: (9,0)-(9,5) = "undef"
+ ├── @ UndefNode (location: (11,0)-(11,16))
+ │ ├── names: (length: 3)
+ │ │ ├── @ SymbolNode (location: (11,6)-(11,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (11,6)-(11,7) = ":"
+ │ │ │ ├── value_loc: (11,7)-(11,8) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── @ SymbolNode (location: (11,10)-(11,12))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (11,10)-(11,11) = ":"
+ │ │ │ ├── value_loc: (11,11)-(11,12) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ └── @ SymbolNode (location: (11,14)-(11,16))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (11,14)-(11,15) = ":"
+ │ │ ├── value_loc: (11,15)-(11,16) = "c"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "c"
+ │ └── keyword_loc: (11,0)-(11,5) = "undef"
+ ├── @ UndefNode (location: (13,0)-(13,12))
+ │ ├── names: (length: 1)
+ │ │ └── @ SymbolNode (location: (13,6)-(13,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (13,6)-(13,8) = ":'"
+ │ │ ├── value_loc: (13,8)-(13,11) = "abc"
+ │ │ ├── closing_loc: (13,11)-(13,12) = "'"
+ │ │ └── unescaped: "abc"
+ │ └── keyword_loc: (13,0)-(13,5) = "undef"
+ ├── @ UndefNode (location: (15,0)-(15,16))
+ │ ├── names: (length: 1)
+ │ │ └── @ InterpolatedSymbolNode (location: (15,6)-(15,16))
+ │ │ ├── opening_loc: (15,6)-(15,8) = ":\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (15,8)-(15,11))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (15,8)-(15,11) = "abc"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "abc"
+ │ │ │ └── @ EmbeddedStatementsNode (location: (15,11)-(15,15))
+ │ │ │ ├── opening_loc: (15,11)-(15,13) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (15,13)-(15,14))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (15,13)-(15,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (15,14)-(15,15) = "}"
+ │ │ └── closing_loc: (15,15)-(15,16) = "\""
+ │ └── keyword_loc: (15,0)-(15,5) = "undef"
+ └── @ UndefNode (location: (17,0)-(17,14))
+ ├── names: (length: 1)
+ │ └── @ SymbolNode (location: (17,6)-(17,14))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (17,6)-(17,14) = "Constant"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "Constant"
+ └── keyword_loc: (17,0)-(17,5) = "undef"
diff --git a/test/prism/snapshots/unescaping.txt b/test/prism/snapshots/unescaping.txt
new file mode 100644
index 0000000000..456ef226d0
--- /dev/null
+++ b/test/prism/snapshots/unescaping.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(7,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,7))
+ └── body: (length: 4)
+ ├── @ ArrayNode (location: (1,0)-(1,10))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (1,1)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,1)-(1,2) = "\""
+ │ │ ├── content_loc: (1,2)-(1,8) = "\\c\#{1}"
+ │ │ ├── closing_loc: (1,8)-(1,9) = "\""
+ │ │ └── unescaped: "\u0003{1}"
+ │ ├── opening_loc: (1,0)-(1,1) = "["
+ │ └── closing_loc: (1,9)-(1,10) = "]"
+ ├── @ RegularExpressionNode (location: (3,0)-(3,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (3,0)-(3,1) = "/"
+ │ ├── content_loc: (3,1)-(3,7) = "\\c\#{1}"
+ │ ├── closing_loc: (3,7)-(3,8) = "/"
+ │ └── unescaped: "\\x03{1}"
+ ├── @ StringNode (location: (5,0)-(5,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (5,0)-(5,1) = "\""
+ │ ├── content_loc: (5,1)-(5,7) = "\\c\#{1}"
+ │ ├── closing_loc: (5,7)-(5,8) = "\""
+ │ └── unescaped: "\u0003{1}"
+ └── @ StringNode (location: (7,0)-(7,7))
+ ├── flags: ∅
+ ├── opening_loc: (7,0)-(7,7) = "<<~HERE"
+ ├── content_loc: (8,0)-(9,0) = " \\c\#{1}\n"
+ ├── closing_loc: (9,0)-(10,0) = "HERE\n"
+ └── unescaped: "\u0003{1}\n"
diff --git a/test/prism/snapshots/unless.txt b/test/prism/snapshots/unless.txt
new file mode 100644
index 0000000000..6611ffe63d
--- /dev/null
+++ b/test/prism/snapshots/unless.txt
@@ -0,0 +1,172 @@
+@ ProgramNode (location: (1,0)-(14,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(14,22))
+ └── body: (length: 7)
+ ├── @ UnlessNode (location: (1,0)-(1,19))
+ │ ├── keyword_loc: (1,0)-(1,6) = "unless"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (1,7)-(1,11))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,13)-(1,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,13)-(1,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (1,16)-(1,19) = "end"
+ ├── @ UnlessNode (location: (3,0)-(4,12))
+ │ ├── keyword_loc: (3,0)-(3,6) = "unless"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (3,7)-(3,11))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (4,0)-(4,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (4,0)-(4,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (4,2)-(4,12))
+ │ │ ├── else_keyword_loc: (4,2)-(4,6) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (4,7)-(4,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (4,7)-(4,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── end_keyword_loc: (4,9)-(4,12) = "end"
+ │ └── end_keyword_loc: (4,9)-(4,12) = "end"
+ ├── @ UnlessNode (location: (6,0)-(6,13))
+ │ ├── keyword_loc: (6,2)-(6,8) = "unless"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (6,9)-(6,13))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (6,0)-(6,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (6,0)-(6,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ CallNode (location: (8,0)-(8,25))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (8,0)-(8,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (8,4)-(8,25))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (8,6)-(8,23))
+ │ │ └── body: (length: 1)
+ │ │ └── @ UnlessNode (location: (8,6)-(8,23))
+ │ │ ├── keyword_loc: (8,12)-(8,18) = "unless"
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (8,19)-(8,23))
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (8,6)-(8,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ BreakNode (location: (8,6)-(8,11))
+ │ │ │ ├── arguments: ∅
+ │ │ │ └── keyword_loc: (8,6)-(8,11) = "break"
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── opening_loc: (8,4)-(8,5) = "{"
+ │ └── closing_loc: (8,24)-(8,25) = "}"
+ ├── @ CallNode (location: (10,0)-(10,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (10,0)-(10,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (10,4)-(10,24))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (10,6)-(10,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ UnlessNode (location: (10,6)-(10,22))
+ │ │ ├── keyword_loc: (10,11)-(10,17) = "unless"
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (10,18)-(10,22))
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (10,6)-(10,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ NextNode (location: (10,6)-(10,10))
+ │ │ │ ├── arguments: ∅
+ │ │ │ └── keyword_loc: (10,6)-(10,10) = "next"
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── opening_loc: (10,4)-(10,5) = "{"
+ │ └── closing_loc: (10,23)-(10,24) = "}"
+ ├── @ UnlessNode (location: (12,0)-(12,18))
+ │ ├── keyword_loc: (12,7)-(12,13) = "unless"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (12,14)-(12,18))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (12,0)-(12,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ReturnNode (location: (12,0)-(12,6))
+ │ │ ├── keyword_loc: (12,0)-(12,6) = "return"
+ │ │ └── arguments: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: ∅
+ └── @ UnlessNode (location: (14,0)-(14,22))
+ ├── keyword_loc: (14,11)-(14,17) = "unless"
+ ├── predicate:
+ │ @ CallNode (location: (14,18)-(14,22))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar?
+ │ ├── message_loc: (14,18)-(14,22) = "bar?"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (14,0)-(14,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (14,0)-(14,10))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (14,0)-(14,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (14,4)-(14,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (14,4)-(14,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (14,4)-(14,5) = ":"
+ │ │ │ ├── value_loc: (14,5)-(14,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (14,8)-(14,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (14,8)-(14,9) = ":"
+ │ │ ├── value_loc: (14,9)-(14,10) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/unparser/corpus/literal/alias.txt b/test/prism/snapshots/unparser/corpus/literal/alias.txt
new file mode 100644
index 0000000000..18ddc86d4f
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/alias.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(2,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,15))
+ └── body: (length: 2)
+ ├── @ AliasGlobalVariableNode (location: (1,0)-(1,15))
+ │ ├── new_name:
+ │ │ @ GlobalVariableReadNode (location: (1,6)-(1,10))
+ │ │ └── name: :$foo
+ │ ├── old_name:
+ │ │ @ GlobalVariableReadNode (location: (1,11)-(1,15))
+ │ │ └── name: :$bar
+ │ └── keyword_loc: (1,0)-(1,5) = "alias"
+ └── @ AliasMethodNode (location: (2,0)-(2,15))
+ ├── new_name:
+ │ @ SymbolNode (location: (2,6)-(2,10))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (2,6)-(2,7) = ":"
+ │ ├── value_loc: (2,7)-(2,10) = "foo"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "foo"
+ ├── old_name:
+ │ @ SymbolNode (location: (2,11)-(2,15))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (2,11)-(2,12) = ":"
+ │ ├── value_loc: (2,12)-(2,15) = "bar"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "bar"
+ └── keyword_loc: (2,0)-(2,5) = "alias"
diff --git a/test/prism/snapshots/unparser/corpus/literal/assignment.txt b/test/prism/snapshots/unparser/corpus/literal/assignment.txt
new file mode 100644
index 0000000000..99c8daf34c
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/assignment.txt
@@ -0,0 +1,1080 @@
+@ ProgramNode (location: (1,0)-(51,17))
+├── locals: [:a, :b, :foo, :c, :x]
+└── statements:
+ @ StatementsNode (location: (1,0)-(51,17))
+ └── body: (length: 43)
+ ├── @ GlobalVariableWriteNode (location: (1,0)-(1,6))
+ │ ├── name: :$a
+ │ ├── name_loc: (1,0)-(1,2) = "$a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,3)-(1,4) = "="
+ ├── @ MultiWriteNode (location: (2,0)-(2,17))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ GlobalVariableTargetNode (location: (2,1)-(2,3))
+ │ │ │ └── name: :$a
+ │ │ └── @ GlobalVariableTargetNode (location: (2,5)-(2,7))
+ │ │ └── name: :$b
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (2,0)-(2,1) = "("
+ │ ├── rparen_loc: (2,7)-(2,8) = ")"
+ │ ├── operator_loc: (2,9)-(2,10) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (2,11)-(2,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (2,12)-(2,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (2,15)-(2,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (2,11)-(2,12) = "["
+ │ └── closing_loc: (2,16)-(2,17) = "]"
+ ├── @ MultiWriteNode (location: (3,0)-(3,13))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ MultiTargetNode (location: (3,1)-(3,5))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ LocalVariableTargetNode (location: (3,2)-(3,3))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── rest:
+ │ │ │ │ @ ImplicitRestNode (location: (3,3)-(3,4))
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (3,1)-(3,2) = "("
+ │ │ │ └── rparen_loc: (3,4)-(3,5) = ")"
+ │ │ └── @ LocalVariableTargetNode (location: (3,7)-(3,8))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (3,0)-(3,1) = "("
+ │ ├── rparen_loc: (3,8)-(3,9) = ")"
+ │ ├── operator_loc: (3,10)-(3,11) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (3,12)-(3,13))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ MultiWriteNode (location: (4,0)-(4,9))
+ │ ├── lefts: (length: 0)
+ │ ├── rest:
+ │ │ @ SplatNode (location: (4,1)-(4,3))
+ │ │ ├── operator_loc: (4,1)-(4,2) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (4,2)-(4,3))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (4,0)-(4,1) = "("
+ │ ├── rparen_loc: (4,3)-(4,4) = ")"
+ │ ├── operator_loc: (4,5)-(4,6) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (4,7)-(4,9))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (4,7)-(4,8) = "["
+ │ └── closing_loc: (4,8)-(4,9) = "]"
+ ├── @ MultiWriteNode (location: (5,0)-(5,15))
+ │ ├── lefts: (length: 0)
+ │ ├── rest:
+ │ │ @ SplatNode (location: (5,1)-(5,5))
+ │ │ ├── operator_loc: (5,1)-(5,2) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (5,2)-(5,5))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (5,0)-(5,1) = "("
+ │ ├── rparen_loc: (5,5)-(5,6) = ")"
+ │ ├── operator_loc: (5,7)-(5,8) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (5,9)-(5,15))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (5,10)-(5,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (5,13)-(5,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (5,9)-(5,10) = "["
+ │ └── closing_loc: (5,14)-(5,15) = "]"
+ ├── @ MultiWriteNode (location: (6,0)-(6,19))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ ClassVariableTargetNode (location: (6,1)-(6,4))
+ │ │ │ └── name: :@@a
+ │ │ └── @ ClassVariableTargetNode (location: (6,6)-(6,9))
+ │ │ └── name: :@@b
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (6,0)-(6,1) = "("
+ │ ├── rparen_loc: (6,9)-(6,10) = ")"
+ │ ├── operator_loc: (6,11)-(6,12) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (6,13)-(6,19))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (6,14)-(6,15))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (6,17)-(6,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (6,13)-(6,14) = "["
+ │ └── closing_loc: (6,18)-(6,19) = "]"
+ ├── @ MultiWriteNode (location: (7,0)-(7,17))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ InstanceVariableTargetNode (location: (7,1)-(7,3))
+ │ │ │ └── name: :@a
+ │ │ └── @ InstanceVariableTargetNode (location: (7,5)-(7,7))
+ │ │ └── name: :@b
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (7,0)-(7,1) = "("
+ │ ├── rparen_loc: (7,7)-(7,8) = ")"
+ │ ├── operator_loc: (7,9)-(7,10) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (7,11)-(7,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (7,12)-(7,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (7,15)-(7,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (7,11)-(7,12) = "["
+ │ └── closing_loc: (7,16)-(7,17) = "]"
+ ├── @ MultiWriteNode (location: (8,0)-(8,25))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (8,1)-(8,2))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ MultiTargetNode (location: (8,4)-(8,10))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (8,5)-(8,6))
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (8,8)-(8,9))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: (8,4)-(8,5) = "("
+ │ │ └── rparen_loc: (8,9)-(8,10) = ")"
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (8,0)-(8,1) = "("
+ │ ├── rparen_loc: (8,10)-(8,11) = ")"
+ │ ├── operator_loc: (8,12)-(8,13) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (8,14)-(8,25))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (8,15)-(8,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ ArrayNode (location: (8,18)-(8,24))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (8,19)-(8,20))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (8,22)-(8,23))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── opening_loc: (8,18)-(8,19) = "["
+ │ │ └── closing_loc: (8,23)-(8,24) = "]"
+ │ ├── opening_loc: (8,14)-(8,15) = "["
+ │ └── closing_loc: (8,24)-(8,25) = "]"
+ ├── @ MultiWriteNode (location: (9,0)-(9,15))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (9,1)-(9,2))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ SplatNode (location: (9,4)-(9,5))
+ │ │ ├── operator_loc: (9,4)-(9,5) = "*"
+ │ │ └── expression: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (9,0)-(9,1) = "("
+ │ ├── rparen_loc: (9,5)-(9,6) = ")"
+ │ ├── operator_loc: (9,7)-(9,8) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (9,9)-(9,15))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (9,10)-(9,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (9,13)-(9,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (9,9)-(9,10) = "["
+ │ └── closing_loc: (9,14)-(9,15) = "]"
+ ├── @ MultiWriteNode (location: (10,0)-(10,18))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (10,1)-(10,2))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ SplatNode (location: (10,4)-(10,8))
+ │ │ ├── operator_loc: (10,4)-(10,5) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (10,5)-(10,8))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (10,0)-(10,1) = "("
+ │ ├── rparen_loc: (10,8)-(10,9) = ")"
+ │ ├── operator_loc: (10,10)-(10,11) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (10,12)-(10,18))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (10,13)-(10,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (10,16)-(10,17))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (10,12)-(10,13) = "["
+ │ └── closing_loc: (10,17)-(10,18) = "]"
+ ├── @ MultiWriteNode (location: (11,0)-(11,15))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (11,1)-(11,2))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (11,4)-(11,5))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (11,0)-(11,1) = "("
+ │ ├── rparen_loc: (11,5)-(11,6) = ")"
+ │ ├── operator_loc: (11,7)-(11,8) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (11,9)-(11,15))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (11,10)-(11,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (11,13)-(11,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (11,9)-(11,10) = "["
+ │ └── closing_loc: (11,14)-(11,15) = "]"
+ ├── @ MultiWriteNode (location: (12,0)-(12,12))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (12,1)-(12,2))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (12,4)-(12,5))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (12,0)-(12,1) = "("
+ │ ├── rparen_loc: (12,5)-(12,6) = ")"
+ │ ├── operator_loc: (12,7)-(12,8) = "="
+ │ └── value:
+ │ @ LocalVariableReadNode (location: (12,9)-(12,12))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── @ MultiWriteNode (location: (13,0)-(13,10))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (13,1)-(13,2))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ ImplicitRestNode (location: (13,2)-(13,3))
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (13,0)-(13,1) = "("
+ │ ├── rparen_loc: (13,3)-(13,4) = ")"
+ │ ├── operator_loc: (13,5)-(13,6) = "="
+ │ └── value:
+ │ @ LocalVariableReadNode (location: (13,7)-(13,10))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── @ MultiWriteNode (location: (14,0)-(14,23))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ CallTargetNode (location: (14,1)-(14,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ LocalVariableReadNode (location: (14,1)-(14,2))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── call_operator_loc: (14,2)-(14,3) = "."
+ │ │ │ ├── name: :foo=
+ │ │ │ └── message_loc: (14,3)-(14,6) = "foo"
+ │ │ └── @ CallTargetNode (location: (14,8)-(14,13))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ LocalVariableReadNode (location: (14,8)-(14,9))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── call_operator_loc: (14,9)-(14,10) = "."
+ │ │ ├── name: :bar=
+ │ │ └── message_loc: (14,10)-(14,13) = "bar"
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (14,0)-(14,1) = "("
+ │ ├── rparen_loc: (14,13)-(14,14) = ")"
+ │ ├── operator_loc: (14,15)-(14,16) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (14,17)-(14,23))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (14,18)-(14,19))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (14,21)-(14,22))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (14,17)-(14,18) = "["
+ │ └── closing_loc: (14,22)-(14,23) = "]"
+ ├── @ MultiWriteNode (location: (15,0)-(15,24))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ IndexTargetNode (location: (15,1)-(15,8))
+ │ │ │ ├── flags: attribute_write
+ │ │ │ ├── receiver:
+ │ │ │ │ @ LocalVariableReadNode (location: (15,1)-(15,2))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── opening_loc: (15,2)-(15,3) = "["
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (15,3)-(15,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ SplatNode (location: (15,3)-(15,7))
+ │ │ │ │ ├── operator_loc: (15,3)-(15,4) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ LocalVariableReadNode (location: (15,4)-(15,7))
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: (15,7)-(15,8) = "]"
+ │ │ │ └── block: ∅
+ │ │ └── @ IndexTargetNode (location: (15,10)-(15,14))
+ │ │ ├── flags: attribute_write
+ │ │ ├── receiver:
+ │ │ │ @ LocalVariableReadNode (location: (15,10)-(15,11))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (15,11)-(15,12) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (15,12)-(15,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (15,12)-(15,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: (15,13)-(15,14) = "]"
+ │ │ └── block: ∅
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (15,0)-(15,1) = "("
+ │ ├── rparen_loc: (15,14)-(15,15) = ")"
+ │ ├── operator_loc: (15,16)-(15,17) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (15,18)-(15,24))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (15,19)-(15,20))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (15,22)-(15,23))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (15,18)-(15,19) = "["
+ │ └── closing_loc: (15,23)-(15,24) = "]"
+ ├── @ MultiWriteNode (location: (16,0)-(16,21))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ IndexTargetNode (location: (16,1)-(16,5))
+ │ │ │ ├── flags: attribute_write
+ │ │ │ ├── receiver:
+ │ │ │ │ @ LocalVariableReadNode (location: (16,1)-(16,2))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── opening_loc: (16,2)-(16,3) = "["
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (16,3)-(16,4))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (16,3)-(16,4))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 0
+ │ │ │ ├── closing_loc: (16,4)-(16,5) = "]"
+ │ │ │ └── block: ∅
+ │ │ └── @ IndexTargetNode (location: (16,7)-(16,11))
+ │ │ ├── flags: attribute_write
+ │ │ ├── receiver:
+ │ │ │ @ LocalVariableReadNode (location: (16,7)-(16,8))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (16,8)-(16,9) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (16,9)-(16,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (16,9)-(16,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: (16,10)-(16,11) = "]"
+ │ │ └── block: ∅
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (16,0)-(16,1) = "("
+ │ ├── rparen_loc: (16,11)-(16,12) = ")"
+ │ ├── operator_loc: (16,13)-(16,14) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (16,15)-(16,21))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (16,16)-(16,17))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (16,19)-(16,20))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (16,15)-(16,16) = "["
+ │ └── closing_loc: (16,20)-(16,21) = "]"
+ ├── @ MultiWriteNode (location: (17,0)-(17,12))
+ │ ├── lefts: (length: 0)
+ │ ├── rest:
+ │ │ @ SplatNode (location: (17,1)-(17,7))
+ │ │ ├── operator_loc: (17,1)-(17,2) = "*"
+ │ │ └── expression:
+ │ │ @ CallTargetNode (location: (17,2)-(17,7))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ LocalVariableReadNode (location: (17,2)-(17,3))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ ├── call_operator_loc: (17,3)-(17,4) = "."
+ │ │ ├── name: :foo=
+ │ │ └── message_loc: (17,4)-(17,7) = "foo"
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (17,0)-(17,1) = "("
+ │ ├── rparen_loc: (17,7)-(17,8) = ")"
+ │ ├── operator_loc: (17,9)-(17,10) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (17,11)-(17,12))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ ConstantPathWriteNode (location: (18,0)-(18,13))
+ │ ├── target:
+ │ │ @ ConstantPathNode (location: (18,0)-(18,5))
+ │ │ ├── parent: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (18,2)-(18,5))
+ │ │ │ └── name: :Foo
+ │ │ └── delimiter_loc: (18,0)-(18,2) = "::"
+ │ ├── 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) = "::"
+ ├── @ ClassVariableWriteNode (location: (19,0)-(19,7))
+ │ ├── name: :@@a
+ │ ├── name_loc: (19,0)-(19,3) = "@@a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (19,6)-(19,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (19,4)-(19,5) = "="
+ ├── @ InstanceVariableWriteNode (location: (20,0)-(20,6))
+ │ ├── name: :@a
+ │ ├── name_loc: (20,0)-(20,2) = "@a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (20,5)-(20,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (20,3)-(20,4) = "="
+ ├── @ ConstantWriteNode (location: (21,0)-(21,9))
+ │ ├── name: :CONST
+ │ ├── name_loc: (21,0)-(21,5) = "CONST"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (21,8)-(21,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (21,6)-(21,7) = "="
+ ├── @ ConstantPathWriteNode (location: (22,0)-(22,23))
+ │ ├── target:
+ │ │ @ ConstantPathNode (location: (22,0)-(22,19))
+ │ │ ├── parent:
+ │ │ │ @ ConstantPathNode (location: (22,0)-(22,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) = "::"
+ │ ├── operator_loc: (22,20)-(22,21) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (22,22)-(22,23))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ LocalVariableWriteNode (location: (23,0)-(23,16))
+ │ ├── name: :a
+ │ ├── depth: 0
+ │ ├── name_loc: (23,0)-(23,1) = "a"
+ │ ├── value:
+ │ │ @ ParenthesesNode (location: (23,4)-(23,16))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (23,5)-(23,15))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ MultiWriteNode (location: (23,5)-(23,15))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ LocalVariableTargetNode (location: (23,6)-(23,7))
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── @ LocalVariableTargetNode (location: (23,9)-(23,10))
+ │ │ │ │ ├── name: :c
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (23,5)-(23,6) = "("
+ │ │ │ ├── rparen_loc: (23,10)-(23,11) = ")"
+ │ │ │ ├── operator_loc: (23,12)-(23,13) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (23,14)-(23,15))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (23,4)-(23,5) = "("
+ │ │ └── closing_loc: (23,15)-(23,16) = ")"
+ │ └── operator_loc: (23,2)-(23,3) = "="
+ ├── @ LocalVariableWriteNode (location: (24,0)-(24,5))
+ │ ├── name: :a
+ │ ├── depth: 0
+ │ ├── name_loc: (24,0)-(24,1) = "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (24,4)-(24,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (24,2)-(24,3) = "="
+ ├── @ LocalVariableWriteNode (location: (25,0)-(25,11))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (25,0)-(25,3) = "foo"
+ │ ├── value:
+ │ │ @ CallNode (location: (25,6)-(25,11))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (25,6)-(25,9) = "foo"
+ │ │ ├── opening_loc: (25,9)-(25,10) = "("
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: (25,10)-(25,11) = ")"
+ │ │ └── block: ∅
+ │ └── operator_loc: (25,4)-(25,5) = "="
+ ├── @ CallNode (location: (26,0)-(26,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (26,0)-(26,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (26,3)-(26,4) = "."
+ │ ├── name: :[]=
+ │ ├── message_loc: (26,4)-(26,7) = "[]="
+ │ ├── opening_loc: (26,7)-(26,8) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (26,8)-(26,9) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (27,0)-(27,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (27,0)-(27,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (27,3)-(27,4) = "."
+ │ ├── name: :[]=
+ │ ├── message_loc: (27,4)-(27,7) = "[]="
+ │ ├── opening_loc: (27,7)-(27,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,8)-(27,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (27,8)-(27,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (27,11)-(27,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: (27,12)-(27,13) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (28,0)-(28,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (28,0)-(28,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (28,3)-(28,4) = "."
+ │ ├── name: :[]=
+ │ ├── message_loc: (28,4)-(28,7) = "[]="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (28,7)-(28,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ TrueNode (location: (28,7)-(28,11))
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (29,0)-(29,19))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (29,0)-(29,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (29,3)-(29,11) = "[*index]"
+ │ ├── opening_loc: (29,3)-(29,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (29,4)-(29,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SplatNode (location: (29,4)-(29,10))
+ │ │ │ ├── operator_loc: (29,4)-(29,5) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (29,5)-(29,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :index
+ │ │ │ ├── message_loc: (29,5)-(29,10) = "index"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (29,14)-(29,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :value
+ │ │ ├── message_loc: (29,14)-(29,19) = "value"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (29,10)-(29,11) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (30,0)-(30,17))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (30,0)-(30,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (30,3)-(30,9) = "[1..2]"
+ │ ├── opening_loc: (30,3)-(30,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (30,4)-(30,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ RangeNode (location: (30,4)-(30,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── left:
+ │ │ │ │ @ IntegerNode (location: (30,4)-(30,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── right:
+ │ │ │ │ @ IntegerNode (location: (30,7)-(30,8))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── operator_loc: (30,5)-(30,7) = ".."
+ │ │ └── @ CallNode (location: (30,12)-(30,17))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :value
+ │ │ ├── message_loc: (30,12)-(30,17) = "value"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (30,8)-(30,9) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (31,0)-(31,9))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (31,0)-(31,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (31,3)-(31,5) = "[]"
+ │ ├── opening_loc: (31,3)-(31,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,8)-(31,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (31,8)-(31,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: (31,4)-(31,5) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (32,0)-(32,17))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (32,0)-(32,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (32,3)-(32,9) = "[a, b]"
+ │ ├── opening_loc: (32,3)-(32,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (32,4)-(32,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ LocalVariableReadNode (location: (32,4)-(32,5))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── @ LocalVariableReadNode (location: (32,7)-(32,8))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ └── @ CallNode (location: (32,12)-(32,17))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :value
+ │ │ ├── message_loc: (32,12)-(32,17) = "value"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (32,8)-(32,9) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (33,0)-(33,18))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (33,0)-(33,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (33,3)-(33,10) = "[index]"
+ │ ├── opening_loc: (33,3)-(33,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (33,4)-(33,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (33,4)-(33,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :index
+ │ │ │ ├── message_loc: (33,4)-(33,9) = "index"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (33,13)-(33,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :value
+ │ │ ├── message_loc: (33,13)-(33,18) = "value"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (33,9)-(33,10) = "]"
+ │ └── block: ∅
+ ├── @ LocalVariableWriteNode (location: (34,0)-(34,7))
+ │ ├── name: :x
+ │ ├── depth: 0
+ │ ├── name_loc: (34,0)-(34,1) = "x"
+ │ ├── value:
+ │ │ @ StringNode (location: (34,4)-(34,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (34,4)-(34,6) = "%("
+ │ │ ├── content_loc: (34,6)-(34,6) = ""
+ │ │ ├── closing_loc: (34,6)-(34,7) = ")"
+ │ │ └── unescaped: ""
+ │ └── operator_loc: (34,2)-(34,3) = "="
+ ├── @ CallNode (location: (35,0)-(35,7))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (35,0)-(35,1))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (35,1)-(35,2) = "."
+ │ ├── name: :x=
+ │ ├── message_loc: (35,2)-(35,3) = "x"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,4)-(35,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (35,4)-(35,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (35,4)-(35,6) = "%("
+ │ │ ├── content_loc: (35,6)-(35,6) = ""
+ │ │ ├── closing_loc: (35,6)-(35,7) = ")"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (36,0)-(36,12))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (36,0)-(36,1))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (36,1)-(36,6) = "[%()]"
+ │ ├── opening_loc: (36,1)-(36,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (36,2)-(36,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ StringNode (location: (36,2)-(36,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (36,2)-(36,4) = "%("
+ │ │ │ ├── content_loc: (36,4)-(36,4) = ""
+ │ │ │ ├── closing_loc: (36,4)-(36,5) = ")"
+ │ │ │ └── unescaped: ""
+ │ │ └── @ CallNode (location: (36,9)-(36,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (36,9)-(36,12) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (36,5)-(36,6) = "]"
+ │ └── block: ∅
+ ├── @ IndexOrWriteNode (location: (37,0)-(37,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (37,0)-(37,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (37,1)-(37,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (37,2)-(37,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (37,2)-(37,5))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (37,2)-(37,4) = "%("
+ │ │ ├── content_loc: (37,4)-(37,4) = ""
+ │ │ ├── closing_loc: (37,4)-(37,5) = ")"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: (37,5)-(37,6) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (37,7)-(37,10) = "||="
+ │ └── value:
+ │ @ CallNode (location: (37,11)-(37,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (37,11)-(37,14) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ InstanceVariableOrWriteNode (location: (38,0)-(38,10))
+ │ ├── name: :@a
+ │ ├── name_loc: (38,0)-(38,2) = "@a"
+ │ ├── operator_loc: (38,3)-(38,6) = "||="
+ │ └── value:
+ │ @ StringNode (location: (38,7)-(38,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (38,7)-(38,9) = "%("
+ │ ├── content_loc: (38,9)-(38,9) = ""
+ │ ├── closing_loc: (38,9)-(38,10) = ")"
+ │ └── unescaped: ""
+ ├── @ LocalVariableWriteNode (location: (39,0)-(39,14))
+ │ ├── name: :x
+ │ ├── depth: 0
+ │ ├── name_loc: (39,0)-(39,1) = "x"
+ │ ├── value:
+ │ │ @ InterpolatedStringNode (location: (39,4)-(39,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (39,4)-(39,14) = "<<-HEREDOC"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (40,0)-(40,2))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (40,0)-(40,2) = " "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " "
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (40,2)-(40,5))
+ │ │ │ │ ├── opening_loc: (40,2)-(40,4) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (40,4)-(40,5) = "}"
+ │ │ │ └── @ StringNode (location: (40,5)-(41,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (40,5)-(41,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (41,0)-(42,0) = "HEREDOC\n"
+ │ └── operator_loc: (39,2)-(39,3) = "="
+ ├── @ CallNode (location: (42,0)-(42,14))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (42,0)-(42,1))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (42,1)-(42,2) = "."
+ │ ├── name: :x=
+ │ ├── message_loc: (42,2)-(42,3) = "x"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (42,4)-(42,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (42,4)-(42,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (42,4)-(42,14) = "<<-HEREDOC"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (43,0)-(43,2))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (43,0)-(43,2) = " "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " "
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (43,2)-(43,5))
+ │ │ │ │ ├── opening_loc: (43,2)-(43,4) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (43,4)-(43,5) = "}"
+ │ │ │ └── @ StringNode (location: (43,5)-(44,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (43,5)-(44,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (44,0)-(45,0) = "HEREDOC\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (45,0)-(45,16))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (45,0)-(45,1))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (45,1)-(45,3) = "[]"
+ │ ├── opening_loc: (45,1)-(45,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (45,6)-(45,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (45,6)-(45,16))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (45,6)-(45,16) = "<<-HEREDOC"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (46,0)-(46,2))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (46,0)-(46,2) = " "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " "
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (46,2)-(46,5))
+ │ │ │ │ ├── opening_loc: (46,2)-(46,4) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (46,4)-(46,5) = "}"
+ │ │ │ └── @ StringNode (location: (46,5)-(47,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (46,5)-(47,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (47,0)-(48,0) = "HEREDOC\n"
+ │ ├── closing_loc: (45,2)-(45,3) = "]"
+ │ └── block: ∅
+ ├── @ IndexOrWriteNode (location: (48,0)-(48,21))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (48,0)-(48,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (48,1)-(48,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (48,2)-(48,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (48,2)-(48,12))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (48,2)-(48,12) = "<<-HEREDOC"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (49,0)-(49,2))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (49,0)-(49,2) = " "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " "
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (49,2)-(49,5))
+ │ │ │ │ ├── opening_loc: (49,2)-(49,4) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (49,4)-(49,5) = "}"
+ │ │ │ └── @ StringNode (location: (49,5)-(50,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (49,5)-(50,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (50,0)-(51,0) = "HEREDOC\n"
+ │ ├── closing_loc: (48,12)-(48,13) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (48,14)-(48,17) = "||="
+ │ └── value:
+ │ @ CallNode (location: (48,18)-(48,21))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (48,18)-(48,21) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ InstanceVariableOrWriteNode (location: (51,0)-(51,17))
+ ├── name: :@a
+ ├── name_loc: (51,0)-(51,2) = "@a"
+ ├── operator_loc: (51,3)-(51,6) = "||="
+ └── value:
+ @ InterpolatedStringNode (location: (51,7)-(51,17))
+ ├── flags: ∅
+ ├── opening_loc: (51,7)-(51,17) = "<<-HEREDOC"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (52,0)-(52,2))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (52,0)-(52,2) = " "
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " "
+ │ ├── @ EmbeddedStatementsNode (location: (52,2)-(52,5))
+ │ │ ├── opening_loc: (52,2)-(52,4) = "\#{"
+ │ │ ├── statements: ∅
+ │ │ └── closing_loc: (52,4)-(52,5) = "}"
+ │ └── @ StringNode (location: (52,5)-(53,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (52,5)-(53,0) = "\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\n"
+ └── closing_loc: (53,0)-(54,0) = "HEREDOC\n"
diff --git a/test/prism/snapshots/unparser/corpus/literal/block.txt b/test/prism/snapshots/unparser/corpus/literal/block.txt
new file mode 100644
index 0000000000..b4c86d0b04
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/block.txt
@@ -0,0 +1,1402 @@
+@ ProgramNode (location: (1,0)-(96,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(96,1))
+ └── body: (length: 30)
+ ├── @ CallNode (location: (1,0)-(2,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,4)-(2,1))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,4)-(1,5) = "{"
+ │ └── closing_loc: (2,0)-(2,1) = "}"
+ ├── @ CallNode (location: (3,0)-(4,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,4)-(4,1))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (3,6)-(3,9))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (3,7)-(3,8))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (3,7)-(3,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (3,6)-(3,7) = "|"
+ │ │ └── closing_loc: (3,8)-(3,9) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (3,4)-(3,5) = "{"
+ │ └── closing_loc: (4,0)-(4,1) = "}"
+ ├── @ CallNode (location: (5,0)-(6,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,4)-(6,1))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (5,6)-(5,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (5,7)-(5,9))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (5,7)-(5,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ ImplicitRestNode (location: (5,8)-(5,9))
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (5,6)-(5,7) = "|"
+ │ │ └── closing_loc: (5,9)-(5,10) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (5,4)-(5,5) = "{"
+ │ └── closing_loc: (6,0)-(6,1) = "}"
+ ├── @ CallNode (location: (7,0)-(8,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (7,4)-(8,1))
+ │ ├── locals: [:a, :x]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (7,6)-(7,13))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (7,7)-(7,9))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (7,7)-(7,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ ImplicitRestNode (location: (7,8)-(7,9))
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 1)
+ │ │ │ └── @ BlockLocalVariableNode (location: (7,11)-(7,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :x
+ │ │ ├── opening_loc: (7,6)-(7,7) = "|"
+ │ │ └── closing_loc: (7,12)-(7,13) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (7,4)-(7,5) = "{"
+ │ └── closing_loc: (8,0)-(8,1) = "}"
+ ├── @ CallNode (location: (9,0)-(10,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (9,0)-(9,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (9,4)-(10,1))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (9,6)-(9,12))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (9,7)-(9,11))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (9,7)-(9,8))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (9,10)-(9,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (9,6)-(9,7) = "|"
+ │ │ └── closing_loc: (9,11)-(9,12) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (9,4)-(9,5) = "{"
+ │ └── closing_loc: (10,0)-(10,1) = "}"
+ ├── @ CallNode (location: (11,0)-(13,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (11,0)-(11,3) = "foo"
+ │ ├── opening_loc: (11,3)-(11,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,4)-(11,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (11,4)-(11,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: (11,5)-(11,6) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (11,7)-(13,1))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (12,2)-(12,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (12,2)-(12,5))
+ │ ├── opening_loc: (11,7)-(11,8) = "{"
+ │ └── closing_loc: (13,0)-(13,1) = "}"
+ ├── @ CallNode (location: (14,0)-(16,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (14,0)-(14,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (14,4)-(16,1))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (14,6)-(14,13))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (14,7)-(14,12))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (14,7)-(14,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (14,10)-(14,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── name_loc: (14,11)-(14,12) = "b"
+ │ │ │ │ └── operator_loc: (14,10)-(14,11) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (14,6)-(14,7) = "|"
+ │ │ └── closing_loc: (14,12)-(14,13) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (15,2)-(15,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (15,2)-(15,5))
+ │ ├── opening_loc: (14,4)-(14,5) = "{"
+ │ └── closing_loc: (16,0)-(16,1) = "}"
+ ├── @ CallNode (location: (17,0)-(19,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (17,0)-(17,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (17,4)-(19,1))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (17,6)-(17,12))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (17,7)-(17,11))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (17,7)-(17,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (17,10)-(17,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: ∅
+ │ │ │ │ ├── name_loc: ∅
+ │ │ │ │ └── operator_loc: (17,10)-(17,11) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (17,6)-(17,7) = "|"
+ │ │ └── closing_loc: (17,11)-(17,12) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (18,2)-(18,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (18,2)-(18,5))
+ │ ├── opening_loc: (17,4)-(17,5) = "{"
+ │ └── closing_loc: (19,0)-(19,1) = "}"
+ ├── @ CallNode (location: (20,0)-(22,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (20,0)-(20,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (20,4)-(22,1))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (21,2)-(21,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (21,2)-(21,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (21,2)-(21,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (20,4)-(20,5) = "{"
+ │ └── closing_loc: (22,0)-(22,1) = "}"
+ ├── @ CallNode (location: (23,0)-(25,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (23,0)-(23,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (23,0)-(23,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (23,3)-(23,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (23,4)-(23,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (23,8)-(25,1))
+ │ ├── locals: [:a, :b, :c]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (23,10)-(23,21))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (23,11)-(23,20))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ MultiTargetNode (location: (23,11)-(23,17))
+ │ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (23,12)-(23,13))
+ │ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ │ └── name: :a
+ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (23,15)-(23,16))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :b
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ │ ├── lparen_loc: (23,11)-(23,12) = "("
+ │ │ │ │ │ └── rparen_loc: (23,16)-(23,17) = ")"
+ │ │ │ │ └── @ RequiredParameterNode (location: (23,19)-(23,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (23,10)-(23,11) = "|"
+ │ │ └── closing_loc: (23,20)-(23,21) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (24,2)-(24,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (24,2)-(24,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (24,2)-(24,3) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (23,8)-(23,9) = "{"
+ │ └── closing_loc: (25,0)-(25,1) = "}"
+ ├── @ CallNode (location: (26,0)-(27,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (26,0)-(26,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (26,0)-(26,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (26,3)-(26,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (26,4)-(26,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (26,8)-(27,1))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (26,10)-(26,17))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (26,11)-(26,13))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (26,11)-(26,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── name_loc: (26,12)-(26,13) = "a"
+ │ │ │ │ └── operator_loc: (26,11)-(26,12) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 1)
+ │ │ │ └── @ BlockLocalVariableNode (location: (26,15)-(26,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── opening_loc: (26,10)-(26,11) = "|"
+ │ │ └── closing_loc: (26,16)-(26,17) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (26,8)-(26,9) = "{"
+ │ └── closing_loc: (27,0)-(27,1) = "}"
+ ├── @ CallNode (location: (28,0)-(29,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (28,0)-(28,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (28,0)-(28,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (28,3)-(28,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (28,4)-(28,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (28,8)-(29,1))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (28,10)-(28,16))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (28,11)-(28,12))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (28,11)-(28,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 1)
+ │ │ │ └── @ BlockLocalVariableNode (location: (28,14)-(28,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── opening_loc: (28,10)-(28,11) = "|"
+ │ │ └── closing_loc: (28,15)-(28,16) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (28,8)-(28,9) = "{"
+ │ └── closing_loc: (29,0)-(29,1) = "}"
+ ├── @ CallNode (location: (30,0)-(31,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (30,0)-(30,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (30,0)-(30,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (30,3)-(30,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (30,4)-(30,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (30,8)-(31,1))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (30,10)-(30,18))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 2)
+ │ │ │ ├── @ BlockLocalVariableNode (location: (30,13)-(30,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ BlockLocalVariableNode (location: (30,16)-(30,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── opening_loc: (30,10)-(30,11) = "|"
+ │ │ └── closing_loc: (30,17)-(30,18) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (30,8)-(30,9) = "{"
+ │ └── closing_loc: (31,0)-(31,1) = "}"
+ ├── @ CallNode (location: (32,0)-(34,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (32,0)-(32,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (32,0)-(32,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (32,3)-(32,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (32,4)-(32,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (32,8)-(34,1))
+ │ ├── locals: []
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (32,10)-(32,13))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (32,11)-(32,12))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (32,11)-(32,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: ∅
+ │ │ │ │ ├── name_loc: ∅
+ │ │ │ │ └── operator_loc: (32,11)-(32,12) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (32,10)-(32,11) = "|"
+ │ │ └── closing_loc: (32,12)-(32,13) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (33,2)-(33,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (33,2)-(33,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (33,2)-(33,3) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (32,8)-(32,9) = "{"
+ │ └── closing_loc: (34,0)-(34,1) = "}"
+ ├── @ CallNode (location: (35,0)-(37,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (35,0)-(35,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (35,0)-(35,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (35,3)-(35,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (35,4)-(35,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (35,8)-(37,1))
+ │ ├── locals: []
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (35,10)-(35,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (35,11)-(35,14))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ MultiTargetNode (location: (35,11)-(35,14))
+ │ │ │ │ ├── lefts: (length: 0)
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ SplatNode (location: (35,12)-(35,13))
+ │ │ │ │ │ ├── operator_loc: (35,12)-(35,13) = "*"
+ │ │ │ │ │ └── expression: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (35,11)-(35,12) = "("
+ │ │ │ │ └── rparen_loc: (35,13)-(35,14) = ")"
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (35,10)-(35,11) = "|"
+ │ │ └── closing_loc: (35,14)-(35,15) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (36,2)-(36,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (36,2)-(36,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (36,2)-(36,3) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (35,8)-(35,9) = "{"
+ │ └── closing_loc: (37,0)-(37,1) = "}"
+ ├── @ CallNode (location: (38,0)-(40,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (38,0)-(38,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (38,0)-(38,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (38,3)-(38,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (38,4)-(38,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (38,8)-(40,1))
+ │ ├── locals: []
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (38,10)-(38,17))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (38,11)-(38,16))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ MultiTargetNode (location: (38,11)-(38,16))
+ │ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ │ └── @ MultiTargetNode (location: (38,12)-(38,15))
+ │ │ │ │ │ ├── lefts: (length: 0)
+ │ │ │ │ │ ├── rest:
+ │ │ │ │ │ │ @ SplatNode (location: (38,13)-(38,14))
+ │ │ │ │ │ │ ├── operator_loc: (38,13)-(38,14) = "*"
+ │ │ │ │ │ │ └── expression: ∅
+ │ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ │ ├── lparen_loc: (38,12)-(38,13) = "("
+ │ │ │ │ │ └── rparen_loc: (38,14)-(38,15) = ")"
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (38,11)-(38,12) = "("
+ │ │ │ │ └── rparen_loc: (38,15)-(38,16) = ")"
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (38,10)-(38,11) = "|"
+ │ │ └── closing_loc: (38,16)-(38,17) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (39,2)-(39,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (39,2)-(39,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (39,2)-(39,3) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (38,8)-(38,9) = "{"
+ │ └── closing_loc: (40,0)-(40,1) = "}"
+ ├── @ CallNode (location: (41,0)-(43,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (41,0)-(41,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (41,0)-(41,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (41,3)-(41,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (41,4)-(41,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (41,8)-(43,1))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (41,10)-(41,20))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (41,11)-(41,19))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ MultiTargetNode (location: (41,11)-(41,19))
+ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ ├── @ RequiredParameterNode (location: (41,12)-(41,13))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :a
+ │ │ │ │ │ └── @ MultiTargetNode (location: (41,15)-(41,18))
+ │ │ │ │ │ ├── lefts: (length: 0)
+ │ │ │ │ │ ├── rest:
+ │ │ │ │ │ │ @ SplatNode (location: (41,16)-(41,17))
+ │ │ │ │ │ │ ├── operator_loc: (41,16)-(41,17) = "*"
+ │ │ │ │ │ │ └── expression: ∅
+ │ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ │ ├── lparen_loc: (41,15)-(41,16) = "("
+ │ │ │ │ │ └── rparen_loc: (41,17)-(41,18) = ")"
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (41,11)-(41,12) = "("
+ │ │ │ │ └── rparen_loc: (41,18)-(41,19) = ")"
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (41,10)-(41,11) = "|"
+ │ │ └── closing_loc: (41,19)-(41,20) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (42,2)-(42,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (42,2)-(42,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (42,2)-(42,3) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (41,8)-(41,9) = "{"
+ │ └── closing_loc: (43,0)-(43,1) = "}"
+ ├── @ CallNode (location: (44,0)-(46,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (44,0)-(44,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (44,0)-(44,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (44,3)-(44,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (44,4)-(44,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (44,8)-(46,1))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (44,10)-(44,18))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (44,11)-(44,17))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ MultiTargetNode (location: (44,11)-(44,17))
+ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ ├── @ RequiredParameterNode (location: (44,12)-(44,13))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :a
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (44,15)-(44,16))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :b
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (44,11)-(44,12) = "("
+ │ │ │ │ └── rparen_loc: (44,16)-(44,17) = ")"
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (44,10)-(44,11) = "|"
+ │ │ └── closing_loc: (44,17)-(44,18) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (45,2)-(45,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (45,2)-(45,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (45,2)-(45,3) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (44,8)-(44,9) = "{"
+ │ └── closing_loc: (46,0)-(46,1) = "}"
+ ├── @ CallNode (location: (47,0)-(48,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (47,0)-(48,1))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (47,0)-(47,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (47,0)-(47,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (47,3)-(47,4) = "."
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (47,4)-(47,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (47,8)-(48,1))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (47,8)-(47,9) = "{"
+ │ │ └── closing_loc: (48,0)-(48,1) = "}"
+ │ ├── call_operator_loc: (48,1)-(48,2) = "."
+ │ ├── name: :baz
+ │ ├── message_loc: (48,2)-(48,5) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (49,0)-(51,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (49,0)-(49,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (49,2)-(51,3))
+ │ ├── locals: [:e]
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (49,2)-(51,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (50,0)-(50,21))
+ │ │ │ ├── keyword_loc: (50,0)-(50,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 1)
+ │ │ │ │ └── @ ConstantReadNode (location: (50,7)-(50,16))
+ │ │ │ │ └── name: :Exception
+ │ │ │ ├── operator_loc: (50,17)-(50,19) = "=>"
+ │ │ │ ├── reference:
+ │ │ │ │ @ LocalVariableTargetNode (location: (50,20)-(50,21))
+ │ │ │ │ ├── name: :e
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (51,0)-(51,3) = "end"
+ │ ├── opening_loc: (49,2)-(49,4) = "do"
+ │ └── closing_loc: (51,0)-(51,3) = "end"
+ ├── @ CallNode (location: (52,0)-(56,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (52,0)-(52,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (52,2)-(56,3))
+ │ ├── locals: [:bar]
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (52,2)-(56,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (53,2)-(53,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (53,2)-(53,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (53,2)-(53,5) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (54,0)-(55,5))
+ │ │ │ ├── keyword_loc: (54,0)-(54,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 1)
+ │ │ │ │ └── @ ConstantReadNode (location: (54,7)-(54,16))
+ │ │ │ │ └── name: :Exception
+ │ │ │ ├── operator_loc: (54,17)-(54,19) = "=>"
+ │ │ │ ├── reference:
+ │ │ │ │ @ LocalVariableTargetNode (location: (54,20)-(54,23))
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (55,2)-(55,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (55,2)-(55,5))
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── depth: 0
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (56,0)-(56,3) = "end"
+ │ ├── opening_loc: (52,2)-(52,4) = "do"
+ │ └── closing_loc: (56,0)-(56,3) = "end"
+ ├── @ CallNode (location: (57,0)-(61,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (57,0)-(57,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (57,2)-(61,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (57,2)-(61,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (58,2)-(58,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (58,2)-(58,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (58,2)-(58,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (59,0)-(60,5))
+ │ │ │ ├── keyword_loc: (59,0)-(59,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 2)
+ │ │ │ │ ├── @ ConstantReadNode (location: (59,7)-(59,16))
+ │ │ │ │ │ └── name: :SomeError
+ │ │ │ │ └── @ SplatNode (location: (59,18)-(59,22))
+ │ │ │ │ ├── operator_loc: (59,18)-(59,19) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ CallNode (location: (59,19)-(59,22))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (59,19)-(59,22) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (60,2)-(60,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (60,2)-(60,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (60,2)-(60,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (61,0)-(61,3) = "end"
+ │ ├── opening_loc: (57,2)-(57,4) = "do"
+ │ └── closing_loc: (61,0)-(61,3) = "end"
+ ├── @ CallNode (location: (62,0)-(66,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (62,0)-(62,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (62,2)-(66,3))
+ │ ├── locals: [:exception]
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (62,2)-(66,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (63,2)-(63,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (63,2)-(63,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (63,2)-(63,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (64,0)-(65,5))
+ │ │ │ ├── keyword_loc: (64,0)-(64,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 2)
+ │ │ │ │ ├── @ ConstantReadNode (location: (64,7)-(64,16))
+ │ │ │ │ │ └── name: :SomeError
+ │ │ │ │ └── @ SplatNode (location: (64,18)-(64,22))
+ │ │ │ │ ├── operator_loc: (64,18)-(64,19) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ CallNode (location: (64,19)-(64,22))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (64,19)-(64,22) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── operator_loc: (64,23)-(64,25) = "=>"
+ │ │ │ ├── reference:
+ │ │ │ │ @ LocalVariableTargetNode (location: (64,26)-(64,35))
+ │ │ │ │ ├── name: :exception
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (65,2)-(65,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (65,2)-(65,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (65,2)-(65,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (66,0)-(66,3) = "end"
+ │ ├── opening_loc: (62,2)-(62,4) = "do"
+ │ └── closing_loc: (66,0)-(66,3) = "end"
+ ├── @ CallNode (location: (67,0)-(71,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (67,0)-(67,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (67,2)-(71,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (67,2)-(71,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (68,2)-(68,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (68,2)-(68,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (68,2)-(68,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (69,0)-(70,5))
+ │ │ │ ├── keyword_loc: (69,0)-(69,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 1)
+ │ │ │ │ └── @ SplatNode (location: (69,7)-(69,11))
+ │ │ │ │ ├── operator_loc: (69,7)-(69,8) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ CallNode (location: (69,8)-(69,11))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (69,8)-(69,11) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (70,2)-(70,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (70,2)-(70,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (70,2)-(70,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (71,0)-(71,3) = "end"
+ │ ├── opening_loc: (67,2)-(67,4) = "do"
+ │ └── closing_loc: (71,0)-(71,3) = "end"
+ ├── @ CallNode (location: (72,0)-(75,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (72,0)-(72,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (72,2)-(75,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (72,2)-(75,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (73,2)-(73,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (73,2)-(73,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (73,2)-(73,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (74,0)-(74,16))
+ │ │ │ ├── keyword_loc: (74,0)-(74,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 1)
+ │ │ │ │ └── @ ConstantReadNode (location: (74,7)-(74,16))
+ │ │ │ │ └── name: :LoadError
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (75,0)-(75,3) = "end"
+ │ ├── opening_loc: (72,2)-(72,4) = "do"
+ │ └── closing_loc: (75,0)-(75,3) = "end"
+ ├── @ CallNode (location: (76,0)-(81,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (76,0)-(76,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (76,2)-(81,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (76,2)-(81,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (77,2)-(77,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (77,2)-(77,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (77,2)-(77,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (78,0)-(78,6))
+ │ │ │ ├── keyword_loc: (78,0)-(78,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause:
+ │ │ │ @ ElseNode (location: (79,0)-(81,3))
+ │ │ │ ├── else_keyword_loc: (79,0)-(79,4) = "else"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (80,2)-(80,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (80,2)-(80,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (80,2)-(80,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── end_keyword_loc: (81,0)-(81,3) = "end"
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (81,0)-(81,3) = "end"
+ │ ├── opening_loc: (76,2)-(76,4) = "do"
+ │ └── closing_loc: (81,0)-(81,3) = "end"
+ ├── @ CallNode (location: (82,0)-(86,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (82,0)-(82,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (82,2)-(86,3))
+ │ ├── locals: [:exception]
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (82,2)-(86,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (83,2)-(83,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (83,2)-(83,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (83,2)-(83,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (84,0)-(85,5))
+ │ │ │ ├── keyword_loc: (84,0)-(84,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 1)
+ │ │ │ │ └── @ SplatNode (location: (84,7)-(84,11))
+ │ │ │ │ ├── operator_loc: (84,7)-(84,8) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ CallNode (location: (84,8)-(84,11))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (84,8)-(84,11) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── operator_loc: (84,12)-(84,14) = "=>"
+ │ │ │ ├── reference:
+ │ │ │ │ @ LocalVariableTargetNode (location: (84,15)-(84,24))
+ │ │ │ │ ├── name: :exception
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (85,2)-(85,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (85,2)-(85,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (85,2)-(85,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (86,0)-(86,3) = "end"
+ │ ├── opening_loc: (82,2)-(82,4) = "do"
+ │ └── closing_loc: (86,0)-(86,3) = "end"
+ ├── @ CallNode (location: (87,0)-(89,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (87,0)-(87,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (87,2)-(89,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (87,2)-(89,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (88,0)-(89,3))
+ │ │ │ ├── ensure_keyword_loc: (88,0)-(88,6) = "ensure"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── end_keyword_loc: (89,0)-(89,3) = "end"
+ │ │ └── end_keyword_loc: (89,0)-(89,3) = "end"
+ │ ├── opening_loc: (87,2)-(87,4) = "do"
+ │ └── closing_loc: (89,0)-(89,3) = "end"
+ ├── @ CallNode (location: (90,0)-(93,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (90,0)-(90,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (90,2)-(93,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (90,2)-(93,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (91,0)-(91,6))
+ │ │ │ ├── keyword_loc: (91,0)-(91,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (92,0)-(93,3))
+ │ │ │ ├── ensure_keyword_loc: (92,0)-(92,6) = "ensure"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── end_keyword_loc: (93,0)-(93,3) = "end"
+ │ │ └── end_keyword_loc: (93,0)-(93,3) = "end"
+ │ ├── opening_loc: (90,2)-(90,4) = "do"
+ │ └── closing_loc: (93,0)-(93,3) = "end"
+ └── @ CallNode (location: (94,0)-(96,1))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :bar
+ ├── message_loc: (94,0)-(94,3) = "bar"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (94,4)-(96,1))
+ ├── locals: [:_1, :_2]
+ ├── parameters:
+ │ @ NumberedParametersNode (location: (94,4)-(96,1))
+ │ └── maximum: 2
+ ├── body:
+ │ @ StatementsNode (location: (95,2)-(95,9))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (95,2)-(95,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (95,2)-(95,4))
+ │ │ ├── name: :_1
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (95,5)-(95,6) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (95,7)-(95,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (95,7)-(95,9))
+ │ │ ├── name: :_2
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (94,4)-(94,5) = "{"
+ └── closing_loc: (96,0)-(96,1) = "}"
diff --git a/test/prism/snapshots/unparser/corpus/literal/case.txt b/test/prism/snapshots/unparser/corpus/literal/case.txt
new file mode 100644
index 0000000000..509caa55c8
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/case.txt
@@ -0,0 +1,446 @@
+@ ProgramNode (location: (1,0)-(37,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(37,3))
+ └── body: (length: 8)
+ ├── @ CaseNode (location: (1,0)-(6,3))
+ │ ├── predicate: ∅
+ │ ├── conditions: (length: 2)
+ │ │ ├── @ WhenNode (location: (2,0)-(3,5))
+ │ │ │ ├── keyword_loc: (2,0)-(2,4) = "when"
+ │ │ │ ├── conditions: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (2,5)-(2,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (2,5)-(2,8) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ └── statements:
+ │ │ │ @ StatementsNode (location: (3,2)-(3,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,2)-(3,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (3,2)-(3,5) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ WhenNode (location: (4,0)-(5,5))
+ │ │ ├── keyword_loc: (4,0)-(4,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ CallNode (location: (4,5)-(4,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (4,5)-(4,8) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (5,2)-(5,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,2)-(5,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (5,2)-(5,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ │ └── end_keyword_loc: (6,0)-(6,3) = "end"
+ ├── @ CaseNode (location: (7,0)-(11,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (7,5)-(7,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (7,5)-(7,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 2)
+ │ │ ├── @ WhenNode (location: (8,0)-(8,8))
+ │ │ │ ├── keyword_loc: (8,0)-(8,4) = "when"
+ │ │ │ ├── conditions: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (8,5)-(8,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (8,5)-(8,8) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ └── statements: ∅
+ │ │ └── @ WhenNode (location: (9,0)-(10,5))
+ │ │ ├── keyword_loc: (9,0)-(9,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ CallNode (location: (9,5)-(9,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (9,5)-(9,8) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (10,2)-(10,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (10,2)-(10,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (10,2)-(10,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (7,0)-(7,4) = "case"
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ CaseNode (location: (12,0)-(17,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (12,5)-(12,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (12,5)-(12,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 2)
+ │ │ ├── @ WhenNode (location: (13,0)-(14,5))
+ │ │ │ ├── keyword_loc: (13,0)-(13,4) = "when"
+ │ │ │ ├── conditions: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (13,5)-(13,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (13,5)-(13,8) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ └── statements:
+ │ │ │ @ StatementsNode (location: (14,2)-(14,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (14,2)-(14,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (14,2)-(14,5) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ WhenNode (location: (15,0)-(16,5))
+ │ │ ├── keyword_loc: (15,0)-(15,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ CallNode (location: (15,5)-(15,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (15,5)-(15,8) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (16,2)-(16,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (16,2)-(16,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (16,2)-(16,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (12,0)-(12,4) = "case"
+ │ └── end_keyword_loc: (17,0)-(17,3) = "end"
+ ├── @ CaseNode (location: (18,0)-(21,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (18,5)-(18,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (18,5)-(18,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (19,0)-(20,8))
+ │ │ ├── keyword_loc: (19,0)-(19,4) = "when"
+ │ │ ├── conditions: (length: 2)
+ │ │ │ ├── @ CallNode (location: (19,5)-(19,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (19,5)-(19,8) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── @ CallNode (location: (19,10)-(19,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (19,10)-(19,13) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (20,2)-(20,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (20,2)-(20,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (20,2)-(20,3) = ":"
+ │ │ ├── value_loc: (20,3)-(20,8) = "other"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "other"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (18,0)-(18,4) = "case"
+ │ └── end_keyword_loc: (21,0)-(21,3) = "end"
+ ├── @ CaseNode (location: (22,0)-(25,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (22,5)-(22,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (22,5)-(22,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (23,0)-(24,8))
+ │ │ ├── keyword_loc: (23,0)-(23,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ SplatNode (location: (23,5)-(23,9))
+ │ │ │ ├── operator_loc: (23,5)-(23,6) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (23,6)-(23,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (23,6)-(23,9) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (24,2)-(24,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (24,2)-(24,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (24,2)-(24,3) = ":"
+ │ │ ├── value_loc: (24,3)-(24,8) = "value"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "value"
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (22,0)-(22,4) = "case"
+ │ └── end_keyword_loc: (25,0)-(25,3) = "end"
+ ├── @ CaseNode (location: (26,0)-(31,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (26,5)-(26,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (26,5)-(26,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (27,0)-(28,5))
+ │ │ ├── keyword_loc: (27,0)-(27,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ CallNode (location: (27,5)-(27,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (27,5)-(27,8) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (28,2)-(28,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (28,2)-(28,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (28,2)-(28,5) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (29,0)-(31,3))
+ │ │ ├── else_keyword_loc: (29,0)-(29,4) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (30,2)-(30,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (30,2)-(30,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (30,2)-(30,3) = ":"
+ │ │ │ ├── value_loc: (30,3)-(30,6) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── end_keyword_loc: (31,0)-(31,3) = "end"
+ │ ├── case_keyword_loc: (26,0)-(26,4) = "case"
+ │ └── end_keyword_loc: (31,0)-(31,3) = "end"
+ ├── @ CaseNode (location: (32,0)-(34,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (32,5)-(32,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (32,5)-(32,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ WhenNode (location: (33,0)-(33,15))
+ │ │ ├── keyword_loc: (33,0)-(33,4) = "when"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ SplatNode (location: (33,5)-(33,15))
+ │ │ │ ├── operator_loc: (33,5)-(33,6) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (33,6)-(33,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (33,6)-(33,9))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (33,6)-(33,9) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :|
+ │ │ │ ├── message_loc: (33,10)-(33,11) = "|"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (33,12)-(33,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (33,12)-(33,15))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (33,12)-(33,15) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (32,0)-(32,4) = "case"
+ │ └── end_keyword_loc: (34,0)-(34,3) = "end"
+ └── @ CaseNode (location: (35,0)-(37,3))
+ ├── predicate:
+ │ @ CallNode (location: (35,5)-(35,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (35,5)-(35,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (36,0)-(36,15))
+ │ ├── keyword_loc: (36,0)-(36,4) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ SplatNode (location: (36,5)-(36,15))
+ │ │ ├── operator_loc: (36,5)-(36,6) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (36,6)-(36,15))
+ │ │ ├── flags: attribute_write
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (36,6)-(36,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (36,6)-(36,9) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (36,9)-(36,10) = "."
+ │ │ ├── name: :baz=
+ │ │ ├── message_loc: (36,10)-(36,13) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (36,14)-(36,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (36,14)-(36,15))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ └── statements: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (35,0)-(35,4) = "case"
+ └── end_keyword_loc: (37,0)-(37,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/class.txt b/test/prism/snapshots/unparser/corpus/literal/class.txt
new file mode 100644
index 0000000000..34eb03edb3
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/class.txt
@@ -0,0 +1,233 @@
+@ ProgramNode (location: (1,0)-(35,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(35,3))
+ └── body: (length: 10)
+ ├── @ ClassNode (location: (1,0)-(2,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (1,6)-(1,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (2,0)-(2,3) = "end"
+ │ └── name: :A
+ ├── @ SingletonClassNode (location: (4,0)-(5,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (4,0)-(4,5) = "class"
+ │ ├── operator_loc: (4,6)-(4,8) = "<<"
+ │ ├── expression:
+ │ │ @ CallNode (location: (4,9)-(4,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (4,9)-(4,10) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ ├── @ SingletonClassNode (location: (7,0)-(9,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (7,0)-(7,5) = "class"
+ │ ├── operator_loc: (7,6)-(7,8) = "<<"
+ │ ├── expression:
+ │ │ @ CallNode (location: (7,9)-(7,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (7,9)-(7,10) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (8,2)-(8,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (8,2)-(8,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (8,2)-(8,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ ├── @ ClassNode (location: (11,0)-(12,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (11,0)-(11,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (11,6)-(11,10))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (11,6)-(11,7))
+ │ │ │ └── name: :A
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (11,9)-(11,10))
+ │ │ │ └── name: :B
+ │ │ └── delimiter_loc: (11,7)-(11,9) = "::"
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (12,0)-(12,3) = "end"
+ │ └── name: :B
+ ├── @ ClassNode (location: (14,0)-(15,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (14,0)-(14,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (14,6)-(14,13))
+ │ │ ├── parent:
+ │ │ │ @ ConstantPathNode (location: (14,6)-(14,10))
+ │ │ │ ├── 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) = "::"
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (15,0)-(15,3) = "end"
+ │ └── name: :C
+ ├── @ ClassNode (location: (17,0)-(18,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (17,0)-(17,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (17,6)-(17,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: (17,8)-(17,9) = "<"
+ │ ├── superclass:
+ │ │ @ ConstantReadNode (location: (17,10)-(17,11))
+ │ │ └── name: :B
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (18,0)-(18,3) = "end"
+ │ └── name: :A
+ ├── @ ClassNode (location: (20,0)-(21,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (20,0)-(20,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (20,6)-(20,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: (20,8)-(20,9) = "<"
+ │ ├── superclass:
+ │ │ @ ConstantPathNode (location: (20,10)-(20,14))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (20,10)-(20,11))
+ │ │ │ └── name: :B
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (20,13)-(20,14))
+ │ │ │ └── name: :C
+ │ │ └── delimiter_loc: (20,11)-(20,13) = "::"
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (21,0)-(21,3) = "end"
+ │ └── name: :A
+ ├── @ ClassNode (location: (23,0)-(24,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (23,0)-(23,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (23,6)-(23,10))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (23,6)-(23,7))
+ │ │ │ └── name: :A
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (23,9)-(23,10))
+ │ │ │ └── name: :B
+ │ │ └── delimiter_loc: (23,7)-(23,9) = "::"
+ │ ├── 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) = "::"
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (24,0)-(24,3) = "end"
+ │ └── name: :B
+ ├── @ ClassNode (location: (26,0)-(32,3))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (26,0)-(26,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (26,6)-(26,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (27,2)-(31,5))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ CallNode (location: (27,2)-(27,16))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :include
+ │ │ │ ├── message_loc: (27,2)-(27,9) = "include"
+ │ │ │ ├── opening_loc: (27,9)-(27,10) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (27,10)-(27,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (27,10)-(27,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ ConstantReadNode (location: (27,10)-(27,11))
+ │ │ │ │ │ └── name: :B
+ │ │ │ │ ├── call_operator_loc: (27,11)-(27,12) = "."
+ │ │ │ │ ├── name: :new
+ │ │ │ │ ├── message_loc: (27,12)-(27,15) = "new"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (27,15)-(27,16) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ DefNode (location: (29,2)-(31,5))
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (29,6)-(29,9) = "foo"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (30,4)-(30,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (30,4)-(30,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (30,4)-(30,5) = ":"
+ │ │ │ ├── value_loc: (30,5)-(30,8) = "bar"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── locals: []
+ │ │ ├── def_keyword_loc: (29,2)-(29,5) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (31,2)-(31,5) = "end"
+ │ ├── end_keyword_loc: (32,0)-(32,3) = "end"
+ │ └── name: :A
+ └── @ ClassNode (location: (34,0)-(35,3))
+ ├── locals: []
+ ├── class_keyword_loc: (34,0)-(34,5) = "class"
+ ├── constant_path:
+ │ @ ConstantPathNode (location: (34,6)-(34,9))
+ │ ├── parent: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (34,8)-(34,9))
+ │ │ └── name: :A
+ │ └── delimiter_loc: (34,6)-(34,8) = "::"
+ ├── inheritance_operator_loc: ∅
+ ├── superclass: ∅
+ ├── body: ∅
+ ├── end_keyword_loc: (35,0)-(35,3) = "end"
+ └── name: :A
diff --git a/test/prism/snapshots/unparser/corpus/literal/def.txt b/test/prism/snapshots/unparser/corpus/literal/def.txt
new file mode 100644
index 0000000000..f3ef6c388e
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/def.txt
@@ -0,0 +1,1204 @@
+@ ProgramNode (location: (1,0)-(134,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(134,3))
+ └── body: (length: 30)
+ ├── @ DefNode (location: (1,0)-(9,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (1,0)-(9,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (2,2)-(2,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,2)-(2,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (2,2)-(2,3) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (3,0)-(4,3))
+ │ │ │ ├── keyword_loc: (3,0)-(3,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (4,2)-(4,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (4,2)-(4,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (4,2)-(4,3) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause:
+ │ │ │ @ ElseNode (location: (5,0)-(7,6))
+ │ │ │ ├── else_keyword_loc: (5,0)-(5,4) = "else"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (6,2)-(6,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (6,2)-(6,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (6,2)-(6,3) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── end_keyword_loc: (7,0)-(7,6) = "ensure"
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (7,0)-(9,3))
+ │ │ │ ├── ensure_keyword_loc: (7,0)-(7,6) = "ensure"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (8,2)-(8,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (8,2)-(8,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :d
+ │ │ │ │ ├── message_loc: (8,2)-(8,3) = "d"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ │ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ ├── @ DefNode (location: (11,0)-(19,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (11,4)-(11,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (11,0)-(19,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (12,2)-(12,12))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ RescueModifierNode (location: (12,2)-(12,12))
+ │ │ │ ├── expression:
+ │ │ │ │ @ CallNode (location: (12,2)-(12,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (12,2)-(12,3) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── keyword_loc: (12,4)-(12,10) = "rescue"
+ │ │ │ └── rescue_expression:
+ │ │ │ @ CallNode (location: (12,11)-(12,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (12,11)-(12,12) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (13,0)-(14,3))
+ │ │ │ ├── keyword_loc: (13,0)-(13,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (14,2)-(14,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (14,2)-(14,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (14,2)-(14,3) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause:
+ │ │ │ @ ElseNode (location: (15,0)-(17,6))
+ │ │ │ ├── else_keyword_loc: (15,0)-(15,4) = "else"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (16,2)-(16,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (16,2)-(16,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (16,2)-(16,3) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── end_keyword_loc: (17,0)-(17,6) = "ensure"
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (17,0)-(19,3))
+ │ │ │ ├── ensure_keyword_loc: (17,0)-(17,6) = "ensure"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (18,2)-(18,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (18,2)-(18,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :d
+ │ │ │ │ ├── message_loc: (18,2)-(18,3) = "d"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ │ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (11,0)-(11,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ ├── @ DefNode (location: (21,0)-(22,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (21,4)-(21,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (21,8)-(21,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ RequiredKeywordParameterNode (location: (21,8)-(21,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── name_loc: (21,8)-(21,12) = "bar:"
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (21,14)-(21,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ └── name_loc: (21,14)-(21,18) = "baz:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:bar, :baz]
+ │ ├── def_keyword_loc: (21,0)-(21,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (21,7)-(21,8) = "("
+ │ ├── rparen_loc: (21,18)-(21,19) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (22,0)-(22,3) = "end"
+ ├── @ DefNode (location: (24,0)-(25,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (24,4)-(24,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (24,0)-(24,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (25,0)-(25,3) = "end"
+ ├── @ DefNode (location: (27,0)-(29,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (27,4)-(27,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (28,2)-(28,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (28,2)-(28,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (28,2)-(28,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (27,0)-(27,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (29,0)-(29,3) = "end"
+ ├── @ DefNode (location: (31,0)-(37,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (31,4)-(31,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (31,0)-(37,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (32,2)-(32,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (32,2)-(32,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (32,2)-(32,5) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (33,0)-(34,5))
+ │ │ │ ├── keyword_loc: (33,0)-(33,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (34,2)-(34,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (34,2)-(34,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (34,2)-(34,5) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (35,0)-(37,3))
+ │ │ │ ├── ensure_keyword_loc: (35,0)-(35,6) = "ensure"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (36,2)-(36,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (36,2)-(36,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (36,2)-(36,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── end_keyword_loc: (37,0)-(37,3) = "end"
+ │ │ └── end_keyword_loc: (37,0)-(37,3) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (31,0)-(31,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (37,0)-(37,3) = "end"
+ ├── @ DefNode (location: (39,0)-(43,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (39,4)-(39,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (39,0)-(43,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (40,2)-(40,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (40,2)-(40,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (40,2)-(40,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause:
+ │ │ │ @ EnsureNode (location: (41,0)-(43,3))
+ │ │ │ ├── ensure_keyword_loc: (41,0)-(41,6) = "ensure"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (42,2)-(42,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (42,2)-(42,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (42,2)-(42,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── end_keyword_loc: (43,0)-(43,3) = "end"
+ │ │ └── end_keyword_loc: (43,0)-(43,3) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (39,0)-(39,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (43,0)-(43,3) = "end"
+ ├── @ DefNode (location: (45,0)-(49,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (45,4)-(45,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (45,0)-(49,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (46,2)-(46,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (46,2)-(46,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (46,2)-(46,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (47,0)-(48,5))
+ │ │ │ ├── keyword_loc: (47,0)-(47,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (48,2)-(48,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (48,2)-(48,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (48,2)-(48,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (49,0)-(49,3) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (45,0)-(45,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (49,0)-(49,3) = "end"
+ ├── @ DefNode (location: (51,0)-(53,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (51,4)-(51,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (51,8)-(51,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (51,8)-(51,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :bar
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (52,2)-(52,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (52,2)-(52,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (51,0)-(51,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (51,7)-(51,8) = "("
+ │ ├── rparen_loc: (51,11)-(51,12) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (53,0)-(53,3) = "end"
+ ├── @ DefNode (location: (55,0)-(57,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (55,4)-(55,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (55,8)-(55,16))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (55,8)-(55,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :bar
+ │ │ │ └── @ RequiredParameterNode (location: (55,13)-(55,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :baz
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (56,2)-(56,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (56,2)-(56,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar, :baz]
+ │ ├── def_keyword_loc: (55,0)-(55,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (55,7)-(55,8) = "("
+ │ ├── rparen_loc: (55,16)-(55,17) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (57,0)-(57,3) = "end"
+ ├── @ DefNode (location: (59,0)-(61,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (59,4)-(59,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (59,8)-(59,16))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (59,8)-(59,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (59,8)-(59,11) = "bar"
+ │ │ │ ├── operator_loc: (59,12)-(59,13) = "="
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (59,14)-(59,16))
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (59,14)-(59,15) = "("
+ │ │ │ └── closing_loc: (59,15)-(59,16) = ")"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (60,2)-(60,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (60,2)-(60,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (59,0)-(59,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (59,7)-(59,8) = "("
+ │ ├── rparen_loc: (59,16)-(59,17) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (61,0)-(61,3) = "end"
+ ├── @ DefNode (location: (63,0)-(64,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (63,4)-(63,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (63,8)-(63,24))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (63,8)-(63,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (63,8)-(63,11) = "bar"
+ │ │ │ ├── operator_loc: (63,12)-(63,13) = "="
+ │ │ │ └── value:
+ │ │ │ @ ParenthesesNode (location: (63,14)-(63,24))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (63,15)-(63,23))
+ │ │ │ │ └── body: (length: 2)
+ │ │ │ │ ├── @ CallNode (location: (63,15)-(63,18))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :baz
+ │ │ │ │ │ ├── message_loc: (63,15)-(63,18) = "baz"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── @ NilNode (location: (63,20)-(63,23))
+ │ │ │ ├── opening_loc: (63,14)-(63,15) = "("
+ │ │ │ └── closing_loc: (63,23)-(63,24) = ")"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (63,0)-(63,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (63,7)-(63,8) = "("
+ │ ├── rparen_loc: (63,24)-(63,25) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (64,0)-(64,3) = "end"
+ ├── @ DefNode (location: (66,0)-(68,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (66,4)-(66,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (66,8)-(66,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (66,8)-(66,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (66,8)-(66,11) = "bar"
+ │ │ │ ├── operator_loc: (66,12)-(66,13) = "="
+ │ │ │ └── value:
+ │ │ │ @ TrueNode (location: (66,14)-(66,18))
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (67,2)-(67,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (67,2)-(67,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (66,0)-(66,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (66,7)-(66,8) = "("
+ │ ├── rparen_loc: (66,18)-(66,19) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (68,0)-(68,3) = "end"
+ ├── @ DefNode (location: (70,0)-(72,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (70,4)-(70,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (70,8)-(70,23))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (70,8)-(70,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :bar
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (70,13)-(70,23))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── name_loc: (70,13)-(70,16) = "baz"
+ │ │ │ ├── operator_loc: (70,17)-(70,18) = "="
+ │ │ │ └── value:
+ │ │ │ @ TrueNode (location: (70,19)-(70,23))
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (71,2)-(71,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (71,2)-(71,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar, :baz]
+ │ ├── def_keyword_loc: (70,0)-(70,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (70,7)-(70,8) = "("
+ │ ├── rparen_loc: (70,23)-(70,24) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (72,0)-(72,3) = "end"
+ ├── @ DefNode (location: (74,0)-(75,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (74,4)-(74,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (74,8)-(74,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (74,8)-(74,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (74,8)-(74,12) = "bar:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (74,13)-(74,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (74,0)-(74,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (74,7)-(74,8) = "("
+ │ ├── rparen_loc: (74,14)-(74,15) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (75,0)-(75,3) = "end"
+ ├── @ DefNode (location: (77,0)-(78,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (77,4)-(77,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (77,8)-(77,16))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (77,8)-(77,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (77,8)-(77,12) = "bar:"
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (77,13)-(77,16))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (77,13)-(77,16) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (77,0)-(77,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (77,7)-(77,8) = "("
+ │ ├── rparen_loc: (77,16)-(77,17) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (78,0)-(78,3) = "end"
+ ├── @ DefNode (location: (80,0)-(81,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (80,4)-(80,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (80,8)-(80,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (80,8)-(80,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (80,8)-(80,12) = "bar:"
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (80,13)-(80,18))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (80,13)-(80,16) = "bar"
+ │ │ │ ├── opening_loc: (80,16)-(80,17) = "("
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: (80,17)-(80,18) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (80,0)-(80,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (80,7)-(80,8) = "("
+ │ ├── rparen_loc: (80,18)-(80,19) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (81,0)-(81,3) = "end"
+ ├── @ DefNode (location: (83,0)-(85,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (83,4)-(83,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (83,8)-(83,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (83,8)-(83,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (83,8)-(83,9) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (84,2)-(84,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (84,2)-(84,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (84,2)-(84,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (83,0)-(83,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (83,7)-(83,8) = "("
+ │ ├── rparen_loc: (83,9)-(83,10) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (85,0)-(85,3) = "end"
+ ├── @ DefNode (location: (87,0)-(89,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (87,4)-(87,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (87,8)-(87,12))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (87,8)-(87,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (87,9)-(87,12) = "bar"
+ │ │ │ └── operator_loc: (87,8)-(87,9) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (88,2)-(88,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (88,2)-(88,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar]
+ │ ├── def_keyword_loc: (87,0)-(87,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (87,7)-(87,8) = "("
+ │ ├── rparen_loc: (87,12)-(87,13) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (89,0)-(89,3) = "end"
+ ├── @ DefNode (location: (91,0)-(93,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (91,4)-(91,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (91,8)-(91,17))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (91,8)-(91,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :bar
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (91,13)-(91,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── name_loc: (91,14)-(91,17) = "baz"
+ │ │ │ └── operator_loc: (91,13)-(91,14) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (92,2)-(92,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (92,2)-(92,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar, :baz]
+ │ ├── def_keyword_loc: (91,0)-(91,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (91,7)-(91,8) = "("
+ │ ├── rparen_loc: (91,17)-(91,18) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (93,0)-(93,3) = "end"
+ ├── @ DefNode (location: (95,0)-(97,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (95,4)-(95,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (95,8)-(95,24))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (95,8)-(95,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── name_loc: (95,8)-(95,11) = "baz"
+ │ │ │ ├── operator_loc: (95,12)-(95,13) = "="
+ │ │ │ └── value:
+ │ │ │ @ TrueNode (location: (95,14)-(95,18))
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (95,20)-(95,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bor
+ │ │ │ ├── name_loc: (95,21)-(95,24) = "bor"
+ │ │ │ └── operator_loc: (95,20)-(95,21) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (96,2)-(96,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (96,2)-(96,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (96,2)-(96,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:baz, :bor]
+ │ ├── def_keyword_loc: (95,0)-(95,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (95,7)-(95,8) = "("
+ │ ├── rparen_loc: (95,24)-(95,25) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (97,0)-(97,3) = "end"
+ ├── @ DefNode (location: (99,0)-(101,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (99,4)-(99,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (99,8)-(99,32))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (99,8)-(99,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── name_loc: (99,8)-(99,11) = "baz"
+ │ │ │ ├── operator_loc: (99,12)-(99,13) = "="
+ │ │ │ └── value:
+ │ │ │ @ TrueNode (location: (99,14)-(99,18))
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (99,20)-(99,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bor
+ │ │ │ ├── name_loc: (99,21)-(99,24) = "bor"
+ │ │ │ └── operator_loc: (99,20)-(99,21) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (99,26)-(99,32))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :block
+ │ │ ├── name_loc: (99,27)-(99,32) = "block"
+ │ │ └── operator_loc: (99,26)-(99,27) = "&"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (100,2)-(100,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (100,2)-(100,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (100,2)-(100,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:baz, :bor, :block]
+ │ ├── def_keyword_loc: (99,0)-(99,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (99,7)-(99,8) = "("
+ │ ├── rparen_loc: (99,32)-(99,33) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (101,0)-(101,3) = "end"
+ ├── @ DefNode (location: (103,0)-(105,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (103,4)-(103,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (103,8)-(103,29))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (103,8)-(103,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :bar
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (103,13)-(103,23))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── name_loc: (103,13)-(103,16) = "baz"
+ │ │ │ ├── operator_loc: (103,17)-(103,18) = "="
+ │ │ │ └── value:
+ │ │ │ @ TrueNode (location: (103,19)-(103,23))
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (103,25)-(103,29))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bor
+ │ │ │ ├── name_loc: (103,26)-(103,29) = "bor"
+ │ │ │ └── operator_loc: (103,25)-(103,26) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (104,2)-(104,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (104,2)-(104,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar, :baz, :bor]
+ │ ├── def_keyword_loc: (103,0)-(103,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (103,7)-(103,8) = "("
+ │ ├── rparen_loc: (103,29)-(103,30) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (105,0)-(105,3) = "end"
+ ├── @ DefNode (location: (107,0)-(109,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (107,4)-(107,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (107,8)-(107,14))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (107,8)-(107,14))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :block
+ │ │ ├── name_loc: (107,9)-(107,14) = "block"
+ │ │ └── operator_loc: (107,8)-(107,9) = "&"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (108,2)-(108,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (108,2)-(108,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (108,2)-(108,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:block]
+ │ ├── def_keyword_loc: (107,0)-(107,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (107,7)-(107,8) = "("
+ │ ├── rparen_loc: (107,14)-(107,15) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (109,0)-(109,3) = "end"
+ ├── @ DefNode (location: (111,0)-(113,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (111,4)-(111,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (111,8)-(111,19))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (111,8)-(111,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :bar
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (111,13)-(111,19))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :block
+ │ │ ├── name_loc: (111,14)-(111,19) = "block"
+ │ │ └── operator_loc: (111,13)-(111,14) = "&"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (112,2)-(112,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (112,2)-(112,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── locals: [:bar, :block]
+ │ ├── def_keyword_loc: (111,0)-(111,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (111,7)-(111,8) = "("
+ │ ├── rparen_loc: (111,19)-(111,20) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (113,0)-(113,3) = "end"
+ ├── @ DefNode (location: (115,0)-(118,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (115,4)-(115,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (116,2)-(117,5))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ CallNode (location: (116,2)-(116,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (116,2)-(116,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (117,2)-(117,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (117,2)-(117,5) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (115,0)-(115,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (118,0)-(118,3) = "end"
+ ├── @ DefNode (location: (120,0)-(121,3))
+ │ ├── name: :f
+ │ ├── name_loc: (120,4)-(120,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (120,6)-(120,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (120,6)-(120,11))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ MultiTargetNode (location: (120,7)-(120,10))
+ │ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (120,8)-(120,9))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (120,7)-(120,8) = "("
+ │ │ │ │ └── rparen_loc: (120,9)-(120,10) = ")"
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (120,6)-(120,7) = "("
+ │ │ │ └── rparen_loc: (120,10)-(120,11) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (120,0)-(120,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (120,5)-(120,6) = "("
+ │ ├── rparen_loc: (120,11)-(120,12) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (121,0)-(121,3) = "end"
+ ├── @ DefNode (location: (123,0)-(124,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (123,4)-(123,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (123,8)-(123,26))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ RequiredKeywordParameterNode (location: (123,8)-(123,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── name_loc: (123,8)-(123,12) = "bar:"
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (123,14)-(123,26))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── name_loc: (123,14)-(123,18) = "baz:"
+ │ │ │ └── value:
+ │ │ │ @ StringNode (location: (123,19)-(123,26))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (123,19)-(123,20) = "\""
+ │ │ │ ├── content_loc: (123,20)-(123,25) = "value"
+ │ │ │ ├── closing_loc: (123,25)-(123,26) = "\""
+ │ │ │ └── unescaped: "value"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:bar, :baz]
+ │ ├── def_keyword_loc: (123,0)-(123,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (123,7)-(123,8) = "("
+ │ ├── rparen_loc: (123,26)-(123,27) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (124,0)-(124,3) = "end"
+ ├── @ DefNode (location: (126,0)-(130,3))
+ │ ├── name: :f
+ │ ├── name_loc: (126,4)-(126,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (127,2)-(127,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (127,2)-(127,12))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (127,2)-(127,12) = "<<-HEREDOC"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (128,0)-(128,4))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (128,0)-(128,4) = " "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " "
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (128,4)-(128,7))
+ │ │ │ │ ├── opening_loc: (128,4)-(128,6) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (128,6)-(128,7) = "}"
+ │ │ │ └── @ StringNode (location: (128,7)-(129,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (128,7)-(129,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (129,0)-(130,0) = " HEREDOC\n"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (126,0)-(126,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (130,0)-(130,3) = "end"
+ └── @ DefNode (location: (132,0)-(134,3))
+ ├── name: :f
+ ├── name_loc: (132,4)-(132,5) = "f"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (133,2)-(133,5))
+ │ └── body: (length: 1)
+ │ └── @ StringNode (location: (133,2)-(133,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (133,2)-(133,4) = "%("
+ │ ├── content_loc: (133,4)-(133,4) = ""
+ │ ├── closing_loc: (133,4)-(133,5) = ")"
+ │ └── unescaped: ""
+ ├── locals: []
+ ├── def_keyword_loc: (132,0)-(132,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (134,0)-(134,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/defined.txt b/test/prism/snapshots/unparser/corpus/literal/defined.txt
new file mode 100644
index 0000000000..89145ddcda
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/defined.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(3,27))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,27))
+ └── body: (length: 3)
+ ├── @ DefinedNode (location: (1,0)-(1,14))
+ │ ├── lparen_loc: (1,8)-(1,9) = "("
+ │ ├── value:
+ │ │ @ InstanceVariableReadNode (location: (1,9)-(1,13))
+ │ │ └── name: :@foo
+ │ ├── rparen_loc: (1,13)-(1,14) = ")"
+ │ └── keyword_loc: (1,0)-(1,8) = "defined?"
+ ├── @ DefinedNode (location: (2,0)-(2,13))
+ │ ├── lparen_loc: (2,8)-(2,9) = "("
+ │ ├── value:
+ │ │ @ ConstantReadNode (location: (2,9)-(2,12))
+ │ │ └── name: :Foo
+ │ ├── rparen_loc: (2,12)-(2,13) = ")"
+ │ └── keyword_loc: (2,0)-(2,8) = "defined?"
+ └── @ DefinedNode (location: (3,0)-(3,27))
+ ├── lparen_loc: (3,8)-(3,9) = "("
+ ├── value:
+ │ @ ParenthesesNode (location: (3,9)-(3,26))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,10)-(3,25))
+ │ │ └── body: (length: 1)
+ │ │ └── @ MultiWriteNode (location: (3,10)-(3,25))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (3,11)-(3,12))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (3,14)-(3,15))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: (3,10)-(3,11) = "("
+ │ │ ├── rparen_loc: (3,15)-(3,16) = ")"
+ │ │ ├── operator_loc: (3,17)-(3,18) = "="
+ │ │ └── value:
+ │ │ @ ArrayNode (location: (3,19)-(3,25))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (3,20)-(3,21))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (3,23)-(3,24))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: (3,19)-(3,20) = "["
+ │ │ └── closing_loc: (3,24)-(3,25) = "]"
+ │ ├── opening_loc: (3,9)-(3,10) = "("
+ │ └── closing_loc: (3,25)-(3,26) = ")"
+ ├── rparen_loc: (3,26)-(3,27) = ")"
+ └── keyword_loc: (3,0)-(3,8) = "defined?"
diff --git a/test/prism/snapshots/unparser/corpus/literal/defs.txt b/test/prism/snapshots/unparser/corpus/literal/defs.txt
new file mode 100644
index 0000000000..431843cc19
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/defs.txt
@@ -0,0 +1,360 @@
+@ ProgramNode (location: (1,0)-(40,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(40,3))
+ └── body: (length: 10)
+ ├── @ DefNode (location: (1,0)-(2,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,9)-(1,12) = "foo"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (1,4)-(1,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: (1,8)-(1,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (2,0)-(2,3) = "end"
+ ├── @ DefNode (location: (4,0)-(6,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (4,9)-(4,12) = "foo"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (4,4)-(4,8))
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,2)-(5,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,2)-(5,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (5,2)-(5,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (4,0)-(4,3) = "def"
+ │ ├── operator_loc: (4,8)-(4,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (6,0)-(6,3) = "end"
+ ├── @ DefNode (location: (8,0)-(11,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (8,9)-(8,12) = "foo"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (8,4)-(8,8))
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (9,2)-(10,5))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ CallNode (location: (9,2)-(9,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (9,2)-(9,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (10,2)-(10,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (10,2)-(10,5) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (8,0)-(8,3) = "def"
+ │ ├── operator_loc: (8,8)-(8,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ DefNode (location: (13,0)-(15,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (13,8)-(13,11) = "bar"
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (13,4)-(13,7))
+ │ │ └── name: :Foo
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (14,2)-(14,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (14,2)-(14,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (14,2)-(14,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (13,0)-(13,3) = "def"
+ │ ├── operator_loc: (13,7)-(13,8) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (15,0)-(15,3) = "end"
+ ├── @ DefNode (location: (17,0)-(20,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (18,3)-(18,6) = "bar"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (17,4)-(18,2))
+ │ │ ├── body:
+ │ │ │ @ CallNode (location: (17,5)-(18,1))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (17,5)-(17,8) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (17,9)-(18,1))
+ │ │ │ ├── locals: [:bar]
+ │ │ │ ├── parameters:
+ │ │ │ │ @ BlockParametersNode (location: (17,11)-(17,16))
+ │ │ │ │ ├── parameters:
+ │ │ │ │ │ @ ParametersNode (location: (17,12)-(17,15))
+ │ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (17,12)-(17,15))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :bar
+ │ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── locals: (length: 0)
+ │ │ │ │ ├── opening_loc: (17,11)-(17,12) = "|"
+ │ │ │ │ └── closing_loc: (17,15)-(17,16) = "|"
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (17,9)-(17,10) = "{"
+ │ │ │ └── closing_loc: (18,0)-(18,1) = "}"
+ │ │ ├── opening_loc: (17,4)-(17,5) = "("
+ │ │ └── closing_loc: (18,1)-(18,2) = ")"
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (19,2)-(19,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (19,2)-(19,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (19,2)-(19,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (17,0)-(17,3) = "def"
+ │ ├── operator_loc: (18,2)-(18,3) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (20,0)-(20,3) = "end"
+ ├── @ DefNode (location: (22,0)-(24,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (22,13)-(22,16) = "bar"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (22,4)-(22,12))
+ │ │ ├── body:
+ │ │ │ @ CallNode (location: (22,5)-(22,11))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (22,5)-(22,8) = "foo"
+ │ │ │ ├── opening_loc: (22,8)-(22,9) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (22,9)-(22,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (22,9)-(22,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── closing_loc: (22,10)-(22,11) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (22,4)-(22,5) = "("
+ │ │ └── closing_loc: (22,11)-(22,12) = ")"
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (23,2)-(23,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (23,2)-(23,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (23,2)-(23,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (22,0)-(22,3) = "def"
+ │ ├── operator_loc: (22,12)-(22,13) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (24,0)-(24,3) = "end"
+ ├── @ DefNode (location: (26,0)-(28,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (26,19)-(26,22) = "bar"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (26,4)-(26,18))
+ │ │ ├── body:
+ │ │ │ @ CallNode (location: (26,5)-(26,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ ConstantPathNode (location: (26,5)-(26,13))
+ │ │ │ │ ├── parent:
+ │ │ │ │ │ @ ConstantReadNode (location: (26,5)-(26,8))
+ │ │ │ │ │ └── name: :Foo
+ │ │ │ │ ├── child:
+ │ │ │ │ │ @ ConstantReadNode (location: (26,10)-(26,13))
+ │ │ │ │ │ └── name: :Bar
+ │ │ │ │ └── delimiter_loc: (26,8)-(26,10) = "::"
+ │ │ │ ├── call_operator_loc: (26,13)-(26,14) = "."
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (26,14)-(26,17) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (26,4)-(26,5) = "("
+ │ │ └── closing_loc: (26,17)-(26,18) = ")"
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (27,2)-(27,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (27,2)-(27,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (27,2)-(27,5) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (26,0)-(26,3) = "def"
+ │ ├── operator_loc: (26,18)-(26,19) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (28,0)-(28,3) = "end"
+ ├── @ DefNode (location: (30,0)-(32,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (30,15)-(30,18) = "bar"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (30,4)-(30,14))
+ │ │ ├── body:
+ │ │ │ @ ConstantPathNode (location: (30,5)-(30,13))
+ │ │ │ ├── parent:
+ │ │ │ │ @ ConstantReadNode (location: (30,5)-(30,8))
+ │ │ │ │ └── name: :Foo
+ │ │ │ ├── child:
+ │ │ │ │ @ ConstantReadNode (location: (30,10)-(30,13))
+ │ │ │ │ └── name: :Bar
+ │ │ │ └── delimiter_loc: (30,8)-(30,10) = "::"
+ │ │ ├── opening_loc: (30,4)-(30,5) = "("
+ │ │ └── closing_loc: (30,13)-(30,14) = ")"
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (31,2)-(31,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (31,2)-(31,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (31,2)-(31,5) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (30,0)-(30,3) = "def"
+ │ ├── operator_loc: (30,14)-(30,15) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (32,0)-(32,3) = "end"
+ ├── @ DefNode (location: (34,0)-(36,3))
+ │ ├── name: :bar
+ │ ├── name_loc: (34,8)-(34,11) = "bar"
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (34,4)-(34,7))
+ │ │ └── name: :Foo
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (35,2)-(35,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (35,2)-(35,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (35,2)-(35,5) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (34,0)-(34,3) = "def"
+ │ ├── operator_loc: (34,7)-(34,8) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (36,0)-(36,3) = "end"
+ └── @ DefNode (location: (38,0)-(40,3))
+ ├── name: :bar
+ ├── name_loc: (38,8)-(38,11) = "bar"
+ ├── receiver:
+ │ @ CallNode (location: (38,4)-(38,7))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (38,4)-(38,7) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (39,2)-(39,5))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (39,2)-(39,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :baz
+ │ ├── message_loc: (39,2)-(39,5) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (38,0)-(38,3) = "def"
+ ├── operator_loc: (38,7)-(38,8) = "."
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (40,0)-(40,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/dstr.txt b/test/prism/snapshots/unparser/corpus/literal/dstr.txt
new file mode 100644
index 0000000000..e60a309b34
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/dstr.txt
@@ -0,0 +1,352 @@
+@ ProgramNode (location: (1,0)-(37,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(37,1))
+ └── body: (length: 11)
+ ├── @ IfNode (location: (1,0)-(3,3))
+ │ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (1,3)-(1,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,2)-(2,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (2,2)-(2,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (2,2)-(2,3) = "\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (2,3)-(2,6))
+ │ │ │ │ ├── opening_loc: (2,3)-(2,5) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (2,5)-(2,6) = "}"
+ │ │ │ └── @ StringNode (location: (2,6)-(2,7))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (2,6)-(2,7) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── closing_loc: (2,7)-(2,8) = "\""
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ IfNode (location: (4,0)-(11,3))
+ │ ├── if_keyword_loc: (4,0)-(4,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (4,3)-(4,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,2)-(10,3))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ InterpolatedStringNode (location: (5,2)-(5,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (5,2)-(5,12) = "<<-HEREDOC"
+ │ │ │ ├── parts: (length: 3)
+ │ │ │ │ ├── @ StringNode (location: (6,0)-(7,0))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (6,0)-(7,0) = "a\n"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a\n"
+ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (7,0)-(7,3))
+ │ │ │ │ │ ├── opening_loc: (7,0)-(7,2) = "\#{"
+ │ │ │ │ │ ├── statements: ∅
+ │ │ │ │ │ └── closing_loc: (7,2)-(7,3) = "}"
+ │ │ │ │ └── @ StringNode (location: (7,3)-(9,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (7,3)-(9,0) = "a\nb\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "a\nb\n"
+ │ │ │ └── closing_loc: (9,0)-(10,0) = " HEREDOC\n"
+ │ │ └── @ CallNode (location: (10,2)-(10,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :x
+ │ │ ├── message_loc: (10,2)-(10,3) = "x"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ InterpolatedStringNode (location: (12,0)-(12,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (12,0)-(12,10) = "<<-HEREDOC"
+ │ ├── parts: (length: 7)
+ │ │ ├── @ StringNode (location: (13,0)-(14,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (13,0)-(14,0) = "\\\#{}\\\#{}\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\#{}\#{}\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (14,0)-(14,3))
+ │ │ │ ├── opening_loc: (14,0)-(14,2) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (14,2)-(14,3) = "}"
+ │ │ ├── @ StringNode (location: (14,3)-(15,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (14,3)-(15,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (15,0)-(15,3))
+ │ │ │ ├── opening_loc: (15,0)-(15,2) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (15,2)-(15,3) = "}"
+ │ │ ├── @ StringNode (location: (15,3)-(16,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (15,3)-(16,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (16,0)-(16,3))
+ │ │ │ ├── opening_loc: (16,0)-(16,2) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (16,2)-(16,3) = "}"
+ │ │ └── @ StringNode (location: (16,3)-(17,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (16,3)-(17,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (17,0)-(18,0) = "HEREDOC\n"
+ ├── @ RescueModifierNode (location: (18,0)-(18,21))
+ │ ├── expression:
+ │ │ @ InterpolatedStringNode (location: (18,0)-(18,10))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (18,0)-(18,10) = "<<-HEREDOC"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (19,0)-(19,3))
+ │ │ │ │ ├── opening_loc: (19,0)-(19,2) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (19,2)-(19,3) = "}"
+ │ │ │ └── @ StringNode (location: (19,3)-(21,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (19,3)-(21,0) = "\na\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\na\n"
+ │ │ └── closing_loc: (21,0)-(22,0) = "HEREDOC\n"
+ │ ├── keyword_loc: (18,11)-(18,17) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (18,18)-(18,21))
+ ├── @ InterpolatedStringNode (location: (22,0)-(22,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (22,0)-(22,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (22,1)-(22,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (22,1)-(22,2) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ EmbeddedVariableNode (location: (22,2)-(22,5))
+ │ │ ├── operator_loc: (22,2)-(22,3) = "#"
+ │ │ └── variable:
+ │ │ @ NumberedReferenceReadNode (location: (22,3)-(22,5))
+ │ │ └── number: 1
+ │ └── closing_loc: (22,5)-(22,6) = "\""
+ ├── @ InterpolatedStringNode (location: (23,0)-(23,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (23,0)-(23,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (23,1)-(23,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (23,1)-(23,2) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ EmbeddedVariableNode (location: (23,2)-(23,5))
+ │ │ ├── operator_loc: (23,2)-(23,3) = "#"
+ │ │ └── variable:
+ │ │ @ GlobalVariableReadNode (location: (23,3)-(23,5))
+ │ │ └── name: :$a
+ │ └── closing_loc: (23,5)-(23,6) = "\""
+ ├── @ InterpolatedStringNode (location: (24,0)-(24,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (24,0)-(24,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (24,1)-(24,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (24,1)-(24,2) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ EmbeddedVariableNode (location: (24,2)-(24,5))
+ │ │ ├── operator_loc: (24,2)-(24,3) = "#"
+ │ │ └── variable:
+ │ │ @ InstanceVariableReadNode (location: (24,3)-(24,5))
+ │ │ └── name: :@a
+ │ └── closing_loc: (24,5)-(24,6) = "\""
+ ├── @ InterpolatedStringNode (location: (25,0)-(25,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (25,0)-(25,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (25,1)-(25,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (25,1)-(25,2) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ EmbeddedVariableNode (location: (25,2)-(25,6))
+ │ │ ├── operator_loc: (25,2)-(25,3) = "#"
+ │ │ └── variable:
+ │ │ @ ClassVariableReadNode (location: (25,3)-(25,6))
+ │ │ └── name: :@@a
+ │ └── closing_loc: (25,6)-(25,7) = "\""
+ ├── @ IfNode (location: (26,0)-(30,3))
+ │ ├── if_keyword_loc: (26,0)-(26,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (26,3)-(26,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (27,2)-(27,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ReturnNode (location: (27,2)-(27,19))
+ │ │ ├── keyword_loc: (27,2)-(27,8) = "return"
+ │ │ └── arguments:
+ │ │ @ ArgumentsNode (location: (27,9)-(27,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (27,9)-(27,19))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (27,9)-(27,19) = "<<-HEREDOC"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (28,0)-(28,4))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (28,0)-(28,4) = " "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " "
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (28,4)-(28,9))
+ │ │ │ │ ├── opening_loc: (28,4)-(28,6) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (28,6)-(28,8))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (28,6)-(28,8))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 42
+ │ │ │ │ └── closing_loc: (28,8)-(28,9) = "}"
+ │ │ │ └── @ StringNode (location: (28,9)-(29,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (28,9)-(29,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (29,0)-(30,0) = " HEREDOC\n"
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (30,0)-(30,3) = "end"
+ ├── @ CallNode (location: (31,0)-(31,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (31,0)-(31,3) = "foo"
+ │ ├── opening_loc: (31,3)-(31,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,4)-(31,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (31,4)-(31,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (31,4)-(31,14) = "<<-HEREDOC"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (32,0)-(32,2))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (32,0)-(32,2) = " "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " "
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (32,2)-(32,8))
+ │ │ │ │ ├── opening_loc: (32,2)-(32,4) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (32,4)-(32,7))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (32,4)-(32,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :bar
+ │ │ │ │ │ ├── message_loc: (32,4)-(32,7) = "bar"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── closing_loc: (32,7)-(32,8) = "}"
+ │ │ │ └── @ StringNode (location: (32,8)-(33,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (32,8)-(33,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (33,0)-(34,0) = "HEREDOC\n"
+ │ ├── closing_loc: (31,14)-(31,15) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (34,0)-(37,1))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (34,0)-(34,3) = "foo"
+ ├── opening_loc: (34,3)-(34,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (34,4)-(34,14))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (34,4)-(34,14))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (34,4)-(34,14) = "<<-HEREDOC"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (35,0)-(35,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (35,0)-(35,2) = " "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " "
+ │ │ ├── @ EmbeddedStatementsNode (location: (35,2)-(35,8))
+ │ │ │ ├── opening_loc: (35,2)-(35,4) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (35,4)-(35,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (35,4)-(35,7))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (35,4)-(35,7) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (35,7)-(35,8) = "}"
+ │ │ └── @ StringNode (location: (35,8)-(36,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (35,8)-(36,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (36,0)-(37,0) = "HEREDOC\n"
+ ├── closing_loc: (34,14)-(34,15) = ")"
+ └── block:
+ @ BlockNode (location: (34,16)-(37,1))
+ ├── locals: [:x]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (34,18)-(34,21))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (34,19)-(34,20))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (34,19)-(34,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :x
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (34,18)-(34,19) = "|"
+ │ └── closing_loc: (34,20)-(34,21) = "|"
+ ├── body: ∅
+ ├── opening_loc: (34,16)-(34,17) = "{"
+ └── closing_loc: (37,0)-(37,1) = "}"
diff --git a/test/prism/snapshots/unparser/corpus/literal/empty.txt b/test/prism/snapshots/unparser/corpus/literal/empty.txt
new file mode 100644
index 0000000000..3a21ce5559
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/empty.txt
@@ -0,0 +1,5 @@
+@ ProgramNode (location: (1,0)-(1,0))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,0))
+ └── body: (length: 0)
diff --git a/test/prism/snapshots/unparser/corpus/literal/empty_begin.txt b/test/prism/snapshots/unparser/corpus/literal/empty_begin.txt
new file mode 100644
index 0000000000..838b4bf6f0
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/empty_begin.txt
@@ -0,0 +1,9 @@
+@ ProgramNode (location: (1,0)-(1,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,2))
+ └── body: (length: 1)
+ └── @ ParenthesesNode (location: (1,0)-(1,2))
+ ├── body: ∅
+ ├── opening_loc: (1,0)-(1,1) = "("
+ └── closing_loc: (1,1)-(1,2) = ")"
diff --git a/test/prism/snapshots/unparser/corpus/literal/flipflop.txt b/test/prism/snapshots/unparser/corpus/literal/flipflop.txt
new file mode 100644
index 0000000000..2d9f669e6f
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/flipflop.txt
@@ -0,0 +1,237 @@
+@ ProgramNode (location: (1,0)-(10,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(10,3))
+ └── body: (length: 4)
+ ├── @ IfNode (location: (1,0)-(3,3))
+ │ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ │ ├── predicate:
+ │ │ @ ParenthesesNode (location: (1,3)-(1,23))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,4)-(1,22))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ FlipFlopNode (location: (1,4)-(1,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── left:
+ │ │ │ │ @ ParenthesesNode (location: (1,4)-(1,12))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (1,5)-(1,11))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (1,5)-(1,11))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── receiver:
+ │ │ │ │ │ │ @ CallNode (location: (1,5)-(1,6))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :i
+ │ │ │ │ │ │ ├── message_loc: (1,5)-(1,6) = "i"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :==
+ │ │ │ │ │ ├── message_loc: (1,7)-(1,9) = "=="
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments:
+ │ │ │ │ │ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 4
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ │ │ │ └── closing_loc: (1,11)-(1,12) = ")"
+ │ │ │ ├── right:
+ │ │ │ │ @ ParenthesesNode (location: (1,14)-(1,22))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (1,15)-(1,21))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (1,15)-(1,21))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── receiver:
+ │ │ │ │ │ │ @ CallNode (location: (1,15)-(1,16))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :i
+ │ │ │ │ │ │ ├── message_loc: (1,15)-(1,16) = "i"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :==
+ │ │ │ │ │ ├── message_loc: (1,17)-(1,19) = "=="
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments:
+ │ │ │ │ │ │ @ ArgumentsNode (location: (1,20)-(1,21))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ │ └── @ IntegerNode (location: (1,20)-(1,21))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 4
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── opening_loc: (1,14)-(1,15) = "("
+ │ │ │ │ └── closing_loc: (1,21)-(1,22) = ")"
+ │ │ │ └── operator_loc: (1,12)-(1,14) = ".."
+ │ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ │ └── closing_loc: (1,22)-(1,23) = ")"
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,2)-(2,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,2)-(2,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (2,2)-(2,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ IfNode (location: (4,0)-(6,3))
+ │ ├── if_keyword_loc: (4,0)-(4,2) = "if"
+ │ ├── predicate:
+ │ │ @ ParenthesesNode (location: (4,3)-(4,24))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (4,4)-(4,23))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ FlipFlopNode (location: (4,4)-(4,23))
+ │ │ │ ├── flags: exclude_end
+ │ │ │ ├── left:
+ │ │ │ │ @ ParenthesesNode (location: (4,4)-(4,12))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (4,5)-(4,11))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (4,5)-(4,11))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── receiver:
+ │ │ │ │ │ │ @ CallNode (location: (4,5)-(4,6))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :i
+ │ │ │ │ │ │ ├── message_loc: (4,5)-(4,6) = "i"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :==
+ │ │ │ │ │ ├── message_loc: (4,7)-(4,9) = "=="
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments:
+ │ │ │ │ │ │ @ ArgumentsNode (location: (4,10)-(4,11))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ │ └── @ IntegerNode (location: (4,10)-(4,11))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 4
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── opening_loc: (4,4)-(4,5) = "("
+ │ │ │ │ └── closing_loc: (4,11)-(4,12) = ")"
+ │ │ │ ├── right:
+ │ │ │ │ @ ParenthesesNode (location: (4,15)-(4,23))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (4,16)-(4,22))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (4,16)-(4,22))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── receiver:
+ │ │ │ │ │ │ @ CallNode (location: (4,16)-(4,17))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :i
+ │ │ │ │ │ │ ├── message_loc: (4,16)-(4,17) = "i"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :==
+ │ │ │ │ │ ├── message_loc: (4,18)-(4,20) = "=="
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments:
+ │ │ │ │ │ │ @ ArgumentsNode (location: (4,21)-(4,22))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ │ └── @ IntegerNode (location: (4,21)-(4,22))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 4
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── opening_loc: (4,15)-(4,16) = "("
+ │ │ │ │ └── closing_loc: (4,22)-(4,23) = ")"
+ │ │ │ └── operator_loc: (4,12)-(4,15) = "..."
+ │ │ ├── opening_loc: (4,3)-(4,4) = "("
+ │ │ └── closing_loc: (4,23)-(4,24) = ")"
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,2)-(5,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,2)-(5,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (5,2)-(5,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (6,0)-(6,3) = "end"
+ ├── @ IfNode (location: (7,0)-(8,3))
+ │ ├── if_keyword_loc: (7,0)-(7,2) = "if"
+ │ ├── predicate:
+ │ │ @ FlipFlopNode (location: (7,3)-(7,8))
+ │ │ ├── flags: ∅
+ │ │ ├── left: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (7,5)-(7,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (7,5)-(7,8) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (7,3)-(7,5) = ".."
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (8,0)-(8,3) = "end"
+ └── @ IfNode (location: (9,0)-(10,3))
+ ├── if_keyword_loc: (9,0)-(9,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (9,3)-(9,8))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ CallNode (location: (9,3)-(9,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (9,3)-(9,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right: ∅
+ │ └── operator_loc: (9,6)-(9,8) = ".."
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (10,0)-(10,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/for.txt b/test/prism/snapshots/unparser/corpus/literal/for.txt
new file mode 100644
index 0000000000..660c6b73f3
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/for.txt
@@ -0,0 +1,171 @@
+@ ProgramNode (location: (1,0)-(12,3))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(12,3))
+ └── body: (length: 4)
+ ├── @ CallNode (location: (1,0)-(3,4))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,0)-(1,3) = "bar"
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(3,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ForNode (location: (1,4)-(3,3))
+ │ │ ├── index:
+ │ │ │ @ LocalVariableTargetNode (location: (1,8)-(1,9))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── collection:
+ │ │ │ @ CallNode (location: (1,13)-(1,16))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,13)-(1,16) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (2,2)-(2,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,2)-(2,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (2,2)-(2,5) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── for_keyword_loc: (1,4)-(1,7) = "for"
+ │ │ ├── in_keyword_loc: (1,10)-(1,12) = "in"
+ │ │ ├── do_keyword_loc: (1,17)-(1,19) = "do"
+ │ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ │ ├── closing_loc: (3,3)-(3,4) = ")"
+ │ └── block: ∅
+ ├── @ ForNode (location: (4,0)-(6,3))
+ │ ├── index:
+ │ │ @ LocalVariableTargetNode (location: (4,4)-(4,5))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── collection:
+ │ │ @ CallNode (location: (4,9)-(4,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (4,9)-(4,12) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,2)-(5,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,2)-(5,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (5,2)-(5,5) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── for_keyword_loc: (4,0)-(4,3) = "for"
+ │ ├── in_keyword_loc: (4,6)-(4,8) = "in"
+ │ ├── do_keyword_loc: (4,13)-(4,15) = "do"
+ │ └── end_keyword_loc: (6,0)-(6,3) = "end"
+ ├── @ ForNode (location: (7,0)-(9,3))
+ │ ├── index:
+ │ │ @ MultiTargetNode (location: (7,4)-(7,11))
+ │ │ ├── lefts: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (7,5)-(7,6))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (7,8)-(7,10))
+ │ │ │ ├── operator_loc: (7,8)-(7,9) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableTargetNode (location: (7,9)-(7,10))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: (7,4)-(7,5) = "("
+ │ │ └── rparen_loc: (7,10)-(7,11) = ")"
+ │ ├── collection:
+ │ │ @ CallNode (location: (7,15)-(7,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (7,15)-(7,18) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (8,2)-(8,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (8,2)-(8,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (8,2)-(8,5) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── for_keyword_loc: (7,0)-(7,3) = "for"
+ │ ├── in_keyword_loc: (7,12)-(7,14) = "in"
+ │ ├── do_keyword_loc: (7,19)-(7,21) = "do"
+ │ └── end_keyword_loc: (9,0)-(9,3) = "end"
+ └── @ ForNode (location: (10,0)-(12,3))
+ ├── index:
+ │ @ MultiTargetNode (location: (10,4)-(10,10))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (10,5)-(10,6))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (10,8)-(10,9))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (10,4)-(10,5) = "("
+ │ └── rparen_loc: (10,9)-(10,10) = ")"
+ ├── collection:
+ │ @ CallNode (location: (10,14)-(10,17))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (10,14)-(10,17) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (11,2)-(11,5))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (11,2)-(11,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :baz
+ │ ├── message_loc: (11,2)-(11,5) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── for_keyword_loc: (10,0)-(10,3) = "for"
+ ├── in_keyword_loc: (10,11)-(10,13) = "in"
+ ├── do_keyword_loc: (10,18)-(10,20) = "do"
+ └── end_keyword_loc: (12,0)-(12,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/hookexe.txt b/test/prism/snapshots/unparser/corpus/literal/hookexe.txt
new file mode 100644
index 0000000000..dabedbc588
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/hookexe.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(7,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,1))
+ └── body: (length: 3)
+ ├── @ PreExecutionNode (location: (1,0)-(3,1))
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,2)-(2,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,2)-(2,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (2,2)-(2,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,0)-(1,5) = "BEGIN"
+ │ ├── opening_loc: (1,6)-(1,7) = "{"
+ │ └── closing_loc: (3,0)-(3,1) = "}"
+ ├── @ CallNode (location: (4,0)-(4,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (4,0)-(4,3) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ PostExecutionNode (location: (5,0)-(7,1))
+ ├── statements:
+ │ @ StatementsNode (location: (6,2)-(6,5))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (6,2)-(6,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :baz
+ │ ├── message_loc: (6,2)-(6,5) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── keyword_loc: (5,0)-(5,3) = "END"
+ ├── opening_loc: (5,4)-(5,5) = "{"
+ └── closing_loc: (7,0)-(7,1) = "}"
diff --git a/test/prism/snapshots/unparser/corpus/literal/if.txt b/test/prism/snapshots/unparser/corpus/literal/if.txt
new file mode 100644
index 0000000000..00eeba179c
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/if.txt
@@ -0,0 +1,288 @@
+@ ProgramNode (location: (1,0)-(36,3))
+├── locals: [:foo, :pair]
+└── statements:
+ @ StatementsNode (location: (1,0)-(36,3))
+ └── body: (length: 10)
+ ├── @ IfNode (location: (1,0)-(3,3))
+ │ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ │ ├── predicate:
+ │ │ @ MatchLastLineNode (location: (1,3)-(1,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,3)-(1,4) = "/"
+ │ │ ├── content_loc: (1,4)-(1,7) = "foo"
+ │ │ ├── closing_loc: (1,7)-(1,8) = "/"
+ │ │ └── unescaped: "foo"
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (2,2)-(2,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,2)-(2,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (2,2)-(2,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ IfNode (location: (4,0)-(6,3))
+ │ ├── if_keyword_loc: (4,0)-(4,2) = "if"
+ │ ├── predicate:
+ │ │ @ IntegerNode (location: (4,3)-(4,4))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,2)-(5,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,2)-(5,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 9
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (6,0)-(6,3) = "end"
+ ├── @ IfNode (location: (7,0)-(11,3))
+ │ ├── if_keyword_loc: (7,0)-(7,2) = "if"
+ │ ├── predicate:
+ │ │ @ IntegerNode (location: (7,3)-(7,4))
+ │ │ ├── flags: decimal
+ │ │ └── value: 4
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (8,2)-(8,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (8,2)-(8,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 5
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (9,0)-(11,3))
+ │ │ ├── else_keyword_loc: (9,0)-(9,4) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (10,2)-(10,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (10,2)-(10,3))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 6
+ │ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ UnlessNode (location: (12,0)-(14,3))
+ │ ├── keyword_loc: (12,0)-(12,6) = "unless"
+ │ ├── predicate:
+ │ │ @ IntegerNode (location: (12,7)-(12,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (13,2)-(13,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (13,2)-(13,5))
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (14,0)-(14,3) = "end"
+ ├── @ UnlessNode (location: (15,0)-(17,3))
+ │ ├── keyword_loc: (15,0)-(15,6) = "unless"
+ │ ├── predicate:
+ │ │ @ IntegerNode (location: (15,7)-(15,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (16,2)-(16,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (16,2)-(16,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 9
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (17,0)-(17,3) = "end"
+ ├── @ IfNode (location: (18,0)-(19,3))
+ │ ├── if_keyword_loc: (18,0)-(18,2) = "if"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (18,3)-(18,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (18,3)-(18,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ ├── @ ModuleNode (location: (21,0)-(23,3))
+ │ ├── locals: [:foo]
+ │ ├── module_keyword_loc: (21,0)-(21,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (21,7)-(21,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (22,2)-(22,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IfNode (location: (22,2)-(22,18))
+ │ │ ├── if_keyword_loc: (22,12)-(22,14) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ LocalVariableReadNode (location: (22,15)-(22,18))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (22,2)-(22,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableWriteNode (location: (22,2)-(22,11))
+ │ │ │ ├── name: :foo
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (22,2)-(22,5) = "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (22,8)-(22,11))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (22,8)-(22,11) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (22,6)-(22,7) = "="
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── end_keyword_loc: (23,0)-(23,3) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (25,0)-(27,3))
+ │ ├── locals: [:foo]
+ │ ├── module_keyword_loc: (25,0)-(25,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (25,7)-(25,8))
+ │ │ └── name: :B
+ │ ├── body:
+ │ │ @ StatementsNode (location: (26,2)-(26,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ UnlessNode (location: (26,2)-(26,22))
+ │ │ ├── keyword_loc: (26,12)-(26,18) = "unless"
+ │ │ ├── predicate:
+ │ │ │ @ LocalVariableReadNode (location: (26,19)-(26,22))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (26,2)-(26,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableWriteNode (location: (26,2)-(26,11))
+ │ │ │ ├── name: :foo
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (26,2)-(26,5) = "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (26,8)-(26,11))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (26,8)-(26,11) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (26,6)-(26,7) = "="
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── end_keyword_loc: (27,0)-(27,3) = "end"
+ │ └── name: :B
+ ├── @ UnlessNode (location: (28,0)-(30,3))
+ │ ├── keyword_loc: (28,0)-(28,6) = "unless"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (28,7)-(28,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (28,7)-(28,10) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (29,2)-(29,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (29,2)-(29,11))
+ │ │ ├── name: :foo
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (29,2)-(29,5) = "foo"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (29,8)-(29,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (29,8)-(29,11) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (29,6)-(29,7) = "="
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (30,0)-(30,3) = "end"
+ └── @ IfNode (location: (31,0)-(36,3))
+ ├── if_keyword_loc: (31,0)-(31,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (31,3)-(33,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (31,3)-(31,6) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (31,7)-(33,1))
+ │ ├── locals: [:pair]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (31,9)-(31,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (31,10)-(31,14))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (31,10)-(31,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :pair
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (31,9)-(31,10) = "|"
+ │ │ └── closing_loc: (31,14)-(31,15) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (32,2)-(32,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (32,2)-(32,6))
+ │ │ ├── name: :pair
+ │ │ └── depth: 0
+ │ ├── opening_loc: (31,7)-(31,8) = "{"
+ │ └── closing_loc: (33,0)-(33,1) = "}"
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (34,2)-(35,5))
+ │ └── body: (length: 2)
+ │ ├── @ LocalVariableWriteNode (location: (34,2)-(34,13))
+ │ │ ├── name: :pair
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (34,2)-(34,6) = "pair"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (34,9)-(34,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (34,9)-(34,10) = ":"
+ │ │ │ ├── value_loc: (34,10)-(34,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── operator_loc: (34,7)-(34,8) = "="
+ │ └── @ LocalVariableReadNode (location: (35,2)-(35,5))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── consequent: ∅
+ └── end_keyword_loc: (36,0)-(36,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/kwbegin.txt b/test/prism/snapshots/unparser/corpus/literal/kwbegin.txt
new file mode 100644
index 0000000000..48e53af00e
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/kwbegin.txt
@@ -0,0 +1,491 @@
+@ ProgramNode (location: (1,0)-(80,3))
+├── locals: [:foo, :bar, :exception]
+└── statements:
+ @ StatementsNode (location: (1,0)-(80,3))
+ └── body: (length: 14)
+ ├── @ BeginNode (location: (1,0)-(3,3))
+ │ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (2,0)-(2,6))
+ │ │ ├── keyword_loc: (2,0)-(2,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ BeginNode (location: (5,0)-(7,3))
+ │ ├── begin_keyword_loc: (5,0)-(5,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (6,0)-(7,3))
+ │ │ ├── ensure_keyword_loc: (6,0)-(6,6) = "ensure"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (7,0)-(7,3) = "end"
+ │ └── end_keyword_loc: (7,0)-(7,3) = "end"
+ ├── @ BeginNode (location: (9,0)-(11,3))
+ │ ├── begin_keyword_loc: (9,0)-(9,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (10,2)-(10,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (10,2)-(10,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (10,2)-(10,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ BeginNode (location: (13,0)-(17,3))
+ │ ├── begin_keyword_loc: (13,0)-(13,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (14,2)-(14,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (14,2)-(14,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (14,2)-(14,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (15,0)-(16,3))
+ │ │ ├── keyword_loc: (15,0)-(15,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (16,2)-(16,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (16,2)-(16,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (16,2)-(16,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (17,0)-(17,3) = "end"
+ ├── @ BeginNode (location: (19,0)-(24,3))
+ │ ├── begin_keyword_loc: (19,0)-(19,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (20,2)-(21,3))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ CallNode (location: (20,2)-(20,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (20,2)-(20,3) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (21,2)-(21,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (21,2)-(21,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (22,0)-(23,3))
+ │ │ ├── keyword_loc: (22,0)-(22,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (23,2)-(23,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (23,2)-(23,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (23,2)-(23,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (24,0)-(24,3) = "end"
+ ├── @ BeginNode (location: (26,0)-(28,3))
+ │ ├── begin_keyword_loc: (26,0)-(26,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (27,0)-(27,8))
+ │ │ ├── keyword_loc: (27,0)-(27,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (27,7)-(27,8))
+ │ │ │ └── name: :A
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (28,0)-(28,3) = "end"
+ ├── @ BeginNode (location: (30,0)-(32,3))
+ │ ├── begin_keyword_loc: (30,0)-(30,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (31,0)-(31,15))
+ │ │ ├── keyword_loc: (31,0)-(31,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (31,7)-(31,8))
+ │ │ │ └── name: :A
+ │ │ ├── operator_loc: (31,9)-(31,11) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (31,12)-(31,15))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (32,0)-(32,3) = "end"
+ ├── @ BeginNode (location: (34,0)-(42,3))
+ │ ├── begin_keyword_loc: (34,0)-(34,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (35,2)-(35,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (35,2)-(35,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (35,2)-(35,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (36,0)-(39,3))
+ │ │ ├── keyword_loc: (36,0)-(36,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (36,7)-(36,8))
+ │ │ │ └── name: :A
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (37,2)-(37,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (37,2)-(37,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (37,2)-(37,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent:
+ │ │ @ RescueNode (location: (38,0)-(39,3))
+ │ │ ├── keyword_loc: (38,0)-(38,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (38,7)-(38,8))
+ │ │ │ └── name: :B
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (39,2)-(39,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (39,2)-(39,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (39,2)-(39,3) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause:
+ │ │ @ EnsureNode (location: (40,0)-(42,3))
+ │ │ ├── ensure_keyword_loc: (40,0)-(40,6) = "ensure"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (41,2)-(41,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (41,2)-(41,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (41,2)-(41,3) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (42,0)-(42,3) = "end"
+ │ └── end_keyword_loc: (42,0)-(42,3) = "end"
+ ├── @ BeginNode (location: (44,0)-(53,3))
+ │ ├── begin_keyword_loc: (44,0)-(44,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (45,2)-(49,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BeginNode (location: (45,2)-(49,5))
+ │ │ ├── begin_keyword_loc: (45,2)-(45,7) = "begin"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (46,4)-(47,7))
+ │ │ │ └── body: (length: 2)
+ │ │ │ ├── @ LocalVariableReadNode (location: (46,4)-(46,7))
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ CallNode (location: (47,4)-(47,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (47,4)-(47,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (48,2)-(48,8))
+ │ │ │ ├── keyword_loc: (48,2)-(48,8) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (49,2)-(49,5) = "end"
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (50,0)-(52,5))
+ │ │ ├── keyword_loc: (50,0)-(50,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (51,2)-(52,5))
+ │ │ │ └── body: (length: 2)
+ │ │ │ ├── @ CallNode (location: (51,2)-(51,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (51,2)-(51,5) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── @ CallNode (location: (52,2)-(52,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (52,2)-(52,5) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (53,0)-(53,3) = "end"
+ ├── @ BeginNode (location: (55,0)-(58,3))
+ │ ├── begin_keyword_loc: (55,0)-(55,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (56,2)-(56,35))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (56,2)-(56,35))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (56,2)-(56,18))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (56,2)-(56,7) = "raise"
+ │ │ │ ├── opening_loc: (56,7)-(56,8) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (56,8)-(56,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ ConstantReadNode (location: (56,8)-(56,17))
+ │ │ │ │ └── name: :Exception
+ │ │ │ ├── closing_loc: (56,17)-(56,18) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (56,19)-(56,25) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ LocalVariableWriteNode (location: (56,26)-(56,35))
+ │ │ ├── name: :foo
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (56,26)-(56,29) = "foo"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (56,32)-(56,35))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (56,32)-(56,35) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (56,30)-(56,31) = "="
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (57,0)-(57,16))
+ │ │ ├── keyword_loc: (57,0)-(57,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (57,7)-(57,16))
+ │ │ │ └── name: :Exception
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (58,0)-(58,3) = "end"
+ ├── @ BeginNode (location: (60,0)-(64,3))
+ │ ├── begin_keyword_loc: (60,0)-(60,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (61,2)-(61,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (61,2)-(61,5))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (62,0)-(63,5))
+ │ │ ├── keyword_loc: (62,0)-(62,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: (62,7)-(62,9) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (62,10)-(62,13))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (63,2)-(63,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (63,2)-(63,5))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (64,0)-(64,3) = "end"
+ ├── @ BeginNode (location: (66,0)-(70,3))
+ │ ├── begin_keyword_loc: (66,0)-(66,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (67,2)-(67,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (67,2)-(67,5))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (68,0)-(69,5))
+ │ │ ├── keyword_loc: (68,0)-(68,6) = "rescue"
+ │ │ ├── exceptions: (length: 2)
+ │ │ │ ├── @ ConstantReadNode (location: (68,7)-(68,16))
+ │ │ │ │ └── name: :Exception
+ │ │ │ └── @ ConstantReadNode (location: (68,18)-(68,23))
+ │ │ │ └── name: :Other
+ │ │ ├── operator_loc: (68,24)-(68,26) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (68,27)-(68,30))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (69,2)-(69,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (69,2)-(69,5))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (70,0)-(70,3) = "end"
+ ├── @ BeginNode (location: (72,0)-(76,3))
+ │ ├── begin_keyword_loc: (72,0)-(72,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (73,2)-(73,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (73,2)-(73,5))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (74,0)-(75,5))
+ │ │ ├── keyword_loc: (74,0)-(74,6) = "rescue"
+ │ │ ├── exceptions: (length: 2)
+ │ │ │ ├── @ ConstantReadNode (location: (74,7)-(74,16))
+ │ │ │ │ └── name: :SomeError
+ │ │ │ └── @ SplatNode (location: (74,18)-(74,22))
+ │ │ │ ├── operator_loc: (74,18)-(74,19) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableReadNode (location: (74,19)-(74,22))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── operator_loc: (74,23)-(74,25) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ LocalVariableTargetNode (location: (74,26)-(74,35))
+ │ │ │ ├── name: :exception
+ │ │ │ └── depth: 0
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (75,2)-(75,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (75,2)-(75,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (75,2)-(75,5) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (76,0)-(76,3) = "end"
+ └── @ SingletonClassNode (location: (78,0)-(80,3))
+ ├── locals: []
+ ├── class_keyword_loc: (78,0)-(78,5) = "class"
+ ├── operator_loc: (78,6)-(78,8) = "<<"
+ ├── expression:
+ │ @ SelfNode (location: (78,9)-(78,13))
+ ├── body:
+ │ @ StatementsNode (location: (79,2)-(79,23))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (79,2)-(79,23))
+ │ ├── expression:
+ │ │ @ UndefNode (location: (79,2)-(79,12))
+ │ │ ├── names: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (79,8)-(79,12))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (79,8)-(79,9) = ":"
+ │ │ │ ├── value_loc: (79,9)-(79,12) = "bar"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "bar"
+ │ │ └── keyword_loc: (79,2)-(79,7) = "undef"
+ │ ├── keyword_loc: (79,13)-(79,19) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (79,20)-(79,23))
+ └── end_keyword_loc: (80,0)-(80,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/lambda.txt b/test/prism/snapshots/unparser/corpus/literal/lambda.txt
new file mode 100644
index 0000000000..3594787bca
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/lambda.txt
@@ -0,0 +1,151 @@
+@ ProgramNode (location: (1,0)-(13,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(13,1))
+ └── body: (length: 6)
+ ├── @ CallNode (location: (1,0)-(2,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :lambda
+ │ ├── message_loc: (1,0)-(1,6) = "lambda"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,7)-(2,1))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,7)-(1,8) = "{"
+ │ └── closing_loc: (2,0)-(2,1) = "}"
+ ├── @ CallNode (location: (3,0)-(5,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :lambda
+ │ ├── message_loc: (3,0)-(3,6) = "lambda"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,7)-(5,1))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (3,9)-(3,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (3,10)-(3,14))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (3,10)-(3,11))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (3,13)-(3,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (3,9)-(3,10) = "|"
+ │ │ └── closing_loc: (3,14)-(3,15) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (4,2)-(4,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (4,2)-(4,3))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── opening_loc: (3,7)-(3,8) = "{"
+ │ └── closing_loc: (5,0)-(5,1) = "}"
+ ├── @ LambdaNode (location: (6,0)-(7,1))
+ │ ├── locals: []
+ │ ├── operator_loc: (6,0)-(6,2) = "->"
+ │ ├── opening_loc: (6,5)-(6,6) = "{"
+ │ ├── closing_loc: (7,0)-(7,1) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (6,2)-(6,4))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (6,2)-(6,3) = "("
+ │ │ └── closing_loc: (6,3)-(6,4) = ")"
+ │ └── body: ∅
+ ├── @ LambdaNode (location: (8,0)-(9,1))
+ │ ├── locals: [:a]
+ │ ├── operator_loc: (8,0)-(8,2) = "->"
+ │ ├── opening_loc: (8,6)-(8,7) = "{"
+ │ ├── closing_loc: (9,0)-(9,1) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (8,2)-(8,5))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (8,3)-(8,4))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (8,3)-(8,4))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (8,2)-(8,3) = "("
+ │ │ └── closing_loc: (8,4)-(8,5) = ")"
+ │ └── body: ∅
+ ├── @ LambdaNode (location: (10,0)-(11,1))
+ │ ├── locals: [:a, :b]
+ │ ├── operator_loc: (10,0)-(10,2) = "->"
+ │ ├── opening_loc: (10,9)-(10,10) = "{"
+ │ ├── closing_loc: (11,0)-(11,1) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (10,2)-(10,8))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (10,3)-(10,7))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (10,3)-(10,4))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (10,6)-(10,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (10,2)-(10,3) = "("
+ │ │ └── closing_loc: (10,7)-(10,8) = ")"
+ │ └── body: ∅
+ └── @ LambdaNode (location: (12,0)-(13,1))
+ ├── locals: [:a, :b, :c]
+ ├── operator_loc: (12,0)-(12,2) = "->"
+ ├── opening_loc: (12,12)-(12,13) = "{"
+ ├── closing_loc: (13,0)-(13,1) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (12,2)-(12,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (12,3)-(12,7))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (12,3)-(12,4))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ └── @ RequiredParameterNode (location: (12,6)-(12,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :b
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 1)
+ │ │ └── @ BlockLocalVariableNode (location: (12,9)-(12,10))
+ │ │ ├── flags: ∅
+ │ │ └── name: :c
+ │ ├── opening_loc: (12,2)-(12,3) = "("
+ │ └── closing_loc: (12,10)-(12,11) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/unparser/corpus/literal/literal.txt b/test/prism/snapshots/unparser/corpus/literal/literal.txt
new file mode 100644
index 0000000000..dcf00bf4e0
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/literal.txt
@@ -0,0 +1,1198 @@
+@ ProgramNode (location: (1,0)-(91,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(91,2))
+ └── body: (length: 78)
+ ├── @ HashNode (location: (1,0)-(1,38))
+ │ ├── opening_loc: (1,0)-(1,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (1,2)-(1,21))
+ │ │ │ ├── key:
+ │ │ │ │ @ StringNode (location: (1,2)-(1,7))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ │ │ │ ├── content_loc: (1,3)-(1,6) = "foo"
+ │ │ │ │ ├── closing_loc: (1,6)-(1,7) = "\""
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ InterpolatedStringNode (location: (1,11)-(1,21))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (1,11)-(1,21) = "<<-HEREDOC"
+ │ │ │ │ ├── parts: (length: 3)
+ │ │ │ │ │ ├── @ StringNode (location: (2,0)-(2,2))
+ │ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── content_loc: (2,0)-(2,2) = " "
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── unescaped: " "
+ │ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (2,2)-(2,5))
+ │ │ │ │ │ │ ├── opening_loc: (2,2)-(2,4) = "\#{"
+ │ │ │ │ │ │ ├── statements: ∅
+ │ │ │ │ │ │ └── closing_loc: (2,4)-(2,5) = "}"
+ │ │ │ │ │ └── @ StringNode (location: (2,5)-(3,0))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (2,5)-(3,0) = "\n"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "\n"
+ │ │ │ │ └── closing_loc: (3,0)-(4,0) = "HEREDOC\n"
+ │ │ │ └── operator_loc: (1,8)-(1,10) = "=>"
+ │ │ └── @ AssocNode (location: (1,23)-(1,36))
+ │ │ ├── key:
+ │ │ │ @ StringNode (location: (1,23)-(1,28))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (1,23)-(1,24) = "\""
+ │ │ │ ├── content_loc: (1,24)-(1,27) = "bar"
+ │ │ │ ├── closing_loc: (1,27)-(1,28) = "\""
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (1,32)-(1,36))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,32)-(1,33) = ":"
+ │ │ │ ├── value_loc: (1,33)-(1,36) = "baz"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "baz"
+ │ │ └── operator_loc: (1,29)-(1,31) = "=>"
+ │ └── closing_loc: (1,37)-(1,38) = "}"
+ ├── @ HashNode (location: (4,0)-(4,31))
+ │ ├── opening_loc: (4,0)-(4,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (4,2)-(4,14))
+ │ │ │ ├── key:
+ │ │ │ │ @ StringNode (location: (4,2)-(4,7))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: (4,2)-(4,3) = "\""
+ │ │ │ │ ├── content_loc: (4,3)-(4,6) = "foo"
+ │ │ │ │ ├── closing_loc: (4,6)-(4,7) = "\""
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ StringNode (location: (4,11)-(4,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (4,11)-(4,13) = "%("
+ │ │ │ │ ├── content_loc: (4,13)-(4,13) = ""
+ │ │ │ │ ├── closing_loc: (4,13)-(4,14) = ")"
+ │ │ │ │ └── unescaped: ""
+ │ │ │ └── operator_loc: (4,8)-(4,10) = "=>"
+ │ │ └── @ AssocNode (location: (4,16)-(4,29))
+ │ │ ├── key:
+ │ │ │ @ StringNode (location: (4,16)-(4,21))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (4,16)-(4,17) = "\""
+ │ │ │ ├── content_loc: (4,17)-(4,20) = "bar"
+ │ │ │ ├── closing_loc: (4,20)-(4,21) = "\""
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (4,25)-(4,29))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (4,25)-(4,26) = ":"
+ │ │ │ ├── value_loc: (4,26)-(4,29) = "baz"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "baz"
+ │ │ └── operator_loc: (4,22)-(4,24) = "=>"
+ │ └── closing_loc: (4,30)-(4,31) = "}"
+ ├── @ ArrayNode (location: (5,0)-(5,12))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (5,1)-(5,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (5,1)-(5,2) = "\""
+ │ │ │ ├── content_loc: (5,2)-(5,5) = "foo"
+ │ │ │ ├── closing_loc: (5,5)-(5,6) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ StringNode (location: (5,8)-(5,11))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (5,8)-(5,10) = "%("
+ │ │ ├── content_loc: (5,10)-(5,10) = ""
+ │ │ ├── closing_loc: (5,10)-(5,11) = ")"
+ │ │ └── unescaped: ""
+ │ ├── opening_loc: (5,0)-(5,1) = "["
+ │ └── closing_loc: (5,11)-(5,12) = "]"
+ ├── @ CallNode (location: (6,0)-(6,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (6,0)-(6,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (6,0)-(6,1) = "a"
+ │ │ ├── opening_loc: (6,1)-(6,2) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (6,2)-(6,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ InterpolatedStringNode (location: (6,2)-(6,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (6,2)-(6,12) = "<<-HEREDOC"
+ │ │ │ ├── parts: (length: 3)
+ │ │ │ │ ├── @ StringNode (location: (7,0)-(7,2))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (7,0)-(7,2) = " "
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: " "
+ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (7,2)-(7,5))
+ │ │ │ │ │ ├── opening_loc: (7,2)-(7,4) = "\#{"
+ │ │ │ │ │ ├── statements: ∅
+ │ │ │ │ │ └── closing_loc: (7,4)-(7,5) = "}"
+ │ │ │ │ └── @ StringNode (location: (7,5)-(8,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (7,5)-(8,0) = "\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "\n"
+ │ │ │ └── closing_loc: (8,0)-(9,0) = "HEREDOC\n"
+ │ │ ├── closing_loc: (6,12)-(6,13) = ")"
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (6,13)-(6,14) = "."
+ │ ├── name: :a
+ │ ├── message_loc: (6,14)-(6,15) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (9,0)-(9,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (9,0)-(9,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (9,0)-(9,1) = "a"
+ │ │ ├── opening_loc: (9,1)-(9,2) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (9,2)-(9,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (9,2)-(9,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (9,2)-(9,4) = "%("
+ │ │ │ ├── content_loc: (9,4)-(9,4) = ""
+ │ │ │ ├── closing_loc: (9,4)-(9,5) = ")"
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: (9,5)-(9,6) = ")"
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (9,6)-(9,7) = "."
+ │ ├── name: :a
+ │ ├── message_loc: (9,7)-(9,8) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ HashNode (location: (10,0)-(10,30))
+ │ ├── opening_loc: (10,0)-(10,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (10,2)-(10,21))
+ │ │ │ ├── key:
+ │ │ │ │ @ StringNode (location: (10,2)-(10,7))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: (10,2)-(10,3) = "\""
+ │ │ │ │ ├── content_loc: (10,3)-(10,6) = "foo"
+ │ │ │ │ ├── closing_loc: (10,6)-(10,7) = "\""
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ InterpolatedStringNode (location: (10,11)-(10,21))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (10,11)-(10,21) = "<<-HEREDOC"
+ │ │ │ │ ├── parts: (length: 3)
+ │ │ │ │ │ ├── @ StringNode (location: (11,0)-(11,2))
+ │ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── content_loc: (11,0)-(11,2) = " "
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── unescaped: " "
+ │ │ │ │ │ ├── @ EmbeddedStatementsNode (location: (11,2)-(11,5))
+ │ │ │ │ │ │ ├── opening_loc: (11,2)-(11,4) = "\#{"
+ │ │ │ │ │ │ ├── statements: ∅
+ │ │ │ │ │ │ └── closing_loc: (11,4)-(11,5) = "}"
+ │ │ │ │ │ └── @ StringNode (location: (11,5)-(12,0))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (11,5)-(12,0) = "\n"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "\n"
+ │ │ │ │ └── closing_loc: (12,0)-(13,0) = "HEREDOC\n"
+ │ │ │ └── operator_loc: (10,8)-(10,10) = "=>"
+ │ │ └── @ AssocSplatNode (location: (10,23)-(10,28))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (10,25)-(10,28))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (10,25)-(10,28) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (10,23)-(10,25) = "**"
+ │ └── closing_loc: (10,29)-(10,30) = "}"
+ ├── @ HashNode (location: (13,0)-(13,23))
+ │ ├── opening_loc: (13,0)-(13,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (13,2)-(13,14))
+ │ │ │ ├── key:
+ │ │ │ │ @ StringNode (location: (13,2)-(13,7))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: (13,2)-(13,3) = "\""
+ │ │ │ │ ├── content_loc: (13,3)-(13,6) = "foo"
+ │ │ │ │ ├── closing_loc: (13,6)-(13,7) = "\""
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ StringNode (location: (13,11)-(13,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (13,11)-(13,13) = "%("
+ │ │ │ │ ├── content_loc: (13,13)-(13,13) = ""
+ │ │ │ │ ├── closing_loc: (13,13)-(13,14) = ")"
+ │ │ │ │ └── unescaped: ""
+ │ │ │ └── operator_loc: (13,8)-(13,10) = "=>"
+ │ │ └── @ AssocSplatNode (location: (13,16)-(13,21))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (13,18)-(13,21))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (13,18)-(13,21) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (13,16)-(13,18) = "**"
+ │ └── closing_loc: (13,22)-(13,23) = "}"
+ ├── @ InterpolatedStringNode (location: (14,0)-(14,14))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (14,0)-(14,1) = "\""
+ │ ├── parts: (length: 5)
+ │ │ ├── @ EmbeddedVariableNode (location: (14,1)-(14,4))
+ │ │ │ ├── operator_loc: (14,1)-(14,2) = "#"
+ │ │ │ └── variable:
+ │ │ │ @ InstanceVariableReadNode (location: (14,2)-(14,4))
+ │ │ │ └── name: :@a
+ │ │ ├── @ StringNode (location: (14,4)-(14,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (14,4)-(14,5) = " "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " "
+ │ │ ├── @ EmbeddedVariableNode (location: (14,5)-(14,9))
+ │ │ │ ├── operator_loc: (14,5)-(14,6) = "#"
+ │ │ │ └── variable:
+ │ │ │ @ ClassVariableReadNode (location: (14,6)-(14,9))
+ │ │ │ └── name: :@@a
+ │ │ ├── @ StringNode (location: (14,9)-(14,10))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (14,9)-(14,10) = " "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " "
+ │ │ └── @ EmbeddedVariableNode (location: (14,10)-(14,13))
+ │ │ ├── operator_loc: (14,10)-(14,11) = "#"
+ │ │ └── variable:
+ │ │ @ GlobalVariableReadNode (location: (14,11)-(14,13))
+ │ │ └── name: :$a
+ │ └── closing_loc: (14,13)-(14,14) = "\""
+ ├── @ IntegerNode (location: (15,0)-(15,1))
+ │ ├── flags: decimal
+ │ └── value: 0
+ ├── @ CallNode (location: (16,0)-(16,3))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (16,1)-(16,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+@
+ │ ├── message_loc: (16,0)-(16,1) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ IntegerNode (location: (17,0)-(17,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ IntegerNode (location: (18,0)-(18,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ RationalNode (location: (19,0)-(19,2))
+ │ └── numeric:
+ │ @ IntegerNode (location: (19,0)-(19,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ RationalNode (location: (20,0)-(20,4))
+ │ └── numeric:
+ │ @ FloatNode (location: (20,0)-(20,3))
+ │ └── value: 1.5
+ ├── @ RationalNode (location: (21,0)-(21,4))
+ │ └── numeric:
+ │ @ FloatNode (location: (21,0)-(21,3))
+ │ └── value: 1.3
+ ├── @ ImaginaryNode (location: (22,0)-(22,2))
+ │ └── numeric:
+ │ @ IntegerNode (location: (22,0)-(22,1))
+ │ ├── flags: decimal
+ │ └── value: 5
+ ├── @ ImaginaryNode (location: (23,0)-(23,3))
+ │ └── numeric:
+ │ @ IntegerNode (location: (23,0)-(23,2))
+ │ ├── flags: decimal
+ │ └── value: -5
+ ├── @ ImaginaryNode (location: (24,0)-(24,4))
+ │ └── numeric:
+ │ @ FloatNode (location: (24,0)-(24,3))
+ │ └── value: 0.6
+ ├── @ ImaginaryNode (location: (25,0)-(25,5))
+ │ └── numeric:
+ │ @ FloatNode (location: (25,0)-(25,4))
+ │ └── value: -0.6
+ ├── @ ImaginaryNode (location: (26,0)-(26,32))
+ │ └── numeric:
+ │ @ IntegerNode (location: (26,0)-(26,31))
+ │ ├── flags: decimal
+ │ └── value: 1000000000000000000000000000000
+ ├── @ ImaginaryNode (location: (27,0)-(27,3))
+ │ └── numeric:
+ │ @ RationalNode (location: (27,0)-(27,2))
+ │ └── numeric:
+ │ @ IntegerNode (location: (27,0)-(27,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ InterpolatedStringNode (location: (28,0)-(28,11))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (28,0)-(28,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (28,0)-(28,1) = "\""
+ │ │ │ ├── content_loc: (28,1)-(28,4) = "foo"
+ │ │ │ ├── closing_loc: (28,4)-(28,5) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ StringNode (location: (28,6)-(28,11))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (28,6)-(28,7) = "\""
+ │ │ ├── content_loc: (28,7)-(28,10) = "bar"
+ │ │ ├── closing_loc: (28,10)-(28,11) = "\""
+ │ │ └── unescaped: "bar"
+ │ └── closing_loc: ∅
+ ├── @ InterpolatedStringNode (location: (29,0)-(29,15))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (29,0)-(29,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (29,1)-(29,8))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (29,1)-(29,8) = "foobar "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foobar "
+ │ │ └── @ EmbeddedStatementsNode (location: (29,8)-(29,14))
+ │ │ ├── opening_loc: (29,8)-(29,10) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (29,10)-(29,13))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (29,10)-(29,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (29,10)-(29,13) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (29,13)-(29,14) = "}"
+ │ └── closing_loc: (29,14)-(29,15) = "\""
+ ├── @ InterpolatedStringNode (location: (30,0)-(30,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (30,0)-(30,1) = "\""
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (30,1)-(30,4))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (30,1)-(30,4) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── @ EmbeddedStatementsNode (location: (30,4)-(30,8))
+ │ │ │ ├── opening_loc: (30,4)-(30,6) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (30,6)-(30,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (30,6)-(30,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (30,7)-(30,8) = "}"
+ │ │ └── @ StringNode (location: (30,8)-(30,11))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (30,8)-(30,11) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ └── closing_loc: (30,11)-(30,12) = "\""
+ ├── @ InterpolatedStringNode (location: (31,0)-(31,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (31,0)-(31,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (31,1)-(31,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (31,1)-(31,5) = "\\\\\\\\"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\\\\"
+ │ │ └── @ EmbeddedStatementsNode (location: (31,5)-(31,8))
+ │ │ ├── opening_loc: (31,5)-(31,7) = "\#{"
+ │ │ ├── statements: ∅
+ │ │ └── closing_loc: (31,7)-(31,8) = "}"
+ │ └── closing_loc: (31,8)-(31,9) = "\""
+ ├── @ InterpolatedStringNode (location: (32,0)-(32,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (32,0)-(32,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (32,1)-(32,4))
+ │ │ │ ├── opening_loc: (32,1)-(32,3) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (32,3)-(32,4) = "}"
+ │ │ └── @ StringNode (location: (32,4)-(32,8))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (32,4)-(32,8) = "\\\#{}"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#{}"
+ │ └── closing_loc: (32,8)-(32,9) = "\""
+ ├── @ InterpolatedStringNode (location: (33,0)-(33,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (33,0)-(33,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (33,1)-(33,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (33,1)-(33,5) = "\\\#{}"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\#{}"
+ │ │ └── @ EmbeddedStatementsNode (location: (33,5)-(33,8))
+ │ │ ├── opening_loc: (33,5)-(33,7) = "\#{"
+ │ │ ├── statements: ∅
+ │ │ └── closing_loc: (33,7)-(33,8) = "}"
+ │ └── closing_loc: (33,8)-(33,9) = "\""
+ ├── @ StringNode (location: (34,0)-(34,15))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (34,0)-(34,1) = "\""
+ │ ├── content_loc: (34,1)-(34,14) = "foo\\\\\\\#{@bar}"
+ │ ├── closing_loc: (34,14)-(34,15) = "\""
+ │ └── unescaped: "foo\\\#{@bar}"
+ ├── @ StringNode (location: (35,0)-(35,4))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (35,0)-(35,1) = "\""
+ │ ├── content_loc: (35,1)-(35,3) = "\\\""
+ │ ├── closing_loc: (35,3)-(35,4) = "\""
+ │ └── unescaped: "\""
+ ├── @ StringNode (location: (36,0)-(36,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (36,0)-(36,1) = "\""
+ │ ├── content_loc: (36,1)-(36,8) = "foo bar"
+ │ ├── closing_loc: (36,8)-(36,9) = "\""
+ │ └── unescaped: "foo bar"
+ ├── @ StringNode (location: (37,0)-(37,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (37,0)-(37,1) = "\""
+ │ ├── content_loc: (37,1)-(37,9) = "foo\\nbar"
+ │ ├── closing_loc: (37,9)-(37,10) = "\""
+ │ └── unescaped: "foo\nbar"
+ ├── @ XStringNode (location: (38,0)-(38,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (38,0)-(38,1) = "`"
+ │ ├── content_loc: (38,1)-(38,4) = "foo"
+ │ ├── closing_loc: (38,4)-(38,5) = "`"
+ │ └── unescaped: "foo"
+ ├── @ InterpolatedXStringNode (location: (39,0)-(39,12))
+ │ ├── opening_loc: (39,0)-(39,1) = "`"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (39,1)-(39,4))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (39,1)-(39,4) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ EmbeddedStatementsNode (location: (39,4)-(39,11))
+ │ │ ├── opening_loc: (39,4)-(39,6) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (39,6)-(39,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ InstanceVariableReadNode (location: (39,6)-(39,10))
+ │ │ │ └── name: :@bar
+ │ │ └── closing_loc: (39,10)-(39,11) = "}"
+ │ └── closing_loc: (39,11)-(39,12) = "`"
+ ├── @ XStringNode (location: (40,0)-(40,3))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (40,0)-(40,1) = "`"
+ │ ├── content_loc: (40,1)-(40,2) = ")"
+ │ ├── closing_loc: (40,2)-(40,3) = "`"
+ │ └── unescaped: ")"
+ ├── @ XStringNode (location: (41,0)-(41,4))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (41,0)-(41,1) = "`"
+ │ ├── content_loc: (41,1)-(41,3) = "\\`"
+ │ ├── closing_loc: (41,3)-(41,4) = "`"
+ │ └── unescaped: "`"
+ ├── @ XStringNode (location: (42,0)-(42,3))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (42,0)-(42,1) = "`"
+ │ ├── content_loc: (42,1)-(42,2) = "\""
+ │ ├── closing_loc: (42,2)-(42,3) = "`"
+ │ └── unescaped: "\""
+ ├── @ SymbolNode (location: (43,0)-(43,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (43,0)-(43,1) = ":"
+ │ ├── value_loc: (43,1)-(43,4) = "foo"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "foo"
+ ├── @ SymbolNode (location: (44,0)-(44,6))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (44,0)-(44,2) = ":\""
+ │ ├── value_loc: (44,2)-(44,5) = "A B"
+ │ ├── closing_loc: (44,5)-(44,6) = "\""
+ │ └── unescaped: "A B"
+ ├── @ SymbolNode (location: (45,0)-(45,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (45,0)-(45,1) = ":"
+ │ ├── value_loc: (45,1)-(45,4) = "foo"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "foo"
+ ├── @ SymbolNode (location: (46,0)-(46,6))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (46,0)-(46,2) = ":\""
+ │ ├── value_loc: (46,2)-(46,5) = "A B"
+ │ ├── closing_loc: (46,5)-(46,6) = "\""
+ │ └── unescaped: "A B"
+ ├── @ SymbolNode (location: (47,0)-(47,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (47,0)-(47,2) = ":\""
+ │ ├── value_loc: (47,2)-(47,6) = "A\\\"B"
+ │ ├── closing_loc: (47,6)-(47,7) = "\""
+ │ └── unescaped: "A\"B"
+ ├── @ SymbolNode (location: (48,0)-(48,3))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (48,0)-(48,2) = ":\""
+ │ ├── value_loc: (1,0)-(1,0) = ""
+ │ ├── closing_loc: (48,2)-(48,3) = "\""
+ │ └── unescaped: ""
+ ├── @ RegularExpressionNode (location: (49,0)-(49,5))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (49,0)-(49,1) = "/"
+ │ ├── content_loc: (49,1)-(49,4) = "foo"
+ │ ├── closing_loc: (49,4)-(49,5) = "/"
+ │ └── unescaped: "foo"
+ ├── @ RegularExpressionNode (location: (50,0)-(50,28))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (50,0)-(50,1) = "/"
+ │ ├── content_loc: (50,1)-(50,27) = "[^-+',.\\/:@[:alnum:]\\[\\]]+"
+ │ ├── closing_loc: (50,27)-(50,28) = "/"
+ │ └── unescaped: "[^-+',./:@[:alnum:]\\[\\]]+"
+ ├── @ InterpolatedRegularExpressionNode (location: (51,0)-(51,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (51,0)-(51,1) = "/"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (51,1)-(51,4))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (51,1)-(51,4) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ EmbeddedStatementsNode (location: (51,4)-(51,11))
+ │ │ ├── opening_loc: (51,4)-(51,6) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (51,6)-(51,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ InstanceVariableReadNode (location: (51,6)-(51,10))
+ │ │ │ └── name: :@bar
+ │ │ └── closing_loc: (51,10)-(51,11) = "}"
+ │ └── closing_loc: (51,11)-(51,12) = "/"
+ ├── @ InterpolatedRegularExpressionNode (location: (52,0)-(52,15))
+ │ ├── flags: ignore_case, extended, multi_line
+ │ ├── opening_loc: (52,0)-(52,1) = "/"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (52,1)-(52,4))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (52,1)-(52,4) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ EmbeddedStatementsNode (location: (52,4)-(52,11))
+ │ │ ├── opening_loc: (52,4)-(52,6) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (52,6)-(52,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ InstanceVariableReadNode (location: (52,6)-(52,10))
+ │ │ │ └── name: :@bar
+ │ │ └── closing_loc: (52,10)-(52,11) = "}"
+ │ └── closing_loc: (52,11)-(52,15) = "/imx"
+ ├── @ InterpolatedRegularExpressionNode (location: (53,0)-(53,13))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (53,0)-(53,1) = "/"
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (53,1)-(53,12))
+ │ │ ├── opening_loc: (53,1)-(53,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (53,3)-(53,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ StringNode (location: (53,3)-(53,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (53,3)-(53,4) = "\""
+ │ │ │ ├── content_loc: (53,4)-(53,10) = "\\u0000"
+ │ │ │ ├── closing_loc: (53,10)-(53,11) = "\""
+ │ │ │ └── unescaped: "\u0000"
+ │ │ └── closing_loc: (53,11)-(53,12) = "}"
+ │ └── closing_loc: (53,12)-(53,13) = "/"
+ ├── @ RegularExpressionNode (location: (54,0)-(54,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (54,0)-(54,1) = "/"
+ │ ├── content_loc: (54,1)-(54,3) = "\\n"
+ │ ├── closing_loc: (54,3)-(54,4) = "/"
+ │ └── unescaped: "\\n"
+ ├── @ RegularExpressionNode (location: (55,0)-(55,4))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (55,0)-(55,1) = "/"
+ │ ├── content_loc: (55,1)-(55,3) = "\\n"
+ │ ├── closing_loc: (55,3)-(55,4) = "/"
+ │ └── unescaped: "\\n"
+ ├── @ RegularExpressionNode (location: (56,0)-(56,5))
+ │ ├── flags: extended, forced_us_ascii_encoding
+ │ ├── opening_loc: (56,0)-(56,1) = "/"
+ │ ├── content_loc: (56,1)-(56,3) = "\\n"
+ │ ├── closing_loc: (56,3)-(56,5) = "/x"
+ │ └── unescaped: "\\n"
+ ├── @ RegularExpressionNode (location: (57,0)-(57,7))
+ │ ├── flags: extended, forced_us_ascii_encoding
+ │ ├── opening_loc: (57,0)-(57,1) = "/"
+ │ ├── content_loc: (57,1)-(57,5) = "\\/\\/"
+ │ ├── closing_loc: (57,5)-(57,7) = "/x"
+ │ └── unescaped: "//"
+ ├── @ InterpolatedSymbolNode (location: (58,0)-(58,15))
+ │ ├── opening_loc: (58,0)-(58,2) = ":\""
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (58,2)-(58,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (58,2)-(58,5) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── @ EmbeddedStatementsNode (location: (58,5)-(58,11))
+ │ │ │ ├── opening_loc: (58,5)-(58,7) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (58,7)-(58,10))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (58,7)-(58,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (58,7)-(58,10) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (58,10)-(58,11) = "}"
+ │ │ └── @ StringNode (location: (58,11)-(58,14))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (58,11)-(58,14) = "baz"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz"
+ │ └── closing_loc: (58,14)-(58,15) = "\""
+ ├── @ InterpolatedSymbolNode (location: (59,0)-(59,11))
+ │ ├── opening_loc: (59,0)-(59,2) = ":\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (59,2)-(59,10))
+ │ │ ├── opening_loc: (59,2)-(59,4) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (59,4)-(59,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ StringNode (location: (59,4)-(59,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (59,4)-(59,5) = "\""
+ │ │ │ ├── content_loc: (59,5)-(59,8) = "foo"
+ │ │ │ ├── closing_loc: (59,8)-(59,9) = "\""
+ │ │ │ └── unescaped: "foo"
+ │ │ └── closing_loc: (59,9)-(59,10) = "}"
+ │ └── closing_loc: (59,10)-(59,11) = "\""
+ ├── @ RangeNode (location: (60,0)-(60,14))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ ParenthesesNode (location: (60,0)-(60,11))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (60,1)-(60,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (60,1)-(60,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ FloatNode (location: (60,1)-(60,4))
+ │ │ │ │ └── value: 0.0
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :/
+ │ │ │ ├── message_loc: (60,5)-(60,6) = "/"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (60,7)-(60,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ FloatNode (location: (60,7)-(60,10))
+ │ │ │ │ └── value: 0.0
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (60,0)-(60,1) = "("
+ │ │ └── closing_loc: (60,10)-(60,11) = ")"
+ │ ├── right:
+ │ │ @ IntegerNode (location: (60,13)-(60,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (60,11)-(60,13) = ".."
+ ├── @ RangeNode (location: (61,0)-(61,14))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (61,0)-(61,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ ParenthesesNode (location: (61,3)-(61,14))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (61,4)-(61,13))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (61,4)-(61,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ FloatNode (location: (61,4)-(61,7))
+ │ │ │ │ └── value: 0.0
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :/
+ │ │ │ ├── message_loc: (61,8)-(61,9) = "/"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (61,10)-(61,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ FloatNode (location: (61,10)-(61,13))
+ │ │ │ │ └── value: 0.0
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (61,3)-(61,4) = "("
+ │ │ └── closing_loc: (61,13)-(61,14) = ")"
+ │ └── operator_loc: (61,1)-(61,3) = ".."
+ ├── @ RangeNode (location: (62,0)-(62,16))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ ParenthesesNode (location: (62,0)-(62,11))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (62,1)-(62,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (62,1)-(62,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ FloatNode (location: (62,1)-(62,4))
+ │ │ │ │ └── value: 0.0
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :/
+ │ │ │ ├── message_loc: (62,5)-(62,6) = "/"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (62,7)-(62,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ FloatNode (location: (62,7)-(62,10))
+ │ │ │ │ └── value: 0.0
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (62,0)-(62,1) = "("
+ │ │ └── closing_loc: (62,10)-(62,11) = ")"
+ │ ├── right:
+ │ │ @ IntegerNode (location: (62,13)-(62,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 100
+ │ └── operator_loc: (62,11)-(62,13) = ".."
+ ├── @ FloatNode (location: (63,0)-(63,4))
+ │ └── value: -0.1
+ ├── @ FloatNode (location: (64,0)-(64,3))
+ │ └── value: 0.1
+ ├── @ ArrayNode (location: (65,0)-(65,6))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (65,1)-(65,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (65,4)-(65,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (65,0)-(65,1) = "["
+ │ └── closing_loc: (65,5)-(65,6) = "]"
+ ├── @ ArrayNode (location: (66,0)-(66,11))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ IntegerNode (location: (66,1)-(66,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ ParenthesesNode (location: (66,4)-(66,6))
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (66,4)-(66,5) = "("
+ │ │ │ └── closing_loc: (66,5)-(66,6) = ")"
+ │ │ └── @ CallNode (location: (66,8)-(66,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :n2
+ │ │ ├── message_loc: (66,8)-(66,10) = "n2"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (66,0)-(66,1) = "["
+ │ └── closing_loc: (66,10)-(66,11) = "]"
+ ├── @ ArrayNode (location: (67,0)-(67,3))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ IntegerNode (location: (67,1)-(67,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (67,0)-(67,1) = "["
+ │ └── closing_loc: (67,2)-(67,3) = "]"
+ ├── @ ArrayNode (location: (68,0)-(68,2))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (68,0)-(68,1) = "["
+ │ └── closing_loc: (68,1)-(68,2) = "]"
+ ├── @ ArrayNode (location: (69,0)-(69,10))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (69,1)-(69,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ SplatNode (location: (69,4)-(69,9))
+ │ │ ├── operator_loc: (69,4)-(69,5) = "*"
+ │ │ └── expression:
+ │ │ @ InstanceVariableReadNode (location: (69,5)-(69,9))
+ │ │ └── name: :@foo
+ │ ├── opening_loc: (69,0)-(69,1) = "["
+ │ └── closing_loc: (69,9)-(69,10) = "]"
+ ├── @ ArrayNode (location: (70,0)-(70,10))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SplatNode (location: (70,1)-(70,6))
+ │ │ │ ├── operator_loc: (70,1)-(70,2) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ InstanceVariableReadNode (location: (70,2)-(70,6))
+ │ │ │ └── name: :@foo
+ │ │ └── @ IntegerNode (location: (70,8)-(70,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (70,0)-(70,1) = "["
+ │ └── closing_loc: (70,9)-(70,10) = "]"
+ ├── @ ArrayNode (location: (71,0)-(71,14))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SplatNode (location: (71,1)-(71,6))
+ │ │ │ ├── operator_loc: (71,1)-(71,2) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ InstanceVariableReadNode (location: (71,2)-(71,6))
+ │ │ │ └── name: :@foo
+ │ │ └── @ SplatNode (location: (71,8)-(71,13))
+ │ │ ├── operator_loc: (71,8)-(71,9) = "*"
+ │ │ └── expression:
+ │ │ @ InstanceVariableReadNode (location: (71,9)-(71,13))
+ │ │ └── name: :@baz
+ │ ├── opening_loc: (71,0)-(71,1) = "["
+ │ └── closing_loc: (71,13)-(71,14) = "]"
+ ├── @ HashNode (location: (72,0)-(72,2))
+ │ ├── opening_loc: (72,0)-(72,1) = "{"
+ │ ├── elements: (length: 0)
+ │ └── closing_loc: (72,1)-(72,2) = "}"
+ ├── @ HashNode (location: (73,0)-(73,12))
+ │ ├── opening_loc: (73,0)-(73,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (73,2)-(73,10))
+ │ │ ├── key:
+ │ │ │ @ ParenthesesNode (location: (73,2)-(73,4))
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (73,2)-(73,3) = "("
+ │ │ │ └── closing_loc: (73,3)-(73,4) = ")"
+ │ │ ├── value:
+ │ │ │ @ ParenthesesNode (location: (73,8)-(73,10))
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (73,8)-(73,9) = "("
+ │ │ │ └── closing_loc: (73,9)-(73,10) = ")"
+ │ │ └── operator_loc: (73,5)-(73,7) = "=>"
+ │ └── closing_loc: (73,11)-(73,12) = "}"
+ ├── @ HashNode (location: (74,0)-(74,10))
+ │ ├── opening_loc: (74,0)-(74,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (74,2)-(74,8))
+ │ │ ├── key:
+ │ │ │ @ IntegerNode (location: (74,2)-(74,3))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (74,7)-(74,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (74,4)-(74,6) = "=>"
+ │ └── closing_loc: (74,9)-(74,10) = "}"
+ ├── @ HashNode (location: (75,0)-(75,18))
+ │ ├── opening_loc: (75,0)-(75,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (75,2)-(75,8))
+ │ │ │ ├── key:
+ │ │ │ │ @ IntegerNode (location: (75,2)-(75,3))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (75,7)-(75,8))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── operator_loc: (75,4)-(75,6) = "=>"
+ │ │ └── @ AssocNode (location: (75,10)-(75,16))
+ │ │ ├── key:
+ │ │ │ @ IntegerNode (location: (75,10)-(75,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (75,15)-(75,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 4
+ │ │ └── operator_loc: (75,12)-(75,14) = "=>"
+ │ └── closing_loc: (75,17)-(75,18) = "}"
+ ├── @ HashNode (location: (76,0)-(76,27))
+ │ ├── opening_loc: (76,0)-(76,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (76,2)-(76,19))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (76,2)-(76,4))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (76,2)-(76,3) = "a"
+ │ │ │ │ ├── closing_loc: (76,3)-(76,4) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ParenthesesNode (location: (76,5)-(76,19))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (76,6)-(76,18))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ RescueModifierNode (location: (76,6)-(76,18))
+ │ │ │ │ │ ├── expression:
+ │ │ │ │ │ │ @ IntegerNode (location: (76,6)-(76,7))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 1
+ │ │ │ │ │ ├── keyword_loc: (76,8)-(76,14) = "rescue"
+ │ │ │ │ │ └── rescue_expression:
+ │ │ │ │ │ @ CallNode (location: (76,15)-(76,18))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :foo
+ │ │ │ │ │ ├── message_loc: (76,15)-(76,18) = "foo"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── opening_loc: (76,5)-(76,6) = "("
+ │ │ │ │ └── closing_loc: (76,18)-(76,19) = ")"
+ │ │ │ └── operator_loc: ∅
+ │ │ └── @ AssocNode (location: (76,21)-(76,25))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (76,21)-(76,23))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (76,21)-(76,22) = "b"
+ │ │ │ ├── closing_loc: (76,22)-(76,23) = ":"
+ │ │ │ └── unescaped: "b"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (76,24)-(76,25))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (76,26)-(76,27) = "}"
+ ├── @ HashNode (location: (77,0)-(77,14))
+ │ ├── opening_loc: (77,0)-(77,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (77,2)-(77,6))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (77,2)-(77,4))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (77,2)-(77,3) = "a"
+ │ │ │ │ ├── closing_loc: (77,3)-(77,4) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (77,5)-(77,6))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: ∅
+ │ │ └── @ AssocNode (location: (77,8)-(77,12))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (77,8)-(77,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (77,8)-(77,9) = "b"
+ │ │ │ ├── closing_loc: (77,9)-(77,10) = ":"
+ │ │ │ └── unescaped: "b"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (77,11)-(77,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (77,13)-(77,14) = "}"
+ ├── @ HashNode (location: (78,0)-(78,9))
+ │ ├── opening_loc: (78,0)-(78,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (78,2)-(78,7))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (78,2)-(78,4))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (78,2)-(78,3) = "a"
+ │ │ │ ├── closing_loc: (78,3)-(78,4) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ SymbolNode (location: (78,5)-(78,7))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (78,5)-(78,6) = ":"
+ │ │ │ ├── value_loc: (78,6)-(78,7) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (78,8)-(78,9) = "}"
+ ├── @ HashNode (location: (79,0)-(79,15))
+ │ ├── opening_loc: (79,0)-(79,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (79,2)-(79,13))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (79,2)-(79,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (79,2)-(79,4) = ":\""
+ │ │ │ ├── value_loc: (79,4)-(79,7) = "a b"
+ │ │ │ ├── closing_loc: (79,7)-(79,8) = "\""
+ │ │ │ └── unescaped: "a b"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (79,12)-(79,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (79,9)-(79,11) = "=>"
+ │ └── closing_loc: (79,14)-(79,15) = "}"
+ ├── @ HashNode (location: (80,0)-(80,12))
+ │ ├── opening_loc: (80,0)-(80,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (80,2)-(80,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (80,2)-(80,5))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (80,2)-(80,3) = ":"
+ │ │ │ ├── value_loc: (80,3)-(80,5) = "-@"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "-@"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (80,9)-(80,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (80,6)-(80,8) = "=>"
+ │ └── closing_loc: (80,11)-(80,12) = "}"
+ ├── @ InterpolatedStringNode (location: (81,0)-(82,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (81,0)-(81,1) = "\""
+ │ ├── parts: (length: 4)
+ │ │ ├── @ EmbeddedStatementsNode (location: (81,1)-(81,4))
+ │ │ │ ├── opening_loc: (81,1)-(81,3) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (81,3)-(81,4) = "}"
+ │ │ ├── @ StringNode (location: (81,4)-(82,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (81,4)-(82,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (82,0)-(82,3))
+ │ │ │ ├── opening_loc: (82,0)-(82,2) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (82,2)-(82,3) = "}"
+ │ │ └── @ StringNode (location: (82,3)-(82,6))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (82,3)-(82,6) = "\\na"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\na"
+ │ └── closing_loc: (82,6)-(82,7) = "\""
+ ├── @ CallNode (location: (83,0)-(86,1))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (83,0)-(83,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (83,4)-(86,1))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (84,2)-(85,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (84,2)-(85,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (84,2)-(84,3) = "\""
+ │ │ ├── parts: (length: 4)
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (84,3)-(84,6))
+ │ │ │ │ ├── opening_loc: (84,3)-(84,5) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (84,5)-(84,6) = "}"
+ │ │ │ ├── @ StringNode (location: (84,6)-(85,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (84,6)-(85,0) = "\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "\n"
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (85,0)-(85,3))
+ │ │ │ │ ├── opening_loc: (85,0)-(85,2) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (85,2)-(85,3) = "}"
+ │ │ │ └── @ StringNode (location: (85,3)-(85,6))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (85,3)-(85,6) = "\\na"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\na"
+ │ │ └── closing_loc: (85,6)-(85,7) = "\""
+ │ ├── opening_loc: (83,4)-(83,5) = "{"
+ │ └── closing_loc: (86,0)-(86,1) = "}"
+ ├── @ SymbolNode (location: (87,0)-(88,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (87,0)-(87,2) = ":\""
+ │ ├── value_loc: (87,2)-(88,1) = "a\\\\\nb"
+ │ ├── closing_loc: (88,1)-(88,2) = "\""
+ │ └── unescaped: "a\\\nb"
+ └── @ InterpolatedXStringNode (location: (89,0)-(91,2))
+ ├── opening_loc: (89,0)-(89,1) = "`"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (89,1)-(90,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (89,1)-(90,0) = " x\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " x\n"
+ │ ├── @ EmbeddedStatementsNode (location: (90,0)-(90,6))
+ │ │ ├── opening_loc: (90,0)-(90,2) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (90,2)-(90,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (90,2)-(90,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (90,2)-(90,5) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (90,5)-(90,6) = "}"
+ │ └── @ StringNode (location: (90,6)-(91,1))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (90,6)-(91,1) = "\n#"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\n#"
+ └── closing_loc: (91,1)-(91,2) = "`"
diff --git a/test/prism/snapshots/unparser/corpus/literal/module.txt b/test/prism/snapshots/unparser/corpus/literal/module.txt
new file mode 100644
index 0000000000..5dd8c03b51
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/module.txt
@@ -0,0 +1,107 @@
+@ ProgramNode (location: (1,0)-(16,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(16,3))
+ └── body: (length: 4)
+ ├── @ ModuleNode (location: (1,0)-(2,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (1,0)-(1,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (1,7)-(1,8))
+ │ │ └── name: :A
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (2,0)-(2,3) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (4,0)-(5,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (4,0)-(4,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (4,7)-(4,11))
+ │ │ ├── parent:
+ │ │ │ @ ConstantReadNode (location: (4,7)-(4,8))
+ │ │ │ └── name: :A
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (4,10)-(4,11))
+ │ │ │ └── name: :B
+ │ │ └── delimiter_loc: (4,8)-(4,10) = "::"
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (5,0)-(5,3) = "end"
+ │ └── name: :B
+ ├── @ ModuleNode (location: (7,0)-(8,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (7,0)-(7,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (7,7)-(7,14))
+ │ │ ├── parent:
+ │ │ │ @ ConstantPathNode (location: (7,7)-(7,11))
+ │ │ │ ├── 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) = "::"
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (8,0)-(8,3) = "end"
+ │ └── name: :C
+ └── @ ModuleNode (location: (10,0)-(16,3))
+ ├── locals: []
+ ├── module_keyword_loc: (10,0)-(10,6) = "module"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (10,7)-(10,8))
+ │ └── name: :A
+ ├── body:
+ │ @ StatementsNode (location: (11,2)-(15,5))
+ │ └── body: (length: 2)
+ │ ├── @ CallNode (location: (11,2)-(11,16))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :include
+ │ │ ├── message_loc: (11,2)-(11,9) = "include"
+ │ │ ├── opening_loc: (11,9)-(11,10) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (11,10)-(11,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (11,10)-(11,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ ConstantReadNode (location: (11,10)-(11,11))
+ │ │ │ │ └── name: :B
+ │ │ │ ├── call_operator_loc: (11,11)-(11,12) = "."
+ │ │ │ ├── name: :new
+ │ │ │ ├── message_loc: (11,12)-(11,15) = "new"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (11,15)-(11,16) = ")"
+ │ │ └── block: ∅
+ │ └── @ DefNode (location: (13,2)-(15,5))
+ │ ├── name: :foo
+ │ ├── name_loc: (13,6)-(13,9) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (14,4)-(14,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (14,4)-(14,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (14,4)-(14,5) = ":"
+ │ │ ├── value_loc: (14,5)-(14,8) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (13,2)-(13,5) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (15,2)-(15,5) = "end"
+ ├── end_keyword_loc: (16,0)-(16,3) = "end"
+ └── name: :A
diff --git a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
new file mode 100644
index 0000000000..8dc0849638
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
@@ -0,0 +1,509 @@
+@ ProgramNode (location: (1,0)-(24,10))
+├── locals: [:a, :h]
+└── statements:
+ @ StatementsNode (location: (1,0)-(24,10))
+ └── body: (length: 24)
+ ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,6))
+ │ ├── name_loc: (1,0)-(1,1) = "a"
+ │ ├── operator_loc: (1,2)-(1,4) = "+="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── name: :a
+ │ ├── operator: :+
+ │ └── depth: 0
+ ├── @ LocalVariableOperatorWriteNode (location: (2,0)-(2,6))
+ │ ├── name_loc: (2,0)-(2,1) = "a"
+ │ ├── operator_loc: (2,2)-(2,4) = "-="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (2,5)-(2,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── name: :a
+ │ ├── operator: :-
+ │ └── depth: 0
+ ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,7))
+ │ ├── name_loc: (3,0)-(3,1) = "a"
+ │ ├── operator_loc: (3,2)-(3,5) = "**="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,6)-(3,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── name: :a
+ │ ├── operator: :**
+ │ └── depth: 0
+ ├── @ LocalVariableOperatorWriteNode (location: (4,0)-(4,6))
+ │ ├── name_loc: (4,0)-(4,1) = "a"
+ │ ├── operator_loc: (4,2)-(4,4) = "*="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (4,5)-(4,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── name: :a
+ │ ├── operator: :*
+ │ └── depth: 0
+ ├── @ LocalVariableOperatorWriteNode (location: (5,0)-(5,6))
+ │ ├── name_loc: (5,0)-(5,1) = "a"
+ │ ├── operator_loc: (5,2)-(5,4) = "/="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (5,5)-(5,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── name: :a
+ │ ├── operator: :/
+ │ └── depth: 0
+ ├── @ LocalVariableAndWriteNode (location: (6,0)-(6,7))
+ │ ├── name_loc: (6,0)-(6,1) = "a"
+ │ ├── operator_loc: (6,2)-(6,5) = "&&="
+ │ ├── value:
+ │ │ @ CallNode (location: (6,6)-(6,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (6,6)-(6,7) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ LocalVariableOrWriteNode (location: (7,0)-(7,7))
+ │ ├── name_loc: (7,0)-(7,1) = "a"
+ │ ├── operator_loc: (7,2)-(7,5) = "||="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (7,6)-(7,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ CallNode (location: (8,0)-(8,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (8,0)-(8,9))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (8,1)-(8,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableOrWriteNode (location: (8,1)-(8,8))
+ │ │ │ ├── name_loc: (8,1)-(8,2) = "a"
+ │ │ │ ├── operator_loc: (8,3)-(8,6) = "||="
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (8,7)-(8,8))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (8,0)-(8,1) = "("
+ │ │ └── closing_loc: (8,8)-(8,9) = ")"
+ │ ├── call_operator_loc: (8,9)-(8,10) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (8,10)-(8,13) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (9,0)-(9,17))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (9,0)-(9,10))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (9,1)-(9,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableOrWriteNode (location: (9,1)-(9,9))
+ │ │ │ ├── name_loc: (9,1)-(9,2) = "h"
+ │ │ │ ├── operator_loc: (9,3)-(9,6) = "||="
+ │ │ │ ├── value:
+ │ │ │ │ @ HashNode (location: (9,7)-(9,9))
+ │ │ │ │ ├── opening_loc: (9,7)-(9,8) = "{"
+ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ └── closing_loc: (9,8)-(9,9) = "}"
+ │ │ │ ├── name: :h
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: (9,0)-(9,1) = "("
+ │ │ └── closing_loc: (9,9)-(9,10) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]=
+ │ ├── message_loc: (9,10)-(9,13) = "[k]"
+ │ ├── opening_loc: (9,10)-(9,11) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,11)-(9,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (9,11)-(9,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :k
+ │ │ │ ├── message_loc: (9,11)-(9,12) = "k"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (9,16)-(9,17))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :v
+ │ │ ├── message_loc: (9,16)-(9,17) = "v"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (9,12)-(9,13) = "]"
+ │ └── block: ∅
+ ├── @ CallOperatorWriteNode (location: (10,0)-(10,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (10,0)-(10,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (10,1)-(10,2) = "."
+ │ ├── message_loc: (10,2)-(10,3) = "b"
+ │ ├── read_name: :b
+ │ ├── write_name: :b=
+ │ ├── operator: :+
+ │ ├── operator_loc: (10,4)-(10,6) = "+="
+ │ └── value:
+ │ @ IntegerNode (location: (10,7)-(10,8))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ CallOperatorWriteNode (location: (11,0)-(11,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (11,0)-(11,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (11,1)-(11,2) = "."
+ │ ├── message_loc: (11,2)-(11,3) = "b"
+ │ ├── read_name: :b
+ │ ├── write_name: :b=
+ │ ├── operator: :-
+ │ ├── operator_loc: (11,4)-(11,6) = "-="
+ │ └── value:
+ │ @ IntegerNode (location: (11,7)-(11,8))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ CallOperatorWriteNode (location: (12,0)-(12,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (12,0)-(12,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (12,1)-(12,2) = "."
+ │ ├── message_loc: (12,2)-(12,3) = "b"
+ │ ├── read_name: :b
+ │ ├── write_name: :b=
+ │ ├── operator: :**
+ │ ├── operator_loc: (12,4)-(12,7) = "**="
+ │ └── value:
+ │ @ IntegerNode (location: (12,8)-(12,9))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ CallOperatorWriteNode (location: (13,0)-(13,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (13,0)-(13,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (13,1)-(13,2) = "."
+ │ ├── message_loc: (13,2)-(13,3) = "b"
+ │ ├── read_name: :b
+ │ ├── write_name: :b=
+ │ ├── operator: :*
+ │ ├── operator_loc: (13,4)-(13,6) = "*="
+ │ └── value:
+ │ @ IntegerNode (location: (13,7)-(13,8))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ CallOperatorWriteNode (location: (14,0)-(14,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (14,0)-(14,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (14,1)-(14,2) = "."
+ │ ├── message_loc: (14,2)-(14,3) = "b"
+ │ ├── read_name: :b
+ │ ├── write_name: :b=
+ │ ├── operator: :/
+ │ ├── operator_loc: (14,4)-(14,6) = "/="
+ │ └── value:
+ │ @ IntegerNode (location: (14,7)-(14,8))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ CallAndWriteNode (location: (15,0)-(15,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (15,0)-(15,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (15,1)-(15,2) = "."
+ │ ├── message_loc: (15,2)-(15,3) = "b"
+ │ ├── read_name: :b
+ │ ├── write_name: :b=
+ │ ├── operator_loc: (15,4)-(15,7) = "&&="
+ │ └── value:
+ │ @ CallNode (location: (15,8)-(15,9))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (15,8)-(15,9) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallOrWriteNode (location: (16,0)-(16,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (16,0)-(16,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (16,1)-(16,2) = "."
+ │ ├── message_loc: (16,2)-(16,3) = "b"
+ │ ├── read_name: :b
+ │ ├── write_name: :b=
+ │ ├── operator_loc: (16,4)-(16,7) = "||="
+ │ └── value:
+ │ @ IntegerNode (location: (16,8)-(16,9))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ IndexOperatorWriteNode (location: (17,0)-(17,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (17,0)-(17,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (17,1)-(17,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (17,2)-(17,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (17,2)-(17,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (17,2)-(17,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (17,3)-(17,4) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :+
+ │ ├── operator_loc: (17,5)-(17,7) = "+="
+ │ └── value:
+ │ @ IntegerNode (location: (17,8)-(17,9))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ IndexOperatorWriteNode (location: (18,0)-(18,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (18,0)-(18,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (18,1)-(18,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (18,2)-(18,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (18,2)-(18,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (18,2)-(18,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (18,3)-(18,4) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :-
+ │ ├── operator_loc: (18,5)-(18,7) = "-="
+ │ └── value:
+ │ @ IntegerNode (location: (18,8)-(18,9))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ IndexOperatorWriteNode (location: (19,0)-(19,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (19,0)-(19,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (19,1)-(19,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (19,2)-(19,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (19,2)-(19,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (19,2)-(19,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (19,3)-(19,4) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :**
+ │ ├── operator_loc: (19,5)-(19,8) = "**="
+ │ └── value:
+ │ @ IntegerNode (location: (19,9)-(19,10))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ IndexOperatorWriteNode (location: (20,0)-(20,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (20,0)-(20,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (20,1)-(20,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (20,2)-(20,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (20,2)-(20,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (20,2)-(20,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (20,3)-(20,4) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :*
+ │ ├── operator_loc: (20,5)-(20,7) = "*="
+ │ └── value:
+ │ @ IntegerNode (location: (20,8)-(20,9))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ IndexOperatorWriteNode (location: (21,0)-(21,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (21,0)-(21,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (21,1)-(21,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (21,2)-(21,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (21,2)-(21,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (21,2)-(21,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (21,3)-(21,4) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :/
+ │ ├── operator_loc: (21,5)-(21,7) = "/="
+ │ └── value:
+ │ @ IntegerNode (location: (21,8)-(21,9))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── @ IndexAndWriteNode (location: (22,0)-(22,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (22,0)-(22,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (22,1)-(22,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (22,2)-(22,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (22,2)-(22,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (22,2)-(22,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (22,3)-(22,4) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (22,5)-(22,8) = "&&="
+ │ └── value:
+ │ @ CallNode (location: (22,9)-(22,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (22,9)-(22,10) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ IndexOrWriteNode (location: (23,0)-(23,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (23,0)-(23,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (23,1)-(23,2) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (23,2)-(23,3))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (23,2)-(23,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (23,2)-(23,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (23,3)-(23,4) = "]"
+ │ ├── block: ∅
+ │ ├── operator_loc: (23,5)-(23,8) = "||="
+ │ └── value:
+ │ @ IntegerNode (location: (23,9)-(23,10))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── @ CallOperatorWriteNode (location: (24,0)-(24,10))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (24,0)-(24,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (24,0)-(24,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (24,3)-(24,4) = "."
+ ├── message_loc: (24,4)-(24,5) = "A"
+ ├── read_name: :A
+ ├── write_name: :A=
+ ├── operator: :+
+ ├── operator_loc: (24,6)-(24,8) = "+="
+ └── value:
+ @ IntegerNode (location: (24,9)-(24,10))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/unparser/corpus/literal/pattern.txt b/test/prism/snapshots/unparser/corpus/literal/pattern.txt
new file mode 100644
index 0000000000..5a0b4bb733
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/pattern.txt
@@ -0,0 +1,446 @@
+@ ProgramNode (location: (1,0)-(41,8))
+├── locals: [:a, :x, :y]
+└── statements:
+ @ StatementsNode (location: (1,0)-(41,8))
+ └── body: (length: 4)
+ ├── @ CaseMatchNode (location: (1,0)-(33,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,5)-(1,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 15)
+ │ │ ├── @ InNode (location: (2,0)-(3,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ ArrayPatternNode (location: (2,3)-(2,17))
+ │ │ │ │ ├── constant:
+ │ │ │ │ │ @ ConstantReadNode (location: (2,3)-(2,4))
+ │ │ │ │ │ └── name: :A
+ │ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ │ ├── @ IntegerNode (location: (2,5)-(2,6))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 1
+ │ │ │ │ │ └── @ IntegerNode (location: (2,8)-(2,9))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ SplatNode (location: (2,11)-(2,13))
+ │ │ │ │ │ ├── operator_loc: (2,11)-(2,12) = "*"
+ │ │ │ │ │ └── expression:
+ │ │ │ │ │ @ LocalVariableTargetNode (location: (2,12)-(2,13))
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ │ └── @ IntegerNode (location: (2,15)-(2,16))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 3
+ │ │ │ │ ├── opening_loc: (2,4)-(2,5) = "["
+ │ │ │ │ └── closing_loc: (2,16)-(2,17) = "]"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (3,2)-(3,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (3,2)-(3,6))
+ │ │ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ │ │ └── then_loc: (2,18)-(2,22) = "then"
+ │ │ ├── @ InNode (location: (4,0)-(5,3))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ ArrayPatternNode (location: (4,3)-(4,11))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ │ ├── @ IntegerNode (location: (4,4)-(4,5))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 1
+ │ │ │ │ │ └── @ IntegerNode (location: (4,7)-(4,8))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ ImplicitRestNode (location: (4,8)-(4,9))
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── opening_loc: (4,3)-(4,4) = "["
+ │ │ │ │ └── closing_loc: (4,10)-(4,11) = "]"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (5,2)-(5,3))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (5,2)-(5,3))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :y
+ │ │ │ │ ├── message_loc: (5,2)-(5,3) = "y"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── in_loc: (4,0)-(4,2) = "in"
+ │ │ │ └── then_loc: (4,12)-(4,16) = "then"
+ │ │ ├── @ InNode (location: (6,0)-(7,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ HashPatternNode (location: (6,3)-(6,8))
+ │ │ │ │ ├── constant:
+ │ │ │ │ │ @ ConstantReadNode (location: (6,3)-(6,4))
+ │ │ │ │ │ └── name: :A
+ │ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ │ └── @ AssocNode (location: (6,5)-(6,7))
+ │ │ │ │ │ ├── key:
+ │ │ │ │ │ │ @ SymbolNode (location: (6,5)-(6,7))
+ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── value_loc: (6,5)-(6,6) = "x"
+ │ │ │ │ │ │ ├── closing_loc: (6,6)-(6,7) = ":"
+ │ │ │ │ │ │ └── unescaped: "x"
+ │ │ │ │ │ ├── value:
+ │ │ │ │ │ │ @ ImplicitNode (location: (6,5)-(6,6))
+ │ │ │ │ │ │ └── value:
+ │ │ │ │ │ │ @ LocalVariableTargetNode (location: (6,5)-(6,6))
+ │ │ │ │ │ │ ├── name: :x
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ └── operator_loc: ∅
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── opening_loc: (6,4)-(6,5) = "("
+ │ │ │ │ └── closing_loc: (6,7)-(6,8) = ")"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (7,2)-(7,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (7,2)-(7,6))
+ │ │ │ ├── in_loc: (6,0)-(6,2) = "in"
+ │ │ │ └── then_loc: (6,9)-(6,13) = "then"
+ │ │ ├── @ InNode (location: (8,0)-(9,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ HashPatternNode (location: (8,3)-(8,8))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ AssocSplatNode (location: (8,4)-(8,7))
+ │ │ │ │ │ ├── value:
+ │ │ │ │ │ │ @ LocalVariableTargetNode (location: (8,6)-(8,7))
+ │ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ └── operator_loc: (8,4)-(8,6) = "**"
+ │ │ │ │ ├── opening_loc: (8,3)-(8,4) = "{"
+ │ │ │ │ └── closing_loc: (8,7)-(8,8) = "}"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (9,2)-(9,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (9,2)-(9,6))
+ │ │ │ ├── in_loc: (8,0)-(8,2) = "in"
+ │ │ │ └── then_loc: (8,9)-(8,13) = "then"
+ │ │ ├── @ InNode (location: (10,0)-(11,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ IfNode (location: (10,3)-(10,13))
+ │ │ │ │ ├── if_keyword_loc: (10,6)-(10,8) = "if"
+ │ │ │ │ ├── predicate:
+ │ │ │ │ │ @ TrueNode (location: (10,9)-(10,13))
+ │ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (10,3)-(10,5))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ HashPatternNode (location: (10,3)-(10,5))
+ │ │ │ │ │ ├── constant: ∅
+ │ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ │ ├── rest: ∅
+ │ │ │ │ │ ├── opening_loc: (10,3)-(10,4) = "{"
+ │ │ │ │ │ └── closing_loc: (10,4)-(10,5) = "}"
+ │ │ │ │ ├── consequent: ∅
+ │ │ │ │ └── end_keyword_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (11,2)-(11,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (11,2)-(11,6))
+ │ │ │ ├── in_loc: (10,0)-(10,2) = "in"
+ │ │ │ └── then_loc: (10,14)-(10,18) = "then"
+ │ │ ├── @ InNode (location: (12,0)-(13,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ ArrayPatternNode (location: (12,3)-(12,12))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ │ ├── @ LocalVariableTargetNode (location: (12,4)-(12,5))
+ │ │ │ │ │ │ ├── name: :x
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ └── @ LocalVariableTargetNode (location: (12,7)-(12,8))
+ │ │ │ │ │ ├── name: :y
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ SplatNode (location: (12,10)-(12,11))
+ │ │ │ │ │ ├── operator_loc: (12,10)-(12,11) = "*"
+ │ │ │ │ │ └── expression: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── opening_loc: (12,3)-(12,4) = "["
+ │ │ │ │ └── closing_loc: (12,11)-(12,12) = "]"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (13,2)-(13,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (13,2)-(13,6))
+ │ │ │ ├── in_loc: (12,0)-(12,2) = "in"
+ │ │ │ └── then_loc: (12,13)-(12,17) = "then"
+ │ │ ├── @ InNode (location: (14,0)-(15,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ HashPatternNode (location: (14,3)-(14,16))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── elements: (length: 2)
+ │ │ │ │ │ ├── @ AssocNode (location: (14,4)-(14,8))
+ │ │ │ │ │ │ ├── key:
+ │ │ │ │ │ │ │ @ SymbolNode (location: (14,4)-(14,6))
+ │ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ │ ├── value_loc: (14,4)-(14,5) = "a"
+ │ │ │ │ │ │ │ ├── closing_loc: (14,5)-(14,6) = ":"
+ │ │ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ │ │ ├── value:
+ │ │ │ │ │ │ │ @ IntegerNode (location: (14,7)-(14,8))
+ │ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ │ └── value: 1
+ │ │ │ │ │ │ └── operator_loc: ∅
+ │ │ │ │ │ └── @ AssocNode (location: (14,10)-(14,15))
+ │ │ │ │ │ ├── key:
+ │ │ │ │ │ │ @ SymbolNode (location: (14,10)-(14,13))
+ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── value_loc: (14,10)-(14,12) = "aa"
+ │ │ │ │ │ │ ├── closing_loc: (14,12)-(14,13) = ":"
+ │ │ │ │ │ │ └── unescaped: "aa"
+ │ │ │ │ │ ├── value:
+ │ │ │ │ │ │ @ IntegerNode (location: (14,14)-(14,15))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 2
+ │ │ │ │ │ └── operator_loc: ∅
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── opening_loc: (14,3)-(14,4) = "{"
+ │ │ │ │ └── closing_loc: (14,15)-(14,16) = "}"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (15,2)-(15,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (15,2)-(15,6))
+ │ │ │ ├── in_loc: (14,0)-(14,2) = "in"
+ │ │ │ └── then_loc: (14,17)-(14,21) = "then"
+ │ │ ├── @ InNode (location: (16,0)-(17,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ HashPatternNode (location: (16,3)-(16,5))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── opening_loc: (16,3)-(16,4) = "{"
+ │ │ │ │ └── closing_loc: (16,4)-(16,5) = "}"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (17,2)-(17,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (17,2)-(17,6))
+ │ │ │ ├── in_loc: (16,0)-(16,2) = "in"
+ │ │ │ └── then_loc: (16,6)-(16,10) = "then"
+ │ │ ├── @ InNode (location: (18,0)-(19,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ HashPatternNode (location: (18,3)-(18,10))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── elements: (length: 0)
+ │ │ │ │ ├── rest:
+ │ │ │ │ │ @ NoKeywordsParameterNode (location: (18,4)-(18,9))
+ │ │ │ │ │ ├── operator_loc: (18,4)-(18,6) = "**"
+ │ │ │ │ │ └── keyword_loc: (18,6)-(18,9) = "nil"
+ │ │ │ │ ├── opening_loc: (18,3)-(18,4) = "{"
+ │ │ │ │ └── closing_loc: (18,9)-(18,10) = "}"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (19,2)-(19,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (19,2)-(19,6))
+ │ │ │ ├── in_loc: (18,0)-(18,2) = "in"
+ │ │ │ └── then_loc: (18,11)-(18,15) = "then"
+ │ │ ├── @ InNode (location: (20,0)-(21,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ HashPatternNode (location: (20,3)-(20,11))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ │ └── @ AssocNode (location: (20,4)-(20,10))
+ │ │ │ │ │ ├── key:
+ │ │ │ │ │ │ @ SymbolNode (location: (20,4)-(20,8))
+ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ ├── opening_loc: (20,4)-(20,5) = "\""
+ │ │ │ │ │ │ ├── value_loc: (20,5)-(20,6) = "a"
+ │ │ │ │ │ │ ├── closing_loc: (20,6)-(20,8) = "\":"
+ │ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ │ ├── value:
+ │ │ │ │ │ │ @ IntegerNode (location: (20,9)-(20,10))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 1
+ │ │ │ │ │ └── operator_loc: ∅
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── opening_loc: (20,3)-(20,4) = "{"
+ │ │ │ │ └── closing_loc: (20,10)-(20,11) = "}"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (21,2)-(21,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (21,2)-(21,6))
+ │ │ │ ├── in_loc: (20,0)-(20,2) = "in"
+ │ │ │ └── then_loc: (20,12)-(20,16) = "then"
+ │ │ ├── @ InNode (location: (22,0)-(23,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ AlternationPatternNode (location: (22,3)-(22,8))
+ │ │ │ │ ├── left:
+ │ │ │ │ │ @ IntegerNode (location: (22,3)-(22,4))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── right:
+ │ │ │ │ │ @ IntegerNode (location: (22,7)-(22,8))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 2
+ │ │ │ │ └── operator_loc: (22,5)-(22,6) = "|"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (23,2)-(23,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (23,2)-(23,6))
+ │ │ │ ├── in_loc: (22,0)-(22,2) = "in"
+ │ │ │ └── then_loc: (22,9)-(22,13) = "then"
+ │ │ ├── @ InNode (location: (24,0)-(25,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ CapturePatternNode (location: (24,3)-(24,9))
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ IntegerNode (location: (24,3)-(24,4))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── target:
+ │ │ │ │ │ @ LocalVariableTargetNode (location: (24,8)-(24,9))
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── operator_loc: (24,5)-(24,7) = "=>"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (25,2)-(25,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (25,2)-(25,6))
+ │ │ │ ├── in_loc: (24,0)-(24,2) = "in"
+ │ │ │ └── then_loc: (24,10)-(24,14) = "then"
+ │ │ ├── @ InNode (location: (26,0)-(27,6))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ PinnedVariableNode (location: (26,3)-(26,5))
+ │ │ │ │ ├── variable:
+ │ │ │ │ │ @ LocalVariableReadNode (location: (26,4)-(26,5))
+ │ │ │ │ │ ├── name: :x
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── operator_loc: (26,3)-(26,4) = "^"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (27,2)-(27,6))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ TrueNode (location: (27,2)-(27,6))
+ │ │ │ ├── in_loc: (26,0)-(26,2) = "in"
+ │ │ │ └── then_loc: (26,6)-(26,10) = "then"
+ │ │ ├── @ InNode (location: (28,0)-(28,4))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ IntegerNode (location: (28,3)-(28,4))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── statements: ∅
+ │ │ │ ├── in_loc: (28,0)-(28,2) = "in"
+ │ │ │ └── then_loc: ∅
+ │ │ └── @ InNode (location: (29,0)-(30,6))
+ │ │ ├── pattern:
+ │ │ │ @ IntegerNode (location: (29,3)-(29,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (30,2)-(30,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ TrueNode (location: (30,2)-(30,6))
+ │ │ ├── in_loc: (29,0)-(29,2) = "in"
+ │ │ └── then_loc: (29,5)-(29,9) = "then"
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (31,0)-(33,3))
+ │ │ ├── else_keyword_loc: (31,0)-(31,4) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (32,2)-(32,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ TrueNode (location: (32,2)-(32,6))
+ │ │ └── end_keyword_loc: (33,0)-(33,3) = "end"
+ │ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ │ └── end_keyword_loc: (33,0)-(33,3) = "end"
+ ├── @ CaseMatchNode (location: (34,0)-(36,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (34,5)-(34,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (34,5)-(34,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (35,0)-(35,17))
+ │ │ ├── pattern:
+ │ │ │ @ ArrayPatternNode (location: (35,3)-(35,17))
+ │ │ │ ├── constant:
+ │ │ │ │ @ ConstantReadNode (location: (35,3)-(35,4))
+ │ │ │ │ └── name: :A
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ IntegerNode (location: (35,5)-(35,6))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── @ IntegerNode (location: (35,8)-(35,9))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (35,11)-(35,13))
+ │ │ │ │ ├── operator_loc: (35,11)-(35,12) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ LocalVariableTargetNode (location: (35,12)-(35,13))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (35,15)-(35,16))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 3
+ │ │ │ ├── opening_loc: (35,4)-(35,5) = "["
+ │ │ │ └── closing_loc: (35,16)-(35,17) = "]"
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (35,0)-(35,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (34,0)-(34,4) = "case"
+ │ └── end_keyword_loc: (36,0)-(36,3) = "end"
+ ├── @ CaseMatchNode (location: (37,0)-(40,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (37,5)-(37,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (37,5)-(37,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 1)
+ │ │ └── @ InNode (location: (38,0)-(38,4))
+ │ │ ├── pattern:
+ │ │ │ @ ConstantReadNode (location: (38,3)-(38,4))
+ │ │ │ └── name: :A
+ │ │ ├── statements: ∅
+ │ │ ├── in_loc: (38,0)-(38,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (39,0)-(40,3))
+ │ │ ├── else_keyword_loc: (39,0)-(39,4) = "else"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (40,0)-(40,3) = "end"
+ │ ├── case_keyword_loc: (37,0)-(37,4) = "case"
+ │ └── end_keyword_loc: (40,0)-(40,3) = "end"
+ └── @ MatchPredicateNode (location: (41,0)-(41,8))
+ ├── value:
+ │ @ IntegerNode (location: (41,0)-(41,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── pattern:
+ │ @ ArrayPatternNode (location: (41,5)-(41,8))
+ │ ├── constant: ∅
+ │ ├── requireds: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (41,6)-(41,7))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── opening_loc: (41,5)-(41,6) = "["
+ │ └── closing_loc: (41,7)-(41,8) = "]"
+ └── operator_loc: (41,2)-(41,4) = "in"
diff --git a/test/prism/snapshots/unparser/corpus/literal/pragma.txt b/test/prism/snapshots/unparser/corpus/literal/pragma.txt
new file mode 100644
index 0000000000..08e386b872
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/pragma.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(4,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,7))
+ └── body: (length: 4)
+ ├── @ SourceEncodingNode (location: (1,0)-(1,12))
+ ├── @ SourceFileNode (location: (2,0)-(2,8))
+ │ ├── flags: ∅
+ │ └── filepath: "unparser/corpus/literal/pragma.txt"
+ ├── @ SourceLineNode (location: (3,0)-(3,8))
+ └── @ CallNode (location: (4,0)-(4,7))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :__dir__
+ ├── message_loc: (4,0)-(4,7) = "__dir__"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/unparser/corpus/literal/range.txt b/test/prism/snapshots/unparser/corpus/literal/range.txt
new file mode 100644
index 0000000000..ab015d04fc
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/range.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(4,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,5))
+ └── body: (length: 4)
+ ├── @ ParenthesesNode (location: (1,0)-(1,5))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,1)-(1,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RangeNode (location: (1,1)-(1,4))
+ │ │ ├── flags: ∅
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (1,1)-(1,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (1,2)-(1,4) = ".."
+ │ ├── opening_loc: (1,0)-(1,1) = "("
+ │ └── closing_loc: (1,4)-(1,5) = ")"
+ ├── @ RangeNode (location: (2,0)-(2,4))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (2,0)-(2,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ IntegerNode (location: (2,3)-(2,4))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: (2,1)-(2,3) = ".."
+ ├── @ ParenthesesNode (location: (3,0)-(3,6))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,1)-(3,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RangeNode (location: (3,1)-(3,5))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left:
+ │ │ │ @ IntegerNode (location: (3,1)-(3,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── right: ∅
+ │ │ └── operator_loc: (3,2)-(3,5) = "..."
+ │ ├── opening_loc: (3,0)-(3,1) = "("
+ │ └── closing_loc: (3,5)-(3,6) = ")"
+ └── @ RangeNode (location: (4,0)-(4,5))
+ ├── flags: exclude_end
+ ├── left:
+ │ @ IntegerNode (location: (4,0)-(4,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── right:
+ │ @ IntegerNode (location: (4,4)-(4,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── operator_loc: (4,1)-(4,4) = "..."
diff --git a/test/prism/snapshots/unparser/corpus/literal/rescue.txt b/test/prism/snapshots/unparser/corpus/literal/rescue.txt
new file mode 100644
index 0000000000..d84366f3f5
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/rescue.txt
@@ -0,0 +1,101 @@
+@ ProgramNode (location: (1,0)-(3,27))
+├── locals: [:x]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,27))
+ └── body: (length: 3)
+ ├── @ RescueModifierNode (location: (1,0)-(1,14))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,4)-(1,10) = "rescue"
+ │ └── rescue_expression:
+ │ @ CallNode (location: (1,11)-(1,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,11)-(1,14) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ RescueModifierNode (location: (2,0)-(2,21))
+ │ ├── expression:
+ │ │ @ CallNode (location: (2,0)-(2,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (2,0)-(2,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (2,4)-(2,10) = "rescue"
+ │ └── rescue_expression:
+ │ @ ReturnNode (location: (2,11)-(2,21))
+ │ ├── keyword_loc: (2,11)-(2,17) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (2,18)-(2,21))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (2,18)-(2,21))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (2,18)-(2,21) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ LocalVariableWriteNode (location: (3,0)-(3,27))
+ ├── name: :x
+ ├── depth: 0
+ ├── name_loc: (3,0)-(3,1) = "x"
+ ├── value:
+ │ @ ParenthesesNode (location: (3,4)-(3,27))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,5)-(3,26))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (3,5)-(3,26))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (3,5)-(3,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (3,5)-(3,8) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (3,9)-(3,15) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ ReturnNode (location: (3,16)-(3,26))
+ │ │ ├── keyword_loc: (3,16)-(3,22) = "return"
+ │ │ └── arguments:
+ │ │ @ ArgumentsNode (location: (3,23)-(3,26))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,23)-(3,26))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,23)-(3,26) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (3,4)-(3,5) = "("
+ │ └── closing_loc: (3,26)-(3,27) = ")"
+ └── operator_loc: (3,2)-(3,3) = "="
diff --git a/test/prism/snapshots/unparser/corpus/literal/send.txt b/test/prism/snapshots/unparser/corpus/literal/send.txt
new file mode 100644
index 0000000000..b7eb064717
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/send.txt
@@ -0,0 +1,2190 @@
+@ ProgramNode (location: (1,0)-(84,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(84,7))
+ └── body: (length: 62)
+ ├── @ ModuleNode (location: (1,0)-(3,3))
+ │ ├── locals: [:foo, :a, :_]
+ │ ├── module_keyword_loc: (1,0)-(1,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (1,7)-(1,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,2)-(2,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableOrWriteNode (location: (2,2)-(2,22))
+ │ │ ├── name_loc: (2,2)-(2,5) = "foo"
+ │ │ ├── operator_loc: (2,6)-(2,9) = "||="
+ │ │ ├── value:
+ │ │ │ @ ParenthesesNode (location: (2,10)-(2,22))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (2,11)-(2,21))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ MultiWriteNode (location: (2,11)-(2,21))
+ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ ├── @ LocalVariableTargetNode (location: (2,12)-(2,13))
+ │ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ └── @ LocalVariableTargetNode (location: (2,15)-(2,16))
+ │ │ │ │ │ ├── name: :_
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (2,11)-(2,12) = "("
+ │ │ │ │ ├── rparen_loc: (2,16)-(2,17) = ")"
+ │ │ │ │ ├── operator_loc: (2,18)-(2,19) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ CallNode (location: (2,20)-(2,21))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (2,20)-(2,21) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (2,10)-(2,11) = "("
+ │ │ │ └── closing_loc: (2,21)-(2,22) = ")"
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── end_keyword_loc: (3,0)-(3,3) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (5,0)-(8,3))
+ │ ├── locals: [:local]
+ │ ├── module_keyword_loc: (5,0)-(5,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (5,7)-(5,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (6,2)-(7,11))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ LocalVariableWriteNode (location: (6,2)-(6,11))
+ │ │ │ ├── name: :local
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (6,2)-(6,7) = "local"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (6,10)-(6,11))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: (6,8)-(6,9) = "="
+ │ │ └── @ CallNode (location: (7,2)-(7,11))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ LocalVariableReadNode (location: (7,2)-(7,7))
+ │ │ │ ├── name: :local
+ │ │ │ └── depth: 0
+ │ │ ├── call_operator_loc: (7,7)-(7,8) = "."
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (7,8)-(7,11) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── end_keyword_loc: (8,0)-(8,3) = "end"
+ │ └── name: :A
+ ├── @ CallNode (location: (9,0)-(10,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ClassNode (location: (9,0)-(10,3))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (9,0)-(9,5) = "class"
+ │ │ ├── constant_path:
+ │ │ │ @ ConstantReadNode (location: (9,6)-(9,7))
+ │ │ │ └── name: :A
+ │ │ ├── inheritance_operator_loc: ∅
+ │ │ ├── superclass: ∅
+ │ │ ├── body: ∅
+ │ │ ├── end_keyword_loc: (10,0)-(10,3) = "end"
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (10,3)-(10,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (10,4)-(10,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (11,0)-(12,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ModuleNode (location: (11,0)-(12,3))
+ │ │ ├── locals: []
+ │ │ ├── module_keyword_loc: (11,0)-(11,6) = "module"
+ │ │ ├── constant_path:
+ │ │ │ @ ConstantReadNode (location: (11,7)-(11,8))
+ │ │ │ └── name: :A
+ │ │ ├── body: ∅
+ │ │ ├── end_keyword_loc: (12,0)-(12,3) = "end"
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (12,3)-(12,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (12,4)-(12,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (13,0)-(15,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ BeginNode (location: (13,0)-(15,3))
+ │ │ ├── begin_keyword_loc: (13,0)-(13,5) = "begin"
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (14,0)-(14,6))
+ │ │ │ ├── keyword_loc: (14,0)-(14,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (15,0)-(15,3) = "end"
+ │ ├── call_operator_loc: (15,3)-(15,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (15,4)-(15,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (16,0)-(19,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CaseNode (location: (16,0)-(19,3))
+ │ │ ├── predicate:
+ │ │ │ @ ParenthesesNode (location: (16,5)-(17,10))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (16,6)-(17,9))
+ │ │ │ │ └── body: (length: 2)
+ │ │ │ │ ├── @ DefNode (location: (16,6)-(17,3))
+ │ │ │ │ │ ├── name: :foo
+ │ │ │ │ │ ├── name_loc: (16,10)-(16,13) = "foo"
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── def_keyword_loc: (16,6)-(16,9) = "def"
+ │ │ │ │ │ ├── operator_loc: ∅
+ │ │ │ │ │ ├── lparen_loc: ∅
+ │ │ │ │ │ ├── rparen_loc: ∅
+ │ │ │ │ │ ├── equal_loc: ∅
+ │ │ │ │ │ └── end_keyword_loc: (17,0)-(17,3) = "end"
+ │ │ │ │ └── @ SymbolNode (location: (17,5)-(17,9))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (17,5)-(17,6) = ":"
+ │ │ │ │ ├── value_loc: (17,6)-(17,9) = "bar"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "bar"
+ │ │ │ ├── opening_loc: (16,5)-(16,6) = "("
+ │ │ │ └── closing_loc: (17,9)-(17,10) = ")"
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ WhenNode (location: (18,0)-(18,8))
+ │ │ │ ├── keyword_loc: (18,0)-(18,4) = "when"
+ │ │ │ ├── conditions: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (18,5)-(18,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (18,5)-(18,8) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ └── statements: ∅
+ │ │ ├── consequent: ∅
+ │ │ ├── case_keyword_loc: (16,0)-(16,4) = "case"
+ │ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ │ ├── call_operator_loc: (19,3)-(19,4) = "."
+ │ ├── name: :baz
+ │ ├── message_loc: (19,4)-(19,7) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (20,0)-(22,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CaseNode (location: (20,0)-(22,3))
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (20,5)-(20,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (20,5)-(20,8) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── conditions: (length: 1)
+ │ │ │ └── @ WhenNode (location: (21,0)-(21,8))
+ │ │ │ ├── keyword_loc: (21,0)-(21,4) = "when"
+ │ │ │ ├── conditions: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (21,5)-(21,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (21,5)-(21,8) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── then_keyword_loc: ∅
+ │ │ │ └── statements: ∅
+ │ │ ├── consequent: ∅
+ │ │ ├── case_keyword_loc: (20,0)-(20,4) = "case"
+ │ │ └── end_keyword_loc: (22,0)-(22,3) = "end"
+ │ ├── call_operator_loc: (22,3)-(22,4) = "."
+ │ ├── name: :baz
+ │ ├── message_loc: (22,4)-(22,7) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (23,0)-(24,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ SingletonClassNode (location: (23,0)-(24,3))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (23,0)-(23,5) = "class"
+ │ │ ├── operator_loc: (23,6)-(23,8) = "<<"
+ │ │ ├── expression:
+ │ │ │ @ SelfNode (location: (23,9)-(23,13))
+ │ │ ├── body: ∅
+ │ │ └── end_keyword_loc: (24,0)-(24,3) = "end"
+ │ ├── call_operator_loc: (24,3)-(24,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (24,4)-(24,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (25,0)-(26,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ DefNode (location: (25,0)-(26,3))
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (25,9)-(25,12) = "foo"
+ │ │ ├── receiver:
+ │ │ │ @ SelfNode (location: (25,4)-(25,8))
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── locals: []
+ │ │ ├── def_keyword_loc: (25,0)-(25,3) = "def"
+ │ │ ├── operator_loc: (25,8)-(25,9) = "."
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (26,0)-(26,3) = "end"
+ │ ├── call_operator_loc: (26,3)-(26,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (26,4)-(26,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (27,0)-(28,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ DefNode (location: (27,0)-(28,3))
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (27,4)-(27,7) = "foo"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── locals: []
+ │ │ ├── def_keyword_loc: (27,0)-(27,3) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (28,0)-(28,3) = "end"
+ │ ├── call_operator_loc: (28,3)-(28,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (28,4)-(28,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (29,0)-(30,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ UntilNode (location: (29,0)-(30,3))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (29,0)-(29,5) = "until"
+ │ │ ├── closing_loc: (30,0)-(30,3) = "end"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (29,6)-(29,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (29,6)-(29,9) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── statements: ∅
+ │ ├── call_operator_loc: (30,3)-(30,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (30,4)-(30,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (31,0)-(32,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ WhileNode (location: (31,0)-(32,3))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (31,0)-(31,5) = "while"
+ │ │ ├── closing_loc: (32,0)-(32,3) = "end"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (31,6)-(31,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (31,6)-(31,9) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── statements: ∅
+ │ ├── call_operator_loc: (32,3)-(32,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (32,4)-(32,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (33,0)-(34,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (33,0)-(34,1))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :loop
+ │ │ ├── message_loc: (33,0)-(33,4) = "loop"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (33,5)-(34,1))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (33,5)-(33,6) = "{"
+ │ │ └── closing_loc: (34,0)-(34,1) = "}"
+ │ ├── call_operator_loc: (34,1)-(34,2) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (34,2)-(34,5) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (35,0)-(36,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IfNode (location: (35,0)-(36,3))
+ │ │ ├── if_keyword_loc: (35,0)-(35,2) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (35,3)-(35,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (35,3)-(35,6) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: (36,0)-(36,3) = "end"
+ │ ├── call_operator_loc: (36,3)-(36,4) = "."
+ │ ├── name: :baz
+ │ ├── message_loc: (36,4)-(36,7) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (37,0)-(37,19))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (37,0)-(37,15))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (37,1)-(37,14))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (37,1)-(37,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ RegularExpressionNode (location: (37,1)-(37,6))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (37,1)-(37,2) = "/"
+ │ │ │ │ ├── content_loc: (37,2)-(37,5) = "bar"
+ │ │ │ │ ├── closing_loc: (37,5)-(37,6) = "/"
+ │ │ │ │ └── unescaped: "bar"
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :=~
+ │ │ │ ├── message_loc: (37,7)-(37,9) = "=~"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (37,10)-(37,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (37,10)-(37,14))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (37,10)-(37,11) = ":"
+ │ │ │ │ ├── value_loc: (37,11)-(37,14) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (37,0)-(37,1) = "("
+ │ │ └── closing_loc: (37,14)-(37,15) = ")"
+ │ ├── call_operator_loc: (37,15)-(37,16) = "."
+ │ ├── name: :foo
+ │ ├── message_loc: (37,16)-(37,19) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (38,0)-(38,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (38,0)-(38,6))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (38,1)-(38,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ RangeNode (location: (38,1)-(38,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── left:
+ │ │ │ │ @ IntegerNode (location: (38,1)-(38,2))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── right:
+ │ │ │ │ @ IntegerNode (location: (38,4)-(38,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── operator_loc: (38,2)-(38,4) = ".."
+ │ │ ├── opening_loc: (38,0)-(38,1) = "("
+ │ │ └── closing_loc: (38,5)-(38,6) = ")"
+ │ ├── call_operator_loc: (38,6)-(38,7) = "."
+ │ ├── name: :max
+ │ ├── message_loc: (38,7)-(38,10) = "max"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (39,0)-(39,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (39,0)-(39,14))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (39,1)-(39,13))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (39,1)-(39,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (39,1)-(39,4))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (39,1)-(39,4) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :=~
+ │ │ │ ├── message_loc: (39,5)-(39,7) = "=~"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (39,8)-(39,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ RegularExpressionNode (location: (39,8)-(39,13))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (39,8)-(39,9) = "/"
+ │ │ │ │ ├── content_loc: (39,9)-(39,12) = "bar"
+ │ │ │ │ ├── closing_loc: (39,12)-(39,13) = "/"
+ │ │ │ │ └── unescaped: "bar"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (39,0)-(39,1) = "("
+ │ │ └── closing_loc: (39,13)-(39,14) = ")"
+ │ ├── call_operator_loc: (39,14)-(39,15) = "."
+ │ ├── name: :foo
+ │ ├── message_loc: (39,15)-(39,18) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (40,0)-(40,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RegularExpressionNode (location: (40,0)-(40,5))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (40,0)-(40,1) = "/"
+ │ │ ├── content_loc: (40,1)-(40,4) = "bar"
+ │ │ ├── closing_loc: (40,4)-(40,5) = "/"
+ │ │ └── unescaped: "bar"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (40,6)-(40,8) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (40,9)-(40,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (40,9)-(40,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (40,9)-(40,10) = ":"
+ │ │ ├── value_loc: (40,10)-(40,13) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (41,0)-(41,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ RegularExpressionNode (location: (41,0)-(41,5))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (41,0)-(41,1) = "/"
+ │ │ ├── content_loc: (41,1)-(41,4) = "bar"
+ │ │ ├── closing_loc: (41,4)-(41,5) = "/"
+ │ │ └── unescaped: "bar"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (41,6)-(41,8) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (41,9)-(41,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (41,9)-(41,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (41,9)-(41,12) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ RangeNode (location: (42,0)-(42,8))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ IntegerNode (location: (42,0)-(42,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── right:
+ │ │ @ CallNode (location: (42,3)-(42,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (42,3)-(42,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── call_operator_loc: (42,4)-(42,5) = "."
+ │ │ ├── name: :max
+ │ │ ├── message_loc: (42,5)-(42,8) = "max"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (42,1)-(42,3) = ".."
+ ├── @ CallNode (location: (43,0)-(43,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (43,0)-(43,1))
+ │ │ └── name: :A
+ │ ├── call_operator_loc: (43,1)-(43,2) = "."
+ │ ├── name: :foo
+ │ ├── message_loc: (43,2)-(43,5) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (44,0)-(44,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :FOO
+ │ ├── message_loc: (44,0)-(44,3) = "FOO"
+ │ ├── opening_loc: (44,3)-(44,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (44,4)-(44,5) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (45,0)-(45,4))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (45,0)-(45,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (45,0)-(45,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (45,1)-(45,3) = "&."
+ │ ├── name: :b
+ │ ├── message_loc: (45,3)-(45,4) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (46,0)-(46,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (46,0)-(46,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (46,0)-(46,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (46,1)-(46,2) = "."
+ │ ├── name: :foo
+ │ ├── message_loc: (46,2)-(46,5) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (47,0)-(47,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (47,0)-(47,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (48,0)-(48,18))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (48,0)-(48,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (48,0)-(48,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<<
+ │ ├── message_loc: (48,4)-(48,6) = "<<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (48,7)-(48,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ParenthesesNode (location: (48,7)-(48,18))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (48,8)-(48,17))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (48,8)-(48,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (48,8)-(48,11))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (48,8)-(48,11) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :*
+ │ │ │ ├── message_loc: (48,12)-(48,13) = "*"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (48,14)-(48,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (48,14)-(48,17))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (48,14)-(48,17) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (48,7)-(48,8) = "("
+ │ │ └── closing_loc: (48,17)-(48,18) = ")"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (49,0)-(49,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (49,0)-(49,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (49,0)-(49,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (49,4)-(49,6) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (49,7)-(49,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ RegularExpressionNode (location: (49,7)-(49,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (49,7)-(49,8) = "/"
+ │ │ ├── content_loc: (49,8)-(49,11) = "bar"
+ │ │ ├── closing_loc: (49,11)-(49,12) = "/"
+ │ │ └── unescaped: "bar"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (50,0)-(50,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (50,0)-(50,3) = "foo"
+ │ ├── opening_loc: (50,3)-(50,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (50,17)-(50,18) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (50,4)-(50,17))
+ │ ├── expression:
+ │ │ @ ParenthesesNode (location: (50,5)-(50,17))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (50,6)-(50,16))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ OrNode (location: (50,6)-(50,16))
+ │ │ │ ├── left:
+ │ │ │ │ @ CallNode (location: (50,6)-(50,9))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (50,6)-(50,9) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ CallNode (location: (50,13)-(50,16))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (50,13)-(50,16) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (50,10)-(50,12) = "||"
+ │ │ ├── opening_loc: (50,5)-(50,6) = "("
+ │ │ └── closing_loc: (50,16)-(50,17) = ")"
+ │ └── operator_loc: (50,4)-(50,5) = "&"
+ ├── @ CallNode (location: (51,0)-(51,10))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (51,0)-(51,3) = "foo"
+ │ ├── opening_loc: (51,3)-(51,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (51,10)-(51,11) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (51,4)-(51,10))
+ │ ├── expression:
+ │ │ @ CallNode (location: (51,5)-(51,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :block
+ │ │ ├── message_loc: (51,5)-(51,10) = "block"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (51,4)-(51,5) = "&"
+ ├── @ CallNode (location: (52,0)-(52,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (52,0)-(52,3) = "foo"
+ │ ├── opening_loc: (52,3)-(52,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (52,4)-(52,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (52,4)-(52,9))
+ │ │ ├── operator_loc: (52,4)-(52,5) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (52,5)-(52,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :args
+ │ │ ├── message_loc: (52,5)-(52,9) = "args"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (52,17)-(52,18) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (52,11)-(52,17))
+ │ ├── expression:
+ │ │ @ CallNode (location: (52,12)-(52,17))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :block
+ │ │ ├── message_loc: (52,12)-(52,17) = "block"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (52,11)-(52,12) = "&"
+ ├── @ CallNode (location: (53,0)-(53,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (53,0)-(53,3) = "foo"
+ │ ├── opening_loc: (53,3)-(53,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (53,4)-(53,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (53,4)-(53,14))
+ │ │ ├── operator_loc: (53,4)-(53,5) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (53,5)-(53,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :arguments
+ │ │ ├── message_loc: (53,5)-(53,14) = "arguments"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (53,14)-(53,15) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (54,0)-(54,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (54,0)-(54,3) = "foo"
+ │ ├── opening_loc: (54,3)-(54,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (54,4)-(54,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (54,4)-(54,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (54,7)-(54,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: (54,8)-(54,9) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (55,0)-(55,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (55,0)-(55,3) = "foo"
+ │ ├── opening_loc: (55,3)-(55,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (55,4)-(55,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (55,4)-(55,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (55,4)-(55,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (55,7)-(55,8) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (56,0)-(56,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (56,0)-(56,3) = "foo"
+ │ ├── opening_loc: (56,3)-(56,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (56,4)-(56,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (56,4)-(56,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (56,4)-(56,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ SplatNode (location: (56,9)-(56,14))
+ │ │ ├── operator_loc: (56,9)-(56,10) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (56,10)-(56,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :args
+ │ │ ├── message_loc: (56,10)-(56,14) = "args"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (56,14)-(56,15) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (57,0)-(57,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (57,0)-(57,3) = "foo"
+ │ ├── opening_loc: (57,3)-(57,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (57,4)-(57,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (57,4)-(57,16))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (57,4)-(57,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (57,4)-(57,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (57,8)-(57,10) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (57,11)-(57,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ RegularExpressionNode (location: (57,11)-(57,16))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (57,11)-(57,12) = "/"
+ │ │ │ ├── content_loc: (57,12)-(57,15) = "bar"
+ │ │ │ ├── closing_loc: (57,15)-(57,16) = "/"
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (57,16)-(57,17) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (58,0)-(58,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (58,0)-(58,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (58,0)-(58,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (58,3)-(58,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (58,4)-(58,7) = "bar"
+ │ ├── opening_loc: (58,7)-(58,8) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (58,12)-(58,13) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (58,8)-(58,12))
+ │ ├── expression:
+ │ │ @ CallNode (location: (58,9)-(58,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (58,9)-(58,12) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (58,8)-(58,9) = "&"
+ ├── @ CallNode (location: (59,0)-(59,26))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (59,0)-(59,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (59,0)-(59,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (59,3)-(59,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (59,4)-(59,7) = "bar"
+ │ ├── opening_loc: (59,7)-(59,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (59,8)-(59,25))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ SplatNode (location: (59,8)-(59,13))
+ │ │ │ ├── operator_loc: (59,8)-(59,9) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (59,9)-(59,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :arga
+ │ │ │ ├── message_loc: (59,9)-(59,13) = "arga"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── @ CallNode (location: (59,15)-(59,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (59,15)-(59,18) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ SplatNode (location: (59,20)-(59,25))
+ │ │ ├── operator_loc: (59,20)-(59,21) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (59,21)-(59,25))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :argb
+ │ │ ├── message_loc: (59,21)-(59,25) = "argb"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (59,25)-(59,26) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (60,0)-(60,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (60,0)-(60,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (60,0)-(60,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (60,3)-(60,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (60,4)-(60,7) = "bar"
+ │ ├── opening_loc: (60,7)-(60,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (60,8)-(60,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (60,8)-(60,13))
+ │ │ ├── operator_loc: (60,8)-(60,9) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (60,9)-(60,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :args
+ │ │ ├── message_loc: (60,9)-(60,13) = "args"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (60,13)-(60,14) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (61,0)-(61,19))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (61,0)-(61,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (61,0)-(61,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (61,3)-(61,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (61,4)-(61,7) = "bar"
+ │ ├── opening_loc: (61,7)-(61,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (61,8)-(61,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SplatNode (location: (61,8)-(61,13))
+ │ │ │ ├── operator_loc: (61,8)-(61,9) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (61,9)-(61,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :args
+ │ │ │ ├── message_loc: (61,9)-(61,13) = "args"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (61,15)-(61,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (61,15)-(61,18) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (61,18)-(61,19) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (62,0)-(62,19))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (62,0)-(62,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (62,0)-(62,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (62,3)-(62,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (62,4)-(62,7) = "bar"
+ │ ├── opening_loc: (62,7)-(62,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (62,8)-(62,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (62,8)-(62,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (62,8)-(62,9) = ":"
+ │ │ ├── value_loc: (62,9)-(62,12) = "baz"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz"
+ │ ├── closing_loc: (62,18)-(62,19) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (62,14)-(62,18))
+ │ ├── expression:
+ │ │ @ CallNode (location: (62,15)-(62,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (62,15)-(62,18) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (62,14)-(62,15) = "&"
+ ├── @ CallNode (location: (63,0)-(63,17))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (63,0)-(63,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (63,0)-(63,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (63,3)-(63,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (63,4)-(63,7) = "bar"
+ │ ├── opening_loc: (63,7)-(63,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (63,8)-(63,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (63,8)-(63,16))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (63,8)-(63,16))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (63,8)-(63,12))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (63,8)-(63,11) = "baz"
+ │ │ │ ├── closing_loc: (63,11)-(63,12) = ":"
+ │ │ │ └── unescaped: "baz"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (63,13)-(63,16))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :boz
+ │ │ │ ├── message_loc: (63,13)-(63,16) = "boz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (63,16)-(63,17) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (64,0)-(64,26))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (64,0)-(64,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (64,0)-(64,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (64,3)-(64,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (64,4)-(64,7) = "bar"
+ │ ├── opening_loc: (64,7)-(64,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (64,8)-(64,25))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (64,8)-(64,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (64,8)-(64,11) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ KeywordHashNode (location: (64,13)-(64,25))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (64,13)-(64,25))
+ │ │ ├── key:
+ │ │ │ @ StringNode (location: (64,13)-(64,18))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (64,13)-(64,14) = "\""
+ │ │ │ ├── content_loc: (64,14)-(64,17) = "baz"
+ │ │ │ ├── closing_loc: (64,17)-(64,18) = "\""
+ │ │ │ └── unescaped: "baz"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (64,22)-(64,25))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :boz
+ │ │ │ ├── message_loc: (64,22)-(64,25) = "boz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (64,19)-(64,21) = "=>"
+ │ ├── closing_loc: (64,25)-(64,26) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (65,0)-(65,19))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (65,0)-(65,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (65,0)-(65,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (65,3)-(65,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (65,4)-(65,7) = "bar"
+ │ ├── opening_loc: (65,7)-(65,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (65,8)-(65,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (65,8)-(65,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (65,8)-(65,11) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ SplatNode (location: (65,13)-(65,18))
+ │ │ ├── operator_loc: (65,13)-(65,14) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (65,14)-(65,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :args
+ │ │ ├── message_loc: (65,14)-(65,18) = "args"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (65,18)-(65,19) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (66,0)-(66,27))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (66,0)-(66,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (66,0)-(66,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (66,3)-(66,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (66,4)-(66,7) = "bar"
+ │ ├── opening_loc: (66,7)-(66,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (66,8)-(66,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (66,8)-(66,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (66,8)-(66,11) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ SplatNode (location: (66,13)-(66,18))
+ │ │ ├── operator_loc: (66,13)-(66,14) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (66,14)-(66,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :args
+ │ │ ├── message_loc: (66,14)-(66,18) = "args"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (66,26)-(66,27) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (66,20)-(66,26))
+ │ ├── expression:
+ │ │ @ CallNode (location: (66,21)-(66,26))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :block
+ │ │ ├── message_loc: (66,21)-(66,26) = "block"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (66,20)-(66,21) = "&"
+ ├── @ CallNode (location: (67,0)-(67,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (67,0)-(67,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (67,0)-(67,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (67,3)-(67,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (67,4)-(67,7) = "bar"
+ │ ├── opening_loc: (67,7)-(67,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (67,8)-(67,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (67,8)-(67,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (67,8)-(67,11) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ HashNode (location: (67,13)-(67,15))
+ │ │ ├── opening_loc: (67,13)-(67,14) = "{"
+ │ │ ├── elements: (length: 0)
+ │ │ └── closing_loc: (67,14)-(67,15) = "}"
+ │ ├── closing_loc: (67,15)-(67,16) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (68,0)-(68,26))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (68,0)-(68,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (68,0)-(68,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (68,3)-(68,4) = "."
+ │ ├── name: :bar
+ │ ├── message_loc: (68,4)-(68,7) = "bar"
+ │ ├── opening_loc: (68,7)-(68,8) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (68,8)-(68,25))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ HashNode (location: (68,8)-(68,20))
+ │ │ │ ├── opening_loc: (68,8)-(68,9) = "{"
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ AssocNode (location: (68,10)-(68,18))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (68,10)-(68,14))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (68,10)-(68,13) = "foo"
+ │ │ │ │ │ ├── closing_loc: (68,13)-(68,14) = ":"
+ │ │ │ │ │ └── unescaped: "foo"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (68,15)-(68,18))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :boz
+ │ │ │ │ │ ├── message_loc: (68,15)-(68,18) = "boz"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ └── closing_loc: (68,19)-(68,20) = "}"
+ │ │ └── @ CallNode (location: (68,22)-(68,25))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :boz
+ │ │ ├── message_loc: (68,22)-(68,25) = "boz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (68,25)-(68,26) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (69,0)-(69,12))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ CallNode (location: (69,0)-(69,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (69,0)-(69,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (69,3)-(69,4) = "."
+ │ ├── name: :bar=
+ │ ├── message_loc: (69,4)-(69,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (69,8)-(69,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (69,8)-(69,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (69,8)-(69,9) = ":"
+ │ │ ├── value_loc: (69,9)-(69,12) = "baz"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (70,0)-(70,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (70,0)-(70,3) = "foo"
+ │ ├── opening_loc: (70,3)-(70,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (70,4)-(70,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (70,4)-(70,8))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (70,4)-(70,8))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (70,4)-(70,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (70,4)-(70,5) = "a"
+ │ │ │ ├── closing_loc: (70,5)-(70,6) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (70,7)-(70,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (70,7)-(70,8) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (70,8)-(70,9) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (71,0)-(71,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (71,0)-(71,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (71,0)-(71,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (71,3)-(71,4) = "."
+ │ ├── name: :&
+ │ ├── message_loc: (71,4)-(71,5) = "&"
+ │ ├── opening_loc: (71,5)-(71,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (71,6)-(71,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (71,6)-(71,10))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (71,6)-(71,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (71,6)-(71,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (71,6)-(71,7) = "a"
+ │ │ │ ├── closing_loc: (71,7)-(71,8) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (71,9)-(71,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (71,9)-(71,10) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (71,10)-(71,11) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (72,0)-(72,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (72,0)-(72,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (72,0)-(72,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (72,3)-(72,4) = "."
+ │ ├── name: :&
+ │ ├── message_loc: (72,4)-(72,5) = "&"
+ │ ├── opening_loc: (72,5)-(72,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (72,6)-(72,9))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (72,6)-(72,9))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (72,6)-(72,9))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (72,8)-(72,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (72,8)-(72,9) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (72,6)-(72,8) = "**"
+ │ ├── closing_loc: (72,9)-(72,10) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (73,0)-(73,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (73,0)-(73,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (73,0)-(73,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (73,3)-(73,9) = "[*baz]"
+ │ ├── opening_loc: (73,3)-(73,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (73,4)-(73,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (73,4)-(73,8))
+ │ │ ├── operator_loc: (73,4)-(73,5) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (73,5)-(73,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (73,5)-(73,8) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (73,8)-(73,9) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (74,0)-(74,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (74,0)-(74,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (74,0)-(74,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (74,3)-(74,9) = "[1, 2]"
+ │ ├── opening_loc: (74,3)-(74,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (74,4)-(74,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ IntegerNode (location: (74,4)-(74,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (74,7)-(74,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── closing_loc: (74,8)-(74,9) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (75,0)-(75,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (75,0)-(75,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (75,0)-(75,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (75,3)-(75,5) = "[]"
+ │ ├── opening_loc: (75,3)-(75,4) = "["
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (75,4)-(75,5) = "]"
+ │ └── block: ∅
+ ├── @ CallNode (location: (76,0)-(76,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (76,0)-(76,4))
+ │ ├── call_operator_loc: (76,4)-(76,5) = "."
+ │ ├── name: :foo
+ │ ├── message_loc: (76,5)-(76,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (77,0)-(77,13))
+ │ ├── flags: attribute_write, ignore_visibility
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (77,0)-(77,4))
+ │ ├── call_operator_loc: (77,4)-(77,5) = "."
+ │ ├── name: :foo=
+ │ ├── message_loc: (77,5)-(77,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (77,9)-(77,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (77,9)-(77,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (77,9)-(77,10) = ":"
+ │ │ ├── value_loc: (77,10)-(77,13) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (78,0)-(78,17))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (78,0)-(78,7))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (78,1)-(78,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (78,1)-(78,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (78,1)-(78,2))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (78,1)-(78,2) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+
+ │ │ │ ├── message_loc: (78,3)-(78,4) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (78,5)-(78,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (78,5)-(78,6))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (78,5)-(78,6) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (78,0)-(78,1) = "("
+ │ │ └── closing_loc: (78,6)-(78,7) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :/
+ │ ├── message_loc: (78,8)-(78,9) = "/"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (78,10)-(78,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ParenthesesNode (location: (78,10)-(78,17))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (78,11)-(78,16))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (78,11)-(78,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (78,11)-(78,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (78,11)-(78,12) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :-
+ │ │ │ ├── message_loc: (78,13)-(78,14) = "-"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (78,15)-(78,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (78,15)-(78,16))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :d
+ │ │ │ │ ├── message_loc: (78,15)-(78,16) = "d"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (78,10)-(78,11) = "("
+ │ │ └── closing_loc: (78,16)-(78,17) = ")"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (79,0)-(79,19))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (79,0)-(79,7))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (79,1)-(79,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (79,1)-(79,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (79,1)-(79,2))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (79,1)-(79,2) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+
+ │ │ │ ├── message_loc: (79,3)-(79,4) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (79,5)-(79,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (79,5)-(79,6))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (79,5)-(79,6) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (79,0)-(79,1) = "("
+ │ │ └── closing_loc: (79,6)-(79,7) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :/
+ │ ├── message_loc: (79,8)-(79,9) = "/"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (79,10)-(79,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (79,10)-(79,19))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (79,10)-(79,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (79,10)-(79,11) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (79,11)-(79,12) = "."
+ │ │ ├── name: :-
+ │ │ ├── message_loc: (79,12)-(79,13) = "-"
+ │ │ ├── opening_loc: (79,13)-(79,14) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (79,14)-(79,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ CallNode (location: (79,14)-(79,15))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :e
+ │ │ │ │ ├── message_loc: (79,14)-(79,15) = "e"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── @ CallNode (location: (79,17)-(79,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :f
+ │ │ │ ├── message_loc: (79,17)-(79,18) = "f"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (79,18)-(79,19) = ")"
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (80,0)-(80,17))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (80,0)-(80,7))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (80,1)-(80,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (80,1)-(80,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (80,1)-(80,2))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (80,1)-(80,2) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+
+ │ │ │ ├── message_loc: (80,3)-(80,4) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (80,5)-(80,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (80,5)-(80,6))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (80,5)-(80,6) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (80,0)-(80,1) = "("
+ │ │ └── closing_loc: (80,6)-(80,7) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :/
+ │ ├── message_loc: (80,8)-(80,9) = "/"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (80,10)-(80,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (80,10)-(80,17))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (80,10)-(80,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (80,10)-(80,11) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (80,11)-(80,12) = "."
+ │ │ ├── name: :-
+ │ │ ├── message_loc: (80,12)-(80,13) = "-"
+ │ │ ├── opening_loc: (80,13)-(80,14) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (80,14)-(80,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SplatNode (location: (80,14)-(80,16))
+ │ │ │ ├── operator_loc: (80,14)-(80,15) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (80,15)-(80,16))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :f
+ │ │ │ ├── message_loc: (80,15)-(80,16) = "f"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (80,16)-(80,17) = ")"
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (81,0)-(81,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :x
+ │ ├── message_loc: (81,0)-(81,1) = "x"
+ │ ├── opening_loc: (81,1)-(81,2) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (81,2)-(81,7))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (81,2)-(81,7))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (81,2)-(81,7))
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (81,4)-(81,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (81,4)-(81,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (81,2)-(81,4) = "**"
+ │ ├── closing_loc: (81,7)-(81,8) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (82,0)-(82,6))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (82,0)-(82,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (82,0)-(82,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (82,3)-(82,5) = "&."
+ │ ├── name: :!
+ │ ├── message_loc: (82,5)-(82,6) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (83,0)-(83,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (83,0)-(83,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (83,0)-(83,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (83,3)-(83,4) = "."
+ │ ├── name: :~
+ │ ├── message_loc: (83,4)-(83,5) = "~"
+ │ ├── opening_loc: (83,5)-(83,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (83,6)-(83,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (83,6)-(83,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (83,6)-(83,7) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (83,7)-(83,8) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (84,0)-(84,7))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (84,0)-(84,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (84,0)-(84,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (84,1)-(84,3) = "&."
+ ├── name: :+
+ ├── message_loc: (84,3)-(84,4) = "+"
+ ├── opening_loc: (84,4)-(84,5) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (84,5)-(84,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (84,5)-(84,6))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (84,5)-(84,6) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (84,6)-(84,7) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/unparser/corpus/literal/since/27.txt b/test/prism/snapshots/unparser/corpus/literal/since/27.txt
new file mode 100644
index 0000000000..60edc18604
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/since/27.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(4,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,5))
+ └── body: (length: 2)
+ ├── @ LambdaNode (location: (1,0)-(3,1))
+ │ ├── locals: [:_1, :_2]
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (1,3)-(1,4) = "{"
+ │ ├── closing_loc: (3,0)-(3,1) = "}"
+ │ ├── parameters:
+ │ │ @ NumberedParametersNode (location: (1,0)-(3,1))
+ │ │ └── maximum: 2
+ │ └── body:
+ │ @ StatementsNode (location: (2,2)-(2,9))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,2)-(2,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (2,2)-(2,4))
+ │ │ ├── name: :_1
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (2,5)-(2,6) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (2,7)-(2,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (2,7)-(2,9))
+ │ │ ├── name: :_2
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ ParenthesesNode (location: (4,0)-(4,5))
+ ├── body:
+ │ @ StatementsNode (location: (4,1)-(4,4))
+ │ └── body: (length: 1)
+ │ └── @ RangeNode (location: (4,1)-(4,4))
+ │ ├── flags: ∅
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ IntegerNode (location: (4,3)-(4,4))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (4,1)-(4,3) = ".."
+ ├── opening_loc: (4,0)-(4,1) = "("
+ └── closing_loc: (4,4)-(4,5) = ")"
diff --git a/test/prism/snapshots/unparser/corpus/literal/since/30.txt b/test/prism/snapshots/unparser/corpus/literal/since/30.txt
new file mode 100644
index 0000000000..300dd869f5
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/since/30.txt
@@ -0,0 +1,88 @@
+@ ProgramNode (location: (1,0)-(4,17))
+├── locals: [:a, :foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,17))
+ └── body: (length: 4)
+ ├── @ MatchRequiredNode (location: (1,0)-(1,8))
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (1,5)-(1,8))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (1,5)-(1,6) = "["
+ │ │ └── closing_loc: (1,7)-(1,8) = "]"
+ │ └── operator_loc: (1,2)-(1,4) = "=>"
+ ├── @ MatchRequiredNode (location: (2,0)-(2,8))
+ │ ├── value:
+ │ │ @ IntegerNode (location: (2,0)-(2,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,5)-(2,8))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ SplatNode (location: (2,6)-(2,7))
+ │ │ │ ├── operator_loc: (2,6)-(2,7) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,5)-(2,6) = "["
+ │ │ └── closing_loc: (2,7)-(2,8) = "]"
+ │ └── operator_loc: (2,2)-(2,4) = "=>"
+ ├── @ MatchPredicateNode (location: (3,0)-(3,15))
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,0)-(3,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── pattern:
+ │ │ @ FindPatternNode (location: (3,5)-(3,15))
+ │ │ ├── constant: ∅
+ │ │ ├── left:
+ │ │ │ @ SplatNode (location: (3,6)-(3,7))
+ │ │ │ ├── operator_loc: (3,6)-(3,7) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,9)-(3,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── right:
+ │ │ │ @ SplatNode (location: (3,13)-(3,14))
+ │ │ │ ├── operator_loc: (3,13)-(3,14) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── opening_loc: (3,5)-(3,6) = "["
+ │ │ └── closing_loc: (3,14)-(3,15) = "]"
+ │ └── operator_loc: (3,2)-(3,4) = "in"
+ └── @ MatchPredicateNode (location: (4,0)-(4,17))
+ ├── value:
+ │ @ IntegerNode (location: (4,0)-(4,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── pattern:
+ │ @ FindPatternNode (location: (4,5)-(4,17))
+ │ ├── constant: ∅
+ │ ├── left:
+ │ │ @ SplatNode (location: (4,6)-(4,7))
+ │ │ ├── operator_loc: (4,6)-(4,7) = "*"
+ │ │ └── expression: ∅
+ │ ├── requireds: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (4,9)-(4,10))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── right:
+ │ │ @ SplatNode (location: (4,12)-(4,16))
+ │ │ ├── operator_loc: (4,12)-(4,13) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (4,13)-(4,16))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── opening_loc: (4,5)-(4,6) = "["
+ │ └── closing_loc: (4,16)-(4,17) = "]"
+ └── operator_loc: (4,2)-(4,4) = "in"
diff --git a/test/prism/snapshots/unparser/corpus/literal/since/31.txt b/test/prism/snapshots/unparser/corpus/literal/since/31.txt
new file mode 100644
index 0000000000..142a56ae83
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/since/31.txt
@@ -0,0 +1,90 @@
+@ ProgramNode (location: (1,0)-(7,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,3))
+ └── body: (length: 2)
+ ├── @ DefNode (location: (1,0)-(3,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,8)-(1,9))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,8)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,8)-(1,9) = "&"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,2)-(2,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,2)-(2,7))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (2,2)-(2,5) = "bar"
+ │ │ ├── opening_loc: (2,5)-(2,6) = "("
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: (2,7)-(2,8) = ")"
+ │ │ └── block:
+ │ │ @ BlockArgumentNode (location: (2,6)-(2,7))
+ │ │ ├── expression: ∅
+ │ │ └── operator_loc: (2,6)-(2,7) = "&"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ ├── rparen_loc: (1,9)-(1,10) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ └── @ DefNode (location: (5,0)-(7,3))
+ ├── name: :foo
+ ├── name_loc: (5,4)-(5,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (5,8)-(5,12))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (5,8)-(5,9))
+ │ │ ├── flags: ∅
+ │ │ └── name: :a
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block:
+ │ @ BlockParameterNode (location: (5,11)-(5,12))
+ │ ├── flags: ∅
+ │ ├── name: ∅
+ │ ├── name_loc: ∅
+ │ └── operator_loc: (5,11)-(5,12) = "&"
+ ├── body:
+ │ @ StatementsNode (location: (6,2)-(6,7))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (6,2)-(6,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (6,2)-(6,5) = "bar"
+ │ ├── opening_loc: (6,5)-(6,6) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (6,7)-(6,8) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (6,6)-(6,7))
+ │ ├── expression: ∅
+ │ └── operator_loc: (6,6)-(6,7) = "&"
+ ├── locals: [:a]
+ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (5,7)-(5,8) = "("
+ ├── rparen_loc: (5,12)-(5,13) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (7,0)-(7,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/since/32.txt b/test/prism/snapshots/unparser/corpus/literal/since/32.txt
new file mode 100644
index 0000000000..e72be6d8b7
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/since/32.txt
@@ -0,0 +1,156 @@
+@ ProgramNode (location: (1,0)-(11,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,3))
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,0)-(3,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,8)-(1,20))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,8)-(1,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :argument
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (1,18)-(1,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (1,18)-(1,20) = "**"
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,2)-(2,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,2)-(2,19))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (2,2)-(2,5) = "bar"
+ │ │ ├── opening_loc: (2,5)-(2,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (2,6)-(2,18))
+ │ │ │ ├── flags: contains_keyword_splat
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ LocalVariableReadNode (location: (2,6)-(2,14))
+ │ │ │ │ ├── name: :argument
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ KeywordHashNode (location: (2,16)-(2,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── elements: (length: 1)
+ │ │ │ └── @ AssocSplatNode (location: (2,16)-(2,18))
+ │ │ │ ├── value: ∅
+ │ │ │ └── operator_loc: (2,16)-(2,18) = "**"
+ │ │ ├── closing_loc: (2,18)-(2,19) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: [:argument]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ ├── rparen_loc: (1,20)-(1,21) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ DefNode (location: (5,0)-(7,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (5,4)-(5,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (5,8)-(5,19))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (5,8)-(5,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :argument
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (5,18)-(5,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (5,18)-(5,19) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (6,2)-(6,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (6,2)-(6,18))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (6,2)-(6,5) = "bar"
+ │ │ ├── opening_loc: (6,5)-(6,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (6,6)-(6,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ LocalVariableReadNode (location: (6,6)-(6,14))
+ │ │ │ │ ├── name: :argument
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ SplatNode (location: (6,16)-(6,17))
+ │ │ │ ├── operator_loc: (6,16)-(6,17) = "*"
+ │ │ │ └── expression: ∅
+ │ │ ├── closing_loc: (6,17)-(6,18) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: [:argument]
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (5,7)-(5,8) = "("
+ │ ├── rparen_loc: (5,19)-(5,20) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (7,0)-(7,3) = "end"
+ └── @ DefNode (location: (9,0)-(11,3))
+ ├── name: :foo
+ ├── name_loc: (9,4)-(9,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (9,8)-(9,10))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (9,8)-(9,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (9,8)-(9,10) = "**"
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (10,2)-(10,20))
+ │ └── body: (length: 1)
+ │ └── @ HashNode (location: (10,2)-(10,20))
+ │ ├── opening_loc: (10,2)-(10,3) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (10,4)-(10,14))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (10,4)-(10,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (10,4)-(10,11) = "default"
+ │ │ │ │ ├── closing_loc: (10,11)-(10,12) = ":"
+ │ │ │ │ └── unescaped: "default"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (10,13)-(10,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: ∅
+ │ │ └── @ AssocSplatNode (location: (10,16)-(10,18))
+ │ │ ├── value: ∅
+ │ │ └── operator_loc: (10,16)-(10,18) = "**"
+ │ └── closing_loc: (10,19)-(10,20) = "}"
+ ├── locals: []
+ ├── def_keyword_loc: (9,0)-(9,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (9,7)-(9,8) = "("
+ ├── rparen_loc: (9,10)-(9,11) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (11,0)-(11,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/literal/singletons.txt b/test/prism/snapshots/unparser/corpus/literal/singletons.txt
new file mode 100644
index 0000000000..45c06f7b07
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/singletons.txt
@@ -0,0 +1,9 @@
+@ ProgramNode (location: (1,0)-(4,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,4))
+ └── body: (length: 4)
+ ├── @ FalseNode (location: (1,0)-(1,5))
+ ├── @ NilNode (location: (2,0)-(2,3))
+ ├── @ SelfNode (location: (3,0)-(3,4))
+ └── @ TrueNode (location: (4,0)-(4,4))
diff --git a/test/prism/snapshots/unparser/corpus/literal/super.txt b/test/prism/snapshots/unparser/corpus/literal/super.txt
new file mode 100644
index 0000000000..d5a7889919
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/super.txt
@@ -0,0 +1,277 @@
+@ ProgramNode (location: (1,0)-(21,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(21,1))
+ └── body: (length: 11)
+ ├── @ ForwardingSuperNode (location: (1,0)-(1,5))
+ │ └── block: ∅
+ ├── @ SuperNode (location: (2,0)-(2,7))
+ │ ├── keyword_loc: (2,0)-(2,5) = "super"
+ │ ├── lparen_loc: (2,5)-(2,6) = "("
+ │ ├── arguments: ∅
+ │ ├── rparen_loc: (2,6)-(2,7) = ")"
+ │ └── block: ∅
+ ├── @ SuperNode (location: (3,0)-(3,8))
+ │ ├── keyword_loc: (3,0)-(3,5) = "super"
+ │ ├── lparen_loc: (3,5)-(3,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,6)-(3,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,6)-(3,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (3,6)-(3,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rparen_loc: (3,7)-(3,8) = ")"
+ │ └── block: ∅
+ ├── @ SuperNode (location: (4,0)-(4,11))
+ │ ├── keyword_loc: (4,0)-(4,5) = "super"
+ │ ├── lparen_loc: (4,5)-(4,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (4,6)-(4,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (4,6)-(4,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (4,6)-(4,7) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (4,9)-(4,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (4,9)-(4,10) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rparen_loc: (4,10)-(4,11) = ")"
+ │ └── block: ∅
+ ├── @ SuperNode (location: (5,0)-(5,13))
+ │ ├── keyword_loc: (5,0)-(5,5) = "super"
+ │ ├── lparen_loc: (5,5)-(5,6) = "("
+ │ ├── arguments: ∅
+ │ ├── rparen_loc: (5,12)-(5,13) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (5,6)-(5,12))
+ │ ├── expression:
+ │ │ @ CallNode (location: (5,7)-(5,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :block
+ │ │ ├── message_loc: (5,7)-(5,12) = "block"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (5,6)-(5,7) = "&"
+ ├── @ SuperNode (location: (6,0)-(6,16))
+ │ ├── keyword_loc: (6,0)-(6,5) = "super"
+ │ ├── lparen_loc: (6,5)-(6,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (6,6)-(6,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (6,6)-(6,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (6,6)-(6,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rparen_loc: (6,15)-(6,16) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (6,9)-(6,15))
+ │ ├── expression:
+ │ │ @ CallNode (location: (6,10)-(6,15))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :block
+ │ │ ├── message_loc: (6,10)-(6,15) = "block"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (6,9)-(6,10) = "&"
+ ├── @ SuperNode (location: (7,0)-(9,2))
+ │ ├── keyword_loc: (7,0)-(7,5) = "super"
+ │ ├── lparen_loc: (7,5)-(7,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,6)-(9,1))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (7,6)-(9,1))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (7,6)-(7,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (7,8)-(9,1))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (8,2)-(8,5))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (8,2)-(8,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (8,2)-(8,5) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (7,8)-(7,9) = "{"
+ │ │ └── closing_loc: (9,0)-(9,1) = "}"
+ │ ├── rparen_loc: (9,1)-(9,2) = ")"
+ │ └── block: ∅
+ ├── @ ForwardingSuperNode (location: (10,0)-(12,1))
+ │ └── block:
+ │ @ BlockNode (location: (10,6)-(12,1))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (11,2)-(11,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (11,2)-(11,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (11,2)-(11,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (10,6)-(10,7) = "{"
+ │ └── closing_loc: (12,0)-(12,1) = "}"
+ ├── @ SuperNode (location: (13,0)-(15,1))
+ │ ├── keyword_loc: (13,0)-(13,5) = "super"
+ │ ├── lparen_loc: (13,5)-(13,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,6)-(13,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (13,6)-(13,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (13,6)-(13,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rparen_loc: (13,7)-(13,8) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (13,9)-(15,1))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (14,2)-(14,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (14,2)-(14,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (14,2)-(14,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (13,9)-(13,10) = "{"
+ │ └── closing_loc: (15,0)-(15,1) = "}"
+ ├── @ SuperNode (location: (16,0)-(18,1))
+ │ ├── keyword_loc: (16,0)-(16,5) = "super"
+ │ ├── lparen_loc: (16,5)-(16,6) = "("
+ │ ├── arguments: ∅
+ │ ├── rparen_loc: (16,6)-(16,7) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (16,8)-(18,1))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (17,2)-(17,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (17,2)-(17,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (17,2)-(17,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (16,8)-(16,9) = "{"
+ │ └── closing_loc: (18,0)-(18,1) = "}"
+ └── @ SuperNode (location: (19,0)-(21,1))
+ ├── keyword_loc: (19,0)-(19,5) = "super"
+ ├── lparen_loc: (19,5)-(19,6) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (19,6)-(19,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (19,6)-(19,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (19,6)-(19,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ CallNode (location: (19,9)-(19,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (19,9)-(19,10) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rparen_loc: (19,10)-(19,11) = ")"
+ └── block:
+ @ BlockNode (location: (19,12)-(21,1))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (20,2)-(20,5))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (20,2)-(20,5))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (20,2)-(20,5) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (19,12)-(19,13) = "{"
+ └── closing_loc: (21,0)-(21,1) = "}"
diff --git a/test/prism/snapshots/unparser/corpus/literal/unary.txt b/test/prism/snapshots/unparser/corpus/literal/unary.txt
new file mode 100644
index 0000000000..5e9563d811
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/unary.txt
@@ -0,0 +1,248 @@
+@ ProgramNode (location: (1,0)-(8,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(8,9))
+ └── body: (length: 8)
+ ├── @ CallNode (location: (1,0)-(1,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (1,1)-(1,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,0)-(1,1) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (2,0)-(2,5))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (2,1)-(2,5))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (2,2)-(2,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,2)-(2,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ IntegerNode (location: (2,3)-(2,4))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :!
+ │ │ │ ├── message_loc: (2,2)-(2,3) = "!"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (2,1)-(2,2) = "("
+ │ │ └── closing_loc: (2,4)-(2,5) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (2,0)-(2,1) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (3,1)-(3,16))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (3,2)-(3,15))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,2)-(3,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ ParenthesesNode (location: (3,3)-(3,15))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (3,4)-(3,14))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ OrNode (location: (3,4)-(3,14))
+ │ │ │ │ │ ├── left:
+ │ │ │ │ │ │ @ CallNode (location: (3,4)-(3,7))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :foo
+ │ │ │ │ │ │ ├── message_loc: (3,4)-(3,7) = "foo"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ ├── right:
+ │ │ │ │ │ │ @ CallNode (location: (3,11)-(3,14))
+ │ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ │ ├── name: :bar
+ │ │ │ │ │ │ ├── message_loc: (3,11)-(3,14) = "bar"
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ │ └── block: ∅
+ │ │ │ │ │ └── operator_loc: (3,8)-(3,10) = "||"
+ │ │ │ │ ├── opening_loc: (3,3)-(3,4) = "("
+ │ │ │ │ └── closing_loc: (3,14)-(3,15) = ")"
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :!
+ │ │ │ ├── message_loc: (3,2)-(3,3) = "!"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (3,1)-(3,2) = "("
+ │ │ └── closing_loc: (3,15)-(3,16) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (3,0)-(3,1) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (4,0)-(4,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (4,1)-(4,9))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ ParenthesesNode (location: (4,1)-(4,5))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (4,2)-(4,4))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (4,2)-(4,4))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── receiver:
+ │ │ │ │ │ @ IntegerNode (location: (4,3)-(4,4))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :!
+ │ │ │ │ ├── message_loc: (4,2)-(4,3) = "!"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (4,1)-(4,2) = "("
+ │ │ │ └── closing_loc: (4,4)-(4,5) = ")"
+ │ │ ├── call_operator_loc: (4,5)-(4,6) = "."
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (4,6)-(4,9) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (4,0)-(4,1) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (5,1)-(5,2))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (5,1)-(5,2) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :~
+ │ ├── message_loc: (5,0)-(5,1) = "~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (6,0)-(6,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (6,1)-(6,2))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (6,1)-(6,2) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :-@
+ │ ├── message_loc: (6,0)-(6,1) = "-"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (7,0)-(7,2))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (7,1)-(7,2))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (7,1)-(7,2) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+@
+ │ ├── message_loc: (7,0)-(7,1) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (8,0)-(8,9))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (8,1)-(8,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (8,1)-(8,5))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (8,2)-(8,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (8,2)-(8,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (8,3)-(8,4))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (8,3)-(8,4) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :-@
+ │ │ │ ├── message_loc: (8,2)-(8,3) = "-"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (8,1)-(8,2) = "("
+ │ │ └── closing_loc: (8,4)-(8,5) = ")"
+ │ ├── call_operator_loc: (8,5)-(8,6) = "."
+ │ ├── name: :foo
+ │ ├── message_loc: (8,6)-(8,9) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :-@
+ ├── message_loc: (8,0)-(8,1) = "-"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/unparser/corpus/literal/undef.txt b/test/prism/snapshots/unparser/corpus/literal/undef.txt
new file mode 100644
index 0000000000..282cbe8f87
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/undef.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(2,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,16))
+ └── body: (length: 2)
+ ├── @ UndefNode (location: (1,0)-(1,10))
+ │ ├── names: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,6)-(1,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,6)-(1,7) = ":"
+ │ │ ├── value_loc: (1,7)-(1,10) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── keyword_loc: (1,0)-(1,5) = "undef"
+ └── @ UndefNode (location: (2,0)-(2,16))
+ ├── names: (length: 2)
+ │ ├── @ SymbolNode (location: (2,6)-(2,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (2,6)-(2,7) = ":"
+ │ │ ├── value_loc: (2,7)-(2,10) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── @ SymbolNode (location: (2,12)-(2,16))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (2,12)-(2,13) = ":"
+ │ ├── value_loc: (2,13)-(2,16) = "bar"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "bar"
+ └── keyword_loc: (2,0)-(2,5) = "undef"
diff --git a/test/prism/snapshots/unparser/corpus/literal/variables.txt b/test/prism/snapshots/unparser/corpus/literal/variables.txt
new file mode 100644
index 0000000000..bf79de385c
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/variables.txt
@@ -0,0 +1,53 @@
+@ ProgramNode (location: (1,0)-(10,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(10,17))
+ └── body: (length: 10)
+ ├── @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ InstanceVariableReadNode (location: (2,0)-(2,2))
+ │ └── name: :@a
+ ├── @ ClassVariableReadNode (location: (3,0)-(3,3))
+ │ └── name: :@@a
+ ├── @ GlobalVariableReadNode (location: (4,0)-(4,2))
+ │ └── name: :$a
+ ├── @ NumberedReferenceReadNode (location: (5,0)-(5,2))
+ │ └── number: 1
+ ├── @ BackReferenceReadNode (location: (6,0)-(6,2))
+ │ └── name: :$`
+ ├── @ ConstantReadNode (location: (7,0)-(7,5))
+ │ └── name: :CONST
+ ├── @ ConstantPathNode (location: (8,0)-(8,13))
+ │ ├── parent:
+ │ │ @ ConstantReadNode (location: (8,0)-(8,6))
+ │ │ └── name: :SCOPED
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (8,8)-(8,13))
+ │ │ └── name: :CONST
+ │ └── delimiter_loc: (8,6)-(8,8) = "::"
+ ├── @ ConstantPathNode (location: (9,0)-(9,10))
+ │ ├── parent: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (9,2)-(9,10))
+ │ │ └── name: :TOPLEVEL
+ │ └── delimiter_loc: (9,0)-(9,2) = "::"
+ └── @ 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) = "::"
diff --git a/test/prism/snapshots/unparser/corpus/literal/while.txt b/test/prism/snapshots/unparser/corpus/literal/while.txt
new file mode 100644
index 0000000000..0f752f3392
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/while.txt
@@ -0,0 +1,704 @@
+@ ProgramNode (location: (1,0)-(73,3))
+├── locals: [:x]
+└── statements:
+ @ StatementsNode (location: (1,0)-(73,3))
+ └── body: (length: 17)
+ ├── @ ModuleNode (location: (1,0)-(7,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (1,0)-(1,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (1,7)-(1,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,2)-(6,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,2)-(6,3))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (2,2)-(2,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (2,6)-(6,3))
+ │ │ ├── locals: [:bar, :foo]
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (2,8)-(2,13))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (2,9)-(2,12))
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (2,9)-(2,12))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :bar
+ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (2,8)-(2,9) = "|"
+ │ │ │ └── closing_loc: (2,12)-(2,13) = "|"
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (3,4)-(5,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ WhileNode (location: (3,4)-(5,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── keyword_loc: (3,4)-(3,9) = "while"
+ │ │ │ ├── closing_loc: (5,4)-(5,7) = "end"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ CallNode (location: (3,10)-(3,13))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (3,10)-(3,13) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── statements:
+ │ │ │ @ StatementsNode (location: (4,6)-(4,15))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableWriteNode (location: (4,6)-(4,15))
+ │ │ │ ├── name: :foo
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (4,6)-(4,9) = "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ LocalVariableReadNode (location: (4,12)-(4,15))
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: (4,10)-(4,11) = "="
+ │ │ ├── opening_loc: (2,6)-(2,7) = "{"
+ │ │ └── closing_loc: (6,2)-(6,3) = "}"
+ │ ├── end_keyword_loc: (7,0)-(7,3) = "end"
+ │ └── name: :A
+ ├── @ DefNode (location: (9,0)-(11,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (9,4)-(9,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (10,2)-(10,28))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (10,2)-(10,28))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (10,12)-(10,17) = "while"
+ │ │ ├── closing_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (10,18)-(10,28))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ LocalVariableReadNode (location: (10,18)-(10,21))
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :!=
+ │ │ │ ├── message_loc: (10,22)-(10,24) = "!="
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (10,25)-(10,28))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (10,25)-(10,28))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (10,25)-(10,28) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (10,2)-(10,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (10,2)-(10,11))
+ │ │ ├── name: :foo
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (10,2)-(10,5) = "foo"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (10,8)-(10,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (10,8)-(10,11) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (10,6)-(10,7) = "="
+ │ ├── locals: [:foo]
+ │ ├── def_keyword_loc: (9,0)-(9,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (11,0)-(11,3) = "end"
+ ├── @ ModuleNode (location: (13,0)-(15,3))
+ │ ├── locals: [:foo]
+ │ ├── module_keyword_loc: (13,0)-(13,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (13,7)-(13,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (14,2)-(14,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (14,2)-(14,21))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (14,12)-(14,17) = "while"
+ │ │ ├── closing_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ LocalVariableReadNode (location: (14,18)-(14,21))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (14,2)-(14,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (14,2)-(14,11))
+ │ │ ├── name: :foo
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (14,2)-(14,5) = "foo"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (14,8)-(14,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (14,8)-(14,11) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (14,6)-(14,7) = "="
+ │ ├── end_keyword_loc: (15,0)-(15,3) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (17,0)-(19,3))
+ │ ├── locals: [:foo]
+ │ ├── module_keyword_loc: (17,0)-(17,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (17,7)-(17,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (18,2)-(18,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ UntilNode (location: (18,2)-(18,21))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (18,12)-(18,17) = "until"
+ │ │ ├── closing_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ LocalVariableReadNode (location: (18,18)-(18,21))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (18,2)-(18,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (18,2)-(18,11))
+ │ │ ├── name: :foo
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (18,2)-(18,5) = "foo"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (18,8)-(18,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (18,8)-(18,11) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (18,6)-(18,7) = "="
+ │ ├── end_keyword_loc: (19,0)-(19,3) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (21,0)-(25,3))
+ │ ├── locals: [:foo]
+ │ ├── module_keyword_loc: (21,0)-(21,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (21,7)-(21,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (22,2)-(24,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (22,2)-(24,5))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (22,2)-(22,7) = "while"
+ │ │ ├── closing_loc: (24,2)-(24,5) = "end"
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (22,8)-(22,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (22,8)-(22,11) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (23,4)-(23,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableWriteNode (location: (23,4)-(23,13))
+ │ │ ├── name: :foo
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (23,4)-(23,7) = "foo"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (23,10)-(23,13))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (23,10)-(23,13) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (23,8)-(23,9) = "="
+ │ ├── end_keyword_loc: (25,0)-(25,3) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (27,0)-(33,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (27,0)-(27,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (27,7)-(27,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (28,2)-(32,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (28,2)-(32,3))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :each
+ │ │ ├── message_loc: (28,2)-(28,6) = "each"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (28,7)-(32,3))
+ │ │ ├── locals: [:baz, :foo]
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (28,9)-(28,14))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (28,10)-(28,13))
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (28,10)-(28,13))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :baz
+ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (28,9)-(28,10) = "|"
+ │ │ │ └── closing_loc: (28,13)-(28,14) = "|"
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (29,4)-(31,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ WhileNode (location: (29,4)-(31,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── keyword_loc: (29,4)-(29,9) = "while"
+ │ │ │ ├── closing_loc: (31,4)-(31,7) = "end"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ CallNode (location: (29,10)-(29,13))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (29,10)-(29,13) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── statements:
+ │ │ │ @ StatementsNode (location: (30,6)-(30,15))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableWriteNode (location: (30,6)-(30,15))
+ │ │ │ ├── name: :foo
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (30,6)-(30,9) = "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (30,12)-(30,15))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (30,12)-(30,15) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (30,10)-(30,11) = "="
+ │ │ ├── opening_loc: (28,7)-(28,8) = "{"
+ │ │ └── closing_loc: (32,2)-(32,3) = "}"
+ │ ├── end_keyword_loc: (33,0)-(33,3) = "end"
+ │ └── name: :A
+ ├── @ ModuleNode (location: (35,0)-(41,3))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (35,0)-(35,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (35,7)-(35,8))
+ │ │ └── name: :A
+ │ ├── body:
+ │ │ @ StatementsNode (location: (36,2)-(40,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (36,2)-(40,3))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :each
+ │ │ ├── message_loc: (36,2)-(36,6) = "each"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (36,7)-(40,3))
+ │ │ ├── locals: [:foo]
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (36,9)-(36,14))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (36,10)-(36,13))
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (36,10)-(36,13))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :foo
+ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (36,9)-(36,10) = "|"
+ │ │ │ └── closing_loc: (36,13)-(36,14) = "|"
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (37,4)-(39,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ WhileNode (location: (37,4)-(39,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── keyword_loc: (37,4)-(37,9) = "while"
+ │ │ │ ├── closing_loc: (39,4)-(39,7) = "end"
+ │ │ │ ├── predicate:
+ │ │ │ │ @ LocalVariableReadNode (location: (37,10)-(37,13))
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ └── depth: 0
+ │ │ │ └── statements:
+ │ │ │ @ StatementsNode (location: (38,6)-(38,15))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableWriteNode (location: (38,6)-(38,15))
+ │ │ │ ├── name: :foo
+ │ │ │ ├── depth: 0
+ │ │ │ ├── name_loc: (38,6)-(38,9) = "foo"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (38,12)-(38,15))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (38,12)-(38,15) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (38,10)-(38,11) = "="
+ │ │ ├── opening_loc: (36,7)-(36,8) = "{"
+ │ │ └── closing_loc: (40,2)-(40,3) = "}"
+ │ ├── end_keyword_loc: (41,0)-(41,3) = "end"
+ │ └── name: :A
+ ├── @ LocalVariableWriteNode (location: (42,0)-(44,14))
+ │ ├── name: :x
+ │ ├── depth: 0
+ │ ├── name_loc: (42,0)-(42,1) = "x"
+ │ ├── value:
+ │ │ @ ParenthesesNode (location: (42,4)-(44,14))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (42,5)-(44,13))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ WhileNode (location: (42,5)-(44,13))
+ │ │ │ ├── flags: begin_modifier
+ │ │ │ ├── keyword_loc: (44,4)-(44,9) = "while"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ ├── predicate:
+ │ │ │ │ @ CallNode (location: (44,10)-(44,13))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── message_loc: (44,10)-(44,13) = "baz"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── statements:
+ │ │ │ @ StatementsNode (location: (42,5)-(44,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ BeginNode (location: (42,5)-(44,3))
+ │ │ │ ├── begin_keyword_loc: (42,5)-(42,10) = "begin"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (43,2)-(43,5))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (43,2)-(43,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (43,2)-(43,5) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── rescue_clause: ∅
+ │ │ │ ├── else_clause: ∅
+ │ │ │ ├── ensure_clause: ∅
+ │ │ │ └── end_keyword_loc: (44,0)-(44,3) = "end"
+ │ │ ├── opening_loc: (42,4)-(42,5) = "("
+ │ │ └── closing_loc: (44,13)-(44,14) = ")"
+ │ └── operator_loc: (42,2)-(42,3) = "="
+ ├── @ WhileNode (location: (45,0)-(47,13))
+ │ ├── flags: begin_modifier
+ │ ├── keyword_loc: (47,4)-(47,9) = "while"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (47,10)-(47,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (47,10)-(47,13) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (45,0)-(47,3))
+ │ └── body: (length: 1)
+ │ └── @ BeginNode (location: (45,0)-(47,3))
+ │ ├── begin_keyword_loc: (45,0)-(45,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (46,2)-(46,5))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (46,2)-(46,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (46,2)-(46,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (47,0)-(47,3) = "end"
+ ├── @ UntilNode (location: (48,0)-(51,13))
+ │ ├── flags: begin_modifier
+ │ ├── keyword_loc: (51,4)-(51,9) = "until"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (51,10)-(51,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (51,10)-(51,13) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (48,0)-(51,3))
+ │ └── body: (length: 1)
+ │ └── @ BeginNode (location: (48,0)-(51,3))
+ │ ├── begin_keyword_loc: (48,0)-(48,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (49,2)-(50,5))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ CallNode (location: (49,2)-(49,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (49,2)-(49,5) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (50,2)-(50,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (50,2)-(50,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (51,0)-(51,3) = "end"
+ ├── @ WhileNode (location: (52,0)-(55,13))
+ │ ├── flags: begin_modifier
+ │ ├── keyword_loc: (55,4)-(55,9) = "while"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (55,10)-(55,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (55,10)-(55,13) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (52,0)-(55,3))
+ │ └── body: (length: 1)
+ │ └── @ BeginNode (location: (52,0)-(55,3))
+ │ ├── begin_keyword_loc: (52,0)-(52,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (53,2)-(54,5))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ CallNode (location: (53,2)-(53,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (53,2)-(53,5) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (54,2)-(54,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (54,2)-(54,5) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (55,0)-(55,3) = "end"
+ ├── @ WhileNode (location: (56,0)-(57,3))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (56,0)-(56,5) = "while"
+ │ ├── closing_loc: (57,0)-(57,3) = "end"
+ │ ├── predicate:
+ │ │ @ FalseNode (location: (56,6)-(56,11))
+ │ └── statements: ∅
+ ├── @ WhileNode (location: (58,0)-(60,3))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (58,0)-(58,5) = "while"
+ │ ├── closing_loc: (60,0)-(60,3) = "end"
+ │ ├── predicate:
+ │ │ @ FalseNode (location: (58,6)-(58,11))
+ │ └── statements:
+ │ @ StatementsNode (location: (59,2)-(59,3))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (59,2)-(59,3))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── @ WhileNode (location: (61,0)-(64,3))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (61,0)-(61,5) = "while"
+ │ ├── closing_loc: (64,0)-(64,3) = "end"
+ │ ├── predicate:
+ │ │ @ ParenthesesNode (location: (61,6)-(62,2))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (61,7)-(62,1))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (61,7)-(62,1))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (61,7)-(61,10) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (61,11)-(62,1))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (61,11)-(61,12) = "{"
+ │ │ │ └── closing_loc: (62,0)-(62,1) = "}"
+ │ │ ├── opening_loc: (61,6)-(61,7) = "("
+ │ │ └── closing_loc: (62,1)-(62,2) = ")"
+ │ └── statements:
+ │ @ StatementsNode (location: (63,2)-(63,7))
+ │ └── body: (length: 1)
+ │ └── @ SymbolNode (location: (63,2)-(63,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (63,2)-(63,3) = ":"
+ │ ├── value_loc: (63,3)-(63,7) = "body"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "body"
+ ├── @ UntilNode (location: (65,0)-(66,3))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (65,0)-(65,5) = "until"
+ │ ├── closing_loc: (66,0)-(66,3) = "end"
+ │ ├── predicate:
+ │ │ @ FalseNode (location: (65,6)-(65,11))
+ │ └── statements: ∅
+ ├── @ UntilNode (location: (67,0)-(69,3))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (67,0)-(67,5) = "until"
+ │ ├── closing_loc: (69,0)-(69,3) = "end"
+ │ ├── predicate:
+ │ │ @ FalseNode (location: (67,6)-(67,11))
+ │ └── statements:
+ │ @ StatementsNode (location: (68,2)-(68,3))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (68,2)-(68,3))
+ │ ├── flags: decimal
+ │ └── value: 3
+ └── @ UntilNode (location: (70,0)-(73,3))
+ ├── flags: ∅
+ ├── keyword_loc: (70,0)-(70,5) = "until"
+ ├── closing_loc: (73,0)-(73,3) = "end"
+ ├── predicate:
+ │ @ ParenthesesNode (location: (70,6)-(71,2))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (70,7)-(71,1))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (70,7)-(71,1))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (70,7)-(70,10) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (70,11)-(71,1))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (70,11)-(70,12) = "{"
+ │ │ └── closing_loc: (71,0)-(71,1) = "}"
+ │ ├── opening_loc: (70,6)-(70,7) = "("
+ │ └── closing_loc: (71,1)-(71,2) = ")"
+ └── statements:
+ @ StatementsNode (location: (72,2)-(72,7))
+ └── body: (length: 1)
+ └── @ SymbolNode (location: (72,2)-(72,7))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (72,2)-(72,3) = ":"
+ ├── value_loc: (72,3)-(72,7) = "body"
+ ├── closing_loc: ∅
+ └── unescaped: "body"
diff --git a/test/prism/snapshots/unparser/corpus/literal/yield.txt b/test/prism/snapshots/unparser/corpus/literal/yield.txt
new file mode 100644
index 0000000000..4d2b272e35
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/literal/yield.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(3,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,11))
+ └── body: (length: 3)
+ ├── @ YieldNode (location: (1,0)-(1,5))
+ │ ├── keyword_loc: (1,0)-(1,5) = "yield"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments: ∅
+ │ └── rparen_loc: ∅
+ ├── @ YieldNode (location: (2,0)-(2,8))
+ │ ├── keyword_loc: (2,0)-(2,5) = "yield"
+ │ ├── lparen_loc: (2,5)-(2,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (2,6)-(2,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (2,6)-(2,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (2,6)-(2,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── rparen_loc: (2,7)-(2,8) = ")"
+ └── @ YieldNode (location: (3,0)-(3,11))
+ ├── keyword_loc: (3,0)-(3,5) = "yield"
+ ├── lparen_loc: (3,5)-(3,6) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,6)-(3,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (3,6)-(3,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (3,6)-(3,7) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ CallNode (location: (3,9)-(3,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (3,9)-(3,10) = "b"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── rparen_loc: (3,10)-(3,11) = ")"
diff --git a/test/prism/snapshots/unparser/corpus/semantic/and.txt b/test/prism/snapshots/unparser/corpus/semantic/and.txt
new file mode 100644
index 0000000000..bc9d674e44
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/and.txt
@@ -0,0 +1,235 @@
+@ ProgramNode (location: (1,0)-(8,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(8,3))
+ └── body: (length: 4)
+ ├── @ OrNode (location: (1,0)-(1,14))
+ │ ├── left:
+ │ │ @ RangeNode (location: (1,0)-(1,5))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (1,4)-(1,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (1,1)-(1,4) = "..."
+ │ ├── right:
+ │ │ @ RangeNode (location: (1,9)-(1,14))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (1,9)-(1,10) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (1,13)-(1,14) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (1,10)-(1,13) = "..."
+ │ └── operator_loc: (1,6)-(1,8) = "or"
+ ├── @ AndNode (location: (2,0)-(2,15))
+ │ ├── left:
+ │ │ @ RangeNode (location: (2,0)-(2,5))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (2,0)-(2,1))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (2,0)-(2,1) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (2,4)-(2,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (2,4)-(2,5) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (2,1)-(2,4) = "..."
+ │ ├── right:
+ │ │ @ RangeNode (location: (2,10)-(2,15))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (2,10)-(2,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (2,10)-(2,11) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (2,14)-(2,15))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (2,14)-(2,15) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (2,11)-(2,14) = "..."
+ │ └── operator_loc: (2,6)-(2,9) = "and"
+ ├── @ IfNode (location: (4,0)-(5,3))
+ │ ├── if_keyword_loc: (4,0)-(4,2) = "if"
+ │ ├── predicate:
+ │ │ @ OrNode (location: (4,3)-(4,17))
+ │ │ ├── left:
+ │ │ │ @ FlipFlopNode (location: (4,3)-(4,8))
+ │ │ │ ├── flags: exclude_end
+ │ │ │ ├── left:
+ │ │ │ │ @ CallNode (location: (4,3)-(4,4))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (4,3)-(4,4) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ CallNode (location: (4,7)-(4,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (4,7)-(4,8) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (4,4)-(4,7) = "..."
+ │ │ ├── right:
+ │ │ │ @ FlipFlopNode (location: (4,12)-(4,17))
+ │ │ │ ├── flags: exclude_end
+ │ │ │ ├── left:
+ │ │ │ │ @ CallNode (location: (4,12)-(4,13))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (4,12)-(4,13) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ CallNode (location: (4,16)-(4,17))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :d
+ │ │ │ │ ├── message_loc: (4,16)-(4,17) = "d"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (4,13)-(4,16) = "..."
+ │ │ └── operator_loc: (4,9)-(4,11) = "or"
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (5,0)-(5,3) = "end"
+ └── @ IfNode (location: (7,0)-(8,3))
+ ├── if_keyword_loc: (7,0)-(7,2) = "if"
+ ├── predicate:
+ │ @ AndNode (location: (7,3)-(7,18))
+ │ ├── left:
+ │ │ @ FlipFlopNode (location: (7,3)-(7,8))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (7,3)-(7,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (7,3)-(7,4) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (7,7)-(7,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (7,7)-(7,8) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (7,4)-(7,7) = "..."
+ │ ├── right:
+ │ │ @ FlipFlopNode (location: (7,13)-(7,18))
+ │ │ ├── flags: exclude_end
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (7,13)-(7,14))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (7,13)-(7,14) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (7,17)-(7,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (7,17)-(7,18) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (7,14)-(7,17) = "..."
+ │ └── operator_loc: (7,9)-(7,12) = "and"
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (8,0)-(8,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/semantic/block.txt b/test/prism/snapshots/unparser/corpus/semantic/block.txt
new file mode 100644
index 0000000000..b9aa6b2184
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/block.txt
@@ -0,0 +1,191 @@
+@ ProgramNode (location: (1,0)-(26,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(26,3))
+ └── body: (length: 6)
+ ├── @ CallNode (location: (1,0)-(2,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,4)-(2,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,4)-(1,6) = "do"
+ │ └── closing_loc: (2,0)-(2,3) = "end"
+ ├── @ CallNode (location: (4,0)-(6,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (4,0)-(4,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (4,4)-(6,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ BeginNode (location: (4,4)-(6,3))
+ │ │ ├── begin_keyword_loc: ∅
+ │ │ ├── statements: ∅
+ │ │ ├── rescue_clause:
+ │ │ │ @ RescueNode (location: (5,0)-(5,6))
+ │ │ │ ├── keyword_loc: (5,0)-(5,6) = "rescue"
+ │ │ │ ├── exceptions: (length: 0)
+ │ │ │ ├── operator_loc: ∅
+ │ │ │ ├── reference: ∅
+ │ │ │ ├── statements: ∅
+ │ │ │ └── consequent: ∅
+ │ │ ├── else_clause: ∅
+ │ │ ├── ensure_clause: ∅
+ │ │ └── end_keyword_loc: (6,0)-(6,3) = "end"
+ │ ├── opening_loc: (4,4)-(4,6) = "do"
+ │ └── closing_loc: (6,0)-(6,3) = "end"
+ ├── @ CallNode (location: (8,0)-(11,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (8,0)-(8,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (8,4)-(11,3))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (9,2)-(10,5))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ RescueModifierNode (location: (9,2)-(9,16))
+ │ │ │ ├── expression:
+ │ │ │ │ @ NilNode (location: (9,2)-(9,5))
+ │ │ │ ├── keyword_loc: (9,6)-(9,12) = "rescue"
+ │ │ │ └── rescue_expression:
+ │ │ │ @ NilNode (location: (9,13)-(9,16))
+ │ │ └── @ NilNode (location: (10,2)-(10,5))
+ │ ├── opening_loc: (8,4)-(8,6) = "do"
+ │ └── closing_loc: (11,0)-(11,3) = "end"
+ ├── @ CallNode (location: (13,0)-(14,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (13,0)-(13,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (13,4)-(14,3))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (13,7)-(13,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (13,8)-(13,9))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (13,8)-(13,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (13,7)-(13,8) = "|"
+ │ │ └── closing_loc: (13,9)-(13,10) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (13,4)-(13,6) = "do"
+ │ └── closing_loc: (14,0)-(14,3) = "end"
+ ├── @ CallNode (location: (16,0)-(20,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (16,0)-(16,3) = "foo"
+ │ ├── opening_loc: (16,3)-(16,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (16,4)-(16,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (16,4)-(16,10))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (16,4)-(16,10) = "<<-DOC"
+ │ │ ├── content_loc: (17,0)-(18,0) = " b\n"
+ │ │ ├── closing_loc: (18,0)-(19,0) = "DOC\n"
+ │ │ └── unescaped: " b\n"
+ │ ├── closing_loc: (16,10)-(16,11) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (16,12)-(20,3))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (16,15)-(16,18))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (16,16)-(16,17))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (16,16)-(16,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (16,15)-(16,16) = "|"
+ │ │ └── closing_loc: (16,17)-(16,18) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (19,2)-(19,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (19,2)-(19,3))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── opening_loc: (16,12)-(16,14) = "do"
+ │ └── closing_loc: (20,0)-(20,3) = "end"
+ └── @ CallNode (location: (22,0)-(26,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (22,0)-(22,3) = "foo"
+ ├── opening_loc: (22,3)-(22,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (22,4)-(22,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ StringNode (location: (22,4)-(22,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (22,4)-(22,10) = "<<-DOC"
+ │ ├── content_loc: (23,0)-(24,0) = " b\n"
+ │ ├── closing_loc: (24,0)-(25,0) = "DOC\n"
+ │ └── unescaped: " b\n"
+ ├── closing_loc: (22,10)-(22,11) = ")"
+ └── block:
+ @ BlockNode (location: (22,12)-(26,3))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (25,2)-(25,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (25,2)-(25,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (25,2)-(25,3) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (22,12)-(22,14) = "do"
+ └── closing_loc: (26,0)-(26,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/semantic/def.txt b/test/prism/snapshots/unparser/corpus/semantic/def.txt
new file mode 100644
index 0000000000..b44983c2f3
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/def.txt
@@ -0,0 +1,90 @@
+@ ProgramNode (location: (1,0)-(7,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,3))
+ └── body: (length: 2)
+ ├── @ DefNode (location: (1,0)-(3,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,2)-(2,9))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ParenthesesNode (location: (2,2)-(2,9))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (2,3)-(2,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,3)-(2,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (2,3)-(2,4))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (2,3)-(2,4) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :-
+ │ │ │ ├── message_loc: (2,5)-(2,6) = "-"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (2,7)-(2,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (2,7)-(2,8))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (2,7)-(2,8) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (2,2)-(2,3) = "("
+ │ │ └── closing_loc: (2,8)-(2,9) = ")"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ └── @ DefNode (location: (5,0)-(7,3))
+ ├── name: :foo
+ ├── name_loc: (5,4)-(5,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (6,2)-(6,20))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (6,2)-(6,20))
+ │ ├── expression:
+ │ │ @ CallNode (location: (6,2)-(6,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (6,2)-(6,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (6,4)-(6,10) = "rescue"
+ │ └── rescue_expression:
+ │ @ ConstantReadNode (location: (6,11)-(6,20))
+ │ └── name: :Exception
+ ├── locals: []
+ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (7,0)-(7,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/semantic/dstr.txt b/test/prism/snapshots/unparser/corpus/semantic/dstr.txt
new file mode 100644
index 0000000000..499bf59d1a
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/dstr.txt
@@ -0,0 +1,598 @@
+@ ProgramNode (location: (1,0)-(127,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(127,11))
+ └── body: (length: 33)
+ ├── @ StringNode (location: (1,0)-(1,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,5) = "<<DOC"
+ │ ├── content_loc: (2,0)-(2,0) = ""
+ │ ├── closing_loc: (2,0)-(3,0) = "DOC\n"
+ │ └── unescaped: ""
+ ├── @ StringNode (location: (4,0)-(4,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (4,0)-(4,7) = "<<'DOC'"
+ │ ├── content_loc: (5,0)-(5,0) = ""
+ │ ├── closing_loc: (5,0)-(6,0) = "DOC\n"
+ │ └── unescaped: ""
+ ├── @ StringNode (location: (7,0)-(7,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(7,6) = "<<~DOC"
+ │ ├── content_loc: (8,0)-(8,0) = ""
+ │ ├── closing_loc: (8,0)-(9,0) = "DOC\n"
+ │ └── unescaped: ""
+ ├── @ StringNode (location: (10,0)-(10,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (10,0)-(10,8) = "<<~'DOC'"
+ │ ├── content_loc: (11,0)-(11,0) = ""
+ │ ├── closing_loc: (11,0)-(12,0) = "DOC\n"
+ │ └── unescaped: ""
+ ├── @ StringNode (location: (13,0)-(13,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (13,0)-(13,5) = "<<DOC"
+ │ ├── content_loc: (14,0)-(15,0) = " a\n"
+ │ ├── closing_loc: (15,0)-(16,0) = "DOC\n"
+ │ └── unescaped: " a\n"
+ ├── @ StringNode (location: (17,0)-(17,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (17,0)-(17,7) = "<<'DOC'"
+ │ ├── content_loc: (18,0)-(19,0) = " a\n"
+ │ ├── closing_loc: (19,0)-(20,0) = "DOC\n"
+ │ └── unescaped: " a\n"
+ ├── @ InterpolatedStringNode (location: (21,0)-(21,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (21,0)-(21,5) = "<<DOC"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (22,0)-(23,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (22,0)-(23,2) = " a\n "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a\n "
+ │ │ ├── @ EmbeddedStatementsNode (location: (23,2)-(23,5))
+ │ │ │ ├── opening_loc: (23,2)-(23,4) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (23,4)-(23,5) = "}"
+ │ │ └── @ StringNode (location: (23,5)-(24,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (23,5)-(24,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (24,0)-(25,0) = "DOC\n"
+ ├── @ InterpolatedStringNode (location: (26,0)-(26,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (26,0)-(26,6) = "<<~DOC"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (27,0)-(28,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (27,0)-(28,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (28,2)-(28,5))
+ │ │ │ ├── opening_loc: (28,2)-(28,4) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (28,4)-(28,5) = "}"
+ │ │ └── @ StringNode (location: (28,5)-(29,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (28,5)-(29,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (29,0)-(30,0) = "DOC\n"
+ ├── @ InterpolatedStringNode (location: (31,0)-(31,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (31,0)-(31,6) = "<<~DOC"
+ │ ├── parts: (length: 4)
+ │ │ ├── @ StringNode (location: (32,0)-(33,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (32,0)-(33,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (33,2)-(33,5))
+ │ │ │ ├── opening_loc: (33,2)-(33,4) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (33,4)-(33,5) = "}"
+ │ │ ├── @ StringNode (location: (33,5)-(34,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (33,5)-(34,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── @ StringNode (location: (34,0)-(35,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (34,0)-(35,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n"
+ │ └── closing_loc: (35,0)-(36,0) = "DOC\n"
+ ├── @ InterpolatedStringNode (location: (37,0)-(37,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (37,0)-(37,6) = "<<~DOC"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (38,0)-(39,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (38,0)-(39,0) = " a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── @ StringNode (location: (39,0)-(40,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (39,0)-(40,0) = " b\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " b\n"
+ │ └── closing_loc: (40,0)-(41,0) = "DOC\n"
+ ├── @ StringNode (location: (42,0)-(42,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (42,0)-(42,7) = "<<'DOC'"
+ │ ├── content_loc: (43,0)-(46,0) = "a\n\nb\n"
+ │ ├── closing_loc: (46,0)-(47,0) = "DOC\n"
+ │ └── unescaped: "a\n\nb\n"
+ ├── @ StringNode (location: (48,0)-(48,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (48,0)-(48,7) = "<<'DOC'"
+ │ ├── content_loc: (49,0)-(52,0) = " a\n\n b\n"
+ │ ├── closing_loc: (52,0)-(53,0) = "DOC\n"
+ │ └── unescaped: " a\n\n b\n"
+ ├── @ StringNode (location: (54,0)-(54,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (54,0)-(54,7) = "<<'DOC'"
+ │ ├── content_loc: (55,0)-(56,0) = " a\\nb\n"
+ │ ├── closing_loc: (56,0)-(57,0) = "DOC\n"
+ │ └── unescaped: " a\\nb\n"
+ ├── @ InterpolatedStringNode (location: (58,0)-(58,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (58,0)-(58,5) = "<<DOC"
+ │ ├── parts: (length: 4)
+ │ │ ├── @ EmbeddedStatementsNode (location: (59,0)-(59,3))
+ │ │ │ ├── opening_loc: (59,0)-(59,2) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (59,2)-(59,3) = "}"
+ │ │ ├── @ StringNode (location: (59,3)-(60,1))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (59,3)-(60,1) = "a\n "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n "
+ │ │ ├── @ EmbeddedStatementsNode (location: (60,1)-(60,4))
+ │ │ │ ├── opening_loc: (60,1)-(60,3) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (60,3)-(60,4) = "}"
+ │ │ └── @ StringNode (location: (60,4)-(61,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (60,4)-(61,0) = "a\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\n"
+ │ └── closing_loc: (61,0)-(62,0) = "DOC\n"
+ ├── @ InterpolatedStringNode (location: (63,0)-(63,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (63,0)-(63,5) = "<<DOC"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (64,0)-(64,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (64,0)-(64,2) = " "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " "
+ │ │ ├── @ EmbeddedStatementsNode (location: (64,2)-(64,5))
+ │ │ │ ├── opening_loc: (64,2)-(64,4) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (64,4)-(64,5) = "}"
+ │ │ └── @ StringNode (location: (64,5)-(66,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (64,5)-(66,0) = "\n \\\#{}\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n \#{}\n"
+ │ └── closing_loc: (66,0)-(67,0) = "DOC\n"
+ ├── @ InterpolatedStringNode (location: (68,0)-(68,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (68,0)-(68,5) = "<<DOC"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (69,0)-(69,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (69,0)-(69,2) = " a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " a"
+ │ │ ├── @ EmbeddedStatementsNode (location: (69,2)-(69,5))
+ │ │ │ ├── opening_loc: (69,2)-(69,4) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (69,4)-(69,5) = "}"
+ │ │ └── @ StringNode (location: (69,5)-(71,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (69,5)-(71,0) = "b\n c\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b\n c\n"
+ │ └── closing_loc: (71,0)-(72,0) = "DOC\n"
+ ├── @ InterpolatedStringNode (location: (73,0)-(73,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (73,0)-(73,6) = "<<~DOC"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (74,2)-(74,5))
+ │ │ │ ├── opening_loc: (74,2)-(74,4) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (74,4)-(74,5) = "}"
+ │ │ └── @ StringNode (location: (74,5)-(75,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (74,5)-(75,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (75,0)-(76,0) = "DOC\n"
+ ├── @ IfNode (location: (77,0)-(81,3))
+ │ ├── if_keyword_loc: (77,0)-(77,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (77,3)-(77,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (78,2)-(78,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (78,2)-(78,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (78,2)-(78,8) = "<<~DOC"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (79,4)-(79,7))
+ │ │ │ │ ├── opening_loc: (79,4)-(79,6) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (79,6)-(79,7) = "}"
+ │ │ │ └── @ StringNode (location: (79,7)-(80,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (79,7)-(80,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (80,0)-(81,0) = " DOC\n"
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (81,0)-(81,3) = "end"
+ ├── @ IfNode (location: (83,0)-(87,3))
+ │ ├── if_keyword_loc: (83,0)-(83,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (83,3)-(83,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (84,2)-(84,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (84,2)-(84,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (84,2)-(84,8) = "<<~DOC"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (85,0)-(85,5))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (85,0)-(85,5) = " b"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (85,5)-(85,8))
+ │ │ │ │ ├── opening_loc: (85,5)-(85,7) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (85,7)-(85,8) = "}"
+ │ │ │ └── @ StringNode (location: (85,8)-(86,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (85,8)-(86,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (86,0)-(87,0) = " DOC\n"
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (87,0)-(87,3) = "end"
+ ├── @ IfNode (location: (89,0)-(93,3))
+ │ ├── if_keyword_loc: (89,0)-(89,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (89,3)-(89,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (90,2)-(90,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (90,2)-(90,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (90,2)-(90,8) = "<<~DOC"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (91,4)-(91,7))
+ │ │ │ │ ├── opening_loc: (91,4)-(91,6) = "\#{"
+ │ │ │ │ ├── statements: ∅
+ │ │ │ │ └── closing_loc: (91,6)-(91,7) = "}"
+ │ │ │ └── @ StringNode (location: (91,7)-(92,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (91,7)-(92,0) = "a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ └── closing_loc: (92,0)-(93,0) = " DOC\n"
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (93,0)-(93,3) = "end"
+ ├── @ IfNode (location: (95,0)-(101,3))
+ │ ├── if_keyword_loc: (95,0)-(95,2) = "if"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (95,3)-(95,7))
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (96,2)-(96,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ StringNode (location: (96,2)-(96,10))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (96,2)-(96,10) = "<<-'DOC'"
+ │ │ ├── content_loc: (97,0)-(100,0) = " a\n\n b\n"
+ │ │ ├── closing_loc: (100,0)-(101,0) = " DOC\n"
+ │ │ └── unescaped: " a\n\n b\n"
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (101,0)-(101,3) = "end"
+ ├── @ InterpolatedStringNode (location: (103,0)-(103,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (103,0)-(103,1) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (103,1)-(103,4))
+ │ │ │ ├── opening_loc: (103,1)-(103,3) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (103,3)-(103,4) = "}"
+ │ │ └── @ StringNode (location: (103,4)-(103,5))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (103,4)-(103,5) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ └── closing_loc: (103,5)-(103,6) = "\""
+ ├── @ InterpolatedStringNode (location: (105,0)-(105,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (105,0)-(105,2) = "%("
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (105,2)-(105,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (105,2)-(105,5) = "\\n\""
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n\""
+ │ │ ├── @ EmbeddedStatementsNode (location: (105,5)-(105,8))
+ │ │ │ ├── opening_loc: (105,5)-(105,7) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (105,7)-(105,8) = "}"
+ │ │ └── @ StringNode (location: (105,8)-(105,11))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (105,8)-(105,11) = "\"\\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\"\n"
+ │ └── closing_loc: (105,11)-(105,12) = ")"
+ ├── @ InterpolatedStringNode (location: (107,0)-(107,14))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (107,0)-(107,3) = "%Q("
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (107,3)-(107,7))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (107,3)-(107,7) = "-\\n\""
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "-\n\""
+ │ │ ├── @ EmbeddedStatementsNode (location: (107,7)-(107,10))
+ │ │ │ ├── opening_loc: (107,7)-(107,9) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (107,9)-(107,10) = "}"
+ │ │ └── @ StringNode (location: (107,10)-(107,13))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (107,10)-(107,13) = "\"\\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\"\n"
+ │ └── closing_loc: (107,13)-(107,14) = ")"
+ ├── @ InterpolatedStringNode (location: (109,0)-(111,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (109,0)-(109,1) = "\""
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (109,1)-(110,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (109,1)-(110,0) = "a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (110,0)-(110,3))
+ │ │ │ ├── opening_loc: (110,0)-(110,2) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (110,2)-(110,3) = "}"
+ │ │ └── @ StringNode (location: (110,3)-(111,1))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (110,3)-(111,1) = "\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\nb"
+ │ └── closing_loc: (111,1)-(111,2) = "\""
+ ├── @ InterpolatedStringNode (location: (113,0)-(114,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (113,0)-(113,1) = "\""
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (113,1)-(113,4))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (113,1)-(113,4) = "a\\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (113,4)-(113,7))
+ │ │ │ ├── opening_loc: (113,4)-(113,6) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (113,6)-(113,7) = "}"
+ │ │ └── @ StringNode (location: (113,7)-(114,1))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (113,7)-(114,1) = "\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\nb"
+ │ └── closing_loc: (114,1)-(114,2) = "\""
+ ├── @ InterpolatedStringNode (location: (116,0)-(117,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (116,0)-(116,1) = "\""
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (116,1)-(117,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (116,1)-(117,0) = "a\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (117,0)-(117,3))
+ │ │ │ ├── opening_loc: (117,0)-(117,2) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (117,2)-(117,3) = "}"
+ │ │ └── @ StringNode (location: (117,3)-(117,6))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (117,3)-(117,6) = "\\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\nb"
+ │ └── closing_loc: (117,6)-(117,7) = "\""
+ ├── @ InterpolatedStringNode (location: (119,0)-(120,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (119,0)-(119,3))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (119,0)-(119,1) = "'"
+ │ │ │ ├── content_loc: (119,1)-(119,2) = "a"
+ │ │ │ ├── closing_loc: (119,2)-(119,3) = "'"
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ InterpolatedStringNode (location: (120,0)-(120,5))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (120,0)-(120,1) = "\""
+ │ │ ├── parts: (length: 1)
+ │ │ │ └── @ EmbeddedStatementsNode (location: (120,1)-(120,4))
+ │ │ │ ├── opening_loc: (120,1)-(120,3) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (120,3)-(120,4) = "}"
+ │ │ └── closing_loc: (120,4)-(120,5) = "\""
+ │ └── closing_loc: ∅
+ ├── @ InterpolatedStringNode (location: (122,0)-(122,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (122,0)-(122,2))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (122,0)-(122,1) = "\""
+ │ │ │ ├── content_loc: (122,1)-(122,1) = ""
+ │ │ │ ├── closing_loc: (122,1)-(122,2) = "\""
+ │ │ │ └── unescaped: ""
+ │ │ ├── @ StringNode (location: (122,3)-(122,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (122,3)-(122,4) = "\""
+ │ │ │ ├── content_loc: (122,4)-(122,4) = ""
+ │ │ │ ├── closing_loc: (122,4)-(122,5) = "\""
+ │ │ │ └── unescaped: ""
+ │ │ └── @ StringNode (location: (122,6)-(122,8))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (122,6)-(122,7) = "\""
+ │ │ ├── content_loc: (122,7)-(122,7) = ""
+ │ │ ├── closing_loc: (122,7)-(122,8) = "\""
+ │ │ └── unescaped: ""
+ │ └── closing_loc: ∅
+ ├── @ InterpolatedStringNode (location: (124,0)-(124,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ InterpolatedStringNode (location: (124,0)-(124,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (124,0)-(124,1) = "\""
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (124,1)-(124,2))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (124,1)-(124,2) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ └── @ EmbeddedStatementsNode (location: (124,2)-(124,7))
+ │ │ │ │ ├── opening_loc: (124,2)-(124,4) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (124,4)-(124,6))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ InstanceVariableReadNode (location: (124,4)-(124,6))
+ │ │ │ │ │ └── name: :@a
+ │ │ │ │ └── closing_loc: (124,6)-(124,7) = "}"
+ │ │ │ └── closing_loc: (124,7)-(124,8) = "\""
+ │ │ └── @ StringNode (location: (124,9)-(124,12))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (124,9)-(124,10) = "\""
+ │ │ ├── content_loc: (124,10)-(124,11) = "b"
+ │ │ ├── closing_loc: (124,11)-(124,12) = "\""
+ │ │ └── unescaped: "b"
+ │ └── closing_loc: ∅
+ ├── @ InterpolatedStringNode (location: (125,0)-(125,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ InterpolatedStringNode (location: (125,0)-(125,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (125,0)-(125,1) = "\""
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (125,1)-(125,2))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (125,1)-(125,2) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ └── @ EmbeddedVariableNode (location: (125,2)-(125,5))
+ │ │ │ │ ├── operator_loc: (125,2)-(125,3) = "#"
+ │ │ │ │ └── variable:
+ │ │ │ │ @ InstanceVariableReadNode (location: (125,3)-(125,5))
+ │ │ │ │ └── name: :@a
+ │ │ │ └── closing_loc: (125,5)-(125,6) = "\""
+ │ │ └── @ StringNode (location: (125,7)-(125,10))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (125,7)-(125,8) = "\""
+ │ │ ├── content_loc: (125,8)-(125,9) = "b"
+ │ │ ├── closing_loc: (125,9)-(125,10) = "\""
+ │ │ └── unescaped: "b"
+ │ └── closing_loc: ∅
+ ├── @ InterpolatedStringNode (location: (126,0)-(126,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ InterpolatedStringNode (location: (126,0)-(126,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (126,0)-(126,1) = "\""
+ │ │ │ ├── parts: (length: 2)
+ │ │ │ │ ├── @ StringNode (location: (126,1)-(126,2))
+ │ │ │ │ │ ├── flags: frozen
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── content_loc: (126,1)-(126,2) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ └── @ EmbeddedVariableNode (location: (126,2)-(126,5))
+ │ │ │ │ ├── operator_loc: (126,2)-(126,3) = "#"
+ │ │ │ │ └── variable:
+ │ │ │ │ @ GlobalVariableReadNode (location: (126,3)-(126,5))
+ │ │ │ │ └── name: :$a
+ │ │ │ └── closing_loc: (126,5)-(126,6) = "\""
+ │ │ └── @ StringNode (location: (126,7)-(126,10))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (126,7)-(126,8) = "\""
+ │ │ ├── content_loc: (126,8)-(126,9) = "b"
+ │ │ ├── closing_loc: (126,9)-(126,10) = "\""
+ │ │ └── unescaped: "b"
+ │ └── closing_loc: ∅
+ └── @ InterpolatedStringNode (location: (127,0)-(127,11))
+ ├── flags: ∅
+ ├── opening_loc: ∅
+ ├── parts: (length: 2)
+ │ ├── @ InterpolatedStringNode (location: (127,0)-(127,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (127,0)-(127,1) = "\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (127,1)-(127,2))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (127,1)-(127,2) = "a"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ └── @ EmbeddedVariableNode (location: (127,2)-(127,6))
+ │ │ │ ├── operator_loc: (127,2)-(127,3) = "#"
+ │ │ │ └── variable:
+ │ │ │ @ ClassVariableReadNode (location: (127,3)-(127,6))
+ │ │ │ └── name: :@@a
+ │ │ └── closing_loc: (127,6)-(127,7) = "\""
+ │ └── @ StringNode (location: (127,8)-(127,11))
+ │ ├── flags: frozen
+ │ ├── opening_loc: (127,8)-(127,9) = "\""
+ │ ├── content_loc: (127,9)-(127,10) = "b"
+ │ ├── closing_loc: (127,10)-(127,11) = "\""
+ │ └── unescaped: "b"
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/unparser/corpus/semantic/kwbegin.txt b/test/prism/snapshots/unparser/corpus/semantic/kwbegin.txt
new file mode 100644
index 0000000000..38486ddc12
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/kwbegin.txt
@@ -0,0 +1,259 @@
+@ ProgramNode (location: (1,0)-(42,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(42,3))
+ └── body: (length: 8)
+ ├── @ BeginNode (location: (1,0)-(3,3))
+ │ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (2,0)-(2,6))
+ │ │ ├── keyword_loc: (2,0)-(2,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ ├── @ BeginNode (location: (5,0)-(8,3))
+ │ ├── begin_keyword_loc: (5,0)-(5,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (6,0)-(6,6))
+ │ │ ├── keyword_loc: (6,0)-(6,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause:
+ │ │ @ ElseNode (location: (7,0)-(8,3))
+ │ │ ├── else_keyword_loc: (7,0)-(7,4) = "else"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (8,0)-(8,3) = "end"
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (8,0)-(8,3) = "end"
+ ├── @ BeginNode (location: (10,0)-(12,3))
+ │ ├── begin_keyword_loc: (10,0)-(10,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (11,2)-(11,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (11,2)-(11,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (11,2)-(11,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (12,0)-(12,3) = "end"
+ ├── @ BeginNode (location: (14,0)-(18,3))
+ │ ├── begin_keyword_loc: (14,0)-(14,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (15,2)-(15,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (15,2)-(15,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (15,2)-(15,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (16,0)-(17,3))
+ │ │ ├── keyword_loc: (16,0)-(16,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (17,2)-(17,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (17,2)-(17,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (17,2)-(17,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (18,0)-(18,3) = "end"
+ ├── @ BeginNode (location: (20,0)-(25,3))
+ │ ├── begin_keyword_loc: (20,0)-(20,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (21,2)-(22,3))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ CallNode (location: (21,2)-(21,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (21,2)-(21,3) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (22,2)-(22,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (22,2)-(22,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (23,0)-(24,3))
+ │ │ ├── keyword_loc: (23,0)-(23,6) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (24,2)-(24,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (24,2)-(24,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (24,2)-(24,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (25,0)-(25,3) = "end"
+ ├── @ BeginNode (location: (27,0)-(30,3))
+ │ ├── begin_keyword_loc: (27,0)-(27,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (28,0)-(28,8))
+ │ │ ├── keyword_loc: (28,0)-(28,6) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (28,7)-(28,8))
+ │ │ │ └── name: :A
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause:
+ │ │ @ ElseNode (location: (29,0)-(30,3))
+ │ │ ├── else_keyword_loc: (29,0)-(29,4) = "else"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (30,0)-(30,3) = "end"
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (30,0)-(30,3) = "end"
+ ├── @ BeginNode (location: (32,0)-(32,26))
+ │ ├── begin_keyword_loc: (32,0)-(32,5) = "begin"
+ │ ├── statements: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (32,7)-(32,15))
+ │ │ ├── keyword_loc: (32,7)-(32,13) = "rescue"
+ │ │ ├── exceptions: (length: 1)
+ │ │ │ └── @ ConstantReadNode (location: (32,14)-(32,15))
+ │ │ │ └── name: :A
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause:
+ │ │ @ ElseNode (location: (32,17)-(32,26))
+ │ │ ├── else_keyword_loc: (32,17)-(32,21) = "else"
+ │ │ ├── statements: ∅
+ │ │ └── end_keyword_loc: (32,23)-(32,26) = "end"
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (32,23)-(32,26) = "end"
+ └── @ BeginNode (location: (34,0)-(42,3))
+ ├── begin_keyword_loc: (34,0)-(34,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (35,2)-(35,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (35,2)-(35,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (35,2)-(35,3) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (36,0)-(39,3))
+ │ ├── keyword_loc: (36,0)-(36,6) = "rescue"
+ │ ├── exceptions: (length: 1)
+ │ │ └── @ ConstantReadNode (location: (36,7)-(36,8))
+ │ │ └── name: :A
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (37,2)-(37,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (37,2)-(37,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (37,2)-(37,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent:
+ │ @ RescueNode (location: (38,0)-(39,3))
+ │ ├── keyword_loc: (38,0)-(38,6) = "rescue"
+ │ ├── exceptions: (length: 1)
+ │ │ └── @ ConstantReadNode (location: (38,7)-(38,8))
+ │ │ └── name: :B
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (39,2)-(39,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (39,2)-(39,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (39,2)-(39,3) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (40,0)-(42,3))
+ │ ├── ensure_keyword_loc: (40,0)-(40,6) = "ensure"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (41,2)-(41,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (41,2)-(41,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (41,2)-(41,3) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (42,0)-(42,3) = "end"
+ └── end_keyword_loc: (42,0)-(42,3) = "end"
diff --git a/test/prism/snapshots/unparser/corpus/semantic/literal.txt b/test/prism/snapshots/unparser/corpus/semantic/literal.txt
new file mode 100644
index 0000000000..ef666890be
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/literal.txt
@@ -0,0 +1,103 @@
+@ ProgramNode (location: (1,0)-(14,10))
+├── locals: []
+└── statements:
+ @ 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
+ ├── @ RationalNode (location: (2,0)-(2,3))
+ │ └── numeric:
+ │ @ IntegerNode (location: (2,0)-(2,2))
+ │ ├── flags: decimal
+ │ └── value: 0
+ ├── @ IntegerNode (location: (3,0)-(3,3))
+ │ ├── flags: hexadecimal
+ │ └── value: 1
+ ├── @ IntegerNode (location: (4,0)-(4,5))
+ │ ├── flags: decimal
+ │ └── value: 1000
+ ├── @ FloatNode (location: (5,0)-(5,4))
+ │ └── value: 10000000000.0
+ ├── @ FloatNode (location: (6,0)-(6,14))
+ │ └── value: Infinity
+ ├── @ FloatNode (location: (7,0)-(7,15))
+ │ └── value: -Infinity
+ ├── @ StringNode (location: (8,0)-(8,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (8,0)-(8,1) = "?"
+ │ ├── content_loc: (8,1)-(8,2) = "c"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "c"
+ ├── @ RegularExpressionNode (location: (9,0)-(9,5))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (9,0)-(9,3) = "%r("
+ │ ├── content_loc: (9,3)-(9,4) = "/"
+ │ ├── closing_loc: (9,4)-(9,5) = ")"
+ │ └── unescaped: "/"
+ ├── @ RegularExpressionNode (location: (10,0)-(10,6))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (10,0)-(10,3) = "%r("
+ │ ├── content_loc: (10,3)-(10,5) = "\\)"
+ │ ├── closing_loc: (10,5)-(10,6) = ")"
+ │ └── unescaped: "\\)"
+ ├── @ InterpolatedRegularExpressionNode (location: (11,0)-(11,14))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (11,0)-(11,3) = "%r("
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (11,3)-(11,10))
+ │ │ │ ├── opening_loc: (11,3)-(11,5) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (11,5)-(11,9))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ InstanceVariableReadNode (location: (11,5)-(11,9))
+ │ │ │ │ └── name: :@bar
+ │ │ │ └── closing_loc: (11,9)-(11,10) = "}"
+ │ │ └── @ StringNode (location: (11,10)-(11,13))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (11,10)-(11,13) = "baz"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz"
+ │ └── closing_loc: (11,13)-(11,14) = ")"
+ ├── @ FloatNode (location: (12,0)-(12,16))
+ │ └── value: Infinity
+ ├── @ FloatNode (location: (13,0)-(13,17))
+ │ └── value: -Infinity
+ └── @ CallNode (location: (14,0)-(14,10))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :w
+ ├── message_loc: (14,0)-(14,1) = "w"
+ ├── opening_loc: (14,1)-(14,2) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (14,2)-(14,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (14,2)-(14,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (14,2)-(14,5) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (14,6)-(14,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (14,6)-(14,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (14,6)-(14,9) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (14,9)-(14,10) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt b/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt
new file mode 100644
index 0000000000..e100dd8ecb
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt
@@ -0,0 +1,69 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ IndexOperatorWriteNode (location: (1,0)-(1,25))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :y
+ │ ├── message_loc: (1,0)-(1,1) = "y"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── opening_loc: (1,1)-(1,2) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (1,2)-(1,11))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (1,3)-(1,8))
+ │ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,5)-(1,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (1,5)-(1,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 42
+ │ │ │ └── closing_loc: (1,7)-(1,8) = "}"
+ │ │ └── @ StringNode (location: (1,8)-(1,10))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,8)-(1,10) = "\\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (1,10)-(1,11) = "\""
+ ├── closing_loc: (1,11)-(1,12) = "]"
+ ├── block: ∅
+ ├── operator: :+
+ ├── operator_loc: (1,13)-(1,15) = "+="
+ └── value:
+ @ InterpolatedStringNode (location: (1,16)-(1,25))
+ ├── flags: ∅
+ ├── opening_loc: (1,16)-(1,17) = "\""
+ ├── parts: (length: 2)
+ │ ├── @ EmbeddedStatementsNode (location: (1,17)-(1,22))
+ │ │ ├── opening_loc: (1,17)-(1,19) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,19)-(1,21))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,19)-(1,21))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ └── closing_loc: (1,21)-(1,22) = "}"
+ │ └── @ StringNode (location: (1,22)-(1,24))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,22)-(1,24) = "\\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\n"
+ └── closing_loc: (1,24)-(1,25) = "\""
diff --git a/test/prism/snapshots/unparser/corpus/semantic/send.txt b/test/prism/snapshots/unparser/corpus/semantic/send.txt
new file mode 100644
index 0000000000..7c152c3bfb
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/send.txt
@@ -0,0 +1,163 @@
+@ ProgramNode (location: (1,0)-(6,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,15))
+ └── body: (length: 4)
+ ├── @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (2,0)-(2,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (2,0)-(2,3) = "foo"
+ │ ├── opening_loc: (2,3)-(2,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (2,4)-(2,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (2,4)-(2,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: (2,5)-(2,6) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (4,0)-(4,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (4,0)-(4,10))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (4,0)-(4,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ CallNode (location: (4,0)-(4,1))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (4,0)-(4,1) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── call_operator_loc: (4,1)-(4,2) = "."
+ │ │ │ ├── name: :===
+ │ │ │ ├── message_loc: (4,2)-(4,5) = "==="
+ │ │ │ ├── opening_loc: (4,5)-(4,6) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (4,6)-(4,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (4,6)-(4,7))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :b
+ │ │ │ │ ├── message_loc: (4,6)-(4,7) = "b"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (4,7)-(4,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (4,8)-(4,9) = "."
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (4,9)-(4,10) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :==
+ │ ├── message_loc: (4,11)-(4,13) = "=="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (4,14)-(4,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (4,14)-(4,15))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :d
+ │ │ ├── message_loc: (4,14)-(4,15) = "d"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (6,0)-(6,15))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (6,0)-(6,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (6,0)-(6,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :==
+ ├── message_loc: (6,2)-(6,4) = "=="
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (6,5)-(6,15))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (6,5)-(6,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (6,5)-(6,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ CallNode (location: (6,5)-(6,6))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :d
+ │ │ │ ├── message_loc: (6,5)-(6,6) = "d"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── call_operator_loc: (6,6)-(6,7) = "."
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (6,7)-(6,8) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (6,8)-(6,9) = "."
+ │ ├── name: :===
+ │ ├── message_loc: (6,9)-(6,12) = "==="
+ │ ├── opening_loc: (6,12)-(6,13) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (6,13)-(6,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (6,13)-(6,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (6,13)-(6,14) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (6,14)-(6,15) = ")"
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/unparser/corpus/semantic/undef.txt b/test/prism/snapshots/unparser/corpus/semantic/undef.txt
new file mode 100644
index 0000000000..ecb073148d
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/undef.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(2,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,14))
+ └── body: (length: 2)
+ ├── @ UndefNode (location: (1,0)-(1,9))
+ │ ├── names: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,6)-(1,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,6)-(1,9) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── keyword_loc: (1,0)-(1,5) = "undef"
+ └── @ UndefNode (location: (2,0)-(2,14))
+ ├── names: (length: 2)
+ │ ├── @ SymbolNode (location: (2,6)-(2,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (2,6)-(2,9) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── @ SymbolNode (location: (2,11)-(2,14))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (2,11)-(2,14) = "bar"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "bar"
+ └── keyword_loc: (2,0)-(2,5) = "undef"
diff --git a/test/prism/snapshots/unparser/corpus/semantic/while.txt b/test/prism/snapshots/unparser/corpus/semantic/while.txt
new file mode 100644
index 0000000000..36bfba5be6
--- /dev/null
+++ b/test/prism/snapshots/unparser/corpus/semantic/while.txt
@@ -0,0 +1,277 @@
+@ ProgramNode (location: (1,0)-(25,3))
+├── locals: [:foo, :a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(25,3))
+ └── body: (length: 7)
+ ├── @ UntilNode (location: (1,0)-(1,13))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (1,2)-(1,7) = "until"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,8)-(1,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b?
+ │ │ ├── message_loc: (1,8)-(1,10) = "b?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,11)-(1,13))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (1,11)-(1,12) = "{"
+ │ │ └── closing_loc: (1,12)-(1,13) = "}"
+ │ └── statements:
+ │ @ StatementsNode (location: (1,0)-(1,1))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ UntilNode (location: (3,0)-(5,3))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (3,0)-(3,5) = "until"
+ │ ├── closing_loc: (5,0)-(5,3) = "end"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (3,6)-(3,11))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b?
+ │ │ ├── message_loc: (3,6)-(3,8) = "b?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (3,9)-(3,11))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (3,9)-(3,10) = "{"
+ │ │ └── closing_loc: (3,10)-(3,11) = "}"
+ │ └── statements:
+ │ @ StatementsNode (location: (4,2)-(4,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (4,2)-(4,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (4,2)-(4,3) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ WhileNode (location: (7,0)-(7,19))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (7,10)-(7,15) = "while"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ LocalVariableReadNode (location: (7,16)-(7,19))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ └── statements:
+ │ @ StatementsNode (location: (7,0)-(7,9))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableWriteNode (location: (7,0)-(7,9))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (7,0)-(7,3) = "foo"
+ │ ├── value:
+ │ │ @ CallNode (location: (7,6)-(7,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (7,6)-(7,9) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (7,4)-(7,5) = "="
+ ├── @ UntilNode (location: (9,0)-(9,18))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (9,2)-(9,7) = "until"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ AndNode (location: (9,8)-(9,18))
+ │ │ ├── left:
+ │ │ │ @ CallNode (location: (9,8)-(9,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (9,8)-(9,9) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── right:
+ │ │ │ @ CallNode (location: (9,13)-(9,18))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (9,13)-(9,14) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (9,15)-(9,18))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (9,15)-(9,16) = "{"
+ │ │ │ └── closing_loc: (9,17)-(9,18) = "}"
+ │ │ └── operator_loc: (9,10)-(9,12) = "&&"
+ │ └── statements:
+ │ @ StatementsNode (location: (9,0)-(9,1))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (9,0)-(9,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (9,0)-(9,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ WhileNode (location: (11,0)-(13,3))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (11,0)-(11,5) = "while"
+ │ ├── closing_loc: (13,0)-(13,3) = "end"
+ │ ├── predicate:
+ │ │ @ LocalVariableWriteNode (location: (11,6)-(11,11))
+ │ │ ├── name: :a
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (11,6)-(11,7) = "a"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (11,10)-(11,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (11,10)-(11,11) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (11,8)-(11,9) = "="
+ │ └── statements:
+ │ @ StatementsNode (location: (12,2)-(12,3))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (12,2)-(12,3))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ UntilNode (location: (15,0)-(18,3))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (15,2)-(15,7) = "until"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (15,8)-(18,3))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (15,8)-(15,9) = "b"
+ │ │ ├── opening_loc: (15,9)-(15,10) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (15,10)-(15,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (15,10)-(15,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (15,10)-(15,16) = "<<-FOO"
+ │ │ │ ├── content_loc: (16,0)-(16,0) = ""
+ │ │ │ ├── closing_loc: (16,0)-(17,0) = "FOO\n"
+ │ │ │ └── unescaped: ""
+ │ │ ├── closing_loc: (15,16)-(15,17) = ")"
+ │ │ └── block:
+ │ │ @ BlockNode (location: (15,18)-(18,3))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (17,2)-(17,3))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (17,2)-(17,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (17,2)-(17,3) = "c"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (15,18)-(15,20) = "do"
+ │ │ └── closing_loc: (18,0)-(18,3) = "end"
+ │ └── statements:
+ │ @ StatementsNode (location: (15,0)-(15,1))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (15,0)-(15,1))
+ │ ├── name: :a
+ │ └── depth: 0
+ └── @ ModuleNode (location: (20,0)-(25,3))
+ ├── locals: [:foo]
+ ├── module_keyword_loc: (20,0)-(20,6) = "module"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (20,7)-(20,8))
+ │ └── name: :A
+ ├── body:
+ │ @ StatementsNode (location: (21,2)-(24,5))
+ │ └── body: (length: 2)
+ │ ├── @ LocalVariableWriteNode (location: (21,2)-(21,11))
+ │ │ ├── name: :foo
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (21,2)-(21,5) = "foo"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (21,8)-(21,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :exp
+ │ │ │ ├── message_loc: (21,8)-(21,11) = "exp"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (21,6)-(21,7) = "="
+ │ └── @ WhileNode (location: (22,2)-(24,5))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (22,2)-(22,7) = "while"
+ │ ├── closing_loc: (24,2)-(24,5) = "end"
+ │ ├── predicate:
+ │ │ @ LocalVariableReadNode (location: (22,8)-(22,11))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ └── statements:
+ │ @ StatementsNode (location: (23,4)-(23,13))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableWriteNode (location: (23,4)-(23,13))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (23,4)-(23,7) = "foo"
+ │ ├── value:
+ │ │ @ CallNode (location: (23,10)-(23,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (23,10)-(23,13) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (23,8)-(23,9) = "="
+ ├── end_keyword_loc: (25,0)-(25,3) = "end"
+ └── name: :A
diff --git a/test/prism/snapshots/until.txt b/test/prism/snapshots/until.txt
new file mode 100644
index 0000000000..d45e39644b
--- /dev/null
+++ b/test/prism/snapshots/until.txt
@@ -0,0 +1,179 @@
+@ ProgramNode (location: (1,0)-(13,20))
+├── locals: [:baz]
+└── statements:
+ @ StatementsNode (location: (1,0)-(13,20))
+ └── body: (length: 7)
+ ├── @ UntilNode (location: (1,0)-(1,18))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (1,0)-(1,5) = "until"
+ │ ├── closing_loc: (1,15)-(1,18) = "end"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (1,6)-(1,10))
+ │ └── statements:
+ │ @ StatementsNode (location: (1,12)-(1,13))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,12)-(1,13))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ UntilNode (location: (3,0)-(3,12))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (3,2)-(3,7) = "until"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (3,8)-(3,12))
+ │ └── statements:
+ │ @ StatementsNode (location: (3,0)-(3,1))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (3,0)-(3,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ CallNode (location: (5,0)-(5,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (5,0)-(5,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,4)-(5,24))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,6)-(5,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ UntilNode (location: (5,6)-(5,22))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (5,12)-(5,17) = "until"
+ │ │ ├── closing_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (5,18)-(5,22))
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (5,6)-(5,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (5,6)-(5,11))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (5,6)-(5,11) = "break"
+ │ ├── opening_loc: (5,4)-(5,5) = "{"
+ │ └── closing_loc: (5,23)-(5,24) = "}"
+ ├── @ CallNode (location: (7,0)-(7,23))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (7,0)-(7,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (7,4)-(7,23))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,6)-(7,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ UntilNode (location: (7,6)-(7,21))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (7,11)-(7,16) = "until"
+ │ │ ├── closing_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (7,17)-(7,21))
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (7,6)-(7,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (7,6)-(7,10))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (7,6)-(7,10) = "next"
+ │ ├── opening_loc: (7,4)-(7,5) = "{"
+ │ └── closing_loc: (7,22)-(7,23) = "}"
+ ├── @ UntilNode (location: (9,0)-(9,17))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (9,7)-(9,12) = "until"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (9,13)-(9,17))
+ │ └── statements:
+ │ @ StatementsNode (location: (9,0)-(9,6))
+ │ └── body: (length: 1)
+ │ └── @ ReturnNode (location: (9,0)-(9,6))
+ │ ├── keyword_loc: (9,0)-(9,6) = "return"
+ │ └── arguments: ∅
+ ├── @ UntilNode (location: (11,0)-(11,21))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (11,11)-(11,16) = "until"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (11,17)-(11,21))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar?
+ │ │ ├── message_loc: (11,17)-(11,21) = "bar?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (11,0)-(11,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (11,0)-(11,10))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (11,0)-(11,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,4)-(11,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (11,4)-(11,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (11,4)-(11,5) = ":"
+ │ │ │ ├── value_loc: (11,5)-(11,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (11,8)-(11,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (11,8)-(11,9) = ":"
+ │ │ ├── value_loc: (11,9)-(11,10) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ WhileNode (location: (13,0)-(13,20))
+ ├── flags: ∅
+ ├── keyword_loc: (13,4)-(13,9) = "while"
+ ├── closing_loc: ∅
+ ├── predicate:
+ │ @ MatchPredicateNode (location: (13,10)-(13,20))
+ │ ├── value:
+ │ │ @ CallNode (location: (13,10)-(13,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (13,10)-(13,13) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ LocalVariableTargetNode (location: (13,17)-(13,20))
+ │ │ ├── name: :baz
+ │ │ └── depth: 0
+ │ └── operator_loc: (13,14)-(13,16) = "in"
+ └── statements:
+ @ StatementsNode (location: (13,0)-(13,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (13,0)-(13,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (13,0)-(13,3) = "foo"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/variables.txt b/test/prism/snapshots/variables.txt
new file mode 100644
index 0000000000..b79612f924
--- /dev/null
+++ b/test/prism/snapshots/variables.txt
@@ -0,0 +1,408 @@
+@ ProgramNode (location: (1,0)-(47,17))
+├── locals: [:abc, :foo, :bar, :baz, :a, :b, :c, :d]
+└── statements:
+ @ StatementsNode (location: (1,0)-(47,17))
+ └── body: (length: 25)
+ ├── @ ClassVariableReadNode (location: (1,0)-(1,5))
+ │ └── name: :@@abc
+ ├── @ ClassVariableWriteNode (location: (3,0)-(3,9))
+ │ ├── name: :@@abc
+ │ ├── name_loc: (3,0)-(3,5) = "@@abc"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,8)-(3,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (3,6)-(3,7) = "="
+ ├── @ MultiWriteNode (location: (5,0)-(5,16))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ ClassVariableTargetNode (location: (5,0)-(5,5))
+ │ │ │ └── name: :@@foo
+ │ │ └── @ ClassVariableTargetNode (location: (5,7)-(5,12))
+ │ │ └── name: :@@bar
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (5,13)-(5,14) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (5,15)-(5,16))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ ClassVariableWriteNode (location: (7,0)-(7,12))
+ │ ├── name: :@@foo
+ │ ├── name_loc: (7,0)-(7,5) = "@@foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (7,8)-(7,12))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (7,8)-(7,9))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (7,11)-(7,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (7,6)-(7,7) = "="
+ ├── @ GlobalVariableWriteNode (location: (9,0)-(9,8))
+ │ ├── name: :$abc
+ │ ├── name_loc: (9,0)-(9,4) = "$abc"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (9,7)-(9,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (9,5)-(9,6) = "="
+ ├── @ GlobalVariableReadNode (location: (11,0)-(11,4))
+ │ └── name: :$abc
+ ├── @ InstanceVariableReadNode (location: (13,0)-(13,4))
+ │ └── name: :@abc
+ ├── @ InstanceVariableWriteNode (location: (15,0)-(15,8))
+ │ ├── name: :@abc
+ │ ├── name_loc: (15,0)-(15,4) = "@abc"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (15,7)-(15,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (15,5)-(15,6) = "="
+ ├── @ CallNode (location: (17,0)-(17,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (17,0)-(17,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ LocalVariableWriteNode (location: (19,0)-(19,7))
+ │ ├── name: :abc
+ │ ├── depth: 0
+ │ ├── name_loc: (19,0)-(19,3) = "abc"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (19,6)-(19,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (19,4)-(19,5) = "="
+ ├── @ MultiWriteNode (location: (21,0)-(21,14))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ GlobalVariableTargetNode (location: (21,0)-(21,4))
+ │ │ │ └── name: :$foo
+ │ │ └── @ GlobalVariableTargetNode (location: (21,6)-(21,10))
+ │ │ └── name: :$bar
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (21,11)-(21,12) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (21,13)-(21,14))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ GlobalVariableWriteNode (location: (23,0)-(23,11))
+ │ ├── name: :$foo
+ │ ├── name_loc: (23,0)-(23,4) = "$foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (23,7)-(23,11))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (23,7)-(23,8))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (23,10)-(23,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (23,5)-(23,6) = "="
+ ├── @ MultiWriteNode (location: (25,0)-(25,14))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ InstanceVariableTargetNode (location: (25,0)-(25,4))
+ │ │ │ └── name: :@foo
+ │ │ └── @ InstanceVariableTargetNode (location: (25,6)-(25,10))
+ │ │ └── name: :@bar
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (25,11)-(25,12) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (25,13)-(25,14))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ InstanceVariableWriteNode (location: (27,0)-(27,11))
+ │ ├── name: :@foo
+ │ ├── name_loc: (27,0)-(27,4) = "@foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (27,7)-(27,11))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (27,7)-(27,8))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (27,10)-(27,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (27,5)-(27,6) = "="
+ ├── @ LocalVariableWriteNode (location: (29,0)-(29,7))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (29,0)-(29,3) = "foo"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (29,6)-(29,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (29,4)-(29,5) = "="
+ ├── @ LocalVariableWriteNode (location: (29,9)-(29,19))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (29,9)-(29,12) = "foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (29,15)-(29,19))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (29,15)-(29,16))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (29,18)-(29,19))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (29,13)-(29,14) = "="
+ ├── @ LocalVariableWriteNode (location: (31,0)-(31,10))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (31,0)-(31,3) = "foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (31,6)-(31,10))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (31,6)-(31,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (31,9)-(31,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (31,4)-(31,5) = "="
+ ├── @ MultiWriteNode (location: (33,0)-(33,13))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (33,0)-(33,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ SplatNode (location: (33,5)-(33,6))
+ │ │ ├── operator_loc: (33,5)-(33,6) = "*"
+ │ │ └── expression: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (33,7)-(33,8) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (33,9)-(33,13))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (33,9)-(33,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (33,12)-(33,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ MultiWriteNode (location: (35,0)-(35,11))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (35,0)-(35,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ ImplicitRestNode (location: (35,3)-(35,4))
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (35,5)-(35,6) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (35,7)-(35,11))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (35,7)-(35,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (35,10)-(35,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ MultiWriteNode (location: (37,0)-(37,16))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (37,0)-(37,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ SplatNode (location: (37,5)-(37,9))
+ │ │ ├── operator_loc: (37,5)-(37,6) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (37,6)-(37,9))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (37,10)-(37,11) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (37,12)-(37,16))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (37,12)-(37,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (37,15)-(37,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ MultiWriteNode (location: (39,0)-(39,27))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (39,0)-(39,3))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ └── @ MultiTargetNode (location: (39,5)-(39,15))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (39,6)-(39,9))
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (39,11)-(39,14))
+ │ │ │ ├── name: :baz
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: (39,5)-(39,6) = "("
+ │ │ └── rparen_loc: (39,14)-(39,15) = ")"
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (39,16)-(39,17) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (39,18)-(39,27))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (39,18)-(39,19))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ ArrayNode (location: (39,21)-(39,27))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (39,22)-(39,23))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ └── @ IntegerNode (location: (39,25)-(39,26))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 3
+ │ │ ├── opening_loc: (39,21)-(39,22) = "["
+ │ │ └── closing_loc: (39,26)-(39,27) = "]"
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ LocalVariableWriteNode (location: (41,0)-(41,10))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (41,0)-(41,3) = "foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (41,6)-(41,10))
+ │ │ ├── flags: contains_splat
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ SplatNode (location: (41,6)-(41,10))
+ │ │ │ ├── operator_loc: (41,6)-(41,7) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ LocalVariableReadNode (location: (41,7)-(41,10))
+ │ │ │ ├── name: :bar
+ │ │ │ └── depth: 0
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (41,4)-(41,5) = "="
+ ├── @ ConstantWriteNode (location: (43,0)-(43,10))
+ │ ├── name: :Foo
+ │ ├── name_loc: (43,0)-(43,3) = "Foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (43,6)-(43,10))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (43,6)-(43,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (43,9)-(43,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (43,4)-(43,5) = "="
+ ├── @ ParenthesesNode (location: (45,0)-(45,9))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (45,1)-(45,8))
+ │ │ └── body: (length: 3)
+ │ │ ├── @ CallNode (location: (45,1)-(45,2))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (45,1)-(45,2) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── @ CallNode (location: (45,4)-(45,5))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (45,4)-(45,5) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ CallNode (location: (45,7)-(45,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :c
+ │ │ ├── message_loc: (45,7)-(45,8) = "c"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (45,0)-(45,1) = "("
+ │ └── closing_loc: (45,8)-(45,9) = ")"
+ └── @ MultiWriteNode (location: (47,0)-(47,17))
+ ├── lefts: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (47,0)-(47,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── @ MultiTargetNode (location: (47,3)-(47,9))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (47,4)-(47,5))
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (47,7)-(47,8))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: (47,3)-(47,4) = "("
+ │ │ └── rparen_loc: (47,8)-(47,9) = ")"
+ │ └── @ LocalVariableTargetNode (location: (47,11)-(47,12))
+ │ ├── name: :d
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (47,13)-(47,14) = "="
+ └── value:
+ @ ArrayNode (location: (47,15)-(47,17))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (47,15)-(47,16) = "["
+ └── closing_loc: (47,16)-(47,17) = "]"
diff --git a/test/prism/snapshots/while.txt b/test/prism/snapshots/while.txt
new file mode 100644
index 0000000000..36fab49960
--- /dev/null
+++ b/test/prism/snapshots/while.txt
@@ -0,0 +1,469 @@
+@ ProgramNode (location: (1,0)-(23,20))
+├── locals: [:baz]
+└── statements:
+ @ StatementsNode (location: (1,0)-(23,20))
+ └── body: (length: 12)
+ ├── @ WhileNode (location: (1,0)-(1,18))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (1,0)-(1,5) = "while"
+ │ ├── closing_loc: (1,15)-(1,18) = "end"
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (1,6)-(1,10))
+ │ └── statements:
+ │ @ StatementsNode (location: (1,12)-(1,13))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,12)-(1,13))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ WhileNode (location: (3,0)-(3,12))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (3,2)-(3,7) = "while"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (3,8)-(3,12))
+ │ └── statements:
+ │ @ StatementsNode (location: (3,0)-(3,1))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (3,0)-(3,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ CallNode (location: (5,0)-(5,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (5,0)-(5,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,4)-(5,24))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,6)-(5,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (5,6)-(5,22))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (5,12)-(5,17) = "while"
+ │ │ ├── closing_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (5,18)-(5,22))
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (5,6)-(5,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (5,6)-(5,11))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (5,6)-(5,11) = "break"
+ │ ├── opening_loc: (5,4)-(5,5) = "{"
+ │ └── closing_loc: (5,23)-(5,24) = "}"
+ ├── @ CallNode (location: (7,0)-(7,23))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (7,0)-(7,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (7,4)-(7,23))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,6)-(7,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (7,6)-(7,21))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (7,11)-(7,16) = "while"
+ │ │ ├── closing_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (7,17)-(7,21))
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (7,6)-(7,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NextNode (location: (7,6)-(7,10))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (7,6)-(7,10) = "next"
+ │ ├── opening_loc: (7,4)-(7,5) = "{"
+ │ └── closing_loc: (7,22)-(7,23) = "}"
+ ├── @ WhileNode (location: (9,0)-(9,17))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (9,7)-(9,12) = "while"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ TrueNode (location: (9,13)-(9,17))
+ │ └── statements:
+ │ @ StatementsNode (location: (9,0)-(9,6))
+ │ └── body: (length: 1)
+ │ └── @ ReturnNode (location: (9,0)-(9,6))
+ │ ├── keyword_loc: (9,0)-(9,6) = "return"
+ │ └── arguments: ∅
+ ├── @ WhileNode (location: (11,0)-(11,21))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (11,11)-(11,16) = "while"
+ │ ├── closing_loc: ∅
+ │ ├── predicate:
+ │ │ @ CallNode (location: (11,17)-(11,21))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar?
+ │ │ ├── message_loc: (11,17)-(11,21) = "bar?"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (11,0)-(11,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (11,0)-(11,10))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (11,0)-(11,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,4)-(11,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (11,4)-(11,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (11,4)-(11,5) = ":"
+ │ │ │ ├── value_loc: (11,5)-(11,6) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ └── @ SymbolNode (location: (11,8)-(11,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (11,8)-(11,9) = ":"
+ │ │ ├── value_loc: (11,9)-(11,10) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (13,0)-(13,58))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (13,0)-(13,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (13,4)-(13,58))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (13,6)-(13,56))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (13,6)-(13,56))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (13,6)-(13,11) = "while"
+ │ │ ├── closing_loc: (13,53)-(13,56) = "end"
+ │ │ ├── predicate:
+ │ │ │ @ DefNode (location: (13,12)-(13,44))
+ │ │ │ ├── name: :foo
+ │ │ │ ├── name_loc: (13,21)-(13,24) = "foo"
+ │ │ │ ├── receiver:
+ │ │ │ │ @ SelfNode (location: (13,16)-(13,20))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (13,25)-(13,39))
+ │ │ │ │ ├── requireds: (length: 0)
+ │ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ │ └── @ OptionalParameterNode (location: (13,25)-(13,39))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ ├── name_loc: (13,25)-(13,26) = "a"
+ │ │ │ │ │ ├── operator_loc: (13,27)-(13,28) = "="
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ CallNode (location: (13,29)-(13,39))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :tap
+ │ │ │ │ │ ├── message_loc: (13,29)-(13,32) = "tap"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (13,33)-(13,39))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (13,33)-(13,35) = "do"
+ │ │ │ │ │ └── closing_loc: (13,36)-(13,39) = "end"
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── locals: [:a]
+ │ │ │ ├── def_keyword_loc: (13,12)-(13,15) = "def"
+ │ │ │ ├── operator_loc: (13,20)-(13,21) = "."
+ │ │ │ ├── lparen_loc: ∅
+ │ │ │ ├── rparen_loc: ∅
+ │ │ │ ├── equal_loc: ∅
+ │ │ │ └── end_keyword_loc: (13,41)-(13,44) = "end"
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (13,46)-(13,51))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (13,46)-(13,51))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (13,46)-(13,51) = "break"
+ │ ├── opening_loc: (13,4)-(13,5) = "{"
+ │ └── closing_loc: (13,57)-(13,58) = "}"
+ ├── @ CallNode (location: (15,0)-(15,55))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (15,0)-(15,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (15,4)-(15,55))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (15,6)-(15,53))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (15,6)-(15,53))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (15,6)-(15,11) = "while"
+ │ │ ├── closing_loc: (15,50)-(15,53) = "end"
+ │ │ ├── predicate:
+ │ │ │ @ ClassNode (location: (15,12)-(15,41))
+ │ │ │ ├── locals: [:a]
+ │ │ │ ├── class_keyword_loc: (15,12)-(15,17) = "class"
+ │ │ │ ├── constant_path:
+ │ │ │ │ @ ConstantReadNode (location: (15,18)-(15,21))
+ │ │ │ │ └── name: :Foo
+ │ │ │ ├── inheritance_operator_loc: ∅
+ │ │ │ ├── superclass: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (15,22)-(15,36))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableWriteNode (location: (15,22)-(15,36))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── depth: 0
+ │ │ │ │ ├── name_loc: (15,22)-(15,23) = "a"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (15,26)-(15,36))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :tap
+ │ │ │ │ │ ├── message_loc: (15,26)-(15,29) = "tap"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (15,30)-(15,36))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (15,30)-(15,32) = "do"
+ │ │ │ │ │ └── closing_loc: (15,33)-(15,36) = "end"
+ │ │ │ │ └── operator_loc: (15,24)-(15,25) = "="
+ │ │ │ ├── end_keyword_loc: (15,38)-(15,41) = "end"
+ │ │ │ └── name: :Foo
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (15,43)-(15,48))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (15,43)-(15,48))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (15,43)-(15,48) = "break"
+ │ ├── opening_loc: (15,4)-(15,5) = "{"
+ │ └── closing_loc: (15,54)-(15,55) = "}"
+ ├── @ CallNode (location: (17,0)-(17,56))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (17,0)-(17,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (17,4)-(17,56))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (17,6)-(17,54))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (17,6)-(17,54))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (17,6)-(17,11) = "while"
+ │ │ ├── closing_loc: (17,51)-(17,54) = "end"
+ │ │ ├── predicate:
+ │ │ │ @ SingletonClassNode (location: (17,12)-(17,42))
+ │ │ │ ├── locals: []
+ │ │ │ ├── class_keyword_loc: (17,12)-(17,17) = "class"
+ │ │ │ ├── operator_loc: (17,18)-(17,20) = "<<"
+ │ │ │ ├── expression:
+ │ │ │ │ @ SelfNode (location: (17,21)-(17,25))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (17,27)-(17,37))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (17,27)-(17,37))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :tap
+ │ │ │ │ ├── message_loc: (17,27)-(17,30) = "tap"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (17,31)-(17,37))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body: ∅
+ │ │ │ │ ├── opening_loc: (17,31)-(17,33) = "do"
+ │ │ │ │ └── closing_loc: (17,34)-(17,37) = "end"
+ │ │ │ └── end_keyword_loc: (17,39)-(17,42) = "end"
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (17,44)-(17,49))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (17,44)-(17,49))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (17,44)-(17,49) = "break"
+ │ ├── opening_loc: (17,4)-(17,5) = "{"
+ │ └── closing_loc: (17,55)-(17,56) = "}"
+ ├── @ CallNode (location: (19,0)-(19,60))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (19,0)-(19,3) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (19,4)-(19,60))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (19,6)-(19,58))
+ │ │ └── body: (length: 1)
+ │ │ └── @ WhileNode (location: (19,6)-(19,58))
+ │ │ ├── flags: ∅
+ │ │ ├── keyword_loc: (19,6)-(19,11) = "while"
+ │ │ ├── closing_loc: (19,55)-(19,58) = "end"
+ │ │ ├── predicate:
+ │ │ │ @ SingletonClassNode (location: (19,12)-(19,46))
+ │ │ │ ├── locals: [:a]
+ │ │ │ ├── class_keyword_loc: (19,12)-(19,17) = "class"
+ │ │ │ ├── operator_loc: (19,18)-(19,20) = "<<"
+ │ │ │ ├── expression:
+ │ │ │ │ @ SelfNode (location: (19,21)-(19,25))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (19,27)-(19,41))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableWriteNode (location: (19,27)-(19,41))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── depth: 0
+ │ │ │ │ ├── name_loc: (19,27)-(19,28) = "a"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (19,31)-(19,41))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :tap
+ │ │ │ │ │ ├── message_loc: (19,31)-(19,34) = "tap"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (19,35)-(19,41))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (19,35)-(19,37) = "do"
+ │ │ │ │ │ └── closing_loc: (19,38)-(19,41) = "end"
+ │ │ │ │ └── operator_loc: (19,29)-(19,30) = "="
+ │ │ │ └── end_keyword_loc: (19,43)-(19,46) = "end"
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (19,48)-(19,53))
+ │ │ └── body: (length: 1)
+ │ │ └── @ BreakNode (location: (19,48)-(19,53))
+ │ │ ├── arguments: ∅
+ │ │ └── keyword_loc: (19,48)-(19,53) = "break"
+ │ ├── opening_loc: (19,4)-(19,5) = "{"
+ │ └── closing_loc: (19,59)-(19,60) = "}"
+ ├── @ WhileNode (location: (21,0)-(21,31))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (21,0)-(21,5) = "while"
+ │ ├── closing_loc: (21,28)-(21,31) = "end"
+ │ ├── predicate:
+ │ │ @ DefNode (location: (21,6)-(21,26))
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (21,10)-(21,13) = "foo"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (21,16)-(21,26))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (21,16)-(21,26))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (21,16)-(21,19) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (21,20)-(21,26))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (21,20)-(21,22) = "do"
+ │ │ │ └── closing_loc: (21,23)-(21,26) = "end"
+ │ │ ├── locals: []
+ │ │ ├── def_keyword_loc: (21,6)-(21,9) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── equal_loc: (21,14)-(21,15) = "="
+ │ │ └── end_keyword_loc: ∅
+ │ └── statements: ∅
+ └── @ WhileNode (location: (23,0)-(23,20))
+ ├── flags: ∅
+ ├── keyword_loc: (23,4)-(23,9) = "while"
+ ├── closing_loc: ∅
+ ├── predicate:
+ │ @ MatchPredicateNode (location: (23,10)-(23,20))
+ │ ├── value:
+ │ │ @ CallNode (location: (23,10)-(23,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (23,10)-(23,13) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── pattern:
+ │ │ @ LocalVariableTargetNode (location: (23,17)-(23,20))
+ │ │ ├── name: :baz
+ │ │ └── depth: 0
+ │ └── operator_loc: (23,14)-(23,16) = "in"
+ └── statements:
+ @ StatementsNode (location: (23,0)-(23,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (23,0)-(23,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (23,0)-(23,3) = "foo"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/__ENCODING__.txt b/test/prism/snapshots/whitequark/__ENCODING__.txt
new file mode 100644
index 0000000000..1b223bd8fe
--- /dev/null
+++ b/test/prism/snapshots/whitequark/__ENCODING__.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ SourceEncodingNode (location: (1,0)-(1,12))
diff --git a/test/prism/snapshots/whitequark/__ENCODING___legacy_.txt b/test/prism/snapshots/whitequark/__ENCODING___legacy_.txt
new file mode 100644
index 0000000000..1b223bd8fe
--- /dev/null
+++ b/test/prism/snapshots/whitequark/__ENCODING___legacy_.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ SourceEncodingNode (location: (1,0)-(1,12))
diff --git a/test/prism/snapshots/whitequark/alias.txt b/test/prism/snapshots/whitequark/alias.txt
new file mode 100644
index 0000000000..509ea2b633
--- /dev/null
+++ b/test/prism/snapshots/whitequark/alias.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ AliasMethodNode (location: (1,0)-(1,14))
+ ├── new_name:
+ │ @ SymbolNode (location: (1,6)-(1,10))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,6)-(1,7) = ":"
+ │ ├── value_loc: (1,7)-(1,10) = "foo"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "foo"
+ ├── old_name:
+ │ @ SymbolNode (location: (1,11)-(1,14))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (1,11)-(1,14) = "bar"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "bar"
+ └── keyword_loc: (1,0)-(1,5) = "alias"
diff --git a/test/prism/snapshots/whitequark/alias_gvar.txt b/test/prism/snapshots/whitequark/alias_gvar.txt
new file mode 100644
index 0000000000..d13f816555
--- /dev/null
+++ b/test/prism/snapshots/whitequark/alias_gvar.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(3,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,11))
+ └── body: (length: 2)
+ ├── @ AliasGlobalVariableNode (location: (1,0)-(1,11))
+ │ ├── new_name:
+ │ │ @ GlobalVariableReadNode (location: (1,6)-(1,8))
+ │ │ └── name: :$a
+ │ ├── old_name:
+ │ │ @ BackReferenceReadNode (location: (1,9)-(1,11))
+ │ │ └── name: :$+
+ │ └── keyword_loc: (1,0)-(1,5) = "alias"
+ └── @ AliasGlobalVariableNode (location: (3,0)-(3,11))
+ ├── new_name:
+ │ @ GlobalVariableReadNode (location: (3,6)-(3,8))
+ │ └── name: :$a
+ ├── old_name:
+ │ @ GlobalVariableReadNode (location: (3,9)-(3,11))
+ │ └── name: :$b
+ └── keyword_loc: (3,0)-(3,5) = "alias"
diff --git a/test/prism/snapshots/whitequark/ambiuous_quoted_label_in_ternary_operator.txt b/test/prism/snapshots/whitequark/ambiuous_quoted_label_in_ternary_operator.txt
new file mode 100644
index 0000000000..c6a5c14934
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ambiuous_quoted_label_in_ternary_operator.txt
@@ -0,0 +1,60 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,15))
+ ├── if_keyword_loc: ∅
+ ├── predicate:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: (1,2)-(1,3) = "?"
+ ├── statements:
+ │ @ StatementsNode (location: (1,4)-(1,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,4)-(1,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,4)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,4)-(1,5) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :&
+ │ ├── message_loc: (1,6)-(1,7) = "&"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (1,8)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,8)-(1,9) = "'"
+ │ │ ├── content_loc: (1,9)-(1,9) = ""
+ │ │ ├── closing_loc: (1,9)-(1,10) = "'"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent:
+ │ @ ElseNode (location: (1,10)-(1,15))
+ │ ├── else_keyword_loc: (1,10)-(1,11) = ":"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,12)-(1,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ NilNode (location: (1,12)-(1,15))
+ │ └── end_keyword_loc: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/and.txt b/test/prism/snapshots/whitequark/and.txt
new file mode 100644
index 0000000000..d2e1b33c50
--- /dev/null
+++ b/test/prism/snapshots/whitequark/and.txt
@@ -0,0 +1,53 @@
+@ ProgramNode (location: (1,0)-(3,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,11))
+ └── body: (length: 2)
+ ├── @ AndNode (location: (1,0)-(1,10))
+ │ ├── left:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (1,7)-(1,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,7)-(1,10) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,4)-(1,6) = "&&"
+ └── @ AndNode (location: (3,0)-(3,11))
+ ├── left:
+ │ @ CallNode (location: (3,0)-(3,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── right:
+ │ @ CallNode (location: (3,8)-(3,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,8)-(3,11) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (3,4)-(3,7) = "and"
diff --git a/test/prism/snapshots/whitequark/and_asgn.txt b/test/prism/snapshots/whitequark/and_asgn.txt
new file mode 100644
index 0000000000..5c7a9a2319
--- /dev/null
+++ b/test/prism/snapshots/whitequark/and_asgn.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(3,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,15))
+ └── body: (length: 2)
+ ├── @ CallAndWriteNode (location: (1,0)-(1,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── message_loc: (1,4)-(1,5) = "a"
+ │ ├── read_name: :a
+ │ ├── write_name: :a=
+ │ ├── operator_loc: (1,6)-(1,9) = "&&="
+ │ └── value:
+ │ @ IntegerNode (location: (1,10)-(1,11))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── @ IndexAndWriteNode (location: (3,0)-(3,15))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (3,0)-(3,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── opening_loc: (3,3)-(3,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,4)-(3,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (3,4)-(3,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ └── @ IntegerNode (location: (3,7)-(3,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (3,8)-(3,9) = "]"
+ ├── block: ∅
+ ├── operator_loc: (3,10)-(3,13) = "&&="
+ └── value:
+ @ IntegerNode (location: (3,14)-(3,15))
+ ├── flags: decimal
+ └── value: 2
diff --git a/test/prism/snapshots/whitequark/and_or_masgn.txt b/test/prism/snapshots/whitequark/and_or_masgn.txt
new file mode 100644
index 0000000000..05aff040cd
--- /dev/null
+++ b/test/prism/snapshots/whitequark/and_or_masgn.txt
@@ -0,0 +1,93 @@
+@ ProgramNode (location: (1,0)-(3,19))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,19))
+ └── body: (length: 2)
+ ├── @ AndNode (location: (1,0)-(1,19))
+ │ ├── left:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ ParenthesesNode (location: (1,7)-(1,19))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,8)-(1,18))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ MultiWriteNode (location: (1,8)-(1,18))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ LocalVariableTargetNode (location: (1,8)-(1,9))
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── @ LocalVariableTargetNode (location: (1,11)-(1,12))
+ │ │ │ │ ├── name: :b
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: ∅
+ │ │ │ ├── rparen_loc: ∅
+ │ │ │ ├── operator_loc: (1,13)-(1,14) = "="
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (1,15)-(1,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,15)-(1,18) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (1,7)-(1,8) = "("
+ │ │ └── closing_loc: (1,18)-(1,19) = ")"
+ │ └── operator_loc: (1,4)-(1,6) = "&&"
+ └── @ OrNode (location: (3,0)-(3,19))
+ ├── left:
+ │ @ CallNode (location: (3,0)-(3,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── right:
+ │ @ ParenthesesNode (location: (3,7)-(3,19))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,8)-(3,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ MultiWriteNode (location: (3,8)-(3,18))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (3,8)-(3,9))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (3,11)-(3,12))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── operator_loc: (3,13)-(3,14) = "="
+ │ │ └── value:
+ │ │ @ CallNode (location: (3,15)-(3,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,15)-(3,18) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (3,7)-(3,8) = "("
+ │ └── closing_loc: (3,18)-(3,19) = ")"
+ └── operator_loc: (3,4)-(3,6) = "||"
diff --git a/test/prism/snapshots/whitequark/anonymous_blockarg.txt b/test/prism/snapshots/whitequark/anonymous_blockarg.txt
new file mode 100644
index 0000000000..92cf1504a9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/anonymous_blockarg.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,23))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,9))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block:
+ │ @ BlockParameterNode (location: (1,8)-(1,9))
+ │ ├── flags: ∅
+ │ ├── name: ∅
+ │ ├── name_loc: ∅
+ │ └── operator_loc: (1,8)-(1,9) = "&"
+ ├── body:
+ │ @ StatementsNode (location: (1,12)-(1,17))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,12)-(1,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,12)-(1,15) = "bar"
+ │ ├── opening_loc: (1,15)-(1,16) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (1,17)-(1,18) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (1,16)-(1,17))
+ │ ├── expression: ∅
+ │ └── operator_loc: (1,16)-(1,17) = "&"
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,9)-(1,10) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,20)-(1,23) = "end"
diff --git a/test/prism/snapshots/whitequark/arg.txt b/test/prism/snapshots/whitequark/arg.txt
new file mode 100644
index 0000000000..38fdb190f3
--- /dev/null
+++ b/test/prism/snapshots/whitequark/arg.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(3,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,20))
+ └── body: (length: 2)
+ ├── @ DefNode (location: (1,0)-(1,15))
+ │ ├── name: :f
+ │ ├── name_loc: (1,4)-(1,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,9))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :foo
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:foo]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ ├── rparen_loc: (1,9)-(1,10) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,12)-(1,15) = "end"
+ └── @ DefNode (location: (3,0)-(3,20))
+ ├── name: :f
+ ├── name_loc: (3,4)-(3,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (3,6)-(3,14))
+ │ ├── requireds: (length: 2)
+ │ │ ├── @ RequiredParameterNode (location: (3,6)-(3,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :foo
+ │ │ └── @ RequiredParameterNode (location: (3,11)-(3,14))
+ │ │ ├── flags: ∅
+ │ │ └── name: :bar
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:foo, :bar]
+ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (3,5)-(3,6) = "("
+ ├── rparen_loc: (3,14)-(3,15) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (3,17)-(3,20) = "end"
diff --git a/test/prism/snapshots/whitequark/arg_duplicate_ignored.txt b/test/prism/snapshots/whitequark/arg_duplicate_ignored.txt
new file mode 100644
index 0000000000..21dc1b7417
--- /dev/null
+++ b/test/prism/snapshots/whitequark/arg_duplicate_ignored.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(3,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,20))
+ └── body: (length: 2)
+ ├── @ DefNode (location: (1,0)-(1,18))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,8)-(1,12))
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ RequiredParameterNode (location: (1,8)-(1,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :_
+ │ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,12))
+ │ │ │ ├── flags: repeated_parameter
+ │ │ │ └── name: :_
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:_]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ ├── rparen_loc: (1,12)-(1,13) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,15)-(1,18) = "end"
+ └── @ DefNode (location: (3,0)-(3,20))
+ ├── name: :foo
+ ├── name_loc: (3,4)-(3,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (3,8)-(3,14))
+ │ ├── requireds: (length: 2)
+ │ │ ├── @ RequiredParameterNode (location: (3,8)-(3,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :_a
+ │ │ └── @ RequiredParameterNode (location: (3,12)-(3,14))
+ │ │ ├── flags: repeated_parameter
+ │ │ └── name: :_a
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:_a]
+ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (3,7)-(3,8) = "("
+ ├── rparen_loc: (3,14)-(3,15) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (3,17)-(3,20) = "end"
diff --git a/test/prism/snapshots/whitequark/arg_label.txt b/test/prism/snapshots/whitequark/arg_label.txt
new file mode 100644
index 0000000000..b72ea59a5d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/arg_label.txt
@@ -0,0 +1,115 @@
+@ ProgramNode (location: (1,0)-(6,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(6,12))
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,0)-(2,8))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,1)-(2,4))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (2,1)-(2,4))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (2,1)-(2,2) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (2,2)-(2,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (2,2)-(2,4))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (2,2)-(2,3) = ":"
+ │ │ │ ├── value_loc: (2,3)-(2,4) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (2,5)-(2,8) = "end"
+ ├── @ DefNode (location: (4,0)-(4,17))
+ │ ├── name: :foo
+ │ ├── name_loc: (4,4)-(4,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (4,10)-(4,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (4,10)-(4,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (4,10)-(4,11) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (4,11)-(4,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (4,11)-(4,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (4,11)-(4,12) = ":"
+ │ │ │ ├── value_loc: (4,12)-(4,13) = "b"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (4,0)-(4,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (4,7)-(4,8) = "("
+ │ ├── rparen_loc: (4,8)-(4,9) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (4,14)-(4,17) = "end"
+ └── @ CallNode (location: (6,0)-(6,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (6,0)-(6,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (6,2)-(6,12))
+ ├── locals: []
+ ├── parameters:
+ │ @ BlockParametersNode (location: (6,4)-(6,6))
+ │ ├── parameters: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (6,4)-(6,5) = "|"
+ │ └── closing_loc: (6,5)-(6,6) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (6,7)-(6,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (6,7)-(6,10))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (6,7)-(6,8) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (6,8)-(6,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (6,8)-(6,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (6,8)-(6,9) = ":"
+ │ │ ├── value_loc: (6,9)-(6,10) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (6,2)-(6,3) = "{"
+ └── closing_loc: (6,11)-(6,12) = "}"
diff --git a/test/prism/snapshots/whitequark/arg_scope.txt b/test/prism/snapshots/whitequark/arg_scope.txt
new file mode 100644
index 0000000000..c04356b8ee
--- /dev/null
+++ b/test/prism/snapshots/whitequark/arg_scope.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :lambda
+ ├── message_loc: (1,0)-(1,6) = "lambda"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,6)-(1,13))
+ ├── locals: [:a]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,7)-(1,11))
+ │ ├── parameters: ∅
+ │ ├── locals: (length: 1)
+ │ │ └── @ BlockLocalVariableNode (location: (1,9)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ └── name: :a
+ │ ├── opening_loc: (1,7)-(1,8) = "|"
+ │ └── closing_loc: (1,10)-(1,11) = "|"
+ ├── body:
+ │ @ StatementsNode (location: (1,11)-(1,12))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (1,11)-(1,12))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── opening_loc: (1,6)-(1,7) = "{"
+ └── closing_loc: (1,12)-(1,13) = "}"
diff --git a/test/prism/snapshots/whitequark/args.txt b/test/prism/snapshots/whitequark/args.txt
new file mode 100644
index 0000000000..bc7ea8ad7d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args.txt
@@ -0,0 +1,1075 @@
+@ ProgramNode (location: (1,0)-(63,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(63,21))
+ └── body: (length: 31)
+ ├── @ DefNode (location: (1,0)-(1,13))
+ │ ├── name: :f
+ │ ├── name_loc: (1,4)-(1,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (1,6)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (1,7)-(1,8) = "b"
+ │ │ └── operator_loc: (1,6)-(1,7) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,10)-(1,13) = "end"
+ ├── @ DefNode (location: (3,0)-(3,18))
+ │ ├── name: :f
+ │ ├── name_loc: (3,4)-(3,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,7)-(3,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (3,7)-(3,12))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ MultiTargetNode (location: (3,8)-(3,11))
+ │ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (3,9)-(3,10))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (3,8)-(3,9) = "("
+ │ │ │ │ └── rparen_loc: (3,10)-(3,11) = ")"
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (3,7)-(3,8) = "("
+ │ │ │ └── rparen_loc: (3,11)-(3,12) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (3,6)-(3,7) = "("
+ │ ├── rparen_loc: (3,12)-(3,13) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,15)-(3,18) = "end"
+ ├── @ DefNode (location: (5,0)-(5,16))
+ │ ├── name: :f
+ │ ├── name_loc: (5,4)-(5,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (5,7)-(5,10))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (5,7)-(5,10))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (5,8)-(5,9))
+ │ │ │ │ ├── operator_loc: (5,8)-(5,9) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (5,7)-(5,8) = "("
+ │ │ │ └── rparen_loc: (5,9)-(5,10) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (5,6)-(5,7) = "("
+ │ ├── rparen_loc: (5,10)-(5,11) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,13)-(5,16) = "end"
+ ├── @ DefNode (location: (7,0)-(7,19))
+ │ ├── name: :f
+ │ ├── name_loc: (7,4)-(7,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (7,7)-(7,13))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (7,7)-(7,13))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (7,8)-(7,9))
+ │ │ │ │ ├── operator_loc: (7,8)-(7,9) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (7,11)-(7,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── lparen_loc: (7,7)-(7,8) = "("
+ │ │ │ └── rparen_loc: (7,12)-(7,13) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:p]
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (7,6)-(7,7) = "("
+ │ ├── rparen_loc: (7,13)-(7,14) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (7,16)-(7,19) = "end"
+ ├── @ DefNode (location: (9,0)-(9,17))
+ │ ├── name: :f
+ │ ├── name_loc: (9,4)-(9,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (9,7)-(9,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (9,7)-(9,11))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (9,8)-(9,10))
+ │ │ │ │ ├── operator_loc: (9,8)-(9,9) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (9,9)-(9,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :r
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (9,7)-(9,8) = "("
+ │ │ │ └── rparen_loc: (9,10)-(9,11) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:r]
+ │ ├── def_keyword_loc: (9,0)-(9,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (9,6)-(9,7) = "("
+ │ ├── rparen_loc: (9,11)-(9,12) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (9,14)-(9,17) = "end"
+ ├── @ DefNode (location: (11,0)-(11,20))
+ │ ├── name: :f
+ │ ├── name_loc: (11,4)-(11,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (11,7)-(11,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (11,7)-(11,14))
+ │ │ │ ├── lefts: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (11,8)-(11,10))
+ │ │ │ │ ├── operator_loc: (11,8)-(11,9) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (11,9)-(11,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :r
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (11,12)-(11,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── lparen_loc: (11,7)-(11,8) = "("
+ │ │ │ └── rparen_loc: (11,13)-(11,14) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:r, :p]
+ │ ├── def_keyword_loc: (11,0)-(11,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (11,6)-(11,7) = "("
+ │ ├── rparen_loc: (11,14)-(11,15) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (11,17)-(11,20) = "end"
+ ├── @ DefNode (location: (13,0)-(13,19))
+ │ ├── name: :f
+ │ ├── name_loc: (13,4)-(13,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (13,7)-(13,13))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (13,7)-(13,13))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (13,8)-(13,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (13,11)-(13,12))
+ │ │ │ │ ├── operator_loc: (13,11)-(13,12) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (13,7)-(13,8) = "("
+ │ │ │ └── rparen_loc: (13,12)-(13,13) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (13,0)-(13,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (13,6)-(13,7) = "("
+ │ ├── rparen_loc: (13,13)-(13,14) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (13,16)-(13,19) = "end"
+ ├── @ DefNode (location: (15,0)-(15,22))
+ │ ├── name: :f
+ │ ├── name_loc: (15,4)-(15,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (15,7)-(15,16))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (15,7)-(15,16))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (15,8)-(15,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (15,11)-(15,12))
+ │ │ │ │ ├── operator_loc: (15,11)-(15,12) = "*"
+ │ │ │ │ └── expression: ∅
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (15,14)-(15,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── lparen_loc: (15,7)-(15,8) = "("
+ │ │ │ └── rparen_loc: (15,15)-(15,16) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :p]
+ │ ├── def_keyword_loc: (15,0)-(15,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (15,6)-(15,7) = "("
+ │ ├── rparen_loc: (15,16)-(15,17) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (15,19)-(15,22) = "end"
+ ├── @ DefNode (location: (17,0)-(17,20))
+ │ ├── name: :f
+ │ ├── name_loc: (17,4)-(17,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (17,7)-(17,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (17,7)-(17,14))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (17,8)-(17,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (17,11)-(17,13))
+ │ │ │ │ ├── operator_loc: (17,11)-(17,12) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (17,12)-(17,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :r
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (17,7)-(17,8) = "("
+ │ │ │ └── rparen_loc: (17,13)-(17,14) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :r]
+ │ ├── def_keyword_loc: (17,0)-(17,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (17,6)-(17,7) = "("
+ │ ├── rparen_loc: (17,14)-(17,15) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (17,17)-(17,20) = "end"
+ ├── @ DefNode (location: (19,0)-(19,23))
+ │ ├── name: :f
+ │ ├── name_loc: (19,4)-(19,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (19,7)-(19,17))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (19,7)-(19,17))
+ │ │ │ ├── lefts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (19,8)-(19,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── rest:
+ │ │ │ │ @ SplatNode (location: (19,11)-(19,13))
+ │ │ │ │ ├── operator_loc: (19,11)-(19,12) = "*"
+ │ │ │ │ └── expression:
+ │ │ │ │ @ RequiredParameterNode (location: (19,12)-(19,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :r
+ │ │ │ ├── rights: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (19,15)-(19,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── lparen_loc: (19,7)-(19,8) = "("
+ │ │ │ └── rparen_loc: (19,16)-(19,17) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :r, :p]
+ │ ├── def_keyword_loc: (19,0)-(19,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (19,6)-(19,7) = "("
+ │ ├── rparen_loc: (19,17)-(19,18) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (19,20)-(19,23) = "end"
+ ├── @ DefNode (location: (21,0)-(21,20))
+ │ ├── name: :f
+ │ ├── name_loc: (21,4)-(21,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (21,7)-(21,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ MultiTargetNode (location: (21,7)-(21,14))
+ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (21,8)-(21,9))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (21,11)-(21,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a1
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── rights: (length: 0)
+ │ │ │ ├── lparen_loc: (21,7)-(21,8) = "("
+ │ │ │ └── rparen_loc: (21,13)-(21,14) = ")"
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :a1]
+ │ ├── def_keyword_loc: (21,0)-(21,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (21,6)-(21,7) = "("
+ │ ├── rparen_loc: (21,14)-(21,15) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (21,17)-(21,20) = "end"
+ ├── @ DefNode (location: (23,0)-(23,23))
+ │ ├── name: :f
+ │ ├── name_loc: (23,4)-(23,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (23,7)-(23,17))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (23,7)-(23,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── name_loc: (23,7)-(23,11) = "foo:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (23,12)-(23,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (23,15)-(23,17))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (23,16)-(23,17) = "b"
+ │ │ └── operator_loc: (23,15)-(23,16) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:foo, :b]
+ │ ├── def_keyword_loc: (23,0)-(23,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (23,6)-(23,7) = "("
+ │ ├── rparen_loc: (23,17)-(23,18) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (23,20)-(23,23) = "end"
+ ├── @ DefNode (location: (25,0)-(25,38))
+ │ ├── name: :f
+ │ ├── name_loc: (25,4)-(25,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (25,7)-(25,32))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 2)
+ │ │ │ ├── @ OptionalKeywordParameterNode (location: (25,7)-(25,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── name_loc: (25,7)-(25,11) = "foo:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (25,12)-(25,13))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (25,15)-(25,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── name_loc: (25,15)-(25,19) = "bar:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (25,20)-(25,21))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (25,23)-(25,28))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── name_loc: (25,25)-(25,28) = "baz"
+ │ │ │ └── operator_loc: (25,23)-(25,25) = "**"
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (25,30)-(25,32))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (25,31)-(25,32) = "b"
+ │ │ └── operator_loc: (25,30)-(25,31) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:foo, :bar, :baz, :b]
+ │ ├── def_keyword_loc: (25,0)-(25,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (25,6)-(25,7) = "("
+ │ ├── rparen_loc: (25,32)-(25,33) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (25,35)-(25,38) = "end"
+ ├── @ DefNode (location: (27,0)-(27,20))
+ │ ├── name: :f
+ │ ├── name_loc: (27,4)-(27,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (27,6)-(27,15))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (27,6)-(27,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── name_loc: (27,8)-(27,11) = "baz"
+ │ │ │ └── operator_loc: (27,6)-(27,8) = "**"
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (27,13)-(27,15))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (27,14)-(27,15) = "b"
+ │ │ └── operator_loc: (27,13)-(27,14) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:baz, :b]
+ │ ├── def_keyword_loc: (27,0)-(27,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (27,17)-(27,20) = "end"
+ ├── @ DefNode (location: (29,0)-(29,16))
+ │ ├── name: :f
+ │ ├── name_loc: (29,4)-(29,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (29,6)-(29,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (29,6)-(29,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (29,6)-(29,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ KeywordRestParameterNode (location: (29,9)-(29,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: ∅
+ │ │ │ ├── name_loc: ∅
+ │ │ │ └── operator_loc: (29,9)-(29,11) = "**"
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (29,0)-(29,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (29,13)-(29,16) = "end"
+ ├── @ DefNode (location: (31,0)-(31,17))
+ │ ├── name: :f
+ │ ├── name_loc: (31,4)-(31,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (31,6)-(31,12))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (31,6)-(31,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :r
+ │ │ │ ├── name_loc: (31,7)-(31,8) = "r"
+ │ │ │ └── operator_loc: (31,6)-(31,7) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (31,10)-(31,12))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (31,11)-(31,12) = "b"
+ │ │ └── operator_loc: (31,10)-(31,11) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:r, :b]
+ │ ├── def_keyword_loc: (31,0)-(31,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (31,14)-(31,17) = "end"
+ ├── @ DefNode (location: (33,0)-(33,20))
+ │ ├── name: :f
+ │ ├── name_loc: (33,4)-(33,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (33,6)-(33,15))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (33,6)-(33,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :r
+ │ │ │ ├── name_loc: (33,7)-(33,8) = "r"
+ │ │ │ └── operator_loc: (33,6)-(33,7) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (33,10)-(33,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :p
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (33,13)-(33,15))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (33,14)-(33,15) = "b"
+ │ │ └── operator_loc: (33,13)-(33,14) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:r, :p, :b]
+ │ ├── def_keyword_loc: (33,0)-(33,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (33,17)-(33,20) = "end"
+ ├── @ DefNode (location: (35,0)-(35,11))
+ │ ├── name: :f
+ │ ├── name_loc: (35,4)-(35,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (35,0)-(35,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (35,8)-(35,11) = "end"
+ ├── @ DefNode (location: (37,0)-(37,16))
+ │ ├── name: :f
+ │ ├── name_loc: (37,4)-(37,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (37,6)-(37,11))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (37,6)-(37,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (37,9)-(37,11))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (37,10)-(37,11) = "b"
+ │ │ └── operator_loc: (37,9)-(37,10) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:a, :b]
+ │ ├── def_keyword_loc: (37,0)-(37,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (37,13)-(37,16) = "end"
+ ├── @ DefNode (location: (39,0)-(39,20))
+ │ ├── name: :f
+ │ ├── name_loc: (39,4)-(39,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (39,6)-(39,15))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (39,6)-(39,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (39,9)-(39,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :r
+ │ │ │ ├── name_loc: (39,10)-(39,11) = "r"
+ │ │ │ └── operator_loc: (39,9)-(39,10) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (39,13)-(39,15))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (39,14)-(39,15) = "b"
+ │ │ └── operator_loc: (39,13)-(39,14) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:a, :r, :b]
+ │ ├── def_keyword_loc: (39,0)-(39,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (39,17)-(39,20) = "end"
+ ├── @ DefNode (location: (41,0)-(41,23))
+ │ ├── name: :f
+ │ ├── name_loc: (41,4)-(41,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (41,6)-(41,18))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (41,6)-(41,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (41,9)-(41,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :r
+ │ │ │ ├── name_loc: (41,10)-(41,11) = "r"
+ │ │ │ └── operator_loc: (41,9)-(41,10) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (41,13)-(41,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :p
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (41,16)-(41,18))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (41,17)-(41,18) = "b"
+ │ │ └── operator_loc: (41,16)-(41,17) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:a, :r, :p, :b]
+ │ ├── def_keyword_loc: (41,0)-(41,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (41,20)-(41,23) = "end"
+ ├── @ DefNode (location: (43,0)-(43,21))
+ │ ├── name: :f
+ │ ├── name_loc: (43,4)-(43,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (43,6)-(43,16))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (43,6)-(43,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (43,9)-(43,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :o
+ │ │ │ ├── name_loc: (43,9)-(43,10) = "o"
+ │ │ │ ├── operator_loc: (43,10)-(43,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (43,11)-(43,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (43,14)-(43,16))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (43,15)-(43,16) = "b"
+ │ │ └── operator_loc: (43,14)-(43,15) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:a, :o, :b]
+ │ ├── def_keyword_loc: (43,0)-(43,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (43,18)-(43,21) = "end"
+ ├── @ DefNode (location: (45,0)-(45,25))
+ │ ├── name: :f
+ │ ├── name_loc: (45,4)-(45,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (45,6)-(45,20))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (45,6)-(45,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (45,9)-(45,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :o
+ │ │ │ ├── name_loc: (45,9)-(45,10) = "o"
+ │ │ │ ├── operator_loc: (45,10)-(45,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (45,11)-(45,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (45,14)-(45,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :r
+ │ │ │ ├── name_loc: (45,15)-(45,16) = "r"
+ │ │ │ └── operator_loc: (45,14)-(45,15) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (45,18)-(45,20))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (45,19)-(45,20) = "b"
+ │ │ └── operator_loc: (45,18)-(45,19) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:a, :o, :r, :b]
+ │ ├── def_keyword_loc: (45,0)-(45,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (45,22)-(45,25) = "end"
+ ├── @ DefNode (location: (47,0)-(47,28))
+ │ ├── name: :f
+ │ ├── name_loc: (47,4)-(47,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (47,6)-(47,23))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (47,6)-(47,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (47,9)-(47,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :o
+ │ │ │ ├── name_loc: (47,9)-(47,10) = "o"
+ │ │ │ ├── operator_loc: (47,10)-(47,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (47,11)-(47,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (47,14)-(47,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :r
+ │ │ │ ├── name_loc: (47,15)-(47,16) = "r"
+ │ │ │ └── operator_loc: (47,14)-(47,15) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (47,18)-(47,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :p
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (47,21)-(47,23))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (47,22)-(47,23) = "b"
+ │ │ └── operator_loc: (47,21)-(47,22) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:a, :o, :r, :p, :b]
+ │ ├── def_keyword_loc: (47,0)-(47,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (47,25)-(47,28) = "end"
+ ├── @ DefNode (location: (49,0)-(49,24))
+ │ ├── name: :f
+ │ ├── name_loc: (49,4)-(49,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (49,6)-(49,19))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (49,6)-(49,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (49,9)-(49,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :o
+ │ │ │ ├── name_loc: (49,9)-(49,10) = "o"
+ │ │ │ ├── operator_loc: (49,10)-(49,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (49,11)-(49,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (49,14)-(49,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :p
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (49,17)-(49,19))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (49,18)-(49,19) = "b"
+ │ │ └── operator_loc: (49,17)-(49,18) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:a, :o, :p, :b]
+ │ ├── def_keyword_loc: (49,0)-(49,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (49,21)-(49,24) = "end"
+ ├── @ DefNode (location: (51,0)-(52,5))
+ │ ├── name: :f
+ │ ├── name_loc: (51,4)-(51,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (51,6)-(51,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (51,6)-(51,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ └── name_loc: (51,6)-(51,10) = "foo:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:foo]
+ │ ├── def_keyword_loc: (51,0)-(51,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (52,2)-(52,5) = "end"
+ ├── @ DefNode (location: (54,0)-(55,5))
+ │ ├── name: :f
+ │ ├── name_loc: (54,4)-(54,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (54,6)-(54,13))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ OptionalKeywordParameterNode (location: (54,6)-(54,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── name_loc: (54,6)-(54,10) = "foo:"
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (54,11)-(54,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: -1
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:foo]
+ │ ├── def_keyword_loc: (54,0)-(54,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (55,2)-(55,5) = "end"
+ ├── @ DefNode (location: (57,0)-(57,18))
+ │ ├── name: :f
+ │ ├── name_loc: (57,4)-(57,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (57,6)-(57,13))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (57,6)-(57,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :o
+ │ │ │ ├── name_loc: (57,6)-(57,7) = "o"
+ │ │ │ ├── operator_loc: (57,7)-(57,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (57,8)-(57,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (57,11)-(57,13))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (57,12)-(57,13) = "b"
+ │ │ └── operator_loc: (57,11)-(57,12) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:o, :b]
+ │ ├── def_keyword_loc: (57,0)-(57,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (57,15)-(57,18) = "end"
+ ├── @ DefNode (location: (59,0)-(59,22))
+ │ ├── name: :f
+ │ ├── name_loc: (59,4)-(59,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (59,6)-(59,17))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (59,6)-(59,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :o
+ │ │ │ ├── name_loc: (59,6)-(59,7) = "o"
+ │ │ │ ├── operator_loc: (59,7)-(59,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (59,8)-(59,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (59,11)-(59,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :r
+ │ │ │ ├── name_loc: (59,12)-(59,13) = "r"
+ │ │ │ └── operator_loc: (59,11)-(59,12) = "*"
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (59,15)-(59,17))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (59,16)-(59,17) = "b"
+ │ │ └── operator_loc: (59,15)-(59,16) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:o, :r, :b]
+ │ ├── def_keyword_loc: (59,0)-(59,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (59,19)-(59,22) = "end"
+ ├── @ DefNode (location: (61,0)-(61,25))
+ │ ├── name: :f
+ │ ├── name_loc: (61,4)-(61,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (61,6)-(61,20))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (61,6)-(61,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :o
+ │ │ │ ├── name_loc: (61,6)-(61,7) = "o"
+ │ │ │ ├── operator_loc: (61,7)-(61,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (61,8)-(61,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest:
+ │ │ │ @ RestParameterNode (location: (61,11)-(61,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :r
+ │ │ │ ├── name_loc: (61,12)-(61,13) = "r"
+ │ │ │ └── operator_loc: (61,11)-(61,12) = "*"
+ │ │ ├── posts: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (61,15)-(61,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :p
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block:
+ │ │ @ BlockParameterNode (location: (61,18)-(61,20))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :b
+ │ │ ├── name_loc: (61,19)-(61,20) = "b"
+ │ │ └── operator_loc: (61,18)-(61,19) = "&"
+ │ ├── body: ∅
+ │ ├── locals: [:o, :r, :p, :b]
+ │ ├── def_keyword_loc: (61,0)-(61,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (61,22)-(61,25) = "end"
+ └── @ DefNode (location: (63,0)-(63,21))
+ ├── name: :f
+ ├── name_loc: (63,4)-(63,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (63,6)-(63,16))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 1)
+ │ │ └── @ OptionalParameterNode (location: (63,6)-(63,9))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :o
+ │ │ ├── name_loc: (63,6)-(63,7) = "o"
+ │ │ ├── operator_loc: (63,7)-(63,8) = "="
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (63,8)-(63,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── rest: ∅
+ │ ├── posts: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (63,11)-(63,12))
+ │ │ ├── flags: ∅
+ │ │ └── name: :p
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block:
+ │ @ BlockParameterNode (location: (63,14)-(63,16))
+ │ ├── flags: ∅
+ │ ├── name: :b
+ │ ├── name_loc: (63,15)-(63,16) = "b"
+ │ └── operator_loc: (63,14)-(63,15) = "&"
+ ├── body: ∅
+ ├── locals: [:o, :p, :b]
+ ├── def_keyword_loc: (63,0)-(63,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (63,18)-(63,21) = "end"
diff --git a/test/prism/snapshots/whitequark/args_args_assocs.txt b/test/prism/snapshots/whitequark/args_args_assocs.txt
new file mode 100644
index 0000000000..6297f212d8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_args_assocs.txt
@@ -0,0 +1,96 @@
+@ ProgramNode (location: (1,0)-(3,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,24))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,19))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (1,0)-(1,3) = "fun"
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,18))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (1,4)-(1,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (1,4)-(1,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ KeywordHashNode (location: (1,9)-(1,18))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,9)-(1,18))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,9)-(1,13))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,9)-(1,10) = ":"
+ │ │ │ ├── value_loc: (1,10)-(1,13) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,17)-(1,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (1,14)-(1,16) = "=>"
+ │ ├── closing_loc: (1,18)-(1,19) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,24))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (3,0)-(3,3) = "fun"
+ ├── opening_loc: (3,3)-(3,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,4)-(3,18))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (3,4)-(3,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,4)-(3,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ KeywordHashNode (location: (3,9)-(3,18))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (3,9)-(3,18))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (3,9)-(3,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,9)-(3,10) = ":"
+ │ │ ├── value_loc: (3,10)-(3,13) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,17)-(3,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (3,14)-(3,16) = "=>"
+ ├── closing_loc: (3,24)-(3,25) = ")"
+ └── block:
+ @ BlockArgumentNode (location: (3,20)-(3,24))
+ ├── expression:
+ │ @ CallNode (location: (3,21)-(3,24))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :baz
+ │ ├── message_loc: (3,21)-(3,24) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (3,20)-(3,21) = "&"
diff --git a/test/prism/snapshots/whitequark/args_args_assocs_comma.txt b/test/prism/snapshots/whitequark/args_args_assocs_comma.txt
new file mode 100644
index 0000000000..969514a511
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_args_assocs_comma.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,20))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,3)-(1,20) = "[bar, :baz => 1,]"
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,18))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (1,4)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,4)-(1,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ KeywordHashNode (location: (1,9)-(1,18))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,9)-(1,18))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,9)-(1,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,9)-(1,10) = ":"
+ │ │ ├── value_loc: (1,10)-(1,13) = "baz"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,17)-(1,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,14)-(1,16) = "=>"
+ ├── closing_loc: (1,19)-(1,20) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/args_args_comma.txt b/test/prism/snapshots/whitequark/args_args_comma.txt
new file mode 100644
index 0000000000..09113a72b6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_args_comma.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,3)-(1,9) = "[bar,]"
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,4)-(1,7))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,4)-(1,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (1,8)-(1,9) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/args_args_star.txt b/test/prism/snapshots/whitequark/args_args_star.txt
new file mode 100644
index 0000000000..26c9e72da3
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_args_star.txt
@@ -0,0 +1,90 @@
+@ ProgramNode (location: (1,0)-(3,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,19))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (1,0)-(1,3) = "fun"
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (1,4)-(1,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (1,4)-(1,7) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ SplatNode (location: (1,9)-(1,13))
+ │ │ ├── operator_loc: (1,9)-(1,10) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (1,10)-(1,13))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,10)-(1,13) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (1,13)-(1,14) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,19))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (3,0)-(3,3) = "fun"
+ ├── opening_loc: (3,3)-(3,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,4)-(3,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (3,4)-(3,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,4)-(3,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ SplatNode (location: (3,9)-(3,13))
+ │ ├── operator_loc: (3,9)-(3,10) = "*"
+ │ └── expression:
+ │ @ CallNode (location: (3,10)-(3,13))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,10)-(3,13) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (3,19)-(3,20) = ")"
+ └── block:
+ @ BlockArgumentNode (location: (3,15)-(3,19))
+ ├── expression:
+ │ @ CallNode (location: (3,16)-(3,19))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :baz
+ │ ├── message_loc: (3,16)-(3,19) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (3,15)-(3,16) = "&"
diff --git a/test/prism/snapshots/whitequark/args_assocs.txt b/test/prism/snapshots/whitequark/args_assocs.txt
new file mode 100644
index 0000000000..47cb68d899
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_assocs.txt
@@ -0,0 +1,195 @@
+@ ProgramNode (location: (1,0)-(11,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,17))
+ └── body: (length: 6)
+ ├── @ CallNode (location: (1,0)-(1,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (1,0)-(1,3) = "fun"
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,4)-(1,13))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,4)-(1,13))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,4)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,4)-(1,5) = ":"
+ │ │ │ ├── value_loc: (1,5)-(1,8) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (1,9)-(1,11) = "=>"
+ │ ├── closing_loc: (1,13)-(1,14) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,19))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (3,0)-(3,3) = "fun"
+ │ ├── opening_loc: (3,3)-(3,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,4)-(3,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (3,4)-(3,13))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (3,4)-(3,13))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (3,4)-(3,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,4)-(3,5) = ":"
+ │ │ │ ├── value_loc: (3,5)-(3,8) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,12)-(3,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (3,9)-(3,11) = "=>"
+ │ ├── closing_loc: (3,19)-(3,20) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (3,15)-(3,19))
+ │ ├── expression:
+ │ │ @ CallNode (location: (3,16)-(3,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (3,16)-(3,19) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (3,15)-(3,16) = "&"
+ ├── @ CallNode (location: (5,0)-(5,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (5,0)-(5,4))
+ │ ├── call_operator_loc: (5,4)-(5,5) = "."
+ │ ├── name: :[]=
+ │ ├── message_loc: (5,5)-(5,8) = "[]="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,9)-(5,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (5,9)-(5,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (5,9)-(5,12) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ KeywordHashNode (location: (5,14)-(5,21))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (5,14)-(5,21))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (5,14)-(5,16))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (5,14)-(5,15) = ":"
+ │ │ │ ├── value_loc: (5,15)-(5,16) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (5,20)-(5,21))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (5,17)-(5,19) = "=>"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (7,0)-(7,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (7,0)-(7,4))
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (7,4)-(7,15) = "[:bar => 1]"
+ │ ├── opening_loc: (7,4)-(7,5) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,5)-(7,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (7,5)-(7,14))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (7,5)-(7,14))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (7,5)-(7,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (7,5)-(7,6) = ":"
+ │ │ │ ├── value_loc: (7,6)-(7,9) = "bar"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (7,13)-(7,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (7,10)-(7,12) = "=>"
+ │ ├── closing_loc: (7,14)-(7,15) = "]"
+ │ └── block: ∅
+ ├── @ SuperNode (location: (9,0)-(9,17))
+ │ ├── keyword_loc: (9,0)-(9,5) = "super"
+ │ ├── lparen_loc: (9,5)-(9,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,6)-(9,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (9,6)-(9,16))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (9,6)-(9,16))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (9,6)-(9,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (9,6)-(9,7) = ":"
+ │ │ │ ├── value_loc: (9,7)-(9,10) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (9,14)-(9,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ └── operator_loc: (9,11)-(9,13) = "=>"
+ │ ├── rparen_loc: (9,16)-(9,17) = ")"
+ │ └── block: ∅
+ └── @ YieldNode (location: (11,0)-(11,17))
+ ├── keyword_loc: (11,0)-(11,5) = "yield"
+ ├── lparen_loc: (11,5)-(11,6) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (11,6)-(11,16))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (11,6)-(11,16))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (11,6)-(11,16))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (11,6)-(11,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (11,6)-(11,7) = ":"
+ │ │ ├── value_loc: (11,7)-(11,10) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (11,14)-(11,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ └── operator_loc: (11,11)-(11,13) = "=>"
+ └── rparen_loc: (11,16)-(11,17) = ")"
diff --git a/test/prism/snapshots/whitequark/args_assocs_comma.txt b/test/prism/snapshots/whitequark/args_assocs_comma.txt
new file mode 100644
index 0000000000..b1b9fbeefe
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_assocs_comma.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,15))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,3)-(1,15) = "[:baz => 1,]"
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,4)-(1,13))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,4)-(1,13))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,4)-(1,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,4)-(1,5) = ":"
+ │ │ ├── value_loc: (1,5)-(1,8) = "baz"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,9)-(1,11) = "=>"
+ ├── closing_loc: (1,14)-(1,15) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/args_assocs_legacy.txt b/test/prism/snapshots/whitequark/args_assocs_legacy.txt
new file mode 100644
index 0000000000..47cb68d899
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_assocs_legacy.txt
@@ -0,0 +1,195 @@
+@ ProgramNode (location: (1,0)-(11,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,17))
+ └── body: (length: 6)
+ ├── @ CallNode (location: (1,0)-(1,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (1,0)-(1,3) = "fun"
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,4)-(1,13))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,4)-(1,13))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,4)-(1,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,4)-(1,5) = ":"
+ │ │ │ ├── value_loc: (1,5)-(1,8) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (1,9)-(1,11) = "=>"
+ │ ├── closing_loc: (1,13)-(1,14) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,19))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (3,0)-(3,3) = "fun"
+ │ ├── opening_loc: (3,3)-(3,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,4)-(3,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (3,4)-(3,13))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (3,4)-(3,13))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (3,4)-(3,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,4)-(3,5) = ":"
+ │ │ │ ├── value_loc: (3,5)-(3,8) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,12)-(3,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (3,9)-(3,11) = "=>"
+ │ ├── closing_loc: (3,19)-(3,20) = ")"
+ │ └── block:
+ │ @ BlockArgumentNode (location: (3,15)-(3,19))
+ │ ├── expression:
+ │ │ @ CallNode (location: (3,16)-(3,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (3,16)-(3,19) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (3,15)-(3,16) = "&"
+ ├── @ CallNode (location: (5,0)-(5,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (5,0)-(5,4))
+ │ ├── call_operator_loc: (5,4)-(5,5) = "."
+ │ ├── name: :[]=
+ │ ├── message_loc: (5,5)-(5,8) = "[]="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,9)-(5,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (5,9)-(5,12))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (5,9)-(5,12) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ KeywordHashNode (location: (5,14)-(5,21))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (5,14)-(5,21))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (5,14)-(5,16))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (5,14)-(5,15) = ":"
+ │ │ │ ├── value_loc: (5,15)-(5,16) = "a"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (5,20)-(5,21))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (5,17)-(5,19) = "=>"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (7,0)-(7,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (7,0)-(7,4))
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :[]
+ │ ├── message_loc: (7,4)-(7,15) = "[:bar => 1]"
+ │ ├── opening_loc: (7,4)-(7,5) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,5)-(7,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (7,5)-(7,14))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (7,5)-(7,14))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (7,5)-(7,9))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (7,5)-(7,6) = ":"
+ │ │ │ ├── value_loc: (7,6)-(7,9) = "bar"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (7,13)-(7,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: (7,10)-(7,12) = "=>"
+ │ ├── closing_loc: (7,14)-(7,15) = "]"
+ │ └── block: ∅
+ ├── @ SuperNode (location: (9,0)-(9,17))
+ │ ├── keyword_loc: (9,0)-(9,5) = "super"
+ │ ├── lparen_loc: (9,5)-(9,6) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,6)-(9,16))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (9,6)-(9,16))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (9,6)-(9,16))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (9,6)-(9,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (9,6)-(9,7) = ":"
+ │ │ │ ├── value_loc: (9,7)-(9,10) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (9,14)-(9,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ └── operator_loc: (9,11)-(9,13) = "=>"
+ │ ├── rparen_loc: (9,16)-(9,17) = ")"
+ │ └── block: ∅
+ └── @ YieldNode (location: (11,0)-(11,17))
+ ├── keyword_loc: (11,0)-(11,5) = "yield"
+ ├── lparen_loc: (11,5)-(11,6) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (11,6)-(11,16))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (11,6)-(11,16))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (11,6)-(11,16))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (11,6)-(11,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (11,6)-(11,7) = ":"
+ │ │ ├── value_loc: (11,7)-(11,10) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (11,14)-(11,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ └── operator_loc: (11,11)-(11,13) = "=>"
+ └── rparen_loc: (11,16)-(11,17) = ")"
diff --git a/test/prism/snapshots/whitequark/args_block_pass.txt b/test/prism/snapshots/whitequark/args_block_pass.txt
new file mode 100644
index 0000000000..99ffa81934
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_block_pass.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (1,0)-(1,3) = "fun"
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments: ∅
+ ├── closing_loc: (1,8)-(1,9) = ")"
+ └── block:
+ @ BlockArgumentNode (location: (1,4)-(1,8))
+ ├── expression:
+ │ @ CallNode (location: (1,5)-(1,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,5)-(1,8) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (1,4)-(1,5) = "&"
diff --git a/test/prism/snapshots/whitequark/args_cmd.txt b/test/prism/snapshots/whitequark/args_cmd.txt
new file mode 100644
index 0000000000..0089e56157
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_cmd.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,10))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (1,0)-(1,3) = "fun"
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,4)-(1,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (1,4)-(1,5) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,6)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,6)-(1,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,6)-(1,9) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (1,9)-(1,10) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/args_star.txt b/test/prism/snapshots/whitequark/args_star.txt
new file mode 100644
index 0000000000..c19577f106
--- /dev/null
+++ b/test/prism/snapshots/whitequark/args_star.txt
@@ -0,0 +1,70 @@
+@ ProgramNode (location: (1,0)-(3,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,14))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (1,0)-(1,3) = "fun"
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (1,4)-(1,8))
+ │ │ ├── operator_loc: (1,4)-(1,5) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (1,5)-(1,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,5)-(1,8) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (1,8)-(1,9) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (3,0)-(3,3) = "fun"
+ ├── opening_loc: (3,3)-(3,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,4)-(3,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ SplatNode (location: (3,4)-(3,8))
+ │ ├── operator_loc: (3,4)-(3,5) = "*"
+ │ └── expression:
+ │ @ CallNode (location: (3,5)-(3,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,5)-(3,8) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (3,14)-(3,15) = ")"
+ └── block:
+ @ BlockArgumentNode (location: (3,10)-(3,14))
+ ├── expression:
+ │ @ CallNode (location: (3,11)-(3,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :baz
+ │ ├── message_loc: (3,11)-(3,14) = "baz"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (3,10)-(3,11) = "&"
diff --git a/test/prism/snapshots/whitequark/array_assocs.txt b/test/prism/snapshots/whitequark/array_assocs.txt
new file mode 100644
index 0000000000..3747e3f7d8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_assocs.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(3,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,13))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(1,10))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,2)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,2)-(1,8))
+ │ │ ├── key:
+ │ │ │ @ IntegerNode (location: (1,2)-(1,3))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (1,4)-(1,6) = "=>"
+ │ ├── opening_loc: (1,0)-(1,1) = "["
+ │ └── closing_loc: (1,9)-(1,10) = "]"
+ └── @ ArrayNode (location: (3,0)-(3,13))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ IntegerNode (location: (3,2)-(3,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ KeywordHashNode (location: (3,5)-(3,11))
+ │ ├── flags: ∅
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (3,5)-(3,11))
+ │ ├── key:
+ │ │ @ IntegerNode (location: (3,5)-(3,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,10)-(3,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── operator_loc: (3,7)-(3,9) = "=>"
+ ├── opening_loc: (3,0)-(3,1) = "["
+ └── closing_loc: (3,12)-(3,13) = "]"
diff --git a/test/prism/snapshots/whitequark/array_plain.txt b/test/prism/snapshots/whitequark/array_plain.txt
new file mode 100644
index 0000000000..b183a7ac6b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_plain.txt
@@ -0,0 +1,16 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ IntegerNode (location: (1,1)-(1,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── opening_loc: (1,0)-(1,1) = "["
+ └── closing_loc: (1,5)-(1,6) = "]"
diff --git a/test/prism/snapshots/whitequark/array_splat.txt b/test/prism/snapshots/whitequark/array_splat.txt
new file mode 100644
index 0000000000..f76563e9f4
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_splat.txt
@@ -0,0 +1,68 @@
+@ ProgramNode (location: (1,0)-(5,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,9))
+ └── body: (length: 3)
+ ├── @ ArrayNode (location: (1,0)-(1,6))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 1)
+ │ │ └── @ SplatNode (location: (1,1)-(1,5))
+ │ │ ├── operator_loc: (1,1)-(1,2) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (1,2)-(1,5))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,2)-(1,5) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "["
+ │ └── closing_loc: (1,5)-(1,6) = "]"
+ ├── @ ArrayNode (location: (3,0)-(3,12))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 3)
+ │ │ ├── @ IntegerNode (location: (3,1)-(3,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ SplatNode (location: (3,4)-(3,8))
+ │ │ │ ├── operator_loc: (3,4)-(3,5) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (3,5)-(3,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (3,5)-(3,8) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ IntegerNode (location: (3,10)-(3,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: (3,0)-(3,1) = "["
+ │ └── closing_loc: (3,11)-(3,12) = "]"
+ └── @ ArrayNode (location: (5,0)-(5,9))
+ ├── flags: contains_splat
+ ├── elements: (length: 2)
+ │ ├── @ IntegerNode (location: (5,1)-(5,2))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ SplatNode (location: (5,4)-(5,8))
+ │ ├── operator_loc: (5,4)-(5,5) = "*"
+ │ └── expression:
+ │ @ CallNode (location: (5,5)-(5,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,5)-(5,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (5,0)-(5,1) = "["
+ └── closing_loc: (5,8)-(5,9) = "]"
diff --git a/test/prism/snapshots/whitequark/array_symbols.txt b/test/prism/snapshots/whitequark/array_symbols.txt
new file mode 100644
index 0000000000..0662f01af1
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_symbols.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,11))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ SymbolNode (location: (1,3)-(1,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,3)-(1,6) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── @ SymbolNode (location: (1,7)-(1,10))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: ∅
+ │ ├── value_loc: (1,7)-(1,10) = "bar"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "bar"
+ ├── opening_loc: (1,0)-(1,3) = "%i["
+ └── closing_loc: (1,10)-(1,11) = "]"
diff --git a/test/prism/snapshots/whitequark/array_symbols_empty.txt b/test/prism/snapshots/whitequark/array_symbols_empty.txt
new file mode 100644
index 0000000000..1068ba6d0e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_symbols_empty.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(3,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,4))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(1,4))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (1,0)-(1,3) = "%I("
+ │ └── closing_loc: (1,3)-(1,4) = ")"
+ └── @ ArrayNode (location: (3,0)-(3,4))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (3,0)-(3,3) = "%i["
+ └── closing_loc: (3,3)-(3,4) = "]"
diff --git a/test/prism/snapshots/whitequark/array_symbols_interp.txt b/test/prism/snapshots/whitequark/array_symbols_interp.txt
new file mode 100644
index 0000000000..2437486b43
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_symbols_interp.txt
@@ -0,0 +1,67 @@
+@ ProgramNode (location: (1,0)-(3,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,13))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(1,14))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ SymbolNode (location: (1,3)-(1,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,3)-(1,6) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ InterpolatedSymbolNode (location: (1,7)-(1,13))
+ │ │ ├── opening_loc: ∅
+ │ │ ├── parts: (length: 1)
+ │ │ │ └── @ EmbeddedStatementsNode (location: (1,7)-(1,13))
+ │ │ │ ├── opening_loc: (1,7)-(1,9) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,9)-(1,12))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,9)-(1,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (1,9)-(1,12) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (1,12)-(1,13) = "}"
+ │ │ └── closing_loc: ∅
+ │ ├── opening_loc: (1,0)-(1,3) = "%I["
+ │ └── closing_loc: (1,13)-(1,14) = "]"
+ └── @ ArrayNode (location: (3,0)-(3,13))
+ ├── flags: ∅
+ ├── elements: (length: 1)
+ │ └── @ InterpolatedSymbolNode (location: (3,3)-(3,12))
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (3,3)-(3,6))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,3)-(3,6) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ EmbeddedStatementsNode (location: (3,6)-(3,12))
+ │ │ ├── opening_loc: (3,6)-(3,8) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,8)-(3,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,8)-(3,11))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (3,8)-(3,11) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (3,11)-(3,12) = "}"
+ │ └── closing_loc: ∅
+ ├── opening_loc: (3,0)-(3,3) = "%I["
+ └── closing_loc: (3,12)-(3,13) = "]"
diff --git a/test/prism/snapshots/whitequark/array_words.txt b/test/prism/snapshots/whitequark/array_words.txt
new file mode 100644
index 0000000000..84121de355
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_words.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ ArrayNode (location: (1,0)-(1,11))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ StringNode (location: (1,3)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,3)-(1,6) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── @ StringNode (location: (1,7)-(1,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,7)-(1,10) = "bar"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "bar"
+ ├── opening_loc: (1,0)-(1,3) = "%w["
+ └── closing_loc: (1,10)-(1,11) = "]"
diff --git a/test/prism/snapshots/whitequark/array_words_empty.txt b/test/prism/snapshots/whitequark/array_words_empty.txt
new file mode 100644
index 0000000000..e4dba94cdf
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_words_empty.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(3,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,4))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(1,4))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 0)
+ │ ├── opening_loc: (1,0)-(1,3) = "%W("
+ │ └── closing_loc: (1,3)-(1,4) = ")"
+ └── @ ArrayNode (location: (3,0)-(3,4))
+ ├── flags: ∅
+ ├── elements: (length: 0)
+ ├── opening_loc: (3,0)-(3,3) = "%w["
+ └── closing_loc: (3,3)-(3,4) = "]"
diff --git a/test/prism/snapshots/whitequark/array_words_interp.txt b/test/prism/snapshots/whitequark/array_words_interp.txt
new file mode 100644
index 0000000000..c3ae9a0cf8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/array_words_interp.txt
@@ -0,0 +1,80 @@
+@ ProgramNode (location: (1,0)-(3,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,22))
+ └── body: (length: 2)
+ ├── @ ArrayNode (location: (1,0)-(1,14))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ StringNode (location: (1,3)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (1,3)-(1,6) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ InterpolatedStringNode (location: (1,7)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── parts: (length: 1)
+ │ │ │ └── @ EmbeddedStatementsNode (location: (1,7)-(1,13))
+ │ │ │ ├── opening_loc: (1,7)-(1,9) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,9)-(1,12))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,9)-(1,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (1,9)-(1,12) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (1,12)-(1,13) = "}"
+ │ │ └── closing_loc: ∅
+ │ ├── opening_loc: (1,0)-(1,3) = "%W["
+ │ └── closing_loc: (1,13)-(1,14) = "]"
+ └── @ ArrayNode (location: (3,0)-(3,22))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ StringNode (location: (3,3)-(3,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (3,3)-(3,6) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── @ InterpolatedStringNode (location: (3,7)-(3,21))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 3)
+ │ │ ├── @ EmbeddedStatementsNode (location: (3,7)-(3,13))
+ │ │ │ ├── opening_loc: (3,7)-(3,9) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (3,9)-(3,12))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (3,9)-(3,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (3,9)-(3,12) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (3,12)-(3,13) = "}"
+ │ │ ├── @ StringNode (location: (3,13)-(3,16))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,13)-(3,16) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ EmbeddedVariableNode (location: (3,16)-(3,21))
+ │ │ ├── operator_loc: (3,16)-(3,17) = "#"
+ │ │ └── variable:
+ │ │ @ InstanceVariableReadNode (location: (3,17)-(3,21))
+ │ │ └── name: :@baz
+ │ └── closing_loc: ∅
+ ├── opening_loc: (3,0)-(3,3) = "%W["
+ └── closing_loc: (3,21)-(3,22) = "]"
diff --git a/test/prism/snapshots/whitequark/asgn_cmd.txt b/test/prism/snapshots/whitequark/asgn_cmd.txt
new file mode 100644
index 0000000000..4a3c36680b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/asgn_cmd.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(3,11))
+├── locals: [:foo, :bar]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,11))
+ └── body: (length: 2)
+ ├── @ LocalVariableWriteNode (location: (1,0)-(1,17))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (1,0)-(1,3) = "foo"
+ │ ├── value:
+ │ │ @ LocalVariableWriteNode (location: (1,6)-(1,17))
+ │ │ ├── name: :bar
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (1,6)-(1,9) = "bar"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (1,12)-(1,17))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :m
+ │ │ │ ├── message_loc: (1,12)-(1,13) = "m"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,14)-(1,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (1,14)-(1,17))
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (1,10)-(1,11) = "="
+ │ └── operator_loc: (1,4)-(1,5) = "="
+ └── @ LocalVariableWriteNode (location: (3,0)-(3,11))
+ ├── name: :foo
+ ├── depth: 0
+ ├── name_loc: (3,0)-(3,3) = "foo"
+ ├── value:
+ │ @ CallNode (location: (3,6)-(3,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (3,6)-(3,7) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,8)-(3,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (3,8)-(3,11))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (3,4)-(3,5) = "="
diff --git a/test/prism/snapshots/whitequark/asgn_mrhs.txt b/test/prism/snapshots/whitequark/asgn_mrhs.txt
new file mode 100644
index 0000000000..41d5bdc5bf
--- /dev/null
+++ b/test/prism/snapshots/whitequark/asgn_mrhs.txt
@@ -0,0 +1,87 @@
+@ ProgramNode (location: (1,0)-(5,15))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,15))
+ └── body: (length: 3)
+ ├── @ LocalVariableWriteNode (location: (1,0)-(1,10))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (1,0)-(1,3) = "foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (1,6)-(1,10))
+ │ │ ├── flags: contains_splat
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ SplatNode (location: (1,6)-(1,10))
+ │ │ │ ├── operator_loc: (1,6)-(1,7) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (1,7)-(1,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,7)-(1,10) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (1,4)-(1,5) = "="
+ ├── @ LocalVariableWriteNode (location: (3,0)-(3,12))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (3,0)-(3,3) = "foo"
+ │ ├── value:
+ │ │ @ ArrayNode (location: (3,6)-(3,12))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ CallNode (location: (3,6)-(3,9))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (3,6)-(3,9) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── @ IntegerNode (location: (3,11)-(3,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (3,4)-(3,5) = "="
+ └── @ LocalVariableWriteNode (location: (5,0)-(5,15))
+ ├── name: :foo
+ ├── depth: 0
+ ├── name_loc: (5,0)-(5,3) = "foo"
+ ├── value:
+ │ @ ArrayNode (location: (5,6)-(5,15))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 2)
+ │ │ ├── @ CallNode (location: (5,6)-(5,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (5,6)-(5,9) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ SplatNode (location: (5,11)-(5,15))
+ │ │ ├── operator_loc: (5,11)-(5,12) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (5,12)-(5,15))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (5,12)-(5,15) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ └── operator_loc: (5,4)-(5,5) = "="
diff --git a/test/prism/snapshots/whitequark/back_ref.txt b/test/prism/snapshots/whitequark/back_ref.txt
new file mode 100644
index 0000000000..ea6b76faf7
--- /dev/null
+++ b/test/prism/snapshots/whitequark/back_ref.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(1,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,2))
+ └── body: (length: 1)
+ └── @ BackReferenceReadNode (location: (1,0)-(1,2))
+ └── name: :$+
diff --git a/test/prism/snapshots/whitequark/bang.txt b/test/prism/snapshots/whitequark/bang.txt
new file mode 100644
index 0000000000..997a8718c5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bang.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,1)-(1,4))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,1)-(1,4) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,1) = "!"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/bang_cmd.txt b/test/prism/snapshots/whitequark/bang_cmd.txt
new file mode 100644
index 0000000000..e487da5e57
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bang_cmd.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,1)-(1,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,1)-(1,2) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,3)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,3)-(1,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,3)-(1,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,1) = "!"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/begin_cmdarg.txt b/test/prism/snapshots/whitequark/begin_cmdarg.txt
new file mode 100644
index 0000000000..b0c03c1754
--- /dev/null
+++ b/test/prism/snapshots/whitequark/begin_cmdarg.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(1,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,28))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,28))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,28))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ BeginNode (location: (1,2)-(1,28))
+ │ ├── begin_keyword_loc: (1,2)-(1,7) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,8)-(1,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,8)-(1,24))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── call_operator_loc: (1,9)-(1,10) = "."
+ │ │ ├── name: :times
+ │ │ ├── message_loc: (1,10)-(1,15) = "times"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,16)-(1,24))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,19)-(1,20))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,19)-(1,20))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (1,16)-(1,18) = "do"
+ │ │ └── closing_loc: (1,21)-(1,24) = "end"
+ │ ├── rescue_clause: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (1,25)-(1,28) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/beginless_erange_after_newline.txt b/test/prism/snapshots/whitequark/beginless_erange_after_newline.txt
new file mode 100644
index 0000000000..69db24a127
--- /dev/null
+++ b/test/prism/snapshots/whitequark/beginless_erange_after_newline.txt
@@ -0,0 +1,23 @@
+@ ProgramNode (location: (1,0)-(2,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,6))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ RangeNode (location: (2,0)-(2,6))
+ ├── flags: exclude_end
+ ├── left: ∅
+ ├── right:
+ │ @ IntegerNode (location: (2,3)-(2,6))
+ │ ├── flags: decimal
+ │ └── value: 100
+ └── operator_loc: (2,0)-(2,3) = "..."
diff --git a/test/prism/snapshots/whitequark/beginless_irange_after_newline.txt b/test/prism/snapshots/whitequark/beginless_irange_after_newline.txt
new file mode 100644
index 0000000000..cbc11c83c1
--- /dev/null
+++ b/test/prism/snapshots/whitequark/beginless_irange_after_newline.txt
@@ -0,0 +1,23 @@
+@ ProgramNode (location: (1,0)-(2,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,5))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ RangeNode (location: (2,0)-(2,5))
+ ├── flags: ∅
+ ├── left: ∅
+ ├── right:
+ │ @ IntegerNode (location: (2,2)-(2,5))
+ │ ├── flags: decimal
+ │ └── value: 100
+ └── operator_loc: (2,0)-(2,2) = ".."
diff --git a/test/prism/snapshots/whitequark/beginless_range.txt b/test/prism/snapshots/whitequark/beginless_range.txt
new file mode 100644
index 0000000000..59e6f135ad
--- /dev/null
+++ b/test/prism/snapshots/whitequark/beginless_range.txt
@@ -0,0 +1,21 @@
+@ ProgramNode (location: (1,0)-(3,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,5))
+ └── body: (length: 2)
+ ├── @ RangeNode (location: (1,0)-(1,6))
+ │ ├── flags: exclude_end
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ IntegerNode (location: (1,3)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 100
+ │ └── operator_loc: (1,0)-(1,3) = "..."
+ └── @ RangeNode (location: (3,0)-(3,5))
+ ├── flags: ∅
+ ├── left: ∅
+ ├── right:
+ │ @ IntegerNode (location: (3,2)-(3,5))
+ │ ├── flags: decimal
+ │ └── value: 100
+ └── operator_loc: (3,0)-(3,2) = ".."
diff --git a/test/prism/snapshots/whitequark/blockarg.txt b/test/prism/snapshots/whitequark/blockarg.txt
new file mode 100644
index 0000000000..70b054e073
--- /dev/null
+++ b/test/prism/snapshots/whitequark/blockarg.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,18))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,12))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block:
+ │ @ BlockParameterNode (location: (1,6)-(1,12))
+ │ ├── flags: ∅
+ │ ├── name: :block
+ │ ├── name_loc: (1,7)-(1,12) = "block"
+ │ └── operator_loc: (1,6)-(1,7) = "&"
+ ├── body: ∅
+ ├── locals: [:block]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,12)-(1,13) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,15)-(1,18) = "end"
diff --git a/test/prism/snapshots/whitequark/blockargs.txt b/test/prism/snapshots/whitequark/blockargs.txt
new file mode 100644
index 0000000000..149c3765c9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/blockargs.txt
@@ -0,0 +1,1339 @@
+@ ProgramNode (location: (1,0)-(71,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(71,7))
+ └── body: (length: 35)
+ ├── @ CallNode (location: (1,0)-(1,5))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (1,0)-(1,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,1)-(1,5))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,1)-(1,2) = "{"
+ │ └── closing_loc: (1,4)-(1,5) = "}"
+ ├── @ CallNode (location: (3,0)-(3,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (3,0)-(3,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,1)-(3,8))
+ │ ├── locals: []
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (3,3)-(3,6))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (3,3)-(3,4) = "|"
+ │ │ └── closing_loc: (3,5)-(3,6) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (3,1)-(3,2) = "{"
+ │ └── closing_loc: (3,7)-(3,8) = "}"
+ ├── @ CallNode (location: (5,0)-(5,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (5,0)-(5,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,1)-(5,9))
+ │ ├── locals: [:b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (5,3)-(5,7))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (5,4)-(5,6))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (5,4)-(5,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (5,5)-(5,6) = "b"
+ │ │ │ └── operator_loc: (5,4)-(5,5) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (5,3)-(5,4) = "|"
+ │ │ └── closing_loc: (5,6)-(5,7) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (5,1)-(5,2) = "{"
+ │ └── closing_loc: (5,8)-(5,9) = "}"
+ ├── @ CallNode (location: (7,0)-(7,16))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (7,0)-(7,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (7,1)-(7,16))
+ │ ├── locals: [:baz, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (7,3)-(7,14))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (7,4)-(7,13))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest:
+ │ │ │ │ @ KeywordRestParameterNode (location: (7,4)-(7,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── name_loc: (7,6)-(7,9) = "baz"
+ │ │ │ │ └── operator_loc: (7,4)-(7,6) = "**"
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (7,11)-(7,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (7,12)-(7,13) = "b"
+ │ │ │ └── operator_loc: (7,11)-(7,12) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (7,3)-(7,4) = "|"
+ │ │ └── closing_loc: (7,13)-(7,14) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (7,1)-(7,2) = "{"
+ │ └── closing_loc: (7,15)-(7,16) = "}"
+ ├── @ CallNode (location: (9,0)-(9,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (9,0)-(9,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (9,1)-(9,12))
+ │ ├── locals: [:b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (9,3)-(9,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (9,4)-(9,9))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (9,4)-(9,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: ∅
+ │ │ │ │ ├── name_loc: ∅
+ │ │ │ │ └── operator_loc: (9,4)-(9,5) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (9,7)-(9,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (9,8)-(9,9) = "b"
+ │ │ │ └── operator_loc: (9,7)-(9,8) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (9,3)-(9,4) = "|"
+ │ │ └── closing_loc: (9,9)-(9,10) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (9,1)-(9,2) = "{"
+ │ └── closing_loc: (9,11)-(9,12) = "}"
+ ├── @ CallNode (location: (11,0)-(11,16))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (11,0)-(11,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (11,1)-(11,16))
+ │ ├── locals: [:r, :p, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (11,3)-(11,14))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (11,4)-(11,13))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (11,4)-(11,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :r
+ │ │ │ │ ├── name_loc: (11,5)-(11,6) = "r"
+ │ │ │ │ └── operator_loc: (11,4)-(11,5) = "*"
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (11,8)-(11,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (11,11)-(11,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (11,12)-(11,13) = "b"
+ │ │ │ └── operator_loc: (11,11)-(11,12) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (11,3)-(11,4) = "|"
+ │ │ └── closing_loc: (11,13)-(11,14) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (11,1)-(11,2) = "{"
+ │ └── closing_loc: (11,15)-(11,16) = "}"
+ ├── @ CallNode (location: (13,0)-(13,13))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (13,0)-(13,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (13,1)-(13,13))
+ │ ├── locals: [:s, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (13,3)-(13,11))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (13,4)-(13,10))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (13,4)-(13,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :s
+ │ │ │ │ ├── name_loc: (13,5)-(13,6) = "s"
+ │ │ │ │ └── operator_loc: (13,4)-(13,5) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (13,8)-(13,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (13,9)-(13,10) = "b"
+ │ │ │ └── operator_loc: (13,8)-(13,9) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (13,3)-(13,4) = "|"
+ │ │ └── closing_loc: (13,10)-(13,11) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (13,1)-(13,2) = "{"
+ │ └── closing_loc: (13,12)-(13,13) = "}"
+ ├── @ CallNode (location: (15,0)-(15,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (15,0)-(15,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (15,1)-(15,9))
+ │ ├── locals: [:s]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (15,3)-(15,7))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (15,4)-(15,6))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (15,4)-(15,6))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :s
+ │ │ │ │ ├── name_loc: (15,5)-(15,6) = "s"
+ │ │ │ │ └── operator_loc: (15,4)-(15,5) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (15,3)-(15,4) = "|"
+ │ │ └── closing_loc: (15,6)-(15,7) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (15,1)-(15,2) = "{"
+ │ └── closing_loc: (15,8)-(15,9) = "}"
+ ├── @ CallNode (location: (17,0)-(17,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (17,0)-(17,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (17,1)-(17,8))
+ │ ├── locals: []
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (17,3)-(17,6))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (17,4)-(17,5))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (17,4)-(17,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: ∅
+ │ │ │ │ ├── name_loc: ∅
+ │ │ │ │ └── operator_loc: (17,4)-(17,5) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (17,3)-(17,4) = "|"
+ │ │ └── closing_loc: (17,5)-(17,6) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (17,1)-(17,2) = "{"
+ │ └── closing_loc: (17,7)-(17,8) = "}"
+ ├── @ CallNode (location: (19,0)-(21,3))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (19,0)-(19,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (19,1)-(21,3))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (19,3)-(21,1))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 1)
+ │ │ │ └── @ BlockLocalVariableNode (location: (20,0)-(20,1))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── opening_loc: (19,3)-(19,4) = "|"
+ │ │ └── closing_loc: (21,0)-(21,1) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (19,1)-(19,2) = "{"
+ │ └── closing_loc: (21,2)-(21,3) = "}"
+ ├── @ CallNode (location: (23,0)-(23,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (23,0)-(23,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (23,1)-(23,9))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (23,3)-(23,7))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 1)
+ │ │ │ └── @ BlockLocalVariableNode (location: (23,5)-(23,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── opening_loc: (23,3)-(23,4) = "|"
+ │ │ └── closing_loc: (23,6)-(23,7) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (23,1)-(23,2) = "{"
+ │ └── closing_loc: (23,8)-(23,9) = "}"
+ ├── @ CallNode (location: (25,0)-(25,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (25,0)-(25,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (25,1)-(25,12))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (25,3)-(25,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (25,4)-(25,9))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (25,4)-(25,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (25,7)-(25,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (25,8)-(25,9) = "b"
+ │ │ │ └── operator_loc: (25,7)-(25,8) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (25,3)-(25,4) = "|"
+ │ │ └── closing_loc: (25,9)-(25,10) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (25,1)-(25,2) = "{"
+ │ └── closing_loc: (25,11)-(25,12) = "}"
+ ├── @ CallNode (location: (27,0)-(27,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (27,0)-(27,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (27,1)-(27,15))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (27,3)-(27,13))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (27,4)-(27,12))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (27,4)-(27,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (27,7)-(27,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: ∅
+ │ │ │ │ ├── name_loc: ∅
+ │ │ │ │ └── operator_loc: (27,7)-(27,8) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (27,10)-(27,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (27,11)-(27,12) = "b"
+ │ │ │ └── operator_loc: (27,10)-(27,11) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (27,3)-(27,4) = "|"
+ │ │ └── closing_loc: (27,12)-(27,13) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (27,1)-(27,2) = "{"
+ │ └── closing_loc: (27,14)-(27,15) = "}"
+ ├── @ CallNode (location: (29,0)-(29,19))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (29,0)-(29,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (29,1)-(29,19))
+ │ ├── locals: [:a, :r, :p, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (29,3)-(29,17))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (29,4)-(29,16))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (29,4)-(29,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (29,7)-(29,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :r
+ │ │ │ │ ├── name_loc: (29,8)-(29,9) = "r"
+ │ │ │ │ └── operator_loc: (29,7)-(29,8) = "*"
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (29,11)-(29,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (29,14)-(29,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (29,15)-(29,16) = "b"
+ │ │ │ └── operator_loc: (29,14)-(29,15) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (29,3)-(29,4) = "|"
+ │ │ └── closing_loc: (29,16)-(29,17) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (29,1)-(29,2) = "{"
+ │ └── closing_loc: (29,18)-(29,19) = "}"
+ ├── @ CallNode (location: (31,0)-(31,16))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (31,0)-(31,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (31,1)-(31,16))
+ │ ├── locals: [:a, :s, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (31,3)-(31,14))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (31,4)-(31,13))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (31,4)-(31,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (31,7)-(31,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :s
+ │ │ │ │ ├── name_loc: (31,8)-(31,9) = "s"
+ │ │ │ │ └── operator_loc: (31,7)-(31,8) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (31,11)-(31,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (31,12)-(31,13) = "b"
+ │ │ │ └── operator_loc: (31,11)-(31,12) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (31,3)-(31,4) = "|"
+ │ │ └── closing_loc: (31,13)-(31,14) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (31,1)-(31,2) = "{"
+ │ └── closing_loc: (31,15)-(31,16) = "}"
+ ├── @ CallNode (location: (33,0)-(33,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (33,0)-(33,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (33,1)-(33,12))
+ │ ├── locals: [:a, :s]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (33,3)-(33,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (33,4)-(33,9))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (33,4)-(33,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (33,7)-(33,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :s
+ │ │ │ │ ├── name_loc: (33,8)-(33,9) = "s"
+ │ │ │ │ └── operator_loc: (33,7)-(33,8) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (33,3)-(33,4) = "|"
+ │ │ └── closing_loc: (33,9)-(33,10) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (33,1)-(33,2) = "{"
+ │ └── closing_loc: (33,11)-(33,12) = "}"
+ ├── @ CallNode (location: (35,0)-(35,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (35,0)-(35,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (35,1)-(35,11))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (35,3)-(35,9))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (35,4)-(35,8))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (35,4)-(35,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (35,7)-(35,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: ∅
+ │ │ │ │ ├── name_loc: ∅
+ │ │ │ │ └── operator_loc: (35,7)-(35,8) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (35,3)-(35,4) = "|"
+ │ │ └── closing_loc: (35,8)-(35,9) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (35,1)-(35,2) = "{"
+ │ └── closing_loc: (35,10)-(35,11) = "}"
+ ├── @ CallNode (location: (37,0)-(37,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (37,0)-(37,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (37,1)-(37,12))
+ │ ├── locals: [:a, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (37,3)-(37,10))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (37,4)-(37,9))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (37,4)-(37,5))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (37,7)-(37,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :b
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ ImplicitRestNode (location: (37,8)-(37,9))
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (37,3)-(37,4) = "|"
+ │ │ └── closing_loc: (37,9)-(37,10) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (37,1)-(37,2) = "{"
+ │ └── closing_loc: (37,11)-(37,12) = "}"
+ ├── @ CallNode (location: (39,0)-(39,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (39,0)-(39,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (39,1)-(39,11))
+ │ ├── locals: [:a, :c]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (39,3)-(39,9))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (39,4)-(39,8))
+ │ │ │ ├── requireds: (length: 2)
+ │ │ │ │ ├── @ RequiredParameterNode (location: (39,4)-(39,5))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :a
+ │ │ │ │ └── @ RequiredParameterNode (location: (39,7)-(39,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :c
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (39,3)-(39,4) = "|"
+ │ │ └── closing_loc: (39,8)-(39,9) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (39,1)-(39,2) = "{"
+ │ └── closing_loc: (39,10)-(39,11) = "}"
+ ├── @ CallNode (location: (41,0)-(41,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (41,0)-(41,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (41,1)-(41,17))
+ │ ├── locals: [:a, :o, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (41,3)-(41,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (41,4)-(41,14))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (41,4)-(41,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (41,7)-(41,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :o
+ │ │ │ │ ├── name_loc: (41,7)-(41,8) = "o"
+ │ │ │ │ ├── operator_loc: (41,8)-(41,9) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (41,9)-(41,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (41,12)-(41,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (41,13)-(41,14) = "b"
+ │ │ │ └── operator_loc: (41,12)-(41,13) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (41,3)-(41,4) = "|"
+ │ │ └── closing_loc: (41,14)-(41,15) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (41,1)-(41,2) = "{"
+ │ └── closing_loc: (41,16)-(41,17) = "}"
+ ├── @ CallNode (location: (43,0)-(43,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (43,0)-(43,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (43,1)-(43,24))
+ │ ├── locals: [:a, :o, :r, :p, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (43,3)-(43,22))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (43,4)-(43,21))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (43,4)-(43,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (43,7)-(43,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :o
+ │ │ │ │ ├── name_loc: (43,7)-(43,8) = "o"
+ │ │ │ │ ├── operator_loc: (43,8)-(43,9) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (43,9)-(43,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (43,12)-(43,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :r
+ │ │ │ │ ├── name_loc: (43,13)-(43,14) = "r"
+ │ │ │ │ └── operator_loc: (43,12)-(43,13) = "*"
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (43,16)-(43,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (43,19)-(43,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (43,20)-(43,21) = "b"
+ │ │ │ └── operator_loc: (43,19)-(43,20) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (43,3)-(43,4) = "|"
+ │ │ └── closing_loc: (43,21)-(43,22) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (43,1)-(43,2) = "{"
+ │ └── closing_loc: (43,23)-(43,24) = "}"
+ ├── @ CallNode (location: (45,0)-(45,27))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (45,0)-(45,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (45,1)-(45,27))
+ │ ├── locals: [:a, :o, :o1, :r, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (45,3)-(45,25))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (45,4)-(45,24))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (45,4)-(45,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 2)
+ │ │ │ │ ├── @ OptionalParameterNode (location: (45,7)-(45,10))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── name: :o
+ │ │ │ │ │ ├── name_loc: (45,7)-(45,8) = "o"
+ │ │ │ │ │ ├── operator_loc: (45,8)-(45,9) = "="
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ IntegerNode (location: (45,9)-(45,10))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── @ OptionalParameterNode (location: (45,12)-(45,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :o1
+ │ │ │ │ ├── name_loc: (45,12)-(45,14) = "o1"
+ │ │ │ │ ├── operator_loc: (45,14)-(45,15) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (45,15)-(45,16))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (45,18)-(45,20))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :r
+ │ │ │ │ ├── name_loc: (45,19)-(45,20) = "r"
+ │ │ │ │ └── operator_loc: (45,18)-(45,19) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (45,22)-(45,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (45,23)-(45,24) = "b"
+ │ │ │ └── operator_loc: (45,22)-(45,23) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (45,3)-(45,4) = "|"
+ │ │ └── closing_loc: (45,24)-(45,25) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (45,1)-(45,2) = "{"
+ │ └── closing_loc: (45,26)-(45,27) = "}"
+ ├── @ CallNode (location: (47,0)-(47,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (47,0)-(47,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (47,1)-(47,20))
+ │ ├── locals: [:a, :o, :p, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (47,3)-(47,18))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (47,4)-(47,17))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (47,4)-(47,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (47,7)-(47,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :o
+ │ │ │ │ ├── name_loc: (47,7)-(47,8) = "o"
+ │ │ │ │ ├── operator_loc: (47,8)-(47,9) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (47,9)-(47,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (47,12)-(47,13))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (47,15)-(47,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (47,16)-(47,17) = "b"
+ │ │ │ └── operator_loc: (47,15)-(47,16) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (47,3)-(47,4) = "|"
+ │ │ └── closing_loc: (47,17)-(47,18) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (47,1)-(47,2) = "{"
+ │ └── closing_loc: (47,19)-(47,20) = "}"
+ ├── @ CallNode (location: (49,0)-(49,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (49,0)-(49,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (49,1)-(49,9))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (49,3)-(49,7))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (49,4)-(49,6))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (49,4)-(49,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ ImplicitRestNode (location: (49,5)-(49,6))
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (49,3)-(49,4) = "|"
+ │ │ └── closing_loc: (49,6)-(49,7) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (49,1)-(49,2) = "{"
+ │ └── closing_loc: (49,8)-(49,9) = "}"
+ ├── @ CallNode (location: (51,0)-(51,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (51,0)-(51,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (51,1)-(51,8))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (51,3)-(51,6))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (51,4)-(51,5))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (51,4)-(51,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (51,3)-(51,4) = "|"
+ │ │ └── closing_loc: (51,5)-(51,6) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (51,1)-(51,2) = "{"
+ │ └── closing_loc: (51,7)-(51,8) = "}"
+ ├── @ CallNode (location: (53,0)-(53,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (53,0)-(53,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (53,1)-(53,8))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (53,3)-(53,6))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (53,4)-(53,5))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (53,4)-(53,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (53,3)-(53,4) = "|"
+ │ │ └── closing_loc: (53,5)-(53,6) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (53,1)-(53,2) = "{"
+ │ └── closing_loc: (53,7)-(53,8) = "}"
+ ├── @ CallNode (location: (55,0)-(55,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (55,0)-(55,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (55,1)-(55,8))
+ │ ├── locals: [:a]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (55,3)-(55,6))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (55,4)-(55,5))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (55,4)-(55,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (55,3)-(55,4) = "|"
+ │ │ └── closing_loc: (55,5)-(55,6) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (55,1)-(55,2) = "{"
+ │ └── closing_loc: (55,7)-(55,8) = "}"
+ ├── @ CallNode (location: (57,0)-(57,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (57,0)-(57,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (57,1)-(57,17))
+ │ ├── locals: [:foo, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (57,3)-(57,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (57,4)-(57,14))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 1)
+ │ │ │ │ └── @ OptionalKeywordParameterNode (location: (57,4)-(57,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── name_loc: (57,4)-(57,8) = "foo:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (57,9)-(57,10))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (57,12)-(57,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (57,13)-(57,14) = "b"
+ │ │ │ └── operator_loc: (57,12)-(57,13) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (57,3)-(57,4) = "|"
+ │ │ └── closing_loc: (57,14)-(57,15) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (57,1)-(57,2) = "{"
+ │ └── closing_loc: (57,16)-(57,17) = "}"
+ ├── @ CallNode (location: (59,0)-(59,32))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (59,0)-(59,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (59,1)-(59,32))
+ │ ├── locals: [:foo, :bar, :baz, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (59,3)-(59,30))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (59,4)-(59,29))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 2)
+ │ │ │ │ ├── @ OptionalKeywordParameterNode (location: (59,4)-(59,10))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── name: :foo
+ │ │ │ │ │ ├── name_loc: (59,4)-(59,8) = "foo:"
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ IntegerNode (location: (59,9)-(59,10))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 1
+ │ │ │ │ └── @ OptionalKeywordParameterNode (location: (59,12)-(59,18))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── name_loc: (59,12)-(59,16) = "bar:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (59,17)-(59,18))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 2
+ │ │ │ ├── keyword_rest:
+ │ │ │ │ @ KeywordRestParameterNode (location: (59,20)-(59,25))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :baz
+ │ │ │ │ ├── name_loc: (59,22)-(59,25) = "baz"
+ │ │ │ │ └── operator_loc: (59,20)-(59,22) = "**"
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (59,27)-(59,29))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (59,28)-(59,29) = "b"
+ │ │ │ └── operator_loc: (59,27)-(59,28) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (59,3)-(59,4) = "|"
+ │ │ └── closing_loc: (59,29)-(59,30) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (59,1)-(59,2) = "{"
+ │ └── closing_loc: (59,31)-(59,32) = "}"
+ ├── @ CallNode (location: (61,0)-(61,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (61,0)-(61,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (61,1)-(61,11))
+ │ ├── locals: [:foo]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (61,3)-(61,9))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (61,4)-(61,8))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 1)
+ │ │ │ │ └── @ RequiredKeywordParameterNode (location: (61,4)-(61,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ └── name_loc: (61,4)-(61,8) = "foo:"
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (61,3)-(61,4) = "|"
+ │ │ └── closing_loc: (61,8)-(61,9) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (61,1)-(61,2) = "{"
+ │ └── closing_loc: (61,10)-(61,11) = "}"
+ ├── @ CallNode (location: (63,0)-(63,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (63,0)-(63,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (63,1)-(63,14))
+ │ ├── locals: [:o, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (63,3)-(63,12))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (63,4)-(63,11))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (63,4)-(63,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :o
+ │ │ │ │ ├── name_loc: (63,4)-(63,5) = "o"
+ │ │ │ │ ├── operator_loc: (63,5)-(63,6) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (63,6)-(63,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (63,9)-(63,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (63,10)-(63,11) = "b"
+ │ │ │ └── operator_loc: (63,9)-(63,10) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (63,3)-(63,4) = "|"
+ │ │ └── closing_loc: (63,11)-(63,12) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (63,1)-(63,2) = "{"
+ │ └── closing_loc: (63,13)-(63,14) = "}"
+ ├── @ CallNode (location: (65,0)-(65,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (65,0)-(65,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (65,1)-(65,18))
+ │ ├── locals: [:o, :r, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (65,3)-(65,16))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (65,4)-(65,15))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (65,4)-(65,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :o
+ │ │ │ │ ├── name_loc: (65,4)-(65,5) = "o"
+ │ │ │ │ ├── operator_loc: (65,5)-(65,6) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (65,6)-(65,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (65,9)-(65,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :r
+ │ │ │ │ ├── name_loc: (65,10)-(65,11) = "r"
+ │ │ │ │ └── operator_loc: (65,9)-(65,10) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (65,13)-(65,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (65,14)-(65,15) = "b"
+ │ │ │ └── operator_loc: (65,13)-(65,14) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (65,3)-(65,4) = "|"
+ │ │ └── closing_loc: (65,15)-(65,16) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (65,1)-(65,2) = "{"
+ │ └── closing_loc: (65,17)-(65,18) = "}"
+ ├── @ CallNode (location: (67,0)-(67,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (67,0)-(67,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (67,1)-(67,21))
+ │ ├── locals: [:o, :r, :p, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (67,3)-(67,19))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (67,4)-(67,18))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (67,4)-(67,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :o
+ │ │ │ │ ├── name_loc: (67,4)-(67,5) = "o"
+ │ │ │ │ ├── operator_loc: (67,5)-(67,6) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (67,6)-(67,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (67,9)-(67,11))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :r
+ │ │ │ │ ├── name_loc: (67,10)-(67,11) = "r"
+ │ │ │ │ └── operator_loc: (67,9)-(67,10) = "*"
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (67,13)-(67,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (67,16)-(67,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (67,17)-(67,18) = "b"
+ │ │ │ └── operator_loc: (67,16)-(67,17) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (67,3)-(67,4) = "|"
+ │ │ └── closing_loc: (67,18)-(67,19) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (67,1)-(67,2) = "{"
+ │ └── closing_loc: (67,20)-(67,21) = "}"
+ ├── @ CallNode (location: (69,0)-(69,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (69,0)-(69,1) = "f"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (69,1)-(69,17))
+ │ ├── locals: [:o, :p, :b]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (69,3)-(69,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (69,4)-(69,14))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ └── @ OptionalParameterNode (location: (69,4)-(69,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :o
+ │ │ │ │ ├── name_loc: (69,4)-(69,5) = "o"
+ │ │ │ │ ├── operator_loc: (69,5)-(69,6) = "="
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (69,6)-(69,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (69,9)-(69,10))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :p
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockParameterNode (location: (69,12)-(69,14))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (69,13)-(69,14) = "b"
+ │ │ │ └── operator_loc: (69,12)-(69,13) = "&"
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (69,3)-(69,4) = "|"
+ │ │ └── closing_loc: (69,14)-(69,15) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (69,1)-(69,2) = "{"
+ │ └── closing_loc: (69,16)-(69,17) = "}"
+ └── @ CallNode (location: (71,0)-(71,7))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (71,0)-(71,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (71,1)-(71,7))
+ ├── locals: []
+ ├── parameters:
+ │ @ BlockParametersNode (location: (71,3)-(71,5))
+ │ ├── parameters: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (71,3)-(71,4) = "|"
+ │ └── closing_loc: (71,4)-(71,5) = "|"
+ ├── body: ∅
+ ├── opening_loc: (71,1)-(71,2) = "{"
+ └── closing_loc: (71,6)-(71,7) = "}"
diff --git a/test/prism/snapshots/whitequark/bug_435.txt b/test/prism/snapshots/whitequark/bug_435.txt
new file mode 100644
index 0000000000..42f9a49c5c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_435.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 1)
+ │ └── @ EmbeddedStatementsNode (location: (1,1)-(1,13))
+ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,3)-(1,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LambdaNode (location: (1,3)-(1,12))
+ │ │ ├── locals: [:foo]
+ │ │ ├── operator_loc: (1,3)-(1,5) = "->"
+ │ │ ├── opening_loc: (1,10)-(1,11) = "{"
+ │ │ ├── closing_loc: (1,11)-(1,12) = "}"
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (1,6)-(1,9))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (1,6)-(1,9))
+ │ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,9))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :foo
+ │ │ │ │ ├── optionals: (length: 0)
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ └── closing_loc: ∅
+ │ │ └── body: ∅
+ │ └── closing_loc: (1,12)-(1,13) = "}"
+ └── closing_loc: (1,13)-(1,14) = "\""
diff --git a/test/prism/snapshots/whitequark/bug_447.txt b/test/prism/snapshots/whitequark/bug_447.txt
new file mode 100644
index 0000000000..7291d01175
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_447.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(3,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,14))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,0)-(1,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,4))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ArrayNode (location: (1,2)-(1,4))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 0)
+ │ │ ├── opening_loc: (1,2)-(1,3) = "["
+ │ │ └── closing_loc: (1,3)-(1,4) = "]"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,5)-(1,11))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,5)-(1,7) = "do"
+ │ └── closing_loc: (1,8)-(1,11) = "end"
+ └── @ CallNode (location: (3,0)-(3,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (3,0)-(3,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,2)-(3,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ ArrayNode (location: (3,2)-(3,4))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 0)
+ │ │ ├── opening_loc: (3,2)-(3,3) = "["
+ │ │ └── closing_loc: (3,3)-(3,4) = "]"
+ │ └── @ IntegerNode (location: (3,6)-(3,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (3,8)-(3,14))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (3,8)-(3,10) = "do"
+ └── closing_loc: (3,11)-(3,14) = "end"
diff --git a/test/prism/snapshots/whitequark/bug_452.txt b/test/prism/snapshots/whitequark/bug_452.txt
new file mode 100644
index 0000000000..e1ea52fbd1
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_452.txt
@@ -0,0 +1,63 @@
+@ ProgramNode (location: (1,0)-(1,37))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,37))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :td
+ │ ├── message_loc: (1,0)-(1,2) = "td"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,3)-(1,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,3)-(1,21))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ ParenthesesNode (location: (1,3)-(1,10))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (1,4)-(1,9))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (1,4)-(1,9))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1500
+ │ │ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ │ │ └── closing_loc: (1,9)-(1,10) = ")"
+ │ │ ├── call_operator_loc: (1,10)-(1,11) = "."
+ │ │ ├── name: :toString
+ │ │ ├── message_loc: (1,11)-(1,19) = "toString"
+ │ │ ├── opening_loc: (1,19)-(1,20) = "("
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: (1,20)-(1,21) = ")"
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (1,23)-(1,37))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,23)-(1,25))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :td
+ │ ├── message_loc: (1,23)-(1,25) = "td"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,25)-(1,26) = "."
+ ├── name: :num
+ ├── message_loc: (1,26)-(1,29) = "num"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,30)-(1,37))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,30)-(1,32) = "do"
+ └── closing_loc: (1,34)-(1,37) = "end"
diff --git a/test/prism/snapshots/whitequark/bug_466.txt b/test/prism/snapshots/whitequark/bug_466.txt
new file mode 100644
index 0000000000..4167c223f2
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_466.txt
@@ -0,0 +1,70 @@
+@ ProgramNode (location: (1,0)-(1,27))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,27))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,27))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (1,0)-(1,3) = "foo"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,19))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (1,4)-(1,19))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,4)-(1,5) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (1,5)-(1,18))
+ │ │ ├── opening_loc: (1,5)-(1,7) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,7)-(1,17))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,7)-(1,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ ParenthesesNode (location: (1,7)-(1,12))
+ │ │ │ │ ├── body:
+ │ │ │ │ │ @ StatementsNode (location: (1,8)-(1,11))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (1,8)-(1,11))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── receiver:
+ │ │ │ │ │ │ @ IntegerNode (location: (1,8)-(1,9))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 1
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :+
+ │ │ │ │ │ ├── message_loc: (1,9)-(1,10) = "+"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments:
+ │ │ │ │ │ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ │ └── value: 1
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── opening_loc: (1,7)-(1,8) = "("
+ │ │ │ │ └── closing_loc: (1,11)-(1,12) = ")"
+ │ │ │ ├── call_operator_loc: (1,12)-(1,13) = "."
+ │ │ │ ├── name: :to_i
+ │ │ │ ├── message_loc: (1,13)-(1,17) = "to_i"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,17)-(1,18) = "}"
+ │ └── closing_loc: (1,18)-(1,19) = "\""
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,20)-(1,27))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,20)-(1,22) = "do"
+ └── closing_loc: (1,24)-(1,27) = "end"
diff --git a/test/prism/snapshots/whitequark/bug_473.txt b/test/prism/snapshots/whitequark/bug_473.txt
new file mode 100644
index 0000000000..028b6a517c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_473.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (1,0)-(1,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (1,2)-(1,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (1,3)-(1,8))
+ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,5)-(1,7))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ ArrayNode (location: (1,5)-(1,7))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── elements: (length: 0)
+ │ │ │ ├── opening_loc: (1,5)-(1,6) = "["
+ │ │ │ └── closing_loc: (1,6)-(1,7) = "]"
+ │ │ └── closing_loc: (1,7)-(1,8) = "}"
+ │ └── closing_loc: (1,8)-(1,9) = "\""
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/bug_480.txt b/test/prism/snapshots/whitequark/bug_480.txt
new file mode 100644
index 0000000000..ed6ba40795
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_480.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (1,0)-(1,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,12))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (1,2)-(1,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (1,3)-(1,6))
+ │ │ │ ├── opening_loc: (1,3)-(1,5) = "\#{"
+ │ │ │ ├── statements: ∅
+ │ │ │ └── closing_loc: (1,5)-(1,6) = "}"
+ │ │ └── @ EmbeddedStatementsNode (location: (1,6)-(1,11))
+ │ │ ├── opening_loc: (1,6)-(1,8) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,8)-(1,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ ParenthesesNode (location: (1,8)-(1,10))
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (1,8)-(1,9) = "("
+ │ │ │ └── closing_loc: (1,9)-(1,10) = ")"
+ │ │ └── closing_loc: (1,10)-(1,11) = "}"
+ │ └── closing_loc: (1,11)-(1,12) = "\""
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/bug_481.txt b/test/prism/snapshots/whitequark/bug_481.txt
new file mode 100644
index 0000000000..0b093d483c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_481.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (1,0)-(1,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,28))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,0)-(1,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ DefNode (location: (1,2)-(1,14))
+ │ │ ├── name: :x
+ │ │ ├── name_loc: (1,6)-(1,7) = "x"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── locals: []
+ │ │ ├── def_keyword_loc: (1,2)-(1,5) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ │ ├── rparen_loc: (1,8)-(1,9) = ")"
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (1,11)-(1,14) = "end"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (1,16)-(1,28))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ IntegerNode (location: (1,16)-(1,17))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── call_operator_loc: (1,17)-(1,18) = "."
+ ├── name: :tap
+ ├── message_loc: (1,18)-(1,21) = "tap"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,22)-(1,28))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,22)-(1,24) = "do"
+ └── closing_loc: (1,25)-(1,28) = "end"
diff --git a/test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt b/test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt
new file mode 100644
index 0000000000..7aa8694f66
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (2,9)-(2,75))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (2,9)-(2,75))
+ └── body: (length: 1)
+ └── @ StringNode (location: (2,9)-(2,75))
+ ├── flags: forced_utf8_encoding
+ ├── opening_loc: (2,9)-(2,10) = "\""
+ ├── content_loc: (2,10)-(2,74) = "\\xD0\\xBF\\xD1\\x80\\xD0\\xBE\\xD0\\xB2\\xD0\\xB5\\xD1\\x80\\xD0\\xBA\\xD0\\xB0"
+ ├── closing_loc: (2,74)-(2,75) = "\""
+ └── unescaped: "проверка"
diff --git a/test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt b/test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt
new file mode 100644
index 0000000000..50c988fa1f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :desc
+ ├── message_loc: (1,0)-(1,4) = "desc"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,5)-(1,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ StringNode (location: (1,5)-(1,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,5)-(1,6) = "\""
+ │ ├── content_loc: (1,6)-(1,9) = "foo"
+ │ ├── closing_loc: (1,9)-(1,10) = "\""
+ │ └── unescaped: "foo"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,11)-(1,17))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,11)-(1,13) = "do"
+ └── closing_loc: (1,14)-(1,17) = "end"
diff --git a/test/prism/snapshots/whitequark/bug_cmdarg.txt b/test/prism/snapshots/whitequark/bug_cmdarg.txt
new file mode 100644
index 0000000000..509dd7e818
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_cmdarg.txt
@@ -0,0 +1,106 @@
+@ ProgramNode (location: (1,0)-(5,26))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,26))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :assert
+ │ ├── message_loc: (1,0)-(1,6) = "assert"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,7)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,7)-(1,15))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,7)-(1,15))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,7)-(1,10))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,7)-(1,9) = "do"
+ │ │ │ ├── closing_loc: (1,9)-(1,10) = ":"
+ │ │ │ └── unescaped: "do"
+ │ │ ├── value:
+ │ │ │ @ TrueNode (location: (1,11)-(1,15))
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,11))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :assert
+ │ ├── message_loc: (3,0)-(3,6) = "assert"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,7)-(3,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,7)-(3,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :dogs
+ │ │ ├── message_loc: (3,7)-(3,11) = "dogs"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,26))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (5,0)-(5,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (5,2)-(5,26))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (5,2)-(5,26))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (5,2)-(5,26))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (5,2)-(5,4))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (5,2)-(5,3) = "x"
+ │ │ ├── closing_loc: (5,3)-(5,4) = ":"
+ │ │ └── unescaped: "x"
+ │ ├── value:
+ │ │ @ LambdaNode (location: (5,5)-(5,26))
+ │ │ ├── locals: []
+ │ │ ├── operator_loc: (5,5)-(5,7) = "->"
+ │ │ ├── opening_loc: (5,8)-(5,10) = "do"
+ │ │ ├── closing_loc: (5,23)-(5,26) = "end"
+ │ │ ├── parameters: ∅
+ │ │ └── body:
+ │ │ @ StatementsNode (location: (5,11)-(5,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,11)-(5,22))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (5,11)-(5,15) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (5,16)-(5,22))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (5,16)-(5,18) = "do"
+ │ │ └── closing_loc: (5,19)-(5,22) = "end"
+ │ └── operator_loc: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt b/test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt
new file mode 100644
index 0000000000..1b45d0132b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(4,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(4,3))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(4,3))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (4,0)-(4,3) = "end"
diff --git a/test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt b/test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt
new file mode 100644
index 0000000000..9b95adda35
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (1,0)-(1,33))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,33))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,33))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :bar
+ ├── message_loc: (1,0)-(1,3) = "bar"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,33))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ DefNode (location: (1,4)-(1,33))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,8)-(1,11) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,13)-(1,29))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,13)-(1,29))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver:
+ │ │ │ @ SelfNode (location: (1,13)-(1,17))
+ │ │ ├── call_operator_loc: (1,17)-(1,18) = "."
+ │ │ ├── name: :each
+ │ │ ├── message_loc: (1,18)-(1,22) = "each"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,23)-(1,29))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (1,23)-(1,25) = "do"
+ │ │ └── closing_loc: (1,26)-(1,29) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,4)-(1,7) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,30)-(1,33) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt b/test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt
new file mode 100644
index 0000000000..3946bc1a4a
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,17))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :tap
+ ├── message_loc: (1,0)-(1,3) = "tap"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,17))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,4)-(1,17))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,5)-(1,16))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,5)-(1,16))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :proc
+ │ │ ├── message_loc: (1,5)-(1,9) = "proc"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,10)-(1,16))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (1,10)-(1,12) = "do"
+ │ │ └── closing_loc: (1,13)-(1,16) = "end"
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (1,16)-(1,17) = ")"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt b/test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt
new file mode 100644
index 0000000000..183d465439
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt
@@ -0,0 +1,383 @@
+@ ProgramNode (location: (1,0)-(9,52))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,52))
+ └── body: (length: 5)
+ ├── @ CallNode (location: (1,0)-(1,42))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (1,0)-(1,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,42))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (1,2)-(1,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,2)-(1,3) = ":"
+ │ │ │ ├── value_loc: (1,3)-(1,6) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ HashNode (location: (1,8)-(1,42))
+ │ │ ├── opening_loc: (1,8)-(1,9) = "{"
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ AssocNode (location: (1,9)-(1,25))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (1,9)-(1,13))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (1,9)-(1,10) = "\""
+ │ │ │ │ │ ├── value_loc: (1,10)-(1,11) = "a"
+ │ │ │ │ │ ├── closing_loc: (1,11)-(1,13) = "\":"
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (1,14)-(1,25))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :proc
+ │ │ │ │ │ ├── message_loc: (1,14)-(1,18) = "proc"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (1,19)-(1,25))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (1,19)-(1,21) = "do"
+ │ │ │ │ │ └── closing_loc: (1,22)-(1,25) = "end"
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ └── @ AssocNode (location: (1,27)-(1,41))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (1,27)-(1,29))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (1,27)-(1,28) = "b"
+ │ │ │ │ ├── closing_loc: (1,28)-(1,29) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (1,30)-(1,41))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :proc
+ │ │ │ │ ├── message_loc: (1,30)-(1,34) = "proc"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (1,35)-(1,41))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body: ∅
+ │ │ │ │ ├── opening_loc: (1,35)-(1,37) = "do"
+ │ │ │ │ └── closing_loc: (1,38)-(1,41) = "end"
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (1,41)-(1,42) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,40))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (3,0)-(3,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,2)-(3,40))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (3,2)-(3,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,2)-(3,3) = ":"
+ │ │ │ ├── value_loc: (3,3)-(3,6) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ HashNode (location: (3,8)-(3,40))
+ │ │ ├── opening_loc: (3,8)-(3,9) = "{"
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ AssocSplatNode (location: (3,9)-(3,23))
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (3,12)-(3,23))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :proc
+ │ │ │ │ │ ├── message_loc: (3,12)-(3,16) = "proc"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (3,17)-(3,23))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (3,17)-(3,19) = "do"
+ │ │ │ │ │ └── closing_loc: (3,20)-(3,23) = "end"
+ │ │ │ │ └── operator_loc: (3,9)-(3,11) = "**"
+ │ │ │ └── @ AssocNode (location: (3,25)-(3,39))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (3,25)-(3,27))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (3,25)-(3,26) = "b"
+ │ │ │ │ ├── closing_loc: (3,26)-(3,27) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (3,28)-(3,39))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :proc
+ │ │ │ │ ├── message_loc: (3,28)-(3,32) = "proc"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (3,33)-(3,39))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body: ∅
+ │ │ │ │ ├── opening_loc: (3,33)-(3,35) = "do"
+ │ │ │ │ └── closing_loc: (3,36)-(3,39) = "end"
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (3,39)-(3,40) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,43))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (5,0)-(5,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,2)-(5,43))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (5,2)-(5,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (5,2)-(5,3) = ":"
+ │ │ │ ├── value_loc: (5,3)-(5,6) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ HashNode (location: (5,8)-(5,43))
+ │ │ ├── opening_loc: (5,8)-(5,9) = "{"
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ AssocNode (location: (5,9)-(5,26))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (5,9)-(5,11))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (5,9)-(5,10) = ":"
+ │ │ │ │ │ ├── value_loc: (5,10)-(5,11) = "a"
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (5,15)-(5,26))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :proc
+ │ │ │ │ │ ├── message_loc: (5,15)-(5,19) = "proc"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (5,20)-(5,26))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (5,20)-(5,22) = "do"
+ │ │ │ │ │ └── closing_loc: (5,23)-(5,26) = "end"
+ │ │ │ │ └── operator_loc: (5,12)-(5,14) = "=>"
+ │ │ │ └── @ AssocNode (location: (5,28)-(5,42))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (5,28)-(5,30))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (5,28)-(5,29) = "b"
+ │ │ │ │ ├── closing_loc: (5,29)-(5,30) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (5,31)-(5,42))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :proc
+ │ │ │ │ ├── message_loc: (5,31)-(5,35) = "proc"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (5,36)-(5,42))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body: ∅
+ │ │ │ │ ├── opening_loc: (5,36)-(5,38) = "do"
+ │ │ │ │ └── closing_loc: (5,39)-(5,42) = "end"
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (5,42)-(5,43) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (7,0)-(7,40))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (7,0)-(7,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,2)-(7,40))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ SymbolNode (location: (7,2)-(7,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (7,2)-(7,3) = ":"
+ │ │ │ ├── value_loc: (7,3)-(7,6) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ HashNode (location: (7,8)-(7,40))
+ │ │ ├── opening_loc: (7,8)-(7,9) = "{"
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ AssocNode (location: (7,9)-(7,23))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (7,9)-(7,11))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── value_loc: (7,9)-(7,10) = "a"
+ │ │ │ │ │ ├── closing_loc: (7,10)-(7,11) = ":"
+ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ CallNode (location: (7,12)-(7,23))
+ │ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :proc
+ │ │ │ │ │ ├── message_loc: (7,12)-(7,16) = "proc"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block:
+ │ │ │ │ │ @ BlockNode (location: (7,17)-(7,23))
+ │ │ │ │ │ ├── locals: []
+ │ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ │ ├── body: ∅
+ │ │ │ │ │ ├── opening_loc: (7,17)-(7,19) = "do"
+ │ │ │ │ │ └── closing_loc: (7,20)-(7,23) = "end"
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ └── @ AssocNode (location: (7,25)-(7,39))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (7,25)-(7,27))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (7,25)-(7,26) = "b"
+ │ │ │ │ ├── closing_loc: (7,26)-(7,27) = ":"
+ │ │ │ │ └── unescaped: "b"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (7,28)-(7,39))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :proc
+ │ │ │ │ ├── message_loc: (7,28)-(7,32) = "proc"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (7,33)-(7,39))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body: ∅
+ │ │ │ │ ├── opening_loc: (7,33)-(7,35) = "do"
+ │ │ │ │ └── closing_loc: (7,36)-(7,39) = "end"
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (7,39)-(7,40) = "}"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (9,0)-(9,52))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (9,0)-(9,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (9,2)-(9,52))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ SymbolNode (location: (9,2)-(9,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (9,2)-(9,3) = ":"
+ │ │ ├── value_loc: (9,3)-(9,6) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ └── @ HashNode (location: (9,8)-(9,52))
+ │ ├── opening_loc: (9,8)-(9,9) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (9,9)-(9,35))
+ │ │ │ ├── key:
+ │ │ │ │ @ CallNode (location: (9,9)-(9,20))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :proc
+ │ │ │ │ ├── message_loc: (9,9)-(9,13) = "proc"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (9,14)-(9,20))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body: ∅
+ │ │ │ │ ├── opening_loc: (9,14)-(9,16) = "do"
+ │ │ │ │ └── closing_loc: (9,17)-(9,20) = "end"
+ │ │ │ ├── value:
+ │ │ │ │ @ CallNode (location: (9,24)-(9,35))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :proc
+ │ │ │ │ ├── message_loc: (9,24)-(9,28) = "proc"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block:
+ │ │ │ │ @ BlockNode (location: (9,29)-(9,35))
+ │ │ │ │ ├── locals: []
+ │ │ │ │ ├── parameters: ∅
+ │ │ │ │ ├── body: ∅
+ │ │ │ │ ├── opening_loc: (9,29)-(9,31) = "do"
+ │ │ │ │ └── closing_loc: (9,32)-(9,35) = "end"
+ │ │ │ └── operator_loc: (9,21)-(9,23) = "=>"
+ │ │ └── @ AssocNode (location: (9,37)-(9,51))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (9,37)-(9,39))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (9,37)-(9,38) = "b"
+ │ │ │ ├── closing_loc: (9,38)-(9,39) = ":"
+ │ │ │ └── unescaped: "b"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (9,40)-(9,51))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :proc
+ │ │ │ ├── message_loc: (9,40)-(9,44) = "proc"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (9,45)-(9,51))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (9,45)-(9,47) = "do"
+ │ │ │ └── closing_loc: (9,48)-(9,51) = "end"
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (9,51)-(9,52) = "}"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/bug_heredoc_do.txt b/test/prism/snapshots/whitequark/bug_heredoc_do.txt
new file mode 100644
index 0000000000..bf4dd645fb
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_heredoc_do.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(3,3))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ StringNode (location: (1,2)-(1,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,2)-(1,10) = "<<-TABLE"
+ │ ├── content_loc: (2,0)-(2,0) = ""
+ │ ├── closing_loc: (2,0)-(3,0) = "TABLE\n"
+ │ └── unescaped: ""
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,11)-(3,3))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,11)-(1,13) = "do"
+ └── closing_loc: (3,0)-(3,3) = "end"
diff --git a/test/prism/snapshots/whitequark/bug_interp_single.txt b/test/prism/snapshots/whitequark/bug_interp_single.txt
new file mode 100644
index 0000000000..74af8607e0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_interp_single.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(3,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,8))
+ └── body: (length: 2)
+ ├── @ InterpolatedStringNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (1,1)-(1,5))
+ │ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,3)-(1,4))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── closing_loc: (1,4)-(1,5) = "}"
+ │ └── closing_loc: (1,5)-(1,6) = "\""
+ └── @ ArrayNode (location: (3,0)-(3,8))
+ ├── flags: ∅
+ ├── elements: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (3,3)-(3,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 1)
+ │ │ └── @ EmbeddedStatementsNode (location: (3,3)-(3,7))
+ │ │ ├── opening_loc: (3,3)-(3,5) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,5)-(3,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,5)-(3,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── closing_loc: (3,6)-(3,7) = "}"
+ │ └── closing_loc: ∅
+ ├── opening_loc: (3,0)-(3,3) = "%W\""
+ └── closing_loc: (3,7)-(3,8) = "\""
diff --git a/test/prism/snapshots/whitequark/bug_lambda_leakage.txt b/test/prism/snapshots/whitequark/bug_lambda_leakage.txt
new file mode 100644
index 0000000000..7178345a22
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_lambda_leakage.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 2)
+ ├── @ LambdaNode (location: (1,0)-(1,12))
+ │ ├── locals: [:scope]
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (1,10)-(1,11) = "{"
+ │ ├── closing_loc: (1,11)-(1,12) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,2)-(1,9))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,3)-(1,8))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :scope
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ │ └── closing_loc: (1,8)-(1,9) = ")"
+ │ └── body: ∅
+ └── @ CallNode (location: (1,14)-(1,19))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :scope
+ ├── message_loc: (1,14)-(1,19) = "scope"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/bug_regex_verification.txt b/test/prism/snapshots/whitequark/bug_regex_verification.txt
new file mode 100644
index 0000000000..4464b66e38
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_regex_verification.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ RegularExpressionNode (location: (1,0)-(1,5))
+ ├── flags: extended, forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,1) = "/"
+ ├── content_loc: (1,1)-(1,3) = "#)"
+ ├── closing_loc: (1,3)-(1,5) = "/x"
+ └── unescaped: "#)"
diff --git a/test/prism/snapshots/whitequark/bug_rescue_empty_else.txt b/test/prism/snapshots/whitequark/bug_rescue_empty_else.txt
new file mode 100644
index 0000000000..52734cc1e9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_rescue_empty_else.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,34))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,34))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,34))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,7)-(1,23))
+ │ ├── keyword_loc: (1,7)-(1,13) = "rescue"
+ │ ├── exceptions: (length: 1)
+ │ │ └── @ ConstantReadNode (location: (1,14)-(1,23))
+ │ │ └── name: :LoadError
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements: ∅
+ │ └── consequent: ∅
+ ├── else_clause:
+ │ @ ElseNode (location: (1,25)-(1,34))
+ │ ├── else_keyword_loc: (1,25)-(1,29) = "else"
+ │ ├── statements: ∅
+ │ └── end_keyword_loc: (1,31)-(1,34) = "end"
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,31)-(1,34) = "end"
diff --git a/test/prism/snapshots/whitequark/bug_while_not_parens_do.txt b/test/prism/snapshots/whitequark/bug_while_not_parens_do.txt
new file mode 100644
index 0000000000..aa8aa11ccc
--- /dev/null
+++ b/test/prism/snapshots/whitequark/bug_while_not_parens_do.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ WhileNode (location: (1,0)-(1,23))
+ ├── flags: ∅
+ ├── keyword_loc: (1,0)-(1,5) = "while"
+ ├── closing_loc: (1,20)-(1,23) = "end"
+ ├── predicate:
+ │ @ CallNode (location: (1,6)-(1,16))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (1,10)-(1,16))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,11)-(1,15))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ TrueNode (location: (1,11)-(1,15))
+ │ │ ├── opening_loc: (1,10)-(1,11) = "("
+ │ │ └── closing_loc: (1,15)-(1,16) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,6)-(1,9) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements: ∅
diff --git a/test/prism/snapshots/whitequark/case_cond.txt b/test/prism/snapshots/whitequark/case_cond.txt
new file mode 100644
index 0000000000..fbe17eaf8f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/case_cond.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,26))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,26))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,26))
+ ├── predicate: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,6)-(1,21))
+ │ ├── keyword_loc: (1,6)-(1,10) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ CallNode (location: (1,11)-(1,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,11)-(1,14) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (1,16)-(1,21))
+ │ └── body: (length: 1)
+ │ └── @ StringNode (location: (1,16)-(1,21))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,16)-(1,17) = "'"
+ │ ├── content_loc: (1,17)-(1,20) = "foo"
+ │ ├── closing_loc: (1,20)-(1,21) = "'"
+ │ └── unescaped: "foo"
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,23)-(1,26) = "end"
diff --git a/test/prism/snapshots/whitequark/case_cond_else.txt b/test/prism/snapshots/whitequark/case_cond_else.txt
new file mode 100644
index 0000000000..b1aff2450e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/case_cond_else.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(1,38))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,38))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,38))
+ ├── predicate: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,6)-(1,21))
+ │ ├── keyword_loc: (1,6)-(1,10) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ CallNode (location: (1,11)-(1,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,11)-(1,14) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (1,16)-(1,21))
+ │ └── body: (length: 1)
+ │ └── @ StringNode (location: (1,16)-(1,21))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,16)-(1,17) = "'"
+ │ ├── content_loc: (1,17)-(1,20) = "foo"
+ │ ├── closing_loc: (1,20)-(1,21) = "'"
+ │ └── unescaped: "foo"
+ ├── consequent:
+ │ @ ElseNode (location: (1,23)-(1,38))
+ │ ├── else_keyword_loc: (1,23)-(1,27) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,28)-(1,33))
+ │ │ └── body: (length: 1)
+ │ │ └── @ StringNode (location: (1,28)-(1,33))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,28)-(1,29) = "'"
+ │ │ ├── content_loc: (1,29)-(1,32) = "bar"
+ │ │ ├── closing_loc: (1,32)-(1,33) = "'"
+ │ │ └── unescaped: "bar"
+ │ └── end_keyword_loc: (1,35)-(1,38) = "end"
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,35)-(1,38) = "end"
diff --git a/test/prism/snapshots/whitequark/case_expr.txt b/test/prism/snapshots/whitequark/case_expr.txt
new file mode 100644
index 0000000000..23054ed132
--- /dev/null
+++ b/test/prism/snapshots/whitequark/case_expr.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(1,30))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,30))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,30))
+ ├── predicate:
+ │ @ CallNode (location: (1,5)-(1,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,10)-(1,25))
+ │ ├── keyword_loc: (1,10)-(1,14) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ StringNode (location: (1,15)-(1,20))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (1,15)-(1,16) = "'"
+ │ │ ├── content_loc: (1,16)-(1,19) = "bar"
+ │ │ ├── closing_loc: (1,19)-(1,20) = "'"
+ │ │ └── unescaped: "bar"
+ │ ├── then_keyword_loc: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (1,22)-(1,25))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,22)-(1,25))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,22)-(1,25) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,27)-(1,30) = "end"
diff --git a/test/prism/snapshots/whitequark/case_expr_else.txt b/test/prism/snapshots/whitequark/case_expr_else.txt
new file mode 100644
index 0000000000..0624d97c84
--- /dev/null
+++ b/test/prism/snapshots/whitequark/case_expr_else.txt
@@ -0,0 +1,60 @@
+@ ProgramNode (location: (1,0)-(1,40))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,40))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,40))
+ ├── predicate:
+ │ @ CallNode (location: (1,5)-(1,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,10)-(1,25))
+ │ ├── keyword_loc: (1,10)-(1,14) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ StringNode (location: (1,15)-(1,20))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (1,15)-(1,16) = "'"
+ │ │ ├── content_loc: (1,16)-(1,19) = "bar"
+ │ │ ├── closing_loc: (1,19)-(1,20) = "'"
+ │ │ └── unescaped: "bar"
+ │ ├── then_keyword_loc: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (1,22)-(1,25))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,22)-(1,25))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,22)-(1,25) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent:
+ │ @ ElseNode (location: (1,27)-(1,40))
+ │ ├── else_keyword_loc: (1,27)-(1,31) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,32)-(1,35))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,32)-(1,35))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (1,32)-(1,35) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (1,37)-(1,40) = "end"
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,37)-(1,40) = "end"
diff --git a/test/prism/snapshots/whitequark/casgn_scoped.txt b/test/prism/snapshots/whitequark/casgn_scoped.txt
new file mode 100644
index 0000000000..4e3fd6fe44
--- /dev/null
+++ b/test/prism/snapshots/whitequark/casgn_scoped.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ ConstantPathWriteNode (location: (1,0)-(1,13))
+ ├── target:
+ │ @ ConstantPathNode (location: (1,0)-(1,8))
+ │ ├── parent:
+ │ │ @ ConstantReadNode (location: (1,0)-(1,3))
+ │ │ └── name: :Bar
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (1,5)-(1,8))
+ │ │ └── name: :Foo
+ │ └── delimiter_loc: (1,3)-(1,5) = "::"
+ ├── operator_loc: (1,9)-(1,10) = "="
+ └── value:
+ @ IntegerNode (location: (1,11)-(1,13))
+ ├── flags: decimal
+ └── value: 10
diff --git a/test/prism/snapshots/whitequark/casgn_toplevel.txt b/test/prism/snapshots/whitequark/casgn_toplevel.txt
new file mode 100644
index 0000000000..11facfefb3
--- /dev/null
+++ b/test/prism/snapshots/whitequark/casgn_toplevel.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ ConstantPathWriteNode (location: (1,0)-(1,10))
+ ├── target:
+ │ @ ConstantPathNode (location: (1,0)-(1,5))
+ │ ├── parent: ∅
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (1,2)-(1,5))
+ │ │ └── name: :Foo
+ │ └── delimiter_loc: (1,0)-(1,2) = "::"
+ ├── operator_loc: (1,6)-(1,7) = "="
+ └── value:
+ @ IntegerNode (location: (1,8)-(1,10))
+ ├── flags: decimal
+ └── value: 10
diff --git a/test/prism/snapshots/whitequark/casgn_unscoped.txt b/test/prism/snapshots/whitequark/casgn_unscoped.txt
new file mode 100644
index 0000000000..f535cafdc6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/casgn_unscoped.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ ConstantWriteNode (location: (1,0)-(1,8))
+ ├── name: :Foo
+ ├── name_loc: (1,0)-(1,3) = "Foo"
+ ├── value:
+ │ @ IntegerNode (location: (1,6)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 10
+ └── operator_loc: (1,4)-(1,5) = "="
diff --git a/test/prism/snapshots/whitequark/character.txt b/test/prism/snapshots/whitequark/character.txt
new file mode 100644
index 0000000000..b70f05b544
--- /dev/null
+++ b/test/prism/snapshots/whitequark/character.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,2))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,0)-(1,2))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "?"
+ ├── content_loc: (1,1)-(1,2) = "a"
+ ├── closing_loc: ∅
+ └── unescaped: "a"
diff --git a/test/prism/snapshots/whitequark/class.txt b/test/prism/snapshots/whitequark/class.txt
new file mode 100644
index 0000000000..e38bec6c47
--- /dev/null
+++ b/test/prism/snapshots/whitequark/class.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(3,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,14))
+ └── body: (length: 2)
+ ├── @ ClassNode (location: (1,0)-(1,13))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (1,6)-(1,9))
+ │ │ └── name: :Foo
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (1,10)-(1,13) = "end"
+ │ └── name: :Foo
+ └── @ ClassNode (location: (3,0)-(3,14))
+ ├── locals: []
+ ├── class_keyword_loc: (3,0)-(3,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (3,6)-(3,9))
+ │ └── name: :Foo
+ ├── inheritance_operator_loc: ∅
+ ├── superclass: ∅
+ ├── body: ∅
+ ├── end_keyword_loc: (3,11)-(3,14) = "end"
+ └── name: :Foo
diff --git a/test/prism/snapshots/whitequark/class_super.txt b/test/prism/snapshots/whitequark/class_super.txt
new file mode 100644
index 0000000000..ea8bbd70d9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/class_super.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ ClassNode (location: (1,0)-(1,20))
+ ├── locals: []
+ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (1,6)-(1,9))
+ │ └── name: :Foo
+ ├── inheritance_operator_loc: (1,10)-(1,11) = "<"
+ ├── superclass:
+ │ @ ConstantReadNode (location: (1,12)-(1,15))
+ │ └── name: :Bar
+ ├── body: ∅
+ ├── end_keyword_loc: (1,17)-(1,20) = "end"
+ └── name: :Foo
diff --git a/test/prism/snapshots/whitequark/class_super_label.txt b/test/prism/snapshots/whitequark/class_super_label.txt
new file mode 100644
index 0000000000..c873ea0c12
--- /dev/null
+++ b/test/prism/snapshots/whitequark/class_super_label.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ ClassNode (location: (1,0)-(1,20))
+ ├── locals: []
+ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (1,6)-(1,9))
+ │ └── name: :Foo
+ ├── inheritance_operator_loc: (1,10)-(1,11) = "<"
+ ├── superclass:
+ │ @ CallNode (location: (1,12)-(1,15))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,12)-(1,13) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,13)-(1,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,13)-(1,15))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,13)-(1,14) = ":"
+ │ │ ├── value_loc: (1,14)-(1,15) = "b"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "b"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── end_keyword_loc: (1,17)-(1,20) = "end"
+ └── name: :Foo
diff --git a/test/prism/snapshots/whitequark/comments_before_leading_dot__27.txt b/test/prism/snapshots/whitequark/comments_before_leading_dot__27.txt
new file mode 100644
index 0000000000..e33f798ef5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/comments_before_leading_dot__27.txt
@@ -0,0 +1,85 @@
+@ ProgramNode (location: (1,0)-(18,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(18,4))
+ └── body: (length: 4)
+ ├── @ CallNode (location: (1,0)-(3,5))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (3,0)-(3,2) = "&."
+ │ ├── name: :foo
+ │ ├── message_loc: (3,2)-(3,5) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (6,0)-(8,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (6,0)-(6,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (6,0)-(6,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (8,0)-(8,1) = "."
+ │ ├── name: :foo
+ │ ├── message_loc: (8,1)-(8,4) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (11,0)-(13,5))
+ │ ├── flags: safe_navigation
+ │ ├── receiver:
+ │ │ @ CallNode (location: (11,0)-(11,1))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (11,0)-(11,1) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (13,0)-(13,2) = "&."
+ │ ├── name: :foo
+ │ ├── message_loc: (13,2)-(13,5) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (16,0)-(18,4))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (16,0)-(16,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (16,0)-(16,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (18,0)-(18,1) = "."
+ ├── name: :foo
+ ├── message_loc: (18,1)-(18,4) = "foo"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/complex.txt b/test/prism/snapshots/whitequark/complex.txt
new file mode 100644
index 0000000000..e688585a5f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/complex.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(7,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,4))
+ └── body: (length: 4)
+ ├── @ ImaginaryNode (location: (1,0)-(1,5))
+ │ └── numeric:
+ │ @ FloatNode (location: (1,0)-(1,4))
+ │ └── value: 42.1
+ ├── @ ImaginaryNode (location: (3,0)-(3,6))
+ │ └── numeric:
+ │ @ RationalNode (location: (3,0)-(3,5))
+ │ └── numeric:
+ │ @ FloatNode (location: (3,0)-(3,4))
+ │ └── value: 42.1
+ ├── @ ImaginaryNode (location: (5,0)-(5,3))
+ │ └── numeric:
+ │ @ IntegerNode (location: (5,0)-(5,2))
+ │ ├── flags: decimal
+ │ └── value: 42
+ └── @ ImaginaryNode (location: (7,0)-(7,4))
+ └── numeric:
+ @ RationalNode (location: (7,0)-(7,3))
+ └── numeric:
+ @ IntegerNode (location: (7,0)-(7,2))
+ ├── flags: decimal
+ └── value: 42
diff --git a/test/prism/snapshots/whitequark/cond_begin.txt b/test/prism/snapshots/whitequark/cond_begin.txt
new file mode 100644
index 0000000000..e349c198a5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_begin.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,18))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ ParenthesesNode (location: (1,3)-(1,8))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,4)-(1,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,4)-(1,7) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ └── closing_loc: (1,7)-(1,8) = ")"
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (1,10)-(1,13))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,10)-(1,13))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,10)-(1,13) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,15)-(1,18) = "end"
diff --git a/test/prism/snapshots/whitequark/cond_begin_masgn.txt b/test/prism/snapshots/whitequark/cond_begin_masgn.txt
new file mode 100644
index 0000000000..b4e6d8682c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_begin_masgn.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,25))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ ParenthesesNode (location: (1,3)-(1,20))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,4)-(1,19))
+ │ │ └── body: (length: 2)
+ │ │ ├── @ CallNode (location: (1,4)-(1,7))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,4)-(1,7) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ MultiWriteNode (location: (1,9)-(1,19))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (1,9)-(1,10))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (1,12)-(1,13))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── operator_loc: (1,14)-(1,15) = "="
+ │ │ └── value:
+ │ │ @ CallNode (location: (1,16)-(1,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,16)-(1,19) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ └── closing_loc: (1,19)-(1,20) = ")"
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,22)-(1,25) = "end"
diff --git a/test/prism/snapshots/whitequark/cond_eflipflop.txt b/test/prism/snapshots/whitequark/cond_eflipflop.txt
new file mode 100644
index 0000000000..18fee58492
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_eflipflop.txt
@@ -0,0 +1,78 @@
+@ ProgramNode (location: (1,0)-(3,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,17))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (1,1)-(1,12))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,2)-(1,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ FlipFlopNode (location: (1,2)-(1,11))
+ │ │ │ ├── flags: exclude_end
+ │ │ │ ├── left:
+ │ │ │ │ @ CallNode (location: (1,2)-(1,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (1,2)-(1,5) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ CallNode (location: (1,8)-(1,11))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (1,8)-(1,11) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (1,5)-(1,8) = "..."
+ │ │ ├── opening_loc: (1,1)-(1,2) = "("
+ │ │ └── closing_loc: (1,11)-(1,12) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,0)-(1,1) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ IfNode (location: (3,0)-(3,17))
+ ├── if_keyword_loc: (3,0)-(3,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (3,3)-(3,12))
+ │ ├── flags: exclude_end
+ │ ├── left:
+ │ │ @ CallNode (location: (3,3)-(3,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,3)-(3,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (3,9)-(3,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,9)-(3,12) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (3,6)-(3,9) = "..."
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (3,14)-(3,17) = "end"
diff --git a/test/prism/snapshots/whitequark/cond_eflipflop_with_beginless_range.txt b/test/prism/snapshots/whitequark/cond_eflipflop_with_beginless_range.txt
new file mode 100644
index 0000000000..05972521e8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_eflipflop_with_beginless_range.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,14))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (1,3)-(1,9))
+ │ ├── flags: exclude_end
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (1,6)-(1,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,6)-(1,9) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,3)-(1,6) = "..."
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,11)-(1,14) = "end"
diff --git a/test/prism/snapshots/whitequark/cond_eflipflop_with_endless_range.txt b/test/prism/snapshots/whitequark/cond_eflipflop_with_endless_range.txt
new file mode 100644
index 0000000000..c85ff292a5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_eflipflop_with_endless_range.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,14))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (1,3)-(1,9))
+ │ ├── flags: exclude_end
+ │ ├── left:
+ │ │ @ CallNode (location: (1,3)-(1,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,3)-(1,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right: ∅
+ │ └── operator_loc: (1,6)-(1,9) = "..."
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,11)-(1,14) = "end"
diff --git a/test/prism/snapshots/whitequark/cond_iflipflop.txt b/test/prism/snapshots/whitequark/cond_iflipflop.txt
new file mode 100644
index 0000000000..f76a6636f6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_iflipflop.txt
@@ -0,0 +1,78 @@
+@ ProgramNode (location: (1,0)-(3,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,16))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (1,1)-(1,11))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,2)-(1,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ FlipFlopNode (location: (1,2)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── left:
+ │ │ │ │ @ CallNode (location: (1,2)-(1,5))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (1,2)-(1,5) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── right:
+ │ │ │ │ @ CallNode (location: (1,7)-(1,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (1,7)-(1,10) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: (1,5)-(1,7) = ".."
+ │ │ ├── opening_loc: (1,1)-(1,2) = "("
+ │ │ └── closing_loc: (1,10)-(1,11) = ")"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,0)-(1,1) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ IfNode (location: (3,0)-(3,16))
+ ├── if_keyword_loc: (3,0)-(3,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (3,3)-(3,11))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ CallNode (location: (3,3)-(3,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,3)-(3,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (3,8)-(3,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,8)-(3,11) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (3,6)-(3,8) = ".."
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (3,13)-(3,16) = "end"
diff --git a/test/prism/snapshots/whitequark/cond_iflipflop_with_beginless_range.txt b/test/prism/snapshots/whitequark/cond_iflipflop_with_beginless_range.txt
new file mode 100644
index 0000000000..63b87ffd49
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_iflipflop_with_beginless_range.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,13))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (1,3)-(1,8))
+ │ ├── flags: ∅
+ │ ├── left: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (1,5)-(1,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,5)-(1,8) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,3)-(1,5) = ".."
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,10)-(1,13) = "end"
diff --git a/test/prism/snapshots/whitequark/cond_iflipflop_with_endless_range.txt b/test/prism/snapshots/whitequark/cond_iflipflop_with_endless_range.txt
new file mode 100644
index 0000000000..328a2da153
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_iflipflop_with_endless_range.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,13))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ FlipFlopNode (location: (1,3)-(1,8))
+ │ ├── flags: ∅
+ │ ├── left:
+ │ │ @ CallNode (location: (1,3)-(1,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,3)-(1,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right: ∅
+ │ └── operator_loc: (1,6)-(1,8) = ".."
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,10)-(1,13) = "end"
diff --git a/test/prism/snapshots/whitequark/cond_match_current_line.txt b/test/prism/snapshots/whitequark/cond_match_current_line.txt
new file mode 100644
index 0000000000..700d0966f7
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cond_match_current_line.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(3,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,13))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,6))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ MatchLastLineNode (location: (1,1)-(1,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,1)-(1,2) = "/"
+ │ │ ├── content_loc: (1,2)-(1,5) = "wat"
+ │ │ ├── closing_loc: (1,5)-(1,6) = "/"
+ │ │ └── unescaped: "wat"
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,0)-(1,1) = "!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ IfNode (location: (3,0)-(3,13))
+ ├── if_keyword_loc: (3,0)-(3,2) = "if"
+ ├── predicate:
+ │ @ MatchLastLineNode (location: (3,3)-(3,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (3,3)-(3,4) = "/"
+ │ ├── content_loc: (3,4)-(3,7) = "wat"
+ │ ├── closing_loc: (3,7)-(3,8) = "/"
+ │ └── unescaped: "wat"
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (3,10)-(3,13) = "end"
diff --git a/test/prism/snapshots/whitequark/const_op_asgn.txt b/test/prism/snapshots/whitequark/const_op_asgn.txt
new file mode 100644
index 0000000000..4985f3e54b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/const_op_asgn.txt
@@ -0,0 +1,101 @@
+@ ProgramNode (location: (1,0)-(9,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,25))
+ └── body: (length: 5)
+ ├── @ ConstantPathOperatorWriteNode (location: (1,0)-(1,8))
+ │ ├── 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) = "+="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator: :+
+ ├── @ ConstantOperatorWriteNode (location: (3,0)-(3,6))
+ │ ├── name: :A
+ │ ├── name_loc: (3,0)-(3,1) = "A"
+ │ ├── operator_loc: (3,2)-(3,4) = "+="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,5)-(3,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── 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) = "+="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (5,8)-(5,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator: :+
+ ├── @ DefNode (location: (7,0)-(7,21))
+ │ ├── name: :x
+ │ ├── name_loc: (7,4)-(7,5) = "x"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,7)-(7,16))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ConstantPathOrWriteNode (location: (7,7)-(7,16))
+ │ │ ├── target:
+ │ │ │ @ ConstantPathNode (location: (7,7)-(7,10))
+ │ │ │ ├── parent: ∅
+ │ │ │ ├── child:
+ │ │ │ │ @ ConstantReadNode (location: (7,9)-(7,10))
+ │ │ │ │ └── name: :A
+ │ │ │ └── delimiter_loc: (7,7)-(7,9) = "::"
+ │ │ ├── operator_loc: (7,11)-(7,14) = "||="
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (7,15)-(7,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (7,18)-(7,21) = "end"
+ └── @ DefNode (location: (9,0)-(9,25))
+ ├── name: :x
+ ├── name_loc: (9,4)-(9,5) = "x"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (9,7)-(9,20))
+ │ └── body: (length: 1)
+ │ └── @ ConstantPathOrWriteNode (location: (9,7)-(9,20))
+ │ ├── target:
+ │ │ @ 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) = "::"
+ │ ├── operator_loc: (9,15)-(9,18) = "||="
+ │ └── value:
+ │ @ IntegerNode (location: (9,19)-(9,20))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── locals: []
+ ├── def_keyword_loc: (9,0)-(9,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (9,22)-(9,25) = "end"
diff --git a/test/prism/snapshots/whitequark/const_scoped.txt b/test/prism/snapshots/whitequark/const_scoped.txt
new file mode 100644
index 0000000000..1e2bccef96
--- /dev/null
+++ b/test/prism/snapshots/whitequark/const_scoped.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ ConstantPathNode (location: (1,0)-(1,8))
+ ├── parent:
+ │ @ ConstantReadNode (location: (1,0)-(1,3))
+ │ └── name: :Bar
+ ├── child:
+ │ @ ConstantReadNode (location: (1,5)-(1,8))
+ │ └── name: :Foo
+ └── delimiter_loc: (1,3)-(1,5) = "::"
diff --git a/test/prism/snapshots/whitequark/const_toplevel.txt b/test/prism/snapshots/whitequark/const_toplevel.txt
new file mode 100644
index 0000000000..b54b069d06
--- /dev/null
+++ b/test/prism/snapshots/whitequark/const_toplevel.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── 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) = "::"
diff --git a/test/prism/snapshots/whitequark/const_unscoped.txt b/test/prism/snapshots/whitequark/const_unscoped.txt
new file mode 100644
index 0000000000..5e272e1775
--- /dev/null
+++ b/test/prism/snapshots/whitequark/const_unscoped.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ ConstantReadNode (location: (1,0)-(1,3))
+ └── name: :Foo
diff --git a/test/prism/snapshots/whitequark/cpath.txt b/test/prism/snapshots/whitequark/cpath.txt
new file mode 100644
index 0000000000..b892525646
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cpath.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(3,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,20))
+ └── body: (length: 2)
+ ├── @ ModuleNode (location: (1,0)-(1,17))
+ │ ├── locals: []
+ │ ├── module_keyword_loc: (1,0)-(1,6) = "module"
+ │ ├── constant_path:
+ │ │ @ ConstantPathNode (location: (1,7)-(1,12))
+ │ │ ├── parent: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (1,9)-(1,12))
+ │ │ │ └── name: :Foo
+ │ │ └── delimiter_loc: (1,7)-(1,9) = "::"
+ │ ├── body: ∅
+ │ ├── end_keyword_loc: (1,14)-(1,17) = "end"
+ │ └── name: :Foo
+ └── @ ModuleNode (location: (3,0)-(3,20))
+ ├── locals: []
+ ├── module_keyword_loc: (3,0)-(3,6) = "module"
+ ├── constant_path:
+ │ @ ConstantPathNode (location: (3,7)-(3,15))
+ │ ├── parent:
+ │ │ @ ConstantReadNode (location: (3,7)-(3,10))
+ │ │ └── name: :Bar
+ │ ├── child:
+ │ │ @ ConstantReadNode (location: (3,12)-(3,15))
+ │ │ └── name: :Foo
+ │ └── delimiter_loc: (3,10)-(3,12) = "::"
+ ├── body: ∅
+ ├── end_keyword_loc: (3,17)-(3,20) = "end"
+ └── name: :Foo
diff --git a/test/prism/snapshots/whitequark/cvar.txt b/test/prism/snapshots/whitequark/cvar.txt
new file mode 100644
index 0000000000..7847ce4495
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cvar.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ ClassVariableReadNode (location: (1,0)-(1,5))
+ └── name: :@@foo
diff --git a/test/prism/snapshots/whitequark/cvasgn.txt b/test/prism/snapshots/whitequark/cvasgn.txt
new file mode 100644
index 0000000000..f3eceed4a4
--- /dev/null
+++ b/test/prism/snapshots/whitequark/cvasgn.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ ClassVariableWriteNode (location: (1,0)-(1,10))
+ ├── name: :@@var
+ ├── name_loc: (1,0)-(1,5) = "@@var"
+ ├── value:
+ │ @ IntegerNode (location: (1,8)-(1,10))
+ │ ├── flags: decimal
+ │ └── value: 10
+ └── operator_loc: (1,6)-(1,7) = "="
diff --git a/test/prism/snapshots/whitequark/dedenting_heredoc.txt b/test/prism/snapshots/whitequark/dedenting_heredoc.txt
new file mode 100644
index 0000000000..acb79e83d2
--- /dev/null
+++ b/test/prism/snapshots/whitequark/dedenting_heredoc.txt
@@ -0,0 +1,496 @@
+@ ProgramNode (location: (1,0)-(72,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(72,8))
+ └── body: (length: 16)
+ ├── @ CallNode (location: (1,0)-(1,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (1,0)-(1,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (1,2)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,2)-(1,8) = "<<~\"E\""
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (2,0)-(3,0) = " x\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " x\n"
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (3,2)-(3,10))
+ │ │ │ │ ├── opening_loc: (3,2)-(3,4) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (3,4)-(3,9))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ StringNode (location: (3,4)-(3,9))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── opening_loc: (3,4)-(3,5) = "\""
+ │ │ │ │ │ ├── content_loc: (3,5)-(3,8) = " y"
+ │ │ │ │ │ ├── closing_loc: (3,8)-(3,9) = "\""
+ │ │ │ │ │ └── unescaped: " y"
+ │ │ │ │ └── closing_loc: (3,9)-(3,10) = "}"
+ │ │ │ └── @ StringNode (location: (3,10)-(4,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,10)-(4,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (4,0)-(5,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (6,0)-(6,8))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (6,0)-(6,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (6,2)-(6,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (6,2)-(6,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (6,2)-(6,8) = "<<~\"E\""
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (7,0)-(8,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (7,0)-(8,0) = " x\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " x\n"
+ │ │ │ ├── @ EmbeddedStatementsNode (location: (8,2)-(8,8))
+ │ │ │ │ ├── opening_loc: (8,2)-(8,4) = "\#{"
+ │ │ │ │ ├── statements:
+ │ │ │ │ │ @ StatementsNode (location: (8,4)-(8,7))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (8,4)-(8,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :foo
+ │ │ │ │ │ ├── message_loc: (8,4)-(8,7) = "foo"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ └── closing_loc: (8,7)-(8,8) = "}"
+ │ │ │ └── @ StringNode (location: (8,8)-(9,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (8,8)-(9,0) = "\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\n"
+ │ │ └── closing_loc: (9,0)-(10,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (11,0)-(11,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (11,0)-(11,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,2)-(11,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (11,2)-(11,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (11,2)-(11,6) = "<<~E"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (12,0)-(13,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (12,0)-(13,0) = "\tx\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "x\n"
+ │ │ │ └── @ StringNode (location: (13,0)-(14,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (13,0)-(14,0) = " y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "y\n"
+ │ │ └── closing_loc: (14,0)-(15,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (16,0)-(16,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (16,0)-(16,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (16,2)-(16,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (16,2)-(16,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (16,2)-(16,6) = "<<~E"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (17,0)-(18,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (17,0)-(18,0) = "\tx\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "\tx\n"
+ │ │ │ └── @ StringNode (location: (18,0)-(19,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (18,0)-(19,0) = " y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "y\n"
+ │ │ └── closing_loc: (19,0)-(20,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (21,0)-(21,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (21,0)-(21,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (21,2)-(21,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (21,2)-(21,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (21,2)-(21,6) = "<<~E"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (22,0)-(23,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (22,0)-(23,0) = " \tx\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "x\n"
+ │ │ │ └── @ StringNode (location: (23,0)-(24,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (23,0)-(24,0) = " y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "y\n"
+ │ │ └── closing_loc: (24,0)-(25,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (26,0)-(26,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (26,0)-(26,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (26,2)-(26,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (26,2)-(26,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (26,2)-(26,6) = "<<~E"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (27,0)-(28,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (27,0)-(28,0) = " \tx\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "\tx\n"
+ │ │ │ └── @ StringNode (location: (28,0)-(29,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (28,0)-(29,0) = "\ty\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "y\n"
+ │ │ └── closing_loc: (29,0)-(30,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (31,0)-(31,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (31,0)-(31,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,2)-(31,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (31,2)-(31,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (31,2)-(31,6) = "<<~E"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (32,0)-(33,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (32,0)-(33,0) = " x\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " x\n"
+ │ │ │ └── @ StringNode (location: (33,0)-(34,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (33,0)-(34,0) = " \\\ty\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "\ty\n"
+ │ │ └── closing_loc: (34,0)-(35,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (36,0)-(36,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (36,0)-(36,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (36,2)-(36,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (36,2)-(36,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (36,2)-(36,6) = "<<~E"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (37,0)-(38,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (37,0)-(38,0) = " x\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " x\n"
+ │ │ │ └── @ StringNode (location: (38,0)-(39,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (38,0)-(39,0) = " \\ y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " y\n"
+ │ │ └── closing_loc: (39,0)-(40,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (41,0)-(41,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (41,0)-(41,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (41,2)-(41,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (41,2)-(41,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (41,2)-(41,6) = "<<~E"
+ │ │ ├── content_loc: (42,0)-(42,0) = ""
+ │ │ ├── closing_loc: (42,0)-(43,0) = " E\n"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (44,0)-(44,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (44,0)-(44,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (44,2)-(44,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (44,2)-(44,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (44,2)-(44,6) = "<<~E"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (45,0)-(46,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (45,0)-(46,0) = " x\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " x\n"
+ │ │ │ ├── @ StringNode (location: (46,0)-(47,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (46,0)-(47,0) = "\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "\n"
+ │ │ │ └── @ StringNode (location: (47,0)-(48,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (47,0)-(48,0) = "y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "y\n"
+ │ │ └── closing_loc: (48,0)-(49,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (50,0)-(50,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (50,0)-(50,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (50,2)-(50,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (50,2)-(50,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (50,2)-(50,6) = "<<~E"
+ │ │ ├── parts: (length: 3)
+ │ │ │ ├── @ StringNode (location: (51,0)-(52,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (51,0)-(52,0) = " x\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "x\n"
+ │ │ │ ├── @ StringNode (location: (52,0)-(53,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (52,0)-(53,0) = " \n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: " \n"
+ │ │ │ └── @ StringNode (location: (53,0)-(54,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (53,0)-(54,0) = " y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "y\n"
+ │ │ └── closing_loc: (54,0)-(55,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (56,0)-(56,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (56,0)-(56,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (56,2)-(56,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ InterpolatedStringNode (location: (56,2)-(56,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (56,2)-(56,6) = "<<~E"
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (57,0)-(58,0))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (57,0)-(58,0) = " x\n"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "x\n"
+ │ │ │ └── @ StringNode (location: (58,0)-(59,0))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (58,0)-(59,0) = " y\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " y\n"
+ │ │ └── closing_loc: (59,0)-(60,0) = "E\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (61,0)-(61,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (61,0)-(61,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (61,2)-(61,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (61,2)-(61,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (61,2)-(61,6) = "<<~E"
+ │ │ ├── content_loc: (62,0)-(63,0) = " x\n"
+ │ │ ├── closing_loc: (63,0)-(64,0) = "E\n"
+ │ │ └── unescaped: "x\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (65,0)-(65,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (65,0)-(65,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (65,2)-(65,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (65,2)-(65,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (65,2)-(65,6) = "<<~E"
+ │ │ ├── content_loc: (66,0)-(67,0) = " ð\n"
+ │ │ ├── closing_loc: (67,0)-(68,0) = "E\n"
+ │ │ └── unescaped: "ð\n"
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (69,0)-(69,6))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (69,0)-(69,1) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (69,2)-(69,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ StringNode (location: (69,2)-(69,6))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (69,2)-(69,6) = "<<~E"
+ │ │ ├── content_loc: (70,0)-(70,0) = ""
+ │ │ ├── closing_loc: (70,0)-(71,0) = "E\n"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (72,0)-(72,8))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (72,0)-(72,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (72,2)-(72,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedXStringNode (location: (72,2)-(72,8))
+ │ ├── opening_loc: (72,2)-(72,8) = "<<~`E`"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (73,0)-(74,0))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (73,0)-(74,0) = " x\n"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: " x\n"
+ │ │ ├── @ EmbeddedStatementsNode (location: (74,2)-(74,8))
+ │ │ │ ├── opening_loc: (74,2)-(74,4) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (74,4)-(74,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (74,4)-(74,7))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :foo
+ │ │ │ │ ├── message_loc: (74,4)-(74,7) = "foo"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (74,7)-(74,8) = "}"
+ │ │ └── @ StringNode (location: (74,8)-(75,0))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (74,8)-(75,0) = "\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\n"
+ │ └── closing_loc: (75,0)-(76,0) = "E\n"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt b/test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt
new file mode 100644
index 0000000000..8d093fdab6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,8) = "<<~'FOO'"
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (2,0)-(3,0) = " baz\\\\\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz\\\\\n"
+ │ └── @ StringNode (location: (3,0)-(4,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (3,0)-(4,0) = " qux\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "qux\n"
+ └── closing_loc: (4,0)-(5,0) = "FOO\n"
diff --git a/test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt b/test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt
new file mode 100644
index 0000000000..d43d313e6b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,8) = "<<~'FOO'"
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (2,0)-(3,0) = " baz\\\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz\\\n"
+ │ └── @ StringNode (location: (3,0)-(4,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (3,0)-(4,0) = " qux\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "qux\n"
+ └── closing_loc: (4,0)-(5,0) = "FOO\n"
diff --git a/test/prism/snapshots/whitequark/def.txt b/test/prism/snapshots/whitequark/def.txt
new file mode 100644
index 0000000000..d5e1139c4d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/def.txt
@@ -0,0 +1,83 @@
+@ ProgramNode (location: (1,0)-(11,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,14))
+ └── body: (length: 6)
+ ├── @ DefNode (location: (1,0)-(1,14))
+ │ ├── name: :BEGIN
+ │ ├── name_loc: (1,4)-(1,9) = "BEGIN"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,11)-(1,14) = "end"
+ ├── @ DefNode (location: (3,0)-(3,12))
+ │ ├── name: :END
+ │ ├── name_loc: (3,4)-(3,7) = "END"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,9)-(3,12) = "end"
+ ├── @ DefNode (location: (5,0)-(5,15))
+ │ ├── name: :String
+ │ ├── name_loc: (5,4)-(5,10) = "String"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,12)-(5,15) = "end"
+ ├── @ DefNode (location: (7,0)-(7,16))
+ │ ├── name: :String=
+ │ ├── name_loc: (7,4)-(7,11) = "String="
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (7,13)-(7,16) = "end"
+ ├── @ DefNode (location: (9,0)-(9,12))
+ │ ├── name: :foo
+ │ ├── name_loc: (9,4)-(9,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (9,0)-(9,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (9,9)-(9,12) = "end"
+ └── @ DefNode (location: (11,0)-(11,14))
+ ├── name: :until
+ ├── name_loc: (11,4)-(11,9) = "until"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (11,0)-(11,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (11,11)-(11,14) = "end"
diff --git a/test/prism/snapshots/whitequark/defined.txt b/test/prism/snapshots/whitequark/defined.txt
new file mode 100644
index 0000000000..5e05870b21
--- /dev/null
+++ b/test/prism/snapshots/whitequark/defined.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(5,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,13))
+ └── body: (length: 3)
+ ├── @ DefinedNode (location: (1,0)-(1,13))
+ │ ├── lparen_loc: ∅
+ │ ├── value:
+ │ │ @ InstanceVariableReadNode (location: (1,9)-(1,13))
+ │ │ └── name: :@foo
+ │ ├── rparen_loc: ∅
+ │ └── keyword_loc: (1,0)-(1,8) = "defined?"
+ ├── @ DefinedNode (location: (3,0)-(3,12))
+ │ ├── lparen_loc: ∅
+ │ ├── value:
+ │ │ @ CallNode (location: (3,9)-(3,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,9)-(3,12) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rparen_loc: ∅
+ │ └── keyword_loc: (3,0)-(3,8) = "defined?"
+ └── @ DefinedNode (location: (5,0)-(5,13))
+ ├── lparen_loc: (5,8)-(5,9) = "("
+ ├── value:
+ │ @ CallNode (location: (5,9)-(5,12))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,9)-(5,12) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rparen_loc: (5,12)-(5,13) = ")"
+ └── keyword_loc: (5,0)-(5,8) = "defined?"
diff --git a/test/prism/snapshots/whitequark/defs.txt b/test/prism/snapshots/whitequark/defs.txt
new file mode 100644
index 0000000000..616cca6155
--- /dev/null
+++ b/test/prism/snapshots/whitequark/defs.txt
@@ -0,0 +1,90 @@
+@ ProgramNode (location: (1,0)-(9,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,18))
+ └── body: (length: 5)
+ ├── @ DefNode (location: (1,0)-(1,18))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,10)-(1,13) = "foo"
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (1,4)-(1,9))
+ │ │ ├── body:
+ │ │ │ @ CallNode (location: (1,5)-(1,8))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ │ └── closing_loc: (1,8)-(1,9) = ")"
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: (1,9)-(1,10) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,15)-(1,18) = "end"
+ ├── @ DefNode (location: (3,0)-(3,19))
+ │ ├── name: :foo
+ │ ├── name_loc: (3,11)-(3,14) = "foo"
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (3,4)-(3,10))
+ │ │ └── name: :String
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: (3,10)-(3,11) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,16)-(3,19) = "end"
+ ├── @ DefNode (location: (5,0)-(5,20))
+ │ ├── name: :foo
+ │ ├── name_loc: (5,12)-(5,15) = "foo"
+ │ ├── receiver:
+ │ │ @ ConstantReadNode (location: (5,4)-(5,10))
+ │ │ └── name: :String
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: (5,10)-(5,12) = "::"
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,17)-(5,20) = "end"
+ ├── @ DefNode (location: (7,0)-(7,17))
+ │ ├── name: :foo
+ │ ├── name_loc: (7,9)-(7,12) = "foo"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (7,4)-(7,8))
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: (7,8)-(7,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (7,14)-(7,17) = "end"
+ └── @ DefNode (location: (9,0)-(9,18))
+ ├── name: :foo
+ ├── name_loc: (9,10)-(9,13) = "foo"
+ ├── receiver:
+ │ @ SelfNode (location: (9,4)-(9,8))
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (9,0)-(9,3) = "def"
+ ├── operator_loc: (9,8)-(9,10) = "::"
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (9,15)-(9,18) = "end"
diff --git a/test/prism/snapshots/whitequark/empty_stmt.txt b/test/prism/snapshots/whitequark/empty_stmt.txt
new file mode 100644
index 0000000000..3a21ce5559
--- /dev/null
+++ b/test/prism/snapshots/whitequark/empty_stmt.txt
@@ -0,0 +1,5 @@
+@ ProgramNode (location: (1,0)-(1,0))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,0))
+ └── body: (length: 0)
diff --git a/test/prism/snapshots/whitequark/endless_comparison_method.txt b/test/prism/snapshots/whitequark/endless_comparison_method.txt
new file mode 100644
index 0000000000..28ec3843bb
--- /dev/null
+++ b/test/prism/snapshots/whitequark/endless_comparison_method.txt
@@ -0,0 +1,221 @@
+@ ProgramNode (location: (1,0)-(11,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,28))
+ └── body: (length: 6)
+ ├── @ DefNode (location: (1,0)-(1,28))
+ │ ├── name: :!=
+ │ ├── name_loc: (1,4)-(1,6) = "!="
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,7)-(1,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,7)-(1,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :other
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,16)-(1,28))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,16)-(1,28))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :do_something
+ │ │ ├── message_loc: (1,16)-(1,28) = "do_something"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:other]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,6)-(1,7) = "("
+ │ ├── rparen_loc: (1,12)-(1,13) = ")"
+ │ ├── equal_loc: (1,14)-(1,15) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (3,0)-(3,28))
+ │ ├── name: :!=
+ │ ├── name_loc: (3,4)-(3,6) = "!="
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,7)-(3,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (3,7)-(3,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :other
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,16)-(3,28))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,16)-(3,28))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :do_something
+ │ │ ├── message_loc: (3,16)-(3,28) = "do_something"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:other]
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (3,6)-(3,7) = "("
+ │ ├── rparen_loc: (3,12)-(3,13) = ")"
+ │ ├── equal_loc: (3,14)-(3,15) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (5,0)-(5,28))
+ │ ├── name: :<=
+ │ ├── name_loc: (5,4)-(5,6) = "<="
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (5,7)-(5,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (5,7)-(5,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :other
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,16)-(5,28))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,16)-(5,28))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :do_something
+ │ │ ├── message_loc: (5,16)-(5,28) = "do_something"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:other]
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (5,6)-(5,7) = "("
+ │ ├── rparen_loc: (5,12)-(5,13) = ")"
+ │ ├── equal_loc: (5,14)-(5,15) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (7,0)-(7,28))
+ │ ├── name: :==
+ │ ├── name_loc: (7,4)-(7,6) = "=="
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (7,7)-(7,12))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (7,7)-(7,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :other
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,16)-(7,28))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (7,16)-(7,28))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :do_something
+ │ │ ├── message_loc: (7,16)-(7,28) = "do_something"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:other]
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (7,6)-(7,7) = "("
+ │ ├── rparen_loc: (7,12)-(7,13) = ")"
+ │ ├── equal_loc: (7,14)-(7,15) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (9,0)-(9,29))
+ │ ├── name: :===
+ │ ├── name_loc: (9,4)-(9,7) = "==="
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (9,8)-(9,13))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (9,8)-(9,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :other
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (9,17)-(9,29))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (9,17)-(9,29))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :do_something
+ │ │ ├── message_loc: (9,17)-(9,29) = "do_something"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:other]
+ │ ├── def_keyword_loc: (9,0)-(9,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (9,7)-(9,8) = "("
+ │ ├── rparen_loc: (9,13)-(9,14) = ")"
+ │ ├── equal_loc: (9,15)-(9,16) = "="
+ │ └── end_keyword_loc: ∅
+ └── @ DefNode (location: (11,0)-(11,28))
+ ├── name: :>=
+ ├── name_loc: (11,4)-(11,6) = ">="
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (11,7)-(11,12))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (11,7)-(11,12))
+ │ │ ├── flags: ∅
+ │ │ └── name: :other
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (11,16)-(11,28))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (11,16)-(11,28))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :do_something
+ │ ├── message_loc: (11,16)-(11,28) = "do_something"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: [:other]
+ ├── def_keyword_loc: (11,0)-(11,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (11,6)-(11,7) = "("
+ ├── rparen_loc: (11,12)-(11,13) = ")"
+ ├── equal_loc: (11,14)-(11,15) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/endless_method.txt b/test/prism/snapshots/whitequark/endless_method.txt
new file mode 100644
index 0000000000..17d3873b66
--- /dev/null
+++ b/test/prism/snapshots/whitequark/endless_method.txt
@@ -0,0 +1,151 @@
+@ ProgramNode (location: (1,0)-(7,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,22))
+ └── body: (length: 4)
+ ├── @ DefNode (location: (1,0)-(1,14))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,12)-(1,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,12)-(1,14))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ ├── rparen_loc: (1,8)-(1,9) = ")"
+ │ ├── equal_loc: (1,10)-(1,11) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (3,0)-(3,18))
+ │ ├── name: :inc
+ │ ├── name_loc: (3,4)-(3,7) = "inc"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,8)-(3,9))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (3,8)-(3,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :x
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,13)-(3,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,13)-(3,18))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ LocalVariableReadNode (location: (3,13)-(3,14))
+ │ │ │ ├── name: :x
+ │ │ │ └── depth: 0
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :+
+ │ │ ├── message_loc: (3,15)-(3,16) = "+"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,17)-(3,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,17)-(3,18))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (3,7)-(3,8) = "("
+ │ ├── rparen_loc: (3,9)-(3,10) = ")"
+ │ ├── equal_loc: (3,11)-(3,12) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (5,0)-(5,18))
+ │ ├── name: :foo
+ │ ├── name_loc: (5,8)-(5,11) = "foo"
+ │ ├── receiver:
+ │ │ @ CallNode (location: (5,4)-(5,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :obj
+ │ │ ├── message_loc: (5,4)-(5,7) = "obj"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,16)-(5,18))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,16)-(5,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: (5,7)-(5,8) = "."
+ │ ├── lparen_loc: (5,11)-(5,12) = "("
+ │ ├── rparen_loc: (5,12)-(5,13) = ")"
+ │ ├── equal_loc: (5,14)-(5,15) = "="
+ │ └── end_keyword_loc: ∅
+ └── @ DefNode (location: (7,0)-(7,22))
+ ├── name: :inc
+ ├── name_loc: (7,8)-(7,11) = "inc"
+ ├── receiver:
+ │ @ CallNode (location: (7,4)-(7,7))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :obj
+ │ ├── message_loc: (7,4)-(7,7) = "obj"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (7,12)-(7,13))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (7,12)-(7,13))
+ │ │ ├── flags: ∅
+ │ │ └── name: :x
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (7,17)-(7,22))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (7,17)-(7,22))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (7,17)-(7,18))
+ │ │ ├── name: :x
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (7,19)-(7,20) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,21)-(7,22))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (7,21)-(7,22))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: [:x]
+ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ ├── operator_loc: (7,7)-(7,8) = "."
+ ├── lparen_loc: (7,11)-(7,12) = "("
+ ├── rparen_loc: (7,13)-(7,14) = ")"
+ ├── equal_loc: (7,15)-(7,16) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/endless_method_command_syntax.txt b/test/prism/snapshots/whitequark/endless_method_command_syntax.txt
new file mode 100644
index 0000000000..4ec57ccd35
--- /dev/null
+++ b/test/prism/snapshots/whitequark/endless_method_command_syntax.txt
@@ -0,0 +1,394 @@
+@ ProgramNode (location: (1,0)-(15,62))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(15,62))
+ └── body: (length: 8)
+ ├── @ DefNode (location: (1,0)-(1,22))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,10)-(1,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,10)-(1,22))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (1,10)-(1,14) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,15)-(1,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (1,15)-(1,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,15)-(1,16) = "\""
+ │ │ │ ├── content_loc: (1,16)-(1,21) = "Hello"
+ │ │ │ ├── closing_loc: (1,21)-(1,22) = "\""
+ │ │ │ └── unescaped: "Hello"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (1,8)-(1,9) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (3,0)-(3,24))
+ │ ├── name: :foo
+ │ ├── name_loc: (3,4)-(3,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,12)-(3,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,12)-(3,24))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (3,12)-(3,16) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,17)-(3,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (3,17)-(3,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (3,17)-(3,18) = "\""
+ │ │ │ ├── content_loc: (3,18)-(3,23) = "Hello"
+ │ │ │ ├── closing_loc: (3,23)-(3,24) = "\""
+ │ │ │ └── unescaped: "Hello"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (3,7)-(3,8) = "("
+ │ ├── rparen_loc: (3,8)-(3,9) = ")"
+ │ ├── equal_loc: (3,10)-(3,11) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (5,0)-(5,19))
+ │ ├── name: :foo
+ │ ├── name_loc: (5,4)-(5,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (5,8)-(5,9))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (5,8)-(5,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :x
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,13)-(5,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,13)-(5,19))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (5,13)-(5,17) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,18)-(5,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (5,18)-(5,19))
+ │ │ │ ├── name: :x
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (5,7)-(5,8) = "("
+ │ ├── rparen_loc: (5,9)-(5,10) = ")"
+ │ ├── equal_loc: (5,11)-(5,12) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (7,0)-(7,26))
+ │ ├── name: :foo
+ │ ├── name_loc: (7,8)-(7,11) = "foo"
+ │ ├── receiver:
+ │ │ @ CallNode (location: (7,4)-(7,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :obj
+ │ │ ├── message_loc: (7,4)-(7,7) = "obj"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,14)-(7,26))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (7,14)-(7,26))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (7,14)-(7,18) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,19)-(7,26))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (7,19)-(7,26))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (7,19)-(7,20) = "\""
+ │ │ │ ├── content_loc: (7,20)-(7,25) = "Hello"
+ │ │ │ ├── closing_loc: (7,25)-(7,26) = "\""
+ │ │ │ └── unescaped: "Hello"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: (7,7)-(7,8) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (7,12)-(7,13) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (9,0)-(9,28))
+ │ ├── name: :foo
+ │ ├── name_loc: (9,8)-(9,11) = "foo"
+ │ ├── receiver:
+ │ │ @ CallNode (location: (9,4)-(9,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :obj
+ │ │ ├── message_loc: (9,4)-(9,7) = "obj"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (9,16)-(9,28))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (9,16)-(9,28))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (9,16)-(9,20) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (9,21)-(9,28))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (9,21)-(9,28))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (9,21)-(9,22) = "\""
+ │ │ │ ├── content_loc: (9,22)-(9,27) = "Hello"
+ │ │ │ ├── closing_loc: (9,27)-(9,28) = "\""
+ │ │ │ └── unescaped: "Hello"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (9,0)-(9,3) = "def"
+ │ ├── operator_loc: (9,7)-(9,8) = "."
+ │ ├── lparen_loc: (9,11)-(9,12) = "("
+ │ ├── rparen_loc: (9,12)-(9,13) = ")"
+ │ ├── equal_loc: (9,14)-(9,15) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (11,0)-(11,23))
+ │ ├── name: :foo
+ │ ├── name_loc: (11,8)-(11,11) = "foo"
+ │ ├── receiver:
+ │ │ @ CallNode (location: (11,4)-(11,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :obj
+ │ │ ├── message_loc: (11,4)-(11,7) = "obj"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (11,12)-(11,13))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (11,12)-(11,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :x
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (11,17)-(11,23))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (11,17)-(11,23))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (11,17)-(11,21) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (11,22)-(11,23))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (11,22)-(11,23))
+ │ │ │ ├── name: :x
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (11,0)-(11,3) = "def"
+ │ ├── operator_loc: (11,7)-(11,8) = "."
+ │ ├── lparen_loc: (11,11)-(11,12) = "("
+ │ ├── rparen_loc: (11,13)-(11,14) = ")"
+ │ ├── equal_loc: (11,15)-(11,16) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (13,0)-(13,60))
+ │ ├── name: :rescued
+ │ ├── name_loc: (13,4)-(13,11) = "rescued"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (13,12)-(13,13))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (13,12)-(13,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :x
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (13,17)-(13,60))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (13,17)-(13,60))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (13,17)-(13,37))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (13,17)-(13,22) = "raise"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (13,23)-(13,37))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ StringNode (location: (13,23)-(13,37))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── opening_loc: (13,23)-(13,24) = "\""
+ │ │ │ │ ├── content_loc: (13,24)-(13,36) = "to be caught"
+ │ │ │ │ ├── closing_loc: (13,36)-(13,37) = "\""
+ │ │ │ │ └── unescaped: "to be caught"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (13,38)-(13,44) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ InterpolatedStringNode (location: (13,45)-(13,60))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (13,45)-(13,46) = "\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (13,46)-(13,55))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (13,46)-(13,55) = "instance "
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "instance "
+ │ │ │ └── @ EmbeddedStatementsNode (location: (13,55)-(13,59))
+ │ │ │ ├── opening_loc: (13,55)-(13,57) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (13,57)-(13,58))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (13,57)-(13,58))
+ │ │ │ │ ├── name: :x
+ │ │ │ │ └── depth: 0
+ │ │ │ └── closing_loc: (13,58)-(13,59) = "}"
+ │ │ └── closing_loc: (13,59)-(13,60) = "\""
+ │ ├── locals: [:x]
+ │ ├── def_keyword_loc: (13,0)-(13,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (13,11)-(13,12) = "("
+ │ ├── rparen_loc: (13,13)-(13,14) = ")"
+ │ ├── equal_loc: (13,15)-(13,16) = "="
+ │ └── end_keyword_loc: ∅
+ └── @ DefNode (location: (15,0)-(15,62))
+ ├── name: :rescued
+ ├── name_loc: (15,9)-(15,16) = "rescued"
+ ├── receiver:
+ │ @ SelfNode (location: (15,4)-(15,8))
+ ├── parameters:
+ │ @ ParametersNode (location: (15,17)-(15,18))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (15,17)-(15,18))
+ │ │ ├── flags: ∅
+ │ │ └── name: :x
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (15,22)-(15,62))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (15,22)-(15,62))
+ │ ├── expression:
+ │ │ @ CallNode (location: (15,22)-(15,42))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (15,22)-(15,27) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (15,28)-(15,42))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (15,28)-(15,42))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (15,28)-(15,29) = "\""
+ │ │ │ ├── content_loc: (15,29)-(15,41) = "to be caught"
+ │ │ │ ├── closing_loc: (15,41)-(15,42) = "\""
+ │ │ │ └── unescaped: "to be caught"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (15,43)-(15,49) = "rescue"
+ │ └── rescue_expression:
+ │ @ InterpolatedStringNode (location: (15,50)-(15,62))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (15,50)-(15,51) = "\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (15,51)-(15,57))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (15,51)-(15,57) = "class "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "class "
+ │ │ └── @ EmbeddedStatementsNode (location: (15,57)-(15,61))
+ │ │ ├── opening_loc: (15,57)-(15,59) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (15,59)-(15,60))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (15,59)-(15,60))
+ │ │ │ ├── name: :x
+ │ │ │ └── depth: 0
+ │ │ └── closing_loc: (15,60)-(15,61) = "}"
+ │ └── closing_loc: (15,61)-(15,62) = "\""
+ ├── locals: [:x]
+ ├── def_keyword_loc: (15,0)-(15,3) = "def"
+ ├── operator_loc: (15,8)-(15,9) = "."
+ ├── lparen_loc: (15,16)-(15,17) = "("
+ ├── rparen_loc: (15,18)-(15,19) = ")"
+ ├── equal_loc: (15,20)-(15,21) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt b/test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt
new file mode 100644
index 0000000000..64a3ffa252
--- /dev/null
+++ b/test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,23))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,11))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (1,8)-(1,11))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,15)-(1,23))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,15)-(1,23))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,15)-(1,18) = "bar"
+ │ ├── opening_loc: (1,18)-(1,19) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,19)-(1,22))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ForwardingArgumentsNode (location: (1,19)-(1,22))
+ │ ├── closing_loc: (1,22)-(1,23) = ")"
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,11)-(1,12) = ")"
+ ├── equal_loc: (1,13)-(1,14) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt b/test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt
new file mode 100644
index 0000000000..2284b24354
--- /dev/null
+++ b/test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(3,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,25))
+ └── body: (length: 2)
+ ├── @ DefNode (location: (1,0)-(1,20))
+ │ ├── name: :m
+ │ ├── name_loc: (1,4)-(1,5) = "m"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,10)-(1,20))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (1,10)-(1,20))
+ │ │ ├── expression:
+ │ │ │ @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── keyword_loc: (1,12)-(1,18) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ IntegerNode (location: (1,19)-(1,20))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ ├── rparen_loc: (1,6)-(1,7) = ")"
+ │ ├── equal_loc: (1,8)-(1,9) = "="
+ │ └── end_keyword_loc: ∅
+ └── @ DefNode (location: (3,0)-(3,25))
+ ├── name: :m
+ ├── name_loc: (3,9)-(3,10) = "m"
+ ├── receiver:
+ │ @ SelfNode (location: (3,4)-(3,8))
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (3,15)-(3,25))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (3,15)-(3,25))
+ │ ├── expression:
+ │ │ @ IntegerNode (location: (3,15)-(3,16))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_loc: (3,17)-(3,23) = "rescue"
+ │ └── rescue_expression:
+ │ @ IntegerNode (location: (3,24)-(3,25))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── locals: []
+ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ ├── operator_loc: (3,8)-(3,9) = "."
+ ├── lparen_loc: (3,10)-(3,11) = "("
+ ├── rparen_loc: (3,11)-(3,12) = ")"
+ ├── equal_loc: (3,13)-(3,14) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/endless_method_without_args.txt b/test/prism/snapshots/whitequark/endless_method_without_args.txt
new file mode 100644
index 0000000000..a7a9c93ef3
--- /dev/null
+++ b/test/prism/snapshots/whitequark/endless_method_without_args.txt
@@ -0,0 +1,89 @@
+@ ProgramNode (location: (1,0)-(7,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,28))
+ └── body: (length: 4)
+ ├── @ DefNode (location: (1,0)-(1,12))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,10)-(1,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,10)-(1,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (1,8)-(1,9) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (3,0)-(3,23))
+ │ ├── name: :foo
+ │ ├── name_loc: (3,4)-(3,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,10)-(3,23))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (3,10)-(3,23))
+ │ │ ├── expression:
+ │ │ │ @ IntegerNode (location: (3,10)-(3,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── keyword_loc: (3,13)-(3,19) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (3,20)-(3,23))
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (3,8)-(3,9) = "="
+ │ └── end_keyword_loc: ∅
+ ├── @ DefNode (location: (5,0)-(5,17))
+ │ ├── name: :foo
+ │ ├── name_loc: (5,9)-(5,12) = "foo"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (5,4)-(5,8))
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,15)-(5,17))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,15)-(5,17))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: (5,8)-(5,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: (5,13)-(5,14) = "="
+ │ └── end_keyword_loc: ∅
+ └── @ DefNode (location: (7,0)-(7,28))
+ ├── name: :foo
+ ├── name_loc: (7,9)-(7,12) = "foo"
+ ├── receiver:
+ │ @ SelfNode (location: (7,4)-(7,8))
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (7,15)-(7,28))
+ │ └── body: (length: 1)
+ │ └── @ RescueModifierNode (location: (7,15)-(7,28))
+ │ ├── expression:
+ │ │ @ IntegerNode (location: (7,15)-(7,17))
+ │ │ ├── flags: decimal
+ │ │ └── value: 42
+ │ ├── keyword_loc: (7,18)-(7,24) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (7,25)-(7,28))
+ ├── locals: []
+ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ ├── operator_loc: (7,8)-(7,9) = "."
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: (7,13)-(7,14) = "="
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/ensure.txt b/test/prism/snapshots/whitequark/ensure.txt
new file mode 100644
index 0000000000..a48d2370e8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ensure.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,29))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,29))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,29))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (1,13)-(1,29))
+ │ ├── ensure_keyword_loc: (1,13)-(1,19) = "ensure"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,21)-(1,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,21)-(1,24))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,21)-(1,24) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (1,26)-(1,29) = "end"
+ └── end_keyword_loc: (1,26)-(1,29) = "end"
diff --git a/test/prism/snapshots/whitequark/ensure_empty.txt b/test/prism/snapshots/whitequark/ensure_empty.txt
new file mode 100644
index 0000000000..0bab5d80c3
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ensure_empty.txt
@@ -0,0 +1,16 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,16))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements: ∅
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (1,6)-(1,16))
+ │ ├── ensure_keyword_loc: (1,6)-(1,12) = "ensure"
+ │ ├── statements: ∅
+ │ └── end_keyword_loc: (1,13)-(1,16) = "end"
+ └── end_keyword_loc: (1,13)-(1,16) = "end"
diff --git a/test/prism/snapshots/whitequark/false.txt b/test/prism/snapshots/whitequark/false.txt
new file mode 100644
index 0000000000..00562f703a
--- /dev/null
+++ b/test/prism/snapshots/whitequark/false.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ FalseNode (location: (1,0)-(1,5))
diff --git a/test/prism/snapshots/whitequark/float.txt b/test/prism/snapshots/whitequark/float.txt
new file mode 100644
index 0000000000..5e6a597db7
--- /dev/null
+++ b/test/prism/snapshots/whitequark/float.txt
@@ -0,0 +1,9 @@
+@ ProgramNode (location: (1,0)-(3,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,4))
+ └── body: (length: 2)
+ ├── @ FloatNode (location: (1,0)-(1,5))
+ │ └── value: -1.33
+ └── @ FloatNode (location: (3,0)-(3,4))
+ └── value: 1.33
diff --git a/test/prism/snapshots/whitequark/for.txt b/test/prism/snapshots/whitequark/for.txt
new file mode 100644
index 0000000000..fec8bdfd64
--- /dev/null
+++ b/test/prism/snapshots/whitequark/for.txt
@@ -0,0 +1,83 @@
+@ ProgramNode (location: (1,0)-(3,22))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,22))
+ └── body: (length: 2)
+ ├── @ ForNode (location: (1,0)-(1,24))
+ │ ├── index:
+ │ │ @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── collection:
+ │ │ @ CallNode (location: (1,9)-(1,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,9)-(1,12) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,16)-(1,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,16)-(1,19))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :p
+ │ │ ├── message_loc: (1,16)-(1,17) = "p"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,18)-(1,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (1,18)-(1,19))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── for_keyword_loc: (1,0)-(1,3) = "for"
+ │ ├── in_keyword_loc: (1,6)-(1,8) = "in"
+ │ ├── do_keyword_loc: (1,13)-(1,15) = "do"
+ │ └── end_keyword_loc: (1,21)-(1,24) = "end"
+ └── @ ForNode (location: (3,0)-(3,22))
+ ├── index:
+ │ @ LocalVariableTargetNode (location: (3,4)-(3,5))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── collection:
+ │ @ CallNode (location: (3,9)-(3,12))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,9)-(3,12) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (3,14)-(3,17))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (3,14)-(3,17))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (3,14)-(3,15) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,16)-(3,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (3,16)-(3,17))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── for_keyword_loc: (3,0)-(3,3) = "for"
+ ├── in_keyword_loc: (3,6)-(3,8) = "in"
+ ├── do_keyword_loc: ∅
+ └── end_keyword_loc: (3,19)-(3,22) = "end"
diff --git a/test/prism/snapshots/whitequark/for_mlhs.txt b/test/prism/snapshots/whitequark/for_mlhs.txt
new file mode 100644
index 0000000000..42d8fa2258
--- /dev/null
+++ b/test/prism/snapshots/whitequark/for_mlhs.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(1,28))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,28))
+ └── body: (length: 1)
+ └── @ ForNode (location: (1,0)-(1,28))
+ ├── index:
+ │ @ MultiTargetNode (location: (1,4)-(1,8))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (1,7)-(1,8))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ └── rparen_loc: ∅
+ ├── collection:
+ │ @ CallNode (location: (1,12)-(1,15))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,12)-(1,15) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (1,17)-(1,23))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,17)-(1,23))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :p
+ │ ├── message_loc: (1,17)-(1,18) = "p"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,19)-(1,23))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ LocalVariableReadNode (location: (1,19)-(1,20))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableReadNode (location: (1,22)-(1,23))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── for_keyword_loc: (1,0)-(1,3) = "for"
+ ├── in_keyword_loc: (1,9)-(1,11) = "in"
+ ├── do_keyword_loc: ∅
+ └── end_keyword_loc: (1,25)-(1,28) = "end"
diff --git a/test/prism/snapshots/whitequark/forward_arg.txt b/test/prism/snapshots/whitequark/forward_arg.txt
new file mode 100644
index 0000000000..17504c64e0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/forward_arg.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,27))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,27))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,27))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,11))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (1,8)-(1,11))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,14)-(1,22))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,14)-(1,22))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,14)-(1,17) = "bar"
+ │ ├── opening_loc: (1,17)-(1,18) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,18)-(1,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ForwardingArgumentsNode (location: (1,18)-(1,21))
+ │ ├── closing_loc: (1,21)-(1,22) = ")"
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,11)-(1,12) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,24)-(1,27) = "end"
diff --git a/test/prism/snapshots/whitequark/forward_arg_with_open_args.txt b/test/prism/snapshots/whitequark/forward_arg_with_open_args.txt
new file mode 100644
index 0000000000..7e58260b58
--- /dev/null
+++ b/test/prism/snapshots/whitequark/forward_arg_with_open_args.txt
@@ -0,0 +1,404 @@
+@ ProgramNode (location: (1,0)-(27,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(27,28))
+ └── body: (length: 10)
+ ├── @ ParenthesesNode (location: (1,0)-(3,4))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,1)-(3,3))
+ │ │ └── body: (length: 1)
+ │ │ └── @ DefNode (location: (1,1)-(3,3))
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (1,5)-(1,8) = "foo"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,9)-(1,12))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest:
+ │ │ │ │ @ ForwardingParameterNode (location: (1,9)-(1,12))
+ │ │ │ └── block: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (2,2)-(2,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (2,2)-(2,10))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (2,2)-(2,5) = "bar"
+ │ │ │ ├── opening_loc: (2,5)-(2,6) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (2,6)-(2,9))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ ForwardingArgumentsNode (location: (2,6)-(2,9))
+ │ │ │ ├── closing_loc: (2,9)-(2,10) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── locals: []
+ │ │ ├── def_keyword_loc: (1,1)-(1,4) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ │ ├── opening_loc: (1,0)-(1,1) = "("
+ │ └── closing_loc: (3,3)-(3,4) = ")"
+ ├── @ ParenthesesNode (location: (5,0)-(5,28))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,1)-(5,27))
+ │ │ └── body: (length: 1)
+ │ │ └── @ DefNode (location: (5,1)-(5,27))
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (5,5)-(5,8) = "foo"
+ │ │ ├── receiver: ∅
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (5,9)-(5,12))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest:
+ │ │ │ │ @ ForwardingParameterNode (location: (5,9)-(5,12))
+ │ │ │ └── block: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (5,14)-(5,22))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (5,14)-(5,22))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (5,14)-(5,17) = "bar"
+ │ │ │ ├── opening_loc: (5,17)-(5,18) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (5,18)-(5,21))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ ForwardingArgumentsNode (location: (5,18)-(5,21))
+ │ │ │ ├── closing_loc: (5,21)-(5,22) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── locals: []
+ │ │ ├── def_keyword_loc: (5,1)-(5,4) = "def"
+ │ │ ├── operator_loc: ∅
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── equal_loc: ∅
+ │ │ └── end_keyword_loc: (5,24)-(5,27) = "end"
+ │ ├── opening_loc: (5,0)-(5,1) = "("
+ │ └── closing_loc: (5,27)-(5,28) = ")"
+ ├── @ DefNode (location: (7,0)-(8,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (7,4)-(7,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (7,8)-(7,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (7,8)-(7,11))
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (8,0)-(8,3) = "end"
+ ├── @ DefNode (location: (10,0)-(10,26))
+ │ ├── name: :foo
+ │ ├── name_loc: (10,4)-(10,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (10,8)-(10,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (10,8)-(10,11))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (10,13)-(10,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (10,13)-(10,21))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (10,13)-(10,16) = "bar"
+ │ │ ├── opening_loc: (10,16)-(10,17) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (10,17)-(10,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ForwardingArgumentsNode (location: (10,17)-(10,20))
+ │ │ ├── closing_loc: (10,20)-(10,21) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (10,0)-(10,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (10,23)-(10,26) = "end"
+ ├── @ DefNode (location: (12,0)-(14,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (12,4)-(12,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (12,8)-(12,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (12,8)-(12,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (12,11)-(12,14))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (13,2)-(13,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (13,2)-(13,10))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (13,2)-(13,5) = "bar"
+ │ │ ├── opening_loc: (13,5)-(13,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (13,6)-(13,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ForwardingArgumentsNode (location: (13,6)-(13,9))
+ │ │ ├── closing_loc: (13,9)-(13,10) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (12,0)-(12,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (14,0)-(14,3) = "end"
+ ├── @ DefNode (location: (16,0)-(16,29))
+ │ ├── name: :foo
+ │ ├── name_loc: (16,4)-(16,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (16,8)-(16,14))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (16,8)-(16,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (16,11)-(16,14))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (16,16)-(16,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (16,16)-(16,24))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (16,16)-(16,19) = "bar"
+ │ │ ├── opening_loc: (16,19)-(16,20) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (16,20)-(16,23))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ForwardingArgumentsNode (location: (16,20)-(16,23))
+ │ │ ├── closing_loc: (16,23)-(16,24) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: [:a]
+ │ ├── def_keyword_loc: (16,0)-(16,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (16,26)-(16,29) = "end"
+ ├── @ DefNode (location: (18,0)-(19,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (18,4)-(18,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (18,8)-(18,21))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (18,8)-(18,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (18,11)-(18,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (18,11)-(18,12) = "b"
+ │ │ │ ├── operator_loc: (18,13)-(18,14) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (18,15)-(18,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (18,18)-(18,21))
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:a, :b]
+ │ ├── def_keyword_loc: (18,0)-(18,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (19,0)-(19,3) = "end"
+ ├── @ DefNode (location: (21,0)-(23,3))
+ │ ├── name: :foo
+ │ ├── name_loc: (21,4)-(21,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (21,8)-(21,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (21,8)-(21,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (21,8)-(21,9) = "b"
+ │ │ │ ├── operator_loc: (21,10)-(21,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (21,12)-(21,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (21,15)-(21,18))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (22,2)-(22,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (22,2)-(22,10))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (22,2)-(22,5) = "bar"
+ │ │ ├── opening_loc: (22,5)-(22,6) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (22,6)-(22,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ForwardingArgumentsNode (location: (22,6)-(22,9))
+ │ │ ├── closing_loc: (22,9)-(22,10) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (21,0)-(21,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (23,0)-(23,3) = "end"
+ ├── @ DefNode (location: (25,0)-(25,33))
+ │ ├── name: :foo
+ │ ├── name_loc: (25,4)-(25,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (25,8)-(25,18))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (25,8)-(25,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── name_loc: (25,8)-(25,9) = "b"
+ │ │ │ ├── operator_loc: (25,10)-(25,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (25,12)-(25,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (25,15)-(25,18))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (25,20)-(25,28))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (25,20)-(25,28))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (25,20)-(25,23) = "bar"
+ │ │ ├── opening_loc: (25,23)-(25,24) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (25,24)-(25,27))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ForwardingArgumentsNode (location: (25,24)-(25,27))
+ │ │ ├── closing_loc: (25,27)-(25,28) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (25,0)-(25,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (25,30)-(25,33) = "end"
+ └── @ DefNode (location: (27,0)-(27,28))
+ ├── name: :foo
+ ├── name_loc: (27,4)-(27,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (27,8)-(27,14))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (27,8)-(27,9))
+ │ │ ├── flags: ∅
+ │ │ └── name: :a
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (27,11)-(27,14))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (27,16)-(27,24))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (27,16)-(27,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (27,16)-(27,19) = "bar"
+ │ ├── opening_loc: (27,19)-(27,20) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,20)-(27,23))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ForwardingArgumentsNode (location: (27,20)-(27,23))
+ │ ├── closing_loc: (27,23)-(27,24) = ")"
+ │ └── block: ∅
+ ├── locals: [:a]
+ ├── def_keyword_loc: (27,0)-(27,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (27,7)-(27,8) = "("
+ ├── rparen_loc: (27,14)-(27,15) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (27,25)-(27,28) = "end"
diff --git a/test/prism/snapshots/whitequark/forward_args_legacy.txt b/test/prism/snapshots/whitequark/forward_args_legacy.txt
new file mode 100644
index 0000000000..f46967ba50
--- /dev/null
+++ b/test/prism/snapshots/whitequark/forward_args_legacy.txt
@@ -0,0 +1,99 @@
+@ ProgramNode (location: (1,0)-(5,29))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,29))
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,0)-(1,27))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,8)-(1,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (1,8)-(1,11))
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,14)-(1,22))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,14)-(1,22))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,14)-(1,17) = "bar"
+ │ │ ├── opening_loc: (1,17)-(1,18) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,18)-(1,21))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ ForwardingArgumentsNode (location: (1,18)-(1,21))
+ │ │ ├── closing_loc: (1,21)-(1,22) = ")"
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (1,7)-(1,8) = "("
+ │ ├── rparen_loc: (1,11)-(1,12) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,24)-(1,27) = "end"
+ ├── @ DefNode (location: (3,0)-(3,17))
+ │ ├── name: :foo
+ │ ├── name_loc: (3,4)-(3,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,8)-(3,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ ForwardingParameterNode (location: (3,8)-(3,11))
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (3,7)-(3,8) = "("
+ │ ├── rparen_loc: (3,11)-(3,12) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,14)-(3,17) = "end"
+ └── @ DefNode (location: (5,0)-(5,29))
+ ├── name: :foo
+ ├── name_loc: (5,4)-(5,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (5,8)-(5,11))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (5,8)-(5,11))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (5,14)-(5,24))
+ │ └── body: (length: 1)
+ │ └── @ SuperNode (location: (5,14)-(5,24))
+ │ ├── keyword_loc: (5,14)-(5,19) = "super"
+ │ ├── lparen_loc: (5,19)-(5,20) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,20)-(5,23))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ForwardingArgumentsNode (location: (5,20)-(5,23))
+ │ ├── rparen_loc: (5,23)-(5,24) = ")"
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (5,7)-(5,8) = "("
+ ├── rparen_loc: (5,11)-(5,12) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (5,26)-(5,29) = "end"
diff --git a/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt b/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt
new file mode 100644
index 0000000000..c06818a98b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(1,45))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,45))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,45))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,20))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,8)-(1,16))
+ │ │ ├── flags: ∅
+ │ │ └── name: :argument
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,18)-(1,20))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,18)-(1,20) = "**"
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,23)-(1,40))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,23)-(1,40))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,23)-(1,26) = "bar"
+ │ ├── opening_loc: (1,26)-(1,27) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,27)-(1,39))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ LocalVariableReadNode (location: (1,27)-(1,35))
+ │ │ │ ├── name: :argument
+ │ │ │ └── depth: 0
+ │ │ └── @ KeywordHashNode (location: (1,37)-(1,39))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (1,37)-(1,39))
+ │ │ ├── value: ∅
+ │ │ └── operator_loc: (1,37)-(1,39) = "**"
+ │ ├── closing_loc: (1,39)-(1,40) = ")"
+ │ └── block: ∅
+ ├── locals: [:argument]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,20)-(1,21) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,42)-(1,45) = "end"
diff --git a/test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt b/test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt
new file mode 100644
index 0000000000..367fad7fec
--- /dev/null
+++ b/test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,43))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,43))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,43))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,19))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (1,8)-(1,16))
+ │ │ ├── flags: ∅
+ │ │ └── name: :argument
+ │ ├── optionals: (length: 0)
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (1,18)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,18)-(1,19) = "*"
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,22)-(1,38))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,22)-(1,38))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,22)-(1,25) = "bar"
+ │ ├── opening_loc: (1,25)-(1,26) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,26)-(1,37))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ LocalVariableReadNode (location: (1,26)-(1,34))
+ │ │ │ ├── name: :argument
+ │ │ │ └── depth: 0
+ │ │ └── @ SplatNode (location: (1,36)-(1,37))
+ │ │ ├── operator_loc: (1,36)-(1,37) = "*"
+ │ │ └── expression: ∅
+ │ ├── closing_loc: (1,37)-(1,38) = ")"
+ │ └── block: ∅
+ ├── locals: [:argument]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,19)-(1,20) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,40)-(1,43) = "end"
diff --git a/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt b/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt
new file mode 100644
index 0000000000..adaf111fd7
--- /dev/null
+++ b/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt
@@ -0,0 +1,52 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,25))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,10))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,8)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,8)-(1,10) = "**"
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,13)-(1,20))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,13)-(1,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,13)-(1,16) = "bar"
+ │ ├── opening_loc: (1,16)-(1,17) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,17)-(1,19))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,17)-(1,19))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (1,17)-(1,19))
+ │ │ ├── value: ∅
+ │ │ └── operator_loc: (1,17)-(1,19) = "**"
+ │ ├── closing_loc: (1,19)-(1,20) = ")"
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,10)-(1,11) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,22)-(1,25) = "end"
diff --git a/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
new file mode 100644
index 0000000000..a03421455c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt
@@ -0,0 +1,63 @@
+@ ProgramNode (location: (1,0)-(1,41))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,41))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,41))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,10))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,8)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,8)-(1,10) = "**"
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,13)-(1,36))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,13)-(1,36))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,13)-(1,16) = "bar"
+ │ ├── opening_loc: (1,16)-(1,17) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,17)-(1,35))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,17)-(1,35))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 2)
+ │ │ ├── @ AssocSplatNode (location: (1,17)-(1,19))
+ │ │ │ ├── value: ∅
+ │ │ │ └── operator_loc: (1,17)-(1,19) = "**"
+ │ │ └── @ AssocNode (location: (1,21)-(1,35))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,21)-(1,30))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,21)-(1,29) = "from_foo"
+ │ │ │ ├── closing_loc: (1,29)-(1,30) = ":"
+ │ │ │ └── unescaped: "from_foo"
+ │ │ ├── value:
+ │ │ │ @ TrueNode (location: (1,31)-(1,35))
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: (1,35)-(1,36) = ")"
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,10)-(1,11) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,38)-(1,41) = "end"
diff --git a/test/prism/snapshots/whitequark/forwarded_restarg.txt b/test/prism/snapshots/whitequark/forwarded_restarg.txt
new file mode 100644
index 0000000000..17ff8894af
--- /dev/null
+++ b/test/prism/snapshots/whitequark/forwarded_restarg.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,23))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,9))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (1,8)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,8)-(1,9) = "*"
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,12)-(1,18))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,12)-(1,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,12)-(1,15) = "bar"
+ │ ├── opening_loc: (1,15)-(1,16) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,16)-(1,17))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ SplatNode (location: (1,16)-(1,17))
+ │ │ ├── operator_loc: (1,16)-(1,17) = "*"
+ │ │ └── expression: ∅
+ │ ├── closing_loc: (1,17)-(1,18) = ")"
+ │ └── block: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,9)-(1,10) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,20)-(1,23) = "end"
diff --git a/test/prism/snapshots/whitequark/gvar.txt b/test/prism/snapshots/whitequark/gvar.txt
new file mode 100644
index 0000000000..f4401c4389
--- /dev/null
+++ b/test/prism/snapshots/whitequark/gvar.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ GlobalVariableReadNode (location: (1,0)-(1,4))
+ └── name: :$foo
diff --git a/test/prism/snapshots/whitequark/gvasgn.txt b/test/prism/snapshots/whitequark/gvasgn.txt
new file mode 100644
index 0000000000..fc044054d8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/gvasgn.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ GlobalVariableWriteNode (location: (1,0)-(1,9))
+ ├── name: :$var
+ ├── name_loc: (1,0)-(1,4) = "$var"
+ ├── value:
+ │ @ IntegerNode (location: (1,7)-(1,9))
+ │ ├── flags: decimal
+ │ └── value: 10
+ └── operator_loc: (1,5)-(1,6) = "="
diff --git a/test/prism/snapshots/whitequark/hash_empty.txt b/test/prism/snapshots/whitequark/hash_empty.txt
new file mode 100644
index 0000000000..38a2c15a9a
--- /dev/null
+++ b/test/prism/snapshots/whitequark/hash_empty.txt
@@ -0,0 +1,9 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,0)-(1,3))
+ ├── opening_loc: (1,0)-(1,1) = "{"
+ ├── elements: (length: 0)
+ └── closing_loc: (1,2)-(1,3) = "}"
diff --git a/test/prism/snapshots/whitequark/hash_hashrocket.txt b/test/prism/snapshots/whitequark/hash_hashrocket.txt
new file mode 100644
index 0000000000..e661a7b048
--- /dev/null
+++ b/test/prism/snapshots/whitequark/hash_hashrocket.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(3,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,25))
+ └── body: (length: 2)
+ ├── @ HashNode (location: (1,0)-(1,10))
+ │ ├── opening_loc: (1,0)-(1,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,2)-(1,8))
+ │ │ ├── key:
+ │ │ │ @ IntegerNode (location: (1,2)-(1,3))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (1,4)-(1,6) = "=>"
+ │ └── closing_loc: (1,9)-(1,10) = "}"
+ └── @ HashNode (location: (3,0)-(3,25))
+ ├── opening_loc: (3,0)-(3,1) = "{"
+ ├── elements: (length: 2)
+ │ ├── @ AssocNode (location: (3,2)-(3,8))
+ │ │ ├── key:
+ │ │ │ @ IntegerNode (location: (3,2)-(3,3))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,7)-(3,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: (3,4)-(3,6) = "=>"
+ │ └── @ AssocNode (location: (3,10)-(3,23))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (3,10)-(3,14))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,10)-(3,11) = ":"
+ │ │ ├── value_loc: (3,11)-(3,14) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── value:
+ │ │ @ StringNode (location: (3,18)-(3,23))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (3,18)-(3,19) = "\""
+ │ │ ├── content_loc: (3,19)-(3,22) = "bar"
+ │ │ ├── closing_loc: (3,22)-(3,23) = "\""
+ │ │ └── unescaped: "bar"
+ │ └── operator_loc: (3,15)-(3,17) = "=>"
+ └── closing_loc: (3,24)-(3,25) = "}"
diff --git a/test/prism/snapshots/whitequark/hash_kwsplat.txt b/test/prism/snapshots/whitequark/hash_kwsplat.txt
new file mode 100644
index 0000000000..a5d12174cc
--- /dev/null
+++ b/test/prism/snapshots/whitequark/hash_kwsplat.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,0)-(1,17))
+ ├── opening_loc: (1,0)-(1,1) = "{"
+ ├── elements: (length: 2)
+ │ ├── @ AssocNode (location: (1,2)-(1,8))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,2)-(1,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,2)-(1,5) = "foo"
+ │ │ │ ├── closing_loc: (1,5)-(1,6) = ":"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: ∅
+ │ └── @ AssocSplatNode (location: (1,10)-(1,15))
+ │ ├── value:
+ │ │ @ CallNode (location: (1,12)-(1,15))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,12)-(1,15) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,10)-(1,12) = "**"
+ └── closing_loc: (1,16)-(1,17) = "}"
diff --git a/test/prism/snapshots/whitequark/hash_label.txt b/test/prism/snapshots/whitequark/hash_label.txt
new file mode 100644
index 0000000000..fdf7a21ed0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/hash_label.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,0)-(1,10))
+ ├── opening_loc: (1,0)-(1,1) = "{"
+ ├── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,2)-(1,8))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,2)-(1,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,2)-(1,5) = "foo"
+ │ │ ├── closing_loc: (1,5)-(1,6) = ":"
+ │ │ └── unescaped: "foo"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,7)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── operator_loc: ∅
+ └── closing_loc: (1,9)-(1,10) = "}"
diff --git a/test/prism/snapshots/whitequark/hash_label_end.txt b/test/prism/snapshots/whitequark/hash_label_end.txt
new file mode 100644
index 0000000000..88b70d38e2
--- /dev/null
+++ b/test/prism/snapshots/whitequark/hash_label_end.txt
@@ -0,0 +1,100 @@
+@ ProgramNode (location: (1,0)-(5,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,22))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :f
+ │ ├── message_loc: (1,0)-(1,1) = "f"
+ │ ├── opening_loc: (1,1)-(1,2) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IfNode (location: (1,2)-(1,11))
+ │ │ ├── if_keyword_loc: ∅
+ │ │ ├── predicate:
+ │ │ │ @ CallNode (location: (1,2)-(1,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (1,2)-(1,3) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: (1,4)-(1,5) = "?"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,6)-(1,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ StringNode (location: (1,6)-(1,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,6)-(1,7) = "\""
+ │ │ │ ├── content_loc: (1,7)-(1,8) = "a"
+ │ │ │ ├── closing_loc: (1,8)-(1,9) = "\""
+ │ │ │ └── unescaped: "a"
+ │ │ ├── consequent:
+ │ │ │ @ ElseNode (location: (1,9)-(1,11))
+ │ │ │ ├── else_keyword_loc: (1,9)-(1,10) = ":"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,10)-(1,11))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── end_keyword_loc: ∅
+ │ │ └── end_keyword_loc: ∅
+ │ ├── closing_loc: (1,11)-(1,12) = ")"
+ │ └── block: ∅
+ ├── @ HashNode (location: (3,0)-(3,12))
+ │ ├── opening_loc: (3,0)-(3,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (3,2)-(3,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (3,2)-(3,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (3,2)-(3,3) = "'"
+ │ │ │ ├── value_loc: (3,3)-(3,6) = "foo"
+ │ │ │ ├── closing_loc: (3,6)-(3,8) = "':"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (3,9)-(3,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (3,11)-(3,12) = "}"
+ └── @ HashNode (location: (5,0)-(5,22))
+ ├── opening_loc: (5,0)-(5,1) = "{"
+ ├── elements: (length: 2)
+ │ ├── @ AssocNode (location: (5,2)-(5,10))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (5,2)-(5,8))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (5,2)-(5,3) = "'"
+ │ │ │ ├── value_loc: (5,3)-(5,6) = "foo"
+ │ │ │ ├── closing_loc: (5,6)-(5,8) = "':"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (5,9)-(5,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── operator_loc: ∅
+ │ └── @ AssocNode (location: (5,12)-(5,21))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (5,12)-(5,18))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,12)-(5,13) = "'"
+ │ │ ├── value_loc: (5,13)-(5,16) = "bar"
+ │ │ ├── closing_loc: (5,16)-(5,18) = "':"
+ │ │ └── unescaped: "bar"
+ │ ├── value:
+ │ │ @ HashNode (location: (5,19)-(5,21))
+ │ │ ├── opening_loc: (5,19)-(5,20) = "{"
+ │ │ ├── elements: (length: 0)
+ │ │ └── closing_loc: (5,20)-(5,21) = "}"
+ │ └── operator_loc: ∅
+ └── closing_loc: (5,21)-(5,22) = "}"
diff --git a/test/prism/snapshots/whitequark/hash_pair_value_omission.txt b/test/prism/snapshots/whitequark/hash_pair_value_omission.txt
new file mode 100644
index 0000000000..455ba48407
--- /dev/null
+++ b/test/prism/snapshots/whitequark/hash_pair_value_omission.txt
@@ -0,0 +1,97 @@
+@ ProgramNode (location: (1,0)-(5,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,7))
+ └── body: (length: 3)
+ ├── @ HashNode (location: (1,0)-(1,6))
+ │ ├── opening_loc: (1,0)-(1,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,1)-(1,5))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,1)-(1,5))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,1)-(1,4) = "BAR"
+ │ │ │ ├── closing_loc: (1,4)-(1,5) = ":"
+ │ │ │ └── unescaped: "BAR"
+ │ │ ├── value:
+ │ │ │ @ ImplicitNode (location: (1,1)-(1,5))
+ │ │ │ └── value:
+ │ │ │ @ ConstantReadNode (location: (1,1)-(1,5))
+ │ │ │ └── name: :BAR
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (1,5)-(1,6) = "}"
+ ├── @ HashNode (location: (3,0)-(3,8))
+ │ ├── opening_loc: (3,0)-(3,1) = "{"
+ │ ├── elements: (length: 2)
+ │ │ ├── @ AssocNode (location: (3,1)-(3,3))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (3,1)-(3,3))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (3,1)-(3,2) = "a"
+ │ │ │ │ ├── closing_loc: (3,2)-(3,3) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (3,1)-(3,3))
+ │ │ │ │ └── value:
+ │ │ │ │ @ CallNode (location: (3,1)-(3,3))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── message_loc: (3,1)-(3,2) = "a"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── operator_loc: ∅
+ │ │ └── @ AssocNode (location: (3,5)-(3,7))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (3,5)-(3,7))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (3,5)-(3,6) = "b"
+ │ │ │ ├── closing_loc: (3,6)-(3,7) = ":"
+ │ │ │ └── unescaped: "b"
+ │ │ ├── value:
+ │ │ │ @ ImplicitNode (location: (3,5)-(3,7))
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (3,5)-(3,7))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (3,5)-(3,6) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (3,7)-(3,8) = "}"
+ └── @ HashNode (location: (5,0)-(5,7))
+ ├── opening_loc: (5,0)-(5,1) = "{"
+ ├── elements: (length: 1)
+ │ └── @ AssocNode (location: (5,1)-(5,6))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (5,1)-(5,6))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (5,1)-(5,5) = "puts"
+ │ │ ├── closing_loc: (5,5)-(5,6) = ":"
+ │ │ └── unescaped: "puts"
+ │ ├── value:
+ │ │ @ ImplicitNode (location: (5,1)-(5,6))
+ │ │ └── value:
+ │ │ @ CallNode (location: (5,1)-(5,6))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :puts
+ │ │ ├── message_loc: (5,1)-(5,5) = "puts"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: ∅
+ └── closing_loc: (5,6)-(5,7) = "}"
diff --git a/test/prism/snapshots/whitequark/heredoc.txt b/test/prism/snapshots/whitequark/heredoc.txt
new file mode 100644
index 0000000000..86543097ee
--- /dev/null
+++ b/test/prism/snapshots/whitequark/heredoc.txt
@@ -0,0 +1,23 @@
+@ ProgramNode (location: (1,0)-(11,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,8))
+ └── body: (length: 3)
+ ├── @ StringNode (location: (1,0)-(1,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,8) = "<<'HERE'"
+ │ ├── content_loc: (2,0)-(4,0) = "foo\nbar\n"
+ │ ├── closing_loc: (4,0)-(5,0) = "HERE\n"
+ │ └── unescaped: "foo\nbar\n"
+ ├── @ StringNode (location: (6,0)-(6,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (6,0)-(6,6) = "<<HERE"
+ │ ├── content_loc: (7,0)-(9,0) = "foo\nbar\n"
+ │ ├── closing_loc: (9,0)-(10,0) = "HERE\n"
+ │ └── unescaped: "foo\nbar\n"
+ └── @ XStringNode (location: (11,0)-(11,8))
+ ├── flags: ∅
+ ├── opening_loc: (11,0)-(11,8) = "<<`HERE`"
+ ├── content_loc: (12,0)-(14,0) = "foo\nbar\n"
+ ├── closing_loc: (14,0)-(15,0) = "HERE\n"
+ └── unescaped: "foo\nbar\n"
diff --git a/test/prism/snapshots/whitequark/if.txt b/test/prism/snapshots/whitequark/if.txt
new file mode 100644
index 0000000000..809a100f8c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/if.txt
@@ -0,0 +1,63 @@
+@ ProgramNode (location: (1,0)-(3,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,16))
+ └── body: (length: 2)
+ ├── @ IfNode (location: (1,0)-(1,20))
+ │ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,3)-(1,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,3)-(1,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (1,7)-(1,11) = "then"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,12)-(1,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,12)-(1,15))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,12)-(1,15) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (1,17)-(1,20) = "end"
+ └── @ IfNode (location: (3,0)-(3,16))
+ ├── if_keyword_loc: (3,0)-(3,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (3,3)-(3,6))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,3)-(3,6) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (3,8)-(3,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (3,8)-(3,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,8)-(3,11) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (3,13)-(3,16) = "end"
diff --git a/test/prism/snapshots/whitequark/if_else.txt b/test/prism/snapshots/whitequark/if_else.txt
new file mode 100644
index 0000000000..c7dab47f13
--- /dev/null
+++ b/test/prism/snapshots/whitequark/if_else.txt
@@ -0,0 +1,95 @@
+@ ProgramNode (location: (1,0)-(3,26))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,26))
+ └── body: (length: 2)
+ ├── @ IfNode (location: (1,0)-(1,30))
+ │ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,3)-(1,6))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,3)-(1,6) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (1,7)-(1,11) = "then"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,12)-(1,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,12)-(1,15))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,12)-(1,15) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (1,17)-(1,30))
+ │ │ ├── else_keyword_loc: (1,17)-(1,21) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,22)-(1,25))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,22)-(1,25))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (1,22)-(1,25) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (1,27)-(1,30) = "end"
+ │ └── end_keyword_loc: (1,27)-(1,30) = "end"
+ └── @ IfNode (location: (3,0)-(3,26))
+ ├── if_keyword_loc: (3,0)-(3,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (3,3)-(3,6))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,3)-(3,6) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (3,8)-(3,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (3,8)-(3,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,8)-(3,11) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent:
+ │ @ ElseNode (location: (3,13)-(3,26))
+ │ ├── else_keyword_loc: (3,13)-(3,17) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,18)-(3,21))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,18)-(3,21))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (3,18)-(3,21) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (3,23)-(3,26) = "end"
+ └── end_keyword_loc: (3,23)-(3,26) = "end"
diff --git a/test/prism/snapshots/whitequark/if_elsif.txt b/test/prism/snapshots/whitequark/if_elsif.txt
new file mode 100644
index 0000000000..1bd1ab7f42
--- /dev/null
+++ b/test/prism/snapshots/whitequark/if_elsif.txt
@@ -0,0 +1,65 @@
+@ ProgramNode (location: (1,0)-(1,38))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,38))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,38))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (1,3)-(1,6))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,3)-(1,6) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (1,8)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,8)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,8)-(1,11) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent:
+ │ @ IfNode (location: (1,13)-(1,38))
+ │ ├── if_keyword_loc: (1,13)-(1,18) = "elsif"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,19)-(1,22))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (1,19)-(1,22) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,24)-(1,25))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,24)-(1,25))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (1,27)-(1,38))
+ │ │ ├── else_keyword_loc: (1,27)-(1,31) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,32)-(1,33))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,32)-(1,33))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── end_keyword_loc: (1,35)-(1,38) = "end"
+ │ └── end_keyword_loc: (1,35)-(1,38) = "end"
+ └── end_keyword_loc: (1,35)-(1,38) = "end"
diff --git a/test/prism/snapshots/whitequark/if_masgn__24.txt b/test/prism/snapshots/whitequark/if_masgn__24.txt
new file mode 100644
index 0000000000..c76a93574d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/if_masgn__24.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,20))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ ParenthesesNode (location: (1,3)-(1,15))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,4)-(1,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ MultiWriteNode (location: (1,4)-(1,14))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (1,4)-(1,5))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (1,7)-(1,8))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── operator_loc: (1,9)-(1,10) = "="
+ │ │ └── value:
+ │ │ @ CallNode (location: (1,11)-(1,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,11)-(1,14) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ └── closing_loc: (1,14)-(1,15) = ")"
+ ├── then_keyword_loc: ∅
+ ├── statements: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (1,17)-(1,20) = "end"
diff --git a/test/prism/snapshots/whitequark/if_mod.txt b/test/prism/snapshots/whitequark/if_mod.txt
new file mode 100644
index 0000000000..241918f020
--- /dev/null
+++ b/test/prism/snapshots/whitequark/if_mod.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,10))
+ ├── if_keyword_loc: (1,4)-(1,6) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (1,7)-(1,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,7)-(1,10) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (1,0)-(1,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,0)-(1,3) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/if_nl_then.txt b/test/prism/snapshots/whitequark/if_nl_then.txt
new file mode 100644
index 0000000000..fbbafe7390
--- /dev/null
+++ b/test/prism/snapshots/whitequark/if_nl_then.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(2,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,12))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(2,12))
+ ├── if_keyword_loc: (1,0)-(1,2) = "if"
+ ├── predicate:
+ │ @ CallNode (location: (1,3)-(1,6))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,3)-(1,6) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: (2,0)-(2,4) = "then"
+ ├── statements:
+ │ @ StatementsNode (location: (2,5)-(2,8))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (2,5)-(2,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (2,5)-(2,8) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (2,9)-(2,12) = "end"
diff --git a/test/prism/snapshots/whitequark/int.txt b/test/prism/snapshots/whitequark/int.txt
new file mode 100644
index 0000000000..6fee32f117
--- /dev/null
+++ b/test/prism/snapshots/whitequark/int.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(5,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,2))
+ └── body: (length: 3)
+ ├── @ IntegerNode (location: (1,0)-(1,3))
+ │ ├── flags: decimal
+ │ └── value: 42
+ ├── @ IntegerNode (location: (3,0)-(3,3))
+ │ ├── flags: decimal
+ │ └── value: -42
+ └── @ IntegerNode (location: (5,0)-(5,2))
+ ├── flags: decimal
+ └── value: 42
diff --git a/test/prism/snapshots/whitequark/int___LINE__.txt b/test/prism/snapshots/whitequark/int___LINE__.txt
new file mode 100644
index 0000000000..bf2ea47102
--- /dev/null
+++ b/test/prism/snapshots/whitequark/int___LINE__.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ SourceLineNode (location: (1,0)-(1,8))
diff --git a/test/prism/snapshots/whitequark/interp_digit_var.txt b/test/prism/snapshots/whitequark/interp_digit_var.txt
new file mode 100644
index 0000000000..09d9098105
--- /dev/null
+++ b/test/prism/snapshots/whitequark/interp_digit_var.txt
@@ -0,0 +1,273 @@
+@ ProgramNode (location: (1,1)-(85,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,1)-(85,9))
+ └── body: (length: 38)
+ ├── @ StringNode (location: (1,1)-(1,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,1)-(1,2) = "\""
+ │ ├── content_loc: (1,2)-(1,5) = "\#@1"
+ │ ├── closing_loc: (1,5)-(1,6) = "\""
+ │ └── unescaped: "\#@1"
+ ├── @ StringNode (location: (3,1)-(3,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (3,1)-(3,2) = "\""
+ │ ├── content_loc: (3,2)-(3,6) = "\#@@1"
+ │ ├── closing_loc: (3,6)-(3,7) = "\""
+ │ └── unescaped: "\#@@1"
+ ├── @ ArrayNode (location: (5,1)-(5,8))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ SymbolNode (location: (5,4)-(5,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (5,4)-(5,7) = "\#@1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#@1"
+ │ ├── opening_loc: (5,1)-(5,4) = "%I["
+ │ └── closing_loc: (5,7)-(5,8) = "]"
+ ├── @ ArrayNode (location: (7,1)-(7,9))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ SymbolNode (location: (7,4)-(7,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (7,4)-(7,8) = "\#@@1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#@@1"
+ │ ├── opening_loc: (7,1)-(7,4) = "%I["
+ │ └── closing_loc: (7,8)-(7,9) = "]"
+ ├── @ StringNode (location: (9,1)-(9,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (9,1)-(9,4) = "%Q{"
+ │ ├── content_loc: (9,4)-(9,7) = "\#@1"
+ │ ├── closing_loc: (9,7)-(9,8) = "}"
+ │ └── unescaped: "\#@1"
+ ├── @ StringNode (location: (11,1)-(11,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (11,1)-(11,4) = "%Q{"
+ │ ├── content_loc: (11,4)-(11,8) = "\#@@1"
+ │ ├── closing_loc: (11,8)-(11,9) = "}"
+ │ └── unescaped: "\#@@1"
+ ├── @ ArrayNode (location: (13,1)-(13,8))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (13,4)-(13,7))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (13,4)-(13,7) = "\#@1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#@1"
+ │ ├── opening_loc: (13,1)-(13,4) = "%W["
+ │ └── closing_loc: (13,7)-(13,8) = "]"
+ ├── @ ArrayNode (location: (15,1)-(15,9))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (15,4)-(15,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (15,4)-(15,8) = "\#@@1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#@@1"
+ │ ├── opening_loc: (15,1)-(15,4) = "%W["
+ │ └── closing_loc: (15,8)-(15,9) = "]"
+ ├── @ ArrayNode (location: (17,1)-(17,10))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ SymbolNode (location: (17,5)-(17,8))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (17,5)-(17,8) = "\#@1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#@1"
+ │ ├── opening_loc: (17,1)-(17,4) = "%i["
+ │ └── closing_loc: (17,9)-(17,10) = "]"
+ ├── @ ArrayNode (location: (19,1)-(19,11))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ SymbolNode (location: (19,5)-(19,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (19,5)-(19,9) = "\#@@1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#@@1"
+ │ ├── opening_loc: (19,1)-(19,4) = "%i["
+ │ └── closing_loc: (19,10)-(19,11) = "]"
+ ├── @ StringNode (location: (21,1)-(21,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (21,1)-(21,4) = "%q{"
+ │ ├── content_loc: (21,4)-(21,7) = "\#@1"
+ │ ├── closing_loc: (21,7)-(21,8) = "}"
+ │ └── unescaped: "\#@1"
+ ├── @ StringNode (location: (23,1)-(23,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (23,1)-(23,4) = "%q{"
+ │ ├── content_loc: (23,4)-(23,8) = "\#@@1"
+ │ ├── closing_loc: (23,8)-(23,9) = "}"
+ │ └── unescaped: "\#@@1"
+ ├── @ RegularExpressionNode (location: (25,1)-(25,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (25,1)-(25,4) = "%r{"
+ │ ├── content_loc: (25,4)-(25,7) = "\#@1"
+ │ ├── closing_loc: (25,7)-(25,8) = "}"
+ │ └── unescaped: "\#@1"
+ ├── @ RegularExpressionNode (location: (27,1)-(27,9))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (27,1)-(27,4) = "%r{"
+ │ ├── content_loc: (27,4)-(27,8) = "\#@@1"
+ │ ├── closing_loc: (27,8)-(27,9) = "}"
+ │ └── unescaped: "\#@@1"
+ ├── @ SymbolNode (location: (29,1)-(29,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (29,1)-(29,4) = "%s{"
+ │ ├── value_loc: (29,4)-(29,7) = "\#@1"
+ │ ├── closing_loc: (29,7)-(29,8) = "}"
+ │ └── unescaped: "\#@1"
+ ├── @ SymbolNode (location: (31,1)-(31,9))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (31,1)-(31,4) = "%s{"
+ │ ├── value_loc: (31,4)-(31,8) = "\#@@1"
+ │ ├── closing_loc: (31,8)-(31,9) = "}"
+ │ └── unescaped: "\#@@1"
+ ├── @ ArrayNode (location: (33,1)-(33,10))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (33,5)-(33,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (33,5)-(33,8) = "\#@1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#@1"
+ │ ├── opening_loc: (33,1)-(33,4) = "%w["
+ │ └── closing_loc: (33,9)-(33,10) = "]"
+ ├── @ ArrayNode (location: (35,1)-(35,11))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (35,5)-(35,9))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (35,5)-(35,9) = "\#@@1"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "\#@@1"
+ │ ├── opening_loc: (35,1)-(35,4) = "%w["
+ │ └── closing_loc: (35,10)-(35,11) = "]"
+ ├── @ XStringNode (location: (37,1)-(37,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (37,1)-(37,4) = "%x{"
+ │ ├── content_loc: (37,4)-(37,7) = "\#@1"
+ │ ├── closing_loc: (37,7)-(37,8) = "}"
+ │ └── unescaped: "\#@1"
+ ├── @ XStringNode (location: (39,1)-(39,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (39,1)-(39,4) = "%x{"
+ │ ├── content_loc: (39,4)-(39,8) = "\#@@1"
+ │ ├── closing_loc: (39,8)-(39,9) = "}"
+ │ └── unescaped: "\#@@1"
+ ├── @ StringNode (location: (41,1)-(41,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (41,1)-(41,3) = "%{"
+ │ ├── content_loc: (41,3)-(41,6) = "\#@1"
+ │ ├── closing_loc: (41,6)-(41,7) = "}"
+ │ └── unescaped: "\#@1"
+ ├── @ StringNode (location: (43,1)-(43,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (43,1)-(43,3) = "%{"
+ │ ├── content_loc: (43,3)-(43,7) = "\#@@1"
+ │ ├── closing_loc: (43,7)-(43,8) = "}"
+ │ └── unescaped: "\#@@1"
+ ├── @ StringNode (location: (45,1)-(45,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (45,1)-(45,2) = "'"
+ │ ├── content_loc: (45,2)-(45,5) = "\#@1"
+ │ ├── closing_loc: (45,5)-(45,6) = "'"
+ │ └── unescaped: "\#@1"
+ ├── @ StringNode (location: (47,1)-(47,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (47,1)-(47,2) = "'"
+ │ ├── content_loc: (47,2)-(47,6) = "\#@@1"
+ │ ├── closing_loc: (47,6)-(47,7) = "'"
+ │ └── unescaped: "\#@@1"
+ ├── @ RegularExpressionNode (location: (49,1)-(49,6))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (49,1)-(49,2) = "/"
+ │ ├── content_loc: (49,2)-(49,5) = "\#@1"
+ │ ├── closing_loc: (49,5)-(49,6) = "/"
+ │ └── unescaped: "\#@1"
+ ├── @ RegularExpressionNode (location: (51,1)-(51,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (51,1)-(51,2) = "/"
+ │ ├── content_loc: (51,2)-(51,6) = "\#@@1"
+ │ ├── closing_loc: (51,6)-(51,7) = "/"
+ │ └── unescaped: "\#@@1"
+ ├── @ SymbolNode (location: (53,1)-(53,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (53,1)-(53,3) = ":\""
+ │ ├── value_loc: (53,3)-(53,6) = "\#@1"
+ │ ├── closing_loc: (53,6)-(53,7) = "\""
+ │ └── unescaped: "\#@1"
+ ├── @ SymbolNode (location: (55,1)-(55,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (55,1)-(55,3) = ":\""
+ │ ├── value_loc: (55,3)-(55,7) = "\#@@1"
+ │ ├── closing_loc: (55,7)-(55,8) = "\""
+ │ └── unescaped: "\#@@1"
+ ├── @ SymbolNode (location: (57,1)-(57,7))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (57,1)-(57,3) = ":'"
+ │ ├── value_loc: (57,3)-(57,6) = "\#@1"
+ │ ├── closing_loc: (57,6)-(57,7) = "'"
+ │ └── unescaped: "\#@1"
+ ├── @ SymbolNode (location: (59,1)-(59,8))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (59,1)-(59,3) = ":'"
+ │ ├── value_loc: (59,3)-(59,7) = "\#@@1"
+ │ ├── closing_loc: (59,7)-(59,8) = "'"
+ │ └── unescaped: "\#@@1"
+ ├── @ XStringNode (location: (61,1)-(61,6))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (61,1)-(61,2) = "`"
+ │ ├── content_loc: (61,2)-(61,5) = "\#@1"
+ │ ├── closing_loc: (61,5)-(61,6) = "`"
+ │ └── unescaped: "\#@1"
+ ├── @ XStringNode (location: (63,1)-(63,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (63,1)-(63,2) = "`"
+ │ ├── content_loc: (63,2)-(63,6) = "\#@@1"
+ │ ├── closing_loc: (63,6)-(63,7) = "`"
+ │ └── unescaped: "\#@@1"
+ ├── @ StringNode (location: (65,0)-(65,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (65,0)-(65,9) = "<<-\"HERE\""
+ │ ├── content_loc: (66,0)-(67,0) = "\#@1\n"
+ │ ├── closing_loc: (67,0)-(68,0) = "HERE\n"
+ │ └── unescaped: "\#@1\n"
+ ├── @ StringNode (location: (69,0)-(69,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (69,0)-(69,9) = "<<-\"HERE\""
+ │ ├── content_loc: (70,0)-(71,0) = "\#@@1\n"
+ │ ├── closing_loc: (71,0)-(72,0) = "HERE\n"
+ │ └── unescaped: "\#@@1\n"
+ ├── @ StringNode (location: (73,0)-(73,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (73,0)-(73,9) = "<<-'HERE'"
+ │ ├── content_loc: (74,0)-(75,0) = "\#@1\n"
+ │ ├── closing_loc: (75,0)-(76,0) = "HERE\n"
+ │ └── unescaped: "\#@1\n"
+ ├── @ StringNode (location: (77,0)-(77,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (77,0)-(77,9) = "<<-'HERE'"
+ │ ├── content_loc: (78,0)-(79,0) = "\#@@1\n"
+ │ ├── closing_loc: (79,0)-(80,0) = "HERE\n"
+ │ └── unescaped: "\#@@1\n"
+ ├── @ XStringNode (location: (81,0)-(81,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (81,0)-(81,9) = "<<-`HERE`"
+ │ ├── content_loc: (82,0)-(83,0) = "\#@1\n"
+ │ ├── closing_loc: (83,0)-(84,0) = "HERE\n"
+ │ └── unescaped: "\#@1\n"
+ └── @ XStringNode (location: (85,0)-(85,9))
+ ├── flags: ∅
+ ├── opening_loc: (85,0)-(85,9) = "<<-`HERE`"
+ ├── content_loc: (86,0)-(87,0) = "\#@@1\n"
+ ├── closing_loc: (87,0)-(88,0) = "HERE\n"
+ └── unescaped: "\#@@1\n"
diff --git a/test/prism/snapshots/whitequark/ivar.txt b/test/prism/snapshots/whitequark/ivar.txt
new file mode 100644
index 0000000000..9c70e6e959
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ivar.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ InstanceVariableReadNode (location: (1,0)-(1,4))
+ └── name: :@foo
diff --git a/test/prism/snapshots/whitequark/ivasgn.txt b/test/prism/snapshots/whitequark/ivasgn.txt
new file mode 100644
index 0000000000..2b57f39554
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ivasgn.txt
@@ -0,0 +1,13 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ InstanceVariableWriteNode (location: (1,0)-(1,9))
+ ├── name: :@var
+ ├── name_loc: (1,0)-(1,4) = "@var"
+ ├── value:
+ │ @ IntegerNode (location: (1,7)-(1,9))
+ │ ├── flags: decimal
+ │ └── value: 10
+ └── operator_loc: (1,5)-(1,6) = "="
diff --git a/test/prism/snapshots/whitequark/keyword_argument_omission.txt b/test/prism/snapshots/whitequark/keyword_argument_omission.txt
new file mode 100644
index 0000000000..62e8fecf4e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/keyword_argument_omission.txt
@@ -0,0 +1,65 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (1,0)-(1,3) = "foo"
+ ├── opening_loc: (1,3)-(1,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,4)-(1,10))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 2)
+ │ ├── @ AssocNode (location: (1,4)-(1,6))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,4)-(1,6))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,4)-(1,5) = "a"
+ │ │ │ ├── closing_loc: (1,5)-(1,6) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ ImplicitNode (location: (1,4)-(1,6))
+ │ │ │ └── value:
+ │ │ │ @ CallNode (location: (1,4)-(1,6))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :a
+ │ │ │ ├── message_loc: (1,4)-(1,5) = "a"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: ∅
+ │ └── @ AssocNode (location: (1,8)-(1,10))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,8)-(1,10))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,8)-(1,9) = "b"
+ │ │ ├── closing_loc: (1,9)-(1,10) = ":"
+ │ │ └── unescaped: "b"
+ │ ├── value:
+ │ │ @ ImplicitNode (location: (1,8)-(1,10))
+ │ │ └── value:
+ │ │ @ CallNode (location: (1,8)-(1,10))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,8)-(1,9) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: ∅
+ ├── closing_loc: (1,10)-(1,11) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/kwarg.txt b/test/prism/snapshots/whitequark/kwarg.txt
new file mode 100644
index 0000000000..5969402356
--- /dev/null
+++ b/test/prism/snapshots/whitequark/kwarg.txt
@@ -0,0 +1,30 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,16))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,10))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ RequiredKeywordParameterNode (location: (1,6)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :foo
+ │ │ └── name_loc: (1,6)-(1,10) = "foo:"
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:foo]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,10)-(1,11) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,13)-(1,16) = "end"
diff --git a/test/prism/snapshots/whitequark/kwbegin_compstmt.txt b/test/prism/snapshots/whitequark/kwbegin_compstmt.txt
new file mode 100644
index 0000000000..376e628f8e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/kwbegin_compstmt.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,20))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,20))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,6)-(1,16))
+ │ └── body: (length: 2)
+ │ ├── @ CallNode (location: (1,6)-(1,10))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo!
+ │ │ ├── message_loc: (1,6)-(1,10) = "foo!"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ CallNode (location: (1,12)-(1,16))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar!
+ │ ├── message_loc: (1,12)-(1,16) = "bar!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,17)-(1,20) = "end"
diff --git a/test/prism/snapshots/whitequark/kwnilarg.txt b/test/prism/snapshots/whitequark/kwnilarg.txt
new file mode 100644
index 0000000000..492f817696
--- /dev/null
+++ b/test/prism/snapshots/whitequark/kwnilarg.txt
@@ -0,0 +1,84 @@
+@ ProgramNode (location: (1,0)-(5,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,13))
+ └── body: (length: 3)
+ ├── @ LambdaNode (location: (1,0)-(1,12))
+ │ ├── locals: []
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (1,10)-(1,11) = "{"
+ │ ├── closing_loc: (1,11)-(1,12) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,2)-(1,9))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,3)-(1,8))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest:
+ │ │ │ │ @ NoKeywordsParameterNode (location: (1,3)-(1,8))
+ │ │ │ │ ├── operator_loc: (1,3)-(1,5) = "**"
+ │ │ │ │ └── keyword_loc: (1,5)-(1,8) = "nil"
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ │ └── closing_loc: (1,8)-(1,9) = ")"
+ │ └── body: ∅
+ ├── @ DefNode (location: (3,0)-(3,17))
+ │ ├── name: :f
+ │ ├── name_loc: (3,4)-(3,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,6)-(3,11))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ NoKeywordsParameterNode (location: (3,6)-(3,11))
+ │ │ │ ├── operator_loc: (3,6)-(3,8) = "**"
+ │ │ │ └── keyword_loc: (3,8)-(3,11) = "nil"
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: (3,5)-(3,6) = "("
+ │ ├── rparen_loc: (3,11)-(3,12) = ")"
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,14)-(3,17) = "end"
+ └── @ CallNode (location: (5,0)-(5,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (5,0)-(5,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (5,2)-(5,13))
+ ├── locals: []
+ ├── parameters:
+ │ @ BlockParametersNode (location: (5,4)-(5,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (5,5)-(5,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest:
+ │ │ │ @ NoKeywordsParameterNode (location: (5,5)-(5,10))
+ │ │ │ ├── operator_loc: (5,5)-(5,7) = "**"
+ │ │ │ └── keyword_loc: (5,7)-(5,10) = "nil"
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (5,4)-(5,5) = "|"
+ │ └── closing_loc: (5,10)-(5,11) = "|"
+ ├── body: ∅
+ ├── opening_loc: (5,2)-(5,3) = "{"
+ └── closing_loc: (5,12)-(5,13) = "}"
diff --git a/test/prism/snapshots/whitequark/kwoptarg.txt b/test/prism/snapshots/whitequark/kwoptarg.txt
new file mode 100644
index 0000000000..9c2c4f9c4c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/kwoptarg.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,18))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,12))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,6)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (1,6)-(1,10) = "foo:"
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (1,11)-(1,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:foo]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,12)-(1,13) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,15)-(1,18) = "end"
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
new file mode 100644
index 0000000000..6d0bdfb817
--- /dev/null
+++ b/test/prism/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(1,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,28))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,28))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,16))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 1)
+ │ │ └── @ OptionalKeywordParameterNode (location: (1,6)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :a
+ │ │ ├── name_loc: (1,6)-(1,8) = "a:"
+ │ │ └── value:
+ │ │ @ NilNode (location: (1,9)-(1,12))
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,14)-(1,16))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,14)-(1,16) = "**"
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,19)-(1,24))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,19)-(1,24))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :b
+ │ ├── message_loc: (1,19)-(1,20) = "b"
+ │ ├── opening_loc: (1,20)-(1,21) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,21)-(1,23))
+ │ │ ├── flags: contains_keyword_splat
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,21)-(1,23))
+ │ │ ├── flags: ∅
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocSplatNode (location: (1,21)-(1,23))
+ │ │ ├── value: ∅
+ │ │ └── operator_loc: (1,21)-(1,23) = "**"
+ │ ├── closing_loc: (1,23)-(1,24) = ")"
+ │ └── block: ∅
+ ├── locals: [:a]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,16)-(1,17) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,25)-(1,28) = "end"
diff --git a/test/prism/snapshots/whitequark/kwrestarg_named.txt b/test/prism/snapshots/whitequark/kwrestarg_named.txt
new file mode 100644
index 0000000000..d24426aed5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/kwrestarg_named.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,17))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,11))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,6)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (1,8)-(1,11) = "foo"
+ │ │ └── operator_loc: (1,6)-(1,8) = "**"
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:foo]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,11)-(1,12) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,14)-(1,17) = "end"
diff --git a/test/prism/snapshots/whitequark/kwrestarg_unnamed.txt b/test/prism/snapshots/whitequark/kwrestarg_unnamed.txt
new file mode 100644
index 0000000000..d471e5ab09
--- /dev/null
+++ b/test/prism/snapshots/whitequark/kwrestarg_unnamed.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,14))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,8))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ KeywordRestParameterNode (location: (1,6)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,6)-(1,8) = "**"
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,8)-(1,9) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,11)-(1,14) = "end"
diff --git a/test/prism/snapshots/whitequark/lbrace_arg_after_command_args.txt b/test/prism/snapshots/whitequark/lbrace_arg_after_command_args.txt
new file mode 100644
index 0000000000..f877fcd270
--- /dev/null
+++ b/test/prism/snapshots/whitequark/lbrace_arg_after_command_args.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,0)-(1,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,22))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,22))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :let
+ ├── message_loc: (1,0)-(1,3) = "let"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,4)-(1,8))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,5)-(1,7))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,5)-(1,7))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,5)-(1,6) = ":"
+ │ │ ├── value_loc: (1,6)-(1,7) = "a"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a"
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (1,7)-(1,8) = ")"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,9)-(1,22))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,11)-(1,20))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,11)-(1,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,11)-(1,12) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,13)-(1,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,13)-(1,15) = "do"
+ │ └── closing_loc: (1,17)-(1,20) = "end"
+ ├── opening_loc: (1,9)-(1,10) = "{"
+ └── closing_loc: (1,21)-(1,22) = "}"
diff --git a/test/prism/snapshots/whitequark/lparenarg_after_lvar__since_25.txt b/test/prism/snapshots/whitequark/lparenarg_after_lvar__since_25.txt
new file mode 100644
index 0000000000..afddc9cd3c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/lparenarg_after_lvar__since_25.txt
@@ -0,0 +1,67 @@
+@ ProgramNode (location: (1,0)-(3,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,15))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,4)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,4)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ ParenthesesNode (location: (1,4)-(1,10))
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (1,5)-(1,9))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ FloatNode (location: (1,5)-(1,9))
+ │ │ │ │ └── value: -1.3
+ │ │ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ │ │ └── closing_loc: (1,9)-(1,10) = ")"
+ │ │ ├── call_operator_loc: (1,10)-(1,11) = "."
+ │ │ ├── name: :abs
+ │ │ ├── message_loc: (1,11)-(1,14) = "abs"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,15))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :meth
+ ├── message_loc: (3,0)-(3,4) = "meth"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,5)-(3,15))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (3,5)-(3,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (3,5)-(3,11))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (3,6)-(3,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ FloatNode (location: (3,6)-(3,10))
+ │ │ │ └── value: -1.3
+ │ │ ├── opening_loc: (3,5)-(3,6) = "("
+ │ │ └── closing_loc: (3,10)-(3,11) = ")"
+ │ ├── call_operator_loc: (3,11)-(3,12) = "."
+ │ ├── name: :abs
+ │ ├── message_loc: (3,12)-(3,15) = "abs"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/lvar.txt b/test/prism/snapshots/whitequark/lvar.txt
new file mode 100644
index 0000000000..afceb6a1a4
--- /dev/null
+++ b/test/prism/snapshots/whitequark/lvar.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,3))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (1,0)-(1,3) = "foo"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/lvar_injecting_match.txt b/test/prism/snapshots/whitequark/lvar_injecting_match.txt
new file mode 100644
index 0000000000..0d1df23d0d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/lvar_injecting_match.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,31))
+├── locals: [:match]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,31))
+ └── body: (length: 2)
+ ├── @ MatchWriteNode (location: (1,0)-(1,24))
+ │ ├── call:
+ │ │ @ CallNode (location: (1,0)-(1,24))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ RegularExpressionNode (location: (1,0)-(1,15))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (1,0)-(1,1) = "/"
+ │ │ │ ├── content_loc: (1,1)-(1,14) = "(?<match>bar)"
+ │ │ │ ├── closing_loc: (1,14)-(1,15) = "/"
+ │ │ │ └── unescaped: "(?<match>bar)"
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :=~
+ │ │ ├── message_loc: (1,16)-(1,18) = "=~"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,19)-(1,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ StringNode (location: (1,19)-(1,24))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── opening_loc: (1,19)-(1,20) = "'"
+ │ │ │ ├── content_loc: (1,20)-(1,23) = "bar"
+ │ │ │ ├── closing_loc: (1,23)-(1,24) = "'"
+ │ │ │ └── unescaped: "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── targets: (length: 1)
+ │ └── @ LocalVariableTargetNode (location: (1,4)-(1,9))
+ │ ├── name: :match
+ │ └── depth: 0
+ └── @ LocalVariableReadNode (location: (1,26)-(1,31))
+ ├── name: :match
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/lvasgn.txt b/test/prism/snapshots/whitequark/lvasgn.txt
new file mode 100644
index 0000000000..be35c00587
--- /dev/null
+++ b/test/prism/snapshots/whitequark/lvasgn.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: [:var]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 2)
+ ├── @ LocalVariableWriteNode (location: (1,0)-(1,8))
+ │ ├── name: :var
+ │ ├── depth: 0
+ │ ├── name_loc: (1,0)-(1,3) = "var"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,6)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ └── operator_loc: (1,4)-(1,5) = "="
+ └── @ LocalVariableReadNode (location: (1,10)-(1,13))
+ ├── name: :var
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/masgn.txt b/test/prism/snapshots/whitequark/masgn.txt
new file mode 100644
index 0000000000..32e46bfdf7
--- /dev/null
+++ b/test/prism/snapshots/whitequark/masgn.txt
@@ -0,0 +1,83 @@
+@ ProgramNode (location: (1,0)-(5,20))
+├── locals: [:foo, :bar, :baz]
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,20))
+ └── body: (length: 3)
+ ├── @ MultiWriteNode (location: (1,0)-(1,17))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (1,1)-(1,4))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,9))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (1,0)-(1,1) = "("
+ │ ├── rparen_loc: (1,9)-(1,10) = ")"
+ │ ├── operator_loc: (1,11)-(1,12) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (1,13)-(1,17))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (1,13)-(1,14))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (1,16)-(1,17))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ MultiWriteNode (location: (3,0)-(3,15))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (3,0)-(3,3))
+ │ │ │ ├── name: :foo
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (3,5)-(3,8))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (3,9)-(3,10) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (3,11)-(3,15))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 2)
+ │ │ ├── @ IntegerNode (location: (3,11)-(3,12))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ IntegerNode (location: (3,14)-(3,15))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ └── @ MultiWriteNode (location: (5,0)-(5,20))
+ ├── lefts: (length: 3)
+ │ ├── @ LocalVariableTargetNode (location: (5,0)-(5,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── @ LocalVariableTargetNode (location: (5,5)-(5,8))
+ │ │ ├── name: :bar
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (5,10)-(5,13))
+ │ ├── name: :baz
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (5,14)-(5,15) = "="
+ └── value:
+ @ ArrayNode (location: (5,16)-(5,20))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ IntegerNode (location: (5,16)-(5,17))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ IntegerNode (location: (5,19)-(5,20))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── opening_loc: ∅
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/whitequark/masgn_attr.txt b/test/prism/snapshots/whitequark/masgn_attr.txt
new file mode 100644
index 0000000000..f4f4276597
--- /dev/null
+++ b/test/prism/snapshots/whitequark/masgn_attr.txt
@@ -0,0 +1,82 @@
+@ ProgramNode (location: (1,0)-(5,18))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,18))
+ └── body: (length: 3)
+ ├── @ MultiWriteNode (location: (1,0)-(1,17))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ CallTargetNode (location: (1,0)-(1,6))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver:
+ │ │ │ │ @ SelfNode (location: (1,0)-(1,4))
+ │ │ │ ├── call_operator_loc: (1,4)-(1,5) = "."
+ │ │ │ ├── name: :A=
+ │ │ │ └── message_loc: (1,5)-(1,6) = "A"
+ │ │ └── @ LocalVariableTargetNode (location: (1,8)-(1,11))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (1,12)-(1,13) = "="
+ │ └── value:
+ │ @ LocalVariableReadNode (location: (1,14)-(1,17))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── @ MultiWriteNode (location: (3,0)-(3,24))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ CallTargetNode (location: (3,0)-(3,6))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver:
+ │ │ │ │ @ SelfNode (location: (3,0)-(3,4))
+ │ │ │ ├── call_operator_loc: (3,4)-(3,5) = "."
+ │ │ │ ├── name: :a=
+ │ │ │ └── message_loc: (3,5)-(3,6) = "a"
+ │ │ └── @ IndexTargetNode (location: (3,8)-(3,18))
+ │ │ ├── flags: attribute_write, ignore_visibility
+ │ │ ├── receiver:
+ │ │ │ @ SelfNode (location: (3,8)-(3,12))
+ │ │ ├── opening_loc: (3,12)-(3,13) = "["
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,13)-(3,17))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (3,13)-(3,14))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (3,16)-(3,17))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: (3,17)-(3,18) = "]"
+ │ │ └── block: ∅
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (3,19)-(3,20) = "="
+ │ └── value:
+ │ @ LocalVariableReadNode (location: (3,21)-(3,24))
+ │ ├── name: :foo
+ │ └── depth: 0
+ └── @ MultiWriteNode (location: (5,0)-(5,18))
+ ├── lefts: (length: 2)
+ │ ├── @ CallTargetNode (location: (5,0)-(5,7))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver:
+ │ │ │ @ SelfNode (location: (5,0)-(5,4))
+ │ │ ├── call_operator_loc: (5,4)-(5,6) = "::"
+ │ │ ├── name: :a=
+ │ │ └── message_loc: (5,6)-(5,7) = "a"
+ │ └── @ LocalVariableTargetNode (location: (5,9)-(5,12))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (5,13)-(5,14) = "="
+ └── value:
+ @ LocalVariableReadNode (location: (5,15)-(5,18))
+ ├── name: :foo
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/masgn_cmd.txt b/test/prism/snapshots/whitequark/masgn_cmd.txt
new file mode 100644
index 0000000000..1c62658ab2
--- /dev/null
+++ b/test/prism/snapshots/whitequark/masgn_cmd.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: [:foo, :bar]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,16))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,5)-(1,8))
+ │ ├── name: :bar
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,9)-(1,10) = "="
+ └── value:
+ @ CallNode (location: (1,11)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (1,11)-(1,12) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,13)-(1,16))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (1,13)-(1,16))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/masgn_const.txt b/test/prism/snapshots/whitequark/masgn_const.txt
new file mode 100644
index 0000000000..56169deb17
--- /dev/null
+++ b/test/prism/snapshots/whitequark/masgn_const.txt
@@ -0,0 +1,46 @@
+@ ProgramNode (location: (1,0)-(3,18))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,18))
+ └── body: (length: 2)
+ ├── @ MultiWriteNode (location: (1,0)-(1,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) = "::"
+ │ │ └── @ LocalVariableTargetNode (location: (1,5)-(1,8))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (1,9)-(1,10) = "="
+ │ └── value:
+ │ @ LocalVariableReadNode (location: (1,11)-(1,14))
+ │ ├── name: :foo
+ │ └── depth: 0
+ └── @ MultiWriteNode (location: (3,0)-(3,18))
+ ├── lefts: (length: 2)
+ │ ├── @ 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) = "::"
+ │ └── @ LocalVariableTargetNode (location: (3,9)-(3,12))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (3,13)-(3,14) = "="
+ └── value:
+ @ LocalVariableReadNode (location: (3,15)-(3,18))
+ ├── name: :foo
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/masgn_nested.txt b/test/prism/snapshots/whitequark/masgn_nested.txt
new file mode 100644
index 0000000000..3e4602472f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/masgn_nested.txt
@@ -0,0 +1,66 @@
+@ ProgramNode (location: (1,0)-(3,15))
+├── locals: [:b, :a, :c]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,15))
+ └── body: (length: 2)
+ ├── @ MultiWriteNode (location: (1,0)-(1,13))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ MultiTargetNode (location: (1,1)-(1,6))
+ │ │ ├── lefts: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (1,2)-(1,3))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest:
+ │ │ │ @ ImplicitRestNode (location: (1,3)-(1,4))
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: (1,1)-(1,2) = "("
+ │ │ └── rparen_loc: (1,5)-(1,6) = ")"
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (1,0)-(1,1) = "("
+ │ ├── rparen_loc: (1,6)-(1,7) = ")"
+ │ ├── operator_loc: (1,8)-(1,9) = "="
+ │ └── value:
+ │ @ CallNode (location: (1,10)-(1,13))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,10)-(1,13) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ MultiWriteNode (location: (3,0)-(3,15))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (3,0)-(3,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ MultiTargetNode (location: (3,3)-(3,9))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (3,4)-(3,5))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (3,7)-(3,8))
+ │ │ ├── name: :c
+ │ │ └── depth: 0
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: (3,3)-(3,4) = "("
+ │ └── rparen_loc: (3,8)-(3,9) = ")"
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (3,10)-(3,11) = "="
+ └── value:
+ @ CallNode (location: (3,12)-(3,15))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :foo
+ ├── message_loc: (3,12)-(3,15) = "foo"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/masgn_splat.txt b/test/prism/snapshots/whitequark/masgn_splat.txt
new file mode 100644
index 0000000000..0db040a3ab
--- /dev/null
+++ b/test/prism/snapshots/whitequark/masgn_splat.txt
@@ -0,0 +1,284 @@
+@ ProgramNode (location: (1,0)-(19,16))
+├── locals: [:c, :d, :b, :a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(19,16))
+ └── body: (length: 10)
+ ├── @ MultiWriteNode (location: (1,0)-(1,7))
+ │ ├── lefts: (length: 0)
+ │ ├── rest:
+ │ │ @ SplatNode (location: (1,0)-(1,1))
+ │ │ ├── operator_loc: (1,0)-(1,1) = "*"
+ │ │ └── expression: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (1,2)-(1,3) = "="
+ │ └── value:
+ │ @ CallNode (location: (1,4)-(1,7))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,4)-(1,7) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (3,0)-(3,13))
+ │ ├── lefts: (length: 0)
+ │ ├── rest:
+ │ │ @ SplatNode (location: (3,0)-(3,1))
+ │ │ ├── operator_loc: (3,0)-(3,1) = "*"
+ │ │ └── expression: ∅
+ │ ├── rights: (length: 2)
+ │ │ ├── @ LocalVariableTargetNode (location: (3,3)-(3,4))
+ │ │ │ ├── name: :c
+ │ │ │ └── depth: 0
+ │ │ └── @ LocalVariableTargetNode (location: (3,6)-(3,7))
+ │ │ ├── name: :d
+ │ │ └── depth: 0
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (3,8)-(3,9) = "="
+ │ └── value:
+ │ @ CallNode (location: (3,10)-(3,13))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,10)-(3,13) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (5,0)-(5,8))
+ │ ├── lefts: (length: 0)
+ │ ├── rest:
+ │ │ @ SplatNode (location: (5,0)-(5,2))
+ │ │ ├── operator_loc: (5,0)-(5,1) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (5,1)-(5,2))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (5,3)-(5,4) = "="
+ │ └── value:
+ │ @ CallNode (location: (5,5)-(5,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (5,5)-(5,8) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (7,0)-(7,11))
+ │ ├── lefts: (length: 0)
+ │ ├── rest:
+ │ │ @ SplatNode (location: (7,0)-(7,2))
+ │ │ ├── operator_loc: (7,0)-(7,1) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (7,1)-(7,2))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rights: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (7,4)-(7,5))
+ │ │ ├── name: :c
+ │ │ └── depth: 0
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (7,6)-(7,7) = "="
+ │ └── value:
+ │ @ CallNode (location: (7,8)-(7,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (7,8)-(7,11) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (9,0)-(9,18))
+ │ ├── lefts: (length: 2)
+ │ │ ├── @ InstanceVariableTargetNode (location: (9,0)-(9,4))
+ │ │ │ └── name: :@foo
+ │ │ └── @ ClassVariableTargetNode (location: (9,6)-(9,11))
+ │ │ └── name: :@@bar
+ │ ├── rest: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (9,12)-(9,13) = "="
+ │ └── value:
+ │ @ ArrayNode (location: (9,14)-(9,18))
+ │ ├── flags: contains_splat
+ │ ├── elements: (length: 1)
+ │ │ └── @ SplatNode (location: (9,14)-(9,18))
+ │ │ ├── operator_loc: (9,14)-(9,15) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (9,15)-(9,18))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (9,15)-(9,18) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ ├── @ MultiWriteNode (location: (11,0)-(11,10))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (11,0)-(11,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ SplatNode (location: (11,3)-(11,4))
+ │ │ ├── operator_loc: (11,3)-(11,4) = "*"
+ │ │ └── expression: ∅
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (11,5)-(11,6) = "="
+ │ └── value:
+ │ @ CallNode (location: (11,7)-(11,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (11,7)-(11,10) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (13,0)-(13,13))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (13,0)-(13,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ SplatNode (location: (13,3)-(13,4))
+ │ │ ├── operator_loc: (13,3)-(13,4) = "*"
+ │ │ └── expression: ∅
+ │ ├── rights: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (13,6)-(13,7))
+ │ │ ├── name: :c
+ │ │ └── depth: 0
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (13,8)-(13,9) = "="
+ │ └── value:
+ │ @ CallNode (location: (13,10)-(13,13))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (13,10)-(13,13) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (15,0)-(15,11))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (15,0)-(15,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ SplatNode (location: (15,3)-(15,5))
+ │ │ ├── operator_loc: (15,3)-(15,4) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (15,4)-(15,5))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rights: (length: 0)
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (15,6)-(15,7) = "="
+ │ └── value:
+ │ @ CallNode (location: (15,8)-(15,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (15,8)-(15,11) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ MultiWriteNode (location: (17,0)-(17,14))
+ │ ├── lefts: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (17,0)-(17,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── rest:
+ │ │ @ SplatNode (location: (17,3)-(17,5))
+ │ │ ├── operator_loc: (17,3)-(17,4) = "*"
+ │ │ └── expression:
+ │ │ @ LocalVariableTargetNode (location: (17,4)-(17,5))
+ │ │ ├── name: :b
+ │ │ └── depth: 0
+ │ ├── rights: (length: 1)
+ │ │ └── @ LocalVariableTargetNode (location: (17,7)-(17,8))
+ │ │ ├── name: :c
+ │ │ └── depth: 0
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── operator_loc: (17,9)-(17,10) = "="
+ │ └── value:
+ │ @ CallNode (location: (17,11)-(17,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (17,11)-(17,14) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ MultiWriteNode (location: (19,0)-(19,16))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (19,0)-(19,1))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (19,3)-(19,4))
+ │ ├── name: :b
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (19,5)-(19,6) = "="
+ └── value:
+ @ ArrayNode (location: (19,7)-(19,16))
+ ├── flags: contains_splat
+ ├── elements: (length: 2)
+ │ ├── @ SplatNode (location: (19,7)-(19,11))
+ │ │ ├── operator_loc: (19,7)-(19,8) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (19,8)-(19,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (19,8)-(19,11) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ CallNode (location: (19,13)-(19,16))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (19,13)-(19,16) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: ∅
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/whitequark/module.txt b/test/prism/snapshots/whitequark/module.txt
new file mode 100644
index 0000000000..87348c4ec9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/module.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ ModuleNode (location: (1,0)-(1,15))
+ ├── locals: []
+ ├── module_keyword_loc: (1,0)-(1,6) = "module"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (1,7)-(1,10))
+ │ └── name: :Foo
+ ├── body: ∅
+ ├── end_keyword_loc: (1,12)-(1,15) = "end"
+ └── name: :Foo
diff --git a/test/prism/snapshots/whitequark/multiple_pattern_matches.txt b/test/prism/snapshots/whitequark/multiple_pattern_matches.txt
new file mode 100644
index 0000000000..afa3517e11
--- /dev/null
+++ b/test/prism/snapshots/whitequark/multiple_pattern_matches.txt
@@ -0,0 +1,173 @@
+@ ProgramNode (location: (1,0)-(5,12))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,12))
+ └── body: (length: 4)
+ ├── @ MatchRequiredNode (location: (1,0)-(1,12))
+ │ ├── value:
+ │ │ @ HashNode (location: (1,0)-(1,6))
+ │ │ ├── opening_loc: (1,0)-(1,1) = "{"
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (1,1)-(1,5))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (1,1)-(1,3))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (1,1)-(1,2) = "a"
+ │ │ │ │ ├── closing_loc: (1,2)-(1,3) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (1,5)-(1,6) = "}"
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (1,10)-(1,12))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (1,10)-(1,12))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (1,10)-(1,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (1,10)-(1,11) = "a"
+ │ │ │ │ ├── closing_loc: (1,11)-(1,12) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (1,10)-(1,11))
+ │ │ │ │ └── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (1,10)-(1,11))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (1,7)-(1,9) = "=>"
+ ├── @ MatchRequiredNode (location: (2,0)-(2,12))
+ │ ├── value:
+ │ │ @ HashNode (location: (2,0)-(2,6))
+ │ │ ├── opening_loc: (2,0)-(2,1) = "{"
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,1)-(2,5))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,1)-(2,3))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,1)-(2,2) = "a"
+ │ │ │ │ ├── closing_loc: (2,2)-(2,3) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (2,4)-(2,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (2,5)-(2,6) = "}"
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (2,10)-(2,12))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (2,10)-(2,12))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (2,10)-(2,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (2,10)-(2,11) = "a"
+ │ │ │ │ ├── closing_loc: (2,11)-(2,12) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (2,10)-(2,11))
+ │ │ │ │ └── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (2,10)-(2,11))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (2,7)-(2,9) = "=>"
+ ├── @ MatchPredicateNode (location: (4,0)-(4,12))
+ │ ├── value:
+ │ │ @ HashNode (location: (4,0)-(4,6))
+ │ │ ├── opening_loc: (4,0)-(4,1) = "{"
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (4,1)-(4,5))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (4,1)-(4,3))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (4,1)-(4,2) = "a"
+ │ │ │ │ ├── closing_loc: (4,2)-(4,3) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (4,4)-(4,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (4,5)-(4,6) = "}"
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (4,10)-(4,12))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (4,10)-(4,12))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (4,10)-(4,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (4,10)-(4,11) = "a"
+ │ │ │ │ ├── closing_loc: (4,11)-(4,12) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (4,10)-(4,11))
+ │ │ │ │ └── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (4,10)-(4,11))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (4,7)-(4,9) = "in"
+ └── @ MatchPredicateNode (location: (5,0)-(5,12))
+ ├── value:
+ │ @ HashNode (location: (5,0)-(5,6))
+ │ ├── opening_loc: (5,0)-(5,1) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (5,1)-(5,5))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (5,1)-(5,3))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (5,1)-(5,2) = "a"
+ │ │ │ ├── closing_loc: (5,2)-(5,3) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (5,4)-(5,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 0
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (5,5)-(5,6) = "}"
+ ├── pattern:
+ │ @ HashPatternNode (location: (5,10)-(5,12))
+ │ ├── constant: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (5,10)-(5,12))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (5,10)-(5,12))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (5,10)-(5,11) = "a"
+ │ │ │ ├── closing_loc: (5,11)-(5,12) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ ImplicitNode (location: (5,10)-(5,11))
+ │ │ │ └── value:
+ │ │ │ @ LocalVariableTargetNode (location: (5,10)-(5,11))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ └── operator_loc: ∅
+ │ ├── rest: ∅
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ └── operator_loc: (5,7)-(5,9) = "in"
diff --git a/test/prism/snapshots/whitequark/newline_in_hash_argument.txt b/test/prism/snapshots/whitequark/newline_in_hash_argument.txt
new file mode 100644
index 0000000000..d5e89d87f9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/newline_in_hash_argument.txt
@@ -0,0 +1,163 @@
+@ ProgramNode (location: (1,0)-(14,1))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(14,1))
+ └── body: (length: 3)
+ ├── @ CaseMatchNode (location: (1,0)-(8,3))
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,5)-(1,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── conditions: (length: 2)
+ │ │ ├── @ InNode (location: (2,0)-(4,4))
+ │ │ │ ├── pattern:
+ │ │ │ │ @ HashPatternNode (location: (2,3)-(2,5))
+ │ │ │ │ ├── constant: ∅
+ │ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ │ └── @ AssocNode (location: (2,3)-(2,5))
+ │ │ │ │ │ ├── key:
+ │ │ │ │ │ │ @ SymbolNode (location: (2,3)-(2,5))
+ │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ │ ├── value_loc: (2,3)-(2,4) = "a"
+ │ │ │ │ │ │ ├── closing_loc: (2,4)-(2,5) = ":"
+ │ │ │ │ │ │ └── unescaped: "a"
+ │ │ │ │ │ ├── value:
+ │ │ │ │ │ │ @ ImplicitNode (location: (2,3)-(2,4))
+ │ │ │ │ │ │ └── value:
+ │ │ │ │ │ │ @ LocalVariableTargetNode (location: (2,3)-(2,4))
+ │ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ │ └── depth: 0
+ │ │ │ │ │ └── operator_loc: ∅
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ └── closing_loc: ∅
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (3,0)-(4,4))
+ │ │ │ │ └── body: (length: 2)
+ │ │ │ │ ├── @ IntegerNode (location: (3,0)-(3,1))
+ │ │ │ │ │ ├── flags: decimal
+ │ │ │ │ │ └── value: 0
+ │ │ │ │ └── @ TrueNode (location: (4,0)-(4,4))
+ │ │ │ ├── in_loc: (2,0)-(2,2) = "in"
+ │ │ │ └── then_loc: ∅
+ │ │ └── @ InNode (location: (5,0)-(7,4))
+ │ │ ├── pattern:
+ │ │ │ @ HashPatternNode (location: (5,3)-(5,7))
+ │ │ │ ├── constant: ∅
+ │ │ │ ├── elements: (length: 1)
+ │ │ │ │ └── @ AssocNode (location: (5,3)-(5,7))
+ │ │ │ │ ├── key:
+ │ │ │ │ │ @ SymbolNode (location: (5,3)-(5,7))
+ │ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ │ ├── opening_loc: (5,3)-(5,4) = "\""
+ │ │ │ │ │ ├── value_loc: (5,4)-(5,5) = "b"
+ │ │ │ │ │ ├── closing_loc: (5,5)-(5,7) = "\":"
+ │ │ │ │ │ └── unescaped: "b"
+ │ │ │ │ ├── value:
+ │ │ │ │ │ @ ImplicitNode (location: (5,4)-(5,5))
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ LocalVariableTargetNode (location: (5,4)-(5,5))
+ │ │ │ │ │ ├── name: :b
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ └── operator_loc: ∅
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ └── closing_loc: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (6,0)-(7,4))
+ │ │ │ └── body: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (6,0)-(6,1))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 0
+ │ │ │ └── @ TrueNode (location: (7,0)-(7,4))
+ │ │ ├── in_loc: (5,0)-(5,2) = "in"
+ │ │ └── then_loc: ∅
+ │ ├── consequent: ∅
+ │ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ │ └── end_keyword_loc: (8,0)-(8,3) = "end"
+ ├── @ CallNode (location: (10,0)-(11,1))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (10,0)-(10,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :obj
+ │ │ ├── message_loc: (10,0)-(10,3) = "obj"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (10,3)-(10,4) = "."
+ │ ├── name: :set
+ │ ├── message_loc: (10,4)-(10,7) = "set"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (10,8)-(11,1))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (10,8)-(11,1))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (10,8)-(11,1))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (10,8)-(10,14))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (10,8)-(10,9) = "\""
+ │ │ │ ├── value_loc: (10,9)-(10,12) = "foo"
+ │ │ │ ├── closing_loc: (10,12)-(10,14) = "\":"
+ │ │ │ └── unescaped: "foo"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (11,0)-(11,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (13,0)-(14,1))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (13,0)-(13,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :obj
+ │ ├── message_loc: (13,0)-(13,3) = "obj"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (13,3)-(13,4) = "."
+ ├── name: :set
+ ├── message_loc: (13,4)-(13,7) = "set"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (13,8)-(14,1))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (13,8)-(14,1))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (13,8)-(14,1))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (13,8)-(13,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (13,8)-(13,11) = "foo"
+ │ │ ├── closing_loc: (13,11)-(13,12) = ":"
+ │ │ └── unescaped: "foo"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (14,0)-(14,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/nil.txt b/test/prism/snapshots/whitequark/nil.txt
new file mode 100644
index 0000000000..15774c02fd
--- /dev/null
+++ b/test/prism/snapshots/whitequark/nil.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ NilNode (location: (1,0)-(1,3))
diff --git a/test/prism/snapshots/whitequark/nil_expression.txt b/test/prism/snapshots/whitequark/nil_expression.txt
new file mode 100644
index 0000000000..7421115611
--- /dev/null
+++ b/test/prism/snapshots/whitequark/nil_expression.txt
@@ -0,0 +1,16 @@
+@ ProgramNode (location: (1,0)-(3,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,9))
+ └── body: (length: 2)
+ ├── @ ParenthesesNode (location: (1,0)-(1,2))
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "("
+ │ └── closing_loc: (1,1)-(1,2) = ")"
+ └── @ BeginNode (location: (3,0)-(3,9))
+ ├── begin_keyword_loc: (3,0)-(3,5) = "begin"
+ ├── statements: ∅
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (3,6)-(3,9) = "end"
diff --git a/test/prism/snapshots/whitequark/non_lvar_injecting_match.txt b/test/prism/snapshots/whitequark/non_lvar_injecting_match.txt
new file mode 100644
index 0000000000..584e997df2
--- /dev/null
+++ b/test/prism/snapshots/whitequark/non_lvar_injecting_match.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(1,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,28))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,28))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ InterpolatedRegularExpressionNode (location: (1,0)-(1,19))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "/"
+ │ ├── parts: (length: 2)
+ │ │ ├── @ EmbeddedStatementsNode (location: (1,1)-(1,5))
+ │ │ │ ├── opening_loc: (1,1)-(1,3) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (1,3)-(1,4))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (1,3)-(1,4))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── closing_loc: (1,4)-(1,5) = "}"
+ │ │ └── @ StringNode (location: (1,5)-(1,18))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,5)-(1,18) = "(?<match>bar)"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "(?<match>bar)"
+ │ └── closing_loc: (1,18)-(1,19) = "/"
+ ├── call_operator_loc: ∅
+ ├── name: :=~
+ ├── message_loc: (1,20)-(1,22) = "=~"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,23)-(1,28))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ StringNode (location: (1,23)-(1,28))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,23)-(1,24) = "'"
+ │ ├── content_loc: (1,24)-(1,27) = "bar"
+ │ ├── closing_loc: (1,27)-(1,28) = "'"
+ │ └── unescaped: "bar"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/not.txt b/test/prism/snapshots/whitequark/not.txt
new file mode 100644
index 0000000000..0a6d60e502
--- /dev/null
+++ b/test/prism/snapshots/whitequark/not.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(5,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,8))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,4)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,4)-(1,7) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (1,0)-(1,3) = "not"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,5))
+ │ ├── flags: ∅
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!
+ │ ├── message_loc: (3,0)-(3,3) = "not"
+ │ ├── opening_loc: (3,3)-(3,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (3,4)-(3,5) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,8))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (5,4)-(5,7))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,4)-(5,7) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (5,0)-(5,3) = "not"
+ ├── opening_loc: (5,3)-(5,4) = "("
+ ├── arguments: ∅
+ ├── closing_loc: (5,7)-(5,8) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/not_cmd.txt b/test/prism/snapshots/whitequark/not_cmd.txt
new file mode 100644
index 0000000000..3b111272c6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/not_cmd.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,4)-(1,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,4)-(1,5) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,6)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,6)-(1,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,6)-(1,9) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,3) = "not"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/not_masgn__24.txt b/test/prism/snapshots/whitequark/not_masgn__24.txt
new file mode 100644
index 0000000000..90124c3866
--- /dev/null
+++ b/test/prism/snapshots/whitequark/not_masgn__24.txt
@@ -0,0 +1,45 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ ParenthesesNode (location: (1,1)-(1,13))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,2)-(1,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ MultiWriteNode (location: (1,2)-(1,12))
+ │ │ ├── lefts: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (1,2)-(1,3))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (1,5)-(1,6))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── rights: (length: 0)
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── rparen_loc: ∅
+ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ └── value:
+ │ │ @ CallNode (location: (1,9)-(1,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,9)-(1,12) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,1)-(1,2) = "("
+ │ └── closing_loc: (1,12)-(1,13) = ")"
+ ├── call_operator_loc: ∅
+ ├── name: :!
+ ├── message_loc: (1,0)-(1,1) = "!"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/nth_ref.txt b/test/prism/snapshots/whitequark/nth_ref.txt
new file mode 100644
index 0000000000..1d386d518b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/nth_ref.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(1,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,3))
+ └── body: (length: 1)
+ └── @ NumberedReferenceReadNode (location: (1,0)-(1,3))
+ └── number: 10
diff --git a/test/prism/snapshots/whitequark/numbered_args_after_27.txt b/test/prism/snapshots/whitequark/numbered_args_after_27.txt
new file mode 100644
index 0000000000..56419adccd
--- /dev/null
+++ b/test/prism/snapshots/whitequark/numbered_args_after_27.txt
@@ -0,0 +1,143 @@
+@ ProgramNode (location: (1,0)-(7,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,13))
+ └── body: (length: 4)
+ ├── @ LambdaNode (location: (1,0)-(1,17))
+ │ ├── locals: [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9]
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (1,3)-(1,5) = "do"
+ │ ├── closing_loc: (1,14)-(1,17) = "end"
+ │ ├── parameters:
+ │ │ @ NumberedParametersNode (location: (1,0)-(1,17))
+ │ │ └── maximum: 9
+ │ └── body:
+ │ @ StatementsNode (location: (1,6)-(1,13))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,6)-(1,13))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (1,6)-(1,8))
+ │ │ ├── name: :_1
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (1,9)-(1,10) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,11)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (1,11)-(1,13))
+ │ │ ├── name: :_9
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ LambdaNode (location: (3,0)-(3,13))
+ │ ├── locals: [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9]
+ │ ├── operator_loc: (3,0)-(3,2) = "->"
+ │ ├── opening_loc: (3,3)-(3,4) = "{"
+ │ ├── closing_loc: (3,12)-(3,13) = "}"
+ │ ├── parameters:
+ │ │ @ NumberedParametersNode (location: (3,0)-(3,13))
+ │ │ └── maximum: 9
+ │ └── body:
+ │ @ StatementsNode (location: (3,5)-(3,12))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (3,5)-(3,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (3,5)-(3,7))
+ │ │ ├── name: :_1
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (3,8)-(3,9) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,10)-(3,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (3,10)-(3,12))
+ │ │ ├── name: :_9
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,16))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (5,0)-(5,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,2)-(5,16))
+ │ ├── locals: [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9]
+ │ ├── parameters:
+ │ │ @ NumberedParametersNode (location: (5,2)-(5,16))
+ │ │ └── maximum: 9
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,5)-(5,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,5)-(5,12))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ LocalVariableReadNode (location: (5,5)-(5,7))
+ │ │ │ ├── name: :_1
+ │ │ │ └── depth: 0
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :+
+ │ │ ├── message_loc: (5,8)-(5,9) = "+"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,10)-(5,12))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (5,10)-(5,12))
+ │ │ │ ├── name: :_9
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (5,2)-(5,4) = "do"
+ │ └── closing_loc: (5,13)-(5,16) = "end"
+ └── @ CallNode (location: (7,0)-(7,13))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (7,0)-(7,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (7,2)-(7,13))
+ ├── locals: [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9]
+ ├── parameters:
+ │ @ NumberedParametersNode (location: (7,2)-(7,13))
+ │ └── maximum: 9
+ ├── body:
+ │ @ StatementsNode (location: (7,4)-(7,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (7,4)-(7,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (7,4)-(7,6))
+ │ │ ├── name: :_1
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (7,7)-(7,8) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,9)-(7,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (7,9)-(7,11))
+ │ │ ├── name: :_9
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (7,2)-(7,3) = "{"
+ └── closing_loc: (7,12)-(7,13) = "}"
diff --git a/test/prism/snapshots/whitequark/numparam_outside_block.txt b/test/prism/snapshots/whitequark/numparam_outside_block.txt
new file mode 100644
index 0000000000..d79aedf7f9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/numparam_outside_block.txt
@@ -0,0 +1,114 @@
+@ ProgramNode (location: (1,0)-(9,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(9,17))
+ └── body: (length: 5)
+ ├── @ CallNode (location: (1,0)-(1,2))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :_1
+ │ ├── message_loc: (1,0)-(1,2) = "_1"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ SingletonClassNode (location: (3,0)-(3,21))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (3,0)-(3,5) = "class"
+ │ ├── operator_loc: (3,6)-(3,8) = "<<"
+ │ ├── expression:
+ │ │ @ CallNode (location: (3,9)-(3,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,9)-(3,12) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,14)-(3,16))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,14)-(3,16))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :_1
+ │ │ ├── message_loc: (3,14)-(3,16) = "_1"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (3,18)-(3,21) = "end"
+ ├── @ ClassNode (location: (5,0)-(5,16))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (5,0)-(5,5) = "class"
+ │ ├── constant_path:
+ │ │ @ ConstantReadNode (location: (5,6)-(5,7))
+ │ │ └── name: :A
+ │ ├── inheritance_operator_loc: ∅
+ │ ├── superclass: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,9)-(5,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,9)-(5,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :_1
+ │ │ ├── message_loc: (5,9)-(5,11) = "_1"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── end_keyword_loc: (5,13)-(5,16) = "end"
+ │ └── name: :A
+ ├── @ DefNode (location: (7,0)-(7,19))
+ │ ├── name: :m
+ │ ├── name_loc: (7,9)-(7,10) = "m"
+ │ ├── receiver:
+ │ │ @ SelfNode (location: (7,4)-(7,8))
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (7,12)-(7,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (7,12)-(7,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :_1
+ │ │ ├── message_loc: (7,12)-(7,14) = "_1"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ │ ├── operator_loc: (7,8)-(7,9) = "."
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (7,16)-(7,19) = "end"
+ └── @ ModuleNode (location: (9,0)-(9,17))
+ ├── locals: []
+ ├── module_keyword_loc: (9,0)-(9,6) = "module"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (9,7)-(9,8))
+ │ └── name: :A
+ ├── body:
+ │ @ StatementsNode (location: (9,10)-(9,12))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (9,10)-(9,12))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :_1
+ │ ├── message_loc: (9,10)-(9,12) = "_1"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── end_keyword_loc: (9,14)-(9,17) = "end"
+ └── name: :A
diff --git a/test/prism/snapshots/whitequark/numparam_ruby_bug_19025.txt b/test/prism/snapshots/whitequark/numparam_ruby_bug_19025.txt
new file mode 100644
index 0000000000..396238cbbf
--- /dev/null
+++ b/test/prism/snapshots/whitequark/numparam_ruby_bug_19025.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,2)-(1,14))
+ ├── locals: [:_1]
+ ├── parameters:
+ │ @ NumberedParametersNode (location: (1,2)-(1,14))
+ │ └── maximum: 1
+ ├── body:
+ │ @ StatementsNode (location: (1,4)-(1,12))
+ │ └── body: (length: 1)
+ │ └── @ ArrayNode (location: (1,4)-(1,12))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ CallNode (location: (1,5)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ LocalVariableReadNode (location: (1,5)-(1,7))
+ │ │ │ ├── name: :_1
+ │ │ │ └── depth: 0
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :**
+ │ │ ├── message_loc: (1,8)-(1,10) = "**"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,4)-(1,5) = "["
+ │ └── closing_loc: (1,11)-(1,12) = "]"
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ └── closing_loc: (1,13)-(1,14) = "}"
diff --git a/test/prism/snapshots/whitequark/op_asgn.txt b/test/prism/snapshots/whitequark/op_asgn.txt
new file mode 100644
index 0000000000..8f24a35ad0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/op_asgn.txt
@@ -0,0 +1,74 @@
+@ ProgramNode (location: (1,0)-(5,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,11))
+ └── body: (length: 3)
+ ├── @ CallOperatorWriteNode (location: (1,0)-(1,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── message_loc: (1,4)-(1,5) = "A"
+ │ ├── read_name: :A
+ │ ├── write_name: :A=
+ │ ├── operator: :+
+ │ ├── operator_loc: (1,6)-(1,8) = "+="
+ │ └── value:
+ │ @ IntegerNode (location: (1,9)-(1,10))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── @ CallOperatorWriteNode (location: (3,0)-(3,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (3,3)-(3,4) = "."
+ │ ├── message_loc: (3,4)-(3,5) = "a"
+ │ ├── read_name: :a
+ │ ├── write_name: :a=
+ │ ├── operator: :+
+ │ ├── operator_loc: (3,6)-(3,8) = "+="
+ │ └── value:
+ │ @ IntegerNode (location: (3,9)-(3,10))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── @ CallOperatorWriteNode (location: (5,0)-(5,11))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (5,0)-(5,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (5,3)-(5,5) = "::"
+ ├── message_loc: (5,5)-(5,6) = "a"
+ ├── read_name: :a
+ ├── write_name: :a=
+ ├── operator: :+
+ ├── operator_loc: (5,7)-(5,9) = "+="
+ └── value:
+ @ IntegerNode (location: (5,10)-(5,11))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/whitequark/op_asgn_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_cmd.txt
new file mode 100644
index 0000000000..109c2fd2ed
--- /dev/null
+++ b/test/prism/snapshots/whitequark/op_asgn_cmd.txt
@@ -0,0 +1,178 @@
+@ ProgramNode (location: (1,0)-(7,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,15))
+ └── body: (length: 4)
+ ├── @ CallOperatorWriteNode (location: (1,0)-(1,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── message_loc: (1,4)-(1,5) = "A"
+ │ ├── read_name: :A
+ │ ├── write_name: :A=
+ │ ├── operator: :+
+ │ ├── operator_loc: (1,6)-(1,8) = "+="
+ │ └── value:
+ │ @ CallNode (location: (1,9)-(1,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,9)-(1,10) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,11)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,11)-(1,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,11)-(1,14) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallOperatorWriteNode (location: (3,0)-(3,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (3,3)-(3,4) = "."
+ │ ├── message_loc: (3,4)-(3,5) = "a"
+ │ ├── read_name: :a
+ │ ├── write_name: :a=
+ │ ├── operator: :+
+ │ ├── operator_loc: (3,6)-(3,8) = "+="
+ │ └── value:
+ │ @ CallNode (location: (3,9)-(3,14))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (3,9)-(3,10) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,11)-(3,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,11)-(3,14))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,11)-(3,14) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ConstantPathOperatorWriteNode (location: (5,0)-(5,15))
+ │ ├── target:
+ │ │ @ ConstantPathNode (location: (5,0)-(5,6))
+ │ │ ├── parent:
+ │ │ │ @ CallNode (location: (5,0)-(5,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── 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) = "+="
+ │ ├── value:
+ │ │ @ CallNode (location: (5,10)-(5,15))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :m
+ │ │ ├── message_loc: (5,10)-(5,11) = "m"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,12)-(5,15))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (5,12)-(5,15))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (5,12)-(5,15) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator: :+
+ └── @ CallOperatorWriteNode (location: (7,0)-(7,15))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (7,0)-(7,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (7,3)-(7,5) = "::"
+ ├── message_loc: (7,5)-(7,6) = "a"
+ ├── read_name: :a
+ ├── write_name: :a=
+ ├── operator: :+
+ ├── operator_loc: (7,7)-(7,9) = "+="
+ └── value:
+ @ CallNode (location: (7,10)-(7,15))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (7,10)-(7,11) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (7,12)-(7,15))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (7,12)-(7,15))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (7,12)-(7,15) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/op_asgn_index.txt b/test/prism/snapshots/whitequark/op_asgn_index.txt
new file mode 100644
index 0000000000..fe077fae13
--- /dev/null
+++ b/test/prism/snapshots/whitequark/op_asgn_index.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ IndexOperatorWriteNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (1,8)-(1,9) = "]"
+ ├── block: ∅
+ ├── operator: :+
+ ├── operator_loc: (1,10)-(1,12) = "+="
+ └── value:
+ @ IntegerNode (location: (1,13)-(1,14))
+ ├── flags: decimal
+ └── value: 2
diff --git a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
new file mode 100644
index 0000000000..87082aad94
--- /dev/null
+++ b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(1,18))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,18))
+ └── body: (length: 1)
+ └── @ IndexOperatorWriteNode (location: (1,0)-(1,18))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (1,8)-(1,9) = "]"
+ ├── block: ∅
+ ├── operator: :+
+ ├── operator_loc: (1,10)-(1,12) = "+="
+ └── value:
+ @ CallNode (location: (1,13)-(1,18))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (1,13)-(1,14) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,15)-(1,18))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,15)-(1,18))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,15)-(1,18) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/optarg.txt b/test/prism/snapshots/whitequark/optarg.txt
new file mode 100644
index 0000000000..695ed827ad
--- /dev/null
+++ b/test/prism/snapshots/whitequark/optarg.txt
@@ -0,0 +1,74 @@
+@ ProgramNode (location: (1,0)-(3,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,24))
+ └── body: (length: 2)
+ ├── @ DefNode (location: (1,0)-(1,18))
+ │ ├── name: :f
+ │ ├── name_loc: (1,4)-(1,5) = "f"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,13))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,6)-(1,13))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── name_loc: (1,6)-(1,9) = "foo"
+ │ │ │ ├── operator_loc: (1,10)-(1,11) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body: ∅
+ │ ├── locals: [:foo]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,15)-(1,18) = "end"
+ └── @ DefNode (location: (3,0)-(3,24))
+ ├── name: :f
+ ├── name_loc: (3,4)-(3,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (3,6)-(3,18))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 2)
+ │ │ ├── @ OptionalParameterNode (location: (3,6)-(3,11))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── name_loc: (3,6)-(3,9) = "foo"
+ │ │ │ ├── operator_loc: (3,9)-(3,10) = "="
+ │ │ │ └── value:
+ │ │ │ @ IntegerNode (location: (3,10)-(3,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── @ OptionalParameterNode (location: (3,13)-(3,18))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :bar
+ │ │ ├── name_loc: (3,13)-(3,16) = "bar"
+ │ │ ├── operator_loc: (3,16)-(3,17) = "="
+ │ │ └── value:
+ │ │ @ IntegerNode (location: (3,17)-(3,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:foo, :bar]
+ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (3,5)-(3,6) = "("
+ ├── rparen_loc: (3,18)-(3,19) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (3,21)-(3,24) = "end"
diff --git a/test/prism/snapshots/whitequark/or.txt b/test/prism/snapshots/whitequark/or.txt
new file mode 100644
index 0000000000..439146b8db
--- /dev/null
+++ b/test/prism/snapshots/whitequark/or.txt
@@ -0,0 +1,53 @@
+@ ProgramNode (location: (1,0)-(3,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,10))
+ └── body: (length: 2)
+ ├── @ OrNode (location: (1,0)-(1,10))
+ │ ├── left:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── right:
+ │ │ @ CallNode (location: (1,7)-(1,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,7)-(1,10) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,4)-(1,6) = "or"
+ └── @ OrNode (location: (3,0)-(3,10))
+ ├── left:
+ │ @ CallNode (location: (3,0)-(3,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── right:
+ │ @ CallNode (location: (3,7)-(3,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,7)-(3,10) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (3,4)-(3,6) = "||"
diff --git a/test/prism/snapshots/whitequark/or_asgn.txt b/test/prism/snapshots/whitequark/or_asgn.txt
new file mode 100644
index 0000000000..c0ded24b93
--- /dev/null
+++ b/test/prism/snapshots/whitequark/or_asgn.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(3,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,15))
+ └── body: (length: 2)
+ ├── @ CallOrWriteNode (location: (1,0)-(1,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── message_loc: (1,4)-(1,5) = "a"
+ │ ├── read_name: :a
+ │ ├── write_name: :a=
+ │ ├── operator_loc: (1,6)-(1,9) = "||="
+ │ └── value:
+ │ @ IntegerNode (location: (1,10)-(1,11))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── @ IndexOrWriteNode (location: (3,0)-(3,15))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (3,0)-(3,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── opening_loc: (3,3)-(3,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,4)-(3,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (3,4)-(3,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ └── @ IntegerNode (location: (3,7)-(3,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (3,8)-(3,9) = "]"
+ ├── block: ∅
+ ├── operator_loc: (3,10)-(3,13) = "||="
+ └── value:
+ @ IntegerNode (location: (3,14)-(3,15))
+ ├── flags: decimal
+ └── value: 2
diff --git a/test/prism/snapshots/whitequark/parser_bug_272.txt b/test/prism/snapshots/whitequark/parser_bug_272.txt
new file mode 100644
index 0000000000..f158f255b9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_272.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,15))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (1,0)-(1,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,4))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InstanceVariableReadNode (location: (1,2)-(1,4))
+ │ └── name: :@b
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,5)-(1,15))
+ ├── locals: [:c]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,8)-(1,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,9)-(1,10))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :c
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,8)-(1,9) = "|"
+ │ └── closing_loc: (1,10)-(1,11) = "|"
+ ├── body: ∅
+ ├── opening_loc: (1,5)-(1,7) = "do"
+ └── closing_loc: (1,12)-(1,15) = "end"
diff --git a/test/prism/snapshots/whitequark/parser_bug_490.txt b/test/prism/snapshots/whitequark/parser_bug_490.txt
new file mode 100644
index 0000000000..9e4cd2bd15
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_490.txt
@@ -0,0 +1,106 @@
+@ ProgramNode (location: (1,0)-(5,45))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,45))
+ └── body: (length: 3)
+ ├── @ DefNode (location: (1,0)-(1,39))
+ │ ├── name: :m
+ │ ├── name_loc: (1,4)-(1,5) = "m"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,7)-(1,34))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SingletonClassNode (location: (1,7)-(1,34))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (1,7)-(1,12) = "class"
+ │ │ ├── operator_loc: (1,13)-(1,15) = "<<"
+ │ │ ├── expression:
+ │ │ │ @ SelfNode (location: (1,16)-(1,20))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,22)-(1,29))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ ConstantWriteNode (location: (1,22)-(1,29))
+ │ │ │ ├── name: :A
+ │ │ │ ├── name_loc: (1,22)-(1,23) = "A"
+ │ │ │ ├── value:
+ │ │ │ │ @ NilNode (location: (1,26)-(1,29))
+ │ │ │ └── operator_loc: (1,24)-(1,25) = "="
+ │ │ └── end_keyword_loc: (1,31)-(1,34) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,36)-(1,39) = "end"
+ ├── @ DefNode (location: (3,0)-(3,44))
+ │ ├── name: :m
+ │ ├── name_loc: (3,4)-(3,5) = "m"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,7)-(3,39))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SingletonClassNode (location: (3,7)-(3,39))
+ │ │ ├── locals: []
+ │ │ ├── class_keyword_loc: (3,7)-(3,12) = "class"
+ │ │ ├── operator_loc: (3,13)-(3,15) = "<<"
+ │ │ ├── expression:
+ │ │ │ @ SelfNode (location: (3,16)-(3,20))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (3,22)-(3,34))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ ClassNode (location: (3,22)-(3,34))
+ │ │ │ ├── locals: []
+ │ │ │ ├── class_keyword_loc: (3,22)-(3,27) = "class"
+ │ │ │ ├── constant_path:
+ │ │ │ │ @ ConstantReadNode (location: (3,28)-(3,29))
+ │ │ │ │ └── name: :C
+ │ │ │ ├── inheritance_operator_loc: ∅
+ │ │ │ ├── superclass: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── end_keyword_loc: (3,31)-(3,34) = "end"
+ │ │ │ └── name: :C
+ │ │ └── end_keyword_loc: (3,36)-(3,39) = "end"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,41)-(3,44) = "end"
+ └── @ DefNode (location: (5,0)-(5,45))
+ ├── name: :m
+ ├── name_loc: (5,4)-(5,5) = "m"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (5,7)-(5,40))
+ │ └── body: (length: 1)
+ │ └── @ SingletonClassNode (location: (5,7)-(5,40))
+ │ ├── locals: []
+ │ ├── class_keyword_loc: (5,7)-(5,12) = "class"
+ │ ├── operator_loc: (5,13)-(5,15) = "<<"
+ │ ├── expression:
+ │ │ @ SelfNode (location: (5,16)-(5,20))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,22)-(5,35))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ModuleNode (location: (5,22)-(5,35))
+ │ │ ├── locals: []
+ │ │ ├── module_keyword_loc: (5,22)-(5,28) = "module"
+ │ │ ├── constant_path:
+ │ │ │ @ ConstantReadNode (location: (5,29)-(5,30))
+ │ │ │ └── name: :M
+ │ │ ├── body: ∅
+ │ │ ├── end_keyword_loc: (5,32)-(5,35) = "end"
+ │ │ └── name: :M
+ │ └── end_keyword_loc: (5,37)-(5,40) = "end"
+ ├── locals: []
+ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (5,42)-(5,45) = "end"
diff --git a/test/prism/snapshots/whitequark/parser_bug_507.txt b/test/prism/snapshots/whitequark/parser_bug_507.txt
new file mode 100644
index 0000000000..7e5fc9ee35
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_507.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: [:m]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,19))
+ ├── name: :m
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,1) = "m"
+ ├── value:
+ │ @ LambdaNode (location: (1,4)-(1,19))
+ │ ├── locals: [:args]
+ │ ├── operator_loc: (1,4)-(1,6) = "->"
+ │ ├── opening_loc: (1,13)-(1,15) = "do"
+ │ ├── closing_loc: (1,16)-(1,19) = "end"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,7)-(1,12))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,7)-(1,12))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (1,7)-(1,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :args
+ │ │ │ │ ├── name_loc: (1,8)-(1,12) = "args"
+ │ │ │ │ └── operator_loc: (1,7)-(1,8) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── body: ∅
+ └── operator_loc: (1,2)-(1,3) = "="
diff --git a/test/prism/snapshots/whitequark/parser_bug_518.txt b/test/prism/snapshots/whitequark/parser_bug_518.txt
new file mode 100644
index 0000000000..b63fbb8284
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_518.txt
@@ -0,0 +1,18 @@
+@ ProgramNode (location: (1,0)-(2,3))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,3))
+ └── body: (length: 1)
+ └── @ ClassNode (location: (1,0)-(2,3))
+ ├── locals: []
+ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ ├── constant_path:
+ │ @ ConstantReadNode (location: (1,6)-(1,7))
+ │ └── name: :A
+ ├── inheritance_operator_loc: (1,8)-(1,9) = "<"
+ ├── superclass:
+ │ @ ConstantReadNode (location: (1,10)-(1,11))
+ │ └── name: :B
+ ├── body: ∅
+ ├── end_keyword_loc: (2,0)-(2,3) = "end"
+ └── name: :A
diff --git a/test/prism/snapshots/whitequark/parser_bug_525.txt b/test/prism/snapshots/whitequark/parser_bug_525.txt
new file mode 100644
index 0000000000..a69b8a207f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_525.txt
@@ -0,0 +1,65 @@
+@ ProgramNode (location: (1,0)-(1,32))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,32))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,32))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m1
+ ├── message_loc: (1,0)-(1,2) = "m1"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,3)-(1,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ KeywordHashNode (location: (1,3)-(1,11))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,3)-(1,11))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,3)-(1,5))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,3)-(1,4) = ":"
+ │ │ ├── value_loc: (1,4)-(1,5) = "k"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "k"
+ │ ├── value:
+ │ │ @ CallNode (location: (1,9)-(1,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :m2
+ │ │ ├── message_loc: (1,9)-(1,11) = "m2"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (1,6)-(1,8) = "=>"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,12)-(1,32))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,16)-(1,27))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,16)-(1,27))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m3
+ │ ├── message_loc: (1,16)-(1,18) = "m3"
+ │ ├── opening_loc: (1,18)-(1,19) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (1,19)-(1,20) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (1,21)-(1,27))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,21)-(1,23) = "do"
+ │ └── closing_loc: (1,24)-(1,27) = "end"
+ ├── opening_loc: (1,12)-(1,14) = "do"
+ └── closing_loc: (1,29)-(1,32) = "end"
diff --git a/test/prism/snapshots/whitequark/parser_bug_604.txt b/test/prism/snapshots/whitequark/parser_bug_604.txt
new file mode 100644
index 0000000000..2577e3bc55
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_604.txt
@@ -0,0 +1,57 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,14))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (1,0)-(1,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,2)-(1,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,2)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,2)-(1,3) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (1,4)-(1,5) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,6)-(1,7))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (1,6)-(1,7) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,8)-(1,14))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,8)-(1,10) = "do"
+ └── closing_loc: (1,11)-(1,14) = "end"
diff --git a/test/prism/snapshots/whitequark/parser_bug_640.txt b/test/prism/snapshots/whitequark/parser_bug_640.txt
new file mode 100644
index 0000000000..157576838b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_640.txt
@@ -0,0 +1,22 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,6) = "<<~FOO"
+ ├── parts: (length: 2)
+ │ ├── @ StringNode (location: (2,0)-(3,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (2,0)-(3,0) = " baz\\\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "baz"
+ │ └── @ StringNode (location: (3,0)-(4,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (3,0)-(4,0) = " qux\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "qux\n"
+ └── closing_loc: (4,0)-(5,0) = "FOO\n"
diff --git a/test/prism/snapshots/whitequark/parser_bug_645.txt b/test/prism/snapshots/whitequark/parser_bug_645.txt
new file mode 100644
index 0000000000..5700f3c3db
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_645.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,14))
+ ├── locals: [:arg]
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,12)-(1,13) = "{"
+ ├── closing_loc: (1,13)-(1,14) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,3)-(1,11))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,4)-(1,10))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 1)
+ │ │ │ └── @ OptionalParameterNode (location: (1,4)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :arg
+ │ │ │ ├── name_loc: (1,4)-(1,7) = "arg"
+ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ └── value:
+ │ │ │ @ HashNode (location: (1,8)-(1,10))
+ │ │ │ ├── opening_loc: (1,8)-(1,9) = "{"
+ │ │ │ ├── elements: (length: 0)
+ │ │ │ └── closing_loc: (1,9)-(1,10) = "}"
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ └── closing_loc: (1,10)-(1,11) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/whitequark/parser_bug_830.txt b/test/prism/snapshots/whitequark/parser_bug_830.txt
new file mode 100644
index 0000000000..e52b291d6a
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_830.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ RegularExpressionNode (location: (1,0)-(1,4))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,1) = "/"
+ ├── content_loc: (1,1)-(1,3) = "\\("
+ ├── closing_loc: (1,3)-(1,4) = "/"
+ └── unescaped: "\\("
diff --git a/test/prism/snapshots/whitequark/parser_bug_989.txt b/test/prism/snapshots/whitequark/parser_bug_989.txt
new file mode 100644
index 0000000000..c241d6127f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_bug_989.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,1)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,1)-(1,8))
+ └── body: (length: 1)
+ └── @ StringNode (location: (1,1)-(1,8))
+ ├── flags: ∅
+ ├── opening_loc: (1,1)-(1,8) = "<<-HERE"
+ ├── content_loc: (2,0)-(3,0) = "\t\tcontent\n"
+ ├── closing_loc: (3,0)-(4,0) = "\tHERE\n"
+ └── unescaped: "\t\tcontent\n"
diff --git a/test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt b/test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt
new file mode 100644
index 0000000000..018d7916a6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt
@@ -0,0 +1,20 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,7))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,7) = "<<~HERE"
+ ├── parts: (length: 2)
+ │ ├── @ EmbeddedStatementsNode (location: (2,2)-(2,5))
+ │ │ ├── opening_loc: (2,2)-(2,4) = "\#{"
+ │ │ ├── statements: ∅
+ │ │ └── closing_loc: (2,4)-(2,5) = "}"
+ │ └── @ StringNode (location: (2,5)-(3,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (2,5)-(3,0) = "\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "\n"
+ └── closing_loc: (3,0)-(4,0) = "HERE\n"
diff --git a/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt b/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt
new file mode 100644
index 0000000000..080d4d0e7d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt
@@ -0,0 +1,139 @@
+@ ProgramNode (location: (1,0)-(62,2))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(62,2))
+ └── body: (length: 19)
+ ├── @ StringNode (location: (1,0)-(2,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ ├── content_loc: (1,1)-(2,1) = "a\\\nb"
+ │ ├── closing_loc: (2,1)-(2,2) = "\""
+ │ └── unescaped: "ab"
+ ├── @ ArrayNode (location: (4,0)-(5,2))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ SymbolNode (location: (4,3)-(5,1))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (4,3)-(5,1) = "a\\\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\nb"
+ │ ├── opening_loc: (4,0)-(4,3) = "%I{"
+ │ └── closing_loc: (5,1)-(5,2) = "}"
+ ├── @ StringNode (location: (7,0)-(8,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(7,3) = "%Q{"
+ │ ├── content_loc: (7,3)-(8,1) = "a\\\nb"
+ │ ├── closing_loc: (8,1)-(8,2) = "}"
+ │ └── unescaped: "ab"
+ ├── @ ArrayNode (location: (10,0)-(11,2))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (10,3)-(11,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (10,3)-(11,1) = "a\\\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\nb"
+ │ ├── opening_loc: (10,0)-(10,3) = "%W{"
+ │ └── closing_loc: (11,1)-(11,2) = "}"
+ ├── @ ArrayNode (location: (13,0)-(14,2))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ SymbolNode (location: (13,3)-(14,1))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (13,3)-(14,1) = "a\\\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\nb"
+ │ ├── opening_loc: (13,0)-(13,3) = "%i{"
+ │ └── closing_loc: (14,1)-(14,2) = "}"
+ ├── @ StringNode (location: (16,0)-(17,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (16,0)-(16,3) = "%q{"
+ │ ├── content_loc: (16,3)-(17,1) = "a\\\nb"
+ │ ├── closing_loc: (17,1)-(17,2) = "}"
+ │ └── unescaped: "a\\\nb"
+ ├── @ RegularExpressionNode (location: (19,0)-(20,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (19,0)-(19,3) = "%r{"
+ │ ├── content_loc: (19,3)-(20,1) = "a\\\nb"
+ │ ├── closing_loc: (20,1)-(20,2) = "}"
+ │ └── unescaped: "ab"
+ ├── @ SymbolNode (location: (22,0)-(23,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (22,0)-(22,3) = "%s{"
+ │ ├── value_loc: (22,3)-(23,1) = "a\\\nb"
+ │ ├── closing_loc: (23,1)-(23,2) = "}"
+ │ └── unescaped: "a\\\nb"
+ ├── @ ArrayNode (location: (25,0)-(26,2))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 1)
+ │ │ └── @ StringNode (location: (25,3)-(26,1))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (25,3)-(26,1) = "a\\\nb"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "a\nb"
+ │ ├── opening_loc: (25,0)-(25,3) = "%w{"
+ │ └── closing_loc: (26,1)-(26,2) = "}"
+ ├── @ XStringNode (location: (28,0)-(29,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (28,0)-(28,3) = "%x{"
+ │ ├── content_loc: (28,3)-(29,1) = "a\\\nb"
+ │ ├── closing_loc: (29,1)-(29,2) = "}"
+ │ └── unescaped: "ab"
+ ├── @ StringNode (location: (31,0)-(32,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (31,0)-(31,2) = "%{"
+ │ ├── content_loc: (31,2)-(32,1) = "a\\\nb"
+ │ ├── closing_loc: (32,1)-(32,2) = "}"
+ │ └── unescaped: "ab"
+ ├── @ StringNode (location: (34,0)-(35,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (34,0)-(34,1) = "'"
+ │ ├── content_loc: (34,1)-(35,1) = "a\\\nb"
+ │ ├── closing_loc: (35,1)-(35,2) = "'"
+ │ └── unescaped: "a\\\nb"
+ ├── @ RegularExpressionNode (location: (37,0)-(38,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (37,0)-(37,1) = "/"
+ │ ├── content_loc: (37,1)-(38,1) = "a\\\nb"
+ │ ├── closing_loc: (38,1)-(38,2) = "/"
+ │ └── unescaped: "ab"
+ ├── @ SymbolNode (location: (40,0)-(41,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (40,0)-(40,2) = ":\""
+ │ ├── value_loc: (40,2)-(41,1) = "a\\\nb"
+ │ ├── closing_loc: (41,1)-(41,2) = "\""
+ │ └── unescaped: "ab"
+ ├── @ SymbolNode (location: (43,0)-(44,2))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (43,0)-(43,2) = ":'"
+ │ ├── value_loc: (43,2)-(44,1) = "a\\\nb"
+ │ ├── closing_loc: (44,1)-(44,2) = "'"
+ │ └── unescaped: "a\\\nb"
+ ├── @ StringNode (location: (46,0)-(46,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (46,0)-(46,9) = "<<-\"HERE\""
+ │ ├── content_loc: (47,0)-(49,0) = "a\\\nb\n"
+ │ ├── closing_loc: (49,0)-(50,0) = "HERE\n"
+ │ └── unescaped: "ab\n"
+ ├── @ StringNode (location: (51,0)-(51,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (51,0)-(51,9) = "<<-'HERE'"
+ │ ├── content_loc: (52,0)-(54,0) = "a\\\nb\n"
+ │ ├── closing_loc: (54,0)-(55,0) = "HERE\n"
+ │ └── unescaped: "a\\\nb\n"
+ ├── @ XStringNode (location: (56,0)-(56,9))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (56,0)-(56,9) = "<<-`HERE`"
+ │ ├── content_loc: (57,0)-(59,0) = "a\\\nb\n"
+ │ ├── closing_loc: (59,0)-(60,0) = "HERE\n"
+ │ └── unescaped: "ab\n"
+ └── @ XStringNode (location: (61,0)-(62,2))
+ ├── flags: ∅
+ ├── opening_loc: (61,0)-(61,1) = "`"
+ ├── content_loc: (61,1)-(62,1) = "a\\\nb"
+ ├── closing_loc: (62,1)-(62,2) = "`"
+ └── unescaped: "ab"
diff --git a/test/prism/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt b/test/prism/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt
new file mode 100644
index 0000000000..6f315780ad
--- /dev/null
+++ b/test/prism/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt
@@ -0,0 +1,54 @@
+@ ProgramNode (location: (1,8)-(3,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,8)-(3,11))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,8)-(3,11))
+ ├── predicate:
+ │ @ ArrayNode (location: (1,13)-(1,51))
+ │ ├── flags: ∅
+ │ ├── elements: (length: 3)
+ │ │ ├── @ SourceFileNode (location: (1,14)-(1,22))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── filepath: "whitequark/pattern_matching__FILE__LINE_literals.txt"
+ │ │ ├── @ CallNode (location: (1,24)-(1,36))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── receiver:
+ │ │ │ │ @ SourceLineNode (location: (1,24)-(1,32))
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :+
+ │ │ │ ├── message_loc: (1,33)-(1,34) = "+"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,35)-(1,36))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ IntegerNode (location: (1,35)-(1,36))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── @ SourceEncodingNode (location: (1,38)-(1,50))
+ │ ├── opening_loc: (1,13)-(1,14) = "["
+ │ └── closing_loc: (1,50)-(1,51) = "]"
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (2,10)-(2,47))
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (2,13)-(2,47))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 3)
+ │ │ │ ├── @ SourceFileNode (location: (2,14)-(2,22))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── filepath: "whitequark/pattern_matching__FILE__LINE_literals.txt"
+ │ │ │ ├── @ SourceLineNode (location: (2,24)-(2,32))
+ │ │ │ └── @ SourceEncodingNode (location: (2,34)-(2,46))
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (2,13)-(2,14) = "["
+ │ │ └── closing_loc: (2,46)-(2,47) = "]"
+ │ ├── statements: ∅
+ │ ├── in_loc: (2,10)-(2,12) = "in"
+ │ └── then_loc: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,8)-(1,12) = "case"
+ └── end_keyword_loc: (3,8)-(3,11) = "end"
diff --git a/test/prism/snapshots/whitequark/pattern_matching_blank_else.txt b/test/prism/snapshots/whitequark/pattern_matching_blank_else.txt
new file mode 100644
index 0000000000..6015c000a9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/pattern_matching_blank_else.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,26))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,26))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(1,26))
+ ├── predicate:
+ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (1,8)-(1,15))
+ │ ├── pattern:
+ │ │ @ IntegerNode (location: (1,11)-(1,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,14)-(1,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,14)-(1,15))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── in_loc: (1,8)-(1,10) = "in"
+ │ └── then_loc: ∅
+ ├── consequent:
+ │ @ ElseNode (location: (1,17)-(1,26))
+ │ ├── else_keyword_loc: (1,17)-(1,21) = "else"
+ │ ├── statements: ∅
+ │ └── end_keyword_loc: (1,23)-(1,26) = "end"
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,23)-(1,26) = "end"
diff --git a/test/prism/snapshots/whitequark/pattern_matching_else.txt b/test/prism/snapshots/whitequark/pattern_matching_else.txt
new file mode 100644
index 0000000000..7f83aafe99
--- /dev/null
+++ b/test/prism/snapshots/whitequark/pattern_matching_else.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,29))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,29))
+ └── body: (length: 1)
+ └── @ CaseMatchNode (location: (1,0)-(1,29))
+ ├── predicate:
+ │ @ IntegerNode (location: (1,5)-(1,6))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── conditions: (length: 1)
+ │ └── @ InNode (location: (1,8)-(1,15))
+ │ ├── pattern:
+ │ │ @ IntegerNode (location: (1,11)-(1,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,14)-(1,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,14)-(1,15))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ ├── in_loc: (1,8)-(1,10) = "in"
+ │ └── then_loc: ∅
+ ├── consequent:
+ │ @ ElseNode (location: (1,17)-(1,29))
+ │ ├── else_keyword_loc: (1,17)-(1,21) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,23)-(1,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,23)-(1,24))
+ │ │ ├── flags: decimal
+ │ │ └── value: 4
+ │ └── end_keyword_loc: (1,26)-(1,29) = "end"
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,26)-(1,29) = "end"
diff --git a/test/prism/snapshots/whitequark/pattern_matching_single_line.txt b/test/prism/snapshots/whitequark/pattern_matching_single_line.txt
new file mode 100644
index 0000000000..2396172dce
--- /dev/null
+++ b/test/prism/snapshots/whitequark/pattern_matching_single_line.txt
@@ -0,0 +1,45 @@
+@ ProgramNode (location: (1,0)-(3,11))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,11))
+ └── body: (length: 4)
+ ├── @ MatchRequiredNode (location: (1,0)-(1,8))
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (1,5)-(1,8))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,7))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (1,5)-(1,6) = "["
+ │ │ └── closing_loc: (1,7)-(1,8) = "]"
+ │ └── operator_loc: (1,2)-(1,4) = "=>"
+ ├── @ LocalVariableReadNode (location: (1,10)-(1,11))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ MatchPredicateNode (location: (3,0)-(3,8))
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,0)-(3,1))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (3,5)-(3,8))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ LocalVariableTargetNode (location: (3,6)-(3,7))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: (3,5)-(3,6) = "["
+ │ │ └── closing_loc: (3,7)-(3,8) = "]"
+ │ └── operator_loc: (3,2)-(3,4) = "in"
+ └── @ LocalVariableReadNode (location: (3,10)-(3,11))
+ ├── name: :a
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt b/test/prism/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt
new file mode 100644
index 0000000000..757a7780c2
--- /dev/null
+++ b/test/prism/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt
@@ -0,0 +1,249 @@
+@ ProgramNode (location: (1,0)-(11,34))
+├── locals: [:a, :b, :value]
+└── statements:
+ @ StatementsNode (location: (1,0)-(11,34))
+ └── body: (length: 12)
+ ├── @ MatchRequiredNode (location: (1,0)-(1,14))
+ │ ├── value:
+ │ │ @ ArrayNode (location: (1,0)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (1,1)-(1,2))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: (1,0)-(1,1) = "["
+ │ │ └── closing_loc: (1,5)-(1,6) = "]"
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (1,10)-(1,14))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (1,10)-(1,11))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (1,13)-(1,14))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (1,7)-(1,9) = "=>"
+ ├── @ LocalVariableReadNode (location: (1,16)-(1,17))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ MatchPredicateNode (location: (3,0)-(3,14))
+ │ ├── value:
+ │ │ @ ArrayNode (location: (3,0)-(3,6))
+ │ │ ├── flags: ∅
+ │ │ ├── elements: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (3,1)-(3,2))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ IntegerNode (location: (3,4)-(3,5))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── opening_loc: (3,0)-(3,1) = "["
+ │ │ └── closing_loc: (3,5)-(3,6) = "]"
+ │ ├── pattern:
+ │ │ @ ArrayPatternNode (location: (3,10)-(3,14))
+ │ │ ├── constant: ∅
+ │ │ ├── requireds: (length: 2)
+ │ │ │ ├── @ LocalVariableTargetNode (location: (3,10)-(3,11))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── @ LocalVariableTargetNode (location: (3,13)-(3,14))
+ │ │ │ ├── name: :b
+ │ │ │ └── depth: 0
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (3,7)-(3,9) = "in"
+ ├── @ LocalVariableReadNode (location: (3,16)-(3,17))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ MatchRequiredNode (location: (5,0)-(5,12))
+ │ ├── value:
+ │ │ @ HashNode (location: (5,0)-(5,6))
+ │ │ ├── opening_loc: (5,0)-(5,1) = "{"
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (5,1)-(5,5))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (5,1)-(5,3))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (5,1)-(5,2) = "a"
+ │ │ │ │ ├── closing_loc: (5,2)-(5,3) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (5,4)-(5,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (5,5)-(5,6) = "}"
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (5,10)-(5,12))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (5,10)-(5,12))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (5,10)-(5,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (5,10)-(5,11) = "a"
+ │ │ │ │ ├── closing_loc: (5,11)-(5,12) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (5,10)-(5,11))
+ │ │ │ │ └── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (5,10)-(5,11))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (5,7)-(5,9) = "=>"
+ ├── @ LocalVariableReadNode (location: (5,14)-(5,15))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ MatchPredicateNode (location: (7,0)-(7,12))
+ │ ├── value:
+ │ │ @ HashNode (location: (7,0)-(7,6))
+ │ │ ├── opening_loc: (7,0)-(7,1) = "{"
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (7,1)-(7,5))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (7,1)-(7,3))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (7,1)-(7,2) = "a"
+ │ │ │ │ ├── closing_loc: (7,2)-(7,3) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ IntegerNode (location: (7,4)-(7,5))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (7,5)-(7,6) = "}"
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (7,10)-(7,12))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (7,10)-(7,12))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (7,10)-(7,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (7,10)-(7,11) = "a"
+ │ │ │ │ ├── closing_loc: (7,11)-(7,12) = ":"
+ │ │ │ │ └── unescaped: "a"
+ │ │ │ ├── value:
+ │ │ │ │ @ ImplicitNode (location: (7,10)-(7,11))
+ │ │ │ │ └── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (7,10)-(7,11))
+ │ │ │ │ ├── name: :a
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (7,7)-(7,9) = "in"
+ ├── @ LocalVariableReadNode (location: (7,14)-(7,15))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── @ MatchRequiredNode (location: (9,0)-(9,27))
+ │ ├── value:
+ │ │ @ HashNode (location: (9,0)-(9,13))
+ │ │ ├── opening_loc: (9,0)-(9,1) = "{"
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (9,1)-(9,12))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (9,1)-(9,5))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (9,1)-(9,4) = "key"
+ │ │ │ │ ├── closing_loc: (9,4)-(9,5) = ":"
+ │ │ │ │ └── unescaped: "key"
+ │ │ │ ├── value:
+ │ │ │ │ @ SymbolNode (location: (9,6)-(9,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (9,6)-(9,7) = ":"
+ │ │ │ │ ├── value_loc: (9,7)-(9,12) = "value"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "value"
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (9,12)-(9,13) = "}"
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (9,17)-(9,27))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (9,17)-(9,27))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (9,17)-(9,21))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (9,17)-(9,20) = "key"
+ │ │ │ │ ├── closing_loc: (9,20)-(9,21) = ":"
+ │ │ │ │ └── unescaped: "key"
+ │ │ │ ├── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (9,22)-(9,27))
+ │ │ │ │ ├── name: :value
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (9,14)-(9,16) = "=>"
+ ├── @ LocalVariableReadNode (location: (9,29)-(9,34))
+ │ ├── name: :value
+ │ └── depth: 0
+ ├── @ MatchPredicateNode (location: (11,0)-(11,27))
+ │ ├── value:
+ │ │ @ HashNode (location: (11,0)-(11,13))
+ │ │ ├── opening_loc: (11,0)-(11,1) = "{"
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (11,1)-(11,12))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (11,1)-(11,5))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (11,1)-(11,4) = "key"
+ │ │ │ │ ├── closing_loc: (11,4)-(11,5) = ":"
+ │ │ │ │ └── unescaped: "key"
+ │ │ │ ├── value:
+ │ │ │ │ @ SymbolNode (location: (11,6)-(11,12))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (11,6)-(11,7) = ":"
+ │ │ │ │ ├── value_loc: (11,7)-(11,12) = "value"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "value"
+ │ │ │ └── operator_loc: ∅
+ │ │ └── closing_loc: (11,12)-(11,13) = "}"
+ │ ├── pattern:
+ │ │ @ HashPatternNode (location: (11,17)-(11,27))
+ │ │ ├── constant: ∅
+ │ │ ├── elements: (length: 1)
+ │ │ │ └── @ AssocNode (location: (11,17)-(11,27))
+ │ │ │ ├── key:
+ │ │ │ │ @ SymbolNode (location: (11,17)-(11,21))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── value_loc: (11,17)-(11,20) = "key"
+ │ │ │ │ ├── closing_loc: (11,20)-(11,21) = ":"
+ │ │ │ │ └── unescaped: "key"
+ │ │ │ ├── value:
+ │ │ │ │ @ LocalVariableTargetNode (location: (11,22)-(11,27))
+ │ │ │ │ ├── name: :value
+ │ │ │ │ └── depth: 0
+ │ │ │ └── operator_loc: ∅
+ │ │ ├── rest: ∅
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── operator_loc: (11,14)-(11,16) = "in"
+ └── @ LocalVariableReadNode (location: (11,29)-(11,34))
+ ├── name: :value
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/postexe.txt b/test/prism/snapshots/whitequark/postexe.txt
new file mode 100644
index 0000000000..6f27327063
--- /dev/null
+++ b/test/prism/snapshots/whitequark/postexe.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ PostExecutionNode (location: (1,0)-(1,9))
+ ├── statements:
+ │ @ StatementsNode (location: (1,6)-(1,7))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── keyword_loc: (1,0)-(1,3) = "END"
+ ├── opening_loc: (1,4)-(1,5) = "{"
+ └── closing_loc: (1,8)-(1,9) = "}"
diff --git a/test/prism/snapshots/whitequark/preexe.txt b/test/prism/snapshots/whitequark/preexe.txt
new file mode 100644
index 0000000000..5e4b88d096
--- /dev/null
+++ b/test/prism/snapshots/whitequark/preexe.txt
@@ -0,0 +1,15 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ PreExecutionNode (location: (1,0)-(1,11))
+ ├── statements:
+ │ @ StatementsNode (location: (1,8)-(1,9))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,8)-(1,9))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── keyword_loc: (1,0)-(1,5) = "BEGIN"
+ ├── opening_loc: (1,6)-(1,7) = "{"
+ └── closing_loc: (1,10)-(1,11) = "}"
diff --git a/test/prism/snapshots/whitequark/procarg0.txt b/test/prism/snapshots/whitequark/procarg0.txt
new file mode 100644
index 0000000000..378c7e5b36
--- /dev/null
+++ b/test/prism/snapshots/whitequark/procarg0.txt
@@ -0,0 +1,78 @@
+@ ProgramNode (location: (1,0)-(3,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,11))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,0)-(1,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,2)-(1,18))
+ │ ├── locals: [:foo, :bar]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,4)-(1,16))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,5)-(1,15))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ MultiTargetNode (location: (1,5)-(1,15))
+ │ │ │ │ ├── lefts: (length: 2)
+ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,9))
+ │ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ │ └── name: :foo
+ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,14))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── name: :bar
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── rights: (length: 0)
+ │ │ │ │ ├── lparen_loc: (1,5)-(1,6) = "("
+ │ │ │ │ └── rparen_loc: (1,14)-(1,15) = ")"
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,4)-(1,5) = "|"
+ │ │ └── closing_loc: (1,15)-(1,16) = "|"
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,2)-(1,3) = "{"
+ │ └── closing_loc: (1,17)-(1,18) = "}"
+ └── @ CallNode (location: (3,0)-(3,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (3,0)-(3,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (3,2)-(3,11))
+ ├── locals: [:foo]
+ ├── parameters:
+ │ @ BlockParametersNode (location: (3,4)-(3,9))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,5)-(3,8))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (3,5)-(3,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :foo
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (3,4)-(3,5) = "|"
+ │ └── closing_loc: (3,8)-(3,9) = "|"
+ ├── body: ∅
+ ├── opening_loc: (3,2)-(3,3) = "{"
+ └── closing_loc: (3,10)-(3,11) = "}"
diff --git a/test/prism/snapshots/whitequark/range_exclusive.txt b/test/prism/snapshots/whitequark/range_exclusive.txt
new file mode 100644
index 0000000000..f74077ce67
--- /dev/null
+++ b/test/prism/snapshots/whitequark/range_exclusive.txt
@@ -0,0 +1,16 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ RangeNode (location: (1,0)-(1,5))
+ ├── flags: exclude_end
+ ├── left:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── right:
+ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── operator_loc: (1,1)-(1,4) = "..."
diff --git a/test/prism/snapshots/whitequark/range_inclusive.txt b/test/prism/snapshots/whitequark/range_inclusive.txt
new file mode 100644
index 0000000000..1836312033
--- /dev/null
+++ b/test/prism/snapshots/whitequark/range_inclusive.txt
@@ -0,0 +1,16 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ RangeNode (location: (1,0)-(1,4))
+ ├── flags: ∅
+ ├── left:
+ │ @ IntegerNode (location: (1,0)-(1,1))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── right:
+ │ @ IntegerNode (location: (1,3)-(1,4))
+ │ ├── flags: decimal
+ │ └── value: 2
+ └── operator_loc: (1,1)-(1,3) = ".."
diff --git a/test/prism/snapshots/whitequark/rational.txt b/test/prism/snapshots/whitequark/rational.txt
new file mode 100644
index 0000000000..90bbd17929
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rational.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(3,3))
+├── locals: []
+└── statements:
+ @ 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
+ └── @ RationalNode (location: (3,0)-(3,3))
+ └── numeric:
+ @ IntegerNode (location: (3,0)-(3,2))
+ ├── flags: decimal
+ └── value: 42
diff --git a/test/prism/snapshots/whitequark/regex_interp.txt b/test/prism/snapshots/whitequark/regex_interp.txt
new file mode 100644
index 0000000000..0a6db4cfdf
--- /dev/null
+++ b/test/prism/snapshots/whitequark/regex_interp.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ InterpolatedRegularExpressionNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "/"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (1,1)-(1,4))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,1)-(1,4) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── @ EmbeddedStatementsNode (location: (1,4)-(1,10))
+ │ │ ├── opening_loc: (1,4)-(1,6) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,6)-(1,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,6)-(1,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,6)-(1,9) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,9)-(1,10) = "}"
+ │ └── @ StringNode (location: (1,10)-(1,13))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,10)-(1,13) = "baz"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "baz"
+ └── closing_loc: (1,13)-(1,14) = "/"
diff --git a/test/prism/snapshots/whitequark/regex_plain.txt b/test/prism/snapshots/whitequark/regex_plain.txt
new file mode 100644
index 0000000000..df771f7a21
--- /dev/null
+++ b/test/prism/snapshots/whitequark/regex_plain.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ RegularExpressionNode (location: (1,0)-(1,10))
+ ├── flags: ignore_case, multi_line, forced_us_ascii_encoding
+ ├── opening_loc: (1,0)-(1,1) = "/"
+ ├── content_loc: (1,1)-(1,7) = "source"
+ ├── closing_loc: (1,7)-(1,10) = "/im"
+ └── unescaped: "source"
diff --git a/test/prism/snapshots/whitequark/resbody_list.txt b/test/prism/snapshots/whitequark/resbody_list.txt
new file mode 100644
index 0000000000..52fcfd02e0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/resbody_list.txt
@@ -0,0 +1,45 @@
+@ ProgramNode (location: (1,0)-(1,39))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,39))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,39))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,13)-(1,34))
+ │ ├── keyword_loc: (1,13)-(1,19) = "rescue"
+ │ ├── exceptions: (length: 1)
+ │ │ └── @ ConstantReadNode (location: (1,20)-(1,29))
+ │ │ └── name: :Exception
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,31)-(1,34))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,31)-(1,34))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,31)-(1,34) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,36)-(1,39) = "end"
diff --git a/test/prism/snapshots/whitequark/resbody_list_mrhs.txt b/test/prism/snapshots/whitequark/resbody_list_mrhs.txt
new file mode 100644
index 0000000000..d48ddb120d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/resbody_list_mrhs.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,44))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,44))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,44))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,13)-(1,39))
+ │ ├── keyword_loc: (1,13)-(1,19) = "rescue"
+ │ ├── exceptions: (length: 2)
+ │ │ ├── @ ConstantReadNode (location: (1,20)-(1,29))
+ │ │ │ └── name: :Exception
+ │ │ └── @ CallNode (location: (1,31)-(1,34))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,31)-(1,34) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,36)-(1,39))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,36)-(1,39))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,36)-(1,39) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,41)-(1,44) = "end"
diff --git a/test/prism/snapshots/whitequark/resbody_list_var.txt b/test/prism/snapshots/whitequark/resbody_list_var.txt
new file mode 100644
index 0000000000..85efb1a3de
--- /dev/null
+++ b/test/prism/snapshots/whitequark/resbody_list_var.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(1,39))
+├── locals: [:ex]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,39))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,39))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,13)-(1,34))
+ │ ├── keyword_loc: (1,13)-(1,19) = "rescue"
+ │ ├── exceptions: (length: 1)
+ │ │ └── @ CallNode (location: (1,20)-(1,23))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,20)-(1,23) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── operator_loc: (1,24)-(1,26) = "=>"
+ │ ├── reference:
+ │ │ @ LocalVariableTargetNode (location: (1,27)-(1,29))
+ │ │ ├── name: :ex
+ │ │ └── depth: 0
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,31)-(1,34))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,31)-(1,34))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,31)-(1,34) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,36)-(1,39) = "end"
diff --git a/test/prism/snapshots/whitequark/resbody_var.txt b/test/prism/snapshots/whitequark/resbody_var.txt
new file mode 100644
index 0000000000..e12d921c75
--- /dev/null
+++ b/test/prism/snapshots/whitequark/resbody_var.txt
@@ -0,0 +1,86 @@
+@ ProgramNode (location: (1,0)-(3,35))
+├── locals: [:ex]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,35))
+ └── body: (length: 2)
+ ├── @ BeginNode (location: (1,0)-(1,36))
+ │ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (1,13)-(1,31))
+ │ │ ├── keyword_loc: (1,13)-(1,19) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: (1,20)-(1,22) = "=>"
+ │ │ ├── reference:
+ │ │ │ @ InstanceVariableTargetNode (location: (1,23)-(1,26))
+ │ │ │ └── name: :@ex
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,28)-(1,31))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,28)-(1,31))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,28)-(1,31) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (1,33)-(1,36) = "end"
+ └── @ BeginNode (location: (3,0)-(3,35))
+ ├── begin_keyword_loc: (3,0)-(3,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (3,7)-(3,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (3,7)-(3,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (3,7)-(3,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (3,13)-(3,30))
+ │ ├── keyword_loc: (3,13)-(3,19) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: (3,20)-(3,22) = "=>"
+ │ ├── reference:
+ │ │ @ LocalVariableTargetNode (location: (3,23)-(3,25))
+ │ │ ├── name: :ex
+ │ │ └── depth: 0
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,27)-(3,30))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,27)-(3,30))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,27)-(3,30) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (3,32)-(3,35) = "end"
diff --git a/test/prism/snapshots/whitequark/rescue.txt b/test/prism/snapshots/whitequark/rescue.txt
new file mode 100644
index 0000000000..28c4f11e67
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue.txt
@@ -0,0 +1,43 @@
+@ ProgramNode (location: (1,0)-(1,29))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,29))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,29))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,13)-(1,24))
+ │ ├── keyword_loc: (1,13)-(1,19) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,21)-(1,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,21)-(1,24))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,21)-(1,24) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,26)-(1,29) = "end"
diff --git a/test/prism/snapshots/whitequark/rescue_else.txt b/test/prism/snapshots/whitequark/rescue_else.txt
new file mode 100644
index 0000000000..36b01a7ef6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_else.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(1,40))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,40))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,40))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,13)-(1,24))
+ │ ├── keyword_loc: (1,13)-(1,19) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,21)-(1,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,21)-(1,24))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,21)-(1,24) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause:
+ │ @ ElseNode (location: (1,26)-(1,40))
+ │ ├── else_keyword_loc: (1,26)-(1,30) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,32)-(1,35))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,32)-(1,35))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,32)-(1,35) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (1,37)-(1,40) = "end"
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,37)-(1,40) = "end"
diff --git a/test/prism/snapshots/whitequark/rescue_else_ensure.txt b/test/prism/snapshots/whitequark/rescue_else_ensure.txt
new file mode 100644
index 0000000000..d97821931b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_else_ensure.txt
@@ -0,0 +1,75 @@
+@ ProgramNode (location: (1,0)-(1,51))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,51))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,51))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,13)-(1,24))
+ │ ├── keyword_loc: (1,13)-(1,19) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,21)-(1,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,21)-(1,24))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (1,21)-(1,24) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause:
+ │ @ ElseNode (location: (1,26)-(1,42))
+ │ ├── else_keyword_loc: (1,26)-(1,30) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,31)-(1,34))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,31)-(1,34))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,31)-(1,34) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (1,36)-(1,42) = "ensure"
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (1,36)-(1,51))
+ │ ├── ensure_keyword_loc: (1,36)-(1,42) = "ensure"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,44)-(1,47))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,44)-(1,47))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,44)-(1,47) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (1,48)-(1,51) = "end"
+ └── end_keyword_loc: (1,48)-(1,51) = "end"
diff --git a/test/prism/snapshots/whitequark/rescue_ensure.txt b/test/prism/snapshots/whitequark/rescue_ensure.txt
new file mode 100644
index 0000000000..f6cddbcc5e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_ensure.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(1,42))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,42))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,42))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,7)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,7)-(1,11))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,13)-(1,24))
+ │ ├── keyword_loc: (1,13)-(1,19) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,21)-(1,24))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,21)-(1,24))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (1,21)-(1,24) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause:
+ │ @ EnsureNode (location: (1,26)-(1,42))
+ │ ├── ensure_keyword_loc: (1,26)-(1,32) = "ensure"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,34)-(1,37))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,34)-(1,37))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,34)-(1,37) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (1,39)-(1,42) = "end"
+ └── end_keyword_loc: (1,39)-(1,42) = "end"
diff --git a/test/prism/snapshots/whitequark/rescue_in_lambda_block.txt b/test/prism/snapshots/whitequark/rescue_in_lambda_block.txt
new file mode 100644
index 0000000000..2ab854cdd7
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_in_lambda_block.txt
@@ -0,0 +1,26 @@
+@ ProgramNode (location: (1,0)-(1,17))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,17))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,17))
+ ├── locals: []
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,3)-(1,5) = "do"
+ ├── closing_loc: (1,14)-(1,17) = "end"
+ ├── parameters: ∅
+ └── body:
+ @ BeginNode (location: (1,3)-(1,17))
+ ├── begin_keyword_loc: ∅
+ ├── statements: ∅
+ ├── rescue_clause:
+ │ @ RescueNode (location: (1,6)-(1,12))
+ │ ├── keyword_loc: (1,6)-(1,12) = "rescue"
+ │ ├── exceptions: (length: 0)
+ │ ├── operator_loc: ∅
+ │ ├── reference: ∅
+ │ ├── statements: ∅
+ │ └── consequent: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,14)-(1,17) = "end"
diff --git a/test/prism/snapshots/whitequark/rescue_mod.txt b/test/prism/snapshots/whitequark/rescue_mod.txt
new file mode 100644
index 0000000000..cd4f0fff45
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_mod.txt
@@ -0,0 +1,29 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ RescueModifierNode (location: (1,0)-(1,15))
+ ├── expression:
+ │ @ CallNode (location: (1,0)-(1,4))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,0)-(1,4) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── keyword_loc: (1,5)-(1,11) = "rescue"
+ └── rescue_expression:
+ @ CallNode (location: (1,12)-(1,15))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :bar
+ ├── message_loc: (1,12)-(1,15) = "bar"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/rescue_mod_asgn.txt b/test/prism/snapshots/whitequark/rescue_mod_asgn.txt
new file mode 100644
index 0000000000..ee094138e5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_mod_asgn.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,21))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,21))
+ └── body: (length: 1)
+ └── @ LocalVariableWriteNode (location: (1,0)-(1,21))
+ ├── name: :foo
+ ├── depth: 0
+ ├── name_loc: (1,0)-(1,3) = "foo"
+ ├── value:
+ │ @ RescueModifierNode (location: (1,6)-(1,21))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,6)-(1,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (1,6)-(1,10) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,11)-(1,17) = "rescue"
+ │ └── rescue_expression:
+ │ @ CallNode (location: (1,18)-(1,21))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,18)-(1,21) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── operator_loc: (1,4)-(1,5) = "="
diff --git a/test/prism/snapshots/whitequark/rescue_mod_masgn.txt b/test/prism/snapshots/whitequark/rescue_mod_masgn.txt
new file mode 100644
index 0000000000..dbe289702f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_mod_masgn.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(1,29))
+├── locals: [:foo, :bar]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,29))
+ └── body: (length: 1)
+ └── @ MultiWriteNode (location: (1,0)-(1,29))
+ ├── lefts: (length: 2)
+ │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ └── @ LocalVariableTargetNode (location: (1,5)-(1,8))
+ │ ├── name: :bar
+ │ └── depth: 0
+ ├── rest: ∅
+ ├── rights: (length: 0)
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── operator_loc: (1,9)-(1,10) = "="
+ └── value:
+ @ RescueModifierNode (location: (1,11)-(1,29))
+ ├── expression:
+ │ @ CallNode (location: (1,11)-(1,15))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,11)-(1,15) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── keyword_loc: (1,16)-(1,22) = "rescue"
+ └── rescue_expression:
+ @ ArrayNode (location: (1,23)-(1,29))
+ ├── flags: ∅
+ ├── elements: (length: 2)
+ │ ├── @ IntegerNode (location: (1,24)-(1,25))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ IntegerNode (location: (1,27)-(1,28))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── opening_loc: (1,23)-(1,24) = "["
+ └── closing_loc: (1,28)-(1,29) = "]"
diff --git a/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
new file mode 100644
index 0000000000..b269104f30
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,22))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,22))
+ └── body: (length: 1)
+ └── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,22))
+ ├── name_loc: (1,0)-(1,3) = "foo"
+ ├── operator_loc: (1,4)-(1,6) = "+="
+ ├── value:
+ │ @ RescueModifierNode (location: (1,7)-(1,22))
+ │ ├── expression:
+ │ │ @ CallNode (location: (1,7)-(1,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (1,7)-(1,11) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (1,12)-(1,18) = "rescue"
+ │ └── rescue_expression:
+ │ @ CallNode (location: (1,19)-(1,22))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,19)-(1,22) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── name: :foo
+ ├── operator: :+
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/rescue_without_begin_end.txt b/test/prism/snapshots/whitequark/rescue_without_begin_end.txt
new file mode 100644
index 0000000000..4281442ab2
--- /dev/null
+++ b/test/prism/snapshots/whitequark/rescue_without_begin_end.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(1,30))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,30))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,30))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :meth
+ ├── message_loc: (1,0)-(1,4) = "meth"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,5)-(1,30))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ BeginNode (location: (1,5)-(1,30))
+ │ ├── begin_keyword_loc: ∅
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,9)-(1,12))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,9)-(1,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,9)-(1,12) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rescue_clause:
+ │ │ @ RescueNode (location: (1,14)-(1,25))
+ │ │ ├── keyword_loc: (1,14)-(1,20) = "rescue"
+ │ │ ├── exceptions: (length: 0)
+ │ │ ├── operator_loc: ∅
+ │ │ ├── reference: ∅
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,22)-(1,25))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,22)-(1,25))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,22)-(1,25) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── consequent: ∅
+ │ ├── else_clause: ∅
+ │ ├── ensure_clause: ∅
+ │ └── end_keyword_loc: (1,27)-(1,30) = "end"
+ ├── opening_loc: (1,5)-(1,7) = "do"
+ └── closing_loc: (1,27)-(1,30) = "end"
diff --git a/test/prism/snapshots/whitequark/restarg_named.txt b/test/prism/snapshots/whitequark/restarg_named.txt
new file mode 100644
index 0000000000..fab9dd9a79
--- /dev/null
+++ b/test/prism/snapshots/whitequark/restarg_named.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,16))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,10))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (1,6)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ ├── name: :foo
+ │ │ ├── name_loc: (1,7)-(1,10) = "foo"
+ │ │ └── operator_loc: (1,6)-(1,7) = "*"
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: [:foo]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,10)-(1,11) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,13)-(1,16) = "end"
diff --git a/test/prism/snapshots/whitequark/restarg_unnamed.txt b/test/prism/snapshots/whitequark/restarg_unnamed.txt
new file mode 100644
index 0000000000..077230f7ba
--- /dev/null
+++ b/test/prism/snapshots/whitequark/restarg_unnamed.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,13))
+ ├── name: :f
+ ├── name_loc: (1,4)-(1,5) = "f"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,6)-(1,7))
+ │ ├── requireds: (length: 0)
+ │ ├── optionals: (length: 0)
+ │ ├── rest:
+ │ │ @ RestParameterNode (location: (1,6)-(1,7))
+ │ │ ├── flags: ∅
+ │ │ ├── name: ∅
+ │ │ ├── name_loc: ∅
+ │ │ └── operator_loc: (1,6)-(1,7) = "*"
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body: ∅
+ ├── locals: []
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,5)-(1,6) = "("
+ ├── rparen_loc: (1,7)-(1,8) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,10)-(1,13) = "end"
diff --git a/test/prism/snapshots/whitequark/return.txt b/test/prism/snapshots/whitequark/return.txt
new file mode 100644
index 0000000000..ddfbae85c8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/return.txt
@@ -0,0 +1,56 @@
+@ ProgramNode (location: (1,0)-(7,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,11))
+ └── body: (length: 4)
+ ├── @ ReturnNode (location: (1,0)-(1,6))
+ │ ├── keyword_loc: (1,0)-(1,6) = "return"
+ │ └── arguments: ∅
+ ├── @ ReturnNode (location: (3,0)-(3,10))
+ │ ├── keyword_loc: (3,0)-(3,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (3,7)-(3,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (3,7)-(3,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,7)-(3,10) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ReturnNode (location: (5,0)-(5,8))
+ │ ├── keyword_loc: (5,0)-(5,6) = "return"
+ │ └── arguments:
+ │ @ ArgumentsNode (location: (5,6)-(5,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (5,6)-(5,8))
+ │ ├── body: ∅
+ │ ├── opening_loc: (5,6)-(5,7) = "("
+ │ └── closing_loc: (5,7)-(5,8) = ")"
+ └── @ ReturnNode (location: (7,0)-(7,11))
+ ├── keyword_loc: (7,0)-(7,6) = "return"
+ └── arguments:
+ @ ArgumentsNode (location: (7,6)-(7,11))
+ ├── flags: ∅
+ └── arguments: (length: 1)
+ └── @ ParenthesesNode (location: (7,6)-(7,11))
+ ├── body:
+ │ @ StatementsNode (location: (7,7)-(7,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (7,7)-(7,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (7,7)-(7,10) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── opening_loc: (7,6)-(7,7) = "("
+ └── closing_loc: (7,10)-(7,11) = ")"
diff --git a/test/prism/snapshots/whitequark/return_block.txt b/test/prism/snapshots/whitequark/return_block.txt
new file mode 100644
index 0000000000..5b8141e4f3
--- /dev/null
+++ b/test/prism/snapshots/whitequark/return_block.txt
@@ -0,0 +1,40 @@
+@ ProgramNode (location: (1,0)-(1,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,21))
+ └── body: (length: 1)
+ └── @ ReturnNode (location: (1,0)-(1,21))
+ ├── keyword_loc: (1,0)-(1,6) = "return"
+ └── arguments:
+ @ ArgumentsNode (location: (1,7)-(1,21))
+ ├── flags: ∅
+ └── arguments: (length: 1)
+ └── @ CallNode (location: (1,7)-(1,21))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (1,7)-(1,10) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,11)-(1,14))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,11)-(1,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,11)-(1,14) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,15)-(1,21))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,15)-(1,17) = "do"
+ └── closing_loc: (1,18)-(1,21) = "end"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_10279.txt b/test/prism/snapshots/whitequark/ruby_bug_10279.txt
new file mode 100644
index 0000000000..66684350a4
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_10279.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ HashNode (location: (1,0)-(1,24))
+ ├── opening_loc: (1,0)-(1,1) = "{"
+ ├── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,1)-(1,23))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,1)-(1,3))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,1)-(1,2) = "a"
+ │ │ ├── closing_loc: (1,2)-(1,3) = ":"
+ │ │ └── unescaped: "a"
+ │ ├── value:
+ │ │ @ IfNode (location: (1,4)-(1,23))
+ │ │ ├── if_keyword_loc: (1,4)-(1,6) = "if"
+ │ │ ├── predicate:
+ │ │ │ @ TrueNode (location: (1,7)-(1,11))
+ │ │ ├── then_keyword_loc: (1,12)-(1,16) = "then"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,17)-(1,19))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,17)-(1,19))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ ├── consequent: ∅
+ │ │ └── end_keyword_loc: (1,20)-(1,23) = "end"
+ │ └── operator_loc: ∅
+ └── closing_loc: (1,23)-(1,24) = "}"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_10653.txt b/test/prism/snapshots/whitequark/ruby_bug_10653.txt
new file mode 100644
index 0000000000..400a8c2861
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_10653.txt
@@ -0,0 +1,173 @@
+@ ProgramNode (location: (1,0)-(5,31))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,31))
+ └── body: (length: 3)
+ ├── @ IfNode (location: (1,0)-(1,33))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ FalseNode (location: (1,0)-(1,5))
+ │ ├── then_keyword_loc: (1,6)-(1,7) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,8)-(1,20))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,8)-(1,20))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (1,8)-(1,13) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,14)-(1,20))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (1,14)-(1,16) = "do"
+ │ │ └── closing_loc: (1,17)-(1,20) = "end"
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (1,21)-(1,33))
+ │ │ ├── else_keyword_loc: (1,21)-(1,22) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,23)-(1,33))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,23)-(1,33))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :tap
+ │ │ │ ├── message_loc: (1,23)-(1,26) = "tap"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (1,27)-(1,33))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (1,27)-(1,29) = "do"
+ │ │ │ └── closing_loc: (1,30)-(1,33) = "end"
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ ├── @ IfNode (location: (3,0)-(3,25))
+ │ ├── if_keyword_loc: ∅
+ │ ├── predicate:
+ │ │ @ FalseNode (location: (3,0)-(3,5))
+ │ ├── then_keyword_loc: (3,6)-(3,7) = "?"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,8)-(3,16))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,8)-(3,16))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (3,8)-(3,13) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (3,14)-(3,16))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (3,14)-(3,15) = "{"
+ │ │ └── closing_loc: (3,15)-(3,16) = "}"
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (3,17)-(3,25))
+ │ │ ├── else_keyword_loc: (3,17)-(3,18) = ":"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (3,19)-(3,25))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (3,19)-(3,25))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :tap
+ │ │ │ ├── message_loc: (3,19)-(3,22) = "tap"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (3,23)-(3,25))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body: ∅
+ │ │ │ ├── opening_loc: (3,23)-(3,24) = "{"
+ │ │ │ └── closing_loc: (3,24)-(3,25) = "}"
+ │ │ └── end_keyword_loc: ∅
+ │ └── end_keyword_loc: ∅
+ └── @ IfNode (location: (5,0)-(5,31))
+ ├── if_keyword_loc: ∅
+ ├── predicate:
+ │ @ TrueNode (location: (5,0)-(5,4))
+ ├── then_keyword_loc: (5,5)-(5,6) = "?"
+ ├── statements:
+ │ @ StatementsNode (location: (5,7)-(5,27))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (5,7)-(5,27))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ IntegerNode (location: (5,7)-(5,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── call_operator_loc: (5,8)-(5,9) = "."
+ │ ├── name: :tap
+ │ ├── message_loc: (5,9)-(5,12) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,13)-(5,27))
+ │ ├── locals: [:n]
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (5,16)-(5,19))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (5,17)-(5,18))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (5,17)-(5,18))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :n
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (5,16)-(5,17) = "|"
+ │ │ └── closing_loc: (5,18)-(5,19) = "|"
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,20)-(5,23))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (5,20)-(5,23))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :p
+ │ │ ├── message_loc: (5,20)-(5,21) = "p"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,22)-(5,23))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ LocalVariableReadNode (location: (5,22)-(5,23))
+ │ │ │ ├── name: :n
+ │ │ │ └── depth: 0
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (5,13)-(5,15) = "do"
+ │ └── closing_loc: (5,24)-(5,27) = "end"
+ ├── consequent:
+ │ @ ElseNode (location: (5,28)-(5,31))
+ │ ├── else_keyword_loc: (5,28)-(5,29) = ":"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (5,30)-(5,31))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,30)-(5,31))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ └── end_keyword_loc: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11107.txt b/test/prism/snapshots/whitequark/ruby_bug_11107.txt
new file mode 100644
index 0000000000..36ece50d88
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_11107.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,24))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,24))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LambdaNode (location: (1,2)-(1,24))
+ │ ├── locals: []
+ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ ├── opening_loc: (1,7)-(1,9) = "do"
+ │ ├── closing_loc: (1,21)-(1,24) = "end"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,4)-(1,6))
+ │ │ ├── parameters: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ │ └── closing_loc: (1,5)-(1,6) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (1,10)-(1,20))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,10)-(1,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,10)-(1,11) = "a"
+ │ ├── opening_loc: (1,11)-(1,12) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (1,12)-(1,13) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (1,14)-(1,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,14)-(1,16) = "do"
+ │ └── closing_loc: (1,17)-(1,20) = "end"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11380.txt b/test/prism/snapshots/whitequark/ruby_bug_11380.txt
new file mode 100644
index 0000000000..b7a7ef9a98
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_11380.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,28))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,28))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,21))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ LambdaNode (location: (1,2)-(1,15))
+ │ │ ├── locals: []
+ │ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ │ ├── opening_loc: (1,5)-(1,6) = "{"
+ │ │ ├── closing_loc: (1,14)-(1,15) = "}"
+ │ │ ├── parameters: ∅
+ │ │ └── body:
+ │ │ @ StatementsNode (location: (1,7)-(1,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ SymbolNode (location: (1,7)-(1,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,7)-(1,8) = ":"
+ │ │ ├── value_loc: (1,8)-(1,13) = "hello"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "hello"
+ │ └── @ KeywordHashNode (location: (1,17)-(1,21))
+ │ ├── flags: symbol_keys
+ │ └── elements: (length: 1)
+ │ └── @ AssocNode (location: (1,17)-(1,21))
+ │ ├── key:
+ │ │ @ SymbolNode (location: (1,17)-(1,19))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,17)-(1,18) = "a"
+ │ │ ├── closing_loc: (1,18)-(1,19) = ":"
+ │ │ └── unescaped: "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,20)-(1,21))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,22)-(1,28))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,22)-(1,24) = "do"
+ └── closing_loc: (1,25)-(1,28) = "end"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11873.txt b/test/prism/snapshots/whitequark/ruby_bug_11873.txt
new file mode 100644
index 0000000000..2999662cc4
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_11873.txt
@@ -0,0 +1,767 @@
+@ ProgramNode (location: (1,0)-(23,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(23,22))
+ └── body: (length: 12)
+ ├── @ CallNode (location: (1,0)-(1,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (1,2)-(1,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,2)-(1,3) = "b"
+ │ │ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,4)-(1,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,4)-(1,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (1,4)-(1,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (1,6)-(1,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (1,6)-(1,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ StringNode (location: (1,10)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,10)-(1,11) = "\""
+ │ │ ├── content_loc: (1,11)-(1,12) = "x"
+ │ │ ├── closing_loc: (1,12)-(1,13) = "\""
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,14)-(1,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,14)-(1,16) = "do"
+ │ └── closing_loc: (1,17)-(1,20) = "end"
+ ├── @ CallNode (location: (3,0)-(3,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (3,0)-(3,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,2)-(3,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (3,2)-(3,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (3,2)-(3,3) = "b"
+ │ │ │ ├── opening_loc: (3,3)-(3,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (3,4)-(3,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (3,4)-(3,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (3,4)-(3,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (3,6)-(3,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (3,6)-(3,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (3,6)-(3,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (3,7)-(3,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ RegularExpressionNode (location: (3,10)-(3,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (3,10)-(3,11) = "/"
+ │ │ ├── content_loc: (3,11)-(3,12) = "x"
+ │ │ ├── closing_loc: (3,12)-(3,13) = "/"
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,14)-(3,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (3,14)-(3,16) = "do"
+ │ └── closing_loc: (3,17)-(3,20) = "end"
+ ├── @ CallNode (location: (5,0)-(5,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (5,0)-(5,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,2)-(5,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (5,2)-(5,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (5,2)-(5,3) = "b"
+ │ │ │ ├── opening_loc: (5,3)-(5,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (5,4)-(5,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (5,4)-(5,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (5,4)-(5,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (5,6)-(5,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (5,6)-(5,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (5,6)-(5,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (5,7)-(5,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ RegularExpressionNode (location: (5,10)-(5,14))
+ │ │ ├── flags: multi_line, forced_us_ascii_encoding
+ │ │ ├── opening_loc: (5,10)-(5,11) = "/"
+ │ │ ├── content_loc: (5,11)-(5,12) = "x"
+ │ │ ├── closing_loc: (5,12)-(5,14) = "/m"
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,15)-(5,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (5,15)-(5,17) = "do"
+ │ └── closing_loc: (5,18)-(5,21) = "end"
+ ├── @ CallNode (location: (7,0)-(7,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (7,0)-(7,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,2)-(7,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (7,2)-(7,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (7,2)-(7,3) = "b"
+ │ │ │ ├── opening_loc: (7,3)-(7,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (7,4)-(7,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (7,4)-(7,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (7,4)-(7,5) = "c"
+ │ │ │ │ ├── opening_loc: (7,5)-(7,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (7,6)-(7,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (7,6)-(7,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (7,6)-(7,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (7,7)-(7,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (7,8)-(7,9) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ StringNode (location: (7,11)-(7,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (7,11)-(7,12) = "\""
+ │ │ ├── content_loc: (7,12)-(7,13) = "x"
+ │ │ ├── closing_loc: (7,13)-(7,14) = "\""
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (7,15)-(7,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (7,15)-(7,17) = "do"
+ │ └── closing_loc: (7,18)-(7,21) = "end"
+ ├── @ CallNode (location: (9,0)-(9,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (9,0)-(9,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,2)-(9,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (9,2)-(9,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (9,2)-(9,3) = "b"
+ │ │ │ ├── opening_loc: (9,3)-(9,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (9,4)-(9,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (9,4)-(9,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (9,4)-(9,5) = "c"
+ │ │ │ │ ├── opening_loc: (9,5)-(9,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (9,6)-(9,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (9,6)-(9,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (9,6)-(9,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (9,7)-(9,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (9,8)-(9,9) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ RegularExpressionNode (location: (9,11)-(9,14))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (9,11)-(9,12) = "/"
+ │ │ ├── content_loc: (9,12)-(9,13) = "x"
+ │ │ ├── closing_loc: (9,13)-(9,14) = "/"
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (9,15)-(9,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (9,15)-(9,17) = "do"
+ │ └── closing_loc: (9,18)-(9,21) = "end"
+ ├── @ CallNode (location: (11,0)-(11,22))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (11,0)-(11,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,2)-(11,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (11,2)-(11,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (11,2)-(11,3) = "b"
+ │ │ │ ├── opening_loc: (11,3)-(11,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (11,4)-(11,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (11,4)-(11,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (11,4)-(11,5) = "c"
+ │ │ │ │ ├── opening_loc: (11,5)-(11,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (11,6)-(11,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (11,6)-(11,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (11,6)-(11,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (11,7)-(11,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (11,8)-(11,9) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ RegularExpressionNode (location: (11,11)-(11,15))
+ │ │ ├── flags: multi_line, forced_us_ascii_encoding
+ │ │ ├── opening_loc: (11,11)-(11,12) = "/"
+ │ │ ├── content_loc: (11,12)-(11,13) = "x"
+ │ │ ├── closing_loc: (11,13)-(11,15) = "/m"
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (11,16)-(11,22))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (11,16)-(11,18) = "do"
+ │ └── closing_loc: (11,19)-(11,22) = "end"
+ ├── @ CallNode (location: (13,0)-(13,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (13,0)-(13,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,2)-(13,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (13,2)-(13,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (13,2)-(13,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (13,3)-(13,8))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (13,4)-(13,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (13,4)-(13,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (13,4)-(13,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (13,6)-(13,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (13,6)-(13,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (13,6)-(13,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (13,3)-(13,4) = "{"
+ │ │ │ └── closing_loc: (13,7)-(13,8) = "}"
+ │ │ └── @ StringNode (location: (13,10)-(13,13))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (13,10)-(13,11) = "\""
+ │ │ ├── content_loc: (13,11)-(13,12) = "x"
+ │ │ ├── closing_loc: (13,12)-(13,13) = "\""
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (13,14)-(13,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (13,14)-(13,16) = "do"
+ │ └── closing_loc: (13,17)-(13,20) = "end"
+ ├── @ CallNode (location: (15,0)-(15,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (15,0)-(15,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,2)-(15,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (15,2)-(15,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (15,2)-(15,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (15,3)-(15,8))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (15,4)-(15,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (15,4)-(15,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (15,4)-(15,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (15,6)-(15,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (15,6)-(15,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (15,6)-(15,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (15,3)-(15,4) = "{"
+ │ │ │ └── closing_loc: (15,7)-(15,8) = "}"
+ │ │ └── @ RegularExpressionNode (location: (15,10)-(15,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (15,10)-(15,11) = "/"
+ │ │ ├── content_loc: (15,11)-(15,12) = "x"
+ │ │ ├── closing_loc: (15,12)-(15,13) = "/"
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (15,14)-(15,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (15,14)-(15,16) = "do"
+ │ └── closing_loc: (15,17)-(15,20) = "end"
+ ├── @ CallNode (location: (17,0)-(17,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (17,0)-(17,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (17,2)-(17,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (17,2)-(17,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (17,2)-(17,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (17,3)-(17,8))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (17,4)-(17,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (17,4)-(17,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (17,4)-(17,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (17,6)-(17,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (17,6)-(17,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (17,6)-(17,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (17,3)-(17,4) = "{"
+ │ │ │ └── closing_loc: (17,7)-(17,8) = "}"
+ │ │ └── @ RegularExpressionNode (location: (17,10)-(17,14))
+ │ │ ├── flags: multi_line, forced_us_ascii_encoding
+ │ │ ├── opening_loc: (17,10)-(17,11) = "/"
+ │ │ ├── content_loc: (17,11)-(17,12) = "x"
+ │ │ ├── closing_loc: (17,12)-(17,14) = "/m"
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (17,15)-(17,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (17,15)-(17,17) = "do"
+ │ └── closing_loc: (17,18)-(17,21) = "end"
+ ├── @ CallNode (location: (19,0)-(19,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (19,0)-(19,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (19,2)-(19,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (19,2)-(19,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (19,2)-(19,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (19,3)-(19,9))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (19,4)-(19,8))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (19,4)-(19,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (19,4)-(19,5) = "c"
+ │ │ │ │ ├── opening_loc: (19,5)-(19,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (19,6)-(19,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (19,6)-(19,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (19,6)-(19,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (19,7)-(19,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (19,3)-(19,4) = "{"
+ │ │ │ └── closing_loc: (19,8)-(19,9) = "}"
+ │ │ └── @ StringNode (location: (19,11)-(19,14))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (19,11)-(19,12) = "\""
+ │ │ ├── content_loc: (19,12)-(19,13) = "x"
+ │ │ ├── closing_loc: (19,13)-(19,14) = "\""
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (19,15)-(19,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (19,15)-(19,17) = "do"
+ │ └── closing_loc: (19,18)-(19,21) = "end"
+ ├── @ CallNode (location: (21,0)-(21,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (21,0)-(21,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (21,2)-(21,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (21,2)-(21,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (21,2)-(21,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (21,3)-(21,9))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (21,4)-(21,8))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (21,4)-(21,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (21,4)-(21,5) = "c"
+ │ │ │ │ ├── opening_loc: (21,5)-(21,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (21,6)-(21,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (21,6)-(21,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (21,6)-(21,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (21,7)-(21,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (21,3)-(21,4) = "{"
+ │ │ │ └── closing_loc: (21,8)-(21,9) = "}"
+ │ │ └── @ RegularExpressionNode (location: (21,11)-(21,14))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (21,11)-(21,12) = "/"
+ │ │ ├── content_loc: (21,12)-(21,13) = "x"
+ │ │ ├── closing_loc: (21,13)-(21,14) = "/"
+ │ │ └── unescaped: "x"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (21,15)-(21,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (21,15)-(21,17) = "do"
+ │ └── closing_loc: (21,18)-(21,21) = "end"
+ └── @ CallNode (location: (23,0)-(23,22))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (23,0)-(23,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (23,2)-(23,15))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (23,2)-(23,9))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (23,2)-(23,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (23,3)-(23,9))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (23,4)-(23,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (23,4)-(23,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (23,4)-(23,5) = "c"
+ │ │ │ ├── opening_loc: (23,5)-(23,6) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (23,6)-(23,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (23,6)-(23,7))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :d
+ │ │ │ │ ├── message_loc: (23,6)-(23,7) = "d"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (23,7)-(23,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (23,3)-(23,4) = "{"
+ │ │ └── closing_loc: (23,8)-(23,9) = "}"
+ │ └── @ RegularExpressionNode (location: (23,11)-(23,15))
+ │ ├── flags: multi_line, forced_us_ascii_encoding
+ │ ├── opening_loc: (23,11)-(23,12) = "/"
+ │ ├── content_loc: (23,12)-(23,13) = "x"
+ │ ├── closing_loc: (23,13)-(23,15) = "/m"
+ │ └── unescaped: "x"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (23,16)-(23,22))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (23,16)-(23,18) = "do"
+ └── closing_loc: (23,19)-(23,22) = "end"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt b/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt
new file mode 100644
index 0000000000..93418e6448
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt
@@ -0,0 +1,1231 @@
+@ ProgramNode (location: (1,0)-(39,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(39,20))
+ └── body: (length: 20)
+ ├── @ CallNode (location: (1,0)-(1,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (1,2)-(1,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (1,2)-(1,3) = "b"
+ │ │ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,4)-(1,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,4)-(1,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (1,4)-(1,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (1,6)-(1,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (1,6)-(1,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (1,7)-(1,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,12)-(1,18))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,12)-(1,14) = "do"
+ │ └── closing_loc: (1,15)-(1,18) = "end"
+ ├── @ CallNode (location: (3,0)-(3,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (3,0)-(3,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,2)-(3,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (3,2)-(3,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (3,2)-(3,3) = "b"
+ │ │ │ ├── opening_loc: (3,3)-(3,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (3,4)-(3,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (3,4)-(3,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (3,4)-(3,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (3,6)-(3,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (3,6)-(3,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (3,6)-(3,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (3,7)-(3,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ FloatNode (location: (3,10)-(3,13))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,14)-(3,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (3,14)-(3,16) = "do"
+ │ └── closing_loc: (3,17)-(3,20) = "end"
+ ├── @ CallNode (location: (5,0)-(5,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (5,0)-(5,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,2)-(5,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (5,2)-(5,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (5,2)-(5,3) = "b"
+ │ │ │ ├── opening_loc: (5,3)-(5,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (5,4)-(5,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (5,4)-(5,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (5,4)-(5,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (5,6)-(5,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (5,6)-(5,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (5,6)-(5,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (5,7)-(5,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ ImaginaryNode (location: (5,10)-(5,14))
+ │ │ └── numeric:
+ │ │ @ FloatNode (location: (5,10)-(5,13))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,15)-(5,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (5,15)-(5,17) = "do"
+ │ └── closing_loc: (5,18)-(5,21) = "end"
+ ├── @ CallNode (location: (7,0)-(7,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (7,0)-(7,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,2)-(7,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (7,2)-(7,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (7,2)-(7,3) = "b"
+ │ │ │ ├── opening_loc: (7,3)-(7,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (7,4)-(7,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (7,4)-(7,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (7,4)-(7,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (7,6)-(7,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (7,6)-(7,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (7,6)-(7,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (7,7)-(7,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ RationalNode (location: (7,10)-(7,14))
+ │ │ └── numeric:
+ │ │ @ FloatNode (location: (7,10)-(7,13))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (7,15)-(7,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (7,15)-(7,17) = "do"
+ │ └── closing_loc: (7,18)-(7,21) = "end"
+ ├── @ CallNode (location: (9,0)-(9,19))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (9,0)-(9,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,2)-(9,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (9,2)-(9,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (9,2)-(9,3) = "b"
+ │ │ │ ├── opening_loc: (9,3)-(9,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (9,4)-(9,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (9,4)-(9,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (9,4)-(9,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (9,6)-(9,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (9,6)-(9,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (9,6)-(9,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (9,7)-(9,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ SymbolNode (location: (9,10)-(9,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (9,10)-(9,11) = ":"
+ │ │ ├── value_loc: (9,11)-(9,12) = "e"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "e"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (9,13)-(9,19))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (9,13)-(9,15) = "do"
+ │ └── closing_loc: (9,16)-(9,19) = "end"
+ ├── @ CallNode (location: (11,0)-(11,19))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (11,0)-(11,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,2)-(11,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (11,2)-(11,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (11,2)-(11,3) = "b"
+ │ │ │ ├── opening_loc: (11,3)-(11,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (11,4)-(11,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (11,4)-(11,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (11,4)-(11,5) = "c"
+ │ │ │ │ ├── opening_loc: (11,5)-(11,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (11,6)-(11,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (11,6)-(11,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (11,6)-(11,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (11,7)-(11,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (11,8)-(11,9) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ IntegerNode (location: (11,11)-(11,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (11,13)-(11,19))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (11,13)-(11,15) = "do"
+ │ └── closing_loc: (11,16)-(11,19) = "end"
+ ├── @ CallNode (location: (13,0)-(13,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (13,0)-(13,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,2)-(13,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (13,2)-(13,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (13,2)-(13,3) = "b"
+ │ │ │ ├── opening_loc: (13,3)-(13,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (13,4)-(13,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (13,4)-(13,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (13,4)-(13,5) = "c"
+ │ │ │ │ ├── opening_loc: (13,5)-(13,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (13,6)-(13,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (13,6)-(13,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (13,6)-(13,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (13,7)-(13,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (13,8)-(13,9) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ FloatNode (location: (13,11)-(13,14))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (13,15)-(13,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (13,15)-(13,17) = "do"
+ │ └── closing_loc: (13,18)-(13,21) = "end"
+ ├── @ CallNode (location: (15,0)-(15,22))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (15,0)-(15,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,2)-(15,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (15,2)-(15,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (15,2)-(15,3) = "b"
+ │ │ │ ├── opening_loc: (15,3)-(15,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (15,4)-(15,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (15,4)-(15,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (15,4)-(15,5) = "c"
+ │ │ │ │ ├── opening_loc: (15,5)-(15,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (15,6)-(15,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (15,6)-(15,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (15,6)-(15,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (15,7)-(15,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (15,8)-(15,9) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ ImaginaryNode (location: (15,11)-(15,15))
+ │ │ └── numeric:
+ │ │ @ FloatNode (location: (15,11)-(15,14))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (15,16)-(15,22))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (15,16)-(15,18) = "do"
+ │ └── closing_loc: (15,19)-(15,22) = "end"
+ ├── @ CallNode (location: (17,0)-(17,22))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (17,0)-(17,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (17,2)-(17,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (17,2)-(17,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (17,2)-(17,3) = "b"
+ │ │ │ ├── opening_loc: (17,3)-(17,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (17,4)-(17,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (17,4)-(17,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (17,4)-(17,5) = "c"
+ │ │ │ │ ├── opening_loc: (17,5)-(17,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (17,6)-(17,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (17,6)-(17,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (17,6)-(17,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (17,7)-(17,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (17,8)-(17,9) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ RationalNode (location: (17,11)-(17,15))
+ │ │ └── numeric:
+ │ │ @ FloatNode (location: (17,11)-(17,14))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (17,16)-(17,22))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (17,16)-(17,18) = "do"
+ │ └── closing_loc: (17,19)-(17,22) = "end"
+ ├── @ CallNode (location: (19,0)-(19,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (19,0)-(19,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (19,2)-(19,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (19,2)-(19,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (19,2)-(19,3) = "b"
+ │ │ │ ├── opening_loc: (19,3)-(19,4) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (19,4)-(19,8))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (19,4)-(19,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (19,4)-(19,5) = "c"
+ │ │ │ │ ├── opening_loc: (19,5)-(19,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (19,6)-(19,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (19,6)-(19,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (19,6)-(19,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (19,7)-(19,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (19,8)-(19,9) = ")"
+ │ │ │ └── block: ∅
+ │ │ └── @ SymbolNode (location: (19,11)-(19,13))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (19,11)-(19,12) = ":"
+ │ │ ├── value_loc: (19,12)-(19,13) = "e"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "e"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (19,14)-(19,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (19,14)-(19,16) = "do"
+ │ └── closing_loc: (19,17)-(19,20) = "end"
+ ├── @ CallNode (location: (21,0)-(21,18))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (21,0)-(21,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (21,2)-(21,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (21,2)-(21,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (21,2)-(21,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (21,3)-(21,8))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (21,4)-(21,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (21,4)-(21,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (21,4)-(21,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (21,6)-(21,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (21,6)-(21,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (21,6)-(21,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (21,3)-(21,4) = "{"
+ │ │ │ └── closing_loc: (21,7)-(21,8) = "}"
+ │ │ └── @ IntegerNode (location: (21,10)-(21,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (21,12)-(21,18))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (21,12)-(21,14) = "do"
+ │ └── closing_loc: (21,15)-(21,18) = "end"
+ ├── @ CallNode (location: (23,0)-(23,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (23,0)-(23,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (23,2)-(23,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (23,2)-(23,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (23,2)-(23,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (23,3)-(23,8))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (23,4)-(23,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (23,4)-(23,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (23,4)-(23,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (23,6)-(23,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (23,6)-(23,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (23,6)-(23,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (23,3)-(23,4) = "{"
+ │ │ │ └── closing_loc: (23,7)-(23,8) = "}"
+ │ │ └── @ FloatNode (location: (23,10)-(23,13))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (23,14)-(23,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (23,14)-(23,16) = "do"
+ │ └── closing_loc: (23,17)-(23,20) = "end"
+ ├── @ CallNode (location: (25,0)-(25,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (25,0)-(25,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (25,2)-(25,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (25,2)-(25,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (25,2)-(25,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (25,3)-(25,8))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (25,4)-(25,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (25,4)-(25,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (25,4)-(25,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (25,6)-(25,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (25,6)-(25,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (25,6)-(25,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (25,3)-(25,4) = "{"
+ │ │ │ └── closing_loc: (25,7)-(25,8) = "}"
+ │ │ └── @ ImaginaryNode (location: (25,10)-(25,14))
+ │ │ └── numeric:
+ │ │ @ FloatNode (location: (25,10)-(25,13))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (25,15)-(25,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (25,15)-(25,17) = "do"
+ │ └── closing_loc: (25,18)-(25,21) = "end"
+ ├── @ CallNode (location: (27,0)-(27,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (27,0)-(27,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,2)-(27,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (27,2)-(27,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (27,2)-(27,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (27,3)-(27,8))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (27,4)-(27,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (27,4)-(27,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (27,4)-(27,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (27,6)-(27,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (27,6)-(27,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (27,6)-(27,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── 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
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (27,15)-(27,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (27,15)-(27,17) = "do"
+ │ └── closing_loc: (27,18)-(27,21) = "end"
+ ├── @ CallNode (location: (29,0)-(29,19))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (29,0)-(29,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (29,2)-(29,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (29,2)-(29,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (29,2)-(29,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (29,3)-(29,8))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (29,4)-(29,7))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (29,4)-(29,7))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (29,4)-(29,5) = "c"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (29,6)-(29,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (29,6)-(29,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (29,6)-(29,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (29,3)-(29,4) = "{"
+ │ │ │ └── closing_loc: (29,7)-(29,8) = "}"
+ │ │ └── @ SymbolNode (location: (29,10)-(29,12))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (29,10)-(29,11) = ":"
+ │ │ ├── value_loc: (29,11)-(29,12) = "e"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "e"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (29,13)-(29,19))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (29,13)-(29,15) = "do"
+ │ └── closing_loc: (29,16)-(29,19) = "end"
+ ├── @ CallNode (location: (31,0)-(31,19))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (31,0)-(31,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,2)-(31,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (31,2)-(31,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (31,2)-(31,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (31,3)-(31,9))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (31,4)-(31,8))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (31,4)-(31,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (31,4)-(31,5) = "c"
+ │ │ │ │ ├── opening_loc: (31,5)-(31,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (31,6)-(31,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (31,6)-(31,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (31,6)-(31,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (31,7)-(31,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (31,3)-(31,4) = "{"
+ │ │ │ └── closing_loc: (31,8)-(31,9) = "}"
+ │ │ └── @ IntegerNode (location: (31,11)-(31,12))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (31,13)-(31,19))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (31,13)-(31,15) = "do"
+ │ └── closing_loc: (31,16)-(31,19) = "end"
+ ├── @ CallNode (location: (33,0)-(33,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (33,0)-(33,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (33,2)-(33,14))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (33,2)-(33,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (33,2)-(33,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (33,3)-(33,9))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (33,4)-(33,8))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (33,4)-(33,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (33,4)-(33,5) = "c"
+ │ │ │ │ ├── opening_loc: (33,5)-(33,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (33,6)-(33,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (33,6)-(33,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (33,6)-(33,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (33,7)-(33,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (33,3)-(33,4) = "{"
+ │ │ │ └── closing_loc: (33,8)-(33,9) = "}"
+ │ │ └── @ FloatNode (location: (33,11)-(33,14))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (33,15)-(33,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (33,15)-(33,17) = "do"
+ │ └── closing_loc: (33,18)-(33,21) = "end"
+ ├── @ CallNode (location: (35,0)-(35,22))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (35,0)-(35,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,2)-(35,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (35,2)-(35,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (35,2)-(35,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (35,3)-(35,9))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (35,4)-(35,8))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (35,4)-(35,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (35,4)-(35,5) = "c"
+ │ │ │ │ ├── opening_loc: (35,5)-(35,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (35,6)-(35,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (35,6)-(35,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (35,6)-(35,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (35,7)-(35,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── opening_loc: (35,3)-(35,4) = "{"
+ │ │ │ └── closing_loc: (35,8)-(35,9) = "}"
+ │ │ └── @ ImaginaryNode (location: (35,11)-(35,15))
+ │ │ └── numeric:
+ │ │ @ FloatNode (location: (35,11)-(35,14))
+ │ │ └── value: 1.0
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (35,16)-(35,22))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (35,16)-(35,18) = "do"
+ │ └── closing_loc: (35,19)-(35,22) = "end"
+ ├── @ CallNode (location: (37,0)-(37,22))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (37,0)-(37,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (37,2)-(37,15))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ CallNode (location: (37,2)-(37,9))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :b
+ │ │ │ ├── message_loc: (37,2)-(37,3) = "b"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block:
+ │ │ │ @ BlockNode (location: (37,3)-(37,9))
+ │ │ │ ├── locals: []
+ │ │ │ ├── parameters: ∅
+ │ │ │ ├── body:
+ │ │ │ │ @ StatementsNode (location: (37,4)-(37,8))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (37,4)-(37,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :c
+ │ │ │ │ ├── message_loc: (37,4)-(37,5) = "c"
+ │ │ │ │ ├── opening_loc: (37,5)-(37,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (37,6)-(37,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (37,6)-(37,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :d
+ │ │ │ │ │ ├── message_loc: (37,6)-(37,7) = "d"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (37,7)-(37,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── 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
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (37,16)-(37,22))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (37,16)-(37,18) = "do"
+ │ └── closing_loc: (37,19)-(37,22) = "end"
+ └── @ CallNode (location: (39,0)-(39,20))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :a
+ ├── message_loc: (39,0)-(39,1) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (39,2)-(39,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (39,2)-(39,9))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :b
+ │ │ ├── message_loc: (39,2)-(39,3) = "b"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (39,3)-(39,9))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (39,4)-(39,8))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (39,4)-(39,8))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :c
+ │ │ │ ├── message_loc: (39,4)-(39,5) = "c"
+ │ │ │ ├── opening_loc: (39,5)-(39,6) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (39,6)-(39,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (39,6)-(39,7))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :d
+ │ │ │ │ ├── message_loc: (39,6)-(39,7) = "d"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (39,7)-(39,8) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (39,3)-(39,4) = "{"
+ │ │ └── closing_loc: (39,8)-(39,9) = "}"
+ │ └── @ SymbolNode (location: (39,11)-(39,13))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (39,11)-(39,12) = ":"
+ │ ├── value_loc: (39,12)-(39,13) = "e"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "e"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (39,14)-(39,20))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (39,14)-(39,16) = "do"
+ └── closing_loc: (39,17)-(39,20) = "end"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11873_b.txt b/test/prism/snapshots/whitequark/ruby_bug_11873_b.txt
new file mode 100644
index 0000000000..6aa8e55e54
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_11873_b.txt
@@ -0,0 +1,98 @@
+@ ProgramNode (location: (1,0)-(1,25))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,25))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,25))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,18))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (1,2)-(1,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :p
+ │ │ ├── message_loc: (1,2)-(1,3) = "p"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,3)-(1,13))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,4)-(1,12))
+ │ │ │ └── body: (length: 2)
+ │ │ │ ├── @ CallNode (location: (1,4)-(1,8))
+ │ │ │ │ ├── flags: ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :p
+ │ │ │ │ ├── message_loc: (1,4)-(1,5) = "p"
+ │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "("
+ │ │ │ │ ├── arguments:
+ │ │ │ │ │ @ ArgumentsNode (location: (1,6)-(1,7))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ │ └── @ CallNode (location: (1,6)-(1,7))
+ │ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ │ ├── name: :p
+ │ │ │ │ │ ├── message_loc: (1,6)-(1,7) = "p"
+ │ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ │ └── block: ∅
+ │ │ │ │ ├── closing_loc: (1,7)-(1,8) = ")"
+ │ │ │ │ └── block: ∅
+ │ │ │ └── @ CallNode (location: (1,9)-(1,12))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :p
+ │ │ │ ├── message_loc: (1,9)-(1,10) = "p"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,11)-(1,12))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,11)-(1,12))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :p
+ │ │ │ │ ├── message_loc: (1,11)-(1,12) = "p"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── opening_loc: (1,3)-(1,4) = "{"
+ │ │ └── closing_loc: (1,12)-(1,13) = "}"
+ │ └── @ CallNode (location: (1,15)-(1,18))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :tap
+ │ ├── message_loc: (1,15)-(1,18) = "tap"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,19)-(1,25))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,19)-(1,21) = "do"
+ └── closing_loc: (1,22)-(1,25) = "end"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11989.txt b/test/prism/snapshots/whitequark/ruby_bug_11989.txt
new file mode 100644
index 0000000000..fe17087e53
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_11989.txt
@@ -0,0 +1,24 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ StringNode (location: (1,2)-(1,8))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,2)-(1,8) = "<<~\"E\""
+ │ ├── content_loc: (2,0)-(3,0) = " x\\n y\n"
+ │ ├── closing_loc: (3,0)-(4,0) = "E\n"
+ │ └── unescaped: "x\n y\n"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/ruby_bug_11990.txt b/test/prism/snapshots/whitequark/ruby_bug_11990.txt
new file mode 100644
index 0000000000..0a5fba1482
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_11990.txt
@@ -0,0 +1,35 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :p
+ ├── message_loc: (1,0)-(1,1) = "p"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,12))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ InterpolatedStringNode (location: (1,2)-(1,12))
+ │ ├── flags: ∅
+ │ ├── opening_loc: ∅
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (1,2)-(1,6))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (1,2)-(1,6) = "<<~E"
+ │ │ │ ├── content_loc: (2,0)-(3,0) = " x\n"
+ │ │ │ ├── closing_loc: (3,0)-(4,0) = "E\n"
+ │ │ │ └── unescaped: "x\n"
+ │ │ └── @ StringNode (location: (1,7)-(1,12))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (1,7)-(1,8) = "\""
+ │ │ ├── content_loc: (1,8)-(1,11) = " y"
+ │ │ ├── closing_loc: (1,11)-(1,12) = "\""
+ │ │ └── unescaped: " y"
+ │ └── closing_loc: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12073.txt b/test/prism/snapshots/whitequark/ruby_bug_12073.txt
new file mode 100644
index 0000000000..9db30f6fec
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_12073.txt
@@ -0,0 +1,96 @@
+@ ProgramNode (location: (1,0)-(3,34))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,34))
+ └── body: (length: 3)
+ ├── @ LocalVariableWriteNode (location: (1,0)-(1,5))
+ │ ├── name: :a
+ │ ├── depth: 0
+ │ ├── name_loc: (1,0)-(1,1) = "a"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,2)-(1,3) = "="
+ ├── @ CallNode (location: (1,7)-(1,13))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,7)-(1,8) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,9)-(1,13))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ KeywordHashNode (location: (1,9)-(1,13))
+ │ │ ├── flags: symbol_keys
+ │ │ └── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (1,9)-(1,13))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (1,9)-(1,11))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (1,9)-(1,10) = "b"
+ │ │ │ ├── closing_loc: (1,10)-(1,11) = ":"
+ │ │ │ └── unescaped: "b"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (1,12)-(1,13))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ DefNode (location: (3,0)-(3,34))
+ ├── name: :foo
+ ├── name_loc: (3,4)-(3,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (3,8)-(3,13))
+ │ ├── requireds: (length: 1)
+ │ │ └── @ RequiredParameterNode (location: (3,8)-(3,13))
+ │ │ ├── flags: ∅
+ │ │ └── name: :raise
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (3,15)-(3,29))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (3,15)-(3,29))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :raise
+ │ ├── message_loc: (3,15)-(3,20) = "raise"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,21)-(3,29))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 2)
+ │ │ ├── @ ConstantPathNode (location: (3,21)-(3,25))
+ │ │ │ ├── parent:
+ │ │ │ │ @ ConstantReadNode (location: (3,21)-(3,22))
+ │ │ │ │ └── name: :A
+ │ │ │ ├── child:
+ │ │ │ │ @ ConstantReadNode (location: (3,24)-(3,25))
+ │ │ │ │ └── name: :B
+ │ │ │ └── delimiter_loc: (3,22)-(3,24) = "::"
+ │ │ └── @ StringNode (location: (3,27)-(3,29))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (3,27)-(3,28) = "'"
+ │ │ ├── content_loc: (3,28)-(3,28) = ""
+ │ │ ├── closing_loc: (3,28)-(3,29) = "'"
+ │ │ └── unescaped: ""
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── locals: [:raise]
+ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (3,31)-(3,34) = "end"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12402.txt b/test/prism/snapshots/whitequark/ruby_bug_12402.txt
new file mode 100644
index 0000000000..df5aea00c3
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_12402.txt
@@ -0,0 +1,567 @@
+@ ProgramNode (location: (1,0)-(27,31))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(27,31))
+ └── body: (length: 14)
+ ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,27))
+ │ ├── name_loc: (1,0)-(1,3) = "foo"
+ │ ├── operator_loc: (1,4)-(1,6) = "+="
+ │ ├── value:
+ │ │ @ RescueModifierNode (location: (1,7)-(1,27))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (1,7)-(1,16))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (1,7)-(1,12) = "raise"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,13)-(1,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (1,13)-(1,16))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (1,13)-(1,16) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (1,17)-(1,23) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (1,24)-(1,27))
+ │ ├── name: :foo
+ │ ├── operator: :+
+ │ └── depth: 0
+ ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,28))
+ │ ├── name_loc: (3,0)-(3,3) = "foo"
+ │ ├── operator_loc: (3,4)-(3,6) = "+="
+ │ ├── value:
+ │ │ @ RescueModifierNode (location: (3,7)-(3,28))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (3,7)-(3,17))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (3,7)-(3,12) = "raise"
+ │ │ │ ├── opening_loc: (3,12)-(3,13) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (3,13)-(3,16))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (3,13)-(3,16))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (3,13)-(3,16) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (3,16)-(3,17) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (3,18)-(3,24) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (3,25)-(3,28))
+ │ ├── name: :foo
+ │ ├── operator: :+
+ │ └── depth: 0
+ ├── @ LocalVariableWriteNode (location: (5,0)-(5,26))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (5,0)-(5,3) = "foo"
+ │ ├── value:
+ │ │ @ RescueModifierNode (location: (5,6)-(5,26))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (5,6)-(5,15))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (5,6)-(5,11) = "raise"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (5,12)-(5,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (5,12)-(5,15))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (5,12)-(5,15) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (5,16)-(5,22) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (5,23)-(5,26))
+ │ └── operator_loc: (5,4)-(5,5) = "="
+ ├── @ LocalVariableWriteNode (location: (7,0)-(7,27))
+ │ ├── name: :foo
+ │ ├── depth: 0
+ │ ├── name_loc: (7,0)-(7,3) = "foo"
+ │ ├── value:
+ │ │ @ RescueModifierNode (location: (7,6)-(7,27))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (7,6)-(7,16))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (7,6)-(7,11) = "raise"
+ │ │ │ ├── opening_loc: (7,11)-(7,12) = "("
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (7,12)-(7,15))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (7,12)-(7,15))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (7,12)-(7,15) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── closing_loc: (7,15)-(7,16) = ")"
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (7,17)-(7,23) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (7,24)-(7,27))
+ │ └── operator_loc: (7,4)-(7,5) = "="
+ ├── @ CallOperatorWriteNode (location: (9,0)-(9,29))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (9,0)-(9,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (9,3)-(9,4) = "."
+ │ ├── message_loc: (9,4)-(9,5) = "C"
+ │ ├── read_name: :C
+ │ ├── write_name: :C=
+ │ ├── operator: :+
+ │ ├── operator_loc: (9,6)-(9,8) = "+="
+ │ └── value:
+ │ @ RescueModifierNode (location: (9,9)-(9,29))
+ │ ├── expression:
+ │ │ @ CallNode (location: (9,9)-(9,18))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (9,9)-(9,14) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (9,15)-(9,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (9,15)-(9,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (9,15)-(9,18) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (9,19)-(9,25) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (9,26)-(9,29))
+ ├── @ CallOperatorWriteNode (location: (11,0)-(11,30))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (11,0)-(11,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (11,3)-(11,4) = "."
+ │ ├── message_loc: (11,4)-(11,5) = "C"
+ │ ├── read_name: :C
+ │ ├── write_name: :C=
+ │ ├── operator: :+
+ │ ├── operator_loc: (11,6)-(11,8) = "+="
+ │ └── value:
+ │ @ RescueModifierNode (location: (11,9)-(11,30))
+ │ ├── expression:
+ │ │ @ CallNode (location: (11,9)-(11,19))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (11,9)-(11,14) = "raise"
+ │ │ ├── opening_loc: (11,14)-(11,15) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (11,15)-(11,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (11,15)-(11,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (11,15)-(11,18) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (11,18)-(11,19) = ")"
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (11,20)-(11,26) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (11,27)-(11,30))
+ ├── @ CallOperatorWriteNode (location: (13,0)-(13,29))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (13,0)-(13,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (13,3)-(13,4) = "."
+ │ ├── message_loc: (13,4)-(13,5) = "m"
+ │ ├── read_name: :m
+ │ ├── write_name: :m=
+ │ ├── operator: :+
+ │ ├── operator_loc: (13,6)-(13,8) = "+="
+ │ └── value:
+ │ @ RescueModifierNode (location: (13,9)-(13,29))
+ │ ├── expression:
+ │ │ @ CallNode (location: (13,9)-(13,18))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (13,9)-(13,14) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (13,15)-(13,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (13,15)-(13,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (13,15)-(13,18) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (13,19)-(13,25) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (13,26)-(13,29))
+ ├── @ CallOperatorWriteNode (location: (15,0)-(15,30))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (15,0)-(15,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (15,3)-(15,4) = "."
+ │ ├── message_loc: (15,4)-(15,5) = "m"
+ │ ├── read_name: :m
+ │ ├── write_name: :m=
+ │ ├── operator: :+
+ │ ├── operator_loc: (15,6)-(15,8) = "+="
+ │ └── value:
+ │ @ RescueModifierNode (location: (15,9)-(15,30))
+ │ ├── expression:
+ │ │ @ CallNode (location: (15,9)-(15,19))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (15,9)-(15,14) = "raise"
+ │ │ ├── opening_loc: (15,14)-(15,15) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (15,15)-(15,18))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (15,15)-(15,18))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (15,15)-(15,18) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (15,18)-(15,19) = ")"
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (15,20)-(15,26) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (15,27)-(15,30))
+ ├── @ ConstantPathOrWriteNode (location: (17,0)-(17,31))
+ │ ├── target:
+ │ │ @ ConstantPathNode (location: (17,0)-(17,6))
+ │ │ ├── parent:
+ │ │ │ @ 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) = "::"
+ │ ├── operator_loc: (17,7)-(17,10) = "||="
+ │ └── value:
+ │ @ RescueModifierNode (location: (17,11)-(17,31))
+ │ ├── expression:
+ │ │ @ CallNode (location: (17,11)-(17,20))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (17,11)-(17,16) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (17,17)-(17,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (17,17)-(17,20))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (17,17)-(17,20) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (17,21)-(17,27) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (17,28)-(17,31))
+ ├── @ ConstantPathOrWriteNode (location: (19,0)-(19,32))
+ │ ├── target:
+ │ │ @ ConstantPathNode (location: (19,0)-(19,6))
+ │ │ ├── parent:
+ │ │ │ @ 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) = "::"
+ │ ├── operator_loc: (19,7)-(19,10) = "||="
+ │ └── value:
+ │ @ RescueModifierNode (location: (19,11)-(19,32))
+ │ ├── expression:
+ │ │ @ CallNode (location: (19,11)-(19,21))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (19,11)-(19,16) = "raise"
+ │ │ ├── opening_loc: (19,16)-(19,17) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (19,17)-(19,20))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (19,17)-(19,20))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (19,17)-(19,20) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (19,20)-(19,21) = ")"
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (19,22)-(19,28) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (19,29)-(19,32))
+ ├── @ CallOperatorWriteNode (location: (21,0)-(21,30))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (21,0)-(21,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (21,3)-(21,5) = "::"
+ │ ├── message_loc: (21,5)-(21,6) = "m"
+ │ ├── read_name: :m
+ │ ├── write_name: :m=
+ │ ├── operator: :+
+ │ ├── operator_loc: (21,7)-(21,9) = "+="
+ │ └── value:
+ │ @ RescueModifierNode (location: (21,10)-(21,30))
+ │ ├── expression:
+ │ │ @ CallNode (location: (21,10)-(21,19))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (21,10)-(21,15) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (21,16)-(21,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (21,16)-(21,19))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (21,16)-(21,19) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (21,20)-(21,26) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (21,27)-(21,30))
+ ├── @ CallOperatorWriteNode (location: (23,0)-(23,31))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (23,0)-(23,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: (23,3)-(23,5) = "::"
+ │ ├── message_loc: (23,5)-(23,6) = "m"
+ │ ├── read_name: :m
+ │ ├── write_name: :m=
+ │ ├── operator: :+
+ │ ├── operator_loc: (23,7)-(23,9) = "+="
+ │ └── value:
+ │ @ RescueModifierNode (location: (23,10)-(23,31))
+ │ ├── expression:
+ │ │ @ CallNode (location: (23,10)-(23,20))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (23,10)-(23,15) = "raise"
+ │ │ ├── opening_loc: (23,15)-(23,16) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (23,16)-(23,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (23,16)-(23,19))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (23,16)-(23,19) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: (23,19)-(23,20) = ")"
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (23,21)-(23,27) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (23,28)-(23,31))
+ ├── @ IndexOperatorWriteNode (location: (25,0)-(25,30))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ LocalVariableReadNode (location: (25,0)-(25,3))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── call_operator_loc: ∅
+ │ ├── opening_loc: (25,3)-(25,4) = "["
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (25,4)-(25,5))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (25,4)-(25,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 0
+ │ ├── closing_loc: (25,5)-(25,6) = "]"
+ │ ├── block: ∅
+ │ ├── operator: :+
+ │ ├── operator_loc: (25,7)-(25,9) = "+="
+ │ └── value:
+ │ @ RescueModifierNode (location: (25,10)-(25,30))
+ │ ├── expression:
+ │ │ @ CallNode (location: (25,10)-(25,19))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (25,10)-(25,15) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (25,16)-(25,19))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (25,16)-(25,19))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (25,16)-(25,19) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── keyword_loc: (25,20)-(25,26) = "rescue"
+ │ └── rescue_expression:
+ │ @ NilNode (location: (25,27)-(25,30))
+ └── @ IndexOperatorWriteNode (location: (27,0)-(27,31))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ LocalVariableReadNode (location: (27,0)-(27,3))
+ │ ├── name: :foo
+ │ └── depth: 0
+ ├── call_operator_loc: ∅
+ ├── opening_loc: (27,3)-(27,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (27,4)-(27,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (27,4)-(27,5))
+ │ ├── flags: decimal
+ │ └── value: 0
+ ├── closing_loc: (27,5)-(27,6) = "]"
+ ├── block: ∅
+ ├── operator: :+
+ ├── operator_loc: (27,7)-(27,9) = "+="
+ └── value:
+ @ RescueModifierNode (location: (27,10)-(27,31))
+ ├── expression:
+ │ @ CallNode (location: (27,10)-(27,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :raise
+ │ ├── message_loc: (27,10)-(27,15) = "raise"
+ │ ├── opening_loc: (27,15)-(27,16) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,16)-(27,19))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (27,16)-(27,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (27,16)-(27,19) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (27,19)-(27,20) = ")"
+ │ └── block: ∅
+ ├── keyword_loc: (27,21)-(27,27) = "rescue"
+ └── rescue_expression:
+ @ NilNode (location: (27,28)-(27,31))
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12669.txt b/test/prism/snapshots/whitequark/ruby_bug_12669.txt
new file mode 100644
index 0000000000..86b021351b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_12669.txt
@@ -0,0 +1,133 @@
+@ ProgramNode (location: (1,0)-(7,16))
+├── locals: [:a, :b]
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,16))
+ └── body: (length: 4)
+ ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,18))
+ │ ├── name_loc: (1,0)-(1,1) = "a"
+ │ ├── 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) = "+="
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (1,10)-(1,18))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (1,10)-(1,15) = "raise"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (1,16)-(1,18))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (1,16)-(1,18))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (1,16)-(1,17) = ":"
+ │ │ │ │ ├── value_loc: (1,17)-(1,18) = "x"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "x"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── name: :b
+ │ │ ├── operator: :+
+ │ │ └── depth: 0
+ │ ├── name: :a
+ │ ├── operator: :+
+ │ └── depth: 0
+ ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,17))
+ │ ├── name_loc: (3,0)-(3,1) = "a"
+ │ ├── operator_loc: (3,2)-(3,4) = "+="
+ │ ├── value:
+ │ │ @ LocalVariableWriteNode (location: (3,5)-(3,17))
+ │ │ ├── name: :b
+ │ │ ├── depth: 0
+ │ │ ├── name_loc: (3,5)-(3,6) = "b"
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (3,9)-(3,17))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (3,9)-(3,14) = "raise"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (3,15)-(3,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (3,15)-(3,17))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (3,15)-(3,16) = ":"
+ │ │ │ │ ├── value_loc: (3,16)-(3,17) = "x"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "x"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── operator_loc: (3,7)-(3,8) = "="
+ │ ├── name: :a
+ │ ├── operator: :+
+ │ └── depth: 0
+ ├── @ LocalVariableWriteNode (location: (5,0)-(5,17))
+ │ ├── name: :a
+ │ ├── depth: 0
+ │ ├── name_loc: (5,0)-(5,1) = "a"
+ │ ├── value:
+ │ │ @ LocalVariableOperatorWriteNode (location: (5,4)-(5,17))
+ │ │ ├── name_loc: (5,4)-(5,5) = "b"
+ │ │ ├── operator_loc: (5,6)-(5,8) = "+="
+ │ │ ├── value:
+ │ │ │ @ CallNode (location: (5,9)-(5,17))
+ │ │ │ ├── flags: ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :raise
+ │ │ │ ├── message_loc: (5,9)-(5,14) = "raise"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments:
+ │ │ │ │ @ ArgumentsNode (location: (5,15)-(5,17))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── arguments: (length: 1)
+ │ │ │ │ └── @ SymbolNode (location: (5,15)-(5,17))
+ │ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ │ ├── opening_loc: (5,15)-(5,16) = ":"
+ │ │ │ │ ├── value_loc: (5,16)-(5,17) = "x"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "x"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── name: :b
+ │ │ ├── operator: :+
+ │ │ └── depth: 0
+ │ └── operator_loc: (5,2)-(5,3) = "="
+ └── @ LocalVariableWriteNode (location: (7,0)-(7,16))
+ ├── name: :a
+ ├── depth: 0
+ ├── name_loc: (7,0)-(7,1) = "a"
+ ├── value:
+ │ @ LocalVariableWriteNode (location: (7,4)-(7,16))
+ │ ├── name: :b
+ │ ├── depth: 0
+ │ ├── name_loc: (7,4)-(7,5) = "b"
+ │ ├── value:
+ │ │ @ CallNode (location: (7,8)-(7,16))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :raise
+ │ │ ├── message_loc: (7,8)-(7,13) = "raise"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,14)-(7,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ SymbolNode (location: (7,14)-(7,16))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: (7,14)-(7,15) = ":"
+ │ │ │ ├── value_loc: (7,15)-(7,16) = "x"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "x"
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── operator_loc: (7,6)-(7,7) = "="
+ └── operator_loc: (7,2)-(7,3) = "="
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12686.txt b/test/prism/snapshots/whitequark/ruby_bug_12686.txt
new file mode 100644
index 0000000000..427c96bbe0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_12686.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,16))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,16))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,16))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :f
+ ├── message_loc: (1,0)-(1,1) = "f"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,2)-(1,16))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,2)-(1,16))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,3)-(1,15))
+ │ │ └── body: (length: 1)
+ │ │ └── @ RescueModifierNode (location: (1,3)-(1,15))
+ │ │ ├── expression:
+ │ │ │ @ CallNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :g
+ │ │ │ ├── message_loc: (1,3)-(1,4) = "g"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── keyword_loc: (1,5)-(1,11) = "rescue"
+ │ │ └── rescue_expression:
+ │ │ @ NilNode (location: (1,12)-(1,15))
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,15)-(1,16) = ")"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/ruby_bug_13547.txt b/test/prism/snapshots/whitequark/ruby_bug_13547.txt
new file mode 100644
index 0000000000..eae9587ea0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_13547.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,4))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,0)-(1,4) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,4)-(1,6) = "[]"
+ ├── opening_loc: (1,4)-(1,5) = "["
+ ├── arguments: ∅
+ ├── closing_loc: (1,5)-(1,6) = "]"
+ └── block:
+ @ BlockNode (location: (1,7)-(1,9))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,7)-(1,8) = "{"
+ └── closing_loc: (1,8)-(1,9) = "}"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_14690.txt b/test/prism/snapshots/whitequark/ruby_bug_14690.txt
new file mode 100644
index 0000000000..36629797db
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_14690.txt
@@ -0,0 +1,59 @@
+@ ProgramNode (location: (1,0)-(1,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,23))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,23))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :let
+ ├── message_loc: (1,0)-(1,3) = "let"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,4)-(1,6))
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (1,5)-(1,6) = ")"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,7)-(1,23))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,9)-(1,21))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,9)-(1,21))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,9)-(1,10) = "m"
+ │ ├── opening_loc: (1,10)-(1,11) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,11)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,11)-(1,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :a
+ │ │ ├── message_loc: (1,11)-(1,12) = "a"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (1,12)-(1,13) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (1,14)-(1,21))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,14)-(1,16) = "do"
+ │ └── closing_loc: (1,18)-(1,21) = "end"
+ ├── opening_loc: (1,7)-(1,8) = "{"
+ └── closing_loc: (1,22)-(1,23) = "}"
diff --git a/test/prism/snapshots/whitequark/ruby_bug_15789.txt b/test/prism/snapshots/whitequark/ruby_bug_15789.txt
new file mode 100644
index 0000000000..db8bc1401f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_15789.txt
@@ -0,0 +1,120 @@
+@ ProgramNode (location: (1,0)-(3,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,19))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,20))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,0)-(1,1) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,2)-(1,20))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LambdaNode (location: (1,2)-(1,20))
+ │ │ ├── locals: [:a]
+ │ │ ├── operator_loc: (1,2)-(1,4) = "->"
+ │ │ ├── opening_loc: (1,17)-(1,18) = "{"
+ │ │ ├── closing_loc: (1,19)-(1,20) = "}"
+ │ │ ├── parameters:
+ │ │ │ @ BlockParametersNode (location: (1,4)-(1,16))
+ │ │ │ ├── parameters:
+ │ │ │ │ @ ParametersNode (location: (1,5)-(1,15))
+ │ │ │ │ ├── requireds: (length: 0)
+ │ │ │ │ ├── optionals: (length: 1)
+ │ │ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,15))
+ │ │ │ │ │ ├── flags: ∅
+ │ │ │ │ │ ├── name: :a
+ │ │ │ │ │ ├── name_loc: (1,5)-(1,6) = "a"
+ │ │ │ │ │ ├── operator_loc: (1,7)-(1,8) = "="
+ │ │ │ │ │ └── value:
+ │ │ │ │ │ @ LambdaNode (location: (1,9)-(1,15))
+ │ │ │ │ │ ├── locals: [:_1]
+ │ │ │ │ │ ├── operator_loc: (1,9)-(1,11) = "->"
+ │ │ │ │ │ ├── opening_loc: (1,11)-(1,12) = "{"
+ │ │ │ │ │ ├── closing_loc: (1,14)-(1,15) = "}"
+ │ │ │ │ │ ├── parameters:
+ │ │ │ │ │ │ @ NumberedParametersNode (location: (1,9)-(1,15))
+ │ │ │ │ │ │ └── maximum: 1
+ │ │ │ │ │ └── body:
+ │ │ │ │ │ @ StatementsNode (location: (1,12)-(1,14))
+ │ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ │ └── @ LocalVariableReadNode (location: (1,12)-(1,14))
+ │ │ │ │ │ ├── name: :_1
+ │ │ │ │ │ └── depth: 0
+ │ │ │ │ ├── rest: ∅
+ │ │ │ │ ├── posts: (length: 0)
+ │ │ │ │ ├── keywords: (length: 0)
+ │ │ │ │ ├── keyword_rest: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ ├── locals: (length: 0)
+ │ │ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ │ │ └── closing_loc: (1,15)-(1,16) = ")"
+ │ │ └── body:
+ │ │ @ StatementsNode (location: (1,18)-(1,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (1,18)-(1,19))
+ │ │ ├── name: :a
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,19))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :m
+ ├── message_loc: (3,0)-(3,1) = "m"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,2)-(3,19))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ LambdaNode (location: (3,2)-(3,19))
+ │ ├── locals: [:a]
+ │ ├── operator_loc: (3,2)-(3,4) = "->"
+ │ ├── opening_loc: (3,16)-(3,17) = "{"
+ │ ├── closing_loc: (3,18)-(3,19) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (3,4)-(3,15))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (3,5)-(3,14))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 1)
+ │ │ │ │ └── @ OptionalKeywordParameterNode (location: (3,5)-(3,14))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── name_loc: (3,5)-(3,7) = "a:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ LambdaNode (location: (3,8)-(3,14))
+ │ │ │ │ ├── locals: [:_1]
+ │ │ │ │ ├── operator_loc: (3,8)-(3,10) = "->"
+ │ │ │ │ ├── opening_loc: (3,10)-(3,11) = "{"
+ │ │ │ │ ├── closing_loc: (3,13)-(3,14) = "}"
+ │ │ │ │ ├── parameters:
+ │ │ │ │ │ @ NumberedParametersNode (location: (3,8)-(3,14))
+ │ │ │ │ │ └── maximum: 1
+ │ │ │ │ └── body:
+ │ │ │ │ @ StatementsNode (location: (3,11)-(3,13))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ LocalVariableReadNode (location: (3,11)-(3,13))
+ │ │ │ │ ├── name: :_1
+ │ │ │ │ └── depth: 0
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (3,4)-(3,5) = "("
+ │ │ └── closing_loc: (3,14)-(3,15) = ")"
+ │ └── body:
+ │ @ StatementsNode (location: (3,17)-(3,18))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (3,17)-(3,18))
+ │ ├── name: :a
+ │ └── depth: 0
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/ruby_bug_9669.txt b/test/prism/snapshots/whitequark/ruby_bug_9669.txt
new file mode 100644
index 0000000000..a73000bed0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ruby_bug_9669.txt
@@ -0,0 +1,58 @@
+@ ProgramNode (location: (1,0)-(8,1))
+├── locals: [:o]
+└── statements:
+ @ StatementsNode (location: (1,0)-(8,1))
+ └── body: (length: 2)
+ ├── @ DefNode (location: (1,0)-(3,3))
+ │ ├── name: :a
+ │ ├── name_loc: (1,4)-(1,5) = "a"
+ │ ├── receiver: ∅
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,6)-(1,8))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (1,6)-(1,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :b
+ │ │ │ └── name_loc: (1,6)-(1,8) = "b:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (2,0)-(2,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ReturnNode (location: (2,0)-(2,6))
+ │ │ ├── keyword_loc: (2,0)-(2,6) = "return"
+ │ │ └── arguments: ∅
+ │ ├── locals: [:b]
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,0)-(3,3) = "end"
+ └── @ LocalVariableWriteNode (location: (5,0)-(8,1))
+ ├── name: :o
+ ├── depth: 0
+ ├── name_loc: (5,0)-(5,1) = "o"
+ ├── value:
+ │ @ HashNode (location: (5,4)-(8,1))
+ │ ├── opening_loc: (5,4)-(5,5) = "{"
+ │ ├── elements: (length: 1)
+ │ │ └── @ AssocNode (location: (6,0)-(7,1))
+ │ │ ├── key:
+ │ │ │ @ SymbolNode (location: (6,0)-(6,2))
+ │ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── value_loc: (6,0)-(6,1) = "a"
+ │ │ │ ├── closing_loc: (6,1)-(6,2) = ":"
+ │ │ │ └── unescaped: "a"
+ │ │ ├── value:
+ │ │ │ @ IntegerNode (location: (7,0)-(7,1))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── operator_loc: ∅
+ │ └── closing_loc: (8,0)-(8,1) = "}"
+ └── operator_loc: (5,2)-(5,3) = "="
diff --git a/test/prism/snapshots/whitequark/sclass.txt b/test/prism/snapshots/whitequark/sclass.txt
new file mode 100644
index 0000000000..53188a7b8a
--- /dev/null
+++ b/test/prism/snapshots/whitequark/sclass.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,22))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,22))
+ └── body: (length: 1)
+ └── @ SingletonClassNode (location: (1,0)-(1,22))
+ ├── locals: []
+ ├── class_keyword_loc: (1,0)-(1,5) = "class"
+ ├── operator_loc: (1,6)-(1,8) = "<<"
+ ├── expression:
+ │ @ CallNode (location: (1,9)-(1,12))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,9)-(1,12) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,14)-(1,17))
+ │ └── body: (length: 1)
+ │ └── @ NilNode (location: (1,14)-(1,17))
+ └── end_keyword_loc: (1,19)-(1,22) = "end"
diff --git a/test/prism/snapshots/whitequark/self.txt b/test/prism/snapshots/whitequark/self.txt
new file mode 100644
index 0000000000..c69f8fa8c5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/self.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ SelfNode (location: (1,0)-(1,4))
diff --git a/test/prism/snapshots/whitequark/send_attr_asgn.txt b/test/prism/snapshots/whitequark/send_attr_asgn.txt
new file mode 100644
index 0000000000..392ae5587e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_attr_asgn.txt
@@ -0,0 +1,106 @@
+@ ProgramNode (location: (1,0)-(7,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,10))
+ └── body: (length: 4)
+ ├── @ CallNode (location: (1,0)-(1,9))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── name: :A=
+ │ ├── message_loc: (1,4)-(1,5) = "A"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,8)-(1,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,9))
+ │ ├── flags: attribute_write
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (3,3)-(3,4) = "."
+ │ ├── name: :a=
+ │ ├── message_loc: (3,4)-(3,5) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,8)-(3,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (3,8)-(3,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ ConstantPathWriteNode (location: (5,0)-(5,10))
+ │ ├── target:
+ │ │ @ ConstantPathNode (location: (5,0)-(5,6))
+ │ │ ├── parent:
+ │ │ │ @ CallNode (location: (5,0)-(5,3))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :foo
+ │ │ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── child:
+ │ │ │ @ ConstantReadNode (location: (5,5)-(5,6))
+ │ │ │ └── name: :A
+ │ │ └── delimiter_loc: (5,3)-(5,5) = "::"
+ │ ├── operator_loc: (5,7)-(5,8) = "="
+ │ └── value:
+ │ @ IntegerNode (location: (5,9)-(5,10))
+ │ ├── flags: decimal
+ │ └── value: 1
+ └── @ CallNode (location: (7,0)-(7,10))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (7,0)-(7,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (7,3)-(7,5) = "::"
+ ├── name: :a=
+ ├── message_loc: (7,5)-(7,6) = "a"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (7,9)-(7,10))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (7,9)-(7,10))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt b/test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt
new file mode 100644
index 0000000000..3cec95ae7c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,8))
+ ├── flags: safe_navigation, attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── name: :b=
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,7)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_binary_op.txt b/test/prism/snapshots/whitequark/send_binary_op.txt
new file mode 100644
index 0000000000..540a7681dc
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_binary_op.txt
@@ -0,0 +1,551 @@
+@ ProgramNode (location: (1,0)-(41,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(41,7))
+ └── body: (length: 21)
+ ├── @ CallNode (location: (1,0)-(1,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!=
+ │ ├── message_loc: (1,4)-(1,6) = "!="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,7)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :!~
+ │ ├── message_loc: (3,4)-(3,6) = "!~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,7)-(3,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (3,7)-(3,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (5,0)-(5,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (5,0)-(5,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :%
+ │ ├── message_loc: (5,4)-(5,5) = "%"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,6)-(5,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,6)-(5,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (7,0)-(7,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (7,0)-(7,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (7,0)-(7,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :&
+ │ ├── message_loc: (7,4)-(7,5) = "&"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,6)-(7,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (7,6)-(7,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (9,0)-(9,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (9,0)-(9,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (9,0)-(9,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :*
+ │ ├── message_loc: (9,4)-(9,5) = "*"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,6)-(9,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (9,6)-(9,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (11,0)-(11,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (11,0)-(11,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (11,0)-(11,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :**
+ │ ├── message_loc: (11,4)-(11,6) = "**"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,7)-(11,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (11,7)-(11,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (13,0)-(13,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (13,0)-(13,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (13,0)-(13,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+
+ │ ├── message_loc: (13,4)-(13,5) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,6)-(13,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (13,6)-(13,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (15,0)-(15,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (15,0)-(15,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (15,0)-(15,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :-
+ │ ├── message_loc: (15,4)-(15,5) = "-"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (15,6)-(15,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (15,6)-(15,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (17,0)-(17,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (17,0)-(17,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (17,0)-(17,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :/
+ │ ├── message_loc: (17,4)-(17,5) = "/"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (17,6)-(17,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (17,6)-(17,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (19,0)-(19,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (19,0)-(19,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (19,0)-(19,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<
+ │ ├── message_loc: (19,4)-(19,5) = "<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (19,6)-(19,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (19,6)-(19,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (21,0)-(21,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (21,0)-(21,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (21,0)-(21,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<<
+ │ ├── message_loc: (21,4)-(21,6) = "<<"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (21,7)-(21,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (21,7)-(21,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (23,0)-(23,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (23,0)-(23,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (23,0)-(23,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<=
+ │ ├── message_loc: (23,4)-(23,6) = "<="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (23,7)-(23,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (23,7)-(23,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (25,0)-(25,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (25,0)-(25,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (25,0)-(25,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :<=>
+ │ ├── message_loc: (25,4)-(25,7) = "<=>"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (25,8)-(25,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (25,8)-(25,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (27,0)-(27,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (27,0)-(27,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (27,0)-(27,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :==
+ │ ├── message_loc: (27,4)-(27,6) = "=="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (27,7)-(27,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (27,7)-(27,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (29,0)-(29,9))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (29,0)-(29,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (29,0)-(29,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :===
+ │ ├── message_loc: (29,4)-(29,7) = "==="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (29,8)-(29,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (29,8)-(29,9))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (31,0)-(31,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (31,0)-(31,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (31,0)-(31,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :=~
+ │ ├── message_loc: (31,4)-(31,6) = "=~"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (31,7)-(31,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (31,7)-(31,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (33,0)-(33,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (33,0)-(33,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (33,0)-(33,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>
+ │ ├── message_loc: (33,4)-(33,5) = ">"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (33,6)-(33,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (33,6)-(33,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (35,0)-(35,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (35,0)-(35,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (35,0)-(35,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>=
+ │ ├── message_loc: (35,4)-(35,6) = ">="
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (35,7)-(35,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (35,7)-(35,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (37,0)-(37,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (37,0)-(37,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (37,0)-(37,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :>>
+ │ ├── message_loc: (37,4)-(37,6) = ">>"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (37,7)-(37,8))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (37,7)-(37,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (39,0)-(39,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (39,0)-(39,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (39,0)-(39,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :^
+ │ ├── message_loc: (39,4)-(39,5) = "^"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (39,6)-(39,7))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (39,6)-(39,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (41,0)-(41,7))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (41,0)-(41,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (41,0)-(41,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :|
+ ├── message_loc: (41,4)-(41,5) = "|"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (41,6)-(41,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (41,6)-(41,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_block_chain_cmd.txt b/test/prism/snapshots/whitequark/send_block_chain_cmd.txt
new file mode 100644
index 0000000000..4013888882
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_block_chain_cmd.txt
@@ -0,0 +1,325 @@
+@ ProgramNode (location: (1,0)-(13,23))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(13,23))
+ └── body: (length: 7)
+ ├── @ CallNode (location: (1,0)-(1,21))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (1,0)-(1,4) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (1,7)-(1,13))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (1,7)-(1,9) = "do"
+ │ │ └── closing_loc: (1,10)-(1,13) = "end"
+ │ ├── call_operator_loc: (1,13)-(1,14) = "."
+ │ ├── name: :fun
+ │ ├── message_loc: (1,14)-(1,17) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,18)-(1,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,18)-(1,21))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,18)-(1,21) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,28))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (3,0)-(3,4) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,5)-(3,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,5)-(3,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (3,7)-(3,13))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (3,7)-(3,9) = "do"
+ │ │ └── closing_loc: (3,10)-(3,13) = "end"
+ │ ├── call_operator_loc: (3,13)-(3,14) = "."
+ │ ├── name: :fun
+ │ ├── message_loc: (3,14)-(3,17) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,18)-(3,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,18)-(3,21))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,18)-(3,21) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,22)-(3,28))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (3,22)-(3,24) = "do"
+ │ └── closing_loc: (3,25)-(3,28) = "end"
+ ├── @ CallNode (location: (5,0)-(5,20))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (5,0)-(5,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (5,0)-(5,4) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,5)-(5,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,5)-(5,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (5,7)-(5,13))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (5,7)-(5,9) = "do"
+ │ │ └── closing_loc: (5,10)-(5,13) = "end"
+ │ ├── call_operator_loc: (5,13)-(5,14) = "."
+ │ ├── name: :fun
+ │ ├── message_loc: (5,14)-(5,17) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (5,18)-(5,20))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (5,18)-(5,19) = "{"
+ │ └── closing_loc: (5,19)-(5,20) = "}"
+ ├── @ CallNode (location: (7,0)-(7,22))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (7,0)-(7,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (7,0)-(7,4) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (7,5)-(7,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (7,5)-(7,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (7,7)-(7,13))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (7,7)-(7,9) = "do"
+ │ │ └── closing_loc: (7,10)-(7,13) = "end"
+ │ ├── call_operator_loc: (7,13)-(7,14) = "."
+ │ ├── name: :fun
+ │ ├── message_loc: (7,14)-(7,17) = "fun"
+ │ ├── opening_loc: (7,17)-(7,18) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,18)-(7,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (7,18)-(7,21))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (7,18)-(7,21) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (7,21)-(7,22) = ")"
+ │ └── block: ∅
+ ├── @ CallNode (location: (9,0)-(9,25))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (9,0)-(9,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (9,0)-(9,4) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (9,5)-(9,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (9,5)-(9,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (9,7)-(9,13))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (9,7)-(9,9) = "do"
+ │ │ └── closing_loc: (9,10)-(9,13) = "end"
+ │ ├── call_operator_loc: (9,13)-(9,14) = "."
+ │ ├── name: :fun
+ │ ├── message_loc: (9,14)-(9,17) = "fun"
+ │ ├── opening_loc: (9,17)-(9,18) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (9,18)-(9,21))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (9,18)-(9,21))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (9,18)-(9,21) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: (9,21)-(9,22) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (9,23)-(9,25))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (9,23)-(9,24) = "{"
+ │ └── closing_loc: (9,24)-(9,25) = "}"
+ ├── @ CallNode (location: (11,0)-(11,22))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (11,0)-(11,13))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :meth
+ │ │ ├── message_loc: (11,0)-(11,4) = "meth"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (11,5)-(11,6))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (11,5)-(11,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── closing_loc: ∅
+ │ │ └── block:
+ │ │ @ BlockNode (location: (11,7)-(11,13))
+ │ │ ├── locals: []
+ │ │ ├── parameters: ∅
+ │ │ ├── body: ∅
+ │ │ ├── opening_loc: (11,7)-(11,9) = "do"
+ │ │ └── closing_loc: (11,10)-(11,13) = "end"
+ │ ├── call_operator_loc: (11,13)-(11,15) = "::"
+ │ ├── name: :fun
+ │ ├── message_loc: (11,15)-(11,18) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (11,19)-(11,22))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (11,19)-(11,22))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (11,19)-(11,22) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (13,0)-(13,23))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (13,0)-(13,13))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (13,0)-(13,4) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (13,5)-(13,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (13,5)-(13,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (13,7)-(13,13))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (13,7)-(13,9) = "do"
+ │ └── closing_loc: (13,10)-(13,13) = "end"
+ ├── call_operator_loc: (13,13)-(13,15) = "::"
+ ├── name: :fun
+ ├── message_loc: (13,15)-(13,18) = "fun"
+ ├── opening_loc: (13,18)-(13,19) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (13,19)-(13,22))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (13,19)-(13,22))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (13,19)-(13,22) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (13,22)-(13,23) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_block_conditional.txt b/test/prism/snapshots/whitequark/send_block_conditional.txt
new file mode 100644
index 0000000000..826d3c8464
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_block_conditional.txt
@@ -0,0 +1,31 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,11))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,3)-(1,5) = "&."
+ ├── name: :bar
+ ├── message_loc: (1,5)-(1,8) = "bar"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,9)-(1,11))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,9)-(1,10) = "{"
+ └── closing_loc: (1,10)-(1,11) = "}"
diff --git a/test/prism/snapshots/whitequark/send_call.txt b/test/prism/snapshots/whitequark/send_call.txt
new file mode 100644
index 0000000000..48063e0121
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_call.txt
@@ -0,0 +1,57 @@
+@ ProgramNode (location: (1,0)-(3,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,8))
+ └── body: (length: 2)
+ ├── @ CallNode (location: (1,0)-(1,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── name: :call
+ │ ├── message_loc: ∅
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,5)-(1,6))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── closing_loc: (1,6)-(1,7) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (3,0)-(3,8))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (3,0)-(3,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (3,3)-(3,5) = "::"
+ ├── name: :call
+ ├── message_loc: ∅
+ ├── opening_loc: (3,5)-(3,6) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,6)-(3,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (3,6)-(3,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (3,7)-(3,8) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_conditional.txt b/test/prism/snapshots/whitequark/send_conditional.txt
new file mode 100644
index 0000000000..7b402d9ef2
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_conditional.txt
@@ -0,0 +1,25 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── name: :b
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_index.txt b/test/prism/snapshots/whitequark/send_index.txt
new file mode 100644
index 0000000000..6c9e08f2ea
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_index.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,3)-(1,9) = "[1, 2]"
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: (1,8)-(1,9) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_index_asgn.txt b/test/prism/snapshots/whitequark/send_index_asgn.txt
new file mode 100644
index 0000000000..9d2e6efcb6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_index_asgn.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]=
+ ├── message_loc: (1,3)-(1,9) = "[1, 2]"
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 3)
+ │ ├── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── @ IntegerNode (location: (1,7)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── @ IntegerNode (location: (1,12)-(1,13))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── closing_loc: (1,8)-(1,9) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_index_asgn_legacy.txt b/test/prism/snapshots/whitequark/send_index_asgn_legacy.txt
new file mode 100644
index 0000000000..9d2e6efcb6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_index_asgn_legacy.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,13))
+ ├── flags: attribute_write
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]=
+ ├── message_loc: (1,3)-(1,9) = "[1, 2]"
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,13))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 3)
+ │ ├── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── @ IntegerNode (location: (1,7)-(1,8))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── @ IntegerNode (location: (1,12)-(1,13))
+ │ ├── flags: decimal
+ │ └── value: 3
+ ├── closing_loc: (1,8)-(1,9) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_index_cmd.txt b/test/prism/snapshots/whitequark/send_index_cmd.txt
new file mode 100644
index 0000000000..0a41fd051d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_index_cmd.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,10))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,3)-(1,10) = "[m bar]"
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,4)-(1,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,4)-(1,5) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,6)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,6)-(1,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,6)-(1,9) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: (1,9)-(1,10) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_index_legacy.txt b/test/prism/snapshots/whitequark/send_index_legacy.txt
new file mode 100644
index 0000000000..6c9e08f2ea
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_index_legacy.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :[]
+ ├── message_loc: (1,3)-(1,9) = "[1, 2]"
+ ├── opening_loc: (1,3)-(1,4) = "["
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,8))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ IntegerNode (location: (1,4)-(1,5))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── @ IntegerNode (location: (1,7)-(1,8))
+ │ ├── flags: decimal
+ │ └── value: 2
+ ├── closing_loc: (1,8)-(1,9) = "]"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_lambda.txt b/test/prism/snapshots/whitequark/send_lambda.txt
new file mode 100644
index 0000000000..bf21700539
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_lambda.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(5,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,5))
+ └── body: (length: 3)
+ ├── @ LambdaNode (location: (1,0)-(1,8))
+ │ ├── locals: []
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (1,5)-(1,6) = "{"
+ │ ├── closing_loc: (1,7)-(1,8) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,3)-(1,4))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,3)-(1,4))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest:
+ │ │ │ │ @ RestParameterNode (location: (1,3)-(1,4))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: ∅
+ │ │ │ │ ├── name_loc: ∅
+ │ │ │ │ └── operator_loc: (1,3)-(1,4) = "*"
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── body: ∅
+ ├── @ LambdaNode (location: (3,0)-(3,9))
+ │ ├── locals: []
+ │ ├── operator_loc: (3,0)-(3,2) = "->"
+ │ ├── opening_loc: (3,3)-(3,5) = "do"
+ │ ├── closing_loc: (3,6)-(3,9) = "end"
+ │ ├── parameters: ∅
+ │ └── body: ∅
+ └── @ LambdaNode (location: (5,0)-(5,5))
+ ├── locals: []
+ ├── operator_loc: (5,0)-(5,2) = "->"
+ ├── opening_loc: (5,2)-(5,3) = "{"
+ ├── closing_loc: (5,4)-(5,5) = "}"
+ ├── parameters: ∅
+ └── body: ∅
diff --git a/test/prism/snapshots/whitequark/send_lambda_args.txt b/test/prism/snapshots/whitequark/send_lambda_args.txt
new file mode 100644
index 0000000000..f61f622bdd
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_lambda_args.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(3,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,9))
+ └── body: (length: 2)
+ ├── @ LambdaNode (location: (1,0)-(1,10))
+ │ ├── locals: [:a]
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (1,7)-(1,8) = "{"
+ │ ├── closing_loc: (1,9)-(1,10) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,3)-(1,6))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,4)-(1,5))
+ │ │ │ ├── requireds: (length: 1)
+ │ │ │ │ └── @ RequiredParameterNode (location: (1,4)-(1,5))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ └── name: :a
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 0)
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: (1,3)-(1,4) = "("
+ │ │ └── closing_loc: (1,5)-(1,6) = ")"
+ │ └── body: ∅
+ └── @ LambdaNode (location: (3,0)-(3,9))
+ ├── locals: [:a]
+ ├── operator_loc: (3,0)-(3,2) = "->"
+ ├── opening_loc: (3,6)-(3,7) = "{"
+ ├── closing_loc: (3,8)-(3,9) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (3,2)-(3,5))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,3)-(3,4))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (3,3)-(3,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: (3,2)-(3,3) = "("
+ │ └── closing_loc: (3,4)-(3,5) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/whitequark/send_lambda_args_noparen.txt b/test/prism/snapshots/whitequark/send_lambda_args_noparen.txt
new file mode 100644
index 0000000000..747656af6b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_lambda_args_noparen.txt
@@ -0,0 +1,57 @@
+@ ProgramNode (location: (1,0)-(3,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,9))
+ └── body: (length: 2)
+ ├── @ LambdaNode (location: (1,0)-(1,11))
+ │ ├── locals: [:a]
+ │ ├── operator_loc: (1,0)-(1,2) = "->"
+ │ ├── opening_loc: (1,8)-(1,9) = "{"
+ │ ├── closing_loc: (1,10)-(1,11) = "}"
+ │ ├── parameters:
+ │ │ @ BlockParametersNode (location: (1,3)-(1,7))
+ │ │ ├── parameters:
+ │ │ │ @ ParametersNode (location: (1,3)-(1,7))
+ │ │ │ ├── requireds: (length: 0)
+ │ │ │ ├── optionals: (length: 0)
+ │ │ │ ├── rest: ∅
+ │ │ │ ├── posts: (length: 0)
+ │ │ │ ├── keywords: (length: 1)
+ │ │ │ │ └── @ OptionalKeywordParameterNode (location: (1,3)-(1,7))
+ │ │ │ │ ├── flags: ∅
+ │ │ │ │ ├── name: :a
+ │ │ │ │ ├── name_loc: (1,3)-(1,5) = "a:"
+ │ │ │ │ └── value:
+ │ │ │ │ @ IntegerNode (location: (1,6)-(1,7))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ ├── keyword_rest: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── locals: (length: 0)
+ │ │ ├── opening_loc: ∅
+ │ │ └── closing_loc: ∅
+ │ └── body: ∅
+ └── @ LambdaNode (location: (3,0)-(3,9))
+ ├── locals: [:a]
+ ├── operator_loc: (3,0)-(3,2) = "->"
+ ├── opening_loc: (3,6)-(3,7) = "{"
+ ├── closing_loc: (3,8)-(3,9) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (3,3)-(3,5))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (3,3)-(3,5))
+ │ │ ├── requireds: (length: 0)
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 1)
+ │ │ │ └── @ RequiredKeywordParameterNode (location: (3,3)-(3,5))
+ │ │ │ ├── flags: ∅
+ │ │ │ ├── name: :a
+ │ │ │ └── name_loc: (3,3)-(3,5) = "a:"
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 0)
+ │ ├── opening_loc: ∅
+ │ └── closing_loc: ∅
+ └── body: ∅
diff --git a/test/prism/snapshots/whitequark/send_lambda_args_shadow.txt b/test/prism/snapshots/whitequark/send_lambda_args_shadow.txt
new file mode 100644
index 0000000000..34a63ec503
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_lambda_args_shadow.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,19))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,19))
+ ├── locals: [:a, :foo, :bar]
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,16)-(1,17) = "{"
+ ├── closing_loc: (1,18)-(1,19) = "}"
+ ├── parameters:
+ │ @ BlockParametersNode (location: (1,2)-(1,15))
+ │ ├── parameters:
+ │ │ @ ParametersNode (location: (1,3)-(1,4))
+ │ │ ├── requireds: (length: 1)
+ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ ├── optionals: (length: 0)
+ │ │ ├── rest: ∅
+ │ │ ├── posts: (length: 0)
+ │ │ ├── keywords: (length: 0)
+ │ │ ├── keyword_rest: ∅
+ │ │ └── block: ∅
+ │ ├── locals: (length: 2)
+ │ │ ├── @ BlockLocalVariableNode (location: (1,6)-(1,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :foo
+ │ │ └── @ BlockLocalVariableNode (location: (1,11)-(1,14))
+ │ │ ├── flags: ∅
+ │ │ └── name: :bar
+ │ ├── opening_loc: (1,2)-(1,3) = "("
+ │ └── closing_loc: (1,14)-(1,15) = ")"
+ └── body: ∅
diff --git a/test/prism/snapshots/whitequark/send_lambda_legacy.txt b/test/prism/snapshots/whitequark/send_lambda_legacy.txt
new file mode 100644
index 0000000000..3a64e941b6
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_lambda_legacy.txt
@@ -0,0 +1,12 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ LambdaNode (location: (1,0)-(1,5))
+ ├── locals: []
+ ├── operator_loc: (1,0)-(1,2) = "->"
+ ├── opening_loc: (1,2)-(1,3) = "{"
+ ├── closing_loc: (1,4)-(1,5) = "}"
+ ├── parameters: ∅
+ └── body: ∅
diff --git a/test/prism/snapshots/whitequark/send_op_asgn_conditional.txt b/test/prism/snapshots/whitequark/send_op_asgn_conditional.txt
new file mode 100644
index 0000000000..05966fc5a3
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_op_asgn_conditional.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,10))
+ └── body: (length: 1)
+ └── @ CallAndWriteNode (location: (1,0)-(1,10))
+ ├── flags: safe_navigation
+ ├── receiver:
+ │ @ CallNode (location: (1,0)-(1,1))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :a
+ │ ├── message_loc: (1,0)-(1,1) = "a"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (1,1)-(1,3) = "&."
+ ├── message_loc: (1,3)-(1,4) = "b"
+ ├── read_name: :b
+ ├── write_name: :b=
+ ├── operator_loc: (1,5)-(1,8) = "&&="
+ └── value:
+ @ IntegerNode (location: (1,9)-(1,10))
+ ├── flags: decimal
+ └── value: 1
diff --git a/test/prism/snapshots/whitequark/send_plain.txt b/test/prism/snapshots/whitequark/send_plain.txt
new file mode 100644
index 0000000000..be57bee5a0
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_plain.txt
@@ -0,0 +1,65 @@
+@ ProgramNode (location: (1,0)-(5,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,8))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,7))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── name: :fun
+ │ ├── message_loc: (1,4)-(1,7) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (3,3)-(3,5) = "::"
+ │ ├── name: :Fun
+ │ ├── message_loc: (3,5)-(3,8) = "Fun"
+ │ ├── opening_loc: (3,8)-(3,9) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (3,9)-(3,10) = ")"
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,8))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (5,0)-(5,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (5,3)-(5,5) = "::"
+ ├── name: :fun
+ ├── message_loc: (5,5)-(5,8) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_plain_cmd.txt b/test/prism/snapshots/whitequark/send_plain_cmd.txt
new file mode 100644
index 0000000000..59236e114d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_plain_cmd.txt
@@ -0,0 +1,104 @@
+@ ProgramNode (location: (1,0)-(5,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,12))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,11))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── name: :fun
+ │ ├── message_loc: (1,4)-(1,7) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,8)-(1,11))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,8)-(1,11) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (3,3)-(3,5) = "::"
+ │ ├── name: :Fun
+ │ ├── message_loc: (3,5)-(3,8) = "Fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,9)-(3,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,9)-(3,12))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (3,9)-(3,12) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,12))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (5,0)-(5,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,0)-(5,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: (5,3)-(5,5) = "::"
+ ├── name: :fun
+ ├── message_loc: (5,5)-(5,8) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (5,9)-(5,12))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (5,9)-(5,12))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (5,9)-(5,12) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_self.txt b/test/prism/snapshots/whitequark/send_self.txt
new file mode 100644
index 0000000000..41fd822110
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_self.txt
@@ -0,0 +1,41 @@
+@ ProgramNode (location: (1,0)-(5,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,6))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (1,0)-(1,3) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,4))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun!
+ │ ├── message_loc: (3,0)-(3,4) = "fun!"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,6))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (5,0)-(5,3) = "fun"
+ ├── opening_loc: (5,3)-(5,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (5,4)-(5,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (5,4)-(5,5))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (5,5)-(5,6) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/send_self_block.txt b/test/prism/snapshots/whitequark/send_self_block.txt
new file mode 100644
index 0000000000..c92935603b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_self_block.txt
@@ -0,0 +1,75 @@
+@ ProgramNode (location: (1,0)-(7,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,10))
+ └── body: (length: 4)
+ ├── @ CallNode (location: (1,0)-(1,10))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (1,0)-(1,3) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,4)-(1,10))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,4)-(1,6) = "do"
+ │ └── closing_loc: (1,7)-(1,10) = "end"
+ ├── @ CallNode (location: (3,0)-(3,7))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (3,0)-(3,3) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,4)-(3,7))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (3,4)-(3,5) = "{"
+ │ └── closing_loc: (3,6)-(3,7) = "}"
+ ├── @ CallNode (location: (5,0)-(5,9))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :fun
+ │ ├── message_loc: (5,0)-(5,3) = "fun"
+ │ ├── opening_loc: (5,3)-(5,4) = "("
+ │ ├── arguments: ∅
+ │ ├── closing_loc: (5,4)-(5,5) = ")"
+ │ └── block:
+ │ @ BlockNode (location: (5,6)-(5,9))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (5,6)-(5,7) = "{"
+ │ └── closing_loc: (5,8)-(5,9) = "}"
+ └── @ CallNode (location: (7,0)-(7,10))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (7,0)-(7,3) = "fun"
+ ├── opening_loc: (7,3)-(7,4) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (7,4)-(7,5))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ IntegerNode (location: (7,4)-(7,5))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── closing_loc: (7,5)-(7,6) = ")"
+ └── block:
+ @ BlockNode (location: (7,7)-(7,10))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (7,7)-(7,8) = "{"
+ └── closing_loc: (7,9)-(7,10) = "}"
diff --git a/test/prism/snapshots/whitequark/send_unary_op.txt b/test/prism/snapshots/whitequark/send_unary_op.txt
new file mode 100644
index 0000000000..8ca1de7968
--- /dev/null
+++ b/test/prism/snapshots/whitequark/send_unary_op.txt
@@ -0,0 +1,65 @@
+@ ProgramNode (location: (1,0)-(5,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,4))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,1)-(1,4))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,1)-(1,4) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :+@
+ │ ├── message_loc: (1,0)-(1,1) = "+"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,4))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,1)-(3,4))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,1)-(3,4) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :-@
+ │ ├── message_loc: (3,0)-(3,1) = "-"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,4))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (5,1)-(5,4))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,1)-(5,4) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :~
+ ├── message_loc: (5,0)-(5,1) = "~"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt b/test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt
new file mode 100644
index 0000000000..ba1fce0c68
--- /dev/null
+++ b/test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(8,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(8,4))
+ └── body: (length: 2)
+ ├── @ StringNode (location: (1,0)-(1,4))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,4) = "<<-E"
+ │ ├── content_loc: (2,0)-(5,0) = " 1 \\\n 2\n 3\n"
+ │ ├── closing_loc: (5,0)-(6,0) = "E\n"
+ │ └── unescaped: " 1 2\n 3\n"
+ └── @ InterpolatedStringNode (location: (8,0)-(8,4))
+ ├── flags: ∅
+ ├── opening_loc: (8,0)-(8,4) = "<<~E"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (9,0)-(10,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (9,0)-(10,0) = " 1 \\\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "1 "
+ │ ├── @ StringNode (location: (10,0)-(11,0))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (10,0)-(11,0) = " 2\n"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "2\n"
+ │ └── @ StringNode (location: (11,0)-(12,0))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (11,0)-(12,0) = " 3\n"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "3\n"
+ └── closing_loc: (12,0)-(13,0) = "E\n"
diff --git a/test/prism/snapshots/whitequark/space_args_arg.txt b/test/prism/snapshots/whitequark/space_args_arg.txt
new file mode 100644
index 0000000000..55750d2b61
--- /dev/null
+++ b/test/prism/snapshots/whitequark/space_args_arg.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,7))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (1,0)-(1,3) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,4)-(1,7))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (1,6)-(1,7) = ")"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/space_args_arg_block.txt b/test/prism/snapshots/whitequark/space_args_arg_block.txt
new file mode 100644
index 0000000000..a6224bcca1
--- /dev/null
+++ b/test/prism/snapshots/whitequark/space_args_arg_block.txt
@@ -0,0 +1,109 @@
+@ ProgramNode (location: (1,0)-(5,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,10))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,14))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (1,0)-(1,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (1,3)-(1,4) = "."
+ │ ├── name: :fun
+ │ ├── message_loc: (1,4)-(1,7) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,11))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ParenthesesNode (location: (1,8)-(1,11))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,9)-(1,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,9)-(1,10))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (1,8)-(1,9) = "("
+ │ │ └── closing_loc: (1,10)-(1,11) = ")"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (1,12)-(1,14))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,12)-(1,13) = "{"
+ │ └── closing_loc: (1,13)-(1,14) = "}"
+ ├── @ CallNode (location: (3,0)-(3,15))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,0)-(3,3))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,0)-(3,3) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: (3,3)-(3,5) = "::"
+ │ ├── name: :fun
+ │ ├── message_loc: (3,5)-(3,8) = "fun"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,9)-(3,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ ParenthesesNode (location: (3,9)-(3,12))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (3,10)-(3,11))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,10)-(3,11))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (3,9)-(3,10) = "("
+ │ │ └── closing_loc: (3,11)-(3,12) = ")"
+ │ ├── closing_loc: ∅
+ │ └── block:
+ │ @ BlockNode (location: (3,13)-(3,15))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (3,13)-(3,14) = "{"
+ │ └── closing_loc: (3,14)-(3,15) = "}"
+ └── @ CallNode (location: (5,0)-(5,10))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (5,0)-(5,3) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (5,4)-(5,7))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (5,4)-(5,7))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,5)-(5,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,5)-(5,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (5,4)-(5,5) = "("
+ │ └── closing_loc: (5,6)-(5,7) = ")"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (5,8)-(5,10))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (5,8)-(5,9) = "{"
+ └── closing_loc: (5,9)-(5,10) = "}"
diff --git a/test/prism/snapshots/whitequark/space_args_arg_call.txt b/test/prism/snapshots/whitequark/space_args_arg_call.txt
new file mode 100644
index 0000000000..767b099a8b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/space_args_arg_call.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,12))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (1,0)-(1,3) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,12))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (1,4)-(1,12))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ ParenthesesNode (location: (1,4)-(1,7))
+ │ │ ├── body:
+ │ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ │ └── closing_loc: (1,6)-(1,7) = ")"
+ │ ├── call_operator_loc: (1,7)-(1,8) = "."
+ │ ├── name: :to_i
+ │ ├── message_loc: (1,8)-(1,12) = "to_i"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/space_args_arg_newline.txt b/test/prism/snapshots/whitequark/space_args_arg_newline.txt
new file mode 100644
index 0000000000..7727a5ddd9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/space_args_arg_newline.txt
@@ -0,0 +1,27 @@
+@ ProgramNode (location: (1,0)-(2,1))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(2,1))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(2,1))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (1,0)-(1,3) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(2,1))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,4)-(2,1))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,5)-(1,6))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,5)-(1,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (2,0)-(2,1) = ")"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/space_args_block.txt b/test/prism/snapshots/whitequark/space_args_block.txt
new file mode 100644
index 0000000000..62b549a674
--- /dev/null
+++ b/test/prism/snapshots/whitequark/space_args_block.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,9))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,9))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,9))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (1,0)-(1,3) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,6))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,4)-(1,6))
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (1,5)-(1,6) = ")"
+ ├── closing_loc: ∅
+ └── block:
+ @ BlockNode (location: (1,7)-(1,9))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (1,7)-(1,8) = "{"
+ └── closing_loc: (1,8)-(1,9) = "}"
diff --git a/test/prism/snapshots/whitequark/space_args_cmd.txt b/test/prism/snapshots/whitequark/space_args_cmd.txt
new file mode 100644
index 0000000000..8a75bef6a8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/space_args_cmd.txt
@@ -0,0 +1,47 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,11))
+ ├── flags: ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :fun
+ ├── message_loc: (1,0)-(1,3) = "fun"
+ ├── opening_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (1,4)-(1,11))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ ParenthesesNode (location: (1,4)-(1,11))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,5)-(1,10))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,5)-(1,10))
+ │ │ ├── flags: ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :f
+ │ │ ├── message_loc: (1,5)-(1,6) = "f"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (1,7)-(1,10))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,7)-(1,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,7)-(1,10) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (1,10)-(1,11) = ")"
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/string___FILE__.txt b/test/prism/snapshots/whitequark/string___FILE__.txt
new file mode 100644
index 0000000000..a12499a631
--- /dev/null
+++ b/test/prism/snapshots/whitequark/string___FILE__.txt
@@ -0,0 +1,8 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ SourceFileNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ └── filepath: "whitequark/string___FILE__.txt"
diff --git a/test/prism/snapshots/whitequark/string_concat.txt b/test/prism/snapshots/whitequark/string_concat.txt
new file mode 100644
index 0000000000..f7f7bf9723
--- /dev/null
+++ b/test/prism/snapshots/whitequark/string_concat.txt
@@ -0,0 +1,32 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── opening_loc: ∅
+ ├── parts: (length: 2)
+ │ ├── @ InterpolatedStringNode (location: (1,0)-(1,8))
+ │ │ ├── flags: ∅
+ │ │ ├── opening_loc: (1,0)-(1,1) = "\""
+ │ │ ├── parts: (length: 2)
+ │ │ │ ├── @ StringNode (location: (1,1)-(1,4))
+ │ │ │ │ ├── flags: frozen
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── content_loc: (1,1)-(1,4) = "foo"
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── unescaped: "foo"
+ │ │ │ └── @ EmbeddedVariableNode (location: (1,4)-(1,7))
+ │ │ │ ├── operator_loc: (1,4)-(1,5) = "#"
+ │ │ │ └── variable:
+ │ │ │ @ InstanceVariableReadNode (location: (1,5)-(1,7))
+ │ │ │ └── name: :@a
+ │ │ └── closing_loc: (1,7)-(1,8) = "\""
+ │ └── @ StringNode (location: (1,9)-(1,14))
+ │ ├── flags: frozen
+ │ ├── opening_loc: (1,9)-(1,10) = "\""
+ │ ├── content_loc: (1,10)-(1,13) = "bar"
+ │ ├── closing_loc: (1,13)-(1,14) = "\""
+ │ └── unescaped: "bar"
+ └── closing_loc: ∅
diff --git a/test/prism/snapshots/whitequark/string_dvar.txt b/test/prism/snapshots/whitequark/string_dvar.txt
new file mode 100644
index 0000000000..9d04232580
--- /dev/null
+++ b/test/prism/snapshots/whitequark/string_dvar.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 5)
+ │ ├── @ EmbeddedVariableNode (location: (1,1)-(1,4))
+ │ │ ├── operator_loc: (1,1)-(1,2) = "#"
+ │ │ └── variable:
+ │ │ @ InstanceVariableReadNode (location: (1,2)-(1,4))
+ │ │ └── name: :@a
+ │ ├── @ StringNode (location: (1,4)-(1,5))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,4)-(1,5) = " "
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " "
+ │ ├── @ EmbeddedVariableNode (location: (1,5)-(1,9))
+ │ │ ├── operator_loc: (1,5)-(1,6) = "#"
+ │ │ └── variable:
+ │ │ @ ClassVariableReadNode (location: (1,6)-(1,9))
+ │ │ └── name: :@@a
+ │ ├── @ StringNode (location: (1,9)-(1,10))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,9)-(1,10) = " "
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " "
+ │ └── @ EmbeddedVariableNode (location: (1,10)-(1,13))
+ │ ├── operator_loc: (1,10)-(1,11) = "#"
+ │ └── variable:
+ │ @ GlobalVariableReadNode (location: (1,11)-(1,13))
+ │ └── name: :$a
+ └── closing_loc: (1,13)-(1,14) = "\""
diff --git a/test/prism/snapshots/whitequark/string_interp.txt b/test/prism/snapshots/whitequark/string_interp.txt
new file mode 100644
index 0000000000..597e8c5d5b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/string_interp.txt
@@ -0,0 +1,38 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ InterpolatedStringNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "\""
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (1,1)-(1,4))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,1)-(1,4) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── @ EmbeddedStatementsNode (location: (1,4)-(1,10))
+ │ │ ├── opening_loc: (1,4)-(1,6) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,6)-(1,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,6)-(1,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,6)-(1,9) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,9)-(1,10) = "}"
+ │ └── @ StringNode (location: (1,10)-(1,13))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,10)-(1,13) = "baz"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "baz"
+ └── closing_loc: (1,13)-(1,14) = "\""
diff --git a/test/prism/snapshots/whitequark/string_plain.txt b/test/prism/snapshots/whitequark/string_plain.txt
new file mode 100644
index 0000000000..7534ac1844
--- /dev/null
+++ b/test/prism/snapshots/whitequark/string_plain.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(3,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,8))
+ └── body: (length: 2)
+ ├── @ StringNode (location: (1,0)-(1,10))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,3) = "%q("
+ │ ├── content_loc: (1,3)-(1,9) = "foobar"
+ │ ├── closing_loc: (1,9)-(1,10) = ")"
+ │ └── unescaped: "foobar"
+ └── @ StringNode (location: (3,0)-(3,8))
+ ├── flags: ∅
+ ├── opening_loc: (3,0)-(3,1) = "'"
+ ├── content_loc: (3,1)-(3,7) = "foobar"
+ ├── closing_loc: (3,7)-(3,8) = "'"
+ └── unescaped: "foobar"
diff --git a/test/prism/snapshots/whitequark/super.txt b/test/prism/snapshots/whitequark/super.txt
new file mode 100644
index 0000000000..132b4912e4
--- /dev/null
+++ b/test/prism/snapshots/whitequark/super.txt
@@ -0,0 +1,49 @@
+@ ProgramNode (location: (1,0)-(5,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,10))
+ └── body: (length: 3)
+ ├── @ SuperNode (location: (1,0)-(1,9))
+ │ ├── keyword_loc: (1,0)-(1,5) = "super"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,6)-(1,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (1,6)-(1,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,6)-(1,9) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── rparen_loc: ∅
+ │ └── block: ∅
+ ├── @ SuperNode (location: (3,0)-(3,7))
+ │ ├── keyword_loc: (3,0)-(3,5) = "super"
+ │ ├── lparen_loc: (3,5)-(3,6) = "("
+ │ ├── arguments: ∅
+ │ ├── rparen_loc: (3,6)-(3,7) = ")"
+ │ └── block: ∅
+ └── @ SuperNode (location: (5,0)-(5,10))
+ ├── keyword_loc: (5,0)-(5,5) = "super"
+ ├── lparen_loc: (5,5)-(5,6) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (5,6)-(5,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (5,6)-(5,9))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (5,6)-(5,9) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rparen_loc: (5,9)-(5,10) = ")"
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/super_block.txt b/test/prism/snapshots/whitequark/super_block.txt
new file mode 100644
index 0000000000..d9ce7b86be
--- /dev/null
+++ b/test/prism/snapshots/whitequark/super_block.txt
@@ -0,0 +1,48 @@
+@ ProgramNode (location: (1,0)-(3,21))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,21))
+ └── body: (length: 2)
+ ├── @ ForwardingSuperNode (location: (1,0)-(1,12))
+ │ └── block:
+ │ @ BlockNode (location: (1,6)-(1,12))
+ │ ├── locals: []
+ │ ├── parameters: ∅
+ │ ├── body: ∅
+ │ ├── opening_loc: (1,6)-(1,8) = "do"
+ │ └── closing_loc: (1,9)-(1,12) = "end"
+ └── @ SuperNode (location: (3,0)-(3,21))
+ ├── keyword_loc: (3,0)-(3,5) = "super"
+ ├── lparen_loc: ∅
+ ├── arguments:
+ │ @ ArgumentsNode (location: (3,6)-(3,14))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 2)
+ │ ├── @ CallNode (location: (3,6)-(3,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,6)-(3,9) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ CallNode (location: (3,11)-(3,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,11)-(3,14) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rparen_loc: ∅
+ └── block:
+ @ BlockNode (location: (3,15)-(3,21))
+ ├── locals: []
+ ├── parameters: ∅
+ ├── body: ∅
+ ├── opening_loc: (3,15)-(3,17) = "do"
+ └── closing_loc: (3,18)-(3,21) = "end"
diff --git a/test/prism/snapshots/whitequark/symbol_interp.txt b/test/prism/snapshots/whitequark/symbol_interp.txt
new file mode 100644
index 0000000000..a9b8dfcb63
--- /dev/null
+++ b/test/prism/snapshots/whitequark/symbol_interp.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,15))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,15))
+ └── body: (length: 1)
+ └── @ InterpolatedSymbolNode (location: (1,0)-(1,15))
+ ├── opening_loc: (1,0)-(1,2) = ":\""
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (1,2)-(1,5))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,2)-(1,5) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── @ EmbeddedStatementsNode (location: (1,5)-(1,11))
+ │ │ ├── opening_loc: (1,5)-(1,7) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,7)-(1,10))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,7)-(1,10))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,7)-(1,10) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,10)-(1,11) = "}"
+ │ └── @ StringNode (location: (1,11)-(1,14))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,11)-(1,14) = "baz"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "baz"
+ └── closing_loc: (1,14)-(1,15) = "\""
diff --git a/test/prism/snapshots/whitequark/symbol_plain.txt b/test/prism/snapshots/whitequark/symbol_plain.txt
new file mode 100644
index 0000000000..a2466600f5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/symbol_plain.txt
@@ -0,0 +1,17 @@
+@ ProgramNode (location: (1,0)-(3,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,4))
+ └── body: (length: 2)
+ ├── @ SymbolNode (location: (1,0)-(1,6))
+ │ ├── flags: forced_us_ascii_encoding
+ │ ├── opening_loc: (1,0)-(1,2) = ":'"
+ │ ├── value_loc: (1,2)-(1,5) = "foo"
+ │ ├── closing_loc: (1,5)-(1,6) = "'"
+ │ └── unescaped: "foo"
+ └── @ SymbolNode (location: (3,0)-(3,4))
+ ├── flags: forced_us_ascii_encoding
+ ├── opening_loc: (3,0)-(3,1) = ":"
+ ├── value_loc: (3,1)-(3,4) = "foo"
+ ├── closing_loc: ∅
+ └── unescaped: "foo"
diff --git a/test/prism/snapshots/whitequark/ternary.txt b/test/prism/snapshots/whitequark/ternary.txt
new file mode 100644
index 0000000000..fa637ffb4e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ternary.txt
@@ -0,0 +1,36 @@
+@ ProgramNode (location: (1,0)-(1,11))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,11))
+ └── body: (length: 1)
+ └── @ IfNode (location: (1,0)-(1,11))
+ ├── if_keyword_loc: ∅
+ ├── predicate:
+ │ @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,0)-(1,3) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: (1,4)-(1,5) = "?"
+ ├── statements:
+ │ @ StatementsNode (location: (1,6)-(1,7))
+ │ └── body: (length: 1)
+ │ └── @ IntegerNode (location: (1,6)-(1,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── consequent:
+ │ @ ElseNode (location: (1,8)-(1,11))
+ │ ├── else_keyword_loc: (1,8)-(1,9) = ":"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,10)-(1,11))
+ │ │ └── body: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,10)-(1,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 2
+ │ └── end_keyword_loc: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/ternary_ambiguous_symbol.txt b/test/prism/snapshots/whitequark/ternary_ambiguous_symbol.txt
new file mode 100644
index 0000000000..833afcff42
--- /dev/null
+++ b/test/prism/snapshots/whitequark/ternary_ambiguous_symbol.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (1,0)-(1,13))
+├── locals: [:t]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,13))
+ └── body: (length: 2)
+ ├── @ LocalVariableWriteNode (location: (1,0)-(1,3))
+ │ ├── name: :t
+ │ ├── depth: 0
+ │ ├── name_loc: (1,0)-(1,1) = "t"
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,2)-(1,3))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator_loc: (1,1)-(1,2) = "="
+ └── @ IfNode (location: (1,4)-(1,13))
+ ├── if_keyword_loc: ∅
+ ├── predicate:
+ │ @ ParenthesesNode (location: (1,4)-(1,9))
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,5)-(1,8))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,5)-(1,8))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── opening_loc: (1,4)-(1,5) = "("
+ │ └── closing_loc: (1,8)-(1,9) = ")"
+ ├── then_keyword_loc: (1,9)-(1,10) = "?"
+ ├── statements:
+ │ @ StatementsNode (location: (1,10)-(1,11))
+ │ └── body: (length: 1)
+ │ └── @ LocalVariableReadNode (location: (1,10)-(1,11))
+ │ ├── name: :t
+ │ └── depth: 0
+ ├── consequent:
+ │ @ ElseNode (location: (1,11)-(1,13))
+ │ ├── else_keyword_loc: (1,11)-(1,12) = ":"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,12)-(1,13))
+ │ │ └── body: (length: 1)
+ │ │ └── @ ConstantReadNode (location: (1,12)-(1,13))
+ │ │ └── name: :T
+ │ └── end_keyword_loc: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/trailing_forward_arg.txt b/test/prism/snapshots/whitequark/trailing_forward_arg.txt
new file mode 100644
index 0000000000..e12dad132b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/trailing_forward_arg.txt
@@ -0,0 +1,55 @@
+@ ProgramNode (location: (1,0)-(1,40))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,40))
+ └── body: (length: 1)
+ └── @ DefNode (location: (1,0)-(1,40))
+ ├── name: :foo
+ ├── name_loc: (1,4)-(1,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters:
+ │ @ ParametersNode (location: (1,8)-(1,17))
+ │ ├── requireds: (length: 2)
+ │ │ ├── @ RequiredParameterNode (location: (1,8)-(1,9))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── name: :a
+ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ └── name: :b
+ │ ├── optionals: (length: 0)
+ │ ├── rest: ∅
+ │ ├── posts: (length: 0)
+ │ ├── keywords: (length: 0)
+ │ ├── keyword_rest:
+ │ │ @ ForwardingParameterNode (location: (1,14)-(1,17))
+ │ └── block: ∅
+ ├── body:
+ │ @ StatementsNode (location: (1,20)-(1,35))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,20)-(1,35))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,20)-(1,23) = "bar"
+ │ ├── opening_loc: (1,23)-(1,24) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,24)-(1,34))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ LocalVariableReadNode (location: (1,24)-(1,25))
+ │ │ │ ├── name: :a
+ │ │ │ └── depth: 0
+ │ │ ├── @ IntegerNode (location: (1,27)-(1,29))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 42
+ │ │ └── @ ForwardingArgumentsNode (location: (1,31)-(1,34))
+ │ ├── closing_loc: (1,34)-(1,35) = ")"
+ │ └── block: ∅
+ ├── locals: [:a, :b]
+ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: (1,7)-(1,8) = "("
+ ├── rparen_loc: (1,17)-(1,18) = ")"
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (1,37)-(1,40) = "end"
diff --git a/test/prism/snapshots/whitequark/true.txt b/test/prism/snapshots/whitequark/true.txt
new file mode 100644
index 0000000000..3e1ceef586
--- /dev/null
+++ b/test/prism/snapshots/whitequark/true.txt
@@ -0,0 +1,6 @@
+@ ProgramNode (location: (1,0)-(1,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ TrueNode (location: (1,0)-(1,4))
diff --git a/test/prism/snapshots/whitequark/unary_num_pow_precedence.txt b/test/prism/snapshots/whitequark/unary_num_pow_precedence.txt
new file mode 100644
index 0000000000..e14b0567e7
--- /dev/null
+++ b/test/prism/snapshots/whitequark/unary_num_pow_precedence.txt
@@ -0,0 +1,80 @@
+@ ProgramNode (location: (1,0)-(5,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(5,10))
+ └── body: (length: 3)
+ ├── @ CallNode (location: (1,0)-(1,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ FloatNode (location: (1,0)-(1,4))
+ │ │ └── value: 2.0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :**
+ │ ├── message_loc: (1,5)-(1,7) = "**"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,8)-(1,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (1,8)-(1,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── @ CallNode (location: (3,0)-(3,8))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ CallNode (location: (3,1)-(3,8))
+ │ │ ├── flags: ∅
+ │ │ ├── receiver:
+ │ │ │ @ IntegerNode (location: (3,1)-(3,2))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :**
+ │ │ ├── message_loc: (3,3)-(3,5) = "**"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (3,6)-(3,8))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (3,6)-(3,8))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 10
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :-@
+ │ ├── message_loc: (3,0)-(3,1) = "-"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ CallNode (location: (5,0)-(5,10))
+ ├── flags: ∅
+ ├── receiver:
+ │ @ CallNode (location: (5,1)-(5,10))
+ │ ├── flags: ∅
+ │ ├── receiver:
+ │ │ @ FloatNode (location: (5,1)-(5,4))
+ │ │ └── value: 2.0
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :**
+ │ ├── message_loc: (5,5)-(5,7) = "**"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (5,8)-(5,10))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ IntegerNode (location: (5,8)-(5,10))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :-@
+ ├── message_loc: (5,0)-(5,1) = "-"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/undef.txt b/test/prism/snapshots/whitequark/undef.txt
new file mode 100644
index 0000000000..163cc2e867
--- /dev/null
+++ b/test/prism/snapshots/whitequark/undef.txt
@@ -0,0 +1,39 @@
+@ ProgramNode (location: (1,0)-(1,27))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,27))
+ └── body: (length: 1)
+ └── @ UndefNode (location: (1,0)-(1,27))
+ ├── names: (length: 3)
+ │ ├── @ SymbolNode (location: (1,6)-(1,9))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: ∅
+ │ │ ├── value_loc: (1,6)-(1,9) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── @ SymbolNode (location: (1,11)-(1,15))
+ │ │ ├── flags: forced_us_ascii_encoding
+ │ │ ├── opening_loc: (1,11)-(1,12) = ":"
+ │ │ ├── value_loc: (1,12)-(1,15) = "bar"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "bar"
+ │ └── @ InterpolatedSymbolNode (location: (1,17)-(1,27))
+ │ ├── opening_loc: (1,17)-(1,19) = ":\""
+ │ ├── parts: (length: 2)
+ │ │ ├── @ StringNode (location: (1,19)-(1,22))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (1,19)-(1,22) = "foo"
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo"
+ │ │ └── @ EmbeddedStatementsNode (location: (1,22)-(1,26))
+ │ │ ├── opening_loc: (1,22)-(1,24) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,24)-(1,25))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (1,24)-(1,25))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── closing_loc: (1,25)-(1,26) = "}"
+ │ └── closing_loc: (1,26)-(1,27) = "\""
+ └── keyword_loc: (1,0)-(1,5) = "undef"
diff --git a/test/prism/snapshots/whitequark/unless.txt b/test/prism/snapshots/whitequark/unless.txt
new file mode 100644
index 0000000000..a3bbbe69c8
--- /dev/null
+++ b/test/prism/snapshots/whitequark/unless.txt
@@ -0,0 +1,63 @@
+@ ProgramNode (location: (1,0)-(3,20))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,20))
+ └── body: (length: 2)
+ ├── @ UnlessNode (location: (1,0)-(1,24))
+ │ ├── keyword_loc: (1,0)-(1,6) = "unless"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,7)-(1,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,7)-(1,10) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (1,11)-(1,15) = "then"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,16)-(1,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,16)-(1,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,16)-(1,19) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent: ∅
+ │ └── end_keyword_loc: (1,21)-(1,24) = "end"
+ └── @ UnlessNode (location: (3,0)-(3,20))
+ ├── keyword_loc: (3,0)-(3,6) = "unless"
+ ├── predicate:
+ │ @ CallNode (location: (3,7)-(3,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,7)-(3,10) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (3,12)-(3,15))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (3,12)-(3,15))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,12)-(3,15) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: (3,17)-(3,20) = "end"
diff --git a/test/prism/snapshots/whitequark/unless_else.txt b/test/prism/snapshots/whitequark/unless_else.txt
new file mode 100644
index 0000000000..f4f95379e5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/unless_else.txt
@@ -0,0 +1,95 @@
+@ ProgramNode (location: (1,0)-(3,30))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,30))
+ └── body: (length: 2)
+ ├── @ UnlessNode (location: (1,0)-(1,34))
+ │ ├── keyword_loc: (1,0)-(1,6) = "unless"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,7)-(1,10))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,7)-(1,10) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: (1,11)-(1,15) = "then"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (1,16)-(1,19))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,16)-(1,19))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,16)-(1,19) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── consequent:
+ │ │ @ ElseNode (location: (1,21)-(1,34))
+ │ │ ├── else_keyword_loc: (1,21)-(1,25) = "else"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,26)-(1,29))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,26)-(1,29))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (1,26)-(1,29) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── end_keyword_loc: (1,31)-(1,34) = "end"
+ │ └── end_keyword_loc: (1,31)-(1,34) = "end"
+ └── @ UnlessNode (location: (3,0)-(3,30))
+ ├── keyword_loc: (3,0)-(3,6) = "unless"
+ ├── predicate:
+ │ @ CallNode (location: (3,7)-(3,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,7)-(3,10) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (3,12)-(3,15))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (3,12)-(3,15))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (3,12)-(3,15) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent:
+ │ @ ElseNode (location: (3,17)-(3,30))
+ │ ├── else_keyword_loc: (3,17)-(3,21) = "else"
+ │ ├── statements:
+ │ │ @ StatementsNode (location: (3,22)-(3,25))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (3,22)-(3,25))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :baz
+ │ │ ├── message_loc: (3,22)-(3,25) = "baz"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── end_keyword_loc: (3,27)-(3,30) = "end"
+ └── end_keyword_loc: (3,27)-(3,30) = "end"
diff --git a/test/prism/snapshots/whitequark/unless_mod.txt b/test/prism/snapshots/whitequark/unless_mod.txt
new file mode 100644
index 0000000000..d4dfda6b2c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/unless_mod.txt
@@ -0,0 +1,34 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ UnlessNode (location: (1,0)-(1,14))
+ ├── keyword_loc: (1,4)-(1,10) = "unless"
+ ├── predicate:
+ │ @ CallNode (location: (1,11)-(1,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,11)-(1,14) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── then_keyword_loc: ∅
+ ├── statements:
+ │ @ StatementsNode (location: (1,0)-(1,3))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,0)-(1,3))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,0)-(1,3) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ └── end_keyword_loc: ∅
diff --git a/test/prism/snapshots/whitequark/until.txt b/test/prism/snapshots/whitequark/until.txt
new file mode 100644
index 0000000000..e5f60a2cf7
--- /dev/null
+++ b/test/prism/snapshots/whitequark/until.txt
@@ -0,0 +1,61 @@
+@ ProgramNode (location: (1,0)-(3,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,19))
+ └── body: (length: 2)
+ ├── @ UntilNode (location: (1,0)-(1,21))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (1,0)-(1,5) = "until"
+ │ ├── closing_loc: (1,18)-(1,21) = "end"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,6)-(1,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,6)-(1,9) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (1,13)-(1,17))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,13)-(1,17))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,13)-(1,17) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ UntilNode (location: (3,0)-(3,19))
+ ├── flags: ∅
+ ├── keyword_loc: (3,0)-(3,5) = "until"
+ ├── closing_loc: (3,16)-(3,19) = "end"
+ ├── predicate:
+ │ @ CallNode (location: (3,6)-(3,9))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,6)-(3,9) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (3,11)-(3,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (3,11)-(3,15))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :meth
+ ├── message_loc: (3,11)-(3,15) = "meth"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/until_mod.txt b/test/prism/snapshots/whitequark/until_mod.txt
new file mode 100644
index 0000000000..0b7e2360b5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/until_mod.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ UntilNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── keyword_loc: (1,5)-(1,10) = "until"
+ ├── closing_loc: ∅
+ ├── predicate:
+ │ @ CallNode (location: (1,11)-(1,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,11)-(1,14) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :meth
+ ├── message_loc: (1,0)-(1,4) = "meth"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/until_post.txt b/test/prism/snapshots/whitequark/until_post.txt
new file mode 100644
index 0000000000..5b282c363b
--- /dev/null
+++ b/test/prism/snapshots/whitequark/until_post.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ UntilNode (location: (1,0)-(1,24))
+ ├── flags: begin_modifier
+ ├── keyword_loc: (1,15)-(1,20) = "until"
+ ├── closing_loc: ∅
+ ├── predicate:
+ │ @ CallNode (location: (1,21)-(1,24))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,21)-(1,24) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,14))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,6)-(1,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,6)-(1,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,6)-(1,10) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,11)-(1,14) = "end"
diff --git a/test/prism/snapshots/whitequark/var_and_asgn.txt b/test/prism/snapshots/whitequark/var_and_asgn.txt
new file mode 100644
index 0000000000..a3c90f804c
--- /dev/null
+++ b/test/prism/snapshots/whitequark/var_and_asgn.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ LocalVariableAndWriteNode (location: (1,0)-(1,7))
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── operator_loc: (1,2)-(1,5) = "&&="
+ ├── value:
+ │ @ IntegerNode (location: (1,6)-(1,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── name: :a
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/var_op_asgn.txt b/test/prism/snapshots/whitequark/var_op_asgn.txt
new file mode 100644
index 0000000000..f423a62dee
--- /dev/null
+++ b/test/prism/snapshots/whitequark/var_op_asgn.txt
@@ -0,0 +1,57 @@
+@ ProgramNode (location: (1,0)-(7,23))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,23))
+ └── body: (length: 4)
+ ├── @ ClassVariableOperatorWriteNode (location: (1,0)-(1,11))
+ │ ├── name: :@@var
+ │ ├── name_loc: (1,0)-(1,5) = "@@var"
+ │ ├── operator_loc: (1,6)-(1,8) = "|="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (1,9)-(1,11))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ └── operator: :|
+ ├── @ InstanceVariableOperatorWriteNode (location: (3,0)-(3,7))
+ │ ├── name: :@a
+ │ ├── name_loc: (3,0)-(3,2) = "@a"
+ │ ├── operator_loc: (3,3)-(3,5) = "|="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (3,6)-(3,7))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ └── operator: :|
+ ├── @ LocalVariableOperatorWriteNode (location: (5,0)-(5,6))
+ │ ├── name_loc: (5,0)-(5,1) = "a"
+ │ ├── operator_loc: (5,2)-(5,4) = "+="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (5,5)-(5,6))
+ │ │ ├── flags: decimal
+ │ │ └── value: 1
+ │ ├── name: :a
+ │ ├── operator: :+
+ │ └── depth: 0
+ └── @ DefNode (location: (7,0)-(7,23))
+ ├── name: :a
+ ├── name_loc: (7,4)-(7,5) = "a"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (7,7)-(7,18))
+ │ └── body: (length: 1)
+ │ └── @ ClassVariableOperatorWriteNode (location: (7,7)-(7,18))
+ │ ├── name: :@@var
+ │ ├── name_loc: (7,7)-(7,12) = "@@var"
+ │ ├── operator_loc: (7,13)-(7,15) = "|="
+ │ ├── value:
+ │ │ @ IntegerNode (location: (7,16)-(7,18))
+ │ │ ├── flags: decimal
+ │ │ └── value: 10
+ │ └── operator: :|
+ ├── locals: []
+ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (7,20)-(7,23) = "end"
diff --git a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
new file mode 100644
index 0000000000..d56c099c7e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
@@ -0,0 +1,28 @@
+@ ProgramNode (location: (1,0)-(1,12))
+├── locals: [:foo]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,12))
+ └── body: (length: 1)
+ └── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,12))
+ ├── name_loc: (1,0)-(1,3) = "foo"
+ ├── operator_loc: (1,4)-(1,6) = "+="
+ ├── value:
+ │ @ CallNode (location: (1,7)-(1,12))
+ │ ├── flags: ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :m
+ │ ├── message_loc: (1,7)-(1,8) = "m"
+ │ ├── opening_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (1,9)-(1,12))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ LocalVariableReadNode (location: (1,9)-(1,12))
+ │ │ ├── name: :foo
+ │ │ └── depth: 0
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── name: :foo
+ ├── operator: :+
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/var_or_asgn.txt b/test/prism/snapshots/whitequark/var_or_asgn.txt
new file mode 100644
index 0000000000..a0531d2c30
--- /dev/null
+++ b/test/prism/snapshots/whitequark/var_or_asgn.txt
@@ -0,0 +1,14 @@
+@ ProgramNode (location: (1,0)-(1,7))
+├── locals: [:a]
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,7))
+ └── body: (length: 1)
+ └── @ LocalVariableOrWriteNode (location: (1,0)-(1,7))
+ ├── name_loc: (1,0)-(1,1) = "a"
+ ├── operator_loc: (1,2)-(1,5) = "||="
+ ├── value:
+ │ @ IntegerNode (location: (1,6)-(1,7))
+ │ ├── flags: decimal
+ │ └── value: 1
+ ├── name: :a
+ └── depth: 0
diff --git a/test/prism/snapshots/whitequark/when_multi.txt b/test/prism/snapshots/whitequark/when_multi.txt
new file mode 100644
index 0000000000..1c399b642d
--- /dev/null
+++ b/test/prism/snapshots/whitequark/when_multi.txt
@@ -0,0 +1,50 @@
+@ ProgramNode (location: (1,0)-(1,37))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,37))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,37))
+ ├── predicate:
+ │ @ CallNode (location: (1,5)-(1,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,10)-(1,32))
+ │ ├── keyword_loc: (1,10)-(1,14) = "when"
+ │ ├── conditions: (length: 2)
+ │ │ ├── @ StringNode (location: (1,15)-(1,20))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: (1,15)-(1,16) = "'"
+ │ │ │ ├── content_loc: (1,16)-(1,19) = "bar"
+ │ │ │ ├── closing_loc: (1,19)-(1,20) = "'"
+ │ │ │ └── unescaped: "bar"
+ │ │ └── @ StringNode (location: (1,22)-(1,27))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (1,22)-(1,23) = "'"
+ │ │ ├── content_loc: (1,23)-(1,26) = "baz"
+ │ │ ├── closing_loc: (1,26)-(1,27) = "'"
+ │ │ └── unescaped: "baz"
+ │ ├── then_keyword_loc: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (1,29)-(1,32))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,29)-(1,32))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,29)-(1,32) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,34)-(1,37) = "end"
diff --git a/test/prism/snapshots/whitequark/when_splat.txt b/test/prism/snapshots/whitequark/when_splat.txt
new file mode 100644
index 0000000000..351631714e
--- /dev/null
+++ b/test/prism/snapshots/whitequark/when_splat.txt
@@ -0,0 +1,72 @@
+@ ProgramNode (location: (1,0)-(1,43))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,43))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,43))
+ ├── predicate:
+ │ @ CallNode (location: (1,5)-(1,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── conditions: (length: 2)
+ │ ├── @ WhenNode (location: (1,10)-(1,27))
+ │ │ ├── keyword_loc: (1,10)-(1,14) = "when"
+ │ │ ├── conditions: (length: 2)
+ │ │ │ ├── @ IntegerNode (location: (1,15)-(1,16))
+ │ │ │ │ ├── flags: decimal
+ │ │ │ │ └── value: 1
+ │ │ │ └── @ SplatNode (location: (1,18)-(1,22))
+ │ │ │ ├── operator_loc: (1,18)-(1,19) = "*"
+ │ │ │ └── expression:
+ │ │ │ @ CallNode (location: (1,19)-(1,22))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :baz
+ │ │ │ ├── message_loc: (1,19)-(1,22) = "baz"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ ├── then_keyword_loc: ∅
+ │ │ └── statements:
+ │ │ @ StatementsNode (location: (1,24)-(1,27))
+ │ │ └── body: (length: 1)
+ │ │ └── @ CallNode (location: (1,24)-(1,27))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :bar
+ │ │ ├── message_loc: (1,24)-(1,27) = "bar"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── @ WhenNode (location: (1,29)-(1,38))
+ │ ├── keyword_loc: (1,29)-(1,33) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ SplatNode (location: (1,34)-(1,38))
+ │ │ ├── operator_loc: (1,34)-(1,35) = "*"
+ │ │ └── expression:
+ │ │ @ CallNode (location: (1,35)-(1,38))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,35)-(1,38) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ ├── then_keyword_loc: ∅
+ │ └── statements: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,40)-(1,43) = "end"
diff --git a/test/prism/snapshots/whitequark/when_then.txt b/test/prism/snapshots/whitequark/when_then.txt
new file mode 100644
index 0000000000..eb6f261ba4
--- /dev/null
+++ b/test/prism/snapshots/whitequark/when_then.txt
@@ -0,0 +1,44 @@
+@ ProgramNode (location: (1,0)-(1,34))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,34))
+ └── body: (length: 1)
+ └── @ CaseNode (location: (1,0)-(1,34))
+ ├── predicate:
+ │ @ CallNode (location: (1,5)-(1,8))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,5)-(1,8) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── conditions: (length: 1)
+ │ └── @ WhenNode (location: (1,10)-(1,29))
+ │ ├── keyword_loc: (1,10)-(1,14) = "when"
+ │ ├── conditions: (length: 1)
+ │ │ └── @ StringNode (location: (1,15)-(1,20))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: (1,15)-(1,16) = "'"
+ │ │ ├── content_loc: (1,16)-(1,19) = "bar"
+ │ │ ├── closing_loc: (1,19)-(1,20) = "'"
+ │ │ └── unescaped: "bar"
+ │ ├── then_keyword_loc: (1,21)-(1,25) = "then"
+ │ └── statements:
+ │ @ StatementsNode (location: (1,26)-(1,29))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,26)-(1,29))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :bar
+ │ ├── message_loc: (1,26)-(1,29) = "bar"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── consequent: ∅
+ ├── case_keyword_loc: (1,0)-(1,4) = "case"
+ └── end_keyword_loc: (1,31)-(1,34) = "end"
diff --git a/test/prism/snapshots/whitequark/while.txt b/test/prism/snapshots/whitequark/while.txt
new file mode 100644
index 0000000000..72f9971fe5
--- /dev/null
+++ b/test/prism/snapshots/whitequark/while.txt
@@ -0,0 +1,61 @@
+@ ProgramNode (location: (1,0)-(3,19))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(3,19))
+ └── body: (length: 2)
+ ├── @ WhileNode (location: (1,0)-(1,21))
+ │ ├── flags: ∅
+ │ ├── keyword_loc: (1,0)-(1,5) = "while"
+ │ ├── closing_loc: (1,18)-(1,21) = "end"
+ │ ├── predicate:
+ │ │ @ CallNode (location: (1,6)-(1,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (1,6)-(1,9) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── statements:
+ │ @ StatementsNode (location: (1,13)-(1,17))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,13)-(1,17))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,13)-(1,17) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── @ WhileNode (location: (3,0)-(3,19))
+ ├── flags: ∅
+ ├── keyword_loc: (3,0)-(3,5) = "while"
+ ├── closing_loc: (3,16)-(3,19) = "end"
+ ├── predicate:
+ │ @ CallNode (location: (3,6)-(3,9))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (3,6)-(3,9) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (3,11)-(3,15))
+ └── body: (length: 1)
+ └── @ CallNode (location: (3,11)-(3,15))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :meth
+ ├── message_loc: (3,11)-(3,15) = "meth"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/while_mod.txt b/test/prism/snapshots/whitequark/while_mod.txt
new file mode 100644
index 0000000000..50a8f84d81
--- /dev/null
+++ b/test/prism/snapshots/whitequark/while_mod.txt
@@ -0,0 +1,33 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ WhileNode (location: (1,0)-(1,14))
+ ├── flags: ∅
+ ├── keyword_loc: (1,5)-(1,10) = "while"
+ ├── closing_loc: ∅
+ ├── predicate:
+ │ @ CallNode (location: (1,11)-(1,14))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,11)-(1,14) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (1,0)-(1,4))
+ └── body: (length: 1)
+ └── @ CallNode (location: (1,0)-(1,4))
+ ├── flags: variable_call, ignore_visibility
+ ├── receiver: ∅
+ ├── call_operator_loc: ∅
+ ├── name: :meth
+ ├── message_loc: (1,0)-(1,4) = "meth"
+ ├── opening_loc: ∅
+ ├── arguments: ∅
+ ├── closing_loc: ∅
+ └── block: ∅
diff --git a/test/prism/snapshots/whitequark/while_post.txt b/test/prism/snapshots/whitequark/while_post.txt
new file mode 100644
index 0000000000..63c6c84a24
--- /dev/null
+++ b/test/prism/snapshots/whitequark/while_post.txt
@@ -0,0 +1,42 @@
+@ ProgramNode (location: (1,0)-(1,24))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,24))
+ └── body: (length: 1)
+ └── @ WhileNode (location: (1,0)-(1,24))
+ ├── flags: begin_modifier
+ ├── keyword_loc: (1,15)-(1,20) = "while"
+ ├── closing_loc: ∅
+ ├── predicate:
+ │ @ CallNode (location: (1,21)-(1,24))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (1,21)-(1,24) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ BeginNode (location: (1,0)-(1,14))
+ ├── begin_keyword_loc: (1,0)-(1,5) = "begin"
+ ├── statements:
+ │ @ StatementsNode (location: (1,6)-(1,10))
+ │ └── body: (length: 1)
+ │ └── @ CallNode (location: (1,6)-(1,10))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :meth
+ │ ├── message_loc: (1,6)-(1,10) = "meth"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ ├── rescue_clause: ∅
+ ├── else_clause: ∅
+ ├── ensure_clause: ∅
+ └── end_keyword_loc: (1,11)-(1,14) = "end"
diff --git a/test/prism/snapshots/whitequark/xstring_interp.txt b/test/prism/snapshots/whitequark/xstring_interp.txt
new file mode 100644
index 0000000000..0676ea9683
--- /dev/null
+++ b/test/prism/snapshots/whitequark/xstring_interp.txt
@@ -0,0 +1,37 @@
+@ ProgramNode (location: (1,0)-(1,14))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,14))
+ └── body: (length: 1)
+ └── @ InterpolatedXStringNode (location: (1,0)-(1,14))
+ ├── opening_loc: (1,0)-(1,1) = "`"
+ ├── parts: (length: 3)
+ │ ├── @ StringNode (location: (1,1)-(1,4))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (1,1)-(1,4) = "foo"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: "foo"
+ │ ├── @ EmbeddedStatementsNode (location: (1,4)-(1,10))
+ │ │ ├── opening_loc: (1,4)-(1,6) = "\#{"
+ │ │ ├── statements:
+ │ │ │ @ StatementsNode (location: (1,6)-(1,9))
+ │ │ │ └── body: (length: 1)
+ │ │ │ └── @ CallNode (location: (1,6)-(1,9))
+ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ ├── receiver: ∅
+ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ ├── name: :bar
+ │ │ │ ├── message_loc: (1,6)-(1,9) = "bar"
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── arguments: ∅
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── block: ∅
+ │ │ └── closing_loc: (1,9)-(1,10) = "}"
+ │ └── @ StringNode (location: (1,10)-(1,13))
+ │ ├── flags: frozen
+ │ ├── opening_loc: ∅
+ │ ├── content_loc: (1,10)-(1,13) = "baz"
+ │ ├── closing_loc: ∅
+ │ └── unescaped: "baz"
+ └── closing_loc: (1,13)-(1,14) = "`"
diff --git a/test/prism/snapshots/whitequark/xstring_plain.txt b/test/prism/snapshots/whitequark/xstring_plain.txt
new file mode 100644
index 0000000000..97084286d9
--- /dev/null
+++ b/test/prism/snapshots/whitequark/xstring_plain.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,8))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,8))
+ └── body: (length: 1)
+ └── @ XStringNode (location: (1,0)-(1,8))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "`"
+ ├── content_loc: (1,1)-(1,7) = "foobar"
+ ├── closing_loc: (1,7)-(1,8) = "`"
+ └── unescaped: "foobar"
diff --git a/test/prism/snapshots/whitequark/yield.txt b/test/prism/snapshots/whitequark/yield.txt
new file mode 100644
index 0000000000..2b37dd479f
--- /dev/null
+++ b/test/prism/snapshots/whitequark/yield.txt
@@ -0,0 +1,51 @@
+@ ProgramNode (location: (1,0)-(7,10))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,10))
+ └── body: (length: 4)
+ ├── @ YieldNode (location: (1,0)-(1,5))
+ │ ├── keyword_loc: (1,0)-(1,5) = "yield"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments: ∅
+ │ └── rparen_loc: ∅
+ ├── @ YieldNode (location: (3,0)-(3,9))
+ │ ├── keyword_loc: (3,0)-(3,5) = "yield"
+ │ ├── lparen_loc: ∅
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (3,6)-(3,9))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 1)
+ │ │ └── @ CallNode (location: (3,6)-(3,9))
+ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ ├── receiver: ∅
+ │ │ ├── call_operator_loc: ∅
+ │ │ ├── name: :foo
+ │ │ ├── message_loc: (3,6)-(3,9) = "foo"
+ │ │ ├── opening_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ ├── closing_loc: ∅
+ │ │ └── block: ∅
+ │ └── rparen_loc: ∅
+ ├── @ YieldNode (location: (5,0)-(5,7))
+ │ ├── keyword_loc: (5,0)-(5,5) = "yield"
+ │ ├── lparen_loc: (5,5)-(5,6) = "("
+ │ ├── arguments: ∅
+ │ └── rparen_loc: (5,6)-(5,7) = ")"
+ └── @ YieldNode (location: (7,0)-(7,10))
+ ├── keyword_loc: (7,0)-(7,5) = "yield"
+ ├── lparen_loc: (7,5)-(7,6) = "("
+ ├── arguments:
+ │ @ ArgumentsNode (location: (7,6)-(7,9))
+ │ ├── flags: ∅
+ │ └── arguments: (length: 1)
+ │ └── @ CallNode (location: (7,6)-(7,9))
+ │ ├── flags: variable_call, ignore_visibility
+ │ ├── receiver: ∅
+ │ ├── call_operator_loc: ∅
+ │ ├── name: :foo
+ │ ├── message_loc: (7,6)-(7,9) = "foo"
+ │ ├── opening_loc: ∅
+ │ ├── arguments: ∅
+ │ ├── closing_loc: ∅
+ │ └── block: ∅
+ └── rparen_loc: (7,9)-(7,10) = ")"
diff --git a/test/prism/snapshots/whitequark/zsuper.txt b/test/prism/snapshots/whitequark/zsuper.txt
new file mode 100644
index 0000000000..9c28128d06
--- /dev/null
+++ b/test/prism/snapshots/whitequark/zsuper.txt
@@ -0,0 +1,7 @@
+@ ProgramNode (location: (1,0)-(1,5))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,5))
+ └── body: (length: 1)
+ └── @ ForwardingSuperNode (location: (1,0)-(1,5))
+ └── block: ∅
diff --git a/test/prism/snapshots/xstring.txt b/test/prism/snapshots/xstring.txt
new file mode 100644
index 0000000000..1a177026db
--- /dev/null
+++ b/test/prism/snapshots/xstring.txt
@@ -0,0 +1,67 @@
+@ ProgramNode (location: (1,0)-(13,4))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(13,4))
+ └── body: (length: 6)
+ ├── @ XStringNode (location: (1,0)-(1,7))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (1,0)-(1,3) = "%x["
+ │ ├── content_loc: (1,3)-(1,6) = "foo"
+ │ ├── closing_loc: (1,6)-(1,7) = "]"
+ │ └── unescaped: "foo"
+ ├── @ InterpolatedXStringNode (location: (3,0)-(3,16))
+ │ ├── opening_loc: (3,0)-(3,1) = "`"
+ │ ├── parts: (length: 3)
+ │ │ ├── @ StringNode (location: (3,1)-(3,5))
+ │ │ │ ├── flags: frozen
+ │ │ │ ├── opening_loc: ∅
+ │ │ │ ├── content_loc: (3,1)-(3,5) = "foo "
+ │ │ │ ├── closing_loc: ∅
+ │ │ │ └── unescaped: "foo "
+ │ │ ├── @ EmbeddedStatementsNode (location: (3,5)-(3,11))
+ │ │ │ ├── opening_loc: (3,5)-(3,7) = "\#{"
+ │ │ │ ├── statements:
+ │ │ │ │ @ StatementsNode (location: (3,7)-(3,10))
+ │ │ │ │ └── body: (length: 1)
+ │ │ │ │ └── @ CallNode (location: (3,7)-(3,10))
+ │ │ │ │ ├── flags: variable_call, ignore_visibility
+ │ │ │ │ ├── receiver: ∅
+ │ │ │ │ ├── call_operator_loc: ∅
+ │ │ │ │ ├── name: :bar
+ │ │ │ │ ├── message_loc: (3,7)-(3,10) = "bar"
+ │ │ │ │ ├── opening_loc: ∅
+ │ │ │ │ ├── arguments: ∅
+ │ │ │ │ ├── closing_loc: ∅
+ │ │ │ │ └── block: ∅
+ │ │ │ └── closing_loc: (3,10)-(3,11) = "}"
+ │ │ └── @ StringNode (location: (3,11)-(3,15))
+ │ │ ├── flags: frozen
+ │ │ ├── opening_loc: ∅
+ │ │ ├── content_loc: (3,11)-(3,15) = " baz"
+ │ │ ├── closing_loc: ∅
+ │ │ └── unescaped: " baz"
+ │ └── closing_loc: (3,15)-(3,16) = "`"
+ ├── @ XStringNode (location: (5,0)-(5,5))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (5,0)-(5,1) = "`"
+ │ ├── content_loc: (5,1)-(5,4) = "foo"
+ │ ├── closing_loc: (5,4)-(5,5) = "`"
+ │ └── unescaped: "foo"
+ ├── @ XStringNode (location: (7,0)-(9,1))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (7,0)-(7,3) = "%x{"
+ │ ├── content_loc: (7,3)-(9,0) = "\n foo\n"
+ │ ├── closing_loc: (9,0)-(9,1) = "}"
+ │ └── unescaped: "\n foo\n"
+ ├── @ XStringNode (location: (11,0)-(11,2))
+ │ ├── flags: ∅
+ │ ├── opening_loc: (11,0)-(11,1) = "`"
+ │ ├── content_loc: (11,1)-(11,1) = ""
+ │ ├── closing_loc: (11,1)-(11,2) = "`"
+ │ └── unescaped: ""
+ └── @ XStringNode (location: (13,0)-(13,4))
+ ├── flags: ∅
+ ├── opening_loc: (13,0)-(13,3) = "%x{"
+ ├── content_loc: (13,3)-(13,3) = ""
+ ├── closing_loc: (13,3)-(13,4) = "}"
+ └── unescaped: ""
diff --git a/test/prism/snapshots/xstring_with_backslash.txt b/test/prism/snapshots/xstring_with_backslash.txt
new file mode 100644
index 0000000000..7e0fa1ab5f
--- /dev/null
+++ b/test/prism/snapshots/xstring_with_backslash.txt
@@ -0,0 +1,11 @@
+@ ProgramNode (location: (1,0)-(1,6))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(1,6))
+ └── body: (length: 1)
+ └── @ XStringNode (location: (1,0)-(1,6))
+ ├── flags: ∅
+ ├── opening_loc: (1,0)-(1,1) = "`"
+ ├── content_loc: (1,1)-(1,5) = "f\\oo"
+ ├── closing_loc: (1,5)-(1,6) = "`"
+ └── unescaped: "foo"
diff --git a/test/prism/snapshots/yield.txt b/test/prism/snapshots/yield.txt
new file mode 100644
index 0000000000..e9680c3b2d
--- /dev/null
+++ b/test/prism/snapshots/yield.txt
@@ -0,0 +1,103 @@
+@ ProgramNode (location: (1,0)-(7,28))
+├── locals: []
+└── statements:
+ @ StatementsNode (location: (1,0)-(7,28))
+ └── body: (length: 4)
+ ├── @ DefNode (location: (1,0)-(1,19))
+ │ ├── name: :foo
+ │ ├── name_loc: (1,4)-(1,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (1,9)-(1,14))
+ │ │ └── body: (length: 1)
+ │ │ └── @ YieldNode (location: (1,9)-(1,14))
+ │ │ ├── keyword_loc: (1,9)-(1,14) = "yield"
+ │ │ ├── lparen_loc: ∅
+ │ │ ├── arguments: ∅
+ │ │ └── rparen_loc: ∅
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (1,0)-(1,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (1,16)-(1,19) = "end"
+ ├── @ DefNode (location: (3,0)-(3,21))
+ │ ├── name: :foo
+ │ ├── name_loc: (3,4)-(3,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (3,9)-(3,16))
+ │ │ └── body: (length: 1)
+ │ │ └── @ YieldNode (location: (3,9)-(3,16))
+ │ │ ├── keyword_loc: (3,9)-(3,14) = "yield"
+ │ │ ├── lparen_loc: (3,14)-(3,15) = "("
+ │ │ ├── arguments: ∅
+ │ │ └── rparen_loc: (3,15)-(3,16) = ")"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (3,0)-(3,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (3,18)-(3,21) = "end"
+ ├── @ DefNode (location: (5,0)-(5,22))
+ │ ├── name: :foo
+ │ ├── name_loc: (5,4)-(5,7) = "foo"
+ │ ├── receiver: ∅
+ │ ├── parameters: ∅
+ │ ├── body:
+ │ │ @ StatementsNode (location: (5,9)-(5,17))
+ │ │ └── body: (length: 1)
+ │ │ └── @ YieldNode (location: (5,9)-(5,17))
+ │ │ ├── keyword_loc: (5,9)-(5,14) = "yield"
+ │ │ ├── lparen_loc: (5,14)-(5,15) = "("
+ │ │ ├── arguments:
+ │ │ │ @ ArgumentsNode (location: (5,15)-(5,16))
+ │ │ │ ├── flags: ∅
+ │ │ │ └── arguments: (length: 1)
+ │ │ │ └── @ IntegerNode (location: (5,15)-(5,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ └── rparen_loc: (5,16)-(5,17) = ")"
+ │ ├── locals: []
+ │ ├── def_keyword_loc: (5,0)-(5,3) = "def"
+ │ ├── operator_loc: ∅
+ │ ├── lparen_loc: ∅
+ │ ├── rparen_loc: ∅
+ │ ├── equal_loc: ∅
+ │ └── end_keyword_loc: (5,19)-(5,22) = "end"
+ └── @ DefNode (location: (7,0)-(7,28))
+ ├── name: :foo
+ ├── name_loc: (7,4)-(7,7) = "foo"
+ ├── receiver: ∅
+ ├── parameters: ∅
+ ├── body:
+ │ @ StatementsNode (location: (7,9)-(7,23))
+ │ └── body: (length: 1)
+ │ └── @ YieldNode (location: (7,9)-(7,23))
+ │ ├── keyword_loc: (7,9)-(7,14) = "yield"
+ │ ├── lparen_loc: (7,14)-(7,15) = "("
+ │ ├── arguments:
+ │ │ @ ArgumentsNode (location: (7,15)-(7,22))
+ │ │ ├── flags: ∅
+ │ │ └── arguments: (length: 3)
+ │ │ ├── @ IntegerNode (location: (7,15)-(7,16))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 1
+ │ │ ├── @ IntegerNode (location: (7,18)-(7,19))
+ │ │ │ ├── flags: decimal
+ │ │ │ └── value: 2
+ │ │ └── @ IntegerNode (location: (7,21)-(7,22))
+ │ │ ├── flags: decimal
+ │ │ └── value: 3
+ │ └── rparen_loc: (7,22)-(7,23) = ")"
+ ├── locals: []
+ ├── def_keyword_loc: (7,0)-(7,3) = "def"
+ ├── operator_loc: ∅
+ ├── lparen_loc: ∅
+ ├── rparen_loc: ∅
+ ├── equal_loc: ∅
+ └── end_keyword_loc: (7,25)-(7,28) = "end"
diff --git a/test/prism/static_inspect_test.rb b/test/prism/static_inspect_test.rb
new file mode 100644
index 0000000000..8df2fd241e
--- /dev/null
+++ b/test/prism/static_inspect_test.rb
@@ -0,0 +1,90 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+return if Prism::BACKEND == :FFI
+
+module Prism
+ class StaticInspectTest < TestCase
+ def test_false
+ assert_equal "false", static_inspect("false")
+ end
+
+ def test_float
+ assert_equal "0.25", static_inspect("0.25")
+ assert_equal "5.125", static_inspect("5.125")
+
+ assert_equal "0.0", static_inspect("0.0")
+ assert_equal "-0.0", static_inspect("-0.0")
+
+ assert_equal "1.0e+100", static_inspect("1e100")
+ assert_equal "-1.0e+100", static_inspect("-1e100")
+
+ assert_equal "Infinity", static_inspect("1e1000")
+ assert_equal "-Infinity", static_inspect("-1e1000")
+ end
+
+ def test_imaginary
+ assert_equal "(0+1i)", static_inspect("1i")
+ assert_equal "(0-1i)", static_inspect("-1i")
+ end
+
+ def test_integer
+ assert_equal "1000", static_inspect("1_0_0_0")
+ assert_equal "10000000000000000000000000000", static_inspect("1_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0")
+ end
+
+ def test_nil
+ assert_equal "nil", static_inspect("nil")
+ end
+
+ def test_rational
+ assert_equal "(0/1)", static_inspect("0r")
+ assert_equal "(1/1)", static_inspect("1r")
+ assert_equal "(1/1)", static_inspect("1.0r")
+ assert_equal "(77777/1000)", static_inspect("77.777r")
+ end
+
+ def test_regular_expression
+ assert_equal "/.*/", static_inspect("/.*/")
+ assert_equal "/.*/i", static_inspect("/.*/i")
+ assert_equal "/.*/", static_inspect("/.*/u")
+ assert_equal "/.*/n", static_inspect("/.*/un")
+ end
+
+ def test_source_encoding
+ assert_equal "#<Encoding:UTF-8>", static_inspect("__ENCODING__")
+ assert_equal "#<Encoding:Windows-31J>", static_inspect("__ENCODING__", encoding: "Windows-31J")
+ end
+
+ def test_source_file
+ assert_equal __FILE__.inspect, static_inspect("__FILE__", filepath: __FILE__, frozen_string_literal: true)
+ end
+
+ def test_source_line
+ assert_equal "1", static_inspect("__LINE__")
+ assert_equal "5", static_inspect("__LINE__", line: 5)
+ end
+
+ def test_string
+ assert_equal "\"\"", static_inspect('""', frozen_string_literal: true)
+ assert_equal "\"Hello, World!\"", static_inspect('"Hello, World!"', frozen_string_literal: true)
+ assert_equal "\"\\a\"", static_inspect("\"\\a\"", frozen_string_literal: true)
+ end
+
+ def test_symbol
+ assert_equal ":foo", static_inspect(":foo")
+ assert_equal ":foo", static_inspect("%s[foo]")
+ end
+
+ def test_true
+ assert_equal "true", static_inspect("true")
+ end
+
+ private
+
+ def static_inspect(source, **options)
+ Debug.static_inspect(source, **options)
+ end
+ end
+end
diff --git a/test/prism/static_literals_test.rb b/test/prism/static_literals_test.rb
new file mode 100644
index 0000000000..31c802bf90
--- /dev/null
+++ b/test/prism/static_literals_test.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class StaticLiteralsTest < TestCase
+ def test_static_literals
+ assert_warning("1")
+ assert_warning("0xA", "10", "10")
+ assert_warning("0o10", "8", "8")
+ assert_warning("0b10", "2", "2")
+ assert_warning("1_000", "1000", "1000")
+ assert_warning((2**32).to_s(10), "0x#{(2**32).to_s(16)}", (2**32).to_s(10))
+ assert_warning((2**64).to_s(10), "0x#{(2**64).to_s(16)}", (2**64).to_s(10))
+
+ refute_warning("1", "-1")
+ refute_warning((2**32).to_s(10), "-0x#{(2**32).to_s(16)}")
+ refute_warning((2**64).to_s(10), "-0x#{(2**64).to_s(16)}")
+
+ assert_warning("__LINE__", "2", "2")
+ assert_warning("3", "__LINE__", "3")
+
+ assert_warning("1.0")
+ assert_warning("1e2", "100.0", "100.0")
+
+ assert_warning("1r", "1r", "(1/1)")
+ assert_warning("1.0r", "1.0r", "(1/1)")
+
+ assert_warning("1i", "1i", "(0+1i)")
+ assert_warning("1.0i", "1.0i", "(0+1.0i)")
+
+ assert_warning("1ri", "1ri", "(0+(1/1)*i)")
+ assert_warning("1.0ri", "1.0ri", "(0+(1/1)*i)")
+
+ assert_warning("__FILE__", "\"#{__FILE__}\"", __FILE__)
+ assert_warning("\"#{__FILE__}\"")
+ assert_warning("\"foo\"")
+
+ assert_warning("/foo/")
+
+ refute_warning("/foo/", "/foo/i")
+
+ assert_warning(":foo")
+ assert_warning("%s[foo]", ":foo", ":foo")
+
+ assert_warning("true")
+ assert_warning("false")
+ assert_warning("nil")
+ assert_warning("__ENCODING__", "__ENCODING__", "#<Encoding:UTF-8>")
+ end
+
+ private
+
+ class NullWarning
+ def message
+ ""
+ end
+ end
+
+ def parse_warnings(left, right)
+ warnings = []
+
+ warnings << (Prism.parse(<<~RUBY, filepath: __FILE__).warnings.first || NullWarning.new)
+ {
+ #{left} => 1,
+ #{right} => 2
+ }
+ RUBY
+
+ warnings << (Prism.parse(<<~RUBY, filepath: __FILE__).warnings.first || NullWarning.new)
+ case foo
+ when #{left}
+ when #{right}
+ end
+ RUBY
+
+ warnings
+ end
+
+ def assert_warning(left, right = left, message = left)
+ hash_keys, when_clauses = parse_warnings(left, right)
+
+ assert_include hash_keys.message, message
+ assert_include hash_keys.message, "line 3"
+ assert_include when_clauses.message, "line 3"
+ end
+
+ def refute_warning(left, right)
+ assert_empty parse_warnings(left, right).grep_v(NullWarning)
+ end
+ end
+end
diff --git a/test/prism/test_helper.rb b/test/prism/test_helper.rb
new file mode 100644
index 0000000000..77af7e7b45
--- /dev/null
+++ b/test/prism/test_helper.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+
+require "prism"
+require "ripper"
+require "pp"
+require "test/unit"
+require "tempfile"
+
+puts "Using prism backend: #{Prism::BACKEND}" if ENV["PRISM_FFI_BACKEND"]
+
+# It is useful to have a diff even if the strings to compare are big
+# However, ruby/ruby does not have a version of Test::Unit with access to
+# max_diff_target_string_size
+if defined?(Test::Unit::Assertions::AssertionMessage)
+ Test::Unit::Assertions::AssertionMessage.max_diff_target_string_size = 5000
+end
+
+module Prism
+ class TestCase < ::Test::Unit::TestCase
+ private
+
+ if RUBY_ENGINE == "ruby"
+ # Check that the given source is valid syntax by compiling it with RubyVM.
+ def check_syntax(source)
+ $VERBOSE, previous = nil, $VERBOSE
+
+ begin
+ RubyVM::InstructionSequence.compile(source)
+ ensure
+ $VERBOSE = previous
+ end
+ end
+
+ # Assert that the given source is valid Ruby syntax by attempting to
+ # compile it, and then implicitly checking that it does not raise an
+ # syntax errors.
+ def assert_valid_syntax(source)
+ check_syntax(source)
+ end
+
+ # Refute that the given source is invalid Ruby syntax by attempting to
+ # compile it and asserting that it raises a SyntaxError.
+ def refute_valid_syntax(source)
+ assert_raise(SyntaxError) { check_syntax(source) }
+ end
+ else
+ def assert_valid_syntax(source)
+ end
+
+ def refute_valid_syntax(source)
+ end
+ end
+
+ def assert_raises(*args, &block)
+ raise "Use assert_raise instead"
+ end
+
+ def assert_equal_nodes(expected, actual, compare_location: true, parent: nil)
+ assert_equal expected.class, actual.class
+
+ case expected
+ when Array
+ assert_equal(
+ expected.size,
+ actual.size,
+ -> { "Arrays were different sizes. Parent: #{parent.pretty_inspect}" }
+ )
+
+ expected.zip(actual).each do |(expected_element, actual_element)|
+ assert_equal_nodes(
+ expected_element,
+ actual_element,
+ compare_location: compare_location,
+ parent: actual
+ )
+ end
+ when SourceFileNode
+ expected_deconstruct = expected.deconstruct_keys(nil)
+ actual_deconstruct = actual.deconstruct_keys(nil)
+ assert_equal expected_deconstruct.keys, actual_deconstruct.keys
+
+ # Filepaths can be different if test suites were run on different
+ # machines. We accommodate for this by comparing the basenames, and not
+ # the absolute filepaths.
+ expected_filepath = expected_deconstruct.delete(:filepath)
+ actual_filepath = actual_deconstruct.delete(:filepath)
+
+ assert_equal expected_deconstruct, actual_deconstruct
+ assert_equal File.basename(expected_filepath), File.basename(actual_filepath)
+ when Node
+ deconstructed_expected = expected.deconstruct_keys(nil)
+ deconstructed_actual = actual.deconstruct_keys(nil)
+ assert_equal deconstructed_expected.keys, deconstructed_actual.keys
+
+ deconstructed_expected.each_key do |key|
+ assert_equal_nodes(
+ deconstructed_expected[key],
+ deconstructed_actual[key],
+ compare_location: compare_location,
+ parent: actual
+ )
+ end
+ when Location
+ assert_operator actual.start_offset, :<=, actual.end_offset, -> {
+ "start_offset > end_offset for #{actual.inspect}, parent is #{parent.pretty_inspect}"
+ }
+
+ if compare_location
+ assert_equal(
+ expected.start_offset,
+ actual.start_offset,
+ -> { "Start locations were different. Parent: #{parent.pretty_inspect}" }
+ )
+
+ assert_equal(
+ expected.end_offset,
+ actual.end_offset,
+ -> { "End locations were different. Parent: #{parent.pretty_inspect}" }
+ )
+ end
+ else
+ assert_equal expected, actual
+ end
+ end
+ end
+end
diff --git a/test/prism/unescape_test.rb b/test/prism/unescape_test.rb
new file mode 100644
index 0000000000..2a352c5234
--- /dev/null
+++ b/test/prism/unescape_test.rb
@@ -0,0 +1,235 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+return if RUBY_VERSION < "3.1.0" || Prism::BACKEND == :FFI
+
+module Prism
+ class UnescapeTest < TestCase
+ module Context
+ class Base
+ attr_reader :left, :right
+
+ def initialize(left, right)
+ @left = left
+ @right = right
+ end
+
+ def name
+ "#{left}#{right}".delete("\n")
+ end
+
+ private
+
+ def code(escape)
+ "#{left}\\#{escape}#{right}".b
+ end
+
+ def ruby(escape)
+ previous, $VERBOSE = $VERBOSE, nil
+
+ begin
+ yield eval(code(escape))
+ rescue SyntaxError
+ :error
+ ensure
+ $VERBOSE = previous
+ end
+ end
+
+ def prism(escape)
+ result = Prism.parse(code(escape))
+
+ if result.success?
+ yield result.value.statements.body.first
+ else
+ :error
+ end
+ end
+
+ def `(command)
+ command
+ end
+ end
+
+ class List < Base
+ def ruby_result(escape)
+ ruby(escape) { |value| value.first.to_s }
+ end
+
+ def prism_result(escape)
+ prism(escape) { |node| node.elements.first.unescaped }
+ end
+ end
+
+ class Symbol < Base
+ def ruby_result(escape)
+ ruby(escape, &:to_s)
+ end
+
+ def prism_result(escape)
+ prism(escape, &:unescaped)
+ end
+ end
+
+ class String < Base
+ def ruby_result(escape)
+ ruby(escape, &:itself)
+ end
+
+ def prism_result(escape)
+ prism(escape, &:unescaped)
+ end
+ end
+
+ class Heredoc < Base
+ def ruby_result(escape)
+ ruby(escape, &:itself)
+ end
+
+ def prism_result(escape)
+ prism(escape) do |node|
+ case node.type
+ when :interpolated_string_node, :interpolated_x_string_node
+ node.parts.flat_map(&:unescaped).join
+ else
+ node.unescaped
+ end
+ end
+ end
+ end
+
+ class RegExp < Base
+ def ruby_result(escape)
+ ruby(escape, &:source)
+ end
+
+ def prism_result(escape)
+ prism(escape, &:unescaped)
+ end
+ end
+ end
+
+ def test_char; assert_context(Context::String.new("?", "")); end
+ def test_sqte; assert_context(Context::String.new("'", "'")); end
+ def test_dqte; assert_context(Context::String.new("\"", "\"")); end
+ def test_lwrq; assert_context(Context::String.new("%q[", "]")); end
+ def test_uprq; assert_context(Context::String.new("%Q[", "]")); end
+ def test_dstr; assert_context(Context::String.new("%[", "]")); end
+ def test_xstr; assert_context(Context::String.new("`", "`")); end
+ def test_lwrx; assert_context(Context::String.new("%x[", "]")); end
+ def test_h0_1; assert_context(Context::String.new("<<H\n", "\nH")); end
+ def test_h0_2; assert_context(Context::String.new("<<'H'\n", "\nH")); end
+ def test_h0_3; assert_context(Context::String.new("<<\"H\"\n", "\nH")); end
+ def test_h0_4; assert_context(Context::String.new("<<`H`\n", "\nH")); end
+ def test_hd_1; assert_context(Context::String.new("<<-H\n", "\nH")); end
+ def test_hd_2; assert_context(Context::String.new("<<-'H'\n", "\nH")); end
+ def test_hd_3; assert_context(Context::String.new("<<-\"H\"\n", "\nH")); end
+ def test_hd_4; assert_context(Context::String.new("<<-`H`\n", "\nH")); end
+ def test_ht_1; assert_context(Context::Heredoc.new("<<~H\n", "\nH")); end
+ def test_ht_2; assert_context(Context::Heredoc.new("<<~'H'\n", "\nH")); end
+ def test_ht_3; assert_context(Context::Heredoc.new("<<~\"H\"\n", "\nH")); end
+ def test_ht_4; assert_context(Context::Heredoc.new("<<~`H`\n", "\nH")); end
+ def test_pw_1; assert_context(Context::List.new("%w[", "]")); end
+ def test_pw_2; assert_context(Context::List.new("%w<", ">")); end
+ def test_uprw; assert_context(Context::List.new("%W[", "]")); end
+ def test_lwri; assert_context(Context::List.new("%i[", "]")); end
+ def test_upri; assert_context(Context::List.new("%I[", "]")); end
+ def test_lwrs; assert_context(Context::Symbol.new("%s[", "]")); end
+ def test_sym1; assert_context(Context::Symbol.new(":'", "'")); end
+ def test_sym2; assert_context(Context::Symbol.new(":\"", "\"")); end
+ def test_reg1; assert_context(Context::RegExp.new("/", "/")); end
+ def test_reg2; assert_context(Context::RegExp.new("%r[", "]")); end
+ def test_reg3; assert_context(Context::RegExp.new("%r<", ">")); end
+ def test_reg4; assert_context(Context::RegExp.new("%r{", "}")); end
+ def test_reg5; assert_context(Context::RegExp.new("%r(", ")")); end
+ def test_reg6; assert_context(Context::RegExp.new("%r|", "|")); end
+
+ private
+
+ def assert_context(context)
+ octal = [*("0".."7")]
+ hex = [*("a".."f"), *("A".."F"), *("0".."9")]
+
+ (0...256).each do |ord|
+ # I think this might be a bug in Ruby.
+ next if context.name == "?" && ord == 0xFF
+
+ # We don't currently support scanning for the number of capture groups
+ # to validate backreferences so these are all going to fail.
+ next if (context.name == "//" || context.name.start_with?("%r")) && ord.chr.start_with?(/\d/)
+
+ # \a \b \c ...
+ assert_unescape(context, ord.chr)
+ end
+
+ # \\r\n
+ assert_unescape(context, "\r\n")
+
+ # We don't currently support scanning for the number of capture groups to
+ # validate backreferences so these are all going to fail.
+ if context.name != "//" && !context.name.start_with?("%r")
+ # \00 \01 \02 ...
+ octal.product(octal).each { |digits| assert_unescape(context, digits.join) }
+
+ # \000 \001 \002 ...
+ octal.product(octal).product(octal).each { |digits| assert_unescape(context, digits.join) }
+ end
+
+ # \x0 \x1 \x2 ...
+ hex.each { |digit| assert_unescape(context, "x#{digit}") }
+
+ # \x00 \x01 \x02 ...
+ hex.product(hex).each { |digits| assert_unescape(context, "x#{digits.join}") }
+
+ # \u0000 \u0001 \u0002 ...
+ assert_unescape(context, "u#{["5"].concat(hex.sample(3)).join}")
+
+ # The behavior of whitespace in the middle of these escape sequences
+ # changed in Ruby 3.3.0, so we only want to test against latest.
+ if RUBY_VERSION >= "3.3.0"
+ # \u{00 00} ...
+ assert_unescape(context, "u{00#{["5"].concat(hex.sample(3)).join} \t\v 00#{["5"].concat(hex.sample(3)).join}}")
+ end
+
+ (0...128).each do |ord|
+ chr = ord.chr
+ next if chr == "\\" || !chr.match?(/[[:print:]]/)
+
+ # \C-a \C-b \C-c ...
+ assert_unescape(context, "C-#{chr}")
+
+ # \ca \cb \cc ...
+ assert_unescape(context, "c#{chr}")
+
+ # \M-a \M-b \M-c ...
+ assert_unescape(context, "M-#{chr}")
+
+ # \M-\C-a \M-\C-b \M-\C-c ...
+ assert_unescape(context, "M-\\C-#{chr}")
+
+ # \M-\ca \M-\cb \M-\cc ...
+ assert_unescape(context, "M-\\c#{chr}")
+
+ # \c\M-a \c\M-b \c\M-c ...
+ assert_unescape(context, "c\\M-#{chr}")
+ end
+ end
+
+ def assert_unescape(context, escape)
+ expected = context.ruby_result(escape)
+ actual = context.prism_result(escape)
+
+ message = -> do
+ "Expected #{context.name} to unescape #{escape.inspect} to " \
+ "#{expected.inspect}, but got #{actual.inspect}"
+ end
+
+ if expected == :error || actual == :error
+ assert_equal expected, actual, message
+ else
+ assert_equal expected.bytes, actual.bytes, message
+ end
+ end
+ end
+end
diff --git a/test/prism/version_test.rb b/test/prism/version_test.rb
new file mode 100644
index 0000000000..29ee6b224c
--- /dev/null
+++ b/test/prism/version_test.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+require_relative "test_helper"
+
+module Prism
+ class VersionTest < TestCase
+ def test_version_is_set
+ refute_nil VERSION
+ end
+ end
+end
diff --git a/test/prism/warnings_test.rb b/test/prism/warnings_test.rb
new file mode 100644
index 0000000000..7eb1bbd2e1
--- /dev/null
+++ b/test/prism/warnings_test.rb
@@ -0,0 +1,236 @@
+# frozen_string_literal: true
+
+return if RUBY_VERSION < "3.1"
+
+require_relative "test_helper"
+require "stringio"
+
+module Prism
+ class WarningsTest < TestCase
+ def test_ambiguous_uminus
+ assert_warning("a -b", "ambiguous first argument")
+ end
+
+ def test_ambiguous_uplus
+ assert_warning("a +b", "ambiguous first argument")
+ end
+
+ def test_ambiguous_ustar
+ assert_warning("a *b", "argument prefix")
+ end
+
+ def test_ambiguous_regexp
+ assert_warning("a /b/", "wrap regexp in parentheses")
+ end
+
+ def test_equal_in_conditional
+ assert_warning("if a = 1; end; a = a", "should be ==")
+ end
+
+ def test_dot_dot_dot_eol
+ assert_warning("_ = foo...", "... at EOL")
+ assert_warning("def foo(...) = bar ...", "... at EOL")
+
+ assert_warning("_ = foo... #", "... at EOL")
+ assert_warning("_ = foo... \t\v\f\n", "... at EOL")
+
+ refute_warning("p foo...bar")
+ refute_warning("p foo... bar")
+ end
+
+ def test_END_in_method
+ assert_warning("def foo; END {}; end", "END in method")
+ end
+
+ def test_duplicated_hash_key
+ assert_warning("{ a: 1, a: 2 }", "duplicated and overwritten")
+ end
+
+ def test_duplicated_when_clause
+ assert_warning("case 1; when 1, 1; end", "clause with line")
+ end
+
+ def test_float_out_of_range
+ assert_warning("_ = 1.0e100000", "out of range")
+ end
+
+ def test_integer_in_flip_flop
+ assert_warning("1 if 2..foo", "integer")
+ end
+
+ def test_keyword_eol
+ assert_warning("if\ntrue; end", "end of line")
+ assert_warning("if true\nelsif\nfalse; end", "end of line")
+ end
+
+ def test_string_in_predicate
+ assert_warning("if 'foo'; end", "string")
+ assert_warning("if \"\#{foo}\"; end", "string")
+ assert_warning("if __FILE__; end", "string")
+ end
+
+ def test_symbol_in_predicate
+ assert_warning("if :foo; end", "symbol")
+ assert_warning("if :\"\#{foo}\"; end", "symbol")
+ end
+
+ def test_literal_in_predicate
+ assert_warning("if __LINE__; end", "literal")
+ assert_warning("if __ENCODING__; end", "literal")
+ assert_warning("if 1; end", "literal")
+ assert_warning("if 1.0; end", "literal")
+ assert_warning("if 1r; end", "literal")
+ assert_warning("if 1i; end", "literal")
+ end
+
+ def test_regexp_in_predicate
+ assert_warning("if /foo/; end", "regex")
+ assert_warning("if /foo\#{bar}/; end", "regex")
+ end
+
+ def test_unused_local_variables
+ assert_warning("foo = 1", "unused")
+
+ refute_warning("foo = 1", compare: false, command_line: "e")
+ refute_warning("foo = 1", compare: false, scopes: [[]])
+
+ assert_warning("def foo; bar = 1; end", "unused")
+ assert_warning("def foo; bar, = 1; end", "unused")
+
+ refute_warning("def foo; bar &&= 1; end")
+ refute_warning("def foo; bar ||= 1; end")
+ refute_warning("def foo; bar += 1; end")
+
+ refute_warning("def foo; bar = bar; end")
+ refute_warning("def foo; bar = bar = 1; end")
+ refute_warning("def foo; bar = (bar = 1); end")
+ refute_warning("def foo; bar = begin; bar = 1; end; end")
+ refute_warning("def foo; bar = (qux; bar = 1); end")
+ refute_warning("def foo; bar, = bar = 1; end")
+ refute_warning("def foo; bar, = 1, bar = 1; end")
+
+ refute_warning("def foo(bar); end")
+ refute_warning("def foo(bar = 1); end")
+ refute_warning("def foo((bar)); end")
+ refute_warning("def foo(*bar); end")
+ refute_warning("def foo(*, bar); end")
+ refute_warning("def foo(*, (bar)); end")
+ refute_warning("def foo(bar:); end")
+ refute_warning("def foo(**bar); end")
+ refute_warning("def foo(&bar); end")
+ refute_warning("->(bar) {}")
+ refute_warning("->(; bar) {}", compare: false)
+
+ refute_warning("def foo; bar = 1; tap { bar }; end")
+ refute_warning("def foo; bar = 1; tap { baz = bar; baz }; end")
+ end
+
+ def test_void_statements
+ assert_warning("foo = 1; foo", "a variable in void")
+ assert_warning("@foo", "a variable in void")
+ assert_warning("@@foo", "a variable in void")
+ assert_warning("$foo", "a variable in void")
+ assert_warning("$+", "a variable in void")
+ assert_warning("$1", "a variable in void")
+
+ assert_warning("self", "self in void")
+ assert_warning("nil", "nil in void")
+ assert_warning("true", "true in void")
+ assert_warning("false", "false in void")
+
+ assert_warning("1", "literal in void")
+ assert_warning("1.0", "literal in void")
+ assert_warning("1r", "literal in void")
+ assert_warning("1i", "literal in void")
+ assert_warning(":foo", "literal in void")
+ assert_warning("\"foo\"", "literal in void")
+ assert_warning("\"foo\#{1}\"", "literal in void")
+ assert_warning("/foo/", "literal in void")
+ assert_warning("/foo\#{1}/", "literal in void")
+
+ assert_warning("Foo", "constant in void")
+ assert_warning("::Foo", ":: in void")
+ assert_warning("Foo::Bar", ":: in void")
+
+ assert_warning("1..2", ".. in void")
+ assert_warning("1..", ".. in void")
+ assert_warning("..2", ".. in void")
+ assert_warning("1...2", "... in void")
+ assert_warning("1...;", "... in void")
+ assert_warning("...2", "... in void")
+
+ assert_warning("defined?(foo)", "defined? in void")
+
+ assert_warning("1 + 1", "+ in void")
+ assert_warning("1 - 1", "- in void")
+ assert_warning("1 * 1", "* in void")
+ assert_warning("1 / 1", "/ in void")
+ assert_warning("1 % 1", "% in void")
+ assert_warning("1 | 1", "| in void")
+ assert_warning("1 ^ 1", "^ in void")
+ assert_warning("1 & 1", "& in void")
+ assert_warning("1 > 1", "> in void")
+ assert_warning("1 < 1", "< in void")
+
+ assert_warning("1 ** 1", "** in void")
+ assert_warning("1 <= 1", "<= in void")
+ assert_warning("1 >= 1", ">= in void")
+ assert_warning("1 != 1", "!= in void")
+ assert_warning("1 == 1", "== in void")
+ assert_warning("1 <=> 1", "<=> in void")
+
+ assert_warning("+foo", "+@ in void")
+ assert_warning("-foo", "-@ in void")
+
+ assert_warning("def foo; @bar; @baz; end", "variable in void")
+ refute_warning("def foo; @bar; end")
+ refute_warning("@foo", compare: false, scopes: [[]])
+ end
+
+ def test_unreachable_statement
+ assert_warning("begin; rescue; retry; foo; end", "statement not reached")
+
+ assert_warning("return; foo", "statement not reached")
+
+ assert_warning("tap { break; foo }", "statement not reached")
+ assert_warning("tap { break 1; foo }", "statement not reached")
+
+ assert_warning("tap { next; foo }", "statement not reached")
+ assert_warning("tap { next 1; foo }", "statement not reached")
+
+ assert_warning("tap { redo; foo }", "statement not reached")
+ end
+
+ private
+
+ def assert_warning(source, message)
+ warnings = Prism.parse(source).warnings
+
+ assert_equal 1, warnings.length
+ assert_include warnings.first.message, message
+
+ if defined?(RubyVM::AbstractSyntaxTree)
+ assert_include capture_warning { RubyVM::AbstractSyntaxTree.parse(source) }, message
+ end
+ end
+
+ def refute_warning(source, compare: true, **options)
+ assert_empty Prism.parse(source, **options).warnings
+
+ if compare && defined?(RubyVM::AbstractSyntaxTree)
+ assert_empty capture_warning { RubyVM::AbstractSyntaxTree.parse(source) }
+ end
+ end
+
+ def capture_warning
+ stderr, $stderr, verbose, $VERBOSE = $stderr, StringIO.new, $VERBOSE, true
+
+ begin
+ yield
+ $stderr.string
+ ensure
+ $stderr, $VERBOSE = stderr, verbose
+ end
+ end
+ end
+end
diff --git a/test/psych/test_coder.rb b/test/psych/test_coder.rb
index b2be0a4109..a6f5ad7f36 100644
--- a/test/psych/test_coder.rb
+++ b/test/psych/test_coder.rb
@@ -220,6 +220,8 @@ module Psych
end
def test_coder_style_map_any
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
foo = Psych.dump CustomEncode.new \
map: {a: 1, b: 2},
style: Psych::Nodes::Mapping::ANY,
@@ -228,6 +230,8 @@ module Psych
end
def test_coder_style_map_block
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
foo = Psych.dump CustomEncode.new \
map: {a: 1, b: 2},
style: Psych::Nodes::Mapping::BLOCK,
@@ -236,6 +240,8 @@ module Psych
end
def test_coder_style_map_flow
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
foo = Psych.dump CustomEncode.new \
map: { a: 1, b: 2 },
style: Psych::Nodes::Mapping::FLOW,
diff --git a/test/psych/test_date_time.rb b/test/psych/test_date_time.rb
index 6f1e8b509e..3379bd24bf 100644
--- a/test/psych/test_date_time.rb
+++ b/test/psych/test_date_time.rb
@@ -44,6 +44,26 @@ module Psych
assert_match(/12:00:00-05:00/, cycled.last.to_s)
end
+ def test_julian_date
+ d = Date.new(1582, 10, 4, Date::GREGORIAN)
+ assert_cycle d
+ end
+
+ def test_proleptic_gregorian_date
+ d = Date.new(1582, 10, 14, Date::GREGORIAN)
+ assert_cycle d
+ end
+
+ def test_julian_datetime
+ dt = DateTime.new(1582, 10, 4, 23, 58, 59, 0, Date::GREGORIAN)
+ assert_cycle dt
+ end
+
+ def test_proleptic_gregorian_datetime
+ dt = DateTime.new(1582, 10, 14, 23, 58, 59, 0, Date::GREGORIAN)
+ assert_cycle dt
+ end
+
def test_invalid_date
assert_cycle "2013-10-31T10:40:07-000000000000033"
end
diff --git a/test/psych/test_encoding.rb b/test/psych/test_encoding.rb
index e5831c9045..1867d59ea6 100644
--- a/test/psych/test_encoding.rb
+++ b/test/psych/test_encoding.rb
@@ -13,13 +13,13 @@ module Psych
(Handler.instance_methods(true) -
Object.instance_methods).each do |m|
- class_eval %{
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
def #{m} *args
@strings += args.flatten.find_all { |a|
String === a
}
end
- }
+ RUBY
end
end
@@ -119,6 +119,8 @@ module Psych
end
def test_emit_alias
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
@emitter.start_stream Psych::Parser::UTF8
@emitter.start_document [], [], true
e = assert_raise(RuntimeError) do
@@ -151,6 +153,7 @@ module Psych
@emitter.end_mapping
@emitter.end_document false
@emitter.end_stream
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
@parser.parse @buffer.string
assert_encodings @utf8, @handler.strings
@@ -170,6 +173,7 @@ module Psych
@emitter.end_sequence
@emitter.end_document false
@emitter.end_stream
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
@parser.parse @buffer.string
assert_encodings @utf8, @handler.strings
@@ -187,6 +191,7 @@ module Psych
@emitter.scalar 'foo', nil, nil, true, false, Nodes::Scalar::ANY
@emitter.end_document false
@emitter.end_stream
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
@parser.parse @buffer.string
assert_encodings @utf8, @handler.strings
@@ -263,6 +268,8 @@ module Psych
end
def test_dump_non_ascii_string_to_file
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
Tempfile.create(['utf8', 'yml'], :encoding => 'UTF-8') do |t|
h = {'one' => 'いち'}
Psych.dump(h, t)
diff --git a/test/psych/test_numeric.rb b/test/psych/test_numeric.rb
index 9c75c016cd..4c012e4562 100644
--- a/test/psych/test_numeric.rb
+++ b/test/psych/test_numeric.rb
@@ -1,6 +1,9 @@
# frozen_string_literal: true
require_relative 'helper'
-require 'bigdecimal'
+begin
+ require 'bigdecimal'
+rescue LoadError
+end
module Psych
###
@@ -29,13 +32,13 @@ module Psych
def test_big_decimal_tag
decimal = BigDecimal("12.34")
assert_match "!ruby/object:BigDecimal", Psych.dump(decimal)
- end
+ end if defined?(BigDecimal)
def test_big_decimal_round_trip
decimal = BigDecimal("12.34")
$DEBUG = false
assert_cycle decimal
- end
+ end if defined?(BigDecimal)
def test_does_not_attempt_numeric
str = Psych.load('--- 4 roses')
diff --git a/test/psych/test_object_references.rb b/test/psych/test_object_references.rb
index 269d72242e..86bb9034b9 100644
--- a/test/psych/test_object_references.rb
+++ b/test/psych/test_object_references.rb
@@ -39,7 +39,7 @@ module Psych
rescue Psych::DisallowedClass
data = Psych.unsafe_load yml
end
- assert_equal data.first.object_id, data.last.object_id
+ assert_same data.first, data.last
end
def test_float_references
@@ -49,7 +49,7 @@ module Psych
- *name
eoyml
assert_equal data.first, data.last
- assert_equal data.first.object_id, data.last.object_id
+ assert_same data.first, data.last
end
def test_binary_references
@@ -60,7 +60,7 @@ module Psych
- *name
eoyml
assert_equal data.first, data.last
- assert_equal data.first.object_id, data.last.object_id
+ assert_same data.first, data.last
end
def test_regexp_references
@@ -70,7 +70,7 @@ module Psych
- *name
eoyml
assert_equal data.first, data.last
- assert_equal data.first.object_id, data.last.object_id
+ assert_same data.first, data.last
end
end
end
diff --git a/test/psych/test_parser.rb b/test/psych/test_parser.rb
index 3604e7c985..c1e0abb89d 100644
--- a/test/psych/test_parser.rb
+++ b/test/psych/test_parser.rb
@@ -16,13 +16,13 @@ module Psych
(Handler.instance_methods(true) -
Object.instance_methods).each do |m|
- class_eval %{
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
def #{m} *args
super
@marks << @parser.mark if @parser
@calls << [:#{m}, args]
end
- }
+ RUBY
end
end
@@ -85,6 +85,8 @@ module Psych
def test_line_numbers
assert_equal 0, @parser.mark.line
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
@parser.parse "---\n- hello\n- world"
line_calls = @handler.marks.map(&:line).zip(@handler.calls.map(&:first))
assert_equal [
@@ -110,6 +112,8 @@ module Psych
def test_column_numbers
assert_equal 0, @parser.mark.column
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
@parser.parse "---\n- hello\n- world"
col_calls = @handler.marks.map(&:column).zip(@handler.calls.map(&:first))
assert_equal [
@@ -135,6 +139,8 @@ module Psych
def test_index_numbers
assert_equal 0, @parser.mark.index
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
@parser.parse "---\n- hello\n- world"
idx_calls = @handler.marks.map(&:index).zip(@handler.calls.map(&:first))
assert_equal [
@@ -352,6 +358,8 @@ module Psych
end
def test_event_location
+ pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/
+
@parser.parse "foo:\n" \
" barbaz: [1, 2]"
@@ -376,6 +384,25 @@ module Psych
[:end_stream, [2, 0, 2, 0]]], events
end
+ if Psych::Parser.method_defined?(:code_point_limit)
+ def test_code_point_limit
+ yaml = "foo: bar\n" * 500_000
+ assert_raise(org.snakeyaml.engine.v2.exceptions.YamlEngineException) do
+ Psych.load(yaml)
+ end
+
+ assert_nothing_raised do
+ begin
+ old_code_point_limit, Psych::Parser.code_point_limit = Psych::Parser::code_point_limit, 5_000_000
+
+ Psych.load(yaml)
+ ensure
+ Psych::Parser.code_point_limit = old_code_point_limit
+ end
+ end
+ end
+ end
+
def assert_called call, with = nil, parser = @parser
if with
call = parser.handler.calls.find { |x|
diff --git a/test/psych/test_psych.rb b/test/psych/test_psych.rb
index 1abd69ceca..42586a8779 100644
--- a/test/psych/test_psych.rb
+++ b/test/psych/test_psych.rb
@@ -419,12 +419,41 @@ eoyml
end
def test_safe_dump_symbols
+ assert_equal Psych.dump(:foo), Psych.safe_dump(:foo, permitted_classes: [Symbol])
+ assert_equal Psych.dump(:foo), Psych.safe_dump(:foo, permitted_symbols: [:foo])
+
error = assert_raise Psych::DisallowedClass do
- Psych.safe_dump(:foo, permitted_classes: [Symbol])
+ Psych.safe_dump(:foo)
end
assert_equal "Tried to dump unspecified class: Symbol(:foo)", error.message
- assert_match(/\A--- :foo\n(?:\.\.\.\n)?\z/, Psych.safe_dump(:foo, permitted_classes: [Symbol], permitted_symbols: [:foo]))
+ assert_match(/\A--- :foo\n(?:\.\.\.\n)?\z/, Psych.safe_dump(:foo, permitted_symbols: [:foo]))
+ end
+
+ def test_safe_dump_stringify_names
+ yaml = <<-eoyml
+---
+foo:
+ bar: bar
+ 'no': special escapes
+ 123: number
+eoyml
+
+ payload = Psych.safe_dump({
+ foo: {
+ bar: "bar",
+ no: "special escapes",
+ 123 => "number"
+ }
+ }, stringify_names: true)
+ assert_equal yaml, payload
+
+ assert_equal("---\nfoo: :bar\n", Psych.safe_dump({foo: :bar}, stringify_names: true, permitted_symbols: [:bar]))
+
+ error = assert_raise Psych::DisallowedClass do
+ Psych.safe_dump({foo: :bar}, stringify_names: true)
+ end
+ assert_equal "Tried to dump unspecified class: Symbol(:bar)", error.message
end
def test_safe_dump_aliases
diff --git a/test/psych/test_scalar_scanner.rb b/test/psych/test_scalar_scanner.rb
index 145db58fd9..02b923afe2 100644
--- a/test/psych/test_scalar_scanner.rb
+++ b/test/psych/test_scalar_scanner.rb
@@ -150,7 +150,7 @@ module Psych
end
def test_scan_strict_int_commas_and_underscores
- # this test is to ensure adherance to YML spec using the 'strict_integer' option
+ # this test is to ensure adherence to YML spec using the 'strict_integer' option
scanner = Psych::ScalarScanner.new ClassLoader.new, strict_integer: true
assert_equal 123_456_789, scanner.tokenize('123_456_789')
assert_equal '123,456,789', scanner.tokenize('123,456,789')
diff --git a/test/psych/test_set.rb b/test/psych/test_set.rb
index 87944d839e..b4968d3425 100644
--- a/test/psych/test_set.rb
+++ b/test/psych/test_set.rb
@@ -46,5 +46,12 @@ bar: baz
@set['self'] = @set
assert_cycle(@set)
end
+
+ def test_stringify_names
+ @set[:symbol] = :value
+
+ assert_match(/^:symbol: :value/, Psych.dump(@set))
+ assert_match(/^symbol: :value/, Psych.dump(@set, stringify_names: true))
+ end
end
end
diff --git a/test/psych/test_string.rb b/test/psych/test_string.rb
index 0dc34b3083..84ae5cbb45 100644
--- a/test/psych/test_string.rb
+++ b/test/psych/test_string.rb
@@ -17,17 +17,17 @@ module Psych
end
end
- # 'y' and 'n' are kind of ambiguous. Syck treated y and n literals in
+ # 'y', 'Y', 'n', 'N' are kind of ambiguous. Syck treated those literals in
# YAML documents as strings. But this is not what the YAML 1.1 spec says.
# YAML 1.1 says they should be treated as booleans. When we're dumping
# documents, we know it's a string, so adding quotes will eliminate the
# "ambiguity" in the emitted document
- def test_y_is_quoted
- assert_match(/"y"/, Psych.dump("y"))
- end
- def test_n_is_quoted
- assert_match(/"n"/, Psych.dump("n"))
+ def test_all_yaml_1_1_booleans_are_quoted
+ yaml_1_1_booleans = %w[y Y yes Yes YES n N no No NO true True TRUE false False FALSE on On ON off Off OFF] # from https://yaml.org/type/bool.html
+ yaml_1_1_booleans.each do |boolean|
+ assert_match(/"#{boolean}"|'#{boolean}'/, Psych.dump(boolean))
+ end
end
def test_string_with_newline
diff --git a/test/psych/test_yaml.rb b/test/psych/test_yaml.rb
index e12b9769fe..cedec46cc7 100644
--- a/test/psych/test_yaml.rb
+++ b/test/psych/test_yaml.rb
@@ -34,7 +34,7 @@ class Psych_Unit_Tests < Psych::TestCase
# [ruby-core:34969]
def test_regexp_with_n
- assert_cycle(Regexp.new('',0,'n'))
+ assert_cycle(Regexp.new('',Regexp::NOENCODING))
end
#
# Tests modified from 00basic.t in Psych.pm
@@ -223,8 +223,8 @@ EOY
&C currency: GBP
&D departure: LAX
&A arrival: EDI
- - { *F: MADF, *C: AUD, *D: SYD, *A: MEL }
- - { *F: DFSF, *C: USD, *D: JFK, *A: MCO }
+ - { *F : MADF, *C : AUD, *D : SYD, *A : MEL }
+ - { *F : DFSF, *C : USD, *D : JFK, *A : MCO }
EOY
)
@@ -233,20 +233,20 @@ EOY
---
ALIASES: [&f fareref, &c currency, &d departure, &a arrival]
FARES:
-- *f: DOGMA
- *c: GBP
- *d: LAX
- *a: EDI
-
-- *f: MADF
- *c: AUD
- *d: SYD
- *a: MEL
-
-- *f: DFSF
- *c: USD
- *d: JFK
- *a: MCO
+- *f : DOGMA
+ *c : GBP
+ *d : LAX
+ *a : EDI
+
+- *f : MADF
+ *c : AUD
+ *d : SYD
+ *a : MEL
+
+- *f : DFSF
+ *c : USD
+ *d : JFK
+ *a : MCO
EOY
)
diff --git a/test/psych/visitors/test_emitter.rb b/test/psych/visitors/test_emitter.rb
index 70adbb9ca0..8bcf5491ca 100644
--- a/test/psych/visitors/test_emitter.rb
+++ b/test/psych/visitors/test_emitter.rb
@@ -61,9 +61,9 @@ module Psych
@visitor.accept s
- assert_match(/key: value/, @io.string)
+ assert_include(@io.string, "key: value")
assert_equal @io.string, s.yaml
- assert(/\.\.\./ !~ s.yaml)
+ assert_not_include(s.yaml, "...")
end
def test_scalar
@@ -76,7 +76,7 @@ module Psych
@visitor.accept s
- assert_match(/hello/, @io.string)
+ assert_include(@io.string, "hello")
assert_equal @io.string, s.yaml
end
@@ -90,8 +90,8 @@ module Psych
@visitor.accept s
- assert_match(/str/, @io.string)
- assert_match(/hello/, @io.string)
+ assert_include(@io.string, "str")
+ assert_include(@io.string, "hello")
assert_equal @io.string, s.yaml
end
@@ -107,7 +107,7 @@ module Psych
@visitor.accept s
- assert_match(/- hello/, @io.string)
+ assert_include(@io.string, "- hello")
assert_equal @io.string, s.yaml
end
@@ -122,7 +122,7 @@ module Psych
@visitor.accept s
- assert_match(/key: value/, @io.string)
+ assert_include(@io.string, "key: value")
assert_equal @io.string, s.yaml
end
@@ -137,7 +137,7 @@ module Psych
@visitor.accept s
- assert_match(/&A key: \*A/, @io.string)
+ assert_include(@io.string, "&A key: \*A")
assert_equal @io.string, s.yaml
end
end
diff --git a/test/psych/visitors/test_to_ruby.rb b/test/psych/visitors/test_to_ruby.rb
index 3d4608b903..89c3676651 100644
--- a/test/psych/visitors/test_to_ruby.rb
+++ b/test/psych/visitors/test_to_ruby.rb
@@ -319,7 +319,7 @@ description:
list = seq.to_ruby
assert_equal %w{ foo foo }, list
- assert_equal list[0].object_id, list[1].object_id
+ assert_same list[0], list[1]
end
def test_mapping_with_str_tag
diff --git a/test/psych/visitors/test_yaml_tree.rb b/test/psych/visitors/test_yaml_tree.rb
index 4c48670f2f..01e685134a 100644
--- a/test/psych/visitors/test_yaml_tree.rb
+++ b/test/psych/visitors/test_yaml_tree.rb
@@ -34,7 +34,7 @@ module Psych
v << "hello world"
v.finish
- assert_match "hello world", io.string
+ assert_include io.string, "hello world"
end
def test_binary_formatting
@@ -167,9 +167,9 @@ module Psych
end
def test_string
- assert_match(/'017'/, Psych.dump({'a' => '017'}))
- assert_match(/'019'/, Psych.dump({'a' => '019'}))
- assert_match(/'01818'/, Psych.dump({'a' => '01818'}))
+ assert_include(Psych.dump({'a' => '017'}), "'017'")
+ assert_include(Psych.dump({'a' => '019'}), "'019'")
+ assert_include(Psych.dump({'a' => '01818'}), "'01818'")
end
# http://yaml.org/type/null.html
diff --git a/test/racc/assets/cadenza.y b/test/racc/assets/cadenza.y
deleted file mode 100644
index 1940ead225..0000000000
--- a/test/racc/assets/cadenza.y
+++ /dev/null
@@ -1,170 +0,0 @@
-# This grammar is released under an MIT license
-# Author: William Howard (http://github.com/whoward)
-# Source: https://github.com/whoward/cadenza/blob/master/src/cadenza.y
-
-class Cadenza::RaccParser
-
-/* expect this many shift/reduce conflicts */
-expect 37
-
-rule
- target
- : document
- | /* none */ { result = nil }
- ;
-
- parameter_list
- : logical_expression { result = [val[0]] }
- | parameter_list ',' logical_expression { result = val[0].push(val[2]) }
- ;
-
- /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
- primary_expression
- : IDENTIFIER { result = VariableNode.new(val[0].value) }
- | IDENTIFIER parameter_list { result = VariableNode.new(val[0].value, val[1]) }
- | INTEGER { result = ConstantNode.new(val[0].value) }
- | REAL { result = ConstantNode.new(val[0].value) }
- | STRING { result = ConstantNode.new(val[0].value) }
- | '(' filtered_expression ')' { result = val[1] }
- ;
-
- multiplicative_expression
- : primary_expression
- | multiplicative_expression '*' primary_expression { result = OperationNode.new(val[0], "*", val[2]) }
- | multiplicative_expression '/' primary_expression { result = OperationNode.new(val[0], "/", val[2]) }
- ;
-
- additive_expression
- : multiplicative_expression
- | additive_expression '+' multiplicative_expression { result = OperationNode.new(val[0], "+", val[2]) }
- | additive_expression '-' multiplicative_expression { result = OperationNode.new(val[0], "-", val[2]) }
- ;
-
- boolean_expression
- : additive_expression
- | boolean_expression OP_EQ additive_expression { result = OperationNode.new(val[0], "==", val[2]) }
- | boolean_expression OP_NEQ additive_expression { result = OperationNode.new(val[0], "!=", val[2]) }
- | boolean_expression OP_LEQ additive_expression { result = OperationNode.new(val[0], "<=", val[2]) }
- | boolean_expression OP_GEQ additive_expression { result = OperationNode.new(val[0], ">=", val[2]) }
- | boolean_expression '>' additive_expression { result = OperationNode.new(val[0], ">", val[2]) }
- | boolean_expression '<' additive_expression { result = OperationNode.new(val[0], "<", val[2]) }
- ;
-
- inverse_expression
- : boolean_expression
- | NOT boolean_expression { result = BooleanInverseNode.new(val[1]) }
- ;
-
- logical_expression
- : inverse_expression
- | logical_expression AND inverse_expression { result = OperationNode.new(val[0], "and", val[2]) }
- | logical_expression OR inverse_expression { result = OperationNode.new(val[0], "or", val[2]) }
- ;
-
- filter
- : IDENTIFIER { result = FilterNode.new(val[0].value) }
- | IDENTIFIER ':' parameter_list { result = FilterNode.new(val[0].value, val[2]) }
- ;
-
- filter_list
- : filter { result = [val[0]] }
- | filter_list '|' filter { result = val[0].push(val[2]) }
- ;
-
- filtered_expression
- : logical_expression
- | logical_expression '|' filter_list { result = FilteredValueNode.new(val[0], val[2]) }
- ;
-
- inject_statement
- : VAR_OPEN filtered_expression VAR_CLOSE { result = val[1] }
- ;
-
- if_tag
- : STMT_OPEN IF logical_expression STMT_CLOSE { open_scope!; result = val[2] }
- | STMT_OPEN UNLESS logical_expression STMT_CLOSE { open_scope!; result = BooleanInverseNode.new(val[2]) }
- ;
-
- else_tag
- : STMT_OPEN ELSE STMT_CLOSE { result = close_scope!; open_scope! }
- ;
-
- end_if_tag
- : STMT_OPEN ENDIF STMT_CLOSE { result = close_scope! }
- | STMT_OPEN ENDUNLESS STMT_CLOSE { result = close_scope! }
- ;
-
- if_block
- : if_tag end_if_tag { result = IfNode.new(val[0], val[1]) }
- | if_tag document end_if_tag { result = IfNode.new(val[0], val[2]) }
- | if_tag else_tag document end_if_tag { result = IfNode.new(val[0], val[1], val[3]) }
- | if_tag document else_tag end_if_tag { result = IfNode.new(val[0], val[2], val[3]) }
- | if_tag document else_tag document end_if_tag { result = IfNode.new(val[0], val[2], val[4]) }
- ;
-
- for_tag
- : STMT_OPEN FOR IDENTIFIER IN filtered_expression STMT_CLOSE { open_scope!; result = [val[2].value, val[4]] }
- ;
-
- end_for_tag
- : STMT_OPEN ENDFOR STMT_CLOSE { result = close_scope! }
- ;
-
- /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
- for_block
- : for_tag end_for_tag { result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[1]) }
- | for_tag document end_for_tag { result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[2]) }
- ;
-
- block_tag
- : STMT_OPEN BLOCK IDENTIFIER STMT_CLOSE { result = open_block_scope!(val[2].value) }
- ;
-
- end_block_tag
- : STMT_OPEN ENDBLOCK STMT_CLOSE { result = close_block_scope! }
- ;
-
- /* this has a shift/reduce conflict but since Racc will shift in this case it is the correct behavior */
- block_block
- : block_tag end_block_tag { result = BlockNode.new(val[0], val[1]) }
- | block_tag document end_block_tag { result = BlockNode.new(val[0], val[2]) }
- ;
-
- generic_block_tag
- : STMT_OPEN IDENTIFIER STMT_CLOSE { open_scope!; result = [val[1].value, []] }
- | STMT_OPEN IDENTIFIER parameter_list STMT_CLOSE { open_scope!; result = [val[1].value, val[2]] }
- ;
-
- end_generic_block_tag
- : STMT_OPEN END STMT_CLOSE { result = close_scope! }
- ;
-
- generic_block
- : generic_block_tag document end_generic_block_tag { result = GenericBlockNode.new(val[0].first, val[2], val[0].last) }
- ;
-
- extends_statement
- : STMT_OPEN EXTENDS STRING STMT_CLOSE { result = val[2].value }
- | STMT_OPEN EXTENDS IDENTIFIER STMT_CLOSE { result = VariableNode.new(val[2].value) }
- ;
-
- document_component
- : TEXT_BLOCK { result = TextNode.new(val[0].value) }
- | inject_statement
- | if_block
- | for_block
- | generic_block
- | block_block
- ;
-
- document
- : document_component { push val[0] }
- | document document_component { push val[1] }
- | extends_statement { document.extends = val[0] }
- | document extends_statement { document.extends = val[1] }
- ;
-
----- header ----
-# racc_parser.rb : generated by racc
-
----- inner ----
diff --git a/test/racc/assets/cast.y b/test/racc/assets/cast.y
deleted file mode 100644
index d180c09e14..0000000000
--- a/test/racc/assets/cast.y
+++ /dev/null
@@ -1,926 +0,0 @@
-# The MIT License
-#
-# Copyright (c) George Ogata
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class C::Parser
-# shift/reduce conflict on "if (c) if (c) ; else ; else ;"
-expect 1
-rule
-
-# A.2.4 External definitions
-
-# Returns TranslationUnit
-translation_unit
- : external_declaration {result = TranslationUnit.new_at(val[0].pos, NodeChain[val[0]])}
- | translation_unit external_declaration {result = val[0]; result.entities << val[1]}
-
-# Returns Declaration|FunctionDef
-external_declaration
- : function_definition {result = val[0]}
- | declaration {result = val[0]}
-
-# Returns FunctionDef
-function_definition
- : declaration_specifiers declarator declaration_list compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], val[2], val[3])}
- | declaration_specifiers declarator compound_statement {result = make_function_def(val[0][0], val[0][1], val[1], nil , val[2])}
-
-# Returns [Declaration]
-declaration_list
- : declaration {result = [val[0]]}
- | declaration_list declaration {result = val[0] << val[1]}
-
-# A.2.3 Statements
-
-# Returns Statement
-statement
- : labeled_statement {result = val[0]}
- | compound_statement {result = val[0]}
- | expression_statement {result = val[0]}
- | selection_statement {result = val[0]}
- | iteration_statement {result = val[0]}
- | jump_statement {result = val[0]}
-
-# Returns Statement
-labeled_statement
- : identifier COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].val)); result = val[2]}
- | CASE constant_expression COLON statement {val[3].labels.unshift(Case .new_at(val[0].pos, val[1] )); result = val[3]}
- | DEFAULT COLON statement {val[2].labels.unshift(Default .new_at(val[0].pos )); result = val[2]}
- # type names can also be used as labels
- | typedef_name COLON statement {val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].name)); result = val[2]}
-
-# Returns Block
-compound_statement
- : LBRACE block_item_list RBRACE {result = Block.new_at(val[0].pos, val[1])}
- | LBRACE RBRACE {result = Block.new_at(val[0].pos )}
-
-# Returns NodeChain[Declaration|Statement]
-block_item_list
- : block_item {result = NodeChain[val[0]]}
- | block_item_list block_item {result = val[0] << val[1]}
-
-# Returns Declaration|Statement
-block_item
- : declaration {result = val[0]}
- | statement {result = val[0]}
-
-# Returns ExpressionStatement
-expression_statement
- : expression SEMICOLON {result = ExpressionStatement.new_at(val[0].pos, val[0])}
- | SEMICOLON {result = ExpressionStatement.new_at(val[0].pos )}
-
-# Returns Statement
-selection_statement
- : IF LPAREN expression RPAREN statement {result = If .new_at(val[0].pos, val[2], val[4] )}
- | IF LPAREN expression RPAREN statement ELSE statement {result = If .new_at(val[0].pos, val[2], val[4], val[6])}
- | SWITCH LPAREN expression RPAREN statement {result = Switch.new_at(val[0].pos, val[2], val[4] )}
-
-# Returns Statement
-iteration_statement
- : WHILE LPAREN expression RPAREN statement {result = While.new_at(val[0].pos, val[2], val[4] )}
- | DO statement WHILE LPAREN expression RPAREN SEMICOLON {result = While.new_at(val[0].pos, val[4], val[1], :do => true )}
- | FOR LPAREN expression SEMICOLON expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], val[4], val[6], val[8])}
- | FOR LPAREN expression SEMICOLON expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], val[4], nil , val[7])}
- | FOR LPAREN expression SEMICOLON SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[5], val[7])}
- | FOR LPAREN expression SEMICOLON SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[6])}
- | FOR LPAREN SEMICOLON expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, nil , val[3], val[5], val[7])}
- | FOR LPAREN SEMICOLON expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, nil , val[3], nil , val[6])}
- | FOR LPAREN SEMICOLON SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, nil , nil , val[4], val[6])}
- | FOR LPAREN SEMICOLON SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, nil , nil , nil , val[5])}
- | FOR LPAREN declaration expression SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], val[3], val[5], val[7])}
- | FOR LPAREN declaration expression SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], val[3], nil , val[6])}
- | FOR LPAREN declaration SEMICOLON expression RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , val[4], val[6])}
- | FOR LPAREN declaration SEMICOLON RPAREN statement {result = For.new_at(val[0].pos, val[2], nil , nil , val[5])}
-
-# Returns Statement
-jump_statement
- : GOTO identifier SEMICOLON {result = Goto .new_at(val[0].pos, val[1].val)}
- | CONTINUE SEMICOLON {result = Continue.new_at(val[0].pos )}
- | BREAK SEMICOLON {result = Break .new_at(val[0].pos )}
- | RETURN expression SEMICOLON {result = Return .new_at(val[0].pos, val[1] )}
- | RETURN SEMICOLON {result = Return .new_at(val[0].pos )}
- # type names can also be used as labels
- | GOTO typedef_name SEMICOLON {result = Goto .new_at(val[0].pos, val[1].name)}
-
-# A.2.2 Declarations
-
-# Returns Declaration
-declaration
- : declaration_specifiers init_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
- | declaration_specifiers SEMICOLON {result = make_declaration(val[0][0], val[0][1], NodeArray[])}
-
-# Returns {Pos, [Symbol]}
-declaration_specifiers
- : storage_class_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
- | storage_class_specifier {result = [val[0][0], [val[0][1]]]}
- | type_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
- | type_specifier {result = [val[0][0], [val[0][1]]]}
- | type_qualifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
- | type_qualifier {result = [val[0][0], [val[0][1]]]}
- | function_specifier declaration_specifiers {val[1][1] << val[0][1]; result = val[1]}
- | function_specifier {result = [val[0][0], [val[0][1]]]}
-
-# Returns NodeArray[Declarator]
-init_declarator_list
- : init_declarator {result = NodeArray[val[0]]}
- | init_declarator_list COMMA init_declarator {result = val[0] << val[2]}
-
-# Returns Declarator
-init_declarator
- : declarator {result = val[0]}
- | declarator EQ initializer {val[0].init = val[2]; result = val[0]}
-
-# Returns [Pos, Symbol]
-storage_class_specifier
- : TYPEDEF {result = [val[0].pos, :typedef ]}
- | EXTERN {result = [val[0].pos, :extern ]}
- | STATIC {result = [val[0].pos, :static ]}
- | AUTO {result = [val[0].pos, :auto ]}
- | REGISTER {result = [val[0].pos, :register]}
-
-# Returns [Pos, Type|Symbol]
-type_specifier
- : VOID {result = [val[0].pos, :void ]}
- | CHAR {result = [val[0].pos, :char ]}
- | SHORT {result = [val[0].pos, :short ]}
- | INT {result = [val[0].pos, :int ]}
- | LONG {result = [val[0].pos, :long ]}
- | FLOAT {result = [val[0].pos, :float ]}
- | DOUBLE {result = [val[0].pos, :double ]}
- | SIGNED {result = [val[0].pos, :signed ]}
- | UNSIGNED {result = [val[0].pos, :unsigned ]}
- | BOOL {result = [val[0].pos, :_Bool ]}
- | COMPLEX {result = [val[0].pos, :_Complex ]}
- | IMAGINARY {result = [val[0].pos, :_Imaginary]}
- | struct_or_union_specifier {result = [val[0].pos, val[0] ]}
- | enum_specifier {result = [val[0].pos, val[0] ]}
- | typedef_name {result = [val[0].pos, val[0] ]}
-
-# Returns Struct|Union
-struct_or_union_specifier
- : struct_or_union identifier LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], val[1].val, val[3])}
- | struct_or_union LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], nil , val[2])}
- | struct_or_union identifier {result = val[0][1].new_at(val[0][0], val[1].val, nil )}
- # type names can also be used as struct identifiers
- | struct_or_union typedef_name LBRACE struct_declaration_list RBRACE {result = val[0][1].new_at(val[0][0], val[1].name, val[3])}
- | struct_or_union typedef_name {result = val[0][1].new_at(val[0][0], val[1].name, nil )}
-
-# Returns [Pos, Class]
-struct_or_union
- : STRUCT {result = [val[0].pos, Struct]}
- | UNION {result = [val[0].pos, Union ]}
-
-# Returns NodeArray[Declaration]
-struct_declaration_list
- : struct_declaration {result = NodeArray[val[0]]}
- | struct_declaration_list struct_declaration {val[0] << val[1]; result = val[0]}
-
-# Returns Declaration
-struct_declaration
- : specifier_qualifier_list struct_declarator_list SEMICOLON {result = make_declaration(val[0][0], val[0][1], val[1])}
-
-# Returns {Pos, [Symbol]}
-specifier_qualifier_list
- : type_specifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
- | type_specifier {result = [val[0][0], [val[0][1]]]}
- | type_qualifier specifier_qualifier_list {val[1][1] << val[0][1]; result = val[1]}
- | type_qualifier {result = [val[0][0], [val[0][1]]]}
-
-# Returns NodeArray[Declarator]
-struct_declarator_list
- : struct_declarator {result = NodeArray[val[0]]}
- | struct_declarator_list COMMA struct_declarator {result = val[0] << val[2]}
-
-# Returns Declarator
-struct_declarator
- : declarator {result = val[0]}
- | declarator COLON constant_expression {result = val[0]; val[0].num_bits = val[2]}
- | COLON constant_expression {result = Declarator.new_at(val[0].pos, :num_bits => val[1])}
-
-# Returns Enum
-enum_specifier
- : ENUM identifier LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
- | ENUM LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
- | ENUM identifier LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].val, val[3])}
- | ENUM LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, nil , val[2])}
- | ENUM identifier {result = Enum.new_at(val[0].pos, val[1].val, nil )}
- # type names can also be used as enum names
- | ENUM typedef_name LBRACE enumerator_list RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
- | ENUM typedef_name LBRACE enumerator_list COMMA RBRACE {result = Enum.new_at(val[0].pos, val[1].name, val[3])}
- | ENUM typedef_name {result = Enum.new_at(val[0].pos, val[1].name, nil )}
-
-# Returns NodeArray[Enumerator]
-enumerator_list
- : enumerator {result = NodeArray[val[0]]}
- | enumerator_list COMMA enumerator {result = val[0] << val[2]}
-
-# Returns Enumerator
-enumerator
- : enumeration_constant {result = Enumerator.new_at(val[0].pos, val[0].val, nil )}
- | enumeration_constant EQ constant_expression {result = Enumerator.new_at(val[0].pos, val[0].val, val[2])}
-
-# Returns [Pos, Symbol]
-type_qualifier
- : CONST {result = [val[0].pos, :const ]}
- | RESTRICT {result = [val[0].pos, :restrict]}
- | VOLATILE {result = [val[0].pos, :volatile]}
-
-# Returns [Pos, Symbol]
-function_specifier
- : INLINE {result = [val[0].pos, :inline]}
-
-# Returns Declarator
-declarator
- : pointer direct_declarator {result = add_decl_type(val[1], val[0])}
- | direct_declarator {result = val[0]}
-
-# Returns Declarator
-direct_declarator
- : identifier {result = Declarator.new_at(val[0].pos, nil, val[0].val)}
- | LPAREN declarator RPAREN {result = val[1]}
- | direct_declarator LBRACKET type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
- | direct_declarator LBRACKET type_qualifier_list RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
- | direct_declarator LBRACKET assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos, nil, val[2]))}
- | direct_declarator LBRACKET RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))}
- | direct_declarator LBRACKET STATIC type_qualifier_list assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
- | direct_declarator LBRACKET STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
- | direct_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
- | direct_declarator LBRACKET type_qualifier_list MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
- | direct_declarator LBRACKET MUL RBRACKET {result = add_decl_type(val[0], Array.new_at(val[0].pos ))} # TODO
- | direct_declarator LPAREN parameter_type_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, param_list(*val[2]), :var_args => val[2][1]))}
- | direct_declarator LPAREN identifier_list RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, val[2]))}
- | direct_declarator LPAREN RPAREN {result = add_decl_type(val[0], Function.new_at(val[0].pos ))}
-
-# Returns Pointer
-pointer
- : MUL type_qualifier_list {result = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]) }
- | MUL {result = Pointer.new_at(val[0].pos) }
- | MUL type_qualifier_list pointer {p = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]); val[2].direct_type = p; result = val[2]}
- | MUL pointer {p = Pointer.new_at(val[0].pos) ; val[1].direct_type = p; result = val[1]}
-
-# Returns {Pos, [Symbol]}
-type_qualifier_list
- : type_qualifier {result = [val[0][0], [val[0][1]]]}
- | type_qualifier_list type_qualifier {val[0][1] << val[1][1]; result = val[0]}
-
-# Returns [NodeArray[Parameter], var_args?]
-parameter_type_list
- : parameter_list {result = [val[0], false]}
- | parameter_list COMMA ELLIPSIS {result = [val[0], true ]}
-
-# Returns NodeArray[Parameter]
-parameter_list
- : parameter_declaration {result = NodeArray[val[0]]}
- | parameter_list COMMA parameter_declaration {result = val[0] << val[2]}
-
-# Returns Parameter
-parameter_declaration
- : declaration_specifiers declarator {ind_type = val[1].indirect_type and ind_type.detach
- result = make_parameter(val[0][0], val[0][1], ind_type, val[1].name)}
- | declaration_specifiers abstract_declarator {result = make_parameter(val[0][0], val[0][1], val[1] , nil )}
- | declaration_specifiers {result = make_parameter(val[0][0], val[0][1], nil , nil )}
-
-# Returns NodeArray[Parameter]
-identifier_list
- : identifier {result = NodeArray[Parameter.new_at(val[0].pos, nil, val[0].val)]}
- | identifier_list COMMA identifier {result = val[0] << Parameter.new_at(val[2].pos, nil, val[2].val)}
-
-# Returns Type
-type_name
- : specifier_qualifier_list abstract_declarator {val[1].direct_type = make_direct_type(val[0][0], val[0][1]); result = val[1]}
- | specifier_qualifier_list {result = make_direct_type(val[0][0], val[0][1]) }
-
-# Returns Type
-abstract_declarator
- : pointer {result = val[0]}
- | pointer direct_abstract_declarator {val[1].direct_type = val[0]; result = val[1]}
- | direct_abstract_declarator {result = val[0]}
-
-# Returns Type
-direct_abstract_declarator
- : LPAREN abstract_declarator RPAREN {result = val[1]}
- | direct_abstract_declarator LBRACKET assignment_expression RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, val[2]); result = val[0]}
- | direct_abstract_declarator LBRACKET RBRACKET {val[0].direct_type = Array.new_at(val[0].pos, nil, nil ); result = val[0]}
- | LBRACKET assignment_expression RBRACKET {result = Array.new_at(val[0].pos, nil, val[1])}
- | LBRACKET RBRACKET {result = Array.new_at(val[0].pos )}
- | direct_abstract_declarator LBRACKET MUL RBRACKET {val[0].direct_type = Array.new_at(val[0].pos); result = val[0]} # TODO
- | LBRACKET MUL RBRACKET {result = Array.new_at(val[0].pos)} # TODO
- | direct_abstract_declarator LPAREN parameter_type_list RPAREN {val[0].direct_type = Function.new_at(val[0].pos, nil, param_list(*val[2]), val[2][1]); result = val[0]}
- | direct_abstract_declarator LPAREN RPAREN {val[0].direct_type = Function.new_at(val[0].pos ); result = val[0]}
- | LPAREN parameter_type_list RPAREN {result = Function.new_at(val[0].pos, nil, param_list(*val[1]), val[1][1])}
- | LPAREN RPAREN {result = Function.new_at(val[0].pos )}
-
-# Returns CustomType
-typedef_name
- #: identifier -- insufficient since we must distinguish between type
- # names and var names (otherwise we have a conflict)
- : TYPENAME {result = CustomType.new_at(val[0].pos, val[0].val)}
-
-# Returns Expression
-initializer
- : assignment_expression {result = val[0]}
- | LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
- | LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, nil, val[1])}
-
-# Returns NodeArray[MemberInit]
-initializer_list
- : designation initializer {result = NodeArray[MemberInit.new_at(val[0][0] , val[0][1], val[1])]}
- | initializer {result = NodeArray[MemberInit.new_at(val[0].pos, nil , val[0])]}
- | initializer_list COMMA designation initializer {result = val[0] << MemberInit.new_at(val[2][0] , val[2][1], val[3])}
- | initializer_list COMMA initializer {result = val[0] << MemberInit.new_at(val[2].pos, nil , val[2])}
-
-# Returns {Pos, NodeArray[Expression|Token]}
-designation
- : designator_list EQ {result = val[0]}
-
-# Returns {Pos, NodeArray[Expression|Token]}
-designator_list
- : designator {result = val[0]; val[0][1] = NodeArray[val[0][1]]}
- | designator_list designator {result = val[0]; val[0][1] << val[1][1]}
-
-# Returns {Pos, Expression|Member}
-designator
- : LBRACKET constant_expression RBRACKET {result = [val[1].pos, val[1] ]}
- | DOT identifier {result = [val[1].pos, Member.new_at(val[1].pos, val[1].val)]}
-
-# A.2.1 Expressions
-
-# Returns Expression
-primary_expression
- : identifier {result = Variable.new_at(val[0].pos, val[0].val)}
- | constant {result = val[0]}
- | string_literal {result = val[0]}
- # GCC EXTENSION: allow a compound statement in parentheses as an expression
- | LPAREN expression RPAREN {result = val[1]}
- | LPAREN compound_statement RPAREN {block_expressions_enabled? or parse_error val[0].pos, "compound statement found where expression expected"
- result = BlockExpression.new(val[1]); result.pos = val[0].pos}
-
-# Returns Expression
-postfix_expression
- : primary_expression {result = val[0]}
- | postfix_expression LBRACKET expression RBRACKET {result = Index .new_at(val[0].pos, val[0], val[2])}
- | postfix_expression LPAREN argument_expression_list RPAREN {result = Call .new_at(val[0].pos, val[0], val[2] )}
- | postfix_expression LPAREN RPAREN {result = Call .new_at(val[0].pos, val[0], NodeArray[])}
- | postfix_expression DOT identifier {result = Dot .new_at(val[0].pos, val[0], Member.new(val[2].val))}
- | postfix_expression ARROW identifier {result = Arrow .new_at(val[0].pos, val[0], Member.new(val[2].val))}
- | postfix_expression INC {result = PostInc .new_at(val[0].pos, val[0] )}
- | postfix_expression DEC {result = PostDec .new_at(val[0].pos, val[0] )}
- | LPAREN type_name RPAREN LBRACE initializer_list RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
- | LPAREN type_name RPAREN LBRACE initializer_list COMMA RBRACE {result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])}
-
-# Returns [Expression|Type]
-argument_expression_list
- : argument_expression {result = NodeArray[val[0]]}
- | argument_expression_list COMMA argument_expression {result = val[0] << val[2]}
-
-# Returns Expression|Type -- EXTENSION: allow type names here too, to support some standard library macros (e.g., va_arg [7.15.1.1])
-argument_expression
- : assignment_expression {result = val[0]}
- | type_name {result = val[0]}
-
-# Returns Expression
-unary_expression
- : postfix_expression {result = val[0]}
- | INC unary_expression {result = PreInc.new_at(val[0].pos, val[1])}
- | DEC unary_expression {result = PreDec.new_at(val[0].pos, val[1])}
- | unary_operator cast_expression {result = val[0][0].new_at(val[0][1], val[1])}
- | SIZEOF unary_expression {result = Sizeof.new_at(val[0].pos, val[1])}
- | SIZEOF LPAREN type_name RPAREN {result = Sizeof.new_at(val[0].pos, val[2])}
-
-# Returns [Class, Pos]
-unary_operator
- : AND {result = [Address , val[0].pos]}
- | MUL {result = [Dereference, val[0].pos]}
- | ADD {result = [Positive , val[0].pos]}
- | SUB {result = [Negative , val[0].pos]}
- | NOT {result = [BitNot , val[0].pos]}
- | BANG {result = [Not , val[0].pos]}
-
-# Returns Expression
-cast_expression
- : unary_expression {result = val[0]}
- | LPAREN type_name RPAREN cast_expression {result = Cast.new_at(val[0].pos, val[1], val[3])}
-
-# Returns Expression
-multiplicative_expression
- : cast_expression {result = val[0]}
- | multiplicative_expression MUL cast_expression {result = Multiply.new_at(val[0].pos, val[0], val[2])}
- | multiplicative_expression DIV cast_expression {result = Divide .new_at(val[0].pos, val[0], val[2])}
- | multiplicative_expression MOD cast_expression {result = Mod .new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-additive_expression
- : multiplicative_expression {result = val[0]}
- | additive_expression ADD multiplicative_expression {result = Add .new_at(val[0].pos, val[0], val[2])}
- | additive_expression SUB multiplicative_expression {result = Subtract.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-shift_expression
- : additive_expression {result = val[0]}
- | shift_expression LSHIFT additive_expression {result = ShiftLeft .new_at(val[0].pos, val[0], val[2])}
- | shift_expression RSHIFT additive_expression {result = ShiftRight.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-relational_expression
- : shift_expression {result = val[0]}
- | relational_expression LT shift_expression {result = Less.new_at(val[0].pos, val[0], val[2])}
- | relational_expression GT shift_expression {result = More.new_at(val[0].pos, val[0], val[2])}
- | relational_expression LEQ shift_expression {result = LessOrEqual.new_at(val[0].pos, val[0], val[2])}
- | relational_expression GEQ shift_expression {result = MoreOrEqual.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-equality_expression
- : relational_expression {result = val[0]}
- | equality_expression EQEQ relational_expression {result = Equal .new_at(val[0].pos, val[0], val[2])}
- | equality_expression NEQ relational_expression {result = NotEqual.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-and_expression
- : equality_expression {result = val[0]}
- | and_expression AND equality_expression {result = BitAnd.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-exclusive_or_expression
- : and_expression {result = val[0]}
- | exclusive_or_expression XOR and_expression {result = BitXor.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-inclusive_or_expression
- : exclusive_or_expression {result = val[0]}
- | inclusive_or_expression OR exclusive_or_expression {result = BitOr.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-logical_and_expression
- : inclusive_or_expression {result = val[0]}
- | logical_and_expression ANDAND inclusive_or_expression {result = And.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-logical_or_expression
- : logical_and_expression {result = val[0]}
- | logical_or_expression OROR logical_and_expression {result = Or.new_at(val[0].pos, val[0], val[2])}
-
-# Returns Expression
-conditional_expression
- : logical_or_expression {result = val[0]}
- | logical_or_expression QUESTION expression COLON conditional_expression {result = Conditional.new_at(val[0].pos, val[0], val[2], val[4])}
-
-# Returns Expression
-assignment_expression
- : conditional_expression {result = val[0]}
- | unary_expression assignment_operator assignment_expression {result = val[1].new_at(val[0].pos, val[0], val[2])}
-
-# Returns Class
-assignment_operator
- : EQ {result = Assign}
- | MULEQ {result = MultiplyAssign}
- | DIVEQ {result = DivideAssign}
- | MODEQ {result = ModAssign}
- | ADDEQ {result = AddAssign}
- | SUBEQ {result = SubtractAssign}
- | LSHIFTEQ {result = ShiftLeftAssign}
- | RSHIFTEQ {result = ShiftRightAssign}
- | ANDEQ {result = BitAndAssign}
- | XOREQ {result = BitXorAssign}
- | OREQ {result = BitOrAssign}
-
-# Returns Expression
-expression
- : assignment_expression {result = val[0]}
- | expression COMMA assignment_expression {
- if val[0].is_a? Comma
- if val[2].is_a? Comma
- val[0].exprs.push(*val[2].exprs)
- else
- val[0].exprs << val[2]
- end
- result = val[0]
- else
- if val[2].is_a? Comma
- val[2].exprs.unshift(val[0])
- val[2].pos = val[0].pos
- result = val[2]
- else
- result = Comma.new_at(val[0].pos, NodeArray[val[0], val[2]])
- end
- end
- }
-
-# Returns Expression
-constant_expression
- : conditional_expression {result = val[0]}
-
-# A.1.1 -- Lexical elements
-#
-# token
-# : keyword (raw string)
-# | identifier expanded below
-# | constant expanded below
-# | string_literal expanded below
-# | punctuator (raw string)
-#
-# preprocessing-token (skip)
-
-# Returns Token
-identifier
- : ID {result = val[0]}
-
-# Returns Literal
-constant
- : ICON {result = val[0].val; result.pos = val[0].pos}
- | FCON {result = val[0].val; result.pos = val[0].pos}
- #| enumeration_constant -- these are parsed as identifiers at all
- # places the `constant' nonterminal appears
- | CCON {result = val[0].val; result.pos = val[0].pos}
-
-# Returns Token
-enumeration_constant
- : ID {result = val[0]}
-
-# Returns StringLiteral
-# Also handles string literal concatenation (6.4.5.4)
-string_literal
- : string_literal SCON {val[0].val << val[1].val.val; result = val[0]}
- | SCON { result = val[0].val; result.pos = val[0].pos }
-
----- inner
- # A.1.9 -- Preprocessing numbers -- skip
- # A.1.8 -- Header names -- skip
-
- # A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since
- # we don't do preprocessing
- @@punctuators = %r'\+\+|-[->]|&&|\|\||\.\.\.|(?:<<|>>|[<>=!*/%+\-&^|])=?|[\[\](){}.~?:;,]'
- @@digraphs = %r'<[:%]|[:%]>'
-
- # A.1.6 -- String Literals -- simple for us because we don't decode
- # the string (and indeed accept some illegal strings)
- @@string_literal = %r'L?"(?:[^\\]|\\.)*?"'m
-
- # A.1.5 -- Constants
- @@decimal_floating_constant = %r'(?:(?:\d*\.\d+|\d+\.)(?:e[-+]?\d+)?|\d+e[-+]?\d+)[fl]?'i
- @@hexadecimal_floating_constant = %r'0x(?:(?:[0-9a-f]*\.[0-9a-f]+|[0-9a-f]+\.)|[0-9a-f]+)p[-+]?\d+[fl]?'i
-
- @@integer_constant = %r'(?:[1-9][0-9]*|0x[0-9a-f]+|0[0-7]*)(?:ul?l?|ll?u?)?'i
- @@floating_constant = %r'#{@@decimal_floating_constant}|#{@@hexadecimal_floating_constant}'
- @@enumeration_constant = %r'[a-zA-Z_\\][a-zA-Z_\\0-9]*'
- @@character_constant = %r"L?'(?:[^\\]|\\.)+?'"
- # (note that as with string-literals, we accept some illegal
- # character-constants)
-
- # A.1.4 -- Universal character names -- skip
-
- # A.1.3 -- Identifiers -- skip, since an identifier is lexically
- # identical to an enumeration constant
-
- # A.1.2 Keywords
- keywords = %w'auto break case char const continue default do
-double else enum extern float for goto if inline int long register
-restrict return short signed sizeof static struct switch typedef union
- unsigned void volatile while _Bool _Complex _Imaginary'
- @@keywords = %r"#{keywords.join('|')}"
-
- def initialize
- @type_names = ::Set.new
-
- @warning_proc = lambda{}
- @pos = C::Node::Pos.new(nil, 1, 0)
- end
- def initialize_copy(x)
- @pos = x.pos.dup
- @type_names = x.type_names.dup
- end
- attr_accessor :pos, :type_names
-
- def parse(str)
- if str.respond_to? :read
- str = str.read
- end
- @str = str
- begin
- prepare_lexer(str)
- return do_parse
- rescue ParseError => e
- e.set_backtrace(caller)
- raise
- end
- end
-
- #
- # Error handler, as used by racc.
- #
- def on_error(error_token_id, error_value, value_stack)
- if error_value == '$'
- parse_error @pos, "unexpected EOF"
- else
- parse_error(error_value.pos,
- "parse error on #{token_to_str(error_token_id)} (#{error_value.val})")
- end
- end
-
- def self.feature(name)
- attr_writer "#{name}_enabled"
- class_eval <<-EOS
- def enable_#{name}
- @#{name}_enabled = true
- end
- def #{name}_enabled?
- @#{name}_enabled
- end
- EOS
- end
- private_class_method :feature
-
- #
- # Allow blocks in parentheses as expressions, as per the gcc
- # extension. [http://rubyurl.com/iB7]
- #
- feature :block_expressions
-
- private # ---------------------------------------------------------
-
- class Token
- attr_accessor :pos, :val
- def initialize(pos, val)
- @pos = pos
- @val = val
- end
- end
- def eat(str)
- lines = str.split(/\r\n|[\r\n]/, -1)
- if lines.length == 1
- @pos.col_num += lines[0].length
- else
- @pos.line_num += lines.length - 1
- @pos.col_num = lines[-1].length
- end
- end
-
- #
- # Make a Declaration from the given specs and declarators.
- #
- def make_declaration(pos, specs, declarators)
- specs.all?{|x| x.is_a?(Symbol) || x.is_a?(Type)} or raise specs.map{|x| x.class}.inspect
- decl = Declaration.new_at(pos, nil, declarators)
-
- # set storage class
- storage_classes = specs.find_all do |x|
- [:typedef, :extern, :static, :auto, :register].include? x
- end
- # 6.7.1p2: at most, one storage-class specifier may be given in
- # the declaration specifiers in a declaration
- storage_classes.length <= 1 or
- begin
- if declarators.length == 0
- for_name = ''
- else
- for_name = "for `#{declarators[0].name}'"
- end
- parse_error pos, "multiple or duplicate storage classes given #{for_name}'"
- end
- decl.storage = storage_classes[0]
-
- # set type (specifiers, qualifiers)
- decl.type = make_direct_type(pos, specs)
-
- # set function specifiers
- decl.inline = specs.include?(:inline)
-
- # look for new type names
- if decl.typedef?
- decl.declarators.each do |d|
- if d.name
- @type_names << d.name
- end
- end
- end
-
- return decl
- end
-
- def make_function_def(pos, specs, func_declarator, decl_list, defn)
- add_decl_type(func_declarator, make_direct_type(pos, specs))
-
- # get types from decl_list if necessary
- function = func_declarator.indirect_type
- function.is_a? Function or
- parse_error pos, "non function type for function `#{func_declarator.name}'"
- params = function.params
- if decl_list
- params.all?{|p| p.type.nil?} or
- parse_error pos, "both prototype and declaration list given for `#{func_declarator.name}'"
- decl_list.each do |declaration|
- declaration.declarators.each do |declarator|
- param = params.find{|p| p.name == declarator.name} or
- parse_error pos, "no parameter named #{declarator.name}"
- if declarator.indirect_type
- param.type = declarator.indirect_type
- param.type.direct_type = declaration.type.dup
- else
- param.type = declaration.type.dup
- end
- end
- end
- params.all?{|p| p.type} or
- begin
- s = params.find_all{|p| p.type.nil?}.map{|p| "`#{p.name}'"}.join(' and ')
- parse_error pos, "types missing for parameters #{s}"
- end
- end
-
- fd = FunctionDef.new_at(pos,
- function.detach,
- func_declarator.name,
- defn,
- :no_prototype => !decl_list.nil?)
-
- # set storage class
- # 6.9.1p4: only extern or static allowed
- specs.each do |s|
- [:typedef, :auto, :register].include?(s) and
- "`#{s}' illegal for function"
- end
- storage_classes = specs.find_all do |s|
- s == :extern || s == :static
- end
- # 6.7.1p2: at most, one storage-class specifier may be given in
- # the declaration specifiers in a declaration
- storage_classes.length <= 1 or
- "multiple or duplicate storage classes given for `#{func_declarator.name}'"
- fd.storage = storage_classes[0] if storage_classes[0]
-
- # set function specifiers
- # 6.7.4p5 'inline' can be repeated
- fd.inline = specs.include?(:inline)
-
- return fd
- end
-
- #
- # Make a direct type from the list of type specifiers and type
- # qualifiers.
- #
- def make_direct_type(pos, specs)
- specs_order = [:signed, :unsigned, :short, :long, :double, :void,
- :char, :int, :float, :_Bool, :_Complex, :_Imaginary]
-
- type_specs = specs.find_all do |x|
- specs_order.include?(x) || !x.is_a?(Symbol)
- end
- type_specs.sort! do |a, b|
- (specs_order.index(a)||100) <=> (specs_order.index(b)||100)
- end
-
- # set type specifiers
- # 6.7.2p2: the specifier list should be one of these
- type =
- case type_specs
- when [:void]
- Void.new
- when [:char]
- Char.new
- when [:signed, :char]
- Char.new :signed => true
- when [:unsigned, :char]
- Char.new :signed => false
- when [:short], [:signed, :short], [:short, :int],
- [:signed, :short, :int]
- Int.new :longness => -1
- when [:unsigned, :short], [:unsigned, :short, :int]
- Int.new :unsigned => true, :longness => -1
- when [:int], [:signed], [:signed, :int]
- Int.new
- when [:unsigned], [:unsigned, :int]
- Int.new :unsigned => true
- when [:long], [:signed, :long], [:long, :int],
- [:signed, :long, :int]
- Int.new :longness => 1
- when [:unsigned, :long], [:unsigned, :long, :int]
- Int.new :longness => 1, :unsigned => true
- when [:long, :long], [:signed, :long, :long],
- [:long, :long, :int], [:signed, :long, :long, :int]
- Int.new :longness => 2
- when [:unsigned, :long, :long], [:unsigned, :long, :long, :int]
- Int.new :longness => 2, :unsigned => true
- when [:float]
- Float.new
- when [:double]
- Float.new :longness => 1
- when [:long, :double]
- Float.new :longness => 2
- when [:_Bool]
- Bool.new
- when [:float, :_Complex]
- Complex.new
- when [:double, :_Complex]
- Complex.new :longness => 1
- when [:long, :double, :_Complex]
- Complex.new :longness => 2
- when [:float, :_Imaginary]
- Imaginary.new
- when [:double, :_Imaginary]
- Imaginary.new :longness => 1
- when [:long, :double, :_Imaginary]
- Imaginary.new :longness => 2
- else
- if type_specs.length == 1 &&
- [CustomType, Struct, Union, Enum].any?{|c| type_specs[0].is_a? c}
- type_specs[0]
- else
- if type_specs == []
- parse_error pos, "no type specifiers given"
- else
- parse_error pos, "invalid type specifier combination: #{type_specs.join(' ')}"
- end
- end
- end
- type.pos ||= pos
-
- # set type qualifiers
- # 6.7.3p4: type qualifiers can be repeated
- type.const = specs.any?{|x| x.equal? :const }
- type.restrict = specs.any?{|x| x.equal? :restrict}
- type.volatile = specs.any?{|x| x.equal? :volatile}
-
- return type
- end
-
- def make_parameter(pos, specs, indirect_type, name)
- type = indirect_type
- if type
- type.direct_type = make_direct_type(pos, specs)
- else
- type = make_direct_type(pos, specs)
- end
- [:typedef, :extern, :static, :auto, :inline].each do |sym|
- specs.include? sym and
- parse_error pos, "parameter `#{declarator.name}' declared `#{sym}'"
- end
- return Parameter.new_at(pos, type, name,
- :register => specs.include?(:register))
- end
-
- def add_type_quals(type, quals)
- type.const = quals.include?(:const )
- type.restrict = quals.include?(:restrict)
- type.volatile = quals.include?(:volatile)
- return type
- end
-
- #
- # Add te given type as the "most direct" type to the given
- # declarator. Return the declarator.
- #
- def add_decl_type(declarator, type)
- if declarator.indirect_type
- declarator.indirect_type.direct_type = type
- else
- declarator.indirect_type = type
- end
- return declarator
- end
-
- def param_list(params, var_args)
- if params.length == 1 &&
- params[0].type.is_a?(Void) &&
- params[0].name.nil?
- return NodeArray[]
- elsif params.empty?
- return nil
- else
- return params
- end
- end
-
- def parse_error(pos, str)
- raise ParseError, "#{pos}: #{str}"
- end
-
----- header
-
-require 'set'
-
-# Error classes
-module C
- class ParseError < StandardError; end
-end
-
-# Local variables:
-# mode: ruby
-# end:
diff --git a/test/racc/assets/chk.y b/test/racc/assets/chk.y
deleted file mode 100644
index 7e0ee20f1e..0000000000
--- a/test/racc/assets/chk.y
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# racc tester
-#
-
-class Calcp
-
- prechigh
- left '*' '/'
- left '+' '-'
- preclow
-
- convert
- NUMBER 'Number'
- end
-
-rule
-
- target : exp | /* none */ { result = 0 } ;
-
- exp : exp '+' exp { result += val[2]; @plus = 'plus' }
- | exp '-' exp { result -= val[2]; @str = "string test" }
- | exp '*' exp { result *= val[2] }
- | exp '/' exp { result /= val[2] }
- | '(' { $emb = true } exp ')'
- {
- raise 'must not happen' unless $emb
- result = val[2]
- }
- | '-' NUMBER { result = -val[1] }
- | NUMBER
- ;
-
-end
-
-----header
-
-class Number; end
-
-----inner
-
- def parse( src )
- $emb = false
- @plus = nil
- @str = nil
- @src = src
- result = do_parse
- if @plus
- raise 'string parse failed' unless @plus == 'plus'
- end
- if @str
- raise 'string parse failed' unless @str == 'string test'
- end
- result
- end
-
- def next_token
- @src.shift
- end
-
- def initialize
- @yydebug = true
- end
-
-----footer
-
-$parser = Calcp.new
-$test_number = 1
-
-def chk( src, ans )
- result = $parser.parse(src)
- raise "test #{$test_number} fail" unless result == ans
- $test_number += 1
-end
-
-chk(
- [ [Number, 9],
- [false, false],
- [false, false] ], 9
-)
-
-chk(
- [ [Number, 5],
- ['*', nil],
- [Number, 1],
- ['-', nil],
- [Number, 1],
- ['*', nil],
- [Number, 8],
- [false, false],
- [false, false] ], -3
-)
-
-chk(
- [ [Number, 5],
- ['+', nil],
- [Number, 2],
- ['-', nil],
- [Number, 5],
- ['+', nil],
- [Number, 2],
- ['-', nil],
- [Number, 5],
- [false, false],
- [false, false] ], -1
-)
-
-chk(
- [ ['-', nil],
- [Number, 4],
- [false, false],
- [false, false] ], -4
-)
-
-chk(
- [ [Number, 7],
- ['*', nil],
- ['(', nil],
- [Number, 4],
- ['+', nil],
- [Number, 3],
- [')', nil],
- ['-', nil],
- [Number, 9],
- [false, false],
- [false, false] ], 40
-)
diff --git a/test/racc/assets/conf.y b/test/racc/assets/conf.y
deleted file mode 100644
index de9de71d28..0000000000
--- a/test/racc/assets/conf.y
+++ /dev/null
@@ -1,16 +0,0 @@
-
-class A
-rule
-
-a: A c C expr;
-
-b: A B; # useless
-
-c: A;
-c: A;
-
-expr: expr '+' expr
-expr: expr '-' expr
-expr: NUMBER
-
-end
diff --git a/test/racc/assets/csspool.y b/test/racc/assets/csspool.y
deleted file mode 100644
index 3d6af25d85..0000000000
--- a/test/racc/assets/csspool.y
+++ /dev/null
@@ -1,729 +0,0 @@
-class CSSPool::CSS::Parser
-
-token CHARSET_SYM IMPORT_SYM STRING SEMI IDENT S COMMA LBRACE RBRACE STAR HASH
-token LSQUARE RSQUARE EQUAL INCLUDES DASHMATCH LPAREN RPAREN FUNCTION GREATER PLUS
-token SLASH NUMBER MINUS LENGTH PERCENTAGE ANGLE TIME FREQ URI
-token IMPORTANT_SYM MEDIA_SYM NOT ONLY AND NTH_PSEUDO_CLASS
-token DOCUMENT_QUERY_SYM FUNCTION_NO_QUOTE
-token TILDE
-token PREFIXMATCH SUFFIXMATCH SUBSTRINGMATCH
-token NOT_PSEUDO_CLASS
-token KEYFRAMES_SYM
-token MATCHES_PSEUDO_CLASS
-token NAMESPACE_SYM
-token MOZ_PSEUDO_ELEMENT
-token RESOLUTION
-token COLON
-token SUPPORTS_SYM
-token OR
-token VARIABLE_NAME
-token CALC_SYM
-token FONTFACE_SYM
-token UNICODE_RANGE
-token RATIO
-
-rule
- document
- : { @handler.start_document }
- stylesheet
- { @handler.end_document }
- ;
- stylesheet
- : charset stylesheet
- | import stylesheet
- | namespace stylesheet
- | charset
- | import
- | namespace
- | body
- |
- ;
- charset
- : CHARSET_SYM STRING SEMI { @handler.charset interpret_string(val[1]), {} }
- ;
- import
- : IMPORT_SYM import_location medium SEMI {
- @handler.import_style val[2], val[1]
- }
- | IMPORT_SYM import_location SEMI {
- @handler.import_style [], val[1]
- }
- ;
- import_location
- : import_location S
- | STRING { result = Terms::String.new interpret_string val.first }
- | URI { result = Terms::URI.new interpret_uri val.first }
- ;
- namespace
- : NAMESPACE_SYM ident import_location SEMI {
- @handler.namespace val[1], val[2]
- }
- | NAMESPACE_SYM import_location SEMI {
- @handler.namespace nil, val[1]
- }
- ;
- medium
- : medium COMMA IDENT {
- result = val[0] << MediaType.new(val[2])
- }
- | IDENT {
- result = [MediaType.new(val[0])]
- }
- ;
- media_query_list
- : media_query { result = MediaQueryList.new([ val[0] ]) }
- | media_query_list COMMA media_query { result = val[0] << val[2] }
- | { result = MediaQueryList.new }
- ;
- media_query
- : optional_only_or_not media_type optional_and_exprs { result = MediaQuery.new(val[0], val[1], val[2]) }
- | media_expr optional_and_exprs { result = MediaQuery.new(nil, val[0], val[1]) }
- ;
- optional_only_or_not
- : ONLY { result = :only }
- | NOT { result = :not }
- | { result = nil }
- ;
- media_type
- : IDENT { result = MediaType.new(val[0]) }
- ;
- media_expr
- : LPAREN optional_space IDENT optional_space RPAREN { result = MediaType.new(val[2]) }
- | LPAREN optional_space IDENT optional_space COLON optional_space expr RPAREN { result = MediaFeature.new(val[2], val[6][0]) }
- ;
- optional_space
- : S { result = val[0] }
- | { result = nil }
- ;
- optional_and_exprs
- : optional_and_exprs AND media_expr { result = val[0] << val[2] }
- | { result = [] }
- ;
- resolution
- : RESOLUTION {
- unit = val.first.gsub(/[\s\d.]/, '')
- number = numeric(val.first)
- result = Terms::Resolution.new(number, unit)
- }
- ;
- body
- : ruleset body
- | conditional_rule body
- | keyframes_rule body
- | fontface_rule body
- | ruleset
- | conditional_rule
- | keyframes_rule
- | fontface_rule
- ;
- conditional_rule
- : media
- | document_query
- | supports
- ;
- body_in_media
- : body
- | empty_ruleset
- ;
- media
- : start_media body_in_media RBRACE { @handler.end_media val.first }
- ;
- start_media
- : MEDIA_SYM media_query_list LBRACE {
- result = val[1]
- @handler.start_media result
- }
- ;
- document_query
- : start_document_query body RBRACE { @handler.end_document_query(before_pos(val), after_pos(val)) }
- | start_document_query RBRACE { @handler.end_document_query(before_pos(val), after_pos(val)) }
- ;
- start_document_query
- : start_document_query_pos url_match_fns LBRACE {
- @handler.start_document_query(val[1], after_pos(val))
- }
- ;
- start_document_query_pos
- : DOCUMENT_QUERY_SYM {
- @handler.node_start_pos = before_pos(val)
- }
- ;
- url_match_fns
- : url_match_fn COMMA url_match_fns {
- result = [val[0], val[2]].flatten
- }
- | url_match_fn {
- result = val
- }
- ;
- url_match_fn
- : function_no_quote
- | function
- | uri
- ;
- supports
- : start_supports body RBRACE { @handler.end_supports }
- | start_supports RBRACE { @handler.end_supports }
- ;
- start_supports
- : SUPPORTS_SYM supports_condition_root LBRACE {
- @handler.start_supports val[1]
- }
- ;
- supports_condition_root
- : supports_negation { result = val.join('') }
- | supports_conjunction_or_disjunction { result = val.join('') }
- | supports_condition_in_parens { result = val.join('') }
- ;
- supports_condition
- : supports_negation { result = val.join('') }
- | supports_conjunction_or_disjunction { result = val.join('') }
- | supports_condition_in_parens { result = val.join('') }
- ;
- supports_condition_in_parens
- : LPAREN supports_condition RPAREN { result = val.join('') }
- | supports_declaration_condition { result = val.join('') }
- ;
- supports_negation
- : NOT supports_condition_in_parens { result = val.join('') }
- ;
- supports_conjunction_or_disjunction
- : supports_conjunction
- | supports_disjunction
- ;
- supports_conjunction
- : supports_condition_in_parens AND supports_condition_in_parens { result = val.join('') }
- | supports_conjunction_or_disjunction AND supports_condition_in_parens { result = val.join('') }
- ;
- supports_disjunction
- : supports_condition_in_parens OR supports_condition_in_parens { result = val.join('') }
- | supports_conjunction_or_disjunction OR supports_condition_in_parens { result = val.join('') }
- ;
- supports_declaration_condition
- : LPAREN declaration_internal RPAREN { result = val.join('') }
- | LPAREN S declaration_internal RPAREN { result = val.join('') }
- ;
- keyframes_rule
- : start_keyframes_rule keyframes_blocks RBRACE
- | start_keyframes_rule RBRACE
- ;
- start_keyframes_rule
- : KEYFRAMES_SYM IDENT LBRACE {
- @handler.start_keyframes_rule val[1]
- }
- ;
- keyframes_blocks
- : keyframes_block keyframes_blocks
- | keyframes_block
- ;
- keyframes_block
- : start_keyframes_block declarations RBRACE { @handler.end_keyframes_block }
- | start_keyframes_block RBRACE { @handler.end_keyframes_block }
- ;
- start_keyframes_block
- : keyframes_selectors LBRACE {
- @handler.start_keyframes_block val[0]
- }
- ;
- keyframes_selectors
- | keyframes_selector COMMA keyframes_selectors {
- result = val[0] + ', ' + val[2]
- }
- | keyframes_selector
- ;
- keyframes_selector
- : IDENT
- | PERCENTAGE { result = val[0].strip }
- ;
- fontface_rule
- : start_fontface_rule declarations RBRACE { @handler.end_fontface_rule }
- | start_fontface_rule RBRACE { @handler.end_fontface_rule }
- ;
- start_fontface_rule
- : FONTFACE_SYM LBRACE {
- @handler.start_fontface_rule
- }
- ;
- ruleset
- : start_selector declarations RBRACE {
- @handler.end_selector val.first
- }
- | start_selector RBRACE {
- @handler.end_selector val.first
- }
- ;
- empty_ruleset
- : optional_space {
- start = @handler.start_selector([])
- @handler.end_selector(start)
- }
- ;
- start_selector
- : S start_selector { result = val.last }
- | selectors LBRACE {
- @handler.start_selector val.first
- }
- ;
- selectors
- : selector COMMA selectors
- {
- sel = Selector.new(val.first, {})
- result = [sel].concat(val[2])
- }
- | selector
- {
- result = [Selector.new(val.first, {})]
- }
- ;
- selector
- : simple_selector combinator selector
- {
- val.flatten!
- val[2].combinator = val.delete_at 1
- result = val
- }
- | simple_selector
- ;
- combinator
- : S { result = :s }
- | GREATER { result = :> }
- | PLUS { result = :+ }
- | TILDE { result = :~ }
- ;
- simple_selector
- : element_name hcap {
- selector = val.first
- selector.additional_selectors = val.last
- result = [selector]
- }
- | element_name { result = val }
- | hcap
- {
- ss = Selectors::Simple.new nil, nil
- ss.additional_selectors = val.flatten
- result = [ss]
- }
- ;
- simple_selectors
- : simple_selector COMMA simple_selectors { result = [val[0], val[2]].flatten }
- | simple_selector
- ;
- ident_with_namespace
- : IDENT { result = [interpret_identifier(val[0]), nil] }
- | IDENT '|' IDENT { result = [interpret_identifier(val[2]), interpret_identifier(val[0])] }
- | '|' IDENT { result = [interpret_identifier(val[1]), nil] }
- | STAR '|' IDENT { result = [interpret_identifier(val[2]), '*'] }
- ;
- element_name
- : ident_with_namespace { result = Selectors::Type.new val.first[0], nil, val.first[1] }
- | STAR { result = Selectors::Universal.new val.first }
- | '|' STAR { result = Selectors::Universal.new val[1] }
- | STAR '|' STAR { result = Selectors::Universal.new val[2], nil, val[0] }
- | IDENT '|' STAR { result = Selectors::Universal.new val[2], nil, interpret_identifier(val[0]) }
- ;
- hcap
- : hash { result = val }
- | class { result = val }
- | attrib { result = val }
- | pseudo { result = val }
- | hash hcap { result = val.flatten }
- | class hcap { result = val.flatten }
- | attrib hcap { result = val.flatten }
- | pseudo hcap { result = val.flatten }
- ;
- hash
- : HASH {
- result = Selectors::Id.new interpret_identifier val.first.sub(/^#/, '')
- }
- class
- : '.' IDENT {
- result = Selectors::Class.new interpret_identifier val.last
- }
- ;
- attrib
- : LSQUARE ident_with_namespace EQUAL IDENT RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::EQUALS,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace EQUAL STRING RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::EQUALS,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace INCLUDES STRING RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::INCLUDES,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace INCLUDES IDENT RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::INCLUDES,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace DASHMATCH IDENT RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::DASHMATCH,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace DASHMATCH STRING RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::DASHMATCH,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace PREFIXMATCH IDENT RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::PREFIXMATCH,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace PREFIXMATCH STRING RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::PREFIXMATCH,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace SUFFIXMATCH IDENT RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::SUFFIXMATCH,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace SUFFIXMATCH STRING RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::SUFFIXMATCH,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace SUBSTRINGMATCH IDENT RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::SUBSTRINGMATCH,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace SUBSTRINGMATCH STRING RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::SUBSTRINGMATCH,
- val[1][1]
- )
- }
- | LSQUARE ident_with_namespace RSQUARE {
- result = Selectors::Attribute.new(
- val[1][0],
- nil,
- Selectors::Attribute::SET,
- val[1][1]
- )
- }
- ;
- pseudo
- : COLON IDENT {
- result = Selectors::pseudo interpret_identifier(val[1])
- }
- | COLON COLON IDENT {
- result = Selectors::PseudoElement.new(
- interpret_identifier(val[2])
- )
- }
- | COLON FUNCTION RPAREN {
- result = Selectors::PseudoClass.new(
- interpret_identifier(val[1].sub(/\($/, '')),
- ''
- )
- }
- | COLON FUNCTION IDENT RPAREN {
- result = Selectors::PseudoClass.new(
- interpret_identifier(val[1].sub(/\($/, '')),
- interpret_identifier(val[2])
- )
- }
- | COLON NOT_PSEUDO_CLASS simple_selector RPAREN {
- result = Selectors::PseudoClass.new(
- 'not',
- val[2].first.to_s
- )
- }
- | COLON NTH_PSEUDO_CLASS {
- result = Selectors::PseudoClass.new(
- interpret_identifier(val[1].sub(/\(.*/, '')),
- interpret_identifier(val[1].sub(/.*\(/, '').sub(/\).*/, ''))
- )
- }
- | COLON MATCHES_PSEUDO_CLASS simple_selectors RPAREN {
- result = Selectors::PseudoClass.new(
- val[1].split('(').first.strip,
- val[2].join(', ')
- )
- }
- | COLON MOZ_PSEUDO_ELEMENT optional_space any_number_of_idents optional_space RPAREN {
- result = Selectors::PseudoElement.new(
- interpret_identifier(val[1].sub(/\($/, ''))
- )
- }
- | COLON COLON MOZ_PSEUDO_ELEMENT optional_space any_number_of_idents optional_space RPAREN {
- result = Selectors::PseudoElement.new(
- interpret_identifier(val[2].sub(/\($/, ''))
- )
- }
- ;
- any_number_of_idents
- :
- | multiple_idents
- ;
- multiple_idents
- : IDENT
- | IDENT COMMA multiple_idents
- ;
- # declarations can be separated by one *or more* semicolons. semi-colons at the start or end of a ruleset are also allowed
- one_or_more_semis
- : SEMI
- | SEMI one_or_more_semis
- ;
- declarations
- : declaration one_or_more_semis declarations
- | one_or_more_semis declarations
- | declaration one_or_more_semis
- | declaration
- | one_or_more_semis
- ;
- declaration
- : declaration_internal { @handler.property val.first }
- ;
- declaration_internal
- : property COLON expr prio
- { result = Declaration.new(val.first, val[2], val[3]) }
- | property COLON S expr prio
- { result = Declaration.new(val.first, val[3], val[4]) }
- | property S COLON expr prio
- { result = Declaration.new(val.first, val[3], val[4]) }
- | property S COLON S expr prio
- { result = Declaration.new(val.first, val[4], val[5]) }
- ;
- prio
- : IMPORTANT_SYM { result = true }
- | { result = false }
- ;
- property
- : IDENT { result = interpret_identifier val[0] }
- | STAR IDENT { result = interpret_identifier val.join }
- | VARIABLE_NAME { result = interpret_identifier val[0] }
- ;
- operator
- : COMMA
- | SLASH
- | EQUAL
- ;
- expr
- : term operator expr {
- result = [val.first, val.last].flatten
- val.last.first.operator = val[1]
- }
- | term expr { result = val.flatten }
- | term { result = val }
- ;
- term
- : ident
- | ratio
- | numeric
- | string
- | uri
- | hexcolor
- | calc
- | function
- | resolution
- | VARIABLE_NAME
- | uranges
- ;
- function
- : function S { result = val.first }
- | FUNCTION expr RPAREN {
- name = interpret_identifier val.first.sub(/\($/, '')
- if name == 'rgb'
- result = Terms::Rgb.new(*val[1])
- else
- result = Terms::Function.new name, val[1]
- end
- }
- | FUNCTION RPAREN {
- name = interpret_identifier val.first.sub(/\($/, '')
- result = Terms::Function.new name
- }
- ;
- function_no_quote
- : function_no_quote S { result = val.first }
- | FUNCTION_NO_QUOTE {
- parts = val.first.split('(')
- name = interpret_identifier parts.first
- result = Terms::Function.new(name, [Terms::String.new(interpret_string_no_quote(parts.last))])
- }
- ;
- uranges
- : UNICODE_RANGE COMMA uranges
- | UNICODE_RANGE
- ;
- calc
- : CALC_SYM calc_sum RPAREN optional_space {
- result = Terms::Math.new(val.first.split('(').first, val[1])
- }
- ;
- # plus and minus are supposed to have whitespace around them, per http://dev.w3.org/csswg/css-values/#calc-syntax, but the numbers are eating trailing whitespace, so we inject it back in
- calc_sum
- : calc_product
- | calc_product PLUS calc_sum { val.insert(1, ' '); result = val.join('') }
- | calc_product MINUS calc_sum { val.insert(1, ' '); result = val.join('') }
- ;
- calc_product
- : calc_value
- | calc_value optional_space STAR calc_value { result = val.join('') }
- | calc_value optional_space SLASH calc_value { result = val.join('') }
- ;
- calc_value
- : numeric { result = val.join('') }
- | function { result = val.join('') } # for var() variable references
- | LPAREN calc_sum RPAREN { result = val.join('') }
- ;
- hexcolor
- : hexcolor S { result = val.first }
- | HASH { result = Terms::Hash.new val.first.sub(/^#/, '') }
- ;
- uri
- : uri S { result = val.first }
- | URI { result = Terms::URI.new interpret_uri val.first }
- ;
- string
- : string S { result = val.first }
- | STRING { result = Terms::String.new interpret_string val.first }
- ;
- numeric
- : unary_operator numeric {
- result = val[1]
- val[1].unary_operator = val.first
- }
- | NUMBER {
- result = Terms::Number.new numeric val.first
- }
- | PERCENTAGE {
- result = Terms::Number.new numeric(val.first), nil, '%'
- }
- | LENGTH {
- unit = val.first.gsub(/[\s\d.]/, '')
- result = Terms::Number.new numeric(val.first), nil, unit
- }
- | ANGLE {
- unit = val.first.gsub(/[\s\d.]/, '')
- result = Terms::Number.new numeric(val.first), nil, unit
- }
- | TIME {
- unit = val.first.gsub(/[\s\d.]/, '')
- result = Terms::Number.new numeric(val.first), nil, unit
- }
- | FREQ {
- unit = val.first.gsub(/[\s\d.]/, '')
- result = Terms::Number.new numeric(val.first), nil, unit
- }
- ;
- ratio
- : RATIO {
- result = Terms::Ratio.new(val[0], val[1])
- }
- ;
- unary_operator
- : MINUS { result = :minus }
- | PLUS { result = :plus }
- ;
- ident
- : ident S { result = val.first }
- | IDENT { result = Terms::Ident.new interpret_identifier val.first }
- ;
-
----- inner
-
-def numeric thing
- thing = thing.gsub(/[^\d.]/, '')
- Integer(thing) rescue Float(thing)
-end
-
-def interpret_identifier s
- interpret_escapes s
-end
-
-def interpret_uri s
- interpret_escapes s.match(/^url\((.*)\)$/mui)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
-end
-
-def interpret_string_no_quote s
- interpret_escapes s.match(/^(.*)\)$/mu)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
-end
-
-def interpret_string s
- interpret_escapes s.match(/^(['"])((?:\\.|.)*)\1$/mu)[2]
-end
-
-def interpret_escapes s
- token_exp = /\\(?:([0-9a-fA-F]{1,6}(?:\r\n|\s)?)|(.))/mu
- return s.gsub(token_exp) do |escape_sequence|
- if !$1.nil?
- code = $1.chomp.to_i 16
- code = 0xFFFD if code > 0x10FFFF
- next [code].pack('U')
- end
- next '' if $2 == "\n"
- next $2
- end
-end
-
-# override racc's on_error so we can have context in our error messages
-def on_error(t, val, vstack)
- errcontext = (@ss.pre_match[-10..-1] || @ss.pre_match) +
- @ss.matched + @ss.post_match[0..9]
- line_number = @ss.pre_match.lines.count
- raise ParseError, sprintf("parse error on value %s (%s) " +
- "on line %s around \"%s\"",
- val.inspect, token_to_str(t) || '?',
- line_number, errcontext)
-end
-
-def before_pos(val)
- # don't include leading whitespace
- return current_pos - val.last.length + val.last[/\A\s*/].size
-end
-
-def after_pos(val)
- # don't include trailing whitespace
- return current_pos - val.last[/\s*\z/].size
-end
-
-# charpos will work with multibyte strings but is not available until ruby 2
-def current_pos
- @ss.respond_to?('charpos') ? @ss.charpos : @ss.pos
-end
diff --git a/test/racc/assets/digraph.y b/test/racc/assets/digraph.y
deleted file mode 100644
index 17a034ee54..0000000000
--- a/test/racc/assets/digraph.y
+++ /dev/null
@@ -1,29 +0,0 @@
-# ? detect digraph bug
-
-class P
- token A B C D
-rule
- target : a b c d
- a : A
- |
- b : B
- |
- c : C
- |
- d : D
- |
-end
-
----- inner
-
- def parse
- do_parse
- end
-
- def next_token
- [false, '$']
- end
-
----- footer
-
-P.new.parse
diff --git a/test/racc/assets/echk.y b/test/racc/assets/echk.y
deleted file mode 100644
index 0fda2685aa..0000000000
--- a/test/racc/assets/echk.y
+++ /dev/null
@@ -1,118 +0,0 @@
-#
-# racc tester
-#
-
-class Calcp
-
- prechigh
- left '*' '/'
- left '+' '-'
- preclow
-
- convert
- NUMBER 'Number'
- end
-
-rule
-
- target : exp | /* none */ { result = 0 } ;
-
- exp : exp '+' exp { result += val[2]; a = 'plus' }
- | exp '-' exp { result -= val[2]; "string test" }
- | exp '*' exp { result *= val[2] }
- | exp '/' exp { result /= val[2] }
- | '(' { $emb = true } exp ')'
- {
- raise 'must not happen' unless $emb
- result = val[2]
- }
- | '-' NUMBER { result = -val[1] }
- | NUMBER
- ;
-
-end
-
-----header
-
-class Number ; end
-
-----inner
-
- def parse( src )
- @src = src
- do_parse
- end
-
- def next_token
- @src.shift
- end
-
- def initialize
- @yydebug = true
- end
-
-----footer
-
-$parser = Calcp.new
-$tidx = 1
-
-def chk( src, ans )
- ret = $parser.parse( src )
- unless ret == ans then
- bug! "test #{$tidx} fail"
- end
- $tidx += 1
-end
-
-chk(
- [ [Number, 9],
- [false, false],
- [false, false] ], 9
-)
-
-chk(
- [ [Number, 5],
- ['*', nil],
- [Number, 1],
- ['-', nil],
- [Number, 1],
- ['*', nil],
- [Number, 8],
- [false, false],
- [false, false] ], -3
-)
-
-chk(
- [ [Number, 5],
- ['+', nil],
- [Number, 2],
- ['-', nil],
- [Number, 5],
- ['+', nil],
- [Number, 2],
- ['-', nil],
- [Number, 5],
- [false, false],
- [false, false] ], -1
-)
-
-chk(
- [ ['-', nil],
- [Number, 4],
- [false, false],
- [false, false] ], -4
-)
-
-chk(
- [ [Number, 7],
- ['*', nil],
- ['(', nil],
- [Number, 4],
- ['+', nil],
- [Number, 3],
- [')', nil],
- ['-', nil],
- [Number, 9],
- [false, false],
- [false, false] ], 40
-)
diff --git a/test/racc/assets/edtf.y b/test/racc/assets/edtf.y
deleted file mode 100644
index 4f5f6bb4fd..0000000000
--- a/test/racc/assets/edtf.y
+++ /dev/null
@@ -1,583 +0,0 @@
-# -*- racc -*-
-
-# Copyright 2011 Sylvester Keil. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-# EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# The views and conclusions contained in the software and documentation are
-# those of the authors and should not be interpreted as representing official
-# policies, either expressed or implied, of the copyright holder.
-
-class EDTF::Parser
-
-token T Z E X U UNKNOWN OPEN LONGYEAR UNMATCHED DOTS UA PUA
-
-expect 0
-
-rule
-
- edtf : level_0_expression
- | level_1_expression
- | level_2_expression
- ;
-
- # ---- Level 0 / ISO 8601 Rules ----
-
- # NB: level 0 intervals are covered by the level 1 interval rules
- level_0_expression : date
- | date_time
- ;
-
- date : positive_date
- | negative_date
- ;
-
- positive_date :
- year { result = Date.new(val[0]).year_precision! }
- | year_month { result = Date.new(*val.flatten).month_precision! }
- | year_month_day { result = Date.new(*val.flatten).day_precision! }
- ;
-
- negative_date : '-' positive_date { result = -val[1] }
-
-
- date_time : date T time {
- result = DateTime.new(val[0].year, val[0].month, val[0].day, *val[2])
- result.skip_timezone = (val[2].length == 3)
- }
-
- time : base_time
- | base_time zone_offset { result = val.flatten }
-
- base_time : hour ':' minute ':' second { result = val.values_at(0, 2, 4) }
- | midnight
-
- midnight : '2' '4' ':' '0' '0' ':' '0' '0' { result = [24, 0, 0] }
-
- zone_offset : Z { result = 0 }
- | '-' zone_offset_hour { result = -1 * val[1] }
- | '+' positive_zone_offset { result = val[1] }
- ;
-
- positive_zone_offset : zone_offset_hour
- | '0' '0' ':' '0' '0' { result = 0 }
- ;
-
-
- zone_offset_hour : d01_13 ':' minute { result = Rational(val[0] * 60 + val[2], 1440) }
- | '1' '4' ':' '0' '0' { result = Rational(840, 1440) }
- | '0' '0' ':' d01_59 { result = Rational(val[3], 1440) }
- ;
-
- year : digit digit digit digit {
- result = val.zip([1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
- }
-
- month : d01_12
- day : d01_31
-
- year_month : year '-' month { result = [val[0], val[2]] }
-
- # We raise an exception if there are two many days for the month, but
- # do not consider leap years, as the EDTF BNF did not either.
- # NB: an exception will be raised regardless, because the Ruby Date
- # implementation calculates leap years.
- year_month_day : year_month '-' day {
- result = val[0] << val[2]
- if result[2] > 31 || (result[2] > 30 && [2,4,6,9,11].include?(result[1])) || (result[2] > 29 && result[1] == 2)
- raise ArgumentError, "invalid date (invalid days #{result[2]} for month #{result[1]})"
- end
- }
-
- hour : d00_23
- minute : d00_59
- second : d00_59
-
- # Completely covered by level_1_interval
- # level_0_interval : date '/' date { result = Interval.new(val[0], val[1]) }
-
-
- # ---- Level 1 Extension Rules ----
-
- # NB: Uncertain/approximate Dates are covered by the Level 2 rules
- level_1_expression : unspecified | level_1_interval | long_year_simple | season
-
- # uncertain_or_approximate_date : date UA { result = uoa(val[0], val[1]) }
-
- unspecified : unspecified_year
- {
- result = Date.new(val[0][0]).year_precision!
- result.unspecified.year[2,2] = val[0][1]
- }
- | unspecified_month
- | unspecified_day
- | unspecified_day_and_month
- ;
-
- unspecified_year :
- digit digit digit U
- {
- result = [val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b }, [false,true]]
- }
- | digit digit U U
- {
- result = [val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b }, [true, true]]
- }
-
- unspecified_month : year '-' U U {
- result = Date.new(val[0]).unspecified!(:month)
- result.precision = :month
- }
-
- unspecified_day : year_month '-' U U {
- result = Date.new(*val[0]).unspecified!(:day)
- }
-
- unspecified_day_and_month : year '-' U U '-' U U {
- result = Date.new(val[0]).unspecified!([:day,:month])
- }
-
-
- level_1_interval : level_1_start '/' level_1_end {
- result = Interval.new(val[0], val[2])
- }
-
- level_1_start : date | partial_uncertain_or_approximate | unspecified | partial_unspecified | UNKNOWN
-
- level_1_end : level_1_start | OPEN
-
-
- long_year_simple :
- LONGYEAR long_year
- {
- result = Date.new(val[1])
- result.precision = :year
- }
- | LONGYEAR '-' long_year
- {
- result = Date.new(-1 * val[2])
- result.precision = :year
- }
- ;
-
- long_year :
- positive_digit digit digit digit digit {
- result = val.zip([10000,1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
- }
- | long_year digit { result = 10 * val[0] + val[1] }
- ;
-
-
- season : year '-' season_number ua {
- result = Season.new(val[0], val[2])
- val[3].each { |ua| result.send(ua) }
- }
-
- season_number : '2' '1' { result = 21 }
- | '2' '2' { result = 22 }
- | '2' '3' { result = 23 }
- | '2' '4' { result = 24 }
- ;
-
-
- # ---- Level 2 Extension Rules ----
-
- # NB: Level 2 Intervals are covered by the Level 1 Interval rules.
- level_2_expression : season_qualified
- | partial_uncertain_or_approximate
- | partial_unspecified
- | choice_list
- | inclusive_list
- | masked_precision
- | date_and_calendar
- | long_year_scientific
- ;
-
-
- season_qualified : season '^' { result = val[0]; result.qualifier = val[1] }
-
-
- long_year_scientific :
- long_year_simple E integer
- {
- result = Date.new(val[0].year * 10 ** val[2]).year_precision!
- }
- | LONGYEAR int1_4 E integer
- {
- result = Date.new(val[1] * 10 ** val[3]).year_precision!
- }
- | LONGYEAR '-' int1_4 E integer
- {
- result = Date.new(-1 * val[2] * 10 ** val[4]).year_precision!
- }
- ;
-
-
- date_and_calendar : date '^' { result = val[0]; result.calendar = val[1] }
-
-
- masked_precision :
- digit digit digit X
- {
- d = val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b }
- result = EDTF::Decade.new(d)
- }
- | digit digit X X
- {
- d = val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b }
- result = EDTF::Century.new(d)
- }
- ;
-
-
- choice_list : '[' list ']' { result = val[1].choice! }
-
- inclusive_list : '{' list '}' { result = val[1] }
-
- list : earlier { result = EDTF::Set.new(val[0]).earlier! }
- | earlier ',' list_elements ',' later { result = EDTF::Set.new([val[0]] + val[2] + [val[4]]).earlier!.later! }
- | earlier ',' list_elements { result = EDTF::Set.new([val[0]] + val[2]).earlier! }
- | earlier ',' later { result = EDTF::Set.new([val[0]] + [val[2]]).earlier!.later! }
- | list_elements ',' later { result = EDTF::Set.new(val[0] + [val[2]]).later! }
- | list_elements { result = EDTF::Set.new(*val[0]) }
- | later { result = EDTF::Set.new(val[0]).later! }
- ;
-
- list_elements : list_element { result = [val[0]].flatten }
- | list_elements ',' list_element { result = val[0] + [val[2]].flatten }
- ;
-
- list_element : atomic
- | consecutives
- ;
-
- atomic : date
- | partial_uncertain_or_approximate
- | unspecified
- ;
-
- earlier : DOTS date { result = val[1] }
-
- later : year_month_day DOTS { result = Date.new(*val[0]).year_precision! }
- | year_month DOTS { result = Date.new(*val[0]).month_precision! }
- | year DOTS { result = Date.new(val[0]).year_precision! }
- ;
-
- consecutives : year_month_day DOTS year_month_day { result = (Date.new(val[0]).day_precision! .. Date.new(val[2]).day_precision!) }
- | year_month DOTS year_month { result = (Date.new(val[0]).month_precision! .. Date.new(val[2]).month_precision!) }
- | year DOTS year { result = (Date.new(val[0]).year_precision! .. Date.new(val[2]).year_precision!) }
- ;
-
- partial_unspecified :
- unspecified_year '-' month '-' day
- {
- result = Date.new(val[0][0], val[2], val[4])
- result.unspecified.year[2,2] = val[0][1]
- }
- | unspecified_year '-' U U '-' day
- {
- result = Date.new(val[0][0], 1, val[5])
- result.unspecified.year[2,2] = val[0][1]
- result.unspecified!(:month)
- }
- | unspecified_year '-' U U '-' U U
- {
- result = Date.new(val[0][0], 1, 1)
- result.unspecified.year[2,2] = val[0][1]
- result.unspecified!([:month, :day])
- }
- | unspecified_year '-' month '-' U U
- {
- result = Date.new(val[0][0], val[2], 1)
- result.unspecified.year[2,2] = val[0][1]
- result.unspecified!(:day)
- }
- | year '-' U U '-' day
- {
- result = Date.new(val[0], 1, val[5])
- result.unspecified!(:month)
- }
- ;
-
-
- partial_uncertain_or_approximate : pua_base
- | '(' pua_base ')' UA { result = uoa(val[1], val[3]) }
-
- pua_base :
- pua_year { result = val[0].year_precision! }
- | pua_year_month { result = val[0][0].month_precision! }
- | pua_year_month_day { result = val[0].day_precision! }
-
- pua_year : year UA { result = uoa(Date.new(val[0]), val[1], :year) }
-
- pua_year_month :
- pua_year '-' month ua {
- result = [uoa(val[0].change(:month => val[2]), val[3], [:month, :year])]
- }
- | year '-' month UA {
- result = [uoa(Date.new(val[0], val[2]), val[3], [:year, :month])]
- }
- | year '-(' month ')' UA {
- result = [uoa(Date.new(val[0], val[2]), val[4], [:month]), true]
- }
- | pua_year '-(' month ')' UA {
- result = [uoa(val[0].change(:month => val[2]), val[4], [:month]), true]
- }
- ;
-
- pua_year_month_day :
- pua_year_month '-' day ua {
- result = uoa(val[0][0].change(:day => val[2]), val[3], val[0][1] ? [:day] : nil)
- }
- | pua_year_month '-(' day ')' UA {
- result = uoa(val[0][0].change(:day => val[2]), val[4], [:day])
- }
- | year '-(' month ')' UA day ua {
- result = uoa(uoa(Date.new(val[0], val[2], val[5]), val[4], :month), val[6], :day)
- }
- | year_month '-' day UA {
- result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[3])
- }
- | year_month '-(' day ')' UA {
- result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[4], [:day])
- }
- | year '-(' month '-' day ')' UA {
- result = uoa(Date.new(val[0], val[2], val[4]), val[6], [:month, :day])
- }
- | year '-(' month '-(' day ')' UA ')' UA {
- result = Date.new(val[0], val[2], val[4])
- result = uoa(result, val[6], [:day])
- result = uoa(result, val[8], [:month, :day])
- }
- | pua_year '-(' month '-' day ')' UA {
- result = val[0].change(:month => val[2], :day => val[4])
- result = uoa(result, val[6], [:month, :day])
- }
- | pua_year '-(' month '-(' day ')' UA ')' UA {
- result = val[0].change(:month => val[2], :day => val[4])
- result = uoa(result, val[6], [:day])
- result = uoa(result, val[8], [:month, :day])
- }
- # | '(' pua_year '-(' month ')' UA ')' UA '-' day ua {
- # result = val[1].change(:month => val[3], :day => val[9])
- # result = uoa(result, val[5], [:month])
- # result = [uoa(result, val[7], [:year]), true]
- # }
- ;
-
- ua : { result = [] } | UA
-
- # ---- Auxiliary Rules ----
-
- digit : '0' { result = 0 }
- | positive_digit
- ;
-
- positive_digit : '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
-
- d01_12 : '0' positive_digit { result = val[1] }
- | '1' '0' { result = 10 }
- | '1' '1' { result = 11 }
- | '1' '2' { result = 12 }
- ;
-
- d01_13 : d01_12
- | '1' '3' { result = 13 }
- ;
-
- d01_23 : '0' positive_digit { result = val[1] }
- | '1' digit { result = 10 + val[1] }
- | '2' '0' { result = 20 }
- | '2' '1' { result = 21 }
- | '2' '2' { result = 22 }
- | '2' '3' { result = 23 }
- ;
-
- d00_23 : '0' '0'
- | d01_23
- ;
-
- d01_29 : d01_23
- | '2' '4' { result = 24 }
- | '2' '5' { result = 25 }
- | '2' '6' { result = 26 }
- | '2' '7' { result = 27 }
- | '2' '8' { result = 28 }
- | '2' '9' { result = 29 }
- ;
-
- d01_30 : d01_29
- | '3' '0' { result = 30 }
- ;
-
- d01_31 : d01_30
- | '3' '1' { result = 31 }
- ;
-
- d01_59 : d01_29
- | '3' digit { result = 30 + val[1] }
- | '4' digit { result = 40 + val[1] }
- | '5' digit { result = 50 + val[1] }
- ;
-
- d00_59 : '0' '0'
- | d01_59
- ;
-
- int1_4 : positive_digit { result = val[0] }
- | positive_digit digit { result = 10 * val[0] + val[1] }
- | positive_digit digit digit
- {
- result = val.zip([100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
- }
- | positive_digit digit digit digit
- {
- result = val.zip([1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
- }
- ;
-
- integer : positive_digit { result = val[0] }
- | integer digit { result = 10 * val[0] + val[1] }
- ;
-
-
-
----- header
-require 'strscan'
-
----- inner
-
- @defaults = {
- :level => 2,
- :debug => false
- }.freeze
-
- class << self; attr_reader :defaults; end
-
- attr_reader :options
-
- def initialize(options = {})
- @options = Parser.defaults.merge(options)
- end
-
- def debug?
- !!(options[:debug] || ENV['DEBUG'])
- end
-
- def parse(input)
- parse!(input)
- rescue => e
- warn e.message if debug?
- nil
- end
-
- def parse!(input)
- @yydebug = debug?
- @src = StringScanner.new(input)
- do_parse
- end
-
- def on_error(tid, value, stack)
- raise ArgumentError,
- "failed to parse date: unexpected '#{value}' at #{stack.inspect}"
- end
-
- def apply_uncertainty(date, uncertainty, scope = nil)
- uncertainty.each do |u|
- scope.nil? ? date.send(u) : date.send(u, scope)
- end
- date
- end
-
- alias uoa apply_uncertainty
-
- def next_token
- case
- when @src.eos?
- nil
- # when @src.scan(/\s+/)
- # ignore whitespace
- when @src.scan(/\(/)
- ['(', @src.matched]
- # when @src.scan(/\)\?~-/)
- # [:PUA, [:uncertain!, :approximate!]]
- # when @src.scan(/\)\?-/)
- # [:PUA, [:uncertain!]]
- # when @src.scan(/\)~-/)
- # [:PUA, [:approximate!]]
- when @src.scan(/\)/)
- [')', @src.matched]
- when @src.scan(/\[/)
- ['[', @src.matched]
- when @src.scan(/\]/)
- [']', @src.matched]
- when @src.scan(/\{/)
- ['{', @src.matched]
- when @src.scan(/\}/)
- ['}', @src.matched]
- when @src.scan(/T/)
- [:T, @src.matched]
- when @src.scan(/Z/)
- [:Z, @src.matched]
- when @src.scan(/\?~/)
- [:UA, [:uncertain!, :approximate!]]
- when @src.scan(/\?/)
- [:UA, [:uncertain!]]
- when @src.scan(/~/)
- [:UA, [:approximate!]]
- when @src.scan(/open/i)
- [:OPEN, :open]
- when @src.scan(/unkn?own/i) # matches 'unkown' typo too
- [:UNKNOWN, :unknown]
- when @src.scan(/u/)
- [:U, @src.matched]
- when @src.scan(/x/i)
- [:X, @src.matched]
- when @src.scan(/y/)
- [:LONGYEAR, @src.matched]
- when @src.scan(/e/)
- [:E, @src.matched]
- when @src.scan(/\+/)
- ['+', @src.matched]
- when @src.scan(/-\(/)
- ['-(', @src.matched]
- when @src.scan(/-/)
- ['-', @src.matched]
- when @src.scan(/:/)
- [':', @src.matched]
- when @src.scan(/\//)
- ['/', @src.matched]
- when @src.scan(/\s*\.\.\s*/)
- [:DOTS, '..']
- when @src.scan(/\s*,\s*/)
- [',', ',']
- when @src.scan(/\^\w+/)
- ['^', @src.matched[1..-1]]
- when @src.scan(/\d/)
- [@src.matched, @src.matched.to_i]
- else @src.scan(/./)
- [:UNMATCHED, @src.rest]
- end
- end
-
-
-# -*- racc -*-
diff --git a/test/racc/assets/err.y b/test/racc/assets/err.y
deleted file mode 100644
index ae280957cc..0000000000
--- a/test/racc/assets/err.y
+++ /dev/null
@@ -1,60 +0,0 @@
-
-class ErrTestp
-
-rule
-
-target: lines
- ;
-
-lines: line
- | lines line
- ;
-
-line: A B C D E
- | error E
- ;
-
-end
-
----- inner
-
-def initialize
- @yydebug = false
- @q = [
- [:A, 'a'],
- # [:B, 'b'],
- [:C, 'c'],
- [:D, 'd'],
- [:E, 'e'],
-
- [:A, 'a'],
- [:B, 'b'],
- [:C, 'c'],
- [:D, 'd'],
- [:E, 'e'],
-
- [:A, 'a'],
- [:B, 'b'],
- # [:C, 'c'],
- [:D, 'd'],
- [:E, 'e'],
- [false, nil]
- ]
-end
-
-def next_token
- @q.shift
-end
-
-def on_error( t, val, values )
- $stderr.puts "error on token '#{val}'(#{t})"
-end
-
-def parse
- do_parse
-end
-
----- footer
-
-p = ErrTestp.new
-p.parse
diff --git a/test/racc/assets/error_recovery.y b/test/racc/assets/error_recovery.y
deleted file mode 100644
index 1fd21ac7d0..0000000000
--- a/test/racc/assets/error_recovery.y
+++ /dev/null
@@ -1,35 +0,0 @@
-# Regression test case for the bug discussed here:
-# https://github.com/whitequark/parser/issues/93
-# In short, a Racc-generated parser could go into an infinite loop when
-# attempting error recovery at EOF
-
-class InfiniteLoop
-
-rule
-
- stmts: stmt
- | error stmt
-
- stmt: '%' stmt
-
-end
-
----- inner
-
- def parse
- @errors = []
- do_parse
- end
-
- def next_token
- nil
- end
-
- def on_error(error_token, error_value, value_stack)
- # oh my, an error
- @errors << [error_token, error_value]
- end
-
----- footer
-
-InfiniteLoop.new.parse \ No newline at end of file
diff --git a/test/racc/assets/expect.y b/test/racc/assets/expect.y
deleted file mode 100644
index 24c27443e2..0000000000
--- a/test/racc/assets/expect.y
+++ /dev/null
@@ -1,7 +0,0 @@
-class E
- expect 1
-rule
- list: inlist inlist
- inlist:
- | A
-end
diff --git a/test/racc/assets/firstline.y b/test/racc/assets/firstline.y
deleted file mode 100644
index ab0692e543..0000000000
--- a/test/racc/assets/firstline.y
+++ /dev/null
@@ -1,4 +0,0 @@
-class T
-rule
- a: A B C
-end
diff --git a/test/racc/assets/huia.y b/test/racc/assets/huia.y
deleted file mode 100644
index de9d45150c..0000000000
--- a/test/racc/assets/huia.y
+++ /dev/null
@@ -1,318 +0,0 @@
-# Copyright (c) 2014 James Harton
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Huia::Parser
-
- token
- IDENTIFIER EQUAL PLUS MINUS ASTERISK FWD_SLASH COLON FLOAT INTEGER STRING
- EXPO INDENT OUTDENT OPAREN CPAREN DOT SIGNATURE NL EOF PIPE COMMA NIL TRUE
- FALSE EQUALITY CALL SELF CONSTANT CHAR DOUBLE_TICK_STRING
- DOUBLE_TICK_STRING_END INTERPOLATE_START INTERPOLATE_END BOX LSQUARE
- RSQUARE FACES LFACE RFACE BANG TILDE RETURN NOT_EQUALITY OR AND GT LT
- GTE LTE AT
-
- prechigh
- left EXPO
- left BANG TILDE
- left ASTERISK FWD_SLASH PERCENT
- left PLUS MINUS
-
- right EQUAL
- preclow
-
- rule
- statements: statement
- | statements statement { return scope }
-
- statement: expr eol { return scope.append val[0] }
- | expr { return scope.append val[0] }
- | eol { return scope }
-
- eol: NL | EOF
- nlq: NL |
-
- expr: literal
- | grouped_expr
- | binary_op
- | unary_op
- | method_call
- | constant
- | variable
- | array
- | hash
- | return
-
- return: return_expr
- | return_nil
- return_expr: RETURN expr { return n(:Return, val[1]) }
- return_nil: RETURN { return n(:Return, n(:Nil)) }
-
- array: empty_array
- | array_list
-
- empty_array: BOX { return n :Array }
-
- array_list: LSQUARE array_items RSQUARE { return val[1] }
- array_items: expr { return n :Array, [val[0]] }
- | array_items COMMA expr { val[0].append(val[2]); return val[0] }
-
- hash: empty_hash
- | hash_list
- empty_hash: FACES { return n :Hash }
- hash_list: LFACE hash_items RFACE { return val[1] }
- hash_items: hash_item { return n :Hash, val[0] }
- | hash_items COMMA hash_item { val[0].append(val[2]); return val[0] }
- hash_item: expr COLON expr { return n :HashItem, val[0], val[2] }
-
- constant: CONSTANT { return constant val[0] }
-
- indented: indented_w_stmts
- | indented_w_expr
- | indented_wo_stmts
- indented_w_stmts: indent statements outdent { return val[0] }
- indented_w_expr: indent expr outdent { return val[0].append(val[1]) }
- indented_wo_stmts: indent outdent { return val[0] }
- outdent: OUTDENT { return pop_scope }
-
-
- indent_w_args: indent_pipe indent_args PIPE nlq INDENT { return val[0] }
- indent_pipe: PIPE { return push_scope }
- indent_wo_args: INDENT { return push_scope }
- indent: indent_w_args
- | indent_wo_args
-
- indent_args: indent_arg
- | indent_args COMMA indent_arg
- indent_arg: arg_var { return scope.add_argument val[0] }
- | arg_var EQUAL expr { return n :Assignment, val[0], val[2] }
- arg_var: IDENTIFIER { return n :Variable, val[0] }
-
- method_call: method_call_on_object
- | method_call_on_self
- | method_call_on_closure
- method_call_on_object: expr DOT call_signature { return n :MethodCall, val[0], val[2] }
- | expr DOT IDENTIFIER { return n :MethodCall, val[0], n(:CallSignature, val[2]) }
- method_call_on_self: call_signature { return n :MethodCall, scope_instance, val[0] }
-
- method_call_on_closure: AT call_signature { return n :MethodCall, this_closure, val[1] }
- | AT IDENTIFIER { return n :MethodCall, this_closure, n(:CallSignature, val[1]) }
-
- call_signature: call_arguments
- | call_simple_name
- call_simple_name: CALL { return n :CallSignature, val[0] }
- call_argument: SIGNATURE call_passed_arg { return n :CallSignature, val[0], [val[1]] }
- call_passed_arg: call_passed_simple
- | call_passed_indented
- call_passed_simple: expr
- | expr NL
- call_passed_indented: indented
- | indented NL
- call_arguments: call_argument { return val[0] }
- | call_arguments call_argument { return val[0].concat_signature val[1] }
-
- grouped_expr: OPAREN expr CPAREN { return n :Expression, val[1] }
-
- variable: IDENTIFIER { return allocate_local val[0] }
-
- binary_op: assignment
- | addition
- | subtraction
- | multiplication
- | division
- | exponentiation
- | modulo
- | equality
- | not_equality
- | logical_or
- | logical_and
- | greater_than
- | less_than
- | greater_or_eq
- | less_or_eq
-
- assignment: IDENTIFIER EQUAL expr { return allocate_local_assignment val[0], val[2] }
- addition: expr PLUS expr { return binary val[0], val[2], 'plus:' }
- subtraction: expr MINUS expr { return binary val[0], val[2], 'minus:' }
- multiplication: expr ASTERISK expr { return binary val[0], val[2], 'multiplyBy:' }
- division: expr FWD_SLASH expr { return binary val[0], val[2], 'divideBy:' }
- exponentiation: expr EXPO expr { return binary val[0], val[2], 'toThePowerOf:' }
- modulo: expr PERCENT expr { return binary val[0], val[2], 'moduloOf:' }
- equality: expr EQUALITY expr { return binary val[0], val[2], 'isEqualTo:' }
- not_equality: expr NOT_EQUALITY expr { return binary val[0], val[2], 'isNotEqualTo:' }
- logical_or: expr OR expr { return binary val[0], val[2], 'logicalOr:' }
- logical_and: expr AND expr { return binary val[0], val[2], 'logicalAnd:' }
- greater_than: expr GT expr { return binary val[0], val[2], 'isGreaterThan:' }
- less_than: expr LT expr { return binary val[0], val[2], 'isLessThan:' }
- greater_or_eq: expr GTE expr { return binary val[0], val[2], 'isGreaterOrEqualTo:' }
- less_or_eq: expr LTE expr { return binary val[0], val[2], 'isLessOrEqualTo:' }
-
- unary_op: unary_not
- | unary_plus
- | unary_minus
- | unary_complement
-
- unary_not: BANG expr { return unary val[1], 'unaryNot' }
- unary_plus: PLUS expr { return unary val[1], 'unaryPlus' }
- unary_minus: MINUS expr { return unary val[1], 'unaryMinus' }
- unary_complement: TILDE expr { return unary val[1], 'unaryComplement' }
-
- literal: integer
- | float
- | string
- | nil
- | true
- | false
- | self
-
- float: FLOAT { return n :Float, val[0] }
- integer: INTEGER { return n :Integer, val[0] }
- nil: NIL { return n :Nil }
- true: TRUE { return n :True }
- false: FALSE { return n :False }
- self: SELF { return n :Self }
-
- string: STRING { return n :String, val[0] }
- | interpolated_string
- | empty_string
-
- interpolated_string: DOUBLE_TICK_STRING interpolated_string_contents DOUBLE_TICK_STRING_END { return val[1] }
- interpolation: INTERPOLATE_START expr INTERPOLATE_END { return val[1] }
- interpolated_string_contents: interpolated_string_chunk { return n :InterpolatedString, val[0] }
- | interpolated_string_contents interpolated_string_chunk { val[0].append(val[1]); return val[0] }
- interpolated_string_chunk: chars { return val[0] }
- | interpolation { return to_string(val[0]) }
- empty_string: DOUBLE_TICK_STRING DOUBLE_TICK_STRING_END { return n :String, '' }
-
- chars: CHAR { return n :String, val[0] }
- | chars CHAR { val[0].append(val[1]); return val[0] }
-end
-
----- inner
-
-attr_accessor :lexer, :scopes, :state
-
-def initialize lexer
- @lexer = lexer
- @state = []
- @scopes = []
- push_scope
-end
-
-def ast
- @ast ||= do_parse
- @scopes.first
-end
-
-def on_error t, val, vstack
- line = lexer.line
- col = lexer.column
- message = "Unexpected #{token_to_str t} at #{lexer.filename} line #{line}:#{col}:\n\n"
-
- start = line - 5 > 0 ? line - 5 : 0
- i_size = line.to_s.size
- (start..(start + 5)).each do |i|
- message << sprintf("\t%#{i_size}d: %s\n", i, lexer.get_line(i))
- message << "\t#{' ' * i_size} #{'-' * (col - 1)}^\n" if i == line
- end
-
- raise SyntaxError, message
-end
-
-def next_token
- nt = lexer.next_computed_token
- # just use a state stack for now, we'll have to do something
- # more sophisticated soon.
- if nt && nt.first == :state
- if nt.last
- state.push << nt.last
- else
- state.pop
- end
- next_token
- else
- nt
- end
-end
-
-def push_scope
- new_scope = Huia::AST::Scope.new scope
- new_scope.file = lexer.filename
- new_scope.line = lexer.line
- new_scope.column = lexer.column
- scopes.push new_scope
- new_scope
-end
-
-def pop_scope
- scopes.pop
-end
-
-def scope
- scopes.last
-end
-
-def binary left, right, method
- node(:MethodCall, left, node(:CallSignature, method, [right]))
-end
-
-def unary left, method
- node(:MethodCall, left, node(:CallSignature, method))
-end
-
-def node type, *args
- Huia::AST.const_get(type).new(*args).tap do |n|
- n.file = lexer.filename
- n.line = lexer.line
- n.column = lexer.column
- end
-end
-alias n node
-
-def allocate_local name
- node(:Variable, name).tap do |n|
- scope.allocate_local n
- end
-end
-
-def allocate_local_assignment name, value
- node(:Assignment, name, value).tap do |n|
- scope.allocate_local n
- end
-end
-
-def this_closure
- allocate_local('@')
-end
-
-def scope_instance
- node(:ScopeInstance, scope)
-end
-
-def constant name
- return scope_instance if name == 'self'
- node(:Constant, name)
-end
-
-def to_string expr
- node(:MethodCall, expr, node(:CallSignature, 'toString'))
-end
diff --git a/test/racc/assets/ichk.y b/test/racc/assets/ichk.y
deleted file mode 100644
index 1d359df83e..0000000000
--- a/test/racc/assets/ichk.y
+++ /dev/null
@@ -1,102 +0,0 @@
-class Calculator
-
- prechigh
- left '*' '/'
- left '+' '-'
- preclow
-
- convert
- NUMBER 'Number'
- end
-
-rule
-
- target : exp
- | /* none */ { result = 0 }
-
- exp : exp '+' exp { result += val[2]; a = 'plus' }
- | exp '-' exp { result -= val[2]; a = "string test" }
- | exp '*' exp { result *= val[2] }
- | exp '/' exp { result /= val[2] }
- | '(' { $emb = true } exp ')'
- {
- raise 'must not happen' unless $emb
- result = val[2]
- }
- | '-' NUMBER { result = -val[1] }
- | NUMBER
-
-----header
-
-class Number
-end
-
-----inner
-
- def initialize
- @racc_debug_out = $stdout
- @yydebug = false
- end
-
- def validate(expected, src)
- result = parse(src)
- unless result == expected
- raise "test #{@test_number} fail"
- end
- @test_number += 1
- end
-
- def parse(src)
- @src = src
- @test_number = 1
- yyparse self, :scan
- end
-
- def scan(&block)
- @src.each(&block)
- end
-
-----footer
-
-calc = Calculator.new
-
-calc.validate(9, [[Number, 9], nil])
-
-calc.validate(-3,
- [[Number, 5],
- ['*', '*'],
- [Number, 1],
- ['-', '*'],
- [Number, 1],
- ['*', '*'],
- [Number, 8],
- nil])
-
-calc.validate(-1,
- [[Number, 5],
- ['+', '+'],
- [Number, 2],
- ['-', '-'],
- [Number, 5],
- ['+', '+'],
- [Number, 2],
- ['-', '-'],
- [Number, 5],
- nil])
-
-calc.validate(-4,
- [['-', 'UMINUS'],
- [Number, 4],
- nil])
-
-calc.validate(40,
- [[Number, 7],
- ['*', '*'],
- ['(', '('],
- [Number, 4],
- ['+', '+'],
- [Number, 3],
- [')', ')'],
- ['-', '-'],
- [Number, 9],
- nil])
diff --git a/test/racc/assets/ifelse.y b/test/racc/assets/ifelse.y
deleted file mode 100644
index 18dbe4b1a7..0000000000
--- a/test/racc/assets/ifelse.y
+++ /dev/null
@@ -1,14 +0,0 @@
-class C::Parser
-token tSOMETHING
-rule
- statement
- : tSOMETHING
- | 'if' statement 'then' statement
- | 'if' statement 'then' statement 'else' statement
- ;
-
- dummy
- : tSOMETHING '+' tSOMETHING
- | tSOMETHING '-' tSOMETHING
- ;
-
diff --git a/test/racc/assets/intp.y b/test/racc/assets/intp.y
deleted file mode 100644
index 39e42afd74..0000000000
--- a/test/racc/assets/intp.y
+++ /dev/null
@@ -1,546 +0,0 @@
-#
-# intp
-#
-
-class Intp::Parser
-
-prechigh
- nonassoc UMINUS
- left '*' '/'
- left '+' '-'
- nonassoc EQ
-preclow
-
-rule
-
- program : stmt_list
- {
- result = RootNode.new( val[0] )
- }
-
- stmt_list :
- {
- result = []
- }
- | stmt_list stmt EOL
- {
- result.push val[1]
- }
- | stmt_list EOL
-
- stmt : expr
- | assign
- | IDENT realprim
- {
- result = FuncallNode.new( @fname, val[0][0],
- val[0][1], [val[1]] )
- }
- | if_stmt
- | while_stmt
- | defun
-
- if_stmt : IF stmt THEN EOL stmt_list else_stmt END
- {
- result = IfNode.new( @fname, val[0][0],
- val[1], val[4], val[5] )
- }
-
- else_stmt : ELSE EOL stmt_list
- {
- result = val[2]
- }
- |
- {
- result = nil
- }
-
- while_stmt: WHILE stmt DO EOL stmt_list END
- {
- result = WhileNode.new(@fname, val[0][0],
- val[1], val[4])
- }
-
- defun : DEF IDENT param EOL stmt_list END
- {
- result = DefNode.new(@fname, val[0][0], val[1][1],
- Function.new(@fname, val[0][0], val[2], val[4]))
- }
-
- param : '(' name_list ')'
- {
- result = val[1]
- }
- | '(' ')'
- {
- result = []
- }
- |
- {
- result = []
- }
-
- name_list : IDENT
- {
- result = [ val[0][1] ]
- }
- | name_list ',' IDENT
- {
- result.push val[2][1]
- }
-
- assign : IDENT '=' expr
- {
- result = AssignNode.new(@fname, val[0][0], val[0][1], val[2])
- }
-
- expr : expr '+' expr
- {
- result = FuncallNode.new(@fname, val[0].lineno, '+', [val[0], val[2]])
- }
- | expr '-' expr
- {
- result = FuncallNode.new(@fname, val[0].lineno, '-', [val[0], val[2]])
- }
- | expr '*' expr
- {
- result = FuncallNode.new(@fname, val[0].lineno, '*', [val[0], val[2]])
- }
- | expr '/' expr
- {
- result = FuncallNode.new(@fname, val[0].lineno,
- '/', [val[0], val[2]])
- }
- | expr EQ expr
- {
- result = FuncallNode.new(@fname, val[0].lineno, '==', [val[0], val[2]])
- }
- | primary
-
- primary : realprim
- | '(' expr ')'
- {
- result = val[1]
- }
- | '-' expr =UMINUS
- {
- result = FuncallNode.new(@fname, val[0][0], '-@', [val[1]])
- }
-
- realprim : IDENT
- {
- result = VarRefNode.new(@fname, val[0][0],
- val[0][1])
- }
- | NUMBER
- {
- result = LiteralNode.new(@fname, *val[0])
- }
- | STRING
- {
- result = StringNode.new(@fname, *val[0])
- }
- | TRUE
- {
- result = LiteralNode.new(@fname, *val[0])
- }
- | FALSE
- {
- result = LiteralNode.new(@fname, *val[0])
- }
- | NIL
- {
- result = LiteralNode.new(@fname, *val[0])
- }
- | funcall
-
- funcall : IDENT '(' args ')'
- {
- result = FuncallNode.new(@fname, val[0][0], val[0][1], val[2])
- }
- | IDENT '(' ')'
- {
- result = FuncallNode.new(@fname, val[0][0], val[0][1], [])
- }
-
- args : expr
- {
- result = val
- }
- | args ',' expr
- {
- result.push val[2]
- }
-
-end
-
----- header
-#
-# intp/parser.rb
-#
-
----- inner
-
- def initialize
- @scope = {}
- end
-
- RESERVED = {
- 'if' => :IF,
- 'else' => :ELSE,
- 'while' => :WHILE,
- 'then' => :THEN,
- 'do' => :DO,
- 'def' => :DEF,
- 'true' => :TRUE,
- 'false' => :FALSE,
- 'nil' => :NIL,
- 'end' => :END
- }
-
- RESERVED_V = {
- 'true' => true,
- 'false' => false,
- 'nil' => nil
- }
-
- def parse(f, fname)
- @q = []
- @fname = fname
- lineno = 1
- f.each do |line|
- line.strip!
- until line.empty?
- case line
- when /\A\s+/, /\A\#.*/
- ;
- when /\A[a-zA-Z_]\w*/
- word = $&
- @q.push [(RESERVED[word] || :IDENT),
- [lineno, RESERVED_V.key?(word) ? RESERVED_V[word] : word.intern]]
- when /\A\d+/
- @q.push [:NUMBER, [lineno, $&.to_i]]
- when /\A"(?:[^"\\]+|\\.)*"/, /\A'(?:[^'\\]+|\\.)*'/
- @q.push [:STRING, [lineno, eval($&)]]
- when /\A==/
- @q.push [:EQ, [lineno, '==']]
- when /\A./
- @q.push [$&, [lineno, $&]]
- else
- raise RuntimeError, 'must not happen'
- end
- line = $'
- end
- @q.push [:EOL, [lineno, nil]]
- lineno += 1
- end
- @q.push [false, '$']
- do_parse
- end
-
- def next_token
- @q.shift
- end
-
- def on_error(t, v, values)
- if v
- line = v[0]
- v = v[1]
- else
- line = 'last'
- end
- raise Racc::ParseError, "#{@fname}:#{line}: syntax error on #{v.inspect}"
- end
-
----- footer
-# intp/node.rb
-
-module Intp
-
- class IntpError < StandardError; end
- class IntpArgumentError < IntpError; end
-
- class Core
-
- def initialize
- @ftab = {}
- @obj = Object.new
- @stack = []
- @stack.push Frame.new '(toplevel)'
- end
-
- def frame
- @stack[-1]
- end
-
- def define_function(fname, node)
- raise IntpError, "function #{fname} defined twice" if @ftab.key?(fname)
- @ftab[fname] = node
- end
-
- def call_function_or(fname, args)
- call_intp_function_or(fname, args) {
- call_ruby_toplevel_or(fname, args) {
- yield
- }
- }
- end
-
- def call_intp_function_or(fname, args)
- if func = @ftab[fname]
- frame = Frame.new(fname)
- @stack.push frame
- func.call self, frame, args
- @stack.pop
- else
- yield
- end
- end
-
- def call_ruby_toplevel_or(fname, args)
- if @obj.respond_to? fname, true
- @obj.send fname, *args
- else
- yield
- end
- end
-
- end
-
- class Frame
-
- def initialize(fname)
- @fname = fname
- @lvars = {}
- end
-
- attr :fname
-
- def lvar?(name)
- @lvars.key? name
- end
-
- def [](key)
- @lvars[key]
- end
-
- def []=(key, val)
- @lvars[key] = val
- end
-
- end
-
-
- class Node
-
- def initialize(fname, lineno)
- @filename = fname
- @lineno = lineno
- end
-
- attr_reader :filename
- attr_reader :lineno
-
- def exec_list(intp, nodes)
- v = nil
- nodes.each {|i| v = i.evaluate(intp) }
- v
- end
-
- def intp_error!(msg)
- raise IntpError, "in #{filename}:#{lineno}: #{msg}"
- end
-
- def inspect
- "#{self.class.name}/#{lineno}"
- end
-
- end
-
-
- class RootNode < Node
-
- def initialize(tree)
- super nil, nil
- @tree = tree
- end
-
- def evaluate
- exec_list Core.new, @tree
- end
-
- end
-
-
- class DefNode < Node
-
- def initialize(file, lineno, fname, func)
- super file, lineno
- @funcname = fname
- @funcobj = func
- end
-
- def evaluate(intp)
- intp.define_function @funcname, @funcobj
- end
-
- end
-
- class FuncallNode < Node
-
- def initialize(file, lineno, func, args)
- super file, lineno
- @funcname = func
- @args = args
- end
-
- def evaluate(intp)
- args = @args.map {|i| i.evaluate intp }
- begin
- intp.call_intp_function_or(@funcname, args) {
- if args.empty? or not args[0].respond_to?(@funcname)
- intp.call_ruby_toplevel_or(@funcname, args) {
- intp_error! "undefined function #{@funcname.id2name}"
- }
- else
- recv = args.shift
- recv.send @funcname, *args
- end
- }
- rescue IntpArgumentError, ArgumentError
- intp_error! $!.message
- end
- end
-
- end
-
- class Function < Node
-
- def initialize(file, lineno, params, body)
- super file, lineno
- @params = params
- @body = body
- end
-
- def call(intp, frame, args)
- unless args.size == @params.size
- raise IntpArgumentError,
- "wrong # of arg for #{frame.fname}() (#{args.size} for #{@params.size})"
- end
- args.each_with_index do |v,i|
- frame[@params[i]] = v
- end
- exec_list intp, @body
- end
-
- end
-
-
- class IfNode < Node
-
- def initialize(fname, lineno, cond, tstmt, fstmt)
- super fname, lineno
- @condition = cond
- @tstmt = tstmt
- @fstmt = fstmt
- end
-
- def evaluate(intp)
- if @condition.evaluate(intp)
- exec_list intp, @tstmt
- else
- exec_list intp, @fstmt if @fstmt
- end
- end
-
- end
-
- class WhileNode < Node
-
- def initialize(fname, lineno, cond, body)
- super fname, lineno
- @condition = cond
- @body = body
- end
-
- def evaluate(intp)
- while @condition.evaluate(intp)
- exec_list intp, @body
- end
- end
-
- end
-
-
- class AssignNode < Node
-
- def initialize(fname, lineno, vname, val)
- super fname, lineno
- @vname = vname
- @val = val
- end
-
- def evaluate(intp)
- intp.frame[@vname] = @val.evaluate(intp)
- end
-
- end
-
- class VarRefNode < Node
-
- def initialize(fname, lineno, vname)
- super fname, lineno
- @vname = vname
- end
-
- def evaluate(intp)
- if intp.frame.lvar?(@vname)
- intp.frame[@vname]
- else
- intp.call_function_or(@vname, []) {
- intp_error! "unknown method or local variable #{@vname.id2name}"
- }
- end
- end
-
- end
-
- class StringNode < Node
-
- def initialize(fname, lineno, str)
- super fname, lineno
- @val = str
- end
-
- def evaluate(intp)
- @val.dup
- end
-
- end
-
- class LiteralNode < Node
-
- def initialize(fname, lineno, val)
- super fname, lineno
- @val = val
- end
-
- def evaluate(intp)
- @val
- end
-
- end
-
-end # module Intp
-
-begin
- tree = nil
- fname = 'src.intp'
- File.open(fname) {|f|
- tree = Intp::Parser.new.parse(f, fname)
- }
- tree.evaluate
-rescue Racc::ParseError, Intp::IntpError, Errno::ENOENT
- raise ####
- $stderr.puts "#{File.basename $0}: #{$!}"
- exit 1
-end
diff --git a/test/racc/assets/journey.y b/test/racc/assets/journey.y
deleted file mode 100644
index c2640f3339..0000000000
--- a/test/racc/assets/journey.y
+++ /dev/null
@@ -1,47 +0,0 @@
-class Journey::Parser
-
-token SLASH LITERAL SYMBOL LPAREN RPAREN DOT STAR OR
-
-rule
- expressions
- : expressions expression { result = Cat.new(val.first, val.last) }
- | expression { result = val.first }
- | or
- ;
- expression
- : terminal
- | group
- | star
- ;
- group
- : LPAREN expressions RPAREN { result = Group.new(val[1]) }
- ;
- or
- : expressions OR expression { result = Or.new([val.first, val.last]) }
- ;
- star
- : STAR { result = Star.new(Symbol.new(val.last)) }
- ;
- terminal
- : symbol
- | literal
- | slash
- | dot
- ;
- slash
- : SLASH { result = Slash.new('/') }
- ;
- symbol
- : SYMBOL { result = Symbol.new(val.first) }
- ;
- literal
- : LITERAL { result = Literal.new(val.first) }
- dot
- : DOT { result = Dot.new(val.first) }
- ;
-
-end
-
----- header
-
-require 'journey/parser_extras'
diff --git a/test/racc/assets/liquor.y b/test/racc/assets/liquor.y
deleted file mode 100644
index 8045a072a4..0000000000
--- a/test/racc/assets/liquor.y
+++ /dev/null
@@ -1,313 +0,0 @@
-# Copyright (c) 2012-2013 Peter Zotov <whitequark@whitequark.org>
-# 2012 Yaroslav Markin <yaroslav@markin.net>
-# 2012 Nate Gadgibalaev <nat@xnsv.ru>
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Liquor::Parser
- token comma dot endtag ident integer keyword lblock lblock2 lbracket
- linterp lparen op_div op_eq op_gt op_geq op_lt op_leq op_minus
- op_mod op_mul op_neq op_not op_plus pipe plaintext rblock
- rbracket rinterp rparen string tag_ident
-
- prechigh
- left dot
- nonassoc op_uminus op_not
- left op_mul op_div op_mod
- left op_plus op_minus
- left op_eq op_neq op_lt op_leq op_gt op_geq
- left op_and
- left op_or
- preclow
-
- expect 15
-
- start block
-
-rule
- block: /* empty */
- { result = [] }
- | plaintext block
- { result = [ val[0], *val[1] ] }
- | interp block
- { result = [ val[0], *val[1] ] }
- | tag block
- { result = [ val[0], *val[1] ] }
-
- interp:
- linterp expr rinterp
- { result = [ :interp, retag(val), val[1] ] }
- | linterp filter_chain rinterp
- { result = [ :interp, retag(val), val[1] ] }
-
- primary_expr:
- ident
- | lparen expr rparen
- { result = [ val[1][0], retag(val), *val[1][2..-1] ] }
-
- expr:
- integer
- | string
- | tuple
- | ident function_args
- { result = [ :call, retag(val), val[0], val[1] ] }
- | expr lbracket expr rbracket
- { result = [ :index, retag(val), val[0], val[2] ] }
- | expr dot ident function_args
- { result = [ :external, retag(val), val[0], val[2], val[3] ] }
- | expr dot ident
- { result = [ :external, retag(val), val[0], val[2], nil ] }
- | op_minus expr =op_uminus
- { result = [ :uminus, retag(val), val[1] ] }
- | op_not expr
- { result = [ :not, retag(val), val[1] ] }
- | expr op_mul expr
- { result = [ :mul, retag(val), val[0], val[2] ] }
- | expr op_div expr
- { result = [ :div, retag(val), val[0], val[2] ] }
- | expr op_mod expr
- { result = [ :mod, retag(val), val[0], val[2] ] }
- | expr op_plus expr
- { result = [ :plus, retag(val), val[0], val[2] ] }
- | expr op_minus expr
- { result = [ :minus, retag(val), val[0], val[2] ] }
- | expr op_eq expr
- { result = [ :eq, retag(val), val[0], val[2] ] }
- | expr op_neq expr
- { result = [ :neq, retag(val), val[0], val[2] ] }
- | expr op_lt expr
- { result = [ :lt, retag(val), val[0], val[2] ] }
- | expr op_leq expr
- { result = [ :leq, retag(val), val[0], val[2] ] }
- | expr op_gt expr
- { result = [ :gt, retag(val), val[0], val[2] ] }
- | expr op_geq expr
- { result = [ :geq, retag(val), val[0], val[2] ] }
- | expr op_and expr
- { result = [ :and, retag(val), val[0], val[2] ] }
- | expr op_or expr
- { result = [ :or, retag(val), val[0], val[2] ] }
- | primary_expr
-
- tuple:
- lbracket tuple_content rbracket
- { result = [ :tuple, retag(val), val[1].compact ] }
-
- tuple_content:
- expr comma tuple_content
- { result = [ val[0], *val[2] ] }
- | expr
- { result = [ val[0] ] }
- | /* empty */
- { result = [ ] }
-
- function_args:
- lparen function_args_inside rparen
- { result = [ :args, retag(val), *val[1] ] }
-
- function_args_inside:
- expr function_keywords
- { result = [ val[0], val[1][2] ] }
- | function_keywords
- { result = [ nil, val[0][2] ] }
-
- function_keywords:
- keyword expr function_keywords
- { name = val[0][2].to_sym
- tail = val[2][2]
- loc = retag([ val[0], val[1] ])
-
- if tail.include? name
- @errors << SyntaxError.new("duplicate keyword argument `#{val[0][2]}'",
- tail[name][1])
- end
-
- hash = {
- name => [ val[1][0], loc, *val[1][2..-1] ]
- }.merge(tail)
-
- result = [ :keywords, retag([ loc, val[2] ]), hash ]
- }
- | /* empty */
- { result = [ :keywords, nil, {} ] }
-
- filter_chain:
- expr pipe filter_chain_cont
- { result = [ val[0], *val[2] ].
- reduce { |tree, node| node[3][2] = tree; node }
- }
-
- filter_chain_cont:
- filter_call pipe filter_chain_cont
- { result = [ val[0], *val[2] ] }
- | filter_call
- { result = [ val[0] ] }
-
- filter_call:
- ident function_keywords
- { ident_loc = val[0][1]
- empty_args_loc = { line: ident_loc[:line],
- start: ident_loc[:end] + 1,
- end: ident_loc[:end] + 1, }
- result = [ :call, val[0][1], val[0],
- [ :args, val[1][1] || empty_args_loc, nil, val[1][2] ] ]
- }
-
- tag:
- lblock ident expr tag_first_cont
- { result = [ :tag, retag(val), val[1], val[2], *reduce_tag_args(val[3][2]) ] }
- | lblock ident tag_first_cont
- { result = [ :tag, retag(val), val[1], nil, *reduce_tag_args(val[2][2]) ] }
-
- # Racc cannot do lookahead across rules. I had to add states
- # explicitly to avoid S/R conflicts. You are not expected to
- # understand this.
-
- tag_first_cont:
- rblock
- { result = [ :cont, retag(val), [] ] }
- | keyword tag_first_cont2
- { result = [ :cont, retag(val), [ val[0], *val[1][2] ] ] }
-
- tag_first_cont2:
- rblock block lblock2 tag_next_cont
- { result = [ :cont2, val[0][1], [ [:block, val[0][1], val[1] ], *val[3] ] ] }
- | expr tag_first_cont
- { result = [ :cont2, retag(val), [ val[0], *val[1][2] ] ] }
-
- tag_next_cont:
- endtag rblock
- { result = [] }
- | keyword tag_next_cont2
- { result = [ val[0], *val[1] ] }
-
- tag_next_cont2:
- rblock block lblock2 tag_next_cont
- { result = [ [:block, val[0][1], val[1] ], *val[3] ] }
- | expr keyword tag_next_cont3
- { result = [ val[0], val[1], *val[2] ] }
-
- tag_next_cont3:
- rblock block lblock2 tag_next_cont
- { result = [ [:block, val[0][1], val[1] ], *val[3] ] }
- | expr tag_next_cont
- { result = [ val[0], *val[1] ] }
-
----- inner
- attr_reader :errors, :ast
-
- def initialize(tags={})
- super()
-
- @errors = []
- @ast = nil
- @tags = tags
- end
-
- def success?
- @errors.empty?
- end
-
- def parse(string, name='(code)')
- @errors.clear
- @name = name
- @ast = nil
-
- begin
- @stream = Lexer.lex(string, @name, @tags)
- @ast = do_parse
- rescue Liquor::SyntaxError => e
- @errors << e
- end
-
- success?
- end
-
- def next_token
- tok = @stream.shift
- [ tok[0], tok ] if tok
- end
-
- TOKEN_NAME_MAP = {
- :comma => ',',
- :dot => '.',
- :lblock => '{%',
- :rblock => '%}',
- :linterp => '{{',
- :rinterp => '}}',
- :lbracket => '[',
- :rbracket => ']',
- :lparen => '(',
- :rparen => ')',
- :pipe => '|',
- :op_not => '!',
- :op_mul => '*',
- :op_div => '/',
- :op_mod => '%',
- :op_plus => '+',
- :op_minus => '-',
- :op_eq => '==',
- :op_neq => '!=',
- :op_lt => '<',
- :op_leq => '<=',
- :op_gt => '>',
- :op_geq => '>=',
- :keyword => 'keyword argument name',
- :kwarg => 'keyword argument',
- :ident => 'identifier',
- }
-
- def on_error(error_token_id, error_token, value_stack)
- if token_to_str(error_token_id) == "$end"
- raise Liquor::SyntaxError.new("unexpected end of program", {
- file: @name
- })
- else
- type, (loc, value) = error_token
- type = TOKEN_NAME_MAP[type] || type
-
- raise Liquor::SyntaxError.new("unexpected token `#{type}'", loc)
- end
- end
-
- def retag(nodes)
- loc = nodes.map { |node| node[1] }.compact
- first, *, last = loc
- return first if last.nil?
-
- {
- file: first[:file],
- line: first[:line],
- start: first[:start],
- end: last[:end],
- }
- end
-
- def reduce_tag_args(list)
- list.each_slice(2).reduce([]) { |args, (k, v)|
- if v[0] == :block
- args << [ :blockarg, retag([ k, v ]), k, v[2] || [] ]
- else
- args << [ :kwarg, retag([ k, v ]), k, v ]
- end
- }
- end \ No newline at end of file
diff --git a/test/racc/assets/machete.y b/test/racc/assets/machete.y
deleted file mode 100644
index ea92d47a69..0000000000
--- a/test/racc/assets/machete.y
+++ /dev/null
@@ -1,423 +0,0 @@
-# Copyright (c) 2011 SUSE
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation
-# files (the "Software"), to deal in the Software without
-# restriction, including without limitation the rights to use,
-# copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following
-# conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
-
-class Machete::Parser
-
-token NIL
-token TRUE
-token FALSE
-token INTEGER
-token SYMBOL
-token STRING
-token REGEXP
-token ANY
-token EVEN
-token ODD
-token METHOD_NAME
-token CLASS_NAME
-
-start expression
-
-rule
-
-expression : primary
- | expression "|" primary {
- result = if val[0].is_a?(ChoiceMatcher)
- ChoiceMatcher.new(val[0].alternatives << val[2])
- else
- ChoiceMatcher.new([val[0], val[2]])
- end
- }
-
-primary : node
- | array
- | literal
- | any
-
-node : CLASS_NAME {
- result = NodeMatcher.new(val[0].to_sym)
- }
- | CLASS_NAME "<" attrs ">" {
- result = NodeMatcher.new(val[0].to_sym, val[2])
- }
-
-attrs : attr
- | attrs "," attr { result = val[0].merge(val[2]) }
-
-attr : method_name "=" expression { result = { val[0].to_sym => val[2] } }
- | method_name "^=" SYMBOL {
- result = {
- val[0].to_sym => SymbolRegexpMatcher.new(
- Regexp.new("^" + Regexp.escape(symbol_value(val[2]).to_s))
- )
- }
- }
- | method_name "$=" SYMBOL {
- result = {
- val[0].to_sym => SymbolRegexpMatcher.new(
- Regexp.new(Regexp.escape(symbol_value(val[2]).to_s) + "$")
- )
- }
- }
- | method_name "*=" SYMBOL {
- result = {
- val[0].to_sym => SymbolRegexpMatcher.new(
- Regexp.new(Regexp.escape(symbol_value(val[2]).to_s))
- )
- }
- }
- | method_name "^=" STRING {
- result = {
- val[0].to_sym => StringRegexpMatcher.new(
- Regexp.new("^" + Regexp.escape(string_value(val[2])))
- )
- }
- }
- | method_name "$=" STRING {
- result = {
- val[0].to_sym => StringRegexpMatcher.new(
- Regexp.new(Regexp.escape(string_value(val[2])) + "$")
- )
- }
- }
- | method_name "*=" STRING {
- result = {
- val[0].to_sym => StringRegexpMatcher.new(
- Regexp.new(Regexp.escape(string_value(val[2])))
- )
- }
- }
- | method_name "*=" REGEXP {
- result = {
- val[0].to_sym => IndifferentRegexpMatcher.new(
- Regexp.new(regexp_value(val[2]))
- )
- }
- }
-
-# Hack to overcome the fact that some tokens will lex as simple tokens, not
-# METHOD_NAME tokens, and that "reserved words" will lex as separate kinds of
-# tokens.
-method_name : METHOD_NAME
- | NIL
- | TRUE
- | FALSE
- | ANY
- | EVEN
- | ODD
- | "*"
- | "+"
- | "<"
- | ">"
- | "^"
- | "|"
-
-array : "[" items_opt "]" { result = ArrayMatcher.new(val[1]) }
-
-items_opt : /* empty */ { result = [] }
- | items
-
-items : item { result = [val[0]] }
- | items "," item { result = val[0] << val[2] }
-
-item : expression
- | expression quantifier { result = Quantifier.new(val[0], *val[1]) }
-
-quantifier : "*" { result = [0, nil, 1] }
- | "+" { result = [1, nil, 1] }
- | "?" { result = [0, 1, 1] }
- | "{" INTEGER "}" {
- result = [integer_value(val[1]), integer_value(val[1]), 1]
- }
- | "{" INTEGER "," "}" {
- result = [integer_value(val[1]), nil, 1]
- }
- | "{" "," INTEGER "}" {
- result = [0, integer_value(val[2]), 1]
- }
- | "{" INTEGER "," INTEGER "}" {
- result = [integer_value(val[1]), integer_value(val[3]), 1]
- }
- | "{" EVEN "}" { result = [0, nil, 2] }
- | "{" ODD "}" { result = [1, nil, 2] }
-
-literal : NIL { result = LiteralMatcher.new(nil) }
- | TRUE { result = LiteralMatcher.new(true) }
- | FALSE { result = LiteralMatcher.new(false) }
- | INTEGER { result = LiteralMatcher.new(integer_value(val[0])) }
- | SYMBOL { result = LiteralMatcher.new(symbol_value(val[0])) }
- | STRING { result = LiteralMatcher.new(string_value(val[0])) }
- | REGEXP { result = LiteralMatcher.new(regexp_value(val[0])) }
-
-any : ANY { result = AnyMatcher.new }
-
----- inner
-
-include Matchers
-
-class SyntaxError < StandardError; end
-
-def parse(input)
- @input = input
- @pos = 0
-
- do_parse
-end
-
-private
-
-def integer_value(value)
- if value =~ /^0[bB]/
- value[2..-1].to_i(2)
- elsif value =~ /^0[oO]/
- value[2..-1].to_i(8)
- elsif value =~ /^0[dD]/
- value[2..-1].to_i(10)
- elsif value =~ /^0[xX]/
- value[2..-1].to_i(16)
- elsif value =~ /^0/
- value.to_i(8)
- else
- value.to_i
- end
-end
-
-def symbol_value(value)
- value[1..-1].to_sym
-end
-
-def string_value(value)
- quote = value[0..0]
- if quote == "'"
- value[1..-2].gsub("\\\\", "\\").gsub("\\'", "'")
- elsif quote == '"'
- value[1..-2].
- gsub("\\\\", "\\").
- gsub('\\"', '"').
- gsub("\\n", "\n").
- gsub("\\t", "\t").
- gsub("\\r", "\r").
- gsub("\\f", "\f").
- gsub("\\v", "\v").
- gsub("\\a", "\a").
- gsub("\\e", "\e").
- gsub("\\b", "\b").
- gsub("\\s", "\s").
- gsub(/\\([0-7]{1,3})/) { $1.to_i(8).chr }.
- gsub(/\\x([0-9a-fA-F]{1,2})/) { $1.to_i(16).chr }
- else
- raise "Unknown quote: #{quote.inspect}."
- end
-end
-
-REGEXP_OPTIONS = {
- 'i' => Regexp::IGNORECASE,
- 'm' => Regexp::MULTILINE,
- 'x' => Regexp::EXTENDED
-}
-
-def regexp_value(value)
- /\A\/(.*)\/([imx]*)\z/ =~ value
- pattern, options = $1, $2
-
- Regexp.new(pattern, options.chars.map { |ch| REGEXP_OPTIONS[ch] }.inject(:|))
-end
-
-# "^" needs to be here because if it were among operators recognized by
-# METHOD_NAME, "^=" would be recognized as two tokens.
-SIMPLE_TOKENS = [
- "|",
- "<",
- ">",
- ",",
- "=",
- "^=",
- "^",
- "$=",
- "[",
- "]",
- "*=",
- "*",
- "+",
- "?",
- "{",
- "}"
-]
-
-COMPLEX_TOKENS = [
- [:NIL, /^nil/],
- [:TRUE, /^true/],
- [:FALSE, /^false/],
- # INTEGER needs to be before METHOD_NAME, otherwise e.g. "+1" would be
- # recognized as two tokens.
- [
- :INTEGER,
- /^
- [+-]? # sign
- (
- 0[bB][01]+(_[01]+)* # binary (prefixed)
- |
- 0[oO][0-7]+(_[0-7]+)* # octal (prefixed)
- |
- 0[dD]\d+(_\d+)* # decimal (prefixed)
- |
- 0[xX][0-9a-fA-F]+(_[0-9a-fA-F]+)* # hexadecimal (prefixed)
- |
- 0[0-7]*(_[0-7]+)* # octal (unprefixed)
- |
- [1-9]\d*(_\d+)* # decimal (unprefixed)
- )
- /x
- ],
- [
- :SYMBOL,
- /^
- :
- (
- # class name
- [A-Z][a-zA-Z0-9_]*
- |
- # regular method name
- [a-z_][a-zA-Z0-9_]*[?!=]?
- |
- # instance variable name
- @[a-zA-Z_][a-zA-Z0-9_]*
- |
- # class variable name
- @@[a-zA-Z_][a-zA-Z0-9_]*
- |
- # operator (sorted by length, then alphabetically)
- (<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&*+\-\/<>^`|~])
- )
- /x
- ],
- [
- :STRING,
- /^
- (
- ' # sinqle-quoted string
- (
- \\[\\'] # escape
- |
- [^'] # regular character
- )*
- '
- |
- " # double-quoted string
- (
- \\ # escape
- (
- [\\"ntrfvaebs] # one-character escape
- |
- [0-7]{1,3} # octal number escape
- |
- x[0-9a-fA-F]{1,2} # hexadecimal number escape
- )
- |
- [^"] # regular character
- )*
- "
- )
- /x
- ],
- [
- :REGEXP,
- /^
- \/
- (
- \\ # escape
- (
- [\\\/ntrfvaebs\(\)\[\]\{\}\-\.\?\*\+\|\^\$] # one-character escape
- |
- [0-7]{2,3} # octal number escape
- |
- x[0-9a-fA-F]{1,2} # hexadecimal number escape
- )
- |
- [^\/] # regular character
- )*
- \/
- [imx]*
- /x
- ],
- # ANY, EVEN and ODD need to be before METHOD_NAME, otherwise they would be
- # recognized as method names.
- [:ANY, /^any/],
- [:EVEN, /^even/],
- [:ODD, /^odd/],
- # We exclude "*", "+", "<", ">", "^" and "|" from method names since they are
- # lexed as simple tokens. This is because they have also other meanings in
- # Machette patterns beside Ruby method names.
- [
- :METHOD_NAME,
- /^
- (
- # regular name
- [a-z_][a-zA-Z0-9_]*[?!=]?
- |
- # operator (sorted by length, then alphabetically)
- (<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&\-\/`~])
- )
- /x
- ],
- [:CLASS_NAME, /^[A-Z][a-zA-Z0-9_]*/]
-]
-
-def next_token
- skip_whitespace
-
- return false if remaining_input.empty?
-
- # Complex tokens need to be before simple tokens, otherwise e.g. "<<" would be
- # recognized as two tokens.
-
- COMPLEX_TOKENS.each do |type, regexp|
- if remaining_input =~ regexp
- @pos += $&.length
- return [type, $&]
- end
- end
-
- SIMPLE_TOKENS.each do |token|
- if remaining_input[0...token.length] == token
- @pos += token.length
- return [token, token]
- end
- end
-
- raise SyntaxError, "Unexpected character: #{remaining_input[0..0].inspect}."
-end
-
-def skip_whitespace
- if remaining_input =~ /\A^[ \t\r\n]+/
- @pos += $&.length
- end
-end
-
-def remaining_input
- @input[@pos..-1]
-end
-
-def on_error(error_token_id, error_value, value_stack)
- raise SyntaxError, "Unexpected token: #{error_value.inspect}."
-end
diff --git a/test/racc/assets/macruby.y b/test/racc/assets/macruby.y
deleted file mode 100644
index 5ede008308..0000000000
--- a/test/racc/assets/macruby.y
+++ /dev/null
@@ -1,2197 +0,0 @@
-# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org>
-#
-# Parts of the source are derived from ruby_parser:
-# Copyright (c) Ryan Davis, seattle.rb
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Parser::MacRuby
-
-token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
- kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
- kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
- kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
- kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
- k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
- tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
- tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
- tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
- tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
- tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
- tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
- tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
- tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
- tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
- tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG
- tCHARACTER
-
-prechigh
- right tBANG tTILDE tUPLUS
- right tPOW
- right tUMINUS_NUM tUMINUS
- left tSTAR2 tDIVIDE tPERCENT
- left tPLUS tMINUS
- left tLSHFT tRSHFT
- left tAMPER2
- left tPIPE tCARET
- left tGT tGEQ tLT tLEQ
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
- left tANDOP
- left tOROP
- nonassoc tDOT2 tDOT3
- right tEH tCOLON
- left kRESCUE_MOD
- right tEQL tOP_ASGN
- nonassoc kDEFINED
- right kNOT
- left kOR kAND
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
- nonassoc tLBRACE_ARG
- nonassoc tLOWEST
-preclow
-
-rule
-
- program: top_compstmt
-
- top_compstmt: top_stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- top_stmts: # nothing
- {
- result = []
- }
- | top_stmt
- {
- result = [ val[0] ]
- }
- | top_stmts terms top_stmt
- {
- result = val[0] << val[2]
- }
- | error top_stmt
- {
- result = [ val[1] ]
- }
-
- top_stmt: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- result = @builder.preexe(val[0], val[1], val[2], val[3])
- }
-
- bodystmt: compstmt opt_rescue opt_else opt_ensure
- {
- rescue_bodies = val[1]
- else_t, else_ = val[2]
- ensure_t, ensure_ = val[3]
-
- if rescue_bodies.empty? && !else_.nil?
- diagnostic :warning, :useless_else, nil, else_t
- end
-
- result = @builder.begin_body(val[0],
- rescue_bodies,
- else_t, else_,
- ensure_t, ensure_)
- }
-
- compstmt: stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- stmts: # nothing
- {
- result = []
- }
- | stmt
- {
- result = [ val[0] ]
- }
- | stmts terms stmt
- {
- result = val[0] << val[2]
- }
- | error stmt
- {
- result = [ val[1] ]
- }
-
- stmt: kALIAS fitem
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = @builder.alias(val[0], val[1], val[3])
- }
- | kALIAS tGVAR tGVAR
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.gvar(val[2]))
- }
- | kALIAS tGVAR tBACK_REF
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.back_ref(val[2]))
- }
- | kALIAS tGVAR tNTH_REF
- {
- diagnostic :error, :nth_ref_alias, nil, val[2]
- }
- | kUNDEF undef_list
- {
- result = @builder.undef_method(val[0], val[1])
- }
- | stmt kIF_MOD expr_value
- {
- result = @builder.condition_mod(val[0], nil,
- val[1], val[2])
- }
- | stmt kUNLESS_MOD expr_value
- {
- result = @builder.condition_mod(nil, val[0],
- val[1], val[2])
- }
- | stmt kWHILE_MOD expr_value
- {
- result = @builder.loop_mod(:while, val[0], val[1], val[2])
- }
- | stmt kUNTIL_MOD expr_value
- {
- result = @builder.loop_mod(:until, val[0], val[1], val[2])
- }
- | stmt kRESCUE_MOD stmt
- {
- rescue_body = @builder.rescue_body(val[1],
- nil, nil, nil,
- nil, val[2])
-
- result = @builder.begin_body(val[0], [ rescue_body ])
- }
- | klEND tLCURLY compstmt tRCURLY
- {
- result = @builder.postexe(val[0], val[1], val[2], val[3])
- }
- | lhs tEQL command_call
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | mlhs tEQL command_call
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN command_call
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | backref tOP_ASGN command_call
- {
- @builder.op_assign(val[0], val[1], val[2])
- }
- | lhs tEQL mrhs
- {
- result = @builder.assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | mlhs tEQL arg_value
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | mlhs tEQL mrhs
- {
- result = @builder.multi_assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | expr
-
- expr: command_call
- | expr kAND expr
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | expr kOR expr
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kNOT opt_nl expr
- {
- result = @builder.not_op(val[0], nil, val[2], nil)
- }
- | tBANG command_call
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | arg
-
- expr_value: expr
-
- command_call: command
- | block_command
-
- block_command: block_call
- | block_call tDOT operation2 command_args
- {
- result = @builder.call_method(val[0], val[1], val[2],
- *val[3])
- }
- | block_call tCOLON2 operation2 command_args
- {
- result = @builder.call_method(val[0], val[1], val[2],
- *val[3])
- }
-
- cmd_brace_block: tLBRACE_ARG
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- command: operation command_args =tLOWEST
- {
- result = @builder.call_method(nil, nil, val[0],
- *val[1])
- }
- | operation command_args cmd_brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0],
- *val[1])
-
- begin_t, args, body, end_t = val[2]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tDOT operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- *val[3])
- }
- | primary_value tDOT operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- *val[3])
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tCOLON2 operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- *val[3])
- }
- | primary_value tCOLON2 operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- *val[3])
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | kSUPER command_args
- {
- result = @builder.keyword_cmd(:super, val[0],
- *val[1])
- }
- | kYIELD command_args
- {
- result = @builder.keyword_cmd(:yield, val[0],
- *val[1])
- }
- | kRETURN call_args
- {
- result = @builder.keyword_cmd(:return, val[0],
- nil, val[1], nil)
- }
- | kBREAK call_args
- {
- result = @builder.keyword_cmd(:break, val[0],
- nil, val[1], nil)
- }
- | kNEXT call_args
- {
- result = @builder.keyword_cmd(:next, val[0],
- nil, val[1], nil)
- }
-
- mlhs: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_inner: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- mlhs_basic: mlhs_head
- | mlhs_head mlhs_item
- {
- result = val[0].
- push(val[1])
- }
- | mlhs_head tSTAR mlhs_node
- {
- result = val[0].
- push(@builder.splat(val[1], val[2]))
- }
- | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1], val[2])).
- concat(val[4])
- }
- | mlhs_head tSTAR
- {
- result = val[0].
- push(@builder.splat(val[1]))
- }
- | mlhs_head tSTAR tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1])).
- concat(val[3])
- }
- | tSTAR mlhs_node
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.splat(val[0]) ]
- }
- | tSTAR tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0]),
- *val[2] ]
- }
-
- mlhs_item: mlhs_node
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_head: mlhs_item tCOMMA
- {
- result = [ val[0] ]
- }
- | mlhs_head mlhs_item tCOMMA
- {
- result = val[0] << val[1]
- }
-
- mlhs_post: mlhs_item
- {
- result = [ val[0] ]
- }
- | mlhs_post tCOMMA mlhs_item
- {
- result = val[0] << val[2]
- }
-
- mlhs_node: variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- lhs: variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- cname: tIDENTIFIER
- {
- diagnostic :error, :module_name_const, nil, val[0]
- }
- | tCONSTANT
-
- cpath: tCOLON3 cname
- {
- result = @builder.const_global(val[0], val[1])
- }
- | cname
- {
- result = @builder.const(val[0])
- }
- | primary_value tCOLON2 cname
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
-
- fname: tIDENTIFIER | tCONSTANT | tFID
- | op
- | reswords
-
- fsym: fname
- {
- result = @builder.symbol(val[0])
- }
- | symbol
-
- fitem: fsym
- | dsym
-
- undef_list: fitem
- {
- result = [ val[0] ]
- }
- | undef_list tCOMMA
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = val[0] << val[3]
- }
-
- op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
- | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
- | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
- | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
- | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
-
- reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
- | kALIAS | kAND | kBEGIN | kBREAK | kCASE
- | kCLASS | kDEF | kDEFINED | kDO | kELSE
- | kELSIF | kEND | kENSURE | kFALSE | kFOR
- | kIN | kMODULE | kNEXT | kNIL | kNOT
- | kOR | kREDO | kRESCUE | kRETRY | kRETURN
- | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
- | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
- | kUNTIL
-
- arg: lhs tEQL arg
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.assign(val[0], val[1], rescue_)
- }
- | var_lhs tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.op_assign(val[0], val[1], rescue_)
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
- {
- diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
- }
- | tCOLON3 tCONSTANT tOP_ASGN arg
- {
- diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
- }
- | backref tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | arg tDOT2 arg
- {
- result = @builder.range_inclusive(val[0], val[1], val[2])
- }
- | arg tDOT3 arg
- {
- result = @builder.range_exclusive(val[0], val[1], val[2])
- }
- | arg tPLUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMINUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tSTAR2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tDIVIDE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPERCENT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPOW arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tUMINUS_NUM tINTEGER tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.integer(val[1]),
- val[2], val[3]))
- }
- | tUMINUS_NUM tFLOAT tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.float(val[1]),
- val[2], val[3]))
- }
- | tUPLUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | tUMINUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tPIPE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCARET arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tAMPER2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCMP arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tNEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMATCH arg
- {
- result = @builder.match_op(val[0], val[1], val[2])
- }
- | arg tNMATCH arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tBANG arg
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | tTILDE arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tLSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tRSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tANDOP arg
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | arg tOROP arg
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kDEFINED opt_nl arg
- {
- result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
- }
-
- | arg tEH arg opt_nl tCOLON arg
- {
- result = @builder.ternary(val[0], val[1],
- val[2], val[4], val[5])
- }
- | primary
-
- arg_value: arg
-
- aref_args: none
- | args trailer
- | args tCOMMA assocs trailer
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs trailer
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- paren_args: tLPAREN2 opt_call_args rparen
- {
- result = val
- }
-
- opt_paren_args: # nothing
- {
- result = [ nil, [], nil ]
- }
- | paren_args
-
- opt_call_args: # nothing
- {
- result = []
- }
- | call_args
-
- call_args: command
- {
- result = [ val[0] ]
- }
- | args opt_block_arg
- {
- result = val[0].concat(val[1])
- }
- | assocs opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- result.concat(val[1])
- }
- | args tCOMMA assocs opt_block_arg
- {
- assocs = @builder.associate(nil, val[2], nil)
- result = val[0] << assocs
- result.concat(val[3])
- }
- | args tCOMMA assocs tCOMMA args opt_block_arg
- {
- val[2][-1] = @builder.objc_varargs(val[2][-1], val[4])
- assocs = @builder.associate(nil, val[2], nil)
- result = val[0] << assocs
- result.concat(val[5])
- }
- | block_arg
- {
- result = [ val[0] ]
- }
-
- call_args2: arg_value tCOMMA args opt_block_arg
- {
- result = [ val[0], *val[2].concat(val[3]) ]
- }
- | arg_value tCOMMA block_arg
- {
- result = [ val[0], val[2] ]
- }
- | assocs opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil),
- *val[1] ]
- }
- | arg_value tCOMMA assocs opt_block_arg
- {
- result = [ val[0],
- @builder.associate(nil, val[2], nil),
- *val[3] ]
- }
- | arg_value tCOMMA args tCOMMA assocs opt_block_arg
- {
- result = [ val[0],
- *val[2].
- push(@builder.associate(nil, val[4], nil)).
- concat(val[5]) ]
- }
- | block_arg
- {
- result = [ val[0] ]
- }
-
- command_args: {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.push(true)
- }
- open_args
- {
- @lexer.cmdarg = val[0]
-
- result = val[1]
- }
-
- open_args: call_args
- {
- result = [ nil, val[0], nil ]
- }
- | tLPAREN_ARG
- {
- @lexer.state = :expr_endarg
- }
- rparen
- {
- result = [ val[0], [], val[2] ]
- }
- | tLPAREN_ARG call_args2
- {
- @lexer.state = :expr_endarg
- }
- rparen
- {
- result = [ val[0], val[1], val[3] ]
- }
-
- block_arg: tAMPER arg_value
- {
- result = @builder.block_pass(val[0], val[1])
- }
-
- opt_block_arg: tCOMMA block_arg
- {
- result = [ val[1] ]
- }
- | tCOMMA
- {
- result = []
- }
- | # nothing
- {
- result = []
- }
-
- args: arg_value
- {
- result = [ val[0] ]
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
-
- mrhs: args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
-
- primary: literal
- | strings
- | xstring
- | regexp
- | words
- | qwords
- | var_ref
- | backref
- | tFID
- {
- result = @builder.call_method(nil, nil, val[0])
- }
- | kBEGIN bodystmt kEND
- {
- result = @builder.begin_keyword(val[0], val[1], val[2])
- }
- | tLPAREN_ARG expr
- {
- @lexer.state = :expr_endarg
- }
- rparen
- {
- result = @builder.begin(val[0], val[1], val[3])
- }
- | tLPAREN compstmt tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.const_global(val[0], val[1])
- }
- | tLBRACK aref_args tRBRACK
- {
- result = @builder.array(val[0], val[1], val[2])
- }
- | tLBRACE assoc_list tRCURLY
- {
- result = @builder.associate(val[0], val[1], val[2])
- }
- | kRETURN
- {
- result = @builder.keyword_cmd(:return, val[0])
- }
- | kYIELD tLPAREN2 call_args rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
- }
- | kYIELD tLPAREN2 rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
- }
- | kYIELD
- {
- result = @builder.keyword_cmd(:yield, val[0])
- }
- | kDEFINED opt_nl tLPAREN2 expr rparen
- {
- result = @builder.keyword_cmd(:defined?, val[0],
- val[2], [ val[3] ], val[4])
- }
- | kNOT tLPAREN2 expr rparen
- {
- result = @builder.not_op(val[0], val[1], val[2], val[3])
- }
- | kNOT tLPAREN2 rparen
- {
- result = @builder.not_op(val[0], val[1], nil, val[2])
- }
- | operation brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0])
-
- begin_t, args, body, end_t = val[1]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | method_call
- | method_call brace_block
- {
- begin_t, args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, args, body, end_t)
- }
- | tLAMBDA lambda
- {
- lambda_call = @builder.call_lambda(val[0])
-
- args, (begin_t, body, end_t) = val[1]
- result = @builder.block(lambda_call,
- begin_t, args, body, end_t)
- }
- | kIF expr_value then compstmt if_tail kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, val[5])
- }
- | kUNLESS expr_value then compstmt opt_else kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- else_, else_t,
- val[3], val[5])
- }
- | kWHILE
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:while, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kUNTIL
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:until, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kCASE expr_value opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[3]
-
- result = @builder.case(val[0], val[1],
- when_bodies, else_t, else_body,
- val[4])
- }
- | kCASE opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[2]
-
- result = @builder.case(val[0], nil,
- when_bodies, else_t, else_body,
- val[3])
- }
- | kFOR for_var kIN
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.for(val[0], val[1],
- val[2], val[4],
- val[5], val[7], val[8])
- }
- | kCLASS cpath superclass
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :class_in_def, nil, val[0]
- end
-
- lt_t, superclass = val[2]
- result = @builder.def_class(val[0], val[1],
- lt_t, superclass,
- val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kCLASS tLSHFT expr term
- {
- result = @def_level
- @def_level = 0
-
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- result = @builder.def_sclass(val[0], val[1], val[2],
- val[5], val[6])
-
- @lexer.pop_cmdarg
- @static_env.unextend
-
- @def_level = val[4]
- }
- | kMODULE cpath
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :module_in_def, nil, val[0]
- end
-
- result = @builder.def_module(val[0], val[1],
- val[3], val[4])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kDEF fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_method(val[0], val[1],
- val[3], val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kDEF singleton dot_or_colon
- {
- @lexer.state = :expr_fname
- }
- fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_singleton(val[0], val[1], val[2],
- val[4], val[6], val[7], val[8])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kBREAK
- {
- result = @builder.keyword_cmd(:break, val[0])
- }
- | kNEXT
- {
- result = @builder.keyword_cmd(:next, val[0])
- }
- | kREDO
- {
- result = @builder.keyword_cmd(:redo, val[0])
- }
- | kRETRY
- {
- result = @builder.keyword_cmd(:retry, val[0])
- }
-
- primary_value: primary
-
- then: term
- | kTHEN
- | term kTHEN
- {
- result = val[1]
- }
-
- do: term
- | kDO_COND
-
- if_tail: opt_else
- | kELSIF expr_value then compstmt if_tail
- {
- else_t, else_ = val[4]
- result = [ val[0],
- @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, nil),
- ]
- }
-
- opt_else: none
- | kELSE compstmt
- {
- result = val
- }
-
- for_var: lhs
- | mlhs
-
- f_marg: f_norm_arg
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_marg_list: f_marg
- {
- result = [ val[0] ]
- }
- | f_marg_list tCOMMA f_marg
- {
- result = val[0] << val[2]
- }
-
- f_margs: f_marg_list
- | f_marg_list tCOMMA tSTAR f_norm_arg
- {
- result = val[0].
- push(@builder.objc_restarg(val[2], val[3]))
- }
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
- {
- result = val[0].
- push(@builder.objc_restarg(val[2], val[3])).
- concat(val[5])
- }
- | f_marg_list tCOMMA tSTAR
- {
- result = val[0].
- push(@builder.objc_restarg(val[2]))
- }
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
- {
- result = val[0].
- push(@builder.objc_restarg(val[2])).
- concat(val[4])
- }
- | tSTAR f_norm_arg
- {
- result = [ @builder.objc_restarg(val[0], val[1]) ]
- }
- | tSTAR f_norm_arg tCOMMA f_marg_list
- {
- result = [ @builder.objc_restarg(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.objc_restarg(val[0]) ]
- }
- | tSTAR tCOMMA f_marg_list
- {
- result = [ @builder.objc_restarg(val[0]),
- *val[2] ]
- }
-
- block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_block_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_block_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_block_optarg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
-
- opt_block_param: # nothing
- {
- result = @builder.args(nil, [], nil)
- }
- | block_param_def
- {
- @lexer.state = :expr_value
- }
-
- block_param_def: tPIPE opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1], val[2])
- }
- | tOROP
- {
- result = @builder.args(val[0], [], val[0])
- }
- | tPIPE block_param opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
-
- opt_bv_decl: # nothing
- {
- result = []
- }
- | tSEMI bv_decls
- {
- result = val[1]
- }
-
- bv_decls: bvar
- {
- result = [ val[0] ]
- }
- | bv_decls tCOMMA bvar
- {
- result = val[0] << val[2]
- }
-
- bvar: tIDENTIFIER
- {
- result = @builder.shadowarg(val[0])
- }
- | f_bad_arg
-
- lambda: {
- @static_env.extend_dynamic
- }
- f_larglist lambda_body
- {
- result = [ val[1], val[2] ]
-
- @static_env.unextend
- }
-
- f_larglist: tLPAREN2 f_args opt_bv_decl rparen
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
- | f_args
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- lambda_body: tLAMBEG compstmt tRCURLY
- {
- result = [ val[0], val[1], val[2] ]
- }
- | kDO_LAMBDA compstmt kEND
- {
- result = [ val[0], val[1], val[2] ]
- }
-
- do_block: kDO_BLOCK
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- block_call: command do_block
- {
- begin_t, block_args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, block_args, body, end_t)
- }
- | block_call tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | block_call tCOLON2 operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
-
- method_call: operation paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
- }
- | primary_value tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation2 paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation3
- {
- result = @builder.call_method(val[0], val[1], val[2])
- }
- | primary_value tDOT paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | kSUPER paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
- }
- | kSUPER
- {
- result = @builder.keyword_cmd(:zsuper, val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index(val[0], val[1], val[2], val[3])
- }
-
- brace_block: tLCURLY
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
- | kDO
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- case_body: kWHEN args then compstmt cases
- {
- result = [ @builder.when(val[0], val[1], val[2], val[3]),
- *val[4] ]
- }
-
- cases: opt_else
- {
- result = [ val[0] ]
- }
- | case_body
-
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
- {
- assoc_t, exc_var = val[2]
-
- if val[1]
- exc_list = @builder.array(nil, val[1], nil)
- end
-
- result = [ @builder.rescue_body(val[0],
- exc_list, assoc_t, exc_var,
- val[3], val[4]),
- *val[5] ]
- }
- |
- {
- result = []
- }
-
- exc_list: arg_value
- {
- result = [ val[0] ]
- }
- | mrhs
- | none
-
- exc_var: tASSOC lhs
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- opt_ensure: kENSURE compstmt
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- literal: numeric
- | symbol
- | dsym
-
- strings: string
- {
- result = @builder.string_compose(nil, val[0], nil)
- }
-
- string: string1
- {
- result = [ val[0] ]
- }
- | string string1
- {
- result = val[0] << val[1]
- }
-
- string1: tSTRING_BEG string_contents tSTRING_END
- {
- result = @builder.string_compose(val[0], val[1], val[2])
- }
- | tSTRING
- {
- result = @builder.string(val[0])
- }
- | tCHARACTER
- {
- result = @builder.character(val[0])
- }
-
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
- {
- result = @builder.xstring_compose(val[0], val[1], val[2])
- }
-
- regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
- {
- opts = @builder.regexp_options(val[3])
- result = @builder.regexp_compose(val[0], val[1], val[2], opts)
- }
-
- words: tWORDS_BEG word_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- word_list: # nothing
- {
- result = []
- }
- | word_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- word: string_content
- {
- result = [ val[0] ]
- }
- | word string_content
- {
- result = val[0] << val[1]
- }
-
- qwords: tQWORDS_BEG qword_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- qword_list: # nothing
- {
- result = []
- }
- | qword_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.string_internal(val[1])
- }
-
- string_contents: # nothing
- {
- result = []
- }
- | string_contents string_content
- {
- result = val[0] << val[1]
- }
-
-xstring_contents: # nothing
- {
- result = []
- }
- | xstring_contents string_content
- {
- result = val[0] << val[1]
- }
-
-regexp_contents: # nothing
- {
- result = []
- }
- | regexp_contents string_content
- {
- result = val[0] << val[1]
- }
-
- string_content: tSTRING_CONTENT
- {
- result = @builder.string_internal(val[0])
- }
- | tSTRING_DVAR string_dvar
- {
- result = val[1]
- }
- | tSTRING_DBEG
- {
- @lexer.cond.push(false)
- @lexer.cmdarg.push(false)
- }
- compstmt tRCURLY
- {
- @lexer.cond.lexpop
- @lexer.cmdarg.lexpop
-
- result = @builder.begin(val[0], val[2], val[3])
- }
-
- string_dvar: tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
- | backref
-
-
- symbol: tSYMBOL
- {
- result = @builder.symbol(val[0])
- }
-
- dsym: tSYMBEG xstring_contents tSTRING_END
- {
- result = @builder.symbol_compose(val[0], val[1], val[2])
- }
-
- numeric: tINTEGER
- {
- result = @builder.integer(val[0])
- }
- | tFLOAT
- {
- result = @builder.float(val[0])
- }
- | tUMINUS_NUM tINTEGER =tLOWEST
- {
- result = @builder.negate(val[0],
- @builder.integer(val[1]))
- }
- | tUMINUS_NUM tFLOAT =tLOWEST
- {
- result = @builder.negate(val[0],
- @builder.float(val[1]))
- }
-
- variable: tIDENTIFIER
- {
- result = @builder.ident(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tCONSTANT
- {
- result = @builder.const(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
- | kNIL
- {
- result = @builder.nil(val[0])
- }
- | kSELF
- {
- result = @builder.self(val[0])
- }
- | kTRUE
- {
- result = @builder.true(val[0])
- }
- | kFALSE
- {
- result = @builder.false(val[0])
- }
- | k__FILE__
- {
- result = @builder.__FILE__(val[0])
- }
- | k__LINE__
- {
- result = @builder.__LINE__(val[0])
- }
- | k__ENCODING__
- {
- result = @builder.__ENCODING__(val[0])
- }
-
- var_ref: variable
- {
- result = @builder.accessible(val[0])
- }
-
- var_lhs: variable
- {
- result = @builder.assignable(val[0])
- }
-
- backref: tNTH_REF
- {
- result = @builder.nth_ref(val[0])
- }
- | tBACK_REF
- {
- result = @builder.back_ref(val[0])
- }
-
- superclass: term
- {
- result = nil
- }
- | tLT expr_value term
- {
- result = [ val[0], val[1] ]
- }
- | error term
- {
- yyerrok
- result = nil
- }
-
- f_arglist: tLPAREN2 f_args rparen
- {
- result = @builder.args(val[0], val[1], val[2])
-
- @lexer.state = :expr_value
- }
- | f_args term
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
- | # nothing
- {
- result = []
- }
-
- f_bad_arg: tCONSTANT
- {
- diagnostic :error, :argument_const, nil, val[0]
- }
- | tIVAR
- {
- diagnostic :error, :argument_ivar, nil, val[0]
- }
- | tGVAR
- {
- diagnostic :error, :argument_gvar, nil, val[0]
- }
- | tCVAR
- {
- diagnostic :error, :argument_cvar, nil, val[0]
- }
-
- f_norm_arg: f_bad_arg
- | tIDENTIFIER
- {
- @static_env.declare val[0][0]
-
- result = @builder.arg(val[0])
- }
- | tIDENTIFIER tASSOC tIDENTIFIER
- {
- @static_env.declare val[2][0]
-
- result = @builder.objc_kwarg(val[0], val[1], val[2])
- }
- | tLABEL tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = @builder.objc_kwarg(val[0], nil, val[1])
- }
-
- f_arg_item: f_norm_arg
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_arg: f_arg_item
- {
- result = [ val[0] ]
- }
- | f_arg tCOMMA f_arg_item
- {
- result = val[0] << val[2]
- }
-
- f_opt: tIDENTIFIER tEQL arg_value
- {
- @static_env.declare val[0][0]
-
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_opt: tIDENTIFIER tEQL primary_value
- {
- @static_env.declare val[0][0]
-
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_optarg: f_block_opt
- {
- result = [ val[0] ]
- }
- | f_block_optarg tCOMMA f_block_opt
- {
- result = val[0] << val[2]
- }
-
- f_optarg: f_opt
- {
- result = [ val[0] ]
- }
- | f_optarg tCOMMA f_opt
- {
- result = val[0] << val[2]
- }
-
- restarg_mark: tSTAR2 | tSTAR
-
- f_rest_arg: restarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | restarg_mark
- {
- result = [ @builder.restarg(val[0]) ]
- }
-
- blkarg_mark: tAMPER2 | tAMPER
-
- f_block_arg: blkarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = @builder.blockarg(val[0], val[1])
- }
-
- opt_f_block_arg: tCOMMA f_block_arg
- {
- result = [ val[1] ]
- }
- | # nothing
- {
- result = []
- }
-
- singleton: var_ref
- | tLPAREN2 expr rparen
- {
- result = val[1]
- }
-
- assoc_list: # nothing
- {
- result = []
- }
- | assocs trailer
-
- assocs: assoc
- {
- result = [ val[0] ]
- }
- | assocs tCOMMA assoc
- {
- result = val[0] << val[2]
- }
-
- assoc: arg_value tASSOC arg_value
- {
- result = @builder.pair(val[0], val[1], val[2])
- }
- | tLABEL arg_value
- {
- result = @builder.pair_keyword(val[0], val[1])
- }
-
- operation: tIDENTIFIER | tCONSTANT | tFID
- operation2: tIDENTIFIER | tCONSTANT | tFID | op
- operation3: tIDENTIFIER | tFID | op
- dot_or_colon: tDOT | tCOLON2
- opt_terms: | terms
- opt_nl: | tNL
- rparen: opt_nl tRPAREN
- {
- result = val[1]
- }
- rbracket: opt_nl tRBRACK
- {
- result = val[1]
- }
- trailer: | tNL | tCOMMA
-
- term: tSEMI
- {
- yyerrok
- }
- | tNL
-
- terms: term
- | terms tSEMI
-
- none: # nothing
- {
- result = nil
- }
-end
-
----- header
-
-require 'parser'
-
-Parser.check_for_encoding_support
-
----- inner
-
- def version
- 19 # closest released match: v1_9_0_2
- end
-
- def default_encoding
- Encoding::BINARY
- end
diff --git a/test/racc/assets/mailp.y b/test/racc/assets/mailp.y
deleted file mode 100644
index eb7d4d529d..0000000000
--- a/test/racc/assets/mailp.y
+++ /dev/null
@@ -1,437 +0,0 @@
-#
-# mailp for test
-#
-
-class Testp
-
-rule
-
- content : DateH datetime { @field.date = val[1] }
- | RecvH received
- | RetpathH returnpath
- | MaddrH addrs { @field.addrs.replace val[1] }
- | SaddrH addr { @field.addr = val[1] }
- | MmboxH mboxes { @field.addrs.replace val[1] }
- | SmboxH mbox { @field.addr = val[1] }
- | MsgidH msgid { @field.msgid = val[1] }
- | KeyH keys { @field.keys.replace val[1] }
- | EncH enc
- | VersionH version
- | CTypeH ctype
- | CEncodingH cencode
- | CDispositionH cdisp
- | Mbox mbox
- {
- mb = val[1]
- @field.phrase = mb.phrase
- @field.setroute mb.route
- @field.local = mb.local
- @field.domain = mb.domain
- }
- | Spec spec
- {
- mb = val[1]
- @field.local = mb.local
- @field.domain = mb.domain
- }
- ;
-
- datetime : day DIGIT ATOM DIGIT hour zone
- # 0 1 2 3 4 5
- # day month year
- {
- t = Time.gm( val[3].to_i, val[2], val[1].to_i, 0, 0, 0 )
- result = (t + val[4] - val[5]).localtime
- }
- ;
-
- day : /* none */
- | ATOM ','
- ;
-
- hour : DIGIT ':' DIGIT
- {
- result = (result.to_i * 60 * 60) + (val[2].to_i * 60)
- }
- | DIGIT ':' DIGIT ':' DIGIT
- {
- result = (result.to_i * 60 * 60) +
- (val[2].to_i * 60)
- + val[4].to_i
- }
- ;
-
- zone : ATOM
- {
- result = ::TMail.zonestr2i( val[0] ) * 60
- }
- ;
-
- received : from by via with id for recvdatetime
- ;
-
- from : /* none */
- | FROM domain
- {
- @field.from = Address.join( val[1] )
- }
- | FROM domain '@' domain
- {
- @field.from = Address.join( val[3] )
- }
- | FROM domain DOMLIT
- {
- @field.from = Address.join( val[1] )
- }
- ;
-
- by : /* none */
- | BY domain
- {
- @field.by = Address.join( val[1] )
- }
- ;
-
- via : /* none */
- | VIA ATOM
- {
- @field.via = val[1]
- }
- ;
-
- with : /* none */
- | WITH ATOM
- {
- @field.with.push val[1]
- }
- ;
-
- id : /* none */
- | ID msgid
- {
- @field.msgid = val[1]
- }
- | ID ATOM
- {
- @field.msgid = val[1]
- }
- ;
-
- for : /* none */
- | FOR addr
- {
- @field.for_ = val[1].address
- }
- ;
-
- recvdatetime
- : /* none */
- | ';' datetime
- {
- @field.date = val[1]
- }
- ;
-
- returnpath: '<' '>'
- | routeaddr
- {
- @field.route.replace result.route
- @field.addr = result.addr
- }
- ;
-
- addrs : addr { result = val }
- | addrs ',' addr { result.push val[2] }
- ;
-
- addr : mbox
- | group
- ;
-
- mboxes : mbox
- {
- result = val
- }
- | mboxes ',' mbox
- {
- result.push val[2]
- }
- ;
-
- mbox : spec
- | routeaddr
- | phrase routeaddr
- {
- val[1].phrase = HFdecoder.decode( result )
- result = val[1]
- }
- ;
-
- group : phrase ':' mboxes ';'
- {
- result = AddressGroup.new( result, val[2] )
- }
- # | phrase ':' ';' { result = AddressGroup.new( result ) }
- ;
-
- routeaddr : '<' route spec '>'
- {
- result = val[2]
- result.route = val[1]
- }
- | '<' spec '>'
- {
- result = val[1]
- }
- ;
-
- route : at_domains ':'
- ;
-
- at_domains: '@' domain { result = [ val[1] ] }
- | at_domains ',' '@' domain { result.push val[3] }
- ;
-
- spec : local '@' domain { result = Address.new( val[0], val[2] ) }
- | local { result = Address.new( result, nil ) }
- ;
-
- local : word { result = val }
- | local '.' word { result.push val[2] }
- ;
-
- domain : domword { result = val }
- | domain '.' domword { result.push val[2] }
- ;
-
- domword : atom
- | DOMLIT
- | DIGIT
- ;
-
- msgid : '<' spec '>'
- {
- val[1] = val[1].addr
- result = val.join('')
- }
- ;
-
- phrase : word
- | phrase word { result << ' ' << val[1] }
- ;
-
- word : atom
- | QUOTED
- | DIGIT
- ;
-
- keys : phrase
- | keys ',' phrase
- ;
-
- enc : word
- {
- @field.encrypter = val[0]
- }
- | word word
- {
- @field.encrypter = val[0]
- @field.keyword = val[1]
- }
- ;
-
- version : DIGIT '.' DIGIT
- {
- @field.major = val[0].to_i
- @field.minor = val[2].to_i
- }
- ;
-
- ctype : TOKEN '/' TOKEN params
- {
- @field.main = val[0]
- @field.sub = val[2]
- }
- | TOKEN params
- {
- @field.main = val[0]
- @field.sub = ''
- }
- ;
-
- params : /* none */
- | params ';' TOKEN '=' value
- {
- @field.params[ val[2].downcase ] = val[4]
- }
- ;
-
- value : TOKEN
- | QUOTED
- ;
-
- cencode : TOKEN
- {
- @field.encoding = val[0]
- }
- ;
-
- cdisp : TOKEN disp_params
- {
- @field.disposition = val[0]
- }
- ;
-
- disp_params
- : /* none */
- | disp_params ';' disp_param
- ;
-
- disp_param: /* none */
- | TOKEN '=' value
- {
- @field.params[ val[0].downcase ] = val[2]
- }
- ;
-
- atom : ATOM
- | FROM
- | BY
- | VIA
- | WITH
- | ID
- | FOR
- ;
-
-end
-
-
----- header
-#
-# mailp for test
-#
-
-require 'tmail/mails'
-
-
-module TMail
-
----- inner
-
- MAILP_DEBUG = false
-
- def initialize
- self.debug = MAILP_DEBUG
- end
-
- def debug=( flag )
- @yydebug = flag && Racc_debug_parser
- @scanner_debug = flag
- end
-
- def debug
- @yydebug
- end
-
-
- def Mailp.parse( str, obj, ident )
- new.parse( str, obj, ident )
- end
-
-
- NATIVE_ROUTINE = {
- 'TMail::MsgidH' => :msgid_parse,
- 'TMail::RefH' => :refs_parse
- }
-
- def parse( str, obj, ident )
- return if /\A\s*\z/ === str
-
- @field = obj
-
- if mid = NATIVE_ROUTINE[ obj.type.name ] then
- send mid, str
- else
- unless ident then
- ident = obj.type.name.split('::')[-1].to_s
- cmt = []
- obj.comments.replace cmt
- else
- cmt = nil
- end
-
- @scanner = MailScanner.new( str, ident, cmt )
- @scanner.debug = @scanner_debug
- @first = [ ident.intern, ident ]
- @pass_array = [nil, nil]
-
- do_parse
- end
- end
-
-
- private
-
-
- def next_token
- if @first then
- ret = @first
- @first = nil
- ret
- else
- @scanner.scan @pass_array
- end
- end
-
- def on_error( tok, val, vstack )
- raise ParseError,
- "\nparse error in '#{@field.name}' header, on token #{val.inspect}"
- end
-
-
-
- def refs_parse( str )
- arr = []
-
- while mdata = ::TMail::MSGID.match( str ) do
- str = mdata.post_match
-
- pre = mdata.pre_match
- pre.strip!
- proc_phrase pre, arr unless pre.empty?
- arr.push mdata.to_s
- end
- str.strip!
- proc_phrase str, arr if not pre or pre.empty?
-
- @field.refs.replace arr
- end
-
- def proc_phrase( str, arr )
- while mdata = /"([^\\]*(?:\\.[^"\\]*)*)"/.match( str ) do
- str = mdata.post_match
-
- pre = mdata.pre_match
- pre.strip!
- arr.push pre unless pre.empty?
- arr.push mdata[1]
- end
- str.strip!
- arr.push unless str.empty?
- end
-
-
- def msgid_parse( str )
- if mdata = ::TMail::MSGID.match( str ) then
- @field.msgid = mdata.to_s
- else
- raise ParseError, "wrong Message-ID format: #{str}"
- end
- end
-
----- footer
-
-end # module TMail
-
-mp = TMail::Testp.new
-mp.parse
diff --git a/test/racc/assets/mediacloth.y b/test/racc/assets/mediacloth.y
deleted file mode 100644
index 94cc411ea7..0000000000
--- a/test/racc/assets/mediacloth.y
+++ /dev/null
@@ -1,599 +0,0 @@
-# Copyright (c) 2006 Pluron Inc.
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-# The parser for the MediaWiki language.
-#
-# Usage together with a lexer:
-# inputFile = File.new("data/input1", "r")
-# input = inputFile.read
-# parser = MediaWikiParser.new
-# parser.lexer = MediaWikiLexer.new
-# parser.parse(input)
-
-class MediaWikiParser
-
-token TEXT BOLD_START BOLD_END ITALIC_START ITALIC_END LINK_START LINK_END LINKSEP
- INTLINK_START INTLINK_END INTLINKSEP RESOURCESEP CHAR_ENT
- PRE_START PRE_END PREINDENT_START PREINDENT_END
- SECTION_START SECTION_END HLINE SIGNATURE_NAME SIGNATURE_DATE SIGNATURE_FULL
- PARA_START PARA_END UL_START UL_END OL_START OL_END LI_START LI_END
- DL_START DL_END DT_START DT_END DD_START DD_END TAG_START TAG_END ATTR_NAME ATTR_VALUE
- TABLE_START TABLE_END ROW_START ROW_END HEAD_START HEAD_END CELL_START CELL_END
- KEYWORD TEMPLATE_START TEMPLATE_END CATEGORY PASTE_START PASTE_END
-
-
-rule
-
-wiki:
- repeated_contents
- {
- @nodes.push WikiAST.new(0, @wiki_ast_length)
- #@nodes.last.children.insert(0, val[0])
- #puts val[0]
- @nodes.last.children += val[0]
- }
- ;
-
-contents:
- text
- {
- result = val[0]
- }
- | bulleted_list
- {
- result = val[0]
- }
- | numbered_list
- {
- result = val[0]
- }
- | dictionary_list
- {
- list = ListAST.new(@ast_index, @ast_length)
- list.list_type = :Dictionary
- list.children = val[0]
- result = list
- }
- | preformatted
- {
- result = val[0]
- }
- | section
- {
- result = val[0]
- }
- | tag
- {
- result = val[0]
- }
- | template
- {
- result = val[0]
- }
- | KEYWORD
- {
- k = KeywordAST.new(@ast_index, @ast_length)
- k.text = val[0]
- result = k
- }
- | PARA_START para_contents PARA_END
- {
- p = ParagraphAST.new(@ast_index, @ast_length)
- p.children = val[1]
- result = p
- }
- | LINK_START link_contents LINK_END
- {
- l = LinkAST.new(@ast_index, @ast_length)
- l.link_type = val[0]
- l.url = val[1][0]
- l.children += val[1][1..-1] if val[1].length > 1
- result = l
- }
- | PASTE_START para_contents PASTE_END
- {
- p = PasteAST.new(@ast_index, @ast_length)
- p.children = val[1]
- result = p
- }
- | INTLINK_START TEXT RESOURCESEP TEXT reslink_repeated_contents INTLINK_END
- {
- l = ResourceLinkAST.new(@ast_index, @ast_length)
- l.prefix = val[1]
- l.locator = val[3]
- l.children = val[4] unless val[4].nil? or val[4].empty?
- result = l
- }
- | INTLINK_START TEXT intlink_repeated_contents INTLINK_END
- {
- l = InternalLinkAST.new(@ast_index, @ast_length)
- l.locator = val[1]
- l.children = val[2] unless val[2].nil? or val[2].empty?
- result = l
- }
- | INTLINK_START CATEGORY TEXT cat_sort_contents INTLINK_END
- {
- l = CategoryAST.new(@ast_index, @ast_length)
- l.locator = val[2]
- l.sort_as = val[3]
- result = l
- }
- | INTLINK_START RESOURCESEP CATEGORY TEXT intlink_repeated_contents INTLINK_END
- {
- l = CategoryLinkAST.new(@ast_index, @ast_length)
- l.locator = val[3]
- l.children = val[4] unless val[4].nil? or val[4].empty?
- result = l
- }
- | table
- ;
-
-para_contents:
- {
- result = nil
- }
- | repeated_contents
- {
- result = val[0]
- }
- ;
-
-tag:
- TAG_START tag_attributes TAG_END
- {
- if val[0] != val[2]
- raise Racc::ParseError.new("XHTML end tag #{val[2]} does not match start tag #{val[0]}")
- end
- elem = ElementAST.new(@ast_index, @ast_length)
- elem.name = val[0]
- elem.attributes = val[1]
- result = elem
- }
- | TAG_START tag_attributes repeated_contents TAG_END
- {
- if val[0] != val[3]
- raise Racc::ParseError.new("XHTML end tag #{val[3]} does not match start tag #{val[0]}")
- end
- elem = ElementAST.new(@ast_index, @ast_length)
- elem.name = val[0]
- elem.attributes = val[1]
- elem.children += val[2]
- result = elem
- }
- ;
-
-tag_attributes:
- {
- result = nil
- }
- | ATTR_NAME tag_attributes
- {
- attr_map = val[2] ? val[2] : {}
- attr_map[val[0]] = true
- result = attr_map
- }
- | ATTR_NAME ATTR_VALUE tag_attributes
- {
- attr_map = val[2] ? val[2] : {}
- attr_map[val[0]] = val[1]
- result = attr_map
- }
- ;
-
-
-link_contents:
- TEXT
- {
- result = val
- }
- | TEXT LINKSEP link_repeated_contents
- {
- result = [val[0]]
- result += val[2]
- }
- ;
-
-
-link_repeated_contents:
- repeated_contents
- {
- result = val[0]
- }
- | repeated_contents LINKSEP link_repeated_contents
- {
- result = val[0]
- result += val[2] if val[2]
- }
- ;
-
-
-intlink_repeated_contents:
- {
- result = nil
- }
- | INTLINKSEP repeated_contents
- {
- result = val[1]
- }
- ;
-
-cat_sort_contents:
- {
- result = nil
- }
- | INTLINKSEP TEXT
- {
- result = val[1]
- }
- ;
-
-reslink_repeated_contents:
- {
- result = nil
- }
- | INTLINKSEP reslink_repeated_contents
- {
- result = val[1]
- }
- | INTLINKSEP repeated_contents reslink_repeated_contents
- {
- i = InternalLinkItemAST.new(@ast_index, @ast_length)
- i.children = val[1]
- result = [i]
- result += val[2] if val[2]
- }
- ;
-
-repeated_contents: contents
- {
- result = []
- result << val[0]
- }
- | repeated_contents contents
- {
- result = []
- result += val[0]
- result << val[1]
- }
- ;
-
-text: element
- {
- p = TextAST.new(@ast_index, @ast_length)
- p.formatting = val[0][0]
- p.contents = val[0][1]
- result = p
- }
- | formatted_element
- {
- result = val[0]
- }
- ;
-
-table:
- TABLE_START table_contents TABLE_END
- {
- table = TableAST.new(@ast_index, @ast_length)
- table.children = val[1] unless val[1].nil? or val[1].empty?
- result = table
- }
- | TABLE_START TEXT table_contents TABLE_END
- {
- table = TableAST.new(@ast_index, @ast_length)
- table.options = val[1]
- table.children = val[2] unless val[2].nil? or val[2].empty?
- result = table
- }
-
-table_contents:
- {
- result = nil
- }
- | ROW_START row_contents ROW_END table_contents
- {
- row = TableRowAST.new(@ast_index, @ast_length)
- row.children = val[1] unless val[1].nil? or val[1].empty?
- result = [row]
- result += val[3] unless val[3].nil? or val[3].empty?
- }
- | ROW_START TEXT row_contents ROW_END table_contents
- {
- row = TableRowAST.new(@ast_index, @ast_length)
- row.children = val[2] unless val[2].nil? or val[2].empty?
- row.options = val[1]
- result = [row]
- result += val[4] unless val[4].nil? or val[4].empty?
- }
-
-row_contents:
- {
- result = nil
- }
- | HEAD_START HEAD_END row_contents
- {
- cell = TableCellAST.new(@ast_index, @ast_length)
- cell.type = :head
- result = [cell]
- result += val[2] unless val[2].nil? or val[2].empty?
- }
- | HEAD_START repeated_contents HEAD_END row_contents
- {
- cell = TableCellAST.new(@ast_index, @ast_length)
- cell.children = val[1] unless val[1].nil? or val[1].empty?
- cell.type = :head
- result = [cell]
- result += val[3] unless val[3].nil? or val[3].empty?
- }
- | CELL_START CELL_END row_contents
- {
- cell = TableCellAST.new(@ast_index, @ast_length)
- cell.type = :body
- result = [cell]
- result += val[2] unless val[2].nil? or val[2].empty?
- }
- | CELL_START repeated_contents CELL_END row_contents
- {
- if val[2] == 'attributes'
- result = []
- else
- cell = TableCellAST.new(@ast_index, @ast_length)
- cell.children = val[1] unless val[1].nil? or val[1].empty?
- cell.type = :body
- result = [cell]
- end
- result += val[3] unless val[3].nil? or val[3].empty?
- if val[2] == 'attributes' and val[3] and val[3].first.class == TableCellAST
- val[3].first.attributes = val[1]
- end
- result
- }
-
-
-element:
- TEXT
- { return [:None, val[0]] }
- | HLINE
- { return [:HLine, val[0]] }
- | CHAR_ENT
- { return [:CharacterEntity, val[0]] }
- | SIGNATURE_DATE
- { return [:SignatureDate, val[0]] }
- | SIGNATURE_NAME
- { return [:SignatureName, val[0]] }
- | SIGNATURE_FULL
- { return [:SignatureFull, val[0]] }
- ;
-
-formatted_element:
- BOLD_START BOLD_END
- {
- result = FormattedAST.new(@ast_index, @ast_length)
- result.formatting = :Bold
- result
- }
- | ITALIC_START ITALIC_END
- {
- result = FormattedAST.new(@ast_index, @ast_length)
- result.formatting = :Italic
- result
- }
- | BOLD_START repeated_contents BOLD_END
- {
- p = FormattedAST.new(@ast_index, @ast_length)
- p.formatting = :Bold
- p.children += val[1]
- result = p
- }
- | ITALIC_START repeated_contents ITALIC_END
- {
- p = FormattedAST.new(@ast_index, @ast_length)
- p.formatting = :Italic
- p.children += val[1]
- result = p
- }
- ;
-
-bulleted_list: UL_START list_item list_contents UL_END
- {
- list = ListAST.new(@ast_index, @ast_length)
- list.list_type = :Bulleted
- list.children << val[1]
- list.children += val[2]
- result = list
- }
- ;
-
-numbered_list: OL_START list_item list_contents OL_END
- {
- list = ListAST.new(@ast_index, @ast_length)
- list.list_type = :Numbered
- list.children << val[1]
- list.children += val[2]
- result = list
- }
- ;
-
-list_contents:
- { result = [] }
- list_item list_contents
- {
- result << val[1]
- result += val[2]
- }
- |
- { result = [] }
- ;
-
-list_item:
- LI_START LI_END
- {
- result = ListItemAST.new(@ast_index, @ast_length)
- }
- | LI_START repeated_contents LI_END
- {
- li = ListItemAST.new(@ast_index, @ast_length)
- li.children += val[1]
- result = li
- }
- ;
-
-dictionary_list:
- DL_START dictionary_term dictionary_contents DL_END
- {
- result = [val[1]]
- result += val[2]
- }
- | DL_START dictionary_contents DL_END
- {
- result = val[1]
- }
- ;
-
-dictionary_term:
- DT_START DT_END
- {
- result = ListTermAST.new(@ast_index, @ast_length)
- }
- | DT_START repeated_contents DT_END
- {
- term = ListTermAST.new(@ast_index, @ast_length)
- term.children += val[1]
- result = term
- }
-
-dictionary_contents:
- dictionary_definition dictionary_contents
- {
- result = [val[0]]
- result += val[1] if val[1]
- }
- |
- {
- result = []
- }
-
-dictionary_definition:
- DD_START DD_END
- {
- result = ListDefinitionAST.new(@ast_index, @ast_length)
- }
- | DD_START repeated_contents DD_END
- {
- term = ListDefinitionAST.new(@ast_index, @ast_length)
- term.children += val[1]
- result = term
- }
-
-preformatted: PRE_START repeated_contents PRE_END
- {
- p = PreformattedAST.new(@ast_index, @ast_length)
- p.children += val[1]
- result = p
- }
- | PREINDENT_START repeated_contents PREINDENT_END
- {
- p = PreformattedAST.new(@ast_index, @ast_length)
- p.indented = true
- p.children += val[1]
- result = p
- }
- ;
-
-section: SECTION_START repeated_contents SECTION_END
- { result = [val[1], val[0].length]
- s = SectionAST.new(@ast_index, @ast_length)
- s.children = val[1]
- s.level = val[0].length
- result = s
- }
- ;
-
-template: TEMPLATE_START TEXT template_parameters TEMPLATE_END
- {
- t = TemplateAST.new(@ast_index, @ast_length)
- t.template_name = val[1]
- t.children = val[2] unless val[2].nil? or val[2].empty?
- result = t
- }
- ;
-
-template_parameters:
- {
- result = nil
- }
- | INTLINKSEP TEXT template_parameters
- {
- p = TemplateParameterAST.new(@ast_index, @ast_length)
- p.parameter_value = val[1]
- result = [p]
- result += val[2] if val[2]
- }
- | INTLINKSEP template template_parameters
- {
- p = TemplateParameterAST.new(@ast_index, @ast_length)
- p.children << val[1]
- result = [p]
- result += val[2] if val[2]
- }
- ;
-
-end
-
----- header ----
-require 'mediacloth/mediawikiast'
-
----- inner ----
-
-attr_accessor :lexer
-
-def initialize
- @nodes = []
- @context = []
- @wiki_ast_length = 0
- super
-end
-
-#Tokenizes input string and parses it.
-def parse(input)
- @yydebug=true
- lexer.tokenize(input)
- do_parse
- return @nodes.last
-end
-
-#Asks the lexer to return the next token.
-def next_token
- token = @lexer.lex
- if token[0].to_s.upcase.include? "_START"
- @context << token[2..3]
- elsif token[0].to_s.upcase.include? "_END"
- @ast_index = @context.last[0]
- @ast_length = token[2] + token[3] - @context.last[0]
- @context.pop
- else
- @ast_index = token[2]
- @ast_length = token[3]
- end
-
- @wiki_ast_length += token[3]
-
- return token[0..1]
-end
diff --git a/test/racc/assets/mof.y b/test/racc/assets/mof.y
deleted file mode 100644
index 2e83c79b6f..0000000000
--- a/test/racc/assets/mof.y
+++ /dev/null
@@ -1,649 +0,0 @@
-# Distributed under the Ruby license
-# See http://www.ruby-lang.org/en/LICENSE.txt for the full license text
-# Copyright (c) 2010 Klaus Kämpf <kkaempf@suse.de>
-
-/*
- * According to appendix A of
- * http://www.dmtf.org/standards/cim/cim_spec_v22
- */
-
-class MOF::Parser
- prechigh
-/* nonassoc UMINUS */
- left '*' '/'
- left '+' '-'
- preclow
-
- token PRAGMA INCLUDE IDENTIFIER CLASS ASSOCIATION INDICATION
- AMENDED ENABLEOVERRIDE DISABLEOVERRIDE RESTRICTED TOSUBCLASS TOINSTANCE
- TRANSLATABLE QUALIFIER SCOPE SCHEMA PROPERTY REFERENCE
- METHOD PARAMETER FLAVOR INSTANCE
- AS REF ANY OF
- DT_VOID
- DT_UINT8 DT_SINT8 DT_UINT16 DT_SINT16 DT_UINT32 DT_SINT32
- DT_UINT64 DT_SINT64 DT_REAL32 DT_REAL64 DT_CHAR16 DT_STR
- DT_BOOLEAN DT_DATETIME
- positiveDecimalValue
- stringValue
- realValue
- charValue
- booleanValue
- nullValue
- binaryValue
- octalValue
- decimalValue
- hexValue
-
-rule
-
- /* Returns a Hash of filename and MofResult */
- mofSpecification
- : /* empty */
- { result = Hash.new }
- | mofProduction
- { result = { @name => @result } }
- | mofSpecification mofProduction
- { result = val[0]
- result[@name] = @result
- }
- ;
-
- mofProduction
- : compilerDirective
- | classDeclaration
- { #puts "Class '#{val[0].name}'"
- @result.classes << val[0]
- }
- | qualifierDeclaration
- { @result.qualifiers << val[0]
- @qualifiers[val[0].name.downcase] = val[0]
- }
- | instanceDeclaration
- { @result.instances << val[0] }
- ;
-
-/***
- * compilerDirective
- *
- */
-
- compilerDirective
- : "#" PRAGMA INCLUDE pragmaParameters_opt
- { raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#pragma include'") unless val[3]
- open val[3], :pragma
- }
- | "#" PRAGMA pragmaName pragmaParameters_opt
- | "#" INCLUDE pragmaParameters_opt
- { raise StyleError.new(@name,@lineno,@line,"Use '#pragma include' instead of '#include'") unless @style == :wmi
- raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#include'") unless val[2]
- open val[2], :pragma
- }
- ;
-
- pragmaName
- : IDENTIFIER
- ;
-
- pragmaParameters_opt
- : /* empty */
- { raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi }
- | "(" pragmaParameterValues ")"
- { result = val[1] }
- ;
-
- pragmaParameterValues
- : pragmaParameterValue
- | pragmaParameterValues "," pragmaParameterValue
- ;
-
- pragmaParameterValue
- : string
- | integerValue
- { raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi }
- | IDENTIFIER
- ;
-
-/***
- * classDeclaration
- *
- */
-
- classDeclaration
- : qualifierList_opt CLASS className alias_opt superClass_opt "{" classFeatures "}" ";"
- { qualifiers = val[0]
- features = val[6]
- # FIXME: features must not include references
- result = CIM::Class.new(val[2],qualifiers,val[3],val[4],features)
- }
- ;
-
- classFeatures
- : /* empty */
- { result = [] }
- | classFeatures classFeature
- { result = val[0] << val[1] }
- ;
-
- classFeature
- : propertyDeclaration
- | methodDeclaration
- | referenceDeclaration /* must have association qualifier */
- ;
-
-
- qualifierList_opt
- : /* empty */
- | qualifierList
- { result = CIM::QualifierSet.new val[0] }
- ;
-
- qualifierList
- : "[" qualifier qualifiers "]"
- { result = val[2]
- result.unshift val[1] if val[1] }
- ;
-
- qualifiers
- : /* empty */
- { result = [] }
- | qualifiers "," qualifier
- { result = val[0]
- result << val[2] if val[2]
- }
- ;
-
- qualifier
- : qualifierName qualifierParameter_opt flavor_opt
- { # Get qualifier decl
- qualifier = case val[0]
- when CIM::Qualifier then val[0].definition
- when CIM::QualifierDeclaration then val[0]
- when String then @qualifiers[val[0].downcase]
- else
- nil
- end
- raise MOF::Helper::Error.new(@name,@lineno,@line,"'#{val[0]}' is not a valid qualifier") unless qualifier
- value = val[1]
- raise MOF::Helper::Error.new(@name,@lineno,@line,"#{value.inspect} does not match qualifier type '#{qualifier.type}'") unless qualifier.type.matches?(value)||@style == :wmi
- # Don't propagate a boolean 'false'
- if qualifier.type == :boolean && value == false
- result = nil
- else
- result = CIM::Qualifier.new(qualifier,value,val[2])
- end
- }
- ;
-
- flavor_opt
- : /* empty */
- | ":" flavor
- { result = CIM::QualifierFlavors.new val[1] }
- ;
-
- qualifierParameter_opt
- : /* empty */
- | qualifierParameter
- ;
-
- qualifierParameter
- : "(" constantValue ")"
- { result = val[1] }
- | arrayInitializer
- ;
-
- /* CIM::Flavors */
- flavor
- : AMENDED | ENABLEOVERRIDE | DISABLEOVERRIDE | RESTRICTED | TOSUBCLASS | TRANSLATABLE | TOINSTANCE
- { case val[0].to_sym
- when :amended, :toinstance
- raise StyleError.new(@name,@lineno,@line,"'#{val[0]}' is not a valid flavor") unless @style == :wmi
- end
- }
- ;
-
- alias_opt
- : /* empty */
- | alias
- ;
-
- superClass_opt
- : /* empty */
- | superClass
- ;
-
- className
- : IDENTIFIER /* must be <schema>_<classname> in CIM v2.x */
- { raise ParseError.new("Class name must be prefixed by '<schema>_'") unless val[0].include?("_") || @style == :wmi }
- ;
-
- alias
- : AS aliasIdentifier
- { result = val[1] }
- ;
-
- aliasIdentifier
- : "$" IDENTIFIER /* NO whitespace ! */
- { result = val[1] }
- ;
-
- superClass
- : ":" className
- { result = val[1] }
- ;
-
-
- propertyDeclaration
- : qualifierList_opt dataType propertyName array_opt defaultValue_opt ";"
- { if val[3]
- type = CIM::Array.new val[3],val[1]
- else
- type = val[1]
- end
- result = CIM::Property.new(type,val[2],val[0],val[4])
- }
- ;
-
- referenceDeclaration
- : qualifierList_opt objectRef referenceName array_opt defaultValue_opt ";"
- { if val[4]
- raise StyleError.new(@name,@lineno,@line,"Array not allowed in reference declaration") unless @style == :wmi
- end
- result = CIM::Reference.new(val[1],val[2],val[0],val[4]) }
- ;
-
- methodDeclaration
- : qualifierList_opt dataType methodName "(" parameterList_opt ")" ";"
- { result = CIM::Method.new(val[1],val[2],val[0],val[4]) }
- ;
-
- propertyName
- : IDENTIFIER
- | PROPERTY
- { # tmplprov.mof has 'string Property;'
- raise StyleError.new(@name,@lineno,@line,"Invalid keyword '#{val[0]}' used for property name") unless @style == :wmi
- }
- ;
-
- referenceName
- : IDENTIFIER
- | INDICATION
- { result = "Indication" }
- ;
-
- methodName
- : IDENTIFIER
- ;
-
- dataType
- : DT_UINT8
- | DT_SINT8
- | DT_UINT16
- | DT_SINT16
- | DT_UINT32
- | DT_SINT32
- | DT_UINT64
- | DT_SINT64
- | DT_REAL32
- | DT_REAL64
- | DT_CHAR16
- | DT_STR
- | DT_BOOLEAN
- | DT_DATETIME
- | DT_VOID
- { raise StyleError.new(@name,@lineno,@line,"'void' is not a valid datatype") unless @style == :wmi }
- ;
-
- objectRef
- : className
- { # WMI uses class names as data types (without REF ?!)
- raise StyleError.new(@name,@lineno,@line,"Expected 'ref' keyword after classname '#{val[0]}'") unless @style == :wmi
- result = CIM::ReferenceType.new val[0]
- }
-
- | className REF
- { result = CIM::ReferenceType.new val[0] }
- ;
-
- parameterList_opt
- : /* empty */
- | parameterList
- ;
-
- parameterList
- : parameter parameters
- { result = val[1].unshift val[0] }
- ;
-
- parameters
- : /* empty */
- { result = [] }
- | parameters "," parameter
- { result = val[0] << val[2] }
- ;
-
- parameter
- : qualifierList_opt typespec parameterName array_opt parameterValue_opt
- { if val[3]
- type = CIM::Array.new val[3], val[1]
- else
- type = val[1]
- end
- result = CIM::Property.new(type,val[2],val[0])
- }
- ;
-
- typespec
- : dataType
- | objectRef
- ;
-
- parameterName
- : IDENTIFIER
- ;
-
- array_opt
- : /* empty */
- | array
- ;
-
- parameterValue_opt
- : /* empty */
- | defaultValue
- { raise "Default parameter value not allowed in syntax style '{@style}'" unless @style == :wmi }
- ;
-
- array
- : "[" positiveDecimalValue_opt "]"
- { result = val[1] }
- ;
-
- positiveDecimalValue_opt
- : /* empty */
- { result = -1 }
- | positiveDecimalValue
- ;
-
- defaultValue_opt
- : /* empty */
- | defaultValue
- ;
-
- defaultValue
- : "=" initializer
- { result = val[1] }
- ;
-
- initializer
- : constantValue
- | arrayInitializer
- | referenceInitializer
- ;
-
- arrayInitializer
- : "{" constantValues "}"
- { result = val[1] }
- ;
-
- constantValues
- : /* empty */
- | constantValue
- { result = [ val[0] ] }
- | constantValues "," constantValue
- { result = val[0] << val[2] }
- ;
-
- constantValue
- : integerValue
- | realValue
- | charValue
- | string
- | booleanValue
- | nullValue
- | instance
- { raise "Instance as property value not allowed in syntax style '{@style}'" unless @style == :wmi }
- ;
-
- integerValue
- : binaryValue
- | octalValue
- | decimalValue
- | positiveDecimalValue
- | hexValue
- ;
-
- string
- : stringValue
- | string stringValue
- { result = val[0] + val[1] }
- ;
-
- referenceInitializer
- : objectHandle
- | aliasIdentifier
- ;
-
- objectHandle
- : namespace_opt modelPath
- ;
-
- namespace_opt
- : /* empty */
- | namespaceHandle ":"
- ;
-
- namespaceHandle
- : IDENTIFIER
- ;
-
- /*
- * Note
- : structure depends on type of namespace
- */
-
- modelPath
- : className "." keyValuePairList
- ;
-
- keyValuePairList
- : keyValuePair keyValuePairs
- ;
-
- keyValuePairs
- : /* empty */
- | keyValuePairs "," keyValuePair
- ;
-
- keyValuePair
- : keyname "=" initializer
- ;
-
- keyname
- : propertyName | referenceName
- ;
-
-/***
- * qualifierDeclaration
- *
- */
-
- qualifierDeclaration
- /* 0 1 2 3 4 */
- : QUALIFIER qualifierName qualifierType scope defaultFlavor_opt ";"
- { result = CIM::QualifierDeclaration.new( val[1], val[2][0], val[2][1], val[3], val[4]) }
- ;
-
- defaultFlavor_opt
- : /* empty */
- | defaultFlavor
- ;
-
- qualifierName
- : IDENTIFIER
- | ASSOCIATION /* meta qualifier */
- | INDICATION /* meta qualifier */
- | REFERENCE /* Added in DSP0004 2.7.0 */
- | SCHEMA
- ;
-
- /* [type, value] */
- qualifierType
- : ":" dataType array_opt defaultValue_opt
- { type = val[2].nil? ? val[1] : CIM::Array.new(val[2],val[1])
- result = [ type, val[3] ]
- }
- ;
-
- scope
- : "," SCOPE "(" metaElements ")"
- { result = CIM::QualifierScopes.new(val[3]) }
- ;
-
- metaElements
- : metaElement
- { result = [ val[0] ] }
- | metaElements "," metaElement
- { result = val[0] << val[2] }
- ;
-
- metaElement
- : SCHEMA
- | CLASS
- | ASSOCIATION
- | INDICATION
- | QUALIFIER
- | PROPERTY
- | REFERENCE
- | METHOD
- | PARAMETER
- | ANY
- ;
-
- defaultFlavor
- : "," FLAVOR "(" flavors ")"
- { result = CIM::QualifierFlavors.new val[3] }
- ;
-
- flavors
- : flavor
- { result = [ val[0] ] }
- | flavors "," flavor
- { result = val[0] << val[2] }
- ;
-
-/***
- * instanceDeclaration
- *
- */
-
- instanceDeclaration
- : instance ";"
- ;
-
- instance
- : qualifierList_opt INSTANCE OF className alias_opt "{" valueInitializers "}"
- ;
-
- valueInitializers
- : valueInitializer
- | valueInitializers valueInitializer
- ;
-
- valueInitializer
- : qualifierList_opt keyname "=" initializer ";"
- | qualifierList_opt keyname ";"
- { raise "Instance property '#{val[1]} must have a value" unless @style == :wmi }
- ;
-
-end # class Parser
-
----- header ----
-
-# parser.rb - generated by racc
-
-require 'strscan'
-require 'rubygems'
-require 'cim'
-require File.join(__dir__, 'result')
-require File.join(__dir__, 'scanner')
-require File.join(__dir__, 'case')
-
----- inner ----
-
-#
-# Initialize MOF::Parser
-# MOF::Parser.new options = {}
-#
-# options -> Hash of options
-# :debug -> boolean
-# :includes -> array of include dirs
-# :style -> :cim or :wmi
-#
-def initialize options = {}
- @yydebug = options[:debug]
- @includes = options[:includes] || []
- @quiet = options[:quiet]
- @style = options[:style] || :cim # default to style CIM v2.2 syntax
-
- @lineno = 1
- @file = nil
- @iconv = nil
- @eol = "\n"
- @fname = nil
- @fstack = []
- @in_comment = false
- @seen_files = []
- @qualifiers = {}
-end
-
-#
-# Make options hash from argv
-#
-# returns [ files, options ]
-#
-
- def self.argv_handler name, argv
- files = []
- options = { :namespace => "" }
- while argv.size > 0
- case opt = argv.shift
- when "-h"
- $stderr.puts "Ruby MOF compiler"
- $stderr.puts "#{name} [-h] [-d] [-I <dir>] [<moffiles>]"
- $stderr.puts "Compiles <moffile>"
- $stderr.puts "\t-d debug"
- $stderr.puts "\t-h this help"
- $stderr.puts "\t-I <dir> include dir"
- $stderr.puts "\t-f force"
- $stderr.puts "\t-n <namespace>"
- $stderr.puts "\t-o <output>"
- $stderr.puts "\t-s <style> syntax style (wmi,cim)"
- $stderr.puts "\t-q quiet"
- $stderr.puts "\t<moffiles> file(s) to read (else use $stdin)"
- exit 0
- when "-f" then options[:force] = true
- when "-s" then options[:style] = argv.shift.to_sym
- when "-d" then options[:debug] = true
- when "-q" then options[:quiet] = true
- when "-I"
- options[:includes] ||= []
- dirname = argv.shift
- unless File.directory?(dirname)
- files << dirname
- dirname = File.dirname(dirname)
- end
- options[:includes] << Pathname.new(dirname)
- when "-n" then options[:namespace] = argv.shift
- when "-o" then options[:output] = argv.shift
- when /^-.+/
- $stderr.puts "Undefined option #{opt}"
- else
- files << opt
- end
- end
- [ files, options ]
- end
-
-include Helper
-include Scanner
-
----- footer ----
diff --git a/test/racc/assets/namae.y b/test/racc/assets/namae.y
deleted file mode 100644
index 0378345fef..0000000000
--- a/test/racc/assets/namae.y
+++ /dev/null
@@ -1,302 +0,0 @@
-# -*- ruby -*-
-# vi: set ft=ruby :
-
-# Copyright (C) 2012 President and Fellows of Harvard College
-# Copyright (C) 2013-2014 Sylvester Keil
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-# EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# The views and conclusions contained in the software and documentation are
-# those of the authors and should not be interpreted as representing official
-# policies, either expressed or implied, of the copyright holder.
-
-class Namae::Parser
-
-token COMMA UWORD LWORD PWORD NICK AND APPELLATION TITLE SUFFIX
-
-expect 0
-
-rule
-
- names : { result = [] }
- | name { result = [val[0]] }
- | names AND name { result = val[0] << val[2] }
-
- name : word { result = Name.new(:given => val[0]) }
- | display_order
- | honorific word { result = val[0].merge(:family => val[1]) }
- | honorific display_order { result = val[1].merge(val[0]) }
- | sort_order
-
- honorific : APPELLATION { result = Name.new(:appellation => val[0]) }
- | TITLE { result = Name.new(:title => val[0]) }
-
- display_order : u_words word opt_suffices opt_titles
- {
- result = Name.new(:given => val[0], :family => val[1],
- :suffix => val[2], :title => val[3])
- }
- | u_words NICK last opt_suffices opt_titles
- {
- result = Name.new(:given => val[0], :nick => val[1],
- :family => val[2], :suffix => val[3], :title => val[4])
- }
- | u_words NICK von last opt_suffices opt_titles
- {
- result = Name.new(:given => val[0], :nick => val[1],
- :particle => val[2], :family => val[3],
- :suffix => val[4], :title => val[5])
- }
- | u_words von last
- {
- result = Name.new(:given => val[0], :particle => val[1],
- :family => val[2])
- }
- | von last
- {
- result = Name.new(:particle => val[0], :family => val[1])
- }
-
- sort_order : last COMMA first
- {
- result = Name.new({ :family => val[0], :suffix => val[2][0],
- :given => val[2][1] }, !!val[2][0])
- }
- | von last COMMA first
- {
- result = Name.new({ :particle => val[0], :family => val[1],
- :suffix => val[3][0], :given => val[3][1] }, !!val[3][0])
- }
- | u_words von last COMMA first
- {
- result = Name.new({ :particle => val[0,2].join(' '), :family => val[2],
- :suffix => val[4][0], :given => val[4][1] }, !!val[4][0])
- }
- ;
-
- von : LWORD
- | von LWORD { result = val.join(' ') }
- | von u_words LWORD { result = val.join(' ') }
-
- last : LWORD | u_words
-
- first : opt_words { result = [nil,val[0]] }
- | words opt_comma suffices { result = [val[2],val[0]] }
- | suffices { result = [val[0],nil] }
- | suffices COMMA words { result = [val[0],val[2]] }
-
- u_words : u_word
- | u_words u_word { result = val.join(' ') }
-
- u_word : UWORD | PWORD
-
- words : word
- | words word { result = val.join(' ') }
-
- opt_comma : /* empty */ | COMMA
- opt_words : /* empty */ | words
-
- word : LWORD | UWORD | PWORD
-
- opt_suffices : /* empty */ | suffices
-
- suffices : SUFFIX
- | suffices SUFFIX { result = val.join(' ') }
-
- opt_titles : /* empty */ | titles
-
- titles : TITLE
- | titles TITLE { result = val.join(' ') }
-
----- header
-require 'singleton'
-require 'strscan'
-
----- inner
-
- include Singleton
-
- attr_reader :options, :input
-
- def initialize
- @input, @options = StringScanner.new(''), {
- :debug => false,
- :prefer_comma_as_separator => false,
- :comma => ',',
- :stops => ',;',
- :separator => /\s*(\band\b|\&|;)\s*/i,
- :title => /\s*\b(sir|lord|count(ess)?|(gen|adm|col|maj|capt|cmdr|lt|sgt|cpl|pvt|prof|dr|md|ph\.?d)\.?)(\s+|$)/i,
- :suffix => /\s*\b(JR|Jr|jr|SR|Sr|sr|[IVX]{2,})(\.|\b)/,
- :appellation => /\s*\b((mrs?|ms|fr|hr)\.?|miss|herr|frau)(\s+|$)/i
- }
- end
-
- def debug?
- options[:debug] || ENV['DEBUG']
- end
-
- def separator
- options[:separator]
- end
-
- def comma
- options[:comma]
- end
-
- def stops
- options[:stops]
- end
-
- def title
- options[:title]
- end
-
- def suffix
- options[:suffix]
- end
-
- def appellation
- options[:appellation]
- end
-
- def prefer_comma_as_separator?
- options[:prefer_comma_as_separator]
- end
-
- def parse(input)
- parse!(input)
- rescue => e
- warn e.message if debug?
- []
- end
-
- def parse!(string)
- input.string = normalize(string)
- reset
- do_parse
- end
-
- def normalize(string)
- string = string.strip
- string
- end
-
- def reset
- @commas, @words, @initials, @suffices, @yydebug = 0, 0, 0, 0, debug?
- self
- end
-
- private
-
- def stack
- @vstack || @racc_vstack || []
- end
-
- def last_token
- stack[-1]
- end
-
- def consume_separator
- return next_token if seen_separator?
- @commas, @words, @initials, @suffices = 0, 0, 0, 0
- [:AND, :AND]
- end
-
- def consume_comma
- @commas += 1
- [:COMMA, :COMMA]
- end
-
- def consume_word(type, word)
- @words += 1
-
- case type
- when :UWORD
- @initials += 1 if word =~ /^[[:upper:]]+\b/
- when :SUFFIX
- @suffices += 1
- end
-
- [type, word]
- end
-
- def seen_separator?
- !stack.empty? && last_token == :AND
- end
-
- def suffix?
- !@suffices.zero? || will_see_suffix?
- end
-
- def will_see_suffix?
- input.peek(8).to_s.strip.split(/\s+/)[0] =~ suffix
- end
-
- def will_see_initial?
- input.peek(6).to_s.strip.split(/\s+/)[0] =~ /^[[:upper:]]+\b/
- end
-
- def seen_full_name?
- prefer_comma_as_separator? && @words > 1 &&
- (@initials > 0 || !will_see_initial?) && !will_see_suffix?
- end
-
- def next_token
- case
- when input.nil?, input.eos?
- nil
- when input.scan(separator)
- consume_separator
- when input.scan(/\s*#{comma}\s*/)
- if @commas.zero? && !seen_full_name? || @commas == 1 && suffix?
- consume_comma
- else
- consume_separator
- end
- when input.scan(/\s+/)
- next_token
- when input.scan(title)
- consume_word(:TITLE, input.matched.strip)
- when input.scan(suffix)
- consume_word(:SUFFIX, input.matched.strip)
- when input.scan(appellation)
- [:APPELLATION, input.matched.strip]
- when input.scan(/((\\\w+)?\{[^\}]*\})*[[:upper:]][^\s#{stops}]*/)
- consume_word(:UWORD, input.matched)
- when input.scan(/((\\\w+)?\{[^\}]*\})*[[:lower:]][^\s#{stops}]*/)
- consume_word(:LWORD, input.matched)
- when input.scan(/(\\\w+)?\{[^\}]*\}[^\s#{stops}]*/)
- consume_word(:PWORD, input.matched)
- when input.scan(/('[^'\n]+')|("[^"\n]+")/)
- consume_word(:NICK, input.matched[1...-1])
- else
- raise ArgumentError,
- "Failed to parse name #{input.string.inspect}: unmatched data at offset #{input.pos}"
- end
- end
-
- def on_error(tid, value, stack)
- raise ArgumentError,
- "Failed to parse name: unexpected '#{value}' at #{stack.inspect}"
- end
-
-# -*- racc -*-
diff --git a/test/racc/assets/nasl.y b/test/racc/assets/nasl.y
deleted file mode 100644
index c7b8e46551..0000000000
--- a/test/racc/assets/nasl.y
+++ /dev/null
@@ -1,626 +0,0 @@
-################################################################################
-# Copyright (c) 2011-2014, Tenable Network Security
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# 1. Redistributions of source code must retain the above copyright notice, this
-# list of conditions and the following disclaimer.
-#
-# 2. Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-################################################################################
-
-class Nasl::Grammar
-
-preclow
- right ASS_EQ ADD_EQ SUB_EQ MUL_EQ DIV_EQ MOD_EQ SLL_EQ SRA_EQ SRL_EQ
- left OR
- left AND
- left CMP_LT CMP_GT CMP_EQ CMP_NE CMP_GE CMP_LE SUBSTR_EQ SUBSTR_NE REGEX_EQ REGEX_NE
- left BIT_OR
- left BIT_XOR
- left AMPERSAND
- left BIT_SRA BIT_SRL BIT_SLL
- left ADD SUB
- left MUL DIV MOD
- right NOT
- right UMINUS BIT_NOT
- right EXP
- right INCR DECR
-prechigh
-
-# Tell the parser generator that we don't wish to use the result variable in the
-# action section of rules. Instead, the result of the rule will be the value of
-# evaluating the action block.
-options no_result_var
-
-# Tell the parser generator that we expect one shift/reduce conflict due to the
-# well-known dangling else problem. We could make the grammar solve this
-# problem, but this is how the NASL YACC file solves it, so we'll follow suit.
-expect 1
-
-rule
- ##############################################################################
- # Aggregate Statements
- ##############################################################################
-
- start : roots
- { val[0] }
- | /* Blank */
- { [] }
- ;
-
- roots : root roots
- { [val[0]] + val[1] }
- | root
- { [val[0]] }
- ;
-
- root : COMMENT export
- { c(*val) }
- | export
- { val[0] }
- | COMMENT function
- { c(*val) }
- | function
- { val[0] }
- | statement
- { val[0] }
- ;
-
- statement : simple
- { val[0] }
- | compound
- { val[0] }
- ;
-
- ##############################################################################
- # Root Statements
- ##############################################################################
-
- export : EXPORT function
- { n(:Export, *val) }
- ;
-
- function : FUNCTION ident LPAREN params RPAREN block
- { n(:Function, *val) }
- | FUNCTION ident LPAREN RPAREN block
- { n(:Function, *val) }
- ;
-
- simple : assign
- { val[0] }
- | break
- { val[0] }
- | call
- { val[0] }
- | continue
- { val[0] }
- | decr
- { val[0] }
- | empty
- { val[0] }
- | COMMENT global
- { c(*val) }
- | global
- { val[0] }
- | import
- { val[0] }
- | include
- { val[0] }
- | incr
- { val[0] }
- | local
- { val[0] }
- | rep
- { val[0] }
- | return
- { val[0] }
- ;
-
- compound : block
- { val[0] }
- | for
- { val[0] }
- | foreach
- { val[0] }
- | if
- { val[0] }
- | repeat
- { val[0] }
- | while
- { val[0] }
- ;
-
- ##############################################################################
- # Simple Statements
- ##############################################################################
-
- assign : assign_exp SEMICOLON
- { val[0] }
- ;
-
- break : BREAK SEMICOLON
- { n(:Break, *val) }
- ;
-
- call : call_exp SEMICOLON
- { val[0] }
- ;
-
- continue : CONTINUE SEMICOLON
- { n(:Continue, *val) }
- ;
-
- decr : decr_exp SEMICOLON
- { val[0] }
- ;
-
- empty : SEMICOLON
- { n(:Empty, *val) }
- ;
-
- global : GLOBAL var_decls SEMICOLON
- { n(:Global, *val) }
- ;
-
- incr : incr_exp SEMICOLON
- { val[0] }
- ;
-
- import : IMPORT LPAREN string RPAREN SEMICOLON
- { n(:Import, *val) }
- ;
-
- include : INCLUDE LPAREN string RPAREN SEMICOLON
- { n(:Include, *val) }
- ;
-
- local : LOCAL var_decls SEMICOLON
- { n(:Local, *val) }
- ;
-
- rep : call_exp REP expr SEMICOLON
- { n(:Repetition, *val[0..-1]) }
- ;
-
- return : RETURN expr SEMICOLON
- { n(:Return, *val) }
- | RETURN ref SEMICOLON
- { n(:Return, *val) }
- | RETURN SEMICOLON
- { n(:Return, *val) }
- ;
-
- ##############################################################################
- # Compound Statements
- ##############################################################################
-
- block : LBRACE statements RBRACE
- { n(:Block, *val) }
- | LBRACE RBRACE
- { n(:Block, *val) }
- ;
-
- for : FOR LPAREN field SEMICOLON expr SEMICOLON field RPAREN statement
- { n(:For, *val) }
- ;
-
- foreach : FOREACH ident LPAREN expr RPAREN statement
- { n(:Foreach, val[0], val[1], val[3], val[5]) }
- | FOREACH LPAREN ident IN expr RPAREN statement
- { n(:Foreach, val[0], val[2], val[4], val[6]) }
- ;
-
- if : IF LPAREN expr RPAREN statement
- { n(:If, *val) }
- | IF LPAREN expr RPAREN statement ELSE statement
- { n(:If, *val) }
- ;
-
- repeat : REPEAT statement UNTIL expr SEMICOLON
- { n(:Repeat, *val) }
- ;
-
- while : WHILE LPAREN expr RPAREN statement
- { n(:While, *val) }
- ;
-
- ##############################################################################
- # Expressions
- ##############################################################################
-
- assign_exp : lval ASS_EQ expr
- { n(:Assignment, *val) }
- | lval ASS_EQ ref
- { n(:Assignment, *val) }
- | lval ADD_EQ expr
- { n(:Assignment, *val) }
- | lval SUB_EQ expr
- { n(:Assignment, *val) }
- | lval MUL_EQ expr
- { n(:Assignment, *val) }
- | lval DIV_EQ expr
- { n(:Assignment, *val) }
- | lval MOD_EQ expr
- { n(:Assignment, *val) }
- | lval SRL_EQ expr
- { n(:Assignment, *val) }
- | lval SRA_EQ expr
- { n(:Assignment, *val) }
- | lval SLL_EQ expr
- { n(:Assignment, *val) }
- ;
-
- call_exp : lval LPAREN args RPAREN
- { n(:Call, *val) }
- | lval LPAREN RPAREN
- { n(:Call, *val) }
- ;
-
- decr_exp : DECR lval
- { n(:Decrement, val[0]) }
- | lval DECR
- { n(:Decrement, val[0]) }
- ;
-
- incr_exp : INCR lval
- { n(:Increment, val[0]) }
- | lval INCR
- { n(:Increment, val[0]) }
- ;
-
- expr : LPAREN expr RPAREN
- { n(:Expression, *val) }
- | expr AND expr
- { n(:Expression, *val) }
- | NOT expr
- { n(:Expression, *val) }
- | expr OR expr
- { n(:Expression, *val) }
- | expr ADD expr
- { n(:Expression, *val) }
- | expr SUB expr
- { n(:Expression, *val) }
- | SUB expr =UMINUS
- { n(:Expression, *val) }
- | BIT_NOT expr
- { n(:Expression, *val) }
- | expr MUL expr
- { n(:Expression, *val) }
- | expr EXP expr
- { n(:Expression, *val) }
- | expr DIV expr
- { n(:Expression, *val) }
- | expr MOD expr
- { n(:Expression, *val) }
- | expr AMPERSAND expr
- { n(:Expression, *val) }
- | expr BIT_XOR expr
- { n(:Expression, *val) }
- | expr BIT_OR expr
- { n(:Expression, *val) }
- | expr BIT_SRA expr
- { n(:Expression, *val) }
- | expr BIT_SRL expr
- { n(:Expression, *val) }
- | expr BIT_SLL expr
- { n(:Expression, *val) }
- | incr_exp
- { val[0] }
- | decr_exp
- { val[0] }
- | expr SUBSTR_EQ expr
- { n(:Expression, *val) }
- | expr SUBSTR_NE expr
- { n(:Expression, *val) }
- | expr REGEX_EQ expr
- { n(:Expression, *val) }
- | expr REGEX_NE expr
- { n(:Expression, *val) }
- | expr CMP_LT expr
- { n(:Expression, *val) }
- | expr CMP_GT expr
- { n(:Expression, *val) }
- | expr CMP_EQ expr
- { n(:Expression, *val) }
- | expr CMP_NE expr
- { n(:Expression, *val) }
- | expr CMP_GE expr
- { n(:Expression, *val) }
- | expr CMP_LE expr
- { n(:Expression, *val) }
- | assign_exp
- { val[0] }
- | string
- { val[0] }
- | call_exp
- { val[0] }
- | lval
- { val[0] }
- | ip
- { val[0] }
- | int
- { val[0] }
- | undef
- { val[0] }
- | list_expr
- { val[0] }
- | array_expr
- { val[0] }
- ;
-
- ##############################################################################
- # Named Components
- ##############################################################################
-
- arg : ident COLON expr
- { n(:Argument, *val) }
- | ident COLON ref
- { n(:Argument, *val) }
- | expr
- { n(:Argument, *val) }
- | ref
- { n(:Argument, *val) }
- ;
-
- kv_pair : string COLON expr
- { n(:KeyValuePair, *val) }
- | int COLON expr
- { n(:KeyValuePair, *val) }
- | ident COLON expr
- { n(:KeyValuePair, *val) }
- | string COLON ref
- { n(:KeyValuePair, *val) }
- | int COLON ref
- { n(:KeyValuePair, *val) }
- | ident COLON ref
- { n(:KeyValuePair, *val) }
- ;
-
- kv_pairs : kv_pair COMMA kv_pairs
- { [val[0]] + val[2] }
- | kv_pair COMMA
- { [val[0]] }
- | kv_pair
- { [val[0]] }
- ;
-
- lval : ident indexes
- { n(:Lvalue, *val) }
- | ident
- { n(:Lvalue, *val) }
- ;
-
- ref : AT_SIGN ident
- { n(:Reference, val[1]) }
- ;
-
- ##############################################################################
- # Anonymous Components
- ##############################################################################
-
- args : arg COMMA args
- { [val[0]] + val[2] }
- | arg
- { [val[0]] }
- ;
-
- array_expr : LBRACE kv_pairs RBRACE
- { n(:Array, *val) }
- | LBRACE RBRACE
- { n(:Array, *val) }
- ;
-
- field : assign_exp
- { val[0] }
- | call_exp
- { val[0] }
- | decr_exp
- { val[0] }
- | incr_exp
- { val[0] }
- | /* Blank */
- { nil }
- ;
-
- index : LBRACK expr RBRACK
- { val[1] }
- | PERIOD ident
- { val[1] }
- ;
-
- indexes : index indexes
- { [val[0]] + val[1] }
- | index
- { [val[0]] }
- ;
-
- list_elem : expr
- { val[0] }
- | ref
- { val[0] }
- ;
-
- list_elems : list_elem COMMA list_elems
- { [val[0]] + val[2] }
- | list_elem
- { [val[0]] }
- ;
-
- list_expr : LBRACK list_elems RBRACK
- { n(:List, *val) }
- | LBRACK RBRACK
- { n(:List, *val) }
- ;
-
- param : AMPERSAND ident
- { n(:Parameter, val[1], 'reference') }
- | ident
- { n(:Parameter, val[0], 'value') }
- ;
-
- params : param COMMA params
- { [val[0]] + val[2] }
- | param
- { [val[0]] }
- ;
-
- statements : statement statements
- { [val[0]] + val[1] }
- | statement
- { [val[0]] }
- ;
-
- var_decl : ident ASS_EQ expr
- { n(:Assignment, *val) }
- | ident ASS_EQ ref
- { n(:Assignment, *val) }
- | ident
- { val[0] }
- ;
-
- var_decls : var_decl COMMA var_decls
- { [val[0]] + val[2] }
- | var_decl
- { [val[0]] }
- ;
-
- ##############################################################################
- # Literals
- ##############################################################################
-
- ident : IDENT
- { n(:Identifier, *val) }
- | REP
- { n(:Identifier, *val) }
- | IN
- { n(:Identifier, *val) }
- ;
-
- int : INT_DEC
- { n(:Integer, *val) }
- | INT_HEX
- { n(:Integer, *val) }
- | INT_OCT
- { n(:Integer, *val) }
- | FALSE
- { n(:Integer, *val) }
- | TRUE
- { n(:Integer, *val) }
- ;
-
- ip : int PERIOD int PERIOD int PERIOD int
- { n(:Ip, *val) }
-
- string : DATA
- { n(:String, *val) }
- | STRING
- { n(:String, *val) }
- ;
-
- undef : UNDEF
- { n(:Undefined, *val) }
- ;
-end
-
----- header ----
-
-require 'nasl/parser/tree'
-
-require 'nasl/parser/argument'
-require 'nasl/parser/array'
-require 'nasl/parser/assigment'
-require 'nasl/parser/block'
-require 'nasl/parser/break'
-require 'nasl/parser/call'
-require 'nasl/parser/comment'
-require 'nasl/parser/continue'
-require 'nasl/parser/decrement'
-require 'nasl/parser/empty'
-require 'nasl/parser/export'
-require 'nasl/parser/expression'
-require 'nasl/parser/for'
-require 'nasl/parser/foreach'
-require 'nasl/parser/function'
-require 'nasl/parser/global'
-require 'nasl/parser/identifier'
-require 'nasl/parser/if'
-require 'nasl/parser/import'
-require 'nasl/parser/include'
-require 'nasl/parser/increment'
-require 'nasl/parser/integer'
-require 'nasl/parser/ip'
-require 'nasl/parser/key_value_pair'
-require 'nasl/parser/list'
-require 'nasl/parser/local'
-require 'nasl/parser/lvalue'
-require 'nasl/parser/parameter'
-require 'nasl/parser/reference'
-require 'nasl/parser/repeat'
-require 'nasl/parser/repetition'
-require 'nasl/parser/return'
-require 'nasl/parser/string'
-require 'nasl/parser/undefined'
-require 'nasl/parser/while'
-
----- inner ----
-
-def n(cls, *args)
- begin
- Nasl.const_get(cls).new(@tree, *args)
- rescue
- puts "An exception occurred during the creation of a #{cls} instance."
- puts
- puts "The arguments passed to the constructor were:"
- puts args
- puts
- puts @tok.last.context
- puts
- raise
- end
-end
-
-def c(*args)
- n(:Comment, *args)
- args[1]
-end
-
-def on_error(type, value, stack)
- raise ParseException, "The language's grammar does not permit #{value.name} to appear here", value.context
-end
-
-def next_token
- @tok = @tkz.get_token
-
- if @first && @tok.first == :COMMENT
- n(:Comment, @tok.last)
- @tok = @tkz.get_token
- end
- @first = false
-
- return @tok
-end
-
-def parse(env, code, path)
- @first = true
- @tree = Tree.new(env)
- @tkz = Tokenizer.new(code, path)
- @tree.concat(do_parse)
-end
-
----- footer ----
diff --git a/test/racc/assets/newsyn.y b/test/racc/assets/newsyn.y
deleted file mode 100644
index 5b670c966a..0000000000
--- a/test/racc/assets/newsyn.y
+++ /dev/null
@@ -1,25 +0,0 @@
-
-class A
-
- preclow
- left preclow prechigh right left nonassoc token
- right preclow prechigh right left nonassoc token
- nonassoc preclow prechigh right left nonassoc token
- prechigh
-
- convert
- left 'a'
- right 'b'
- preclow 'c'
- nonassoc 'd'
- preclow 'e'
- prechigh 'f'
- end
-
-rule
-
- left: right nonassoc preclow prechigh
-
- right: A B C
-
-end
diff --git a/test/racc/assets/noend.y b/test/racc/assets/noend.y
deleted file mode 100644
index 5aa0670be0..0000000000
--- a/test/racc/assets/noend.y
+++ /dev/null
@@ -1,4 +0,0 @@
-class MyParser
-rule
-input: A B C
-end
diff --git a/test/racc/assets/nokogiri-css.y b/test/racc/assets/nokogiri-css.y
deleted file mode 100644
index 24dfbf3b1b..0000000000
--- a/test/racc/assets/nokogiri-css.y
+++ /dev/null
@@ -1,255 +0,0 @@
-class Nokogiri::CSS::Parser
-
-token FUNCTION INCLUDES DASHMATCH LBRACE HASH PLUS GREATER S STRING IDENT
-token COMMA NUMBER PREFIXMATCH SUFFIXMATCH SUBSTRINGMATCH TILDE NOT_EQUAL
-token SLASH DOUBLESLASH NOT EQUAL RPAREN LSQUARE RSQUARE HAS
-
-rule
- selector
- : selector COMMA simple_selector_1toN {
- result = [val.first, val.last].flatten
- }
- | prefixless_combinator_selector { result = val.flatten }
- | optional_S simple_selector_1toN { result = [val.last].flatten }
- ;
- combinator
- : PLUS { result = :DIRECT_ADJACENT_SELECTOR }
- | GREATER { result = :CHILD_SELECTOR }
- | TILDE { result = :FOLLOWING_SELECTOR }
- | DOUBLESLASH { result = :DESCENDANT_SELECTOR }
- | SLASH { result = :CHILD_SELECTOR }
- ;
- simple_selector
- : element_name hcap_0toN {
- result = if val[1].nil?
- val.first
- else
- Node.new(:CONDITIONAL_SELECTOR, [val.first, val[1]])
- end
- }
- | function
- | function pseudo {
- result = Node.new(:CONDITIONAL_SELECTOR, val)
- }
- | function attrib {
- result = Node.new(:CONDITIONAL_SELECTOR, val)
- }
- | hcap_1toN {
- result = Node.new(:CONDITIONAL_SELECTOR,
- [Node.new(:ELEMENT_NAME, ['*']), val.first]
- )
- }
- ;
- prefixless_combinator_selector
- : combinator simple_selector_1toN {
- result = Node.new(val.first, [nil, val.last])
- }
- ;
- simple_selector_1toN
- : simple_selector combinator simple_selector_1toN {
- result = Node.new(val[1], [val.first, val.last])
- }
- | simple_selector S simple_selector_1toN {
- result = Node.new(:DESCENDANT_SELECTOR, [val.first, val.last])
- }
- | simple_selector
- ;
- class
- : '.' IDENT { result = Node.new(:CLASS_CONDITION, [val[1]]) }
- ;
- element_name
- : namespaced_ident
- | '*' { result = Node.new(:ELEMENT_NAME, val) }
- ;
- namespaced_ident
- : namespace '|' IDENT {
- result = Node.new(:ELEMENT_NAME,
- [[val.first, val.last].compact.join(':')]
- )
- }
- | IDENT {
- name = @namespaces.key?('xmlns') ? "xmlns:#{val.first}" : val.first
- result = Node.new(:ELEMENT_NAME, [name])
- }
- ;
- namespace
- : IDENT { result = val[0] }
- |
- ;
- attrib
- : LSQUARE attrib_name attrib_val_0or1 RSQUARE {
- result = Node.new(:ATTRIBUTE_CONDITION,
- [val[1]] + (val[2] || [])
- )
- }
- | LSQUARE function attrib_val_0or1 RSQUARE {
- result = Node.new(:ATTRIBUTE_CONDITION,
- [val[1]] + (val[2] || [])
- )
- }
- | LSQUARE NUMBER RSQUARE {
- # Non standard, but hpricot supports it.
- result = Node.new(:PSEUDO_CLASS,
- [Node.new(:FUNCTION, ['nth-child(', val[1]])]
- )
- }
- ;
- attrib_name
- : namespace '|' IDENT {
- result = Node.new(:ELEMENT_NAME,
- [[val.first, val.last].compact.join(':')]
- )
- }
- | IDENT {
- # Default namespace is not applied to attributes.
- # So we don't add prefix "xmlns:" as in namespaced_ident.
- result = Node.new(:ELEMENT_NAME, [val.first])
- }
- ;
- function
- : FUNCTION RPAREN {
- result = Node.new(:FUNCTION, [val.first.strip])
- }
- | FUNCTION expr RPAREN {
- result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
- }
- | FUNCTION nth RPAREN {
- result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
- }
- | NOT expr RPAREN {
- result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
- }
- | HAS selector RPAREN {
- result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
- }
- ;
- expr
- : NUMBER COMMA expr { result = [val.first, val.last] }
- | STRING COMMA expr { result = [val.first, val.last] }
- | IDENT COMMA expr { result = [val.first, val.last] }
- | NUMBER
- | STRING
- | IDENT # even, odd
- {
- case val[0]
- when 'even'
- result = Node.new(:NTH, ['2','n','+','0'])
- when 'odd'
- result = Node.new(:NTH, ['2','n','+','1'])
- when 'n'
- result = Node.new(:NTH, ['1','n','+','0'])
- else
- # This is not CSS standard. It allows us to support this:
- # assert_xpath("//a[foo(., @href)]", @parser.parse('a:foo(@href)'))
- # assert_xpath("//a[foo(., @a, b)]", @parser.parse('a:foo(@a, b)'))
- # assert_xpath("//a[foo(., a, 10)]", @parser.parse('a:foo(a, 10)'))
- result = val
- end
- }
- ;
- nth
- : NUMBER IDENT PLUS NUMBER # 5n+3 -5n+3
- {
- if val[1] == 'n'
- result = Node.new(:NTH, val)
- else
- raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
- end
- }
- | IDENT PLUS NUMBER { # n+3, -n+3
- if val[0] == 'n'
- val.unshift("1")
- result = Node.new(:NTH, val)
- elsif val[0] == '-n'
- val[0] = 'n'
- val.unshift("-1")
- result = Node.new(:NTH, val)
- else
- raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
- end
- }
- | NUMBER IDENT { # 5n, -5n, 10n-1
- n = val[1]
- if n[0, 2] == 'n-'
- val[1] = 'n'
- val << "-"
- # b is contained in n as n is the string "n-b"
- val << n[2, n.size]
- result = Node.new(:NTH, val)
- elsif n == 'n'
- val << "+"
- val << "0"
- result = Node.new(:NTH, val)
- else
- raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
- end
- }
- ;
- pseudo
- : ':' function {
- result = Node.new(:PSEUDO_CLASS, [val[1]])
- }
- | ':' IDENT { result = Node.new(:PSEUDO_CLASS, [val[1]]) }
- ;
- hcap_0toN
- : hcap_1toN
- |
- ;
- hcap_1toN
- : attribute_id hcap_1toN {
- result = Node.new(:COMBINATOR, val)
- }
- | class hcap_1toN {
- result = Node.new(:COMBINATOR, val)
- }
- | attrib hcap_1toN {
- result = Node.new(:COMBINATOR, val)
- }
- | pseudo hcap_1toN {
- result = Node.new(:COMBINATOR, val)
- }
- | negation hcap_1toN {
- result = Node.new(:COMBINATOR, val)
- }
- | attribute_id
- | class
- | attrib
- | pseudo
- | negation
- ;
- attribute_id
- : HASH { result = Node.new(:ID, val) }
- ;
- attrib_val_0or1
- : eql_incl_dash IDENT { result = [val.first, val[1]] }
- | eql_incl_dash STRING { result = [val.first, val[1]] }
- |
- ;
- eql_incl_dash
- : EQUAL { result = :equal }
- | PREFIXMATCH { result = :prefix_match }
- | SUFFIXMATCH { result = :suffix_match }
- | SUBSTRINGMATCH { result = :substring_match }
- | NOT_EQUAL { result = :not_equal }
- | INCLUDES { result = :includes }
- | DASHMATCH { result = :dash_match }
- ;
- negation
- : NOT negation_arg RPAREN {
- result = Node.new(:NOT, [val[1]])
- }
- ;
- negation_arg
- : element_name
- | element_name hcap_1toN
- | hcap_1toN
- ;
- optional_S
- : S
- |
- ;
-end
-
----- header
-
-require 'nokogiri/css/parser_extras'
diff --git a/test/racc/assets/nonass.y b/test/racc/assets/nonass.y
deleted file mode 100644
index b9a35a2626..0000000000
--- a/test/racc/assets/nonass.y
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# nonassoc test
-#
-
-class P
-
-preclow
- nonassoc N
- left P
-prechigh
-
-rule
-
-target : exp
-exp : exp N exp
- | exp P exp
- | T
-
-end
-
----- inner
-
- def parse
- @src = [[:T,'T'], [:N,'N'], [:T,'T'], [:N,'N'], [:T,'T']]
- do_parse
- end
-
- def next_token
- @src.shift
- end
-
----- footer
-
-begin
- P.new.parse
-rescue ParseError
- exit 0
-else
- $stderr.puts 'parse error not raised: nonassoc not work'
- exit 1
-end
diff --git a/test/racc/assets/normal.y b/test/racc/assets/normal.y
deleted file mode 100644
index 96ae352c82..0000000000
--- a/test/racc/assets/normal.y
+++ /dev/null
@@ -1,27 +0,0 @@
-
-class Testp
-
- convert
- A '2'
- B '3'
- end
-
- prechigh
- left B
- preclow
-
-rule
-
-/* comment */
- target: A B C nonterminal { action "string" == /regexp/o
- 1 /= 3 }
- ; # comment
-
- nonterminal: A '+' B = A;
-
-/* end */
-end
-
----- driver
-
- # driver is old name
diff --git a/test/racc/assets/norule.y b/test/racc/assets/norule.y
deleted file mode 100644
index e50a4b3472..0000000000
--- a/test/racc/assets/norule.y
+++ /dev/null
@@ -1,4 +0,0 @@
-
-class A
-rule
-end
diff --git a/test/racc/assets/nullbug1.y b/test/racc/assets/nullbug1.y
deleted file mode 100644
index 4b267ba0ea..0000000000
--- a/test/racc/assets/nullbug1.y
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# number of conflicts must be ZERO.
-#
-
-class T
-
-rule
-
-targ : dummy
- | a b c
-
-dummy : V v
-
-V : E e
- | F f
- |
- ;
-
-E :
- ;
-
-F :
- ;
-
-end
diff --git a/test/racc/assets/nullbug2.y b/test/racc/assets/nullbug2.y
deleted file mode 100644
index 0c1d43bf3e..0000000000
--- a/test/racc/assets/nullbug2.y
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# number of conflicts must be ZERO.
-#
-
-class A
-rule
- targ: operation voidhead
- | variable
-
- voidhead : void B
- void:
-
- operation: A
- variable : A
-end
diff --git a/test/racc/assets/opal.y b/test/racc/assets/opal.y
deleted file mode 100644
index ae6a5a6bdd..0000000000
--- a/test/racc/assets/opal.y
+++ /dev/null
@@ -1,1807 +0,0 @@
-# Copyright (C) 2013 by Adam Beynon
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-class Opal::Parser
-
-token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
- kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
- kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
- kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
- kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
- k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
- tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
- tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ tGEQ tLEQ tANDOP
- tOROP tMATCH tNMATCH tJSDOT tDOT tDOT2 tDOT3 tAREF tASET tLSHFT tRSHFT
- tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN tLPAREN2 tRPAREN tLPAREN_ARG
- ARRAY_BEG tRBRACK tLBRACE tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2
- tTILDE tPERCENT tDIVIDE tPLUS tMINUS tLT tGT tPIPE tBANG tCARET
- tLCURLY tRCURLY tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
- tWORDS_BEG tAWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END tSTRING
- tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG
- tLBRACK2 tLBRACK tJSLBRACK tDSTAR
-
-prechigh
- right tBANG tTILDE tUPLUS
- right tPOW
- right tUMINUS_NUM tUMINUS
- left tSTAR2 tDIVIDE tPERCENT
- left tPLUS tMINUS
- left tLSHFT tRSHFT
- left tAMPER2
- left tPIPE tCARET
- left tGT tGEQ tLT tLEQ
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
- left tANDOP
- left tOROP
- nonassoc tDOT2 tDOT3
- right tEH tCOLON
- left kRESCUE_MOD
- right tEQL tOP_ASGN
- nonassoc kDEFINED
- right kNOT
- left kOR kAND
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
- nonassoc tLBRACE_ARG
- nonassoc tLOWEST
-preclow
-
-rule
-
- program: top_compstmt
-
- top_compstmt: top_stmts opt_terms
- {
- result = new_compstmt val[0]
- }
-
- top_stmts: # none
- {
- result = new_block
- }
- | top_stmt
- {
- result = new_block val[0]
- }
- | top_stmts terms top_stmt
- {
- val[0] << val[2]
- result = val[0]
- }
-
- top_stmt: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- result = val[2]
- }
-
- bodystmt: compstmt opt_rescue opt_else opt_ensure
- {
- result = new_body(val[0], val[1], val[2], val[3])
- }
-
- compstmt: stmts opt_terms
- {
- result = new_compstmt val[0]
- }
-
- stmts: # none
- {
- result = new_block
- }
- | stmt
- {
- result = new_block val[0]
- }
- | stmts terms stmt
- {
- val[0] << val[2]
- result = val[0]
- }
-
- stmt: kALIAS fitem
- {
- lexer.lex_state = :expr_fname
- }
- fitem
- {
- result = new_alias(val[0], val[1], val[3])
- }
- | kALIAS tGVAR tGVAR
- {
- result = s(:valias, value(val[1]).to_sym, value(val[2]).to_sym)
- }
- | kALIAS tGVAR tBACK_REF
- | kALIAS tGVAR tNTH_REF
- {
- result = s(:valias, value(val[1]).to_sym, value(val[2]).to_sym)
- }
- | kUNDEF undef_list
- {
- result = val[1]
- }
- | stmt kIF_MOD expr_value
- {
- result = new_if(val[1], val[2], val[0], nil)
- }
- | stmt kUNLESS_MOD expr_value
- {
- result = new_if(val[1], val[2], nil, val[0])
- }
- | stmt kWHILE_MOD expr_value
- {
- result = new_while(val[1], val[2], val[0])
- }
- | stmt kUNTIL_MOD expr_value
- {
- result = new_until(val[1], val[2], val[0])
- }
- | stmt kRESCUE_MOD stmt
- {
- result = new_rescue_mod(val[1], val[0], val[2])
- }
- | klEND tLCURLY compstmt tRCURLY
- | lhs tEQL command_call
- {
- result = new_assign(val[0], val[1], val[2])
- }
- | mlhs tEQL command_call
- {
- result = s(:masgn, val[0], s(:to_ary, val[2]))
- }
- | var_lhs tOP_ASGN command_call
- {
- result = new_op_asgn val[1], val[0], val[2]
- }
- | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN command_call
- | primary_value tJSLBRACK aref_args tRBRACK tOP_ASGN command_call
- | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
- {
- result = s(:op_asgn2, val[0], op_to_setter(val[2]), value(val[3]).to_sym, val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN command_call
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
- | backref tOP_ASGN command_call
- | lhs tEQL mrhs
- {
- result = new_assign val[0], val[1], s(:svalue, val[2])
- }
- | mlhs tEQL arg_value
- {
- result = s(:masgn, val[0], s(:to_ary, val[2]))
- }
- | mlhs tEQL mrhs
- {
- result = s(:masgn, val[0], val[2])
- }
- | expr
-
- expr: command_call
- | expr kAND expr
- {
- result = s(:and, val[0], val[2])
- }
- | expr kOR expr
- {
- result = s(:or, val[0], val[2])
- }
- | kNOT expr
- {
- result = new_unary_call(['!', []], val[1])
- }
- | tBANG command_call
- {
- result = new_unary_call(val[0], val[1])
- }
- | arg
-
- expr_value: expr
-
- command_call: command
- | block_command
- | kRETURN call_args
- {
- result = new_return(val[0], val[1])
- }
- | kBREAK call_args
- {
- result = new_break(val[0], val[1])
- }
- | kNEXT call_args
- {
- result = new_next(val[0], val[1])
- }
-
- block_command: block_call
- | block_call tJSDOT operation2 command_args
- | block_call tDOT operation2 command_args
- | block_call tCOLON2 operation2 command_args
-
- cmd_brace_block: tLBRACE_ARG opt_block_var compstmt tRCURLY
-
- command: operation command_args =tLOWEST
- {
- result = new_call(nil, val[0], val[1])
- }
- | operation command_args cmd_brace_block
- | primary_value tJSDOT operation2 command_args =tLOWEST
- {
- result = new_js_call(val[0], val[2], val[3])
- }
- | primary_value tJSDOT operation2 command_args cmd_brace_block
- | primary_value tDOT operation2 command_args =tLOWEST
- {
- result = new_call(val[0], val[2], val[3])
- }
- | primary_value tDOT operation2 command_args cmd_brace_block
- | primary_value tCOLON2 operation2 command_args =tLOWEST
- {
- result = new_call(val[0], val[2], val[3])
- }
- | primary_value tCOLON2 operation2 command_args cmd_brace_block
- | kSUPER command_args
- {
- result = new_super(val[0], val[1])
- }
- | kYIELD command_args
- {
- result = new_yield val[1]
- }
-
- mlhs: mlhs_basic
- {
- result = val[0]
- }
- | tLPAREN mlhs_entry tRPAREN
- {
- result = val[1]
- }
-
- mlhs_entry: mlhs_basic
- {
- result = val[0]
- }
- | tLPAREN mlhs_entry tRPAREN
- {
- result = val[1]
- }
-
- mlhs_basic: mlhs_head
- {
- result = val[0]
- }
- | mlhs_head mlhs_item
- {
- result = val[0] << val[1]
- }
- | mlhs_head tSTAR mlhs_node
- {
- result = val[0] << s(:splat, val[2])
- }
- | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
- | mlhs_head tSTAR
- {
- result = val[0] << s(:splat)
- }
- | mlhs_head tSTAR tCOMMA mlhs_post
- | tSTAR mlhs_node
- {
- result = s(:array, s(:splat, val[1]))
- }
- | tSTAR
- {
- result = s(:array, s(:splat))
- }
- | tSTAR tCOMMA mlhs_post
-
- mlhs_item: mlhs_node
- {
- result = val[0]
- }
- | tLPAREN mlhs_entry tRPAREN
- {
- result = val[1]
- }
-
- mlhs_head: mlhs_item tCOMMA
- {
- result = s(:array, val[0])
- }
- | mlhs_head mlhs_item tCOMMA
- {
- result = val[0] << val[1]
- }
-
- mlhs_post: mlhs_item
- | mlhs_post tCOMMA mlhs_item
-
- mlhs_node: variable
- {
- result = new_assignable val[0]
- }
- | primary_value tLBRACK2 aref_args tRBRACK
- {
- args = val[2] ? val[2] : []
- result = s(:attrasgn, val[0], :[]=, s(:arglist, *args))
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = new_call val[0], val[2], []
- }
- | primary_value tCOLON2 tIDENTIFIER
- | primary_value tDOT tCONSTANT
- | primary_value tCOLON2 tCONSTANT
- | tCOLON3 tCONSTANT
- | backref
-
- lhs: variable
- {
- result = new_assignable val[0]
- }
- | primary_value tJSLBRACK aref_args tRBRACK
- {
- result = new_js_attrasgn(val[0], val[2])
- }
- | primary_value tLBRACK2 aref_args tRBRACK
- {
- result = new_attrasgn(val[0], :[]=, val[2])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = new_attrasgn(val[0], op_to_setter(val[2]))
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = new_attrasgn(val[0], op_to_setter(val[2]))
- }
- | primary_value tDOT tCONSTANT
- {
- result = new_attrasgn(val[0], op_to_setter(val[2]))
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = new_colon2(val[0], val[1], val[2])
- }
- | tCOLON3 tCONSTANT
- {
- result = new_colon3(val[0], val[1])
- }
- | backref
-
- cname: tCONSTANT
-
- cpath: tCOLON3 cname
- {
- result = new_colon3(val[0], val[1])
- }
- | cname
- {
- result = new_const(val[0])
- }
- | primary_value tCOLON2 cname
- {
- result = new_colon2(val[0], val[1], val[2])
- }
-
- fname: tIDENTIFIER
- | tCONSTANT
- | tFID
- | op
- {
- lexer.lex_state = :expr_end
- result = val[0]
- }
- | reswords
- {
- lexer.lex_state = :expr_end
- result = val[0]
- }
-
- fitem: fname
- {
- result = new_sym(val[0])
- }
- | symbol
-
- undef_list: fitem
- {
- result = s(:undef, val[0])
- }
- | undef_list tCOMMA fitem
- {
- result = val[0] << val[2]
- }
-
- op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
- | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
- | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
- | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
- | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
-
- reswords: k__LINE__ | k__FILE__ | klBEGIN | klEND | kALIAS | kAND
- | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | kDEFINED
- | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE
- | kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT
- | kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF
- | kSUPER | kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD
- | kIF_MOD | kUNLESS_MOD | kWHILE_MOD | kUNTIL_MOD | kRESCUE_MOD
- | kIF | kWHILE | kUNTIL | kUNLESS
-
- arg: lhs tEQL arg
- {
- result = new_assign(val[0], val[1], val[2])
- }
- | lhs tEQL arg kRESCUE_MOD arg
- {
- result = new_assign val[0], val[1], s(:rescue_mod, val[2], val[4])
- }
- | var_lhs tOP_ASGN arg
- {
- result = new_op_asgn val[1], val[0], val[2]
- }
- | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN arg
- {
- result = new_op_asgn1(val[0], val[2], val[4], val[5])
- }
- | primary_value tJSLBRACK aref_args tRBRACK tOP_ASGN arg
- {
- raise ".JS[...] #{val[4]} is not supported"
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN arg
- {
- result = s(:op_asgn2, val[0], op_to_setter(val[2]), value(val[3]).to_sym, val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN arg
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
- | tCOLON3 tCONSTANT tOP_ASGN arg
- | backref tOP_ASGN arg
- | arg tDOT2 arg
- {
- result = new_irange(val[0], val[1], val[2])
- }
- | arg tDOT3 arg
- {
- result = new_erange(val[0], val[1], val[2])
- }
- | arg tPLUS arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tMINUS arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tSTAR2 arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tDIVIDE arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tPERCENT arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tPOW arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | '-@NUM' tINTEGER tPOW arg
- {
- result = new_call new_binary_call(new_int(val[1]), val[2], val[3]), [:"-@", []], []
- }
- | '-@NUM' tFLOAT tPOW arg
- {
- result = new_call new_binary_call(new_float(val[1]), val[2], val[3]), [:"-@", []], []
- }
- | tUPLUS arg
- {
- result = new_call val[1], [:"+@", []], []
- if [:int, :float].include? val[1].type
- result = val[1]
- end
- }
- | tUMINUS arg
- {
- result = new_call val[1], [:"-@", []], []
- if val[1].type == :int
- val[1][1] = -val[1][1]
- result = val[1]
- elsif val[1].type == :float
- val[1][1] = -val[1][1].to_f
- result = val[1]
- end
- }
- | arg tPIPE arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tCARET arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tAMPER2 arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tCMP arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tGT arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tGEQ arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tLT arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tLEQ arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tEQ arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tEQQ arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tNEQ arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tMATCH arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tNMATCH arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | tBANG arg
- {
- result = new_unary_call(val[0], val[1])
- }
- | tTILDE arg
- {
- result = new_unary_call(val[0], val[1])
- }
- | arg tLSHFT arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tRSHFT arg
- {
- result = new_binary_call(val[0], val[1], val[2])
- }
- | arg tANDOP arg
- {
- result = new_and(val[0], val[1], val[2])
- }
- | arg tOROP arg
- {
- result = new_or(val[0], val[1], val[2])
- }
- | kDEFINED opt_nl arg
- {
- result = s(:defined, val[2])
- }
- | arg tEH arg tCOLON arg
- {
- result = new_if(val[1], val[0], val[2], val[4])
- }
- | primary
-
- arg_value: arg
-
- aref_args: none
- {
- result = nil
- }
- | command opt_nl
- {
- result = [val[0]]
- }
- | args trailer
- {
- result = val[0]
- }
- | args tCOMMA assocs trailer
- {
- val[0] << s(:hash, *val[2])
- result = val[0]
- }
- | assocs trailer
- {
- result = [s(:hash, *val[0])]
- }
-
- paren_args: tLPAREN2 opt_call_args rparen
- {
- result = val[1]
- }
-
- rparen: opt_nl tRPAREN
-
- opt_paren_args: none
- {
- result = []
- }
- | paren_args
-
- opt_call_args: none
- {
- result = []
- }
- | call_args
- | args tCOMMA
- {
- result = val[0]
- }
- | args tCOMMA assocs tCOMMA
- {
- result = val[0]
- result << new_hash(nil, val[2], nil)
- }
- | assocs tCOMMA
- {
- result = [new_hash(nil, val[0], nil)]
- }
-
- call_args: command
- {
- result = [val[0]]
- }
- | args opt_block_arg
- {
- result = val[0]
- add_block_pass val[0], val[1]
- }
- | assocs opt_block_arg
- {
- result = [new_hash(nil, val[0], nil)]
- add_block_pass result, val[1]
- }
- | args tCOMMA assocs opt_block_arg
- {
- result = val[0]
- result << new_hash(nil, val[2], nil)
- result << val[3] if val[3]
- }
- | block_arg
- {
- result = []
- add_block_pass result, val[0]
- }
-
- call_args2: arg_value tCOMMA args opt_block_arg
- | block_arg
-
- command_args: {
- lexer.cmdarg_push 1
- }
- open_args
- {
- lexer.cmdarg_pop
- result = val[1]
- }
-
- open_args: call_args
- | tLPAREN_ARG tRPAREN
- {
- result = nil
- }
- | tLPAREN_ARG call_args2 tRPAREN
- {
- result = val[1]
- }
-
- block_arg: tAMPER arg_value
- {
- result = new_block_pass(val[0], val[1])
- }
-
- opt_block_arg: tCOMMA block_arg
- {
- result = val[1]
- }
- | # none
- {
- result = nil
- }
-
- args: arg_value
- {
- result = [val[0]]
- }
- | tSTAR arg_value
- {
- result = [new_splat(val[0], val[1])]
- }
- | args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << new_splat(val[2], val[3])
- }
-
- mrhs: args tCOMMA arg_value
- {
- val[0] << val[2]
- result = s(:array, *val[0])
- }
- | args tCOMMA tSTAR arg_value
- {
- val[0] << s(:splat, val[3])
- result = s(:array, *val[0])
- }
- | tSTAR arg_value
- {
- result = s(:splat, val[1])
- }
-
- primary: literal
- | strings
- | xstring
- | regexp
- | words
- | awords
- | var_ref
- | backref
- | tFID
- | kBEGIN
- {
- result = lexer.line
- }
- bodystmt kEND
- {
- result = s(:begin, val[2])
- }
- | tLPAREN_ARG expr opt_nl tRPAREN
- {
- result = val[1]
- }
- | tLPAREN compstmt tRPAREN
- {
- result = new_paren(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = new_colon2(val[0], val[1], val[2])
- }
- | tCOLON3 tCONSTANT
- {
- result = new_colon3(val[0], val[1])
- }
- | primary_value tLBRACK2 aref_args tRBRACK
- {
- result = new_call val[0], [:[], []], val[2]
- }
- | primary_value tJSLBRACK aref_args tRBRACK
- {
- result = new_js_call val[0], [:[], []], val[2]
- }
- | tLBRACK aref_args tRBRACK
- {
- result = new_array(val[0], val[1], val[2])
- }
- | tLBRACE assoc_list tRCURLY
- {
- result = new_hash(val[0], val[1], val[2])
- }
- | kRETURN
- {
- result = new_return(val[0])
- }
- | kYIELD tLPAREN2 call_args tRPAREN
- {
- result = new_yield val[2]
- }
- | kYIELD tLPAREN2 tRPAREN
- {
- result = s(:yield)
- }
- | kYIELD
- {
- result = s(:yield)
- }
- | kDEFINED opt_nl tLPAREN2 expr tRPAREN
- {
- result = s(:defined, val[3])
- }
- | kNOT tLPAREN2 expr tRPAREN
- {
- result = new_unary_call(['!', []], val[2])
- }
- | kNOT tLPAREN2 tRPAREN
- {
- result = new_unary_call(['!', []], new_nil(val[0]))
- }
- | operation brace_block
- {
- result = new_call(nil, val[0], [])
- result << val[1]
- }
- | method_call
- | method_call brace_block
- {
- val[0] << val[1]
- result = val[0]
- }
- | tLAMBDA lambda
- {
- result = val[1]
- }
- | kIF expr_value then compstmt if_tail kEND
- {
- result = new_if(val[0], val[1], val[3], val[4])
- }
- | kUNLESS expr_value then compstmt opt_else kEND
- {
- result = new_if(val[0], val[1], val[4], val[3])
- }
- | kWHILE
- {
- lexer.cond_push 1
- result = lexer.line
- }
- expr_value do
- {
- lexer.cond_pop
- }
- compstmt kEND
- {
- result = s(:while, val[2], val[5])
- }
- | kUNTIL
- {
- lexer.cond_push 1
- result = lexer.line
- }
- expr_value do
- {
- lexer.cond_pop
- }
- compstmt kEND
- {
- result = s(:until, val[2], val[5])
- }
- | kCASE expr_value opt_terms case_body kEND
- {
- result = s(:case, val[1], *val[3])
- }
- | kCASE opt_terms case_body kEND
- {
- result = s(:case, nil, *val[2])
- }
- | kCASE opt_terms kELSE compstmt kEND
- {
- result = s(:case, nil, val[3])
- }
- | kFOR for_var kIN
- {
- lexer.cond_push 1
- result = lexer.line
- }
- expr_value do
- {
- lexer.cond_pop
- }
- compstmt kEND
- {
- result = s(:for, val[4], val[1], val[7])
- }
- | kCLASS cpath superclass
- {
- # ...
- }
- bodystmt kEND
- {
- result = new_class val[0], val[1], val[2], val[4], val[5]
- }
- | kCLASS tLSHFT
- {
- result = lexer.line
- }
- expr term
- {
- # ...
- }
- bodystmt kEND
- {
- result = new_sclass(val[0], val[3], val[6], val[7])
- }
- | kMODULE
- {
- result = lexer.line
- }
- cpath
- {
- # ...
- }
- bodystmt kEND
- {
- result = new_module(val[0], val[2], val[4], val[5])
- }
- | kDEF fname
- {
- push_scope
- lexer.lex_state = :expr_endfn
- }
- f_arglist bodystmt kEND
- {
- result = new_def(val[0], nil, val[1], val[3], val[4], val[5])
- pop_scope
- }
- | kDEF singleton dot_or_colon
- {
- lexer.lex_state = :expr_fname
- }
- fname
- {
- push_scope
- lexer.lex_state = :expr_endfn
- }
- f_arglist bodystmt kEND
- {
- result = new_def(val[0], val[1], val[4], val[6], val[7], val[8])
- pop_scope
- }
- | kBREAK
- {
- result = new_break(val[0])
- }
- | kNEXT
- {
- result = s(:next)
- }
- | kREDO
- {
- result = s(:redo)
- }
- | kRETRY
-
- primary_value: primary
-
- then: term
- | tCOLON
- | kTHEN
- | term kTHEN
-
- do: term
- | tCOLON
- | kDO_COND
-
- lambda: f_larglist lambda_body
- {
- result = new_call nil, [:lambda, []], []
- result << new_iter(val[0], val[1])
- }
-
- f_larglist: tLPAREN2 block_param tRPAREN
- {
- result = val[1]
- }
- | tLPAREN2 tRPAREN
- {
- result = nil
- }
- | block_param
- | none
-
- lambda_body: tLAMBEG compstmt tRCURLY
- {
- result = val[1]
- }
- | kDO_LAMBDA compstmt kEND
- {
- result = val[1]
- }
-
- if_tail: opt_else
- {
- result = val[0]
- }
- | kELSIF expr_value then compstmt if_tail
- {
- result = new_if(val[0], val[1], val[3], val[4])
- }
-
- opt_else: none
- | kELSE compstmt
- {
- result = val[1]
- }
-
- f_block_optarg: f_block_opt
- {
- result = s(:block, val[0])
- }
- | f_block_optarg tCOMMA f_block_opt
- {
- val[0] << val[2]
- result = val[0]
- }
-
- f_block_opt: tIDENTIFIER tEQL primary_value
- {
- result = new_assign(new_assignable(new_ident(
- val[0])), val[1], val[2])
- }
-
- opt_block_var: none
- | tPIPE tPIPE
- {
- result = nil
- }
- | tOROP
- {
- result = nil
- }
- | tPIPE block_param tPIPE
- {
- result = val[1]
- }
-
- block_args_tail: f_block_arg
- {
- result = val[0]
- }
-
-opt_block_args_tail: tCOMMA block_args_tail
- {
- result = val[1]
- }
- | none
- {
- nil
- }
-
- block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = new_block_args(val[0], val[2], val[4], val[5])
- }
- | f_arg tCOMMA f_block_optarg opt_block_args_tail
- {
- result = new_block_args(val[0], val[2], nil, val[3])
- }
- | f_arg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = new_block_args(val[0], nil, val[2], val[3])
- }
- | f_arg tCOMMA
- {
- result = new_block_args(val[0], nil, nil, nil)
- }
- | f_arg opt_block_args_tail
- {
- result = new_block_args(val[0], nil, nil, val[1])
- }
- | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = new_block_args(nil, val[0], val[2], val[3])
- }
- | f_block_optarg opt_block_args_tail
- {
- result = new_block_args(nil, val[0], nil, val[1])
- }
- | f_rest_arg opt_block_args_tail
- {
- result = new_block_args(nil, nil, val[0], val[1])
- }
- | block_args_tail
- {
- result = new_block_args(nil, nil, nil, val[0])
- }
-
- do_block: kDO_BLOCK
- {
- push_scope :block
- result = lexer.line
- }
- opt_block_var compstmt kEND
- {
- result = new_iter val[2], val[3]
- pop_scope
- }
-
- block_call: command do_block
- {
- val[0] << val[1]
- result = val[0]
- }
- | block_call tJSDOT operation2 opt_paren_args
- | block_call tDOT operation2 opt_paren_args
- | block_call tCOLON2 operation2 opt_paren_args
-
- method_call: operation paren_args
- {
- result = new_call(nil, val[0], val[1])
- }
- | primary_value tDOT operation2 opt_paren_args
- {
- result = new_call(val[0], val[2], val[3])
- }
- | primary_value tJSDOT operation2 opt_paren_args
- {
- result = new_js_call(val[0], val[2], val[3])
- }
- | primary_value tDOT paren_args
- {
- result = new_call(val[0], [:call, []], val[2])
- }
- | primary_value tCOLON2 operation2 paren_args
- {
- result = new_call(val[0], val[2], val[3])
- }
- | primary_value tCOLON2 operation3
- {
- result = new_call(val[0], val[2])
- }
- | kSUPER paren_args
- {
- result = new_super(val[0], val[1])
- }
- | kSUPER
- {
- result = new_super(val[0], nil)
- }
-
- brace_block: tLCURLY
- {
- push_scope :block
- result = lexer.line
- }
- opt_block_var compstmt tRCURLY
- {
- result = new_iter val[2], val[3]
- pop_scope
- }
- | kDO
- {
- push_scope :block
- result = lexer.line
- }
- opt_block_var compstmt kEND
- {
- result = new_iter val[2], val[3]
- pop_scope
- }
-
- case_body: kWHEN
- {
- result = lexer.line
- }
- args then compstmt cases
- {
- part = s(:when, s(:array, *val[2]), val[4])
- result = [part]
- result.push(*val[5]) if val[5]
- }
-
- cases: opt_else
- {
- result = [val[0]]
- }
- | case_body
-
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
- {
- exc = val[1] || s(:array)
- exc << new_assign(val[2], val[2], s(:gvar, '$!'.intern)) if val[2]
- result = [s(:resbody, exc, val[4])]
- result.push val[5].first if val[5]
- }
- | # none
- {
- result = nil
- }
-
- exc_list: arg_value
- {
- result = s(:array, val[0])
- }
- | mrhs
- | none
-
- exc_var: tASSOC lhs
- {
- result = val[1]
- }
- | none
- {
- result = nil
- }
-
- opt_ensure: kENSURE compstmt
- {
- result = val[1].nil? ? s(:nil) : val[1]
- }
- | none
-
- literal: numeric
- | symbol
- | dsym
-
- strings: string
- {
- result = new_str val[0]
- }
-
- string: string1
- | string string1
- {
- result = str_append val[0], val[1]
- }
-
- string1: tSTRING_BEG string_contents tSTRING_END
- {
- result = val[1]
- }
- | tSTRING
- {
- result = s(:str, value(val[0]))
- }
-
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
- {
- result = new_xstr(val[0], val[1], val[2])
- }
-
- regexp: tREGEXP_BEG xstring_contents tREGEXP_END
- {
- result = new_regexp val[1], val[2]
- }
-
- words: tWORDS_BEG tSPACE tSTRING_END
- {
- result = s(:array)
- }
- | tWORDS_BEG word_list tSTRING_END
- {
- result = val[1]
- }
-
- word_list: none
- {
- result = s(:array)
- }
- | word_list word tSPACE
- {
- part = val[1]
- part = s(:dstr, "", val[1]) if part.type == :evstr
- result = val[0] << part
- }
-
- word: string_content
- {
- result = val[0]
- }
- | word string_content
- {
- result = val[0].concat([val[1]])
- }
-
- awords: tAWORDS_BEG tSPACE tSTRING_END
- {
- result = s(:array)
- }
- | tAWORDS_BEG qword_list tSTRING_END
- {
- result = val[1]
- }
-
- qword_list: none
- {
- result = s(:array)
- }
- | qword_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << s(:str, value(val[1]))
- }
-
- string_contents: none
- {
- result = nil
- }
- | string_contents string_content
- {
- result = str_append val[0], val[1]
- }
-
-xstring_contents: none
- {
- result = nil
- }
- | xstring_contents string_content
- {
- result = str_append val[0], val[1]
- }
-
- string_content: tSTRING_CONTENT
- {
- result = new_str_content(val[0])
- }
- | tSTRING_DVAR
- {
- result = lexer.strterm
- lexer.strterm = nil
- }
- string_dvar
- {
- lexer.strterm = val[1]
- result = new_evstr(val[2])
- }
- | tSTRING_DBEG
- {
- lexer.cond_push 0
- lexer.cmdarg_push 0
- result = lexer.strterm
- lexer.strterm = nil
- lexer.lex_state = :expr_beg
- }
- compstmt tRCURLY
- {
- lexer.strterm = val[1]
- lexer.cond_lexpop
- lexer.cmdarg_lexpop
- result = new_evstr(val[2])
- }
-
- string_dvar: tGVAR
- {
- result = new_gvar(val[0])
- }
- | tIVAR
- {
- result = new_ivar(val[0])
- }
- | tCVAR
- {
- result = new_cvar(val[0])
- }
- | backref
-
-
- symbol: tSYMBEG sym
- {
- result = new_sym(val[1])
- lexer.lex_state = :expr_end
- }
- | tSYMBOL
- {
- result = new_sym(val[0])
- }
-
- sym: fname
- | tIVAR
- | tGVAR
- | tCVAR
-
- dsym: tSYMBEG xstring_contents tSTRING_END
- {
- result = new_dsym val[1]
- }
-
- numeric: tINTEGER
- {
- result = new_int(val[0])
- }
- | tFLOAT
- {
- result = new_float(val[0])
- }
- | '-@NUM' tINTEGER =tLOWEST
- {
- result = negate_num(new_int(val[1]))
- }
- | '-@NUM' tFLOAT =tLOWEST
- {
- result = negate_num(new_float(val[1]))
- }
- | '+@NUM' tINTEGER =tLOWEST
- {
- result = new_int(val[1])
- }
- | '+@NUM' tFLOAT =tLOWEST
- {
- result = new_float(val[1])
- }
-
- variable: tIDENTIFIER
- {
- result = new_ident(val[0])
- }
- | tIVAR
- {
- result = new_ivar(val[0])
- }
- | tGVAR
- {
- result = new_gvar(val[0])
- }
- | tCONSTANT
- {
- result = new_const(val[0])
- }
- | tCVAR
- {
- result = new_cvar(val[0])
- }
- | kNIL
- {
- result = new_nil(val[0])
- }
- | kSELF
- {
- result = new_self(val[0])
- }
- | kTRUE
- {
- result = new_true(val[0])
- }
- | kFALSE
- {
- result = new_false(val[0])
- }
- | k__FILE__
- {
- result = new___FILE__(val[0])
- }
- | k__LINE__
- {
- result = new___LINE__(val[0])
- }
-
- var_ref: variable
- {
- result = new_var_ref(val[0])
- }
-
- var_lhs: variable
- {
- result = new_assignable val[0]
- }
-
- backref: tNTH_REF
- {
- result = s(:nth_ref, value(val[0]))
- }
- | tBACK_REF
-
- superclass: term
- {
- result = nil
- }
- | tLT expr_value term
- {
- result = val[1]
- }
- | error term
- {
- result = nil
- }
-
- f_arglist: tLPAREN2 f_args opt_nl tRPAREN
- {
- result = val[1]
- lexer.lex_state = :expr_beg
- }
- | f_args term
- {
- result = val[0]
- lexer.lex_state = :expr_beg
- }
-
- kwrest_mark: tPOW
- | tDSTAR
-
- f_kwrest: kwrest_mark tIDENTIFIER
- {
- result = new_kwrestarg(val[1])
- }
- | kwrest_mark
- {
- result = new_kwrestarg()
- }
-
- f_label: tLABEL
- {
- result = new_sym(val[0])
- }
-
- f_kw: f_label arg_value
- {
- result = new_kwoptarg(val[0], val[1])
- }
- | f_label
- {
- result = new_kwarg(val[0])
- }
-
- f_kwarg: f_kw
- {
- result = [val[0]]
- }
- | f_kwarg tCOMMA f_kw
- {
- result = val[0]
- result << val[2]
- }
-
- args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
- {
- result = new_args_tail(val[0], val[2], val[3])
- }
- | f_kwarg opt_f_block_arg
- {
- result = new_args_tail(val[0], nil, val[1])
- }
- | f_kwrest opt_f_block_arg
- {
- result = new_args_tail(nil, val[0], val[1])
- }
- | f_block_arg
- {
- result = new_args_tail(nil, nil, val[0])
- }
-
- opt_args_tail: tCOMMA args_tail
- {
- result = val[1]
- }
- | # none
- {
- result = new_args_tail(nil, nil, nil)
- }
-
- f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
- {
- result = new_args(val[0], val[2], val[4], val[5])
- }
- | f_arg tCOMMA f_optarg opt_args_tail
- {
- result = new_args(val[0], val[2], nil, val[3])
- }
- | f_arg tCOMMA f_rest_arg opt_args_tail
- {
- result = new_args(val[0], nil, val[2], val[3])
- }
- | f_arg opt_args_tail
- {
- result = new_args(val[0], nil, nil, val[1])
- }
- | f_optarg tCOMMA f_rest_arg opt_args_tail
- {
- result = new_args(nil, val[0], val[2], val[3])
- }
- | f_optarg opt_args_tail
- {
- result = new_args(nil, val[0], nil, val[1])
- }
- | f_rest_arg opt_args_tail
- {
- result = new_args(nil, nil, val[0], val[1])
- }
- | args_tail
- {
- result = new_args(nil, nil, nil, val[0])
- }
- | # none
- {
- result = new_args(nil, nil, nil, nil)
- }
-
- f_norm_arg: f_bad_arg
- | tIDENTIFIER
- {
- result = value(val[0]).to_sym
- scope.add_local result
- }
-
- f_bad_arg: tCONSTANT
- {
- raise 'formal argument cannot be a constant'
- }
- | tIVAR
- {
- raise 'formal argument cannot be an instance variable'
- }
- | tCVAR
- {
- raise 'formal argument cannot be a class variable'
- }
- | tGVAR
- {
- raise 'formal argument cannot be a global variable'
- }
-
- f_arg_item: f_norm_arg
- {
- result = val[0]
- }
- | tLPAREN f_margs tRPAREN
- {
- result = val[1]
- }
-
- for_var: lhs
- | mlhs
-
- f_marg: f_norm_arg
- {
- result = s(:lasgn, val[0])
- }
- | tLPAREN f_margs tRPAREN
-
- f_marg_list: f_marg
- {
- result = s(:array, val[0])
- }
- | f_marg_list tCOMMA f_marg
- {
- val[0] << val[2]
- result = val[0]
- }
-
- f_margs: f_marg_list
- | f_marg_list tCOMMA tSTAR f_norm_arg
- | f_marg_list tCOMMA tSTAR
- | tSTAR f_norm_arg
- | tSTAR
-
- f_arg: f_arg_item
- {
- result = [val[0]]
- }
- | f_arg tCOMMA f_arg_item
- {
- val[0] << val[2]
- result = val[0]
- }
-
- f_opt: tIDENTIFIER tEQL arg_value
- {
- result = new_assign(new_assignable(new_ident(val[0])), val[1], val[2])
- }
-
- f_optarg: f_opt
- {
- result = s(:block, val[0])
- }
- | f_optarg tCOMMA f_opt
- {
- result = val[0]
- val[0] << val[2]
- }
-
- restarg_mark: tSTAR2
- | tSTAR
-
- f_rest_arg: restarg_mark tIDENTIFIER
- {
- result = "*#{value(val[1])}".to_sym
- }
- | restarg_mark
- {
- result = :"*"
- }
-
- blkarg_mark: tAMPER2
- | tAMPER
-
- f_block_arg: blkarg_mark tIDENTIFIER
- {
- result = "&#{value(val[1])}".to_sym
- }
-
- opt_f_block_arg: tCOMMA f_block_arg
- {
- result = val[1]
- }
- | # none
- {
- result = nil
- }
-
- singleton: var_ref
- {
- result = val[0]
- }
- | tLPAREN2 expr opt_nl tRPAREN
- {
- result = val[1]
- }
-
- assoc_list: # none
- {
- result = []
- }
- | assocs trailer
- {
- result = val[0]
- }
-
- assocs: assoc
- {
- result = val[0]
- }
- | assocs tCOMMA assoc
- {
- result = val[0].push(*val[2])
- }
-
- assoc: arg_value tASSOC arg_value
- {
- result = [val[0], val[2]]
- }
- | tLABEL arg_value
- {
- result = [new_sym(val[0]), val[1]]
- }
-
- operation: tIDENTIFIER
- | tCONSTANT
- | tFID
-
- operation2: tIDENTIFIER
- | tCONSTANT
- | tFID
- | op
-
- operation3: tIDENTIFIER
- | tFID
- | op
-
- dot_or_colon: tDOT
- | tCOLON2
-
- opt_terms: # none
- | terms
-
- opt_nl: # none
- | tNL
-
- trailer: # none
- | tNL
- | tCOMMA
-
- term: tSEMI
- | tNL
-
- terms: term
- | terms tSEMI
-
- none: # none
- {
- result = nil
- }
-end
-
----- inner
diff --git a/test/racc/assets/opt.y b/test/racc/assets/opt.y
deleted file mode 100644
index a011953a51..0000000000
--- a/test/racc/assets/opt.y
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# check options working
-#
-
-class Calcp
-
- prechigh
- left '*' '/'
- left '+' '-'
- preclow
-
- convert
- NUMBER 'Number'
- end
-
- options no_omit_action_call no_result_var
-
-rule
-
- target : exp | /* none */ { 0 } ;
-
- exp : exp '+' exp { chk(val[0] + val[2]) }
- | exp '-' exp { chk(val[0] - val[2]) }
- | exp '*' exp { chk(val[0] * val[2]) }
- | exp '/' exp { chk(val[0] / val[2]) }
- | '(' { $emb = true } exp ')'
- {
- raise 'must not happen' unless $emb
- val[2]
- }
- | '-' NUMBER { -val[1] }
- | NUMBER
- ;
-
-end
-
-----header
-
-class Number; end
-
-----inner
-
- def parse( src )
- @src = src
- do_parse
- end
-
- def next_token
- @src.shift
- end
-
- def initialize
- @yydebug = true
- end
-
- def chk( i )
- # p i
- i
- end
-
-----footer
-
-$parser = Calcp.new
-$test_number = 1
-
-def chk( src, ans )
- result = $parser.parse(src)
- raise "test #{$test_number} failed" unless result == ans
- $test_number += 1
-end
-
-chk(
- [ [Number, 9],
- [false, false],
- [false, false] ], 9
-)
-
-chk(
- [ [Number, 5],
- ['*', nil],
- [Number, 1],
- ['-', nil],
- [Number, 1],
- ['*', nil],
- [Number, 8],
- [false, false],
- [false, false] ], -3
-)
-
-chk(
- [ [Number, 5],
- ['+', nil],
- [Number, 2],
- ['-', nil],
- [Number, 5],
- ['+', nil],
- [Number, 2],
- ['-', nil],
- [Number, 5],
- [false, false],
- [false, false] ], -1
-)
-
-chk(
- [ ['-', nil],
- [Number, 4],
- [false, false],
- [false, false] ], -4
-)
-
-chk(
- [ [Number, 7],
- ['*', nil],
- ['(', nil],
- [Number, 4],
- ['+', nil],
- [Number, 3],
- [')', nil],
- ['-', nil],
- [Number, 9],
- [false, false],
- [false, false] ], 40
-)
diff --git a/test/racc/assets/percent.y b/test/racc/assets/percent.y
deleted file mode 100644
index 68d63583ca..0000000000
--- a/test/racc/assets/percent.y
+++ /dev/null
@@ -1,35 +0,0 @@
-class ScannerChecker
-rule
- target: A
- {
- i = 7
- i %= 4
- raise 'assert failed' unless i == 3
- tmp = %-This is percent string.-
- raise 'assert failed' unless tmp == 'This is percent string.'
- a = 5; b = 3
- assert_equal(2,(a%b)) #A
- # assert_equal(2,(a %b)) # is %-string
- assert_equal(2,(a% b)) #B
- assert_equal(2,(a % b)) #C
- }
-end
-
----- inner ----
-
- def parse
- @q = [[:A, 'A'], [false, '$']]
- do_parse
- end
-
- def next_token
- @q.shift
- end
-
- def assert_equal( expect, real )
- raise "expect #{expect.inspect} but #{real.inspect}" unless expect == real
- end
-
----- footer ----
-
-parser = ScannerChecker.new.parse
diff --git a/test/racc/assets/php_serialization.y b/test/racc/assets/php_serialization.y
deleted file mode 100644
index 99f78f2081..0000000000
--- a/test/racc/assets/php_serialization.y
+++ /dev/null
@@ -1,98 +0,0 @@
-# MIT License
-# See https://github.com/divoxx/ruby-php-serialization/blob/master/LICENSE.txt
-
-class PhpSerialization::Unserializer
-rule
-
- data : null ';' { @object = val[0] }
- | bool ';' { @object = val[0] }
- | integer ';' { @object = val[0] }
- | double ';' { @object = val[0] }
- | string ';' { @object = val[0] }
- | assoc_array { @object = val[0] }
- | object { @object = val[0] }
- ;
-
- null : 'N' { result = nil }
- ;
-
- bool : 'b' ':' NUMBER { result = Integer(val[2]) > 0 }
- ;
-
- integer : 'i' ':' NUMBER { result = Integer(val[2]) }
- ;
-
- double : 'd' ':' NUMBER { result = Float(val[2]) }
- ;
-
- string : 's' ':' NUMBER ':' STRING { result = val[4] }
- ;
-
- object : 'O' ':' NUMBER ':' STRING ':' NUMBER ':' '{' attribute_list '}'
- {
- if eval("defined?(#{val[4]})")
- result = Object.const_get(val[4]).new
-
- val[9].each do |(attr_name, value)|
- # Protected and private attributes will have a \0..\0 prefix
- attr_name = attr_name.gsub(/\A\\0[^\\]+\\0/, '')
- result.instance_variable_set("@#{attr_name}", value)
- end
- else
- klass_name = val[4].gsub(/^Struct::/, '')
- attr_names, values = [], []
-
- val[9].each do |(attr_name, value)|
- # Protected and private attributes will have a \0..\0 prefix
- attr_names << attr_name.gsub(/\A\\0[^\\]+\\0/, '')
- values << value
- end
-
- result = Struct.new(klass_name, *attr_names).new(*values)
- result.instance_variable_set("@_php_class", klass_name)
- end
- }
- ;
-
- attribute_list : attribute_list attribute { result = val[0] << val[1] }
- | { result = [] }
- ;
-
- attribute : data data { result = val }
- ;
-
- assoc_array : 'a' ':' NUMBER ':' '{' attribute_list '}'
- {
- # Checks if the keys are a sequence of integers
- idx = -1
- arr = val[5].all? { |(k,v)| k == (idx += 1) }
-
- if arr
- result = val[5].map { |(k,v)| v }
- else
- result = Hash[val[5]]
- end
- }
- ;
-
-end
-
----- header ----
-require 'php_serialization/tokenizer'
-
----- inner ----
- def initialize(tokenizer_klass = Tokenizer)
- @tokenizer_klass = tokenizer_klass
- end
-
- def run(string)
- @tokenizer = @tokenizer_klass.new(string)
- yyparse(@tokenizer, :each)
- return @object
- ensure
- @tokenizer = nil
- end
-
- def next_token
- @tokenizer.next_token
- end
diff --git a/test/racc/assets/recv.y b/test/racc/assets/recv.y
deleted file mode 100644
index b6e849dda9..0000000000
--- a/test/racc/assets/recv.y
+++ /dev/null
@@ -1,97 +0,0 @@
-# s/r 5, r/r 10
-class A
-rule
-
- content: RecvH received
- ;
-
- datetime: day
- ;
-
- msgid: '<' spec '>';
-
- day:
- | ATOM ','
- ;
-
- received: recvitem_list recvdatetime
- ;
-
- recvitem_list:
- | recvitem_list recvitem
- ;
-
- recvitem: by | via | with | for ;
-
- by:
- | BY domain
- ;
-
- via:
- | VIA ATOM
- ;
-
- with: WITH ATOM
- ;
-
- for:
- | FOR addr
- ;
-
- recvdatetime:
- | ';' datetime
- ;
-
- addr: mbox | group ;
-
- mboxes: mbox
- | mboxes ',' mbox
- ;
-
- mbox: spec
- | routeaddr
- | phrase routeaddr
- ;
-
- group: phrase ':' mboxes ';'
- ;
-
- routeaddr: '<' route spec '>'
- | '<' spec '>'
- ;
-
- route: at_domains ':' ;
-
- at_domains: '@' domain
- | at_domains ',' '@' domain
- ;
-
- spec: local '@' domain
- | local
- ;
-
- local: word
- | local '.' word
- ;
-
- domain: domword
- | domain '.' domword
- ;
-
- domword: atom
- | DOMLIT
- | DIGIT
- ;
-
- phrase: word
- | phrase word
- ;
-
- word: atom
- | QUOTED
- | DIGIT
- ;
-
- atom: ATOM | FROM | BY | VIA | WITH | ID | FOR ;
-
-end
diff --git a/test/racc/assets/riml.y b/test/racc/assets/riml.y
deleted file mode 100644
index 1d99b0fdb8..0000000000
--- a/test/racc/assets/riml.y
+++ /dev/null
@@ -1,665 +0,0 @@
-# Copyright (c) 2012-2014 by Luke Gruber
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Riml::Parser
-
-token IF ELSE ELSEIF THEN UNLESS END
-token WHILE UNTIL BREAK CONTINUE
-token TRY CATCH FINALLY
-token FOR IN
-token DEF DEF_BANG SPLAT_PARAM SPLAT_ARG CALL BUILTIN_COMMAND # such as echo "hi"
-token CLASS NEW DEFM DEFM_BANG SUPER
-token RIML_FILE_COMMAND RIML_CLASS_COMMAND
-token RETURN
-token NEWLINE
-token NUMBER
-token STRING_D STRING_S # single- and double-quoted
-token EX_LITERAL
-token REGEXP
-token TRUE FALSE
-token LET UNLET UNLET_BANG IDENTIFIER
-token DICT_VAL # like dict.key, 'key' is a DICT_VAL
-token SCOPE_MODIFIER SCOPE_MODIFIER_LITERAL SPECIAL_VAR_PREFIX
-token FINISH
-
-prechigh
- right '!'
- left '*' '/' '%'
- left '+' '-' '.'
- left '>' '>#' '>?' '<' '<#' '<?' '>=' '>=#' '>=?' '<=' '<=#' '<=?'
- left '==' '==?' '==#' '=~' '=~?' '=~#' '!~' '!~?' '!~#' '!=' '!=?' '!=#'
- left IS ISNOT
- left '&&'
- left '||'
- right '?'
- right '=' '+=' '-=' '.='
- left ','
- left IF UNLESS
-preclow
-
-# All rules
-rule
-
- Root:
- /* nothing */ { result = make_node(val) { |_| Riml::Nodes.new([]) } }
- | Terminator { result = make_node(val) { |_| Riml::Nodes.new([]) } }
- | Statements { result = val[0] }
- ;
-
- # any list of expressions
- Statements:
- Statement { result = make_node(val) { |v| Riml::Nodes.new([ v[0] ]) } }
- | Statements Terminator Statement { result = val[0] << val[2] }
- | Statements Terminator { result = val[0] }
- | Terminator Statements { result = make_node(val) { |v| Riml::Nodes.new(v[1]) } }
- ;
-
- # All types of expressions in Riml
- Statement:
- ExplicitCall { result = val[0] }
- | Def { result = val[0] }
- | Return { result = val[0] }
- | UnletVariable { result = val[0] }
- | ExLiteral { result = val[0] }
- | For { result = val[0] }
- | While { result = val[0] }
- | Until { result = val[0] }
- | Try { result = val[0] }
- | ClassDefinition { result = val[0] }
- | LoopKeyword { result = val[0] }
- | EndScript { result = val[0] }
- | RimlFileCommand { result = val[0] }
- | RimlClassCommand { result = val[0] }
- | MultiAssign { result = val[0] }
- | If { result = val[0] }
- | Unless { result = val[0] }
- | Expression { result = val[0] }
- ;
-
- Expression:
- ExpressionWithoutDictLiteral { result = val[0] }
- | Dictionary { result = val[0] }
- | Dictionary DictGetWithDotLiteral { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } }
- | BinaryOperator { result = val[0] }
- | Ternary { result = val[0] }
- | Assign { result = val[0] }
- | Super { result = val[0] }
- | '(' Expression ')' { result = make_node(val) { |v| Riml::WrapInParensNode.new(v[1]) } }
- ;
-
- ExpressionWithoutDictLiteral:
- UnaryOperator { result = val[0] }
- | DictGet { result = val[0] }
- | ListOrDictGet { result = val[0] }
- | AllVariableRetrieval { result = val[0] }
- | LiteralWithoutDictLiteral { result = val[0] }
- | Call { result = val[0] }
- | ObjectInstantiation { result = val[0] }
- | '(' ExpressionWithoutDictLiteral ')' { result = make_node(val) { |v| Riml::WrapInParensNode.new(v[1]) } }
- ;
-
- # for inside curly-brace variable names
- PossibleStringValue:
- String { result = val[0] }
- | DictGet { result = val[0] }
- | ListOrDictGet { result = val[0] }
- | AllVariableRetrieval { result = val[0] }
- | BinaryOperator { result = val[0] }
- | Ternary { result = val[0] }
- | Call { result = val[0] }
- ;
-
- Terminator:
- NEWLINE { result = nil }
- | ';' { result = nil }
- ;
-
- LiteralWithoutDictLiteral:
- Number { result = val[0] }
- | String { result = val[0] }
- | Regexp { result = val[0] }
- | List { result = val[0] }
- | ScopeModifierLiteral { result = val[0] }
- | TRUE { result = make_node(val) { |_| Riml::TrueNode.new } }
- | FALSE { result = make_node(val) { |_| Riml::FalseNode.new } }
- ;
-
- Number:
- NUMBER { result = make_node(val) { |v| Riml::NumberNode.new(v[0]) } }
- ;
-
- String:
- STRING_S { result = make_node(val) { |v| Riml::StringNode.new(v[0], :s) } }
- | STRING_D { result = make_node(val) { |v| Riml::StringNode.new(v[0], :d) } }
- | String STRING_S { result = make_node(val) { |v| Riml::StringLiteralConcatNode.new(v[0], Riml::StringNode.new(v[1], :s)) } }
- | String STRING_D { result = make_node(val) { |v| Riml::StringLiteralConcatNode.new(v[0], Riml::StringNode.new(v[1], :d)) } }
- ;
-
- Regexp:
- REGEXP { result = make_node(val) { |v| Riml::RegexpNode.new(v[0]) } }
- ;
-
- ScopeModifierLiteral:
- SCOPE_MODIFIER_LITERAL { result = make_node(val) { |v| Riml::ScopeModifierLiteralNode.new(v[0]) } }
- ;
-
- List:
- ListLiteral { result = make_node(val) { |v| Riml::ListNode.new(v[0]) } }
- ;
-
- ListUnpack:
- '[' ListItems ';' Expression ']' { result = make_node(val) { |v| Riml::ListUnpackNode.new(v[1] << v[3]) } }
- ;
-
- ListLiteral:
- '[' ListItems ']' { result = val[1] }
- | '[' ListItems ',' ']' { result = val[1] }
- ;
-
- ListItems:
- /* nothing */ { result = [] }
- | Expression { result = [val[0]] }
- | ListItems ',' Expression { result = val[0] << val[2] }
- ;
-
- Dictionary:
- DictionaryLiteral { result = make_node(val) { |v| Riml::DictionaryNode.new(v[0]) } }
- ;
-
- # {'key': 'value', 'key2': 'value2'}
- # Save as [['key', 'value'], ['key2', 'value2']] because ruby-1.8.7 offers
- # no guarantee for key-value pair ordering.
- DictionaryLiteral:
- '{' DictItems '}' { result = val[1] }
- | '{' DictItems ',' '}' { result = val[1] }
- ;
-
- # [[key, value], [key, value]]
- DictItems:
- /* nothing */ { result = [] }
- | DictItem { result = val }
- | DictItems ',' DictItem { result = val[0] << val[2] }
- ;
-
- # [key, value]
- DictItem:
- Expression ':' Expression { result = [val[0], val[2]] }
- ;
-
- DictGet:
- AllVariableRetrieval DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } }
- | ListOrDictGet DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } }
- | Call DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } }
- | '(' Expression ')' DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(Riml::WrapInParensNode.new(v[1]), v[3]) } }
- ;
-
- ListOrDictGet:
- ExpressionWithoutDictLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(v[0], v[1]) } }
- | '(' Expression ')' ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(Riml::WrapInParensNode.new(v[1]), v[3]) } }
- ;
-
- ListOrDictGetAssign:
- ExpressionWithoutDictLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(v[0], v[1]) } }
- ;
-
- ListOrDictGetWithBrackets:
- '[' Expression ']' { result = [val[1]] }
- | '[' SubList ']' { result = [val[1]] }
- | ListOrDictGetWithBrackets '[' Expression ']' { result = val[0] << val[2] }
- | ListOrDictGetWithBrackets '[' SubList ']' { result = val[0] << val[2] }
- ;
-
- SubList:
- Expression ':' Expression { result = make_node(val) { |v| Riml::SublistNode.new([v[0], Riml::LiteralNode.new(' : '), v[2]]) } }
- | Expression ':' { result = make_node(val) { |v| Riml::SublistNode.new([v[0], Riml::LiteralNode.new(' :')]) } }
- | ':' Expression { result = make_node(val) { |v| Riml::SublistNode.new([Riml::LiteralNode.new(': '), v[1]]) } }
- | ':' { result = make_node(val) { |_| Riml::SublistNode.new([Riml::LiteralNode.new(':')]) } }
- ;
-
- DictGetWithDot:
- DICT_VAL { result = [val[0]] }
- | DictGetWithDot DICT_VAL { result = val[0] << val[1] }
- ;
-
- DictGetWithDotLiteral:
- '.' IDENTIFIER { result = [val[1]] }
- | DictGetWithDotLiteral DICT_VAL { result = val[0] << val[1] }
- ;
-
- Call:
- Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], v[3]) } }
- | DictGet '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[2]) } }
- | BUILTIN_COMMAND '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[2]) } }
- | BUILTIN_COMMAND ArgListWithoutNothing { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[1]) } }
- | BUILTIN_COMMAND NEWLINE { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], []) } }
- | CALL '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(nil, nil, v[2]) } }
- ;
-
- ObjectInstantiationCall:
- Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], v[3]) } }
- | Scope DefCallIdentifier { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], []) } }
- ;
-
- RimlFileCommand:
- RIML_FILE_COMMAND '(' ArgList ')' { result = make_node(val) { |v| Riml::RimlFileCommandNode.new(nil, v[0], v[2]) } }
- | RIML_FILE_COMMAND ArgList { result = make_node(val) { |v| Riml::RimlFileCommandNode.new(nil, v[0], v[1]) } }
- ;
-
- RimlClassCommand:
- RIML_CLASS_COMMAND '(' ClassArgList ')' { result = make_node(val) { |v| Riml::RimlClassCommandNode.new(nil, v[0], v[2]) } }
- | RIML_CLASS_COMMAND ClassArgList { result = make_node(val) { |v| Riml::RimlClassCommandNode.new(nil, v[0], v[1]) } }
- ;
-
- ClassArgList:
- Scope IDENTIFIER { result = ["#{val[0]}#{val[1]}"] }
- | String { result = val }
- | ClassArgList ',' Scope IDENTIFIER { result = val[0].concat ["#{val[2]}#{val[3]}"] }
- ;
-
- ExplicitCall:
- CALL Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(v[1], v[2], v[4]) } }
- | CALL DictGet '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(nil, v[1], v[3]) } }
- ;
-
- Scope:
- SCOPE_MODIFIER { result = val[0] }
- | /* nothing */ { result = nil }
- ;
-
- # [SID, scope_modifier]
- SIDAndScope:
- Scope { result = [ nil, val[0] ] }
- | '<' IDENTIFIER '>' Scope { result = [ make_node(val) { |v| Riml::SIDNode.new(v[1]) }, val[3] ] }
- ;
-
- ArgList:
- /* nothing */ { result = [] }
- | ArgListWithoutNothingWithSplat { result = val[0] }
- ;
-
- ArgListWithSplat:
- /* nothing */ { result = [] }
- | ArgListWithoutNothingWithSplat { result = val[0] }
- ;
-
- ArgListWithoutNothingWithSplat:
- Expression { result = val }
- | SPLAT_ARG Expression { result = [ make_node(val) { |v| Riml::SplatNode.new(v[1]) } ] }
- | ArgListWithoutNothingWithSplat "," Expression { result = val[0] << val[2] }
- | ArgListWithoutNothingWithSplat "," SPLAT_ARG Expression { result = val[0] << make_node(val) { |v| Riml::SplatNode.new(v[3]) } }
- ;
-
- ArgListWithoutNothing:
- Expression { result = val }
- | ArgListWithoutNothing "," Expression { result = val[0] << val[2] }
- ;
-
- BinaryOperator:
- Expression '||' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '&&' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '==' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '==#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '==?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- # added by riml
- | Expression '===' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '!=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '!=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '!=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '=~' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '=~#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '=~?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '!~' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '!~#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '!~?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '>' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '>#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '>?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '>=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '>=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '>=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '<' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '<#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '<?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '<=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '<=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '<=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression '+' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '-' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '*' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '/' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '.' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression '%' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
-
- | Expression IS Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- | Expression ISNOT Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
- ;
-
- UnaryOperator:
- '!' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } }
- | '+' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } }
- | '-' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } }
- ;
-
- # ['=', LHS, RHS]
- Assign:
- LET AssignExpression { result = make_node(val) { |v| Riml::AssignNode.new(v[1][0], v[1][1], v[1][2]) } }
- | AssignExpression { result = make_node(val) { |v| Riml::AssignNode.new(v[0][0], v[0][1], v[0][2]) } }
- ;
-
- MultiAssign:
- Assign ',' Assign { result = make_node(val) { |v| Riml::MultiAssignNode.new([v[0], v[2]]) } }
- | MultiAssign ',' Assign { val[0].assigns << val[2]; result = val[0] }
- ;
-
- # ['=', AssignLHS, Expression]
- AssignExpression:
- AssignLHS '=' Expression { result = [val[1], val[0], val[2]] }
- | AssignLHS '+=' Expression { result = [val[1], val[0], val[2]] }
- | AssignLHS '-=' Expression { result = [val[1], val[0], val[2]] }
- | AssignLHS '.=' Expression { result = [val[1], val[0], val[2]] }
- ;
-
- AssignLHS:
- AllVariableRetrieval { result = val[0] }
- | List { result = val[0] }
- | ListUnpack { result = val[0] }
- | DictGet { result = val[0] }
- | ListOrDictGetAssign { result = val[0] }
- ;
-
- # retrieving the value of a variable
- VariableRetrieval:
- SimpleVariableRetrieval { result = val[0] }
- | SPECIAL_VAR_PREFIX IDENTIFIER { result = make_node(val) { |v| Riml::GetSpecialVariableNode.new(v[0], v[1]) } }
- | ScopeModifierLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::GetVariableByScopeAndDictNameNode.new(v[0], v[1]) } }
- ;
-
- SimpleVariableRetrieval:
- Scope IDENTIFIER { result = make_node(val) { |v| Riml::GetVariableNode.new(v[0], v[1]) } }
- ;
-
- AllVariableRetrieval:
- VariableRetrieval { result = val[0] }
- | Scope CurlyBraceName { result = make_node(val) { |v| Riml::GetCurlyBraceNameNode.new(v[0], v[1]) } }
- ;
-
- UnletVariable:
- UNLET VariableRetrieval { result = make_node(val) { |v| Riml::UnletVariableNode.new('!', [ v[1] ]) } }
- | UNLET_BANG VariableRetrieval { result = make_node(val) { |v| Riml::UnletVariableNode.new('!', [ v[1] ]) } }
- | UnletVariable VariableRetrieval { result = val[0] << val[1] }
- ;
-
- CurlyBraceName:
- CurlyBraceVarPart { result = make_node(val) { |v| Riml::CurlyBraceVariable.new([ v[0] ]) } }
- | IDENTIFIER CurlyBraceName { result = make_node(val) { |v| Riml::CurlyBraceVariable.new([ Riml::CurlyBracePart.new(v[0]), v[1] ]) } }
- | CurlyBraceName IDENTIFIER { result = val[0] << make_node(val) { |v| Riml::CurlyBracePart.new(v[1]) } }
- | CurlyBraceName CurlyBraceVarPart { result = val[0] << val[1] }
- ;
-
- CurlyBraceVarPart:
- '{' PossibleStringValue '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new(v[1]) } }
- | '{' PossibleStringValue CurlyBraceVarPart '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new([v[1], v[2]]) } }
- | '{' CurlyBraceVarPart PossibleStringValue '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new([v[1], v[2]]) } }
- ;
-
- # Method definition
- # [SID, scope_modifier, name, parameters, keyword, expressions]
- Def:
- FunctionType SIDAndScope DefCallIdentifier DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], [], v[3], v[4]) } }
- | FunctionType SIDAndScope DefCallIdentifier '(' ParamList ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], v[4], v[6], v[7]) } }
- | FunctionType SIDAndScope DefCallIdentifier '(' SPLAT_PARAM ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], [v[4]], v[6], v[7]) } }
- | FunctionType SIDAndScope DefCallIdentifier '(' ParamList ',' SPLAT_PARAM ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], v[4] << v[6], v[8], v[9]) } }
- ;
-
- FunctionType:
- DEF { result = "DefNode" }
- | DEF_BANG { result = "DefNode" }
- | DEFM { result = "DefMethodNode" }
- ;
-
- DefCallIdentifier:
- # use '' for first argument instead of nil in order to avoid a double scope-modifier
- CurlyBraceName { result = make_node(val) { |v| Riml::GetCurlyBraceNameNode.new('', v[0]) } }
- | IDENTIFIER { result = val[0] }
- ;
-
- # Example: 'range', 'dict' or 'abort' after function definition
- DefKeywords:
- IDENTIFIER { result = [val[0]] }
- | DefKeywords IDENTIFIER { result = val[0] << val[1] }
- | /* nothing */ { result = nil }
- ;
-
- ParamList:
- /* nothing */ { result = [] }
- | IDENTIFIER { result = val }
- | DefaultParam { result = val }
- | ParamList ',' IDENTIFIER { result = val[0] << val[2] }
- | ParamList ',' DefaultParam { result = val[0] << val[2] }
- ;
-
- DefaultParam:
- IDENTIFIER '=' Expression { result = make_node(val) { |v| Riml::DefaultParamNode.new(v[0], v[2]) } }
- ;
-
- Return:
- RETURN Returnable { result = make_node(val) { |v| Riml::ReturnNode.new(v[1]) } }
- | RETURN Returnable IF Expression { result = make_node(val) { |v| Riml::IfNode.new(v[3], Nodes.new([ReturnNode.new(v[1])])) } }
- | RETURN Returnable UNLESS Expression { result = make_node(val) { |v| Riml::UnlessNode.new(v[3], Nodes.new([ReturnNode.new(v[1])])) } }
- ;
-
- Returnable:
- /* nothing */ { result = nil }
- | Expression { result = val[0] }
- ;
-
- EndScript:
- FINISH { result = make_node(val) { |_| Riml::FinishNode.new } }
- ;
-
- # [expression, expressions]
- If:
- IF Expression IfBlock END { result = make_node(val) { |v| Riml::IfNode.new(v[1], v[2]) } }
- | IF Expression THEN Expression END { result = make_node(val) { |v| Riml::IfNode.new(v[1], Riml::Nodes.new([v[3]])) } }
- | Expression IF Expression { result = make_node(val) { |v| Riml::IfNode.new(v[2], Riml::Nodes.new([v[0]])) } }
- ;
-
- Unless:
- UNLESS Expression IfBlock END { result = make_node(val) { |v| Riml::UnlessNode.new(v[1], v[2]) } }
- | UNLESS Expression THEN Expression END { result = make_node(val) { |v| Riml::UnlessNode.new(v[1], Riml::Nodes.new([v[3]])) } }
- | Expression UNLESS Expression { result = make_node(val) { |v| Riml::UnlessNode.new(v[2], Riml::Nodes.new([v[0]])) } }
- ;
-
- Ternary:
- Expression '?' Expression ':' Expression { result = make_node(val) { |v| Riml::TernaryOperatorNode.new([v[0], v[2], v[4]]) } }
- ;
-
- While:
- WHILE Expression Block END { result = make_node(val) { |v| Riml::WhileNode.new(v[1], v[2]) } }
- ;
-
- LoopKeyword:
- BREAK { result = make_node(val) { |_| Riml::BreakNode.new } }
- | CONTINUE { result = make_node(val) { |_| Riml::ContinueNode.new } }
- ;
-
- Until:
- UNTIL Expression Block END { result = make_node(val) { |v| Riml::UntilNode.new(v[1], v[2]) } }
- ;
-
- For:
- FOR SimpleVariableRetrieval IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } }
- | FOR List IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } }
- | FOR ListUnpack IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } }
- ;
-
- Try:
- TRY Block END { result = make_node(val) { |v| Riml::TryNode.new(v[1], nil, nil) } }
- | TRY Block Catch END { result = make_node(val) { |v| Riml::TryNode.new(v[1], v[2], nil) } }
- | TRY Block Catch FINALLY Block END { result = make_node(val) { |v| Riml::TryNode.new(v[1], v[2], v[4]) } }
- ;
-
- Catch:
- /* nothing */ { result = nil }
- | CATCH Block { result = [ make_node(val) { |v| Riml::CatchNode.new(nil, v[1]) } ] }
- | CATCH Catchable Block { result = [ make_node(val) { |v| Riml::CatchNode.new(v[1], v[2]) } ] }
- | Catch CATCH Block { result = val[0] << make_node(val) { |v| Riml::CatchNode.new(nil, v[2]) } }
- | Catch CATCH Catchable Block { result = val[0] << make_node(val) { |v| Riml::CatchNode.new(v[2], v[3]) } }
- ;
-
- Catchable:
- Regexp { result = val[0] }
- | String { result = val[0] }
- ;
-
- # [expressions]
- # expressions list could contain an ElseNode, which contains expressions
- # itself
- Block:
- NEWLINE Statements { result = val[1] }
- | NEWLINE { result = make_node(val) { |_| Riml::Nodes.new([]) } }
- ;
-
- IfBlock:
- Block { result = val[0] }
- | NEWLINE Statements ElseBlock { result = val[1] << val[2] }
- | NEWLINE Statements ElseifBlock { result = val[1] << val[2] }
- | NEWLINE Statements ElseifBlock ElseBlock { result = val[1] << val[2] << val[3] }
- ;
-
- ElseBlock:
- ELSE NEWLINE Statements { result = make_node(val) { |v| Riml::ElseNode.new(v[2]) } }
- ;
-
- ElseifBlock:
- ELSEIF Expression NEWLINE Statements { result = make_node(val) { |v| Riml::Nodes.new([Riml::ElseifNode.new(v[1], v[3])]) } }
- | ElseifBlock ELSEIF Expression NEWLINE Statements { result = val[0] << make_node(val) { |v| Riml::ElseifNode.new(v[2], v[4]) } }
- ;
-
- ClassDefinition:
- CLASS Scope IDENTIFIER Block END { result = make_node(val) { |v| Riml::ClassDefinitionNode.new(v[1], v[2], nil, v[3]) } }
- | CLASS Scope IDENTIFIER '<' Scope IDENTIFIER Block END { result = make_node(val) { |v| Riml::ClassDefinitionNode.new(v[1], v[2], (v[4] || ClassDefinitionNode::DEFAULT_SCOPE_MODIFIER) + v[5], v[6]) } }
- ;
-
- ObjectInstantiation:
- NEW ObjectInstantiationCall { result = make_node(val) { |v| Riml::ObjectInstantiationNode.new(v[1]) } }
- ;
-
- Super:
- SUPER '(' ArgListWithSplat ')' { result = make_node(val) { |v| Riml::SuperNode.new(v[2], true) } }
- | SUPER { result = make_node(val) { |_| Riml::SuperNode.new([], false) } }
- ;
-
- ExLiteral:
- EX_LITERAL { result = make_node(val) { |v| Riml::ExLiteralNode.new(v[0]) } }
- ;
-end
-
----- header
- require File.expand_path("../lexer", __FILE__)
- require File.expand_path("../nodes", __FILE__)
- require File.expand_path("../errors", __FILE__)
- require File.expand_path("../ast_rewriter", __FILE__)
----- inner
- # This code will be put as-is in the parser class
-
- attr_accessor :ast_rewriter
- attr_writer :options
-
- # The Parser and AST_Rewriter share this same hash of options
- def options
- @options ||= {}
- end
-
- def self.ast_cache
- @ast_cache
- end
- @ast_cache = {}
-
- # parses tokens or code into output nodes
- def parse(object, ast_rewriter = Riml::AST_Rewriter.new, filename = nil, included = false)
- if (ast = self.class.ast_cache[filename])
- else
- if tokens?(object)
- @tokens = object
- elsif code?(object)
- @lexer = Riml::Lexer.new(object, filename, true)
- end
-
- begin
- ast = do_parse
- rescue Racc::ParseError => e
- raise unless @lexer
- if (invalid_token = @lexer.prev_token_is_keyword?)
- warning = "#{invalid_token.inspect} is a keyword, and cannot " \
- "be used as a variable name"
- end
- error_msg = e.message
- error_msg << "\nWARNING: #{warning}" if warning
- error = Riml::ParseError.new(error_msg, @lexer.filename, @lexer.lineno)
- raise error
- end
- self.class.ast_cache[filename] = ast if filename
- end
- @ast_rewriter ||= ast_rewriter
- return ast unless @ast_rewriter
- @ast_rewriter.ast = ast.dup
- @ast_rewriter.options ||= options
- @ast_rewriter.rewrite(filename, included)
- @ast_rewriter.ast
- end
-
- # get the next token from either the list of tokens provided, or
- # the lexer getting the next token
- def next_token
- return @tokens.shift unless @lexer
- token = @lexer.next_token
- if token && @lexer.parser_info
- @current_parser_info = token.pop
- end
- token
- end
-
- private
-
- def tokens?(object)
- Array === object
- end
-
- def code?(object)
- String === object
- end
-
- def make_node(racc_val)
- node = yield racc_val
- node.parser_info = @current_parser_info
- node
- end
diff --git a/test/racc/assets/rrconf.y b/test/racc/assets/rrconf.y
deleted file mode 100644
index baf9249a77..0000000000
--- a/test/racc/assets/rrconf.y
+++ /dev/null
@@ -1,14 +0,0 @@
-# 1 s/r conflict and 1 r/r conflict
-
-class A
-rule
-
-target: a
-
-a :
- | a list
-
-list :
- | list ITEM
-
-end
diff --git a/test/racc/assets/ruby18.y b/test/racc/assets/ruby18.y
deleted file mode 100644
index eceb253298..0000000000
--- a/test/racc/assets/ruby18.y
+++ /dev/null
@@ -1,1943 +0,0 @@
-# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org>
-#
-# Parts of the source are derived from ruby_parser:
-# Copyright (c) Ryan Davis, seattle.rb
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Parser::Ruby18
-
-token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
- kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
- kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kRETURN kYIELD kSUPER
- kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
- kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
- k__FILE__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tNTH_REF
- tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT tREGEXP_END tUPLUS
- tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ tGEQ tLEQ tANDOP
- tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF tASET tLSHFT tRSHFT
- tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN tLPAREN2 tRPAREN tLPAREN_ARG
- tLBRACK tLBRACK2 tRBRACK tLBRACE tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2
- tTILDE tPERCENT tDIVIDE tPLUS tMINUS tLT tGT tPIPE tBANG tCARET
- tLCURLY tRCURLY tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
- tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END tSTRING
- tSYMBOL tREGEXP_OPT tNL tEH tCOLON tCOMMA tSPACE tSEMI
-
-prechigh
- right tBANG tTILDE tUPLUS
- right tPOW
- right tUMINUS_NUM tUMINUS
- left tSTAR2 tDIVIDE tPERCENT
- left tPLUS tMINUS
- left tLSHFT tRSHFT
- left tAMPER2
- left tPIPE tCARET
- left tGT tGEQ tLT tLEQ
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
- left tANDOP
- left tOROP
- nonassoc tDOT2 tDOT3
- right tEH tCOLON
- left kRESCUE_MOD
- right tEQL tOP_ASGN
- nonassoc kDEFINED
- right kNOT
- left kOR kAND
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
- nonassoc tLBRACE_ARG
- nonassoc tLOWEST
-preclow
-
-rule
-
- program: compstmt
- {
- result = val[0]
- }
-
- bodystmt: compstmt opt_rescue opt_else opt_ensure
- {
- rescue_bodies = val[1]
- else_t, else_ = val[2]
- ensure_t, ensure_ = val[3]
-
- if rescue_bodies.empty? && !else_.nil?
- diagnostic :warning, :useless_else, nil, else_t
- end
-
- result = @builder.begin_body(val[0],
- rescue_bodies,
- else_t, else_,
- ensure_t, ensure_)
- }
-
- compstmt: stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- stmts: # nothing
- {
- result = []
- }
- | stmt
- {
- result = [ val[0] ]
- }
- | error stmt
- {
- result = [ val[1] ]
- }
- | stmts terms stmt
- {
- result = val[0] << val[2]
- }
-
- stmt: kALIAS fitem
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = @builder.alias(val[0], val[1], val[3])
- }
- | kALIAS tGVAR tGVAR
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.gvar(val[2]))
- }
- | kALIAS tGVAR tBACK_REF
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.back_ref(val[2]))
- }
- | kALIAS tGVAR tNTH_REF
- {
- diagnostic :error, :nth_ref_alias, nil, val[2]
- }
- | kUNDEF undef_list
- {
- result = @builder.undef_method(val[0], val[1])
- }
- | stmt kIF_MOD expr_value
- {
- result = @builder.condition_mod(val[0], nil,
- val[1], val[2])
- }
- | stmt kUNLESS_MOD expr_value
- {
- result = @builder.condition_mod(nil, val[0],
- val[1], val[2])
- }
- | stmt kWHILE_MOD expr_value
- {
- result = @builder.loop_mod(:while, val[0], val[1], val[2])
- }
- | stmt kUNTIL_MOD expr_value
- {
- result = @builder.loop_mod(:until, val[0], val[1], val[2])
- }
- | stmt kRESCUE_MOD stmt
- {
- rescue_body = @builder.rescue_body(val[1],
- nil, nil, nil,
- nil, val[2])
-
- result = @builder.begin_body(val[0], [ rescue_body ])
- }
- | klBEGIN tLCURLY compstmt tRCURLY
- {
- if in_def?
- diagnostic :error, :begin_in_method, nil, val[0]
- end
-
- result = @builder.preexe(val[0], val[1], val[2], val[3])
- }
- | klEND tLCURLY compstmt tRCURLY
- {
- result = @builder.postexe(val[0], val[1], val[2], val[3])
- }
- | lhs tEQL command_call
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | mlhs tEQL command_call
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN command_call
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | backref tOP_ASGN command_call
- {
- @builder.op_assign(val[0], val[1], val[2])
- }
- | lhs tEQL mrhs
- {
- result = @builder.assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | mlhs tEQL arg_value
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | mlhs tEQL mrhs
- {
- result = @builder.multi_assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | expr
-
- expr: command_call
- | expr kAND expr
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | expr kOR expr
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kNOT expr
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | tBANG command_call
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | arg
-
- expr_value: expr
-
- command_call: command
- | block_command
- | kRETURN call_args
- {
- result = @builder.keyword_cmd(:return, val[0],
- nil, val[1], nil)
- }
- | kBREAK call_args
- {
- result = @builder.keyword_cmd(:break, val[0],
- nil, val[1], nil)
- }
- | kNEXT call_args
- {
- result = @builder.keyword_cmd(:next, val[0],
- nil, val[1], nil)
- }
-
- block_command: block_call
- | block_call tDOT operation2 command_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | block_call tCOLON2 operation2 command_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
-
- cmd_brace_block: tLBRACE_ARG
- {
- @static_env.extend_dynamic
- }
- opt_block_var compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- command: operation command_args =tLOWEST
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
- }
- | operation command_args cmd_brace_block
- {
- lparen_t, args, rparen_t = val[1]
- method_call = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
-
- begin_t, block_args, body, end_t = val[2]
- result = @builder.block(method_call,
- begin_t, block_args, body, end_t)
- }
- | primary_value tDOT operation2 command_args =tLOWEST
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- }
- | primary_value tDOT operation2 command_args cmd_brace_block
- {
- lparen_t, args, rparen_t = val[3]
- method_call = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- begin_t, block_args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, block_args, body, end_t)
- }
- | primary_value tCOLON2 operation2 command_args =tLOWEST
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation2 command_args cmd_brace_block
- {
- lparen_t, args, rparen_t = val[3]
- method_call = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- begin_t, block_args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, block_args, body, end_t)
- }
- | kSUPER command_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
- }
- | kYIELD command_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:yield, val[0],
- lparen_t, args, rparen_t)
- }
-
- mlhs: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_entry tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_entry: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_entry tRPAREN
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- mlhs_basic: mlhs_head
- {
- result = val[0]
- }
- | mlhs_head mlhs_item
- {
- result = val[0] << val[1]
- }
- | mlhs_head tSTAR mlhs_node
- {
- result = val[0] << @builder.splat(val[1], val[2])
- }
- | mlhs_head tSTAR
- {
- result = val[0] << @builder.splat(val[1])
- }
- | tSTAR mlhs_node
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | tSTAR
- {
- result = [ @builder.splat(val[0]) ]
- }
-
- mlhs_item: mlhs_node
- | tLPAREN mlhs_entry tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_head: mlhs_item tCOMMA
- {
- result = [ val[0] ]
- }
- | mlhs_head mlhs_item tCOMMA
- {
- result = val[0] << val[1]
- }
-
- mlhs_node: variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 aref_args tRBRACK
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- lhs: variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 aref_args tRBRACK
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- cname: tIDENTIFIER
- {
- diagnostic :error, :module_name_const, nil, val[0]
- }
- | tCONSTANT
-
- cpath: tCOLON3 cname
- {
- result = @builder.const_global(val[0], val[1])
- }
- | cname
- {
- result = @builder.const(val[0])
- }
- | primary_value tCOLON2 cname
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
-
- fname: tIDENTIFIER | tCONSTANT | tFID
- | op
- | reswords
-
- fsym: fname
- {
- result = @builder.symbol(val[0])
- }
- | symbol
-
- fitem: fsym
- | dsym
-
- undef_list: fitem
- {
- result = [ val[0] ]
- }
- | undef_list tCOMMA
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = val[0] << val[3]
- }
-
- op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
- | tMATCH | tGT | tGEQ | tLT | tLEQ | tLSHFT
- | tRSHFT | tPLUS | tMINUS | tSTAR2 | tSTAR | tDIVIDE
- | tPERCENT | tPOW | tTILDE | tUPLUS | tUMINUS | tAREF
- | tASET | tBACK_REF2
-
- reswords: k__LINE__ | k__FILE__ | klBEGIN | klEND | kALIAS | kAND
- | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | kDEFINED
- | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE
- | kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT
- | kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF
- | kSUPER | kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD
- | kIF | kUNLESS | kWHILE | kUNTIL
-
- arg: lhs tEQL arg
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.assign(val[0], val[1], rescue_)
- }
- | var_lhs tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
- {
- diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
- }
- | tCOLON3 tCONSTANT tOP_ASGN arg
- {
- diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
- }
- | backref tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | arg tDOT2 arg
- {
- result = @builder.range_inclusive(val[0], val[1], val[2])
- }
- | arg tDOT3 arg
- {
- result = @builder.range_exclusive(val[0], val[1], val[2])
- }
- | arg tPLUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMINUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tSTAR2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tDIVIDE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPERCENT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPOW arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tUMINUS_NUM tINTEGER tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.integer(val[1]),
- val[2], val[3]))
- }
- | tUMINUS_NUM tFLOAT tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.float(val[1]),
- val[2], val[3]))
- }
- | tUPLUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | tUMINUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tPIPE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCARET arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tAMPER2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCMP arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tNEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMATCH arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tNMATCH arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tBANG arg
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | tTILDE arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tLSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tRSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tANDOP arg
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | arg tOROP arg
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kDEFINED opt_nl arg
- {
- result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
- }
- | arg tEH arg tCOLON arg
- {
- result = @builder.ternary(val[0], val[1],
- val[2], val[3], val[4])
- }
- | primary
-
- arg_value: arg
-
- aref_args: none
- | command opt_nl
- {
- result = [ val[0] ]
- }
- | args trailer
- {
- result = val[0]
- }
- | args tCOMMA tSTAR arg opt_nl
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
- | assocs trailer
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
- | tSTAR arg opt_nl
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
-
- paren_args: tLPAREN2 none tRPAREN
- {
- result = [ val[0], [], val[2] ]
- }
- | tLPAREN2 call_args opt_nl tRPAREN
- {
- result = [ val[0], val[1], val[3] ]
- }
- | tLPAREN2 block_call opt_nl tRPAREN
- {
- result = [ val[0], [ val[1] ], val[3] ]
- }
- | tLPAREN2 args tCOMMA block_call opt_nl tRPAREN
- {
- result = [ val[0], val[1] << val[3], val[5] ]
- }
-
- opt_paren_args: # nothing
- {
- result = [ nil, [], nil ]
- }
- | paren_args
-
- call_args: command
- {
- result = [ val[0] ]
- }
- | args opt_block_arg
- {
- result = val[0].concat(val[1])
- }
- | args tCOMMA tSTAR arg_value opt_block_arg
- {
- result = val[0].concat(
- [ @builder.splat(val[2], val[3]),
- *val[4] ])
- }
- | assocs opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil),
- *val[1] ]
- }
- | assocs tCOMMA tSTAR arg_value opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil),
- @builder.splat(val[2], val[3]),
- *val[4] ]
- }
- | args tCOMMA assocs opt_block_arg
- {
- result = val[0].concat(
- [ @builder.associate(nil, val[2], nil),
- *val[3] ])
- }
- | args tCOMMA assocs tCOMMA tSTAR arg opt_block_arg
- {
- result = val[0].concat(
- [ @builder.associate(nil, val[2], nil),
- @builder.splat(val[4], val[5]),
- *val[6] ])
- }
- | tSTAR arg_value opt_block_arg
- {
- result = [ @builder.splat(val[0], val[1]),
- *val[2] ]
- }
- | block_arg
- {
- result = [ val[0] ]
- }
-
- call_args2: arg_value tCOMMA args opt_block_arg
- {
- result = [ val[0], *val[2].concat(val[3]) ]
- }
- | arg_value tCOMMA block_arg
- {
- result = [ val[0], val[2] ]
- }
- | arg_value tCOMMA tSTAR arg_value opt_block_arg
- {
- result = [ val[0],
- @builder.splat(val[2], val[3]),
- *val[4] ]
- }
- | arg_value tCOMMA args tCOMMA tSTAR arg_value opt_block_arg
- {
- result = [ val[0],
- *val[2].
- push(@builder.splat(val[4], val[5])).
- concat(val[6]) ]
- }
- | assocs opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil),
- *val[1] ]
- }
- | assocs tCOMMA tSTAR arg_value opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil),
- @builder.splat(val[2], val[3]),
- *val[4] ]
- }
- | arg_value tCOMMA assocs opt_block_arg
- {
- result = [ val[0],
- @builder.associate(nil, val[2], nil),
- *val[3] ]
- }
- | arg_value tCOMMA args tCOMMA assocs opt_block_arg
- {
- result = [ val[0],
- *val[2].
- push(@builder.associate(nil, val[4], nil)).
- concat(val[5]) ]
- }
- | arg_value tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg
- {
- result = [ val[0],
- @builder.associate(nil, val[2], nil),
- @builder.splat(val[4], val[5]),
- *val[6] ]
- }
- | arg_value tCOMMA args tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg
- {
- result = [ val[0],
- *val[2].
- push(@builder.associate(nil, val[4], nil)).
- push(@builder.splat(val[6], val[7])).
- concat(val[8]) ]
- }
- | tSTAR arg_value opt_block_arg
- {
- result = [ @builder.splat(val[0], val[1]),
- *val[2] ]
- }
- | block_arg
- {
- result = [ val[0] ]
- }
-
- command_args: {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.push(true)
- }
- open_args
- {
- @lexer.cmdarg = val[0]
-
- result = val[1]
- }
-
- open_args: call_args
- {
- result = [ nil, val[0], nil ]
- }
- | tLPAREN_ARG
- {
- @lexer.state = :expr_endarg
- }
- tRPAREN
- {
- result = [ val[0], [], val[2] ]
- }
- | tLPAREN_ARG call_args2
- {
- @lexer.state = :expr_endarg
- }
- tRPAREN
- {
- result = [ val[0], val[1], val[3] ]
- }
-
- block_arg: tAMPER arg_value
- {
- result = @builder.block_pass(val[0], val[1])
- }
-
- opt_block_arg: tCOMMA block_arg
- {
- result = [ val[1] ]
- }
- | # nothing
- {
- result = []
- }
-
- args: arg_value
- {
- result = [ val[0] ]
- }
- | args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
-
- mrhs: args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
-
- primary: literal
- | strings
- | xstring
- | regexp
- | words
- | qwords
- | var_ref
- | backref
- | tFID
- {
- result = @builder.call_method(nil, nil, val[0])
- }
- | kBEGIN bodystmt kEND
- {
- result = @builder.begin_keyword(val[0], val[1], val[2])
- }
- | tLPAREN_ARG expr
- {
- @lexer.state = :expr_endarg
- }
- opt_nl tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[4])
- }
- | tLPAREN compstmt tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.const_global(val[0], val[1])
- }
- | primary_value tLBRACK2 aref_args tRBRACK
- {
- result = @builder.index(val[0], val[1], val[2], val[3])
- }
- | tLBRACK aref_args tRBRACK
- {
- result = @builder.array(val[0], val[1], val[2])
- }
- | tLBRACE assoc_list tRCURLY
- {
- result = @builder.associate(val[0], val[1], val[2])
- }
- | kRETURN
- {
- result = @builder.keyword_cmd(:return, val[0])
- }
- | kYIELD tLPAREN2 call_args tRPAREN
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
- }
- | kYIELD tLPAREN2 tRPAREN
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
- }
- | kYIELD
- {
- result = @builder.keyword_cmd(:yield, val[0])
- }
- | kDEFINED opt_nl tLPAREN2 expr tRPAREN
- {
- result = @builder.keyword_cmd(:defined?, val[0],
- val[2], [ val[3] ], val[4])
- }
- | operation brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0])
-
- begin_t, args, body, end_t = val[1]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | method_call
- | method_call brace_block
- {
- begin_t, args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, args, body, end_t)
- }
- | kIF expr_value then compstmt if_tail kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, val[5])
- }
- | kUNLESS expr_value then compstmt opt_else kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- else_, else_t,
- val[3], val[5])
- }
- | kWHILE
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:while, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kUNTIL
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:until, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kCASE expr_value opt_terms case_body kEND
- {
- when_bodies = val[3][0..-2]
- else_t, else_body = val[3][-1]
-
- result = @builder.case(val[0], val[1],
- when_bodies, else_t, else_body,
- val[4])
- }
- | kCASE opt_terms case_body kEND
- {
- when_bodies = val[2][0..-2]
- else_t, else_body = val[2][-1]
-
- result = @builder.case(val[0], nil,
- when_bodies, else_t, else_body,
- val[3])
- }
- | kCASE opt_terms kELSE compstmt kEND
- {
- result = @builder.case(val[0], nil,
- [], val[2], val[3],
- val[4])
- }
- | kFOR for_var kIN
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.for(val[0], val[1],
- val[2], val[4],
- val[5], val[7], val[8])
- }
- | kCLASS cpath superclass
- {
- @static_env.extend_static
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :class_in_def, nil, val[0]
- end
-
- lt_t, superclass = val[2]
- result = @builder.def_class(val[0], val[1],
- lt_t, superclass,
- val[4], val[5])
-
- @static_env.unextend
- }
- | kCLASS tLSHFT expr term
- {
- result = @def_level
- @def_level = 0
-
- @static_env.extend_static
- }
- bodystmt kEND
- {
- result = @builder.def_sclass(val[0], val[1], val[2],
- val[5], val[6])
-
- @static_env.unextend
-
- @def_level = val[4]
- }
- | kMODULE cpath
- {
- @static_env.extend_static
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :module_in_def, nil, val[0]
- end
-
- result = @builder.def_module(val[0], val[1],
- val[3], val[4])
-
- @static_env.unextend
- }
- | kDEF fname
- {
- @def_level += 1
- @static_env.extend_static
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_method(val[0], val[1],
- val[3], val[4], val[5])
-
- @static_env.unextend
- @def_level -= 1
- }
- | kDEF singleton dot_or_colon
- {
- @lexer.state = :expr_fname
- }
- fname
- {
- @def_level += 1
- @static_env.extend_static
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_singleton(val[0], val[1], val[2],
- val[4], val[6], val[7], val[8])
-
- @static_env.unextend
- @def_level -= 1
- }
- | kBREAK
- {
- result = @builder.keyword_cmd(:break, val[0])
- }
- | kNEXT
- {
- result = @builder.keyword_cmd(:next, val[0])
- }
- | kREDO
- {
- result = @builder.keyword_cmd(:redo, val[0])
- }
- | kRETRY
- {
- result = @builder.keyword_cmd(:retry, val[0])
- }
-
- primary_value: primary
-
- then: term
- | tCOLON
- | kTHEN
- | term kTHEN
- {
- result = val[1]
- }
-
- do: term
- | tCOLON
- | kDO_COND
-
- if_tail: opt_else
- | kELSIF expr_value then compstmt if_tail
- {
- else_t, else_ = val[4]
- result = [ val[0],
- @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, nil),
- ]
- }
-
- opt_else: none
- | kELSE compstmt
- {
- result = val
- }
-
- for_var: lhs
- | mlhs
-
- block_par: mlhs_item
- {
- result = [ @builder.arg_expr(val[0]) ]
- }
- | block_par tCOMMA mlhs_item
- {
- result = val[0] << @builder.arg_expr(val[2])
- }
-
- block_var: block_par
- | block_par tCOMMA
- | block_par tCOMMA tAMPER lhs
- {
- result = val[0].
- push(@builder.blockarg_expr(val[2], val[3]))
- }
- | block_par tCOMMA tSTAR lhs tCOMMA tAMPER lhs
- {
- result = val[0].
- push(@builder.restarg_expr(val[2], val[3])).
- push(@builder.blockarg_expr(val[5], val[6]))
- }
- | block_par tCOMMA tSTAR tCOMMA tAMPER lhs
- {
- result = val[0].
- push(@builder.restarg_expr(val[2])).
- push(@builder.blockarg_expr(val[4], val[5]))
- }
- | block_par tCOMMA tSTAR lhs
- {
- result = val[0].
- push(@builder.restarg_expr(val[2], val[3]))
- }
- | block_par tCOMMA tSTAR
- {
- result = val[0].
- push(@builder.restarg_expr(val[2]))
- }
- | tSTAR lhs tCOMMA tAMPER lhs
- {
- result = [ @builder.restarg_expr(val[0], val[1]),
- @builder.blockarg_expr(val[3], val[4]) ]
- }
- | tSTAR tCOMMA tAMPER lhs
- {
- result = [ @builder.restarg_expr(val[0]),
- @builder.blockarg_expr(val[2], val[3]) ]
- }
- | tSTAR lhs
- {
- result = [ @builder.restarg_expr(val[0], val[1]) ]
- }
- | tSTAR
- {
- result = [ @builder.restarg_expr(val[0]) ]
- }
- | tAMPER lhs
- {
- result = [ @builder.blockarg_expr(val[0], val[1]) ]
- }
- ;
-
- opt_block_var: # nothing
- {
- result = @builder.args(nil, [], nil)
- }
- | tPIPE tPIPE
- {
- result = @builder.args(val[0], [], val[1])
- }
- | tOROP
- {
- result = @builder.args(val[0], [], val[0])
- }
- | tPIPE block_var tPIPE
- {
- result = @builder.args(val[0], val[1], val[2], false)
- }
-
- do_block: kDO_BLOCK
- {
- @static_env.extend_dynamic
- }
- opt_block_var compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- block_call: command do_block
- {
- begin_t, block_args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, block_args, body, end_t)
- }
- | block_call tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | block_call tCOLON2 operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
-
- method_call: operation paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
- }
- | primary_value tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation2 paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation3
- {
- result = @builder.call_method(val[0], val[1], val[2])
- }
- | kSUPER paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
- }
- | kSUPER
- {
- result = @builder.keyword_cmd(:zsuper, val[0])
- }
-
- brace_block: tLCURLY
- {
- @static_env.extend_dynamic
- }
- opt_block_var compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
- | kDO
- {
- @static_env.extend_dynamic
- }
- opt_block_var compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- case_body: kWHEN when_args then compstmt cases
- {
- result = [ @builder.when(val[0], val[1], val[2], val[3]),
- *val[4] ]
- }
-
- when_args: args
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
-
- cases: opt_else
- {
- result = [ val[0] ]
- }
- | case_body
-
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
- {
- assoc_t, exc_var = val[2]
-
- if val[1]
- exc_list = @builder.array(nil, val[1], nil)
- end
-
- result = [ @builder.rescue_body(val[0],
- exc_list, assoc_t, exc_var,
- val[3], val[4]),
- *val[5] ]
- }
- | # nothing
- {
- result = []
- }
-
- exc_list: arg_value
- {
- result = [ val[0] ]
- }
- | mrhs
- | none
-
- exc_var: tASSOC lhs
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- opt_ensure: kENSURE compstmt
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- literal: numeric
- | symbol
- | dsym
-
- strings: string
- {
- result = @builder.string_compose(nil, val[0], nil)
- }
-
- string: string1
- {
- result = [ val[0] ]
- }
- | string string1
- {
- result = val[0] << val[1]
- }
-
- string1: tSTRING_BEG string_contents tSTRING_END
- {
- result = @builder.string_compose(val[0], val[1], val[2])
- }
- | tSTRING
- {
- result = @builder.string(val[0])
- }
-
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
- {
- result = @builder.xstring_compose(val[0], val[1], val[2])
- }
-
- regexp: tREGEXP_BEG xstring_contents tSTRING_END tREGEXP_OPT
- {
- opts = @builder.regexp_options(val[3])
- result = @builder.regexp_compose(val[0], val[1], val[2], opts)
- }
-
- words: tWORDS_BEG word_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- word_list: # nothing
- {
- result = []
- }
- | word_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- word: string_content
- {
- result = [ val[0] ]
- }
- | word string_content
- {
- result = val[0] << val[1]
- }
-
- qwords: tQWORDS_BEG qword_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- qword_list: # nothing
- {
- result = []
- }
- | qword_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.string_internal(val[1])
- }
-
- string_contents: # nothing
- {
- result = []
- }
- | string_contents string_content
- {
- result = val[0] << val[1]
- }
-
-xstring_contents: # nothing
- {
- result = []
- }
- | xstring_contents string_content
- {
- result = val[0] << val[1]
- }
-
- string_content: tSTRING_CONTENT
- {
- result = @builder.string_internal(val[0])
- }
- | tSTRING_DVAR string_dvar
- {
- result = val[1]
- }
- | tSTRING_DBEG
- {
- @lexer.cond.push(false)
- @lexer.cmdarg.push(false)
- }
- compstmt tRCURLY
- {
- @lexer.cond.lexpop
- @lexer.cmdarg.lexpop
-
- result = @builder.begin(val[0], val[2], val[3])
- }
-
- string_dvar: tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
- | backref
-
-
- symbol: tSYMBOL
- {
- result = @builder.symbol(val[0])
- }
-
- dsym: tSYMBEG xstring_contents tSTRING_END
- {
- result = @builder.symbol_compose(val[0], val[1], val[2])
- }
-
- numeric: tINTEGER
- {
- result = @builder.integer(val[0])
- }
- | tFLOAT
- {
- result = @builder.float(val[0])
- }
- | tUMINUS_NUM tINTEGER =tLOWEST
- {
- result = @builder.negate(val[0],
- @builder.integer(val[1]))
- }
- | tUMINUS_NUM tFLOAT =tLOWEST
- {
- result = @builder.negate(val[0],
- @builder.float(val[1]))
- }
-
- variable: tIDENTIFIER
- {
- result = @builder.ident(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
- | tCONSTANT
- {
- result = @builder.const(val[0])
- }
- | kNIL
- {
- result = @builder.nil(val[0])
- }
- | kSELF
- {
- result = @builder.self(val[0])
- }
- | kTRUE
- {
- result = @builder.true(val[0])
- }
- | kFALSE
- {
- result = @builder.false(val[0])
- }
- | k__FILE__
- {
- result = @builder.__FILE__(val[0])
- }
- | k__LINE__
- {
- result = @builder.__LINE__(val[0])
- }
-
- var_ref: variable
- {
- result = @builder.accessible(val[0])
- }
-
- var_lhs: variable
- {
- result = @builder.assignable(val[0])
- }
-
- backref: tNTH_REF
- {
- result = @builder.nth_ref(val[0])
- }
- | tBACK_REF
- {
- result = @builder.back_ref(val[0])
- }
-
- superclass: term
- {
- result = nil
- }
- | tLT expr_value term
- {
- result = [ val[0], val[1] ]
- }
- | error term
- {
- yyerrok
- result = nil
- }
-
- f_arglist: tLPAREN2 f_args opt_nl tRPAREN
- {
- result = @builder.args(val[0], val[1], val[3])
-
- @lexer.state = :expr_beg
- }
- | f_args term
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
- | # nothing
- {
- result = []
- }
-
- f_norm_arg: tCONSTANT
- {
- diagnostic :error, :argument_const, nil, val[0]
- }
- | tIVAR
- {
- diagnostic :error, :argument_ivar, nil, val[0]
- }
- | tGVAR
- {
- diagnostic :error, :argument_gvar, nil, val[0]
- }
- | tCVAR
- {
- diagnostic :error, :argument_cvar, nil, val[0]
- }
- | tIDENTIFIER
- {
- @static_env.declare val[0][0]
-
- result = @builder.arg(val[0])
- }
-
- f_arg: f_norm_arg
- {
- result = [ val[0] ]
- }
- | f_arg tCOMMA f_norm_arg
- {
- result = val[0] << val[2]
- }
-
- f_opt: tIDENTIFIER tEQL arg_value
- {
- @static_env.declare val[0][0]
-
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_optarg: f_opt
- {
- result = [ val[0] ]
- }
- | f_optarg tCOMMA f_opt
- {
- result = val[0] << val[2]
- }
-
- restarg_mark: tSTAR2 | tSTAR
-
- f_rest_arg: restarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | restarg_mark
- {
- result = [ @builder.restarg(val[0]) ]
- }
-
- blkarg_mark: tAMPER2 | tAMPER
-
- f_block_arg: blkarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = @builder.blockarg(val[0], val[1])
- }
-
- opt_f_block_arg: tCOMMA f_block_arg
- {
- result = [ val[1] ]
- }
- | # nothing
- {
- result = []
- }
-
- singleton: var_ref
- | tLPAREN2 expr opt_nl tRPAREN
- {
- result = val[1]
- }
-
- assoc_list: # nothing
- {
- result = []
- }
- | assocs trailer
- {
- result = val[0]
- }
- | args trailer
- {
- result = @builder.pair_list_18(val[0])
- }
-
- assocs: assoc
- {
- result = [ val[0] ]
- }
- | assocs tCOMMA assoc
- {
- result = val[0] << val[2]
- }
-
- assoc: arg_value tASSOC arg_value
- {
- result = @builder.pair(val[0], val[1], val[2])
- }
-
- operation: tIDENTIFIER | tCONSTANT | tFID
- operation2: tIDENTIFIER | tCONSTANT | tFID | op
- operation3: tIDENTIFIER | tFID | op
- dot_or_colon: tDOT | tCOLON2
- opt_terms: | terms
- opt_nl: | tNL
- trailer: | tNL | tCOMMA
-
- term: tSEMI
- {
- yyerrok
- }
- | tNL
-
- terms: term
- | terms tSEMI
-
- none: # nothing
- {
- result = nil
- }
-
-end
-
----- header
-
-require 'parser'
-
----- inner
-
- def version
- 18
- end
-
- def default_encoding
- Encoding::BINARY if defined? Encoding
- end
diff --git a/test/racc/assets/ruby19.y b/test/racc/assets/ruby19.y
deleted file mode 100644
index b405c952e7..0000000000
--- a/test/racc/assets/ruby19.y
+++ /dev/null
@@ -1,2174 +0,0 @@
-# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org>
-#
-# Parts of the source are derived from ruby_parser:
-# Copyright (c) Ryan Davis, seattle.rb
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Parser::Ruby19
-
-token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
- kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
- kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
- kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
- kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
- k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
- tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
- tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
- tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
- tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
- tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
- tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
- tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
- tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
- tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
- tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG
- tCHARACTER
-
-prechigh
- right tBANG tTILDE tUPLUS
- right tPOW
- right tUMINUS_NUM tUMINUS
- left tSTAR2 tDIVIDE tPERCENT
- left tPLUS tMINUS
- left tLSHFT tRSHFT
- left tAMPER2
- left tPIPE tCARET
- left tGT tGEQ tLT tLEQ
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
- left tANDOP
- left tOROP
- nonassoc tDOT2 tDOT3
- right tEH tCOLON
- left kRESCUE_MOD
- right tEQL tOP_ASGN
- nonassoc kDEFINED
- right kNOT
- left kOR kAND
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
- nonassoc tLBRACE_ARG
- nonassoc tLOWEST
-preclow
-
-rule
-
- program: top_compstmt
-
- top_compstmt: top_stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- top_stmts: # nothing
- {
- result = []
- }
- | top_stmt
- {
- result = [ val[0] ]
- }
- | top_stmts terms top_stmt
- {
- result = val[0] << val[2]
- }
- | error top_stmt
- {
- result = [ val[1] ]
- }
-
- top_stmt: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- result = @builder.preexe(val[0], val[1], val[2], val[3])
- }
-
- bodystmt: compstmt opt_rescue opt_else opt_ensure
- {
- rescue_bodies = val[1]
- else_t, else_ = val[2]
- ensure_t, ensure_ = val[3]
-
- if rescue_bodies.empty? && !else_.nil?
- diagnostic :warning, :useless_else, nil, else_t
- end
-
- result = @builder.begin_body(val[0],
- rescue_bodies,
- else_t, else_,
- ensure_t, ensure_)
- }
-
- compstmt: stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- stmts: # nothing
- {
- result = []
- }
- | stmt
- {
- result = [ val[0] ]
- }
- | stmts terms stmt
- {
- result = val[0] << val[2]
- }
- | error stmt
- {
- result = [ val[1] ]
- }
-
- stmt: kALIAS fitem
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = @builder.alias(val[0], val[1], val[3])
- }
- | kALIAS tGVAR tGVAR
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.gvar(val[2]))
- }
- | kALIAS tGVAR tBACK_REF
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.back_ref(val[2]))
- }
- | kALIAS tGVAR tNTH_REF
- {
- diagnostic :error, :nth_ref_alias, nil, val[2]
- }
- | kUNDEF undef_list
- {
- result = @builder.undef_method(val[0], val[1])
- }
- | stmt kIF_MOD expr_value
- {
- result = @builder.condition_mod(val[0], nil,
- val[1], val[2])
- }
- | stmt kUNLESS_MOD expr_value
- {
- result = @builder.condition_mod(nil, val[0],
- val[1], val[2])
- }
- | stmt kWHILE_MOD expr_value
- {
- result = @builder.loop_mod(:while, val[0], val[1], val[2])
- }
- | stmt kUNTIL_MOD expr_value
- {
- result = @builder.loop_mod(:until, val[0], val[1], val[2])
- }
- | stmt kRESCUE_MOD stmt
- {
- rescue_body = @builder.rescue_body(val[1],
- nil, nil, nil,
- nil, val[2])
-
- result = @builder.begin_body(val[0], [ rescue_body ])
- }
- | klEND tLCURLY compstmt tRCURLY
- {
- result = @builder.postexe(val[0], val[1], val[2], val[3])
- }
- | command_asgn
- | mlhs tEQL command_call
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN command_call
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | backref tOP_ASGN command_call
- {
- @builder.op_assign(val[0], val[1], val[2])
- }
- | lhs tEQL mrhs
- {
- result = @builder.assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | mlhs tEQL arg_value
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | mlhs tEQL mrhs
- {
- result = @builder.multi_assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | expr
-
- command_asgn: lhs tEQL command_call
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL command_asgn
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
-
- expr: command_call
- | expr kAND expr
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | expr kOR expr
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kNOT opt_nl expr
- {
- result = @builder.not_op(val[0], nil, val[2], nil)
- }
- | tBANG command_call
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | arg
-
- expr_value: expr
-
- command_call: command
- | block_command
-
- block_command: block_call
- | block_call tDOT operation2 command_args
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | block_call tCOLON2 operation2 command_args
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
-
- cmd_brace_block: tLBRACE_ARG
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- command: operation command_args =tLOWEST
- {
- result = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
- }
- | operation command_args cmd_brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
-
- begin_t, args, body, end_t = val[2]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tDOT operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | primary_value tDOT operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tCOLON2 operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | primary_value tCOLON2 operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | kSUPER command_args
- {
- result = @builder.keyword_cmd(:super, val[0],
- nil, val[1], nil)
- }
- | kYIELD command_args
- {
- result = @builder.keyword_cmd(:yield, val[0],
- nil, val[1], nil)
- }
- | kRETURN call_args
- {
- result = @builder.keyword_cmd(:return, val[0],
- nil, val[1], nil)
- }
- | kBREAK call_args
- {
- result = @builder.keyword_cmd(:break, val[0],
- nil, val[1], nil)
- }
- | kNEXT call_args
- {
- result = @builder.keyword_cmd(:next, val[0],
- nil, val[1], nil)
- }
-
- mlhs: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_inner: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- mlhs_basic: mlhs_head
- | mlhs_head mlhs_item
- {
- result = val[0].
- push(val[1])
- }
- | mlhs_head tSTAR mlhs_node
- {
- result = val[0].
- push(@builder.splat(val[1], val[2]))
- }
- | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1], val[2])).
- concat(val[4])
- }
- | mlhs_head tSTAR
- {
- result = val[0].
- push(@builder.splat(val[1]))
- }
- | mlhs_head tSTAR tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1])).
- concat(val[3])
- }
- | tSTAR mlhs_node
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.splat(val[0]) ]
- }
- | tSTAR tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0]),
- *val[2] ]
- }
-
- mlhs_item: mlhs_node
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_head: mlhs_item tCOMMA
- {
- result = [ val[0] ]
- }
- | mlhs_head mlhs_item tCOMMA
- {
- result = val[0] << val[1]
- }
-
- mlhs_post: mlhs_item
- {
- result = [ val[0] ]
- }
- | mlhs_post tCOMMA mlhs_item
- {
- result = val[0] << val[2]
- }
-
- mlhs_node: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- lhs: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- cname: tIDENTIFIER
- {
- diagnostic :error, :module_name_const, nil, val[0]
- }
- | tCONSTANT
-
- cpath: tCOLON3 cname
- {
- result = @builder.const_global(val[0], val[1])
- }
- | cname
- {
- result = @builder.const(val[0])
- }
- | primary_value tCOLON2 cname
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
-
- fname: tIDENTIFIER | tCONSTANT | tFID
- | op
- | reswords
-
- fsym: fname
- {
- result = @builder.symbol(val[0])
- }
- | symbol
-
- fitem: fsym
- | dsym
-
- undef_list: fitem
- {
- result = [ val[0] ]
- }
- | undef_list tCOMMA
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = val[0] << val[3]
- }
-
- op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
- | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
- | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
- | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
- | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
-
- reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
- | kALIAS | kAND | kBEGIN | kBREAK | kCASE
- | kCLASS | kDEF | kDEFINED | kDO | kELSE
- | kELSIF | kEND | kENSURE | kFALSE | kFOR
- | kIN | kMODULE | kNEXT | kNIL | kNOT
- | kOR | kREDO | kRESCUE | kRETRY | kRETURN
- | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
- | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
- | kUNTIL
-
- arg: lhs tEQL arg
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.assign(val[0], val[1], rescue_)
- }
- | var_lhs tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.op_assign(val[0], val[1], rescue_)
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
- {
- diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
- }
- | tCOLON3 tCONSTANT tOP_ASGN arg
- {
- diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
- }
- | backref tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | arg tDOT2 arg
- {
- result = @builder.range_inclusive(val[0], val[1], val[2])
- }
- | arg tDOT3 arg
- {
- result = @builder.range_exclusive(val[0], val[1], val[2])
- }
- | arg tPLUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMINUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tSTAR2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tDIVIDE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPERCENT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPOW arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tUMINUS_NUM tINTEGER tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.integer(val[1]),
- val[2], val[3]))
- }
- | tUMINUS_NUM tFLOAT tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.float(val[1]),
- val[2], val[3]))
- }
- | tUPLUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | tUMINUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tPIPE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCARET arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tAMPER2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCMP arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tNEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMATCH arg
- {
- result = @builder.match_op(val[0], val[1], val[2])
- }
- | arg tNMATCH arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tBANG arg
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | tTILDE arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tLSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tRSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tANDOP arg
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | arg tOROP arg
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kDEFINED opt_nl arg
- {
- result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
- }
-
- | arg tEH arg opt_nl tCOLON arg
- {
- result = @builder.ternary(val[0], val[1],
- val[2], val[4], val[5])
- }
- | primary
-
- arg_value: arg
-
- aref_args: none
- | args trailer
- | args tCOMMA assocs trailer
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs trailer
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- paren_args: tLPAREN2 opt_call_args rparen
- {
- result = val
- }
-
- opt_paren_args: # nothing
- {
- result = [ nil, [], nil ]
- }
- | paren_args
-
- opt_call_args: # nothing
- {
- result = []
- }
- | call_args
- | args tCOMMA
- | args tCOMMA assocs tCOMMA
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs tCOMMA
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- call_args: command
- {
- result = [ val[0] ]
- }
- | args opt_block_arg
- {
- result = val[0].concat(val[1])
- }
- | assocs opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- result.concat(val[1])
- }
- | args tCOMMA assocs opt_block_arg
- {
- assocs = @builder.associate(nil, val[2], nil)
- result = val[0] << assocs
- result.concat(val[3])
- }
- | block_arg
- {
- result = [ val[0] ]
- }
-
- command_args: {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.push(true)
- }
- call_args
- {
- @lexer.cmdarg = val[0]
-
- result = val[1]
- }
-
- block_arg: tAMPER arg_value
- {
- result = @builder.block_pass(val[0], val[1])
- }
-
- opt_block_arg: tCOMMA block_arg
- {
- result = [ val[1] ]
- }
- | # nothing
- {
- result = []
- }
-
- args: arg_value
- {
- result = [ val[0] ]
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
-
- mrhs: args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
-
- primary: literal
- | strings
- | xstring
- | regexp
- | words
- | qwords
- | var_ref
- | backref
- | tFID
- {
- result = @builder.call_method(nil, nil, val[0])
- }
- | kBEGIN bodystmt kEND
- {
- result = @builder.begin_keyword(val[0], val[1], val[2])
- }
- | tLPAREN_ARG
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- expr
- {
- @lexer.state = :expr_endarg
- }
- opt_nl tRPAREN
- {
- @lexer.cmdarg = val[1]
-
- result = @builder.begin(val[0], val[2], val[5])
- }
- | tLPAREN compstmt tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.const_global(val[0], val[1])
- }
- | tLBRACK aref_args tRBRACK
- {
- result = @builder.array(val[0], val[1], val[2])
- }
- | tLBRACE assoc_list tRCURLY
- {
- result = @builder.associate(val[0], val[1], val[2])
- }
- | kRETURN
- {
- result = @builder.keyword_cmd(:return, val[0])
- }
- | kYIELD tLPAREN2 call_args rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
- }
- | kYIELD tLPAREN2 rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
- }
- | kYIELD
- {
- result = @builder.keyword_cmd(:yield, val[0])
- }
- | kDEFINED opt_nl tLPAREN2 expr rparen
- {
- result = @builder.keyword_cmd(:defined?, val[0],
- val[2], [ val[3] ], val[4])
- }
- | kNOT tLPAREN2 expr rparen
- {
- result = @builder.not_op(val[0], val[1], val[2], val[3])
- }
- | kNOT tLPAREN2 rparen
- {
- result = @builder.not_op(val[0], val[1], nil, val[2])
- }
- | operation brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0])
-
- begin_t, args, body, end_t = val[1]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | method_call
- | method_call brace_block
- {
- begin_t, args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, args, body, end_t)
- }
- | tLAMBDA lambda
- {
- lambda_call = @builder.call_lambda(val[0])
-
- args, (begin_t, body, end_t) = val[1]
- result = @builder.block(lambda_call,
- begin_t, args, body, end_t)
- }
- | kIF expr_value then compstmt if_tail kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, val[5])
- }
- | kUNLESS expr_value then compstmt opt_else kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- else_, else_t,
- val[3], val[5])
- }
- | kWHILE
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:while, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kUNTIL
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:until, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kCASE expr_value opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[3]
-
- result = @builder.case(val[0], val[1],
- when_bodies, else_t, else_body,
- val[4])
- }
- | kCASE opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[2]
-
- result = @builder.case(val[0], nil,
- when_bodies, else_t, else_body,
- val[3])
- }
- | kFOR for_var kIN
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.for(val[0], val[1],
- val[2], val[4],
- val[5], val[7], val[8])
- }
- | kCLASS cpath superclass
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :class_in_def, nil, val[0]
- end
-
- lt_t, superclass = val[2]
- result = @builder.def_class(val[0], val[1],
- lt_t, superclass,
- val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kCLASS tLSHFT expr term
- {
- result = @def_level
- @def_level = 0
-
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- result = @builder.def_sclass(val[0], val[1], val[2],
- val[5], val[6])
-
- @lexer.pop_cmdarg
- @static_env.unextend
-
- @def_level = val[4]
- }
- | kMODULE cpath
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :module_in_def, nil, val[0]
- end
-
- result = @builder.def_module(val[0], val[1],
- val[3], val[4])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kDEF fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_method(val[0], val[1],
- val[3], val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kDEF singleton dot_or_colon
- {
- @lexer.state = :expr_fname
- }
- fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_singleton(val[0], val[1], val[2],
- val[4], val[6], val[7], val[8])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kBREAK
- {
- result = @builder.keyword_cmd(:break, val[0])
- }
- | kNEXT
- {
- result = @builder.keyword_cmd(:next, val[0])
- }
- | kREDO
- {
- result = @builder.keyword_cmd(:redo, val[0])
- }
- | kRETRY
- {
- result = @builder.keyword_cmd(:retry, val[0])
- }
-
- primary_value: primary
-
- then: term
- | kTHEN
- | term kTHEN
- {
- result = val[1]
- }
-
- do: term
- | kDO_COND
-
- if_tail: opt_else
- | kELSIF expr_value then compstmt if_tail
- {
- else_t, else_ = val[4]
- result = [ val[0],
- @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, nil),
- ]
- }
-
- opt_else: none
- | kELSE compstmt
- {
- result = val
- }
-
- for_var: lhs
- | mlhs
-
- f_marg: f_norm_arg
- {
- @static_env.declare val[0][0]
-
- result = @builder.arg(val[0])
- }
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_marg_list: f_marg
- {
- result = [ val[0] ]
- }
- | f_marg_list tCOMMA f_marg
- {
- result = val[0] << val[2]
- }
-
- f_margs: f_marg_list
- | f_marg_list tCOMMA tSTAR f_norm_arg
- {
- @static_env.declare val[3][0]
-
- result = val[0].
- push(@builder.restarg(val[2], val[3]))
- }
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
- {
- @static_env.declare val[3][0]
-
- result = val[0].
- push(@builder.restarg(val[2], val[3])).
- concat(val[5])
- }
- | f_marg_list tCOMMA tSTAR
- {
- result = val[0].
- push(@builder.restarg(val[2]))
- }
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
- {
- result = val[0].
- push(@builder.restarg(val[2])).
- concat(val[4])
- }
- | tSTAR f_norm_arg
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | tSTAR f_norm_arg tCOMMA f_marg_list
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.restarg(val[0]) ]
- }
- | tSTAR tCOMMA f_marg_list
- {
- result = [ @builder.restarg(val[0]),
- *val[2] ]
- }
-
- block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_block_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_block_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_block_optarg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
-
- opt_block_param: # nothing
- {
- result = @builder.args(nil, [], nil)
- }
- | block_param_def
- {
- @lexer.state = :expr_value
- }
-
- block_param_def: tPIPE opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1], val[2])
- }
- | tOROP
- {
- result = @builder.args(val[0], [], val[0])
- }
- | tPIPE block_param opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
-
- opt_bv_decl: # nothing
- {
- result = []
- }
- | tSEMI bv_decls
- {
- result = val[1]
- }
-
- bv_decls: bvar
- {
- result = [ val[0] ]
- }
- | bv_decls tCOMMA bvar
- {
- result = val[0] << val[2]
- }
-
- bvar: tIDENTIFIER
- {
- result = @builder.shadowarg(val[0])
- }
- | f_bad_arg
-
- lambda: {
- @static_env.extend_dynamic
- }
- f_larglist lambda_body
- {
- result = [ val[1], val[2] ]
-
- @static_env.unextend
- }
-
- f_larglist: tLPAREN2 f_args opt_bv_decl rparen
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
- | f_args
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- lambda_body: tLAMBEG compstmt tRCURLY
- {
- result = [ val[0], val[1], val[2] ]
- }
- | kDO_LAMBDA compstmt kEND
- {
- result = [ val[0], val[1], val[2] ]
- }
-
- do_block: kDO_BLOCK
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- block_call: command do_block
- {
- begin_t, block_args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, block_args, body, end_t)
- }
- | block_call tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | block_call tCOLON2 operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
-
- method_call: operation paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
- }
- | primary_value tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation2 paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation3
- {
- result = @builder.call_method(val[0], val[1], val[2])
- }
- | primary_value tDOT paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | kSUPER paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
- }
- | kSUPER
- {
- result = @builder.keyword_cmd(:zsuper, val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index(val[0], val[1], val[2], val[3])
- }
-
- brace_block: tLCURLY
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
- | kDO
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- case_body: kWHEN args then compstmt cases
- {
- result = [ @builder.when(val[0], val[1], val[2], val[3]),
- *val[4] ]
- }
-
- cases: opt_else
- {
- result = [ val[0] ]
- }
- | case_body
-
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
- {
- assoc_t, exc_var = val[2]
-
- if val[1]
- exc_list = @builder.array(nil, val[1], nil)
- end
-
- result = [ @builder.rescue_body(val[0],
- exc_list, assoc_t, exc_var,
- val[3], val[4]),
- *val[5] ]
- }
- |
- {
- result = []
- }
-
- exc_list: arg_value
- {
- result = [ val[0] ]
- }
- | mrhs
- | none
-
- exc_var: tASSOC lhs
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- opt_ensure: kENSURE compstmt
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- literal: numeric
- | symbol
- | dsym
-
- strings: string
- {
- result = @builder.string_compose(nil, val[0], nil)
- }
-
- string: string1
- {
- result = [ val[0] ]
- }
- | string string1
- {
- result = val[0] << val[1]
- }
-
- string1: tSTRING_BEG string_contents tSTRING_END
- {
- result = @builder.string_compose(val[0], val[1], val[2])
- }
- | tSTRING
- {
- result = @builder.string(val[0])
- }
- | tCHARACTER
- {
- result = @builder.character(val[0])
- }
-
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
- {
- result = @builder.xstring_compose(val[0], val[1], val[2])
- }
-
- regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
- {
- opts = @builder.regexp_options(val[3])
- result = @builder.regexp_compose(val[0], val[1], val[2], opts)
- }
-
- words: tWORDS_BEG word_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- word_list: # nothing
- {
- result = []
- }
- | word_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- word: string_content
- {
- result = [ val[0] ]
- }
- | word string_content
- {
- result = val[0] << val[1]
- }
-
- qwords: tQWORDS_BEG qword_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- qword_list: # nothing
- {
- result = []
- }
- | qword_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.string_internal(val[1])
- }
-
- string_contents: # nothing
- {
- result = []
- }
- | string_contents string_content
- {
- result = val[0] << val[1]
- }
-
-xstring_contents: # nothing
- {
- result = []
- }
- | xstring_contents string_content
- {
- result = val[0] << val[1]
- }
-
-regexp_contents: # nothing
- {
- result = []
- }
- | regexp_contents string_content
- {
- result = val[0] << val[1]
- }
-
- string_content: tSTRING_CONTENT
- {
- result = @builder.string_internal(val[0])
- }
- | tSTRING_DVAR string_dvar
- {
- result = val[1]
- }
- | tSTRING_DBEG
- {
- @lexer.cond.push(false)
- @lexer.cmdarg.push(false)
- }
- compstmt tRCURLY
- {
- @lexer.cond.lexpop
- @lexer.cmdarg.lexpop
-
- result = @builder.begin(val[0], val[2], val[3])
- }
-
- string_dvar: tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
- | backref
-
-
- symbol: tSYMBOL
- {
- result = @builder.symbol(val[0])
- }
-
- dsym: tSYMBEG xstring_contents tSTRING_END
- {
- result = @builder.symbol_compose(val[0], val[1], val[2])
- }
-
- numeric: tINTEGER
- {
- result = @builder.integer(val[0])
- }
- | tFLOAT
- {
- result = @builder.float(val[0])
- }
- | tUMINUS_NUM tINTEGER =tLOWEST
- {
- result = @builder.negate(val[0],
- @builder.integer(val[1]))
- }
- | tUMINUS_NUM tFLOAT =tLOWEST
- {
- result = @builder.negate(val[0],
- @builder.float(val[1]))
- }
-
- user_variable: tIDENTIFIER
- {
- result = @builder.ident(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tCONSTANT
- {
- result = @builder.const(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
-
-keyword_variable: kNIL
- {
- result = @builder.nil(val[0])
- }
- | kSELF
- {
- result = @builder.self(val[0])
- }
- | kTRUE
- {
- result = @builder.true(val[0])
- }
- | kFALSE
- {
- result = @builder.false(val[0])
- }
- | k__FILE__
- {
- result = @builder.__FILE__(val[0])
- }
- | k__LINE__
- {
- result = @builder.__LINE__(val[0])
- }
- | k__ENCODING__
- {
- result = @builder.__ENCODING__(val[0])
- }
-
- var_ref: user_variable
- {
- result = @builder.accessible(val[0])
- }
- | keyword_variable
- {
- result = @builder.accessible(val[0])
- }
-
- var_lhs: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
-
- backref: tNTH_REF
- {
- result = @builder.nth_ref(val[0])
- }
- | tBACK_REF
- {
- result = @builder.back_ref(val[0])
- }
-
- superclass: term
- {
- result = nil
- }
- | tLT expr_value term
- {
- result = [ val[0], val[1] ]
- }
- | error term
- {
- yyerrok
- result = nil
- }
-
- f_arglist: tLPAREN2 f_args rparen
- {
- result = @builder.args(val[0], val[1], val[2])
-
- @lexer.state = :expr_value
- }
- | f_args term
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_optarg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_f_block_arg
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
- | # nothing
- {
- result = []
- }
-
- f_bad_arg: tCONSTANT
- {
- diagnostic :error, :argument_const, nil, val[0]
- }
- | tIVAR
- {
- diagnostic :error, :argument_ivar, nil, val[0]
- }
- | tGVAR
- {
- diagnostic :error, :argument_gvar, nil, val[0]
- }
- | tCVAR
- {
- diagnostic :error, :argument_cvar, nil, val[0]
- }
-
- f_norm_arg: f_bad_arg
- | tIDENTIFIER
-
- f_arg_item: f_norm_arg
- {
- @static_env.declare val[0][0]
-
- result = @builder.arg(val[0])
- }
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_arg: f_arg_item
- {
- result = [ val[0] ]
- }
- | f_arg tCOMMA f_arg_item
- {
- result = val[0] << val[2]
- }
-
- f_opt: tIDENTIFIER tEQL arg_value
- {
- @static_env.declare val[0][0]
-
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_opt: tIDENTIFIER tEQL primary_value
- {
- @static_env.declare val[0][0]
-
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_optarg: f_block_opt
- {
- result = [ val[0] ]
- }
- | f_block_optarg tCOMMA f_block_opt
- {
- result = val[0] << val[2]
- }
-
- f_optarg: f_opt
- {
- result = [ val[0] ]
- }
- | f_optarg tCOMMA f_opt
- {
- result = val[0] << val[2]
- }
-
- restarg_mark: tSTAR2 | tSTAR
-
- f_rest_arg: restarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | restarg_mark
- {
- result = [ @builder.restarg(val[0]) ]
- }
-
- blkarg_mark: tAMPER2 | tAMPER
-
- f_block_arg: blkarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = @builder.blockarg(val[0], val[1])
- }
-
- opt_f_block_arg: tCOMMA f_block_arg
- {
- result = [ val[1] ]
- }
- | # nothing
- {
- result = []
- }
-
- singleton: var_ref
- | tLPAREN2 expr rparen
- {
- result = val[1]
- }
-
- assoc_list: # nothing
- {
- result = []
- }
- | assocs trailer
-
- assocs: assoc
- {
- result = [ val[0] ]
- }
- | assocs tCOMMA assoc
- {
- result = val[0] << val[2]
- }
-
- assoc: arg_value tASSOC arg_value
- {
- result = @builder.pair(val[0], val[1], val[2])
- }
- | tLABEL arg_value
- {
- result = @builder.pair_keyword(val[0], val[1])
- }
-
- operation: tIDENTIFIER | tCONSTANT | tFID
- operation2: tIDENTIFIER | tCONSTANT | tFID | op
- operation3: tIDENTIFIER | tFID | op
- dot_or_colon: tDOT | tCOLON2
- opt_terms: | terms
- opt_nl: | tNL
- rparen: opt_nl tRPAREN
- {
- result = val[1]
- }
- rbracket: opt_nl tRBRACK
- {
- result = val[1]
- }
- trailer: | tNL | tCOMMA
-
- term: tSEMI
- {
- yyerrok
- }
- | tNL
-
- terms: term
- | terms tSEMI
-
- none: # nothing
- {
- result = nil
- }
-end
-
----- header
-
-require 'parser'
-
-Parser.check_for_encoding_support
-
----- inner
-
- def version
- 19
- end
-
- def default_encoding
- Encoding::BINARY
- end
diff --git a/test/racc/assets/ruby20.y b/test/racc/assets/ruby20.y
deleted file mode 100644
index 6e07734778..0000000000
--- a/test/racc/assets/ruby20.y
+++ /dev/null
@@ -1,2350 +0,0 @@
-# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org>
-#
-# Parts of the source are derived from ruby_parser:
-# Copyright (c) Ryan Davis, seattle.rb
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Parser::Ruby20
-
-token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
- kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
- kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
- kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
- kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
- k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
- tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
- tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
- tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
- tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
- tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
- tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
- tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
- tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
- tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
- tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
- tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
-
-prechigh
- right tBANG tTILDE tUPLUS
- right tPOW
- right tUMINUS_NUM tUMINUS
- left tSTAR2 tDIVIDE tPERCENT
- left tPLUS tMINUS
- left tLSHFT tRSHFT
- left tAMPER2
- left tPIPE tCARET
- left tGT tGEQ tLT tLEQ
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
- left tANDOP
- left tOROP
- nonassoc tDOT2 tDOT3
- right tEH tCOLON
- left kRESCUE_MOD
- right tEQL tOP_ASGN
- nonassoc kDEFINED
- right kNOT
- left kOR kAND
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
- nonassoc tLBRACE_ARG
- nonassoc tLOWEST
-preclow
-
-rule
-
- program: top_compstmt
-
- top_compstmt: top_stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- top_stmts: # nothing
- {
- result = []
- }
- | top_stmt
- {
- result = [ val[0] ]
- }
- | top_stmts terms top_stmt
- {
- result = val[0] << val[2]
- }
- | error top_stmt
- {
- result = [ val[1] ]
- }
-
- top_stmt: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- result = @builder.preexe(val[0], val[1], val[2], val[3])
- }
-
- bodystmt: compstmt opt_rescue opt_else opt_ensure
- {
- rescue_bodies = val[1]
- else_t, else_ = val[2]
- ensure_t, ensure_ = val[3]
-
- if rescue_bodies.empty? && !else_.nil?
- diagnostic :warning, :useless_else, nil, else_t
- end
-
- result = @builder.begin_body(val[0],
- rescue_bodies,
- else_t, else_,
- ensure_t, ensure_)
- }
-
- compstmt: stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- stmts: # nothing
- {
- result = []
- }
- | stmt_or_begin
- {
- result = [ val[0] ]
- }
- | stmts terms stmt_or_begin
- {
- result = val[0] << val[2]
- }
- | error stmt
- {
- result = [ val[1] ]
- }
-
- stmt_or_begin: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- if in_def?
- diagnostic :error, :begin_in_method, nil, val[0]
- end
-
- result = @builder.preexe(val[0], val[1], val[2], val[3])
- }
-
- stmt: kALIAS fitem
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = @builder.alias(val[0], val[1], val[3])
- }
- | kALIAS tGVAR tGVAR
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.gvar(val[2]))
- }
- | kALIAS tGVAR tBACK_REF
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.back_ref(val[2]))
- }
- | kALIAS tGVAR tNTH_REF
- {
- diagnostic :error, :nth_ref_alias, nil, val[2]
- }
- | kUNDEF undef_list
- {
- result = @builder.undef_method(val[0], val[1])
- }
- | stmt kIF_MOD expr_value
- {
- result = @builder.condition_mod(val[0], nil,
- val[1], val[2])
- }
- | stmt kUNLESS_MOD expr_value
- {
- result = @builder.condition_mod(nil, val[0],
- val[1], val[2])
- }
- | stmt kWHILE_MOD expr_value
- {
- result = @builder.loop_mod(:while, val[0], val[1], val[2])
- }
- | stmt kUNTIL_MOD expr_value
- {
- result = @builder.loop_mod(:until, val[0], val[1], val[2])
- }
- | stmt kRESCUE_MOD stmt
- {
- rescue_body = @builder.rescue_body(val[1],
- nil, nil, nil,
- nil, val[2])
-
- result = @builder.begin_body(val[0], [ rescue_body ])
- }
- | klEND tLCURLY compstmt tRCURLY
- {
- result = @builder.postexe(val[0], val[1], val[2], val[3])
- }
- | command_asgn
- | mlhs tEQL command_call
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN command_call
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | backref tOP_ASGN command_call
- {
- @builder.op_assign(val[0], val[1], val[2])
- }
- | lhs tEQL mrhs
- {
- result = @builder.assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | mlhs tEQL arg_value
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | mlhs tEQL mrhs
- {
- result = @builder.multi_assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | expr
-
- command_asgn: lhs tEQL command_call
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL command_asgn
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
-
- expr: command_call
- | expr kAND expr
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | expr kOR expr
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kNOT opt_nl expr
- {
- result = @builder.not_op(val[0], nil, val[2], nil)
- }
- | tBANG command_call
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | arg
-
- expr_value: expr
-
- command_call: command
- | block_command
-
- block_command: block_call
- | block_call dot_or_colon operation2 command_args
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
-
- cmd_brace_block: tLBRACE_ARG
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- fcall: operation
-
- command: fcall command_args =tLOWEST
- {
- result = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
- }
- | fcall command_args cmd_brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
-
- begin_t, args, body, end_t = val[2]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tDOT operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | primary_value tDOT operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tCOLON2 operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | primary_value tCOLON2 operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | kSUPER command_args
- {
- result = @builder.keyword_cmd(:super, val[0],
- nil, val[1], nil)
- }
- | kYIELD command_args
- {
- result = @builder.keyword_cmd(:yield, val[0],
- nil, val[1], nil)
- }
- | kRETURN call_args
- {
- result = @builder.keyword_cmd(:return, val[0],
- nil, val[1], nil)
- }
- | kBREAK call_args
- {
- result = @builder.keyword_cmd(:break, val[0],
- nil, val[1], nil)
- }
- | kNEXT call_args
- {
- result = @builder.keyword_cmd(:next, val[0],
- nil, val[1], nil)
- }
-
- mlhs: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_inner: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- mlhs_basic: mlhs_head
- | mlhs_head mlhs_item
- {
- result = val[0].
- push(val[1])
- }
- | mlhs_head tSTAR mlhs_node
- {
- result = val[0].
- push(@builder.splat(val[1], val[2]))
- }
- | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1], val[2])).
- concat(val[4])
- }
- | mlhs_head tSTAR
- {
- result = val[0].
- push(@builder.splat(val[1]))
- }
- | mlhs_head tSTAR tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1])).
- concat(val[3])
- }
- | tSTAR mlhs_node
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.splat(val[0]) ]
- }
- | tSTAR tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0]),
- *val[2] ]
- }
-
- mlhs_item: mlhs_node
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_head: mlhs_item tCOMMA
- {
- result = [ val[0] ]
- }
- | mlhs_head mlhs_item tCOMMA
- {
- result = val[0] << val[1]
- }
-
- mlhs_post: mlhs_item
- {
- result = [ val[0] ]
- }
- | mlhs_post tCOMMA mlhs_item
- {
- result = val[0] << val[2]
- }
-
- mlhs_node: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- lhs: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- cname: tIDENTIFIER
- {
- diagnostic :error, :module_name_const, nil, val[0]
- }
- | tCONSTANT
-
- cpath: tCOLON3 cname
- {
- result = @builder.const_global(val[0], val[1])
- }
- | cname
- {
- result = @builder.const(val[0])
- }
- | primary_value tCOLON2 cname
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
-
- fname: tIDENTIFIER | tCONSTANT | tFID
- | op
- | reswords
-
- fsym: fname
- {
- result = @builder.symbol(val[0])
- }
- | symbol
-
- fitem: fsym
- | dsym
-
- undef_list: fitem
- {
- result = [ val[0] ]
- }
- | undef_list tCOMMA
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = val[0] << val[3]
- }
-
- op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
- | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
- | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
- | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
- | tUPLUS | tUMINUS | tAREF | tASET | tDSTAR | tBACK_REF2
-
- reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
- | kALIAS | kAND | kBEGIN | kBREAK | kCASE
- | kCLASS | kDEF | kDEFINED | kDO | kELSE
- | kELSIF | kEND | kENSURE | kFALSE | kFOR
- | kIN | kMODULE | kNEXT | kNIL | kNOT
- | kOR | kREDO | kRESCUE | kRETRY | kRETURN
- | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
- | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
- | kUNTIL
-
- arg: lhs tEQL arg
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.assign(val[0], val[1], rescue_)
- }
- | var_lhs tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.op_assign(val[0], val[1], rescue_)
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
- {
- const = @builder.const_op_assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- result = @builder.op_assign(const, val[3], val[4])
- }
- | tCOLON3 tCONSTANT tOP_ASGN arg
- {
- const = @builder.const_op_assignable(
- @builder.const_global(val[0], val[1]))
- result = @builder.op_assign(const, val[2], val[3])
- }
- | backref tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | arg tDOT2 arg
- {
- result = @builder.range_inclusive(val[0], val[1], val[2])
- }
- | arg tDOT3 arg
- {
- result = @builder.range_exclusive(val[0], val[1], val[2])
- }
- | arg tPLUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMINUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tSTAR2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tDIVIDE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPERCENT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPOW arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tUMINUS_NUM tINTEGER tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.integer(val[1]),
- val[2], val[3]))
- }
- | tUMINUS_NUM tFLOAT tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.float(val[1]),
- val[2], val[3]))
- }
- | tUPLUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | tUMINUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tPIPE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCARET arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tAMPER2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCMP arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tNEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMATCH arg
- {
- result = @builder.match_op(val[0], val[1], val[2])
- }
- | arg tNMATCH arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tBANG arg
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | tTILDE arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tLSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tRSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tANDOP arg
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | arg tOROP arg
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kDEFINED opt_nl arg
- {
- result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
- }
-
- | arg tEH arg opt_nl tCOLON arg
- {
- result = @builder.ternary(val[0], val[1],
- val[2], val[4], val[5])
- }
- | primary
-
- arg_value: arg
-
- aref_args: none
- | args trailer
- | args tCOMMA assocs trailer
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs trailer
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- paren_args: tLPAREN2 opt_call_args rparen
- {
- result = val
- }
-
- opt_paren_args: # nothing
- {
- result = [ nil, [], nil ]
- }
- | paren_args
-
- opt_call_args: # nothing
- {
- result = []
- }
- | call_args
- | args tCOMMA
- | args tCOMMA assocs tCOMMA
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs tCOMMA
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- call_args: command
- {
- result = [ val[0] ]
- }
- | args opt_block_arg
- {
- result = val[0].concat(val[1])
- }
- | assocs opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- result.concat(val[1])
- }
- | args tCOMMA assocs opt_block_arg
- {
- assocs = @builder.associate(nil, val[2], nil)
- result = val[0] << assocs
- result.concat(val[3])
- }
- | block_arg
- {
- result = [ val[0] ]
- }
-
- command_args: {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.push(true)
- }
- call_args
- {
- @lexer.cmdarg = val[0]
-
- result = val[1]
- }
-
- block_arg: tAMPER arg_value
- {
- result = @builder.block_pass(val[0], val[1])
- }
-
- opt_block_arg: tCOMMA block_arg
- {
- result = [ val[1] ]
- }
- | # nothing
- {
- result = []
- }
-
- args: arg_value
- {
- result = [ val[0] ]
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
-
- mrhs: args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
-
- primary: literal
- | strings
- | xstring
- | regexp
- | words
- | qwords
- | symbols
- | qsymbols
- | var_ref
- | backref
- | tFID
- {
- result = @builder.call_method(nil, nil, val[0])
- }
- | kBEGIN
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- bodystmt kEND
- {
- @lexer.cmdarg = val[1]
-
- result = @builder.begin_keyword(val[0], val[2], val[3])
- }
- | tLPAREN_ARG
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- expr
- {
- @lexer.state = :expr_endarg
- }
- opt_nl tRPAREN
- {
- @lexer.cmdarg = val[1]
-
- result = @builder.begin(val[0], val[2], val[5])
- }
- | tLPAREN_ARG
- {
- @lexer.state = :expr_endarg
- }
- opt_nl tRPAREN
- {
- result = @builder.begin(val[0], nil, val[3])
- }
- | tLPAREN compstmt tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.const_global(val[0], val[1])
- }
- | tLBRACK aref_args tRBRACK
- {
- result = @builder.array(val[0], val[1], val[2])
- }
- | tLBRACE assoc_list tRCURLY
- {
- result = @builder.associate(val[0], val[1], val[2])
- }
- | kRETURN
- {
- result = @builder.keyword_cmd(:return, val[0])
- }
- | kYIELD tLPAREN2 call_args rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
- }
- | kYIELD tLPAREN2 rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
- }
- | kYIELD
- {
- result = @builder.keyword_cmd(:yield, val[0])
- }
- | kDEFINED opt_nl tLPAREN2 expr rparen
- {
- result = @builder.keyword_cmd(:defined?, val[0],
- val[2], [ val[3] ], val[4])
- }
- | kNOT tLPAREN2 expr rparen
- {
- result = @builder.not_op(val[0], val[1], val[2], val[3])
- }
- | kNOT tLPAREN2 rparen
- {
- result = @builder.not_op(val[0], val[1], nil, val[2])
- }
- | fcall brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0])
-
- begin_t, args, body, end_t = val[1]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | method_call
- | method_call brace_block
- {
- begin_t, args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, args, body, end_t)
- }
- | tLAMBDA lambda
- {
- lambda_call = @builder.call_lambda(val[0])
-
- args, (begin_t, body, end_t) = val[1]
- result = @builder.block(lambda_call,
- begin_t, args, body, end_t)
- }
- | kIF expr_value then compstmt if_tail kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, val[5])
- }
- | kUNLESS expr_value then compstmt opt_else kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- else_, else_t,
- val[3], val[5])
- }
- | kWHILE
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:while, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kUNTIL
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:until, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kCASE expr_value opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[3]
-
- result = @builder.case(val[0], val[1],
- when_bodies, else_t, else_body,
- val[4])
- }
- | kCASE opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[2]
-
- result = @builder.case(val[0], nil,
- when_bodies, else_t, else_body,
- val[3])
- }
- | kFOR for_var kIN
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.for(val[0], val[1],
- val[2], val[4],
- val[5], val[7], val[8])
- }
- | kCLASS cpath superclass
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :class_in_def, nil, val[0]
- end
-
- lt_t, superclass = val[2]
- result = @builder.def_class(val[0], val[1],
- lt_t, superclass,
- val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kCLASS tLSHFT expr term
- {
- result = @def_level
- @def_level = 0
-
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- result = @builder.def_sclass(val[0], val[1], val[2],
- val[5], val[6])
-
- @lexer.pop_cmdarg
- @static_env.unextend
-
- @def_level = val[4]
- }
- | kMODULE cpath
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :module_in_def, nil, val[0]
- end
-
- result = @builder.def_module(val[0], val[1],
- val[3], val[4])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kDEF fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_method(val[0], val[1],
- val[3], val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kDEF singleton dot_or_colon
- {
- @lexer.state = :expr_fname
- }
- fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_singleton(val[0], val[1], val[2],
- val[4], val[6], val[7], val[8])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kBREAK
- {
- result = @builder.keyword_cmd(:break, val[0])
- }
- | kNEXT
- {
- result = @builder.keyword_cmd(:next, val[0])
- }
- | kREDO
- {
- result = @builder.keyword_cmd(:redo, val[0])
- }
- | kRETRY
- {
- result = @builder.keyword_cmd(:retry, val[0])
- }
-
- primary_value: primary
-
- then: term
- | kTHEN
- | term kTHEN
- {
- result = val[1]
- }
-
- do: term
- | kDO_COND
-
- if_tail: opt_else
- | kELSIF expr_value then compstmt if_tail
- {
- else_t, else_ = val[4]
- result = [ val[0],
- @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, nil),
- ]
- }
-
- opt_else: none
- | kELSE compstmt
- {
- result = val
- }
-
- for_var: lhs
- | mlhs
-
- f_marg: f_norm_arg
- {
- @static_env.declare val[0][0]
-
- result = @builder.arg(val[0])
- }
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_marg_list: f_marg
- {
- result = [ val[0] ]
- }
- | f_marg_list tCOMMA f_marg
- {
- result = val[0] << val[2]
- }
-
- f_margs: f_marg_list
- | f_marg_list tCOMMA tSTAR f_norm_arg
- {
- @static_env.declare val[3][0]
-
- result = val[0].
- push(@builder.restarg(val[2], val[3]))
- }
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
- {
- @static_env.declare val[3][0]
-
- result = val[0].
- push(@builder.restarg(val[2], val[3])).
- concat(val[5])
- }
- | f_marg_list tCOMMA tSTAR
- {
- result = val[0].
- push(@builder.restarg(val[2]))
- }
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
- {
- result = val[0].
- push(@builder.restarg(val[2])).
- concat(val[4])
- }
- | tSTAR f_norm_arg
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | tSTAR f_norm_arg tCOMMA f_marg_list
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.restarg(val[0]) ]
- }
- | tSTAR tCOMMA f_marg_list
- {
- result = [ @builder.restarg(val[0]),
- *val[2] ]
- }
-
- block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[2]).concat(val[3])
- }
- | f_block_kwarg opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
-
-opt_block_args_tail:
- tCOMMA block_args_tail
- {
- result = val[1]
- }
- | # nothing
- {
- result = []
- }
-
- block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_block_optarg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_block_args_tail
- {
- result = val[0].concat(val[1])
- }
- | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_block_optarg opt_block_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_block_optarg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | block_args_tail
-
- opt_block_param: # nothing
- {
- result = @builder.args(nil, [], nil)
- }
- | block_param_def
- {
- @lexer.state = :expr_value
- }
-
- block_param_def: tPIPE opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1], val[2])
- }
- | tOROP
- {
- result = @builder.args(val[0], [], val[0])
- }
- | tPIPE block_param opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
-
- opt_bv_decl: opt_nl
- {
- result = []
- }
- | opt_nl tSEMI bv_decls opt_nl
- {
- result = val[2]
- }
-
- bv_decls: bvar
- {
- result = [ val[0] ]
- }
- | bv_decls tCOMMA bvar
- {
- result = val[0] << val[2]
- }
-
- bvar: tIDENTIFIER
- {
- result = @builder.shadowarg(val[0])
- }
- | f_bad_arg
-
- lambda: {
- @static_env.extend_dynamic
- }
- f_larglist lambda_body
- {
- result = [ val[1], val[2] ]
-
- @static_env.unextend
- }
-
- f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
- | f_args
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- lambda_body: tLAMBEG compstmt tRCURLY
- {
- result = [ val[0], val[1], val[2] ]
- }
- | kDO_LAMBDA compstmt kEND
- {
- result = [ val[0], val[1], val[2] ]
- }
-
- do_block: kDO_BLOCK
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- block_call: command do_block
- {
- begin_t, block_args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, block_args, body, end_t)
- }
- | block_call dot_or_colon operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | block_call dot_or_colon operation2 opt_paren_args brace_block
- {
- lparen_t, args, rparen_t = val[3]
- method_call = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | block_call dot_or_colon operation2 command_args do_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
-
- method_call: fcall paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
- }
- | primary_value tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation2 paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation3
- {
- result = @builder.call_method(val[0], val[1], val[2])
- }
- | primary_value tDOT paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | kSUPER paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
- }
- | kSUPER
- {
- result = @builder.keyword_cmd(:zsuper, val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index(val[0], val[1], val[2], val[3])
- }
-
- brace_block: tLCURLY
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
- | kDO
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- case_body: kWHEN args then compstmt cases
- {
- result = [ @builder.when(val[0], val[1], val[2], val[3]),
- *val[4] ]
- }
-
- cases: opt_else
- {
- result = [ val[0] ]
- }
- | case_body
-
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
- {
- assoc_t, exc_var = val[2]
-
- if val[1]
- exc_list = @builder.array(nil, val[1], nil)
- end
-
- result = [ @builder.rescue_body(val[0],
- exc_list, assoc_t, exc_var,
- val[3], val[4]),
- *val[5] ]
- }
- |
- {
- result = []
- }
-
- exc_list: arg_value
- {
- result = [ val[0] ]
- }
- | mrhs
- | none
-
- exc_var: tASSOC lhs
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- opt_ensure: kENSURE compstmt
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- literal: numeric
- | symbol
- | dsym
-
- strings: string
- {
- result = @builder.string_compose(nil, val[0], nil)
- }
-
- string: string1
- {
- result = [ val[0] ]
- }
- | string string1
- {
- result = val[0] << val[1]
- }
-
- string1: tSTRING_BEG string_contents tSTRING_END
- {
- result = @builder.string_compose(val[0], val[1], val[2])
- }
- | tSTRING
- {
- result = @builder.string(val[0])
- }
- | tCHARACTER
- {
- result = @builder.character(val[0])
- }
-
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
- {
- result = @builder.xstring_compose(val[0], val[1], val[2])
- }
-
- regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
- {
- opts = @builder.regexp_options(val[3])
- result = @builder.regexp_compose(val[0], val[1], val[2], opts)
- }
-
- words: tWORDS_BEG word_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- word_list: # nothing
- {
- result = []
- }
- | word_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- word: string_content
- {
- result = [ val[0] ]
- }
- | word string_content
- {
- result = val[0] << val[1]
- }
-
- symbols: tSYMBOLS_BEG symbol_list tSTRING_END
- {
- result = @builder.symbols_compose(val[0], val[1], val[2])
- }
-
- symbol_list: # nothing
- {
- result = []
- }
- | symbol_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- qwords: tQWORDS_BEG qword_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END
- {
- result = @builder.symbols_compose(val[0], val[1], val[2])
- }
-
- qword_list: # nothing
- {
- result = []
- }
- | qword_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.string_internal(val[1])
- }
-
- qsym_list: # nothing
- {
- result = []
- }
- | qsym_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.symbol_internal(val[1])
- }
-
- string_contents: # nothing
- {
- result = []
- }
- | string_contents string_content
- {
- result = val[0] << val[1]
- }
-
-xstring_contents: # nothing
- {
- result = []
- }
- | xstring_contents string_content
- {
- result = val[0] << val[1]
- }
-
-regexp_contents: # nothing
- {
- result = []
- }
- | regexp_contents string_content
- {
- result = val[0] << val[1]
- }
-
- string_content: tSTRING_CONTENT
- {
- result = @builder.string_internal(val[0])
- }
- | tSTRING_DVAR string_dvar
- {
- result = val[1]
- }
- | tSTRING_DBEG
- {
- @lexer.cond.push(false)
- @lexer.cmdarg.push(false)
- }
- compstmt tSTRING_DEND
- {
- @lexer.cond.lexpop
- @lexer.cmdarg.lexpop
-
- result = @builder.begin(val[0], val[2], val[3])
- }
-
- string_dvar: tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
- | backref
-
-
- symbol: tSYMBOL
- {
- result = @builder.symbol(val[0])
- }
-
- dsym: tSYMBEG xstring_contents tSTRING_END
- {
- result = @builder.symbol_compose(val[0], val[1], val[2])
- }
-
- numeric: tINTEGER
- {
- result = @builder.integer(val[0])
- }
- | tFLOAT
- {
- result = @builder.float(val[0])
- }
- | tUMINUS_NUM tINTEGER =tLOWEST
- {
- result = @builder.negate(val[0],
- @builder.integer(val[1]))
- }
- | tUMINUS_NUM tFLOAT =tLOWEST
- {
- result = @builder.negate(val[0],
- @builder.float(val[1]))
- }
-
- user_variable: tIDENTIFIER
- {
- result = @builder.ident(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tCONSTANT
- {
- result = @builder.const(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
-
-keyword_variable: kNIL
- {
- result = @builder.nil(val[0])
- }
- | kSELF
- {
- result = @builder.self(val[0])
- }
- | kTRUE
- {
- result = @builder.true(val[0])
- }
- | kFALSE
- {
- result = @builder.false(val[0])
- }
- | k__FILE__
- {
- result = @builder.__FILE__(val[0])
- }
- | k__LINE__
- {
- result = @builder.__LINE__(val[0])
- }
- | k__ENCODING__
- {
- result = @builder.__ENCODING__(val[0])
- }
-
- var_ref: user_variable
- {
- result = @builder.accessible(val[0])
- }
- | keyword_variable
- {
- result = @builder.accessible(val[0])
- }
-
- var_lhs: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
-
- backref: tNTH_REF
- {
- result = @builder.nth_ref(val[0])
- }
- | tBACK_REF
- {
- result = @builder.back_ref(val[0])
- }
-
- superclass: term
- {
- result = nil
- }
- | tLT
- {
- @lexer.state = :expr_value
- }
- expr_value term
- {
- result = [ val[0], val[2] ]
- }
- | error term
- {
- yyerrok
- result = nil
- }
-
- f_arglist: tLPAREN2 f_args rparen
- {
- result = @builder.args(val[0], val[1], val[2])
-
- @lexer.state = :expr_value
- }
- | f_args term
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[2]).concat(val[3])
- }
- | f_kwarg opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
-
- opt_args_tail: tCOMMA args_tail
- {
- result = val[1]
- }
- | # nothing
- {
- result = []
- }
-
- f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_optarg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_optarg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | args_tail
- {
- result = val[0]
- }
- | # nothing
- {
- result = []
- }
-
- f_bad_arg: tCONSTANT
- {
- diagnostic :error, :argument_const, nil, val[0]
- }
- | tIVAR
- {
- diagnostic :error, :argument_ivar, nil, val[0]
- }
- | tGVAR
- {
- diagnostic :error, :argument_gvar, nil, val[0]
- }
- | tCVAR
- {
- diagnostic :error, :argument_cvar, nil, val[0]
- }
-
- f_norm_arg: f_bad_arg
- | tIDENTIFIER
-
- f_arg_item: f_norm_arg
- {
- @static_env.declare val[0][0]
-
- result = @builder.arg(val[0])
- }
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_arg: f_arg_item
- {
- result = [ val[0] ]
- }
- | f_arg tCOMMA f_arg_item
- {
- result = val[0] << val[2]
- }
-
- f_kw: tLABEL arg_value
- {
- check_kwarg_name(val[0])
-
- @static_env.declare val[0][0]
-
- result = @builder.kwoptarg(val[0], val[1])
- }
-
- f_block_kw: tLABEL primary_value
- {
- check_kwarg_name(val[0])
-
- @static_env.declare val[0][0]
-
- result = @builder.kwoptarg(val[0], val[1])
- }
-
- f_block_kwarg: f_block_kw
- {
- result = [ val[0] ]
- }
- | f_block_kwarg tCOMMA f_block_kw
- {
- result = val[0] << val[2]
- }
-
- f_kwarg: f_kw
- {
- result = [ val[0] ]
- }
- | f_kwarg tCOMMA f_kw
- {
- result = val[0] << val[2]
- }
-
- kwrest_mark: tPOW | tDSTAR
-
- f_kwrest: kwrest_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.kwrestarg(val[0], val[1]) ]
- }
- | kwrest_mark
- {
- result = [ @builder.kwrestarg(val[0]) ]
- }
-
- f_opt: tIDENTIFIER tEQL arg_value
- {
- @static_env.declare val[0][0]
-
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_opt: tIDENTIFIER tEQL primary_value
- {
- @static_env.declare val[0][0]
-
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_optarg: f_block_opt
- {
- result = [ val[0] ]
- }
- | f_block_optarg tCOMMA f_block_opt
- {
- result = val[0] << val[2]
- }
-
- f_optarg: f_opt
- {
- result = [ val[0] ]
- }
- | f_optarg tCOMMA f_opt
- {
- result = val[0] << val[2]
- }
-
- restarg_mark: tSTAR2 | tSTAR
-
- f_rest_arg: restarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | restarg_mark
- {
- result = [ @builder.restarg(val[0]) ]
- }
-
- blkarg_mark: tAMPER2 | tAMPER
-
- f_block_arg: blkarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = @builder.blockarg(val[0], val[1])
- }
-
- opt_f_block_arg: tCOMMA f_block_arg
- {
- result = [ val[1] ]
- }
- |
- {
- result = []
- }
-
- singleton: var_ref
- | tLPAREN2 expr rparen
- {
- result = val[1]
- }
-
- assoc_list: # nothing
- {
- result = []
- }
- | assocs trailer
-
- assocs: assoc
- {
- result = [ val[0] ]
- }
- | assocs tCOMMA assoc
- {
- result = val[0] << val[2]
- }
-
- assoc: arg_value tASSOC arg_value
- {
- result = @builder.pair(val[0], val[1], val[2])
- }
- | tLABEL arg_value
- {
- result = @builder.pair_keyword(val[0], val[1])
- }
- | tDSTAR arg_value
- {
- result = @builder.kwsplat(val[0], val[1])
- }
-
- operation: tIDENTIFIER | tCONSTANT | tFID
- operation2: tIDENTIFIER | tCONSTANT | tFID | op
- operation3: tIDENTIFIER | tFID | op
- dot_or_colon: tDOT | tCOLON2
- opt_terms: | terms
- opt_nl: | tNL
- rparen: opt_nl tRPAREN
- {
- result = val[1]
- }
- rbracket: opt_nl tRBRACK
- {
- result = val[1]
- }
- trailer: | tNL | tCOMMA
-
- term: tSEMI
- {
- yyerrok
- }
- | tNL
-
- terms: term
- | terms tSEMI
-
- none: # nothing
- {
- result = nil
- }
-end
-
----- header
-
-require 'parser'
-
-Parser.check_for_encoding_support
-
----- inner
-
- def version
- 20
- end
-
- def default_encoding
- Encoding::UTF_8
- end
diff --git a/test/racc/assets/ruby21.y b/test/racc/assets/ruby21.y
deleted file mode 100644
index 2ac94afb0c..0000000000
--- a/test/racc/assets/ruby21.y
+++ /dev/null
@@ -1,2359 +0,0 @@
-# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org>
-#
-# Parts of the source are derived from ruby_parser:
-# Copyright (c) Ryan Davis, seattle.rb
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Parser::Ruby21
-
-token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
- kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
- kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
- kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
- kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
- k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
- tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
- tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
- tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
- tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
- tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
- tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
- tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
- tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
- tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
- tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
- tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
- tRATIONAL tIMAGINARY
-
-prechigh
- right tBANG tTILDE tUPLUS
- right tPOW
- right tUMINUS_NUM tUMINUS
- left tSTAR2 tDIVIDE tPERCENT
- left tPLUS tMINUS
- left tLSHFT tRSHFT
- left tAMPER2
- left tPIPE tCARET
- left tGT tGEQ tLT tLEQ
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
- left tANDOP
- left tOROP
- nonassoc tDOT2 tDOT3
- right tEH tCOLON
- left kRESCUE_MOD
- right tEQL tOP_ASGN
- nonassoc kDEFINED
- right kNOT
- left kOR kAND
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
- nonassoc tLBRACE_ARG
- nonassoc tLOWEST
-preclow
-
-rule
-
- program: top_compstmt
-
- top_compstmt: top_stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- top_stmts: # nothing
- {
- result = []
- }
- | top_stmt
- {
- result = [ val[0] ]
- }
- | top_stmts terms top_stmt
- {
- result = val[0] << val[2]
- }
- | error top_stmt
- {
- result = [ val[1] ]
- }
-
- top_stmt: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- result = @builder.preexe(val[0], val[1], val[2], val[3])
- }
-
- bodystmt: compstmt opt_rescue opt_else opt_ensure
- {
- rescue_bodies = val[1]
- else_t, else_ = val[2]
- ensure_t, ensure_ = val[3]
-
- if rescue_bodies.empty? && !else_.nil?
- diagnostic :warning, :useless_else, nil, else_t
- end
-
- result = @builder.begin_body(val[0],
- rescue_bodies,
- else_t, else_,
- ensure_t, ensure_)
- }
-
- compstmt: stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- stmts: # nothing
- {
- result = []
- }
- | stmt_or_begin
- {
- result = [ val[0] ]
- }
- | stmts terms stmt_or_begin
- {
- result = val[0] << val[2]
- }
- | error stmt
- {
- result = [ val[1] ]
- }
-
- stmt_or_begin: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- diagnostic :error, :begin_in_method, nil, val[0]
- }
-
- stmt: kALIAS fitem
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = @builder.alias(val[0], val[1], val[3])
- }
- | kALIAS tGVAR tGVAR
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.gvar(val[2]))
- }
- | kALIAS tGVAR tBACK_REF
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.back_ref(val[2]))
- }
- | kALIAS tGVAR tNTH_REF
- {
- diagnostic :error, :nth_ref_alias, nil, val[2]
- }
- | kUNDEF undef_list
- {
- result = @builder.undef_method(val[0], val[1])
- }
- | stmt kIF_MOD expr_value
- {
- result = @builder.condition_mod(val[0], nil,
- val[1], val[2])
- }
- | stmt kUNLESS_MOD expr_value
- {
- result = @builder.condition_mod(nil, val[0],
- val[1], val[2])
- }
- | stmt kWHILE_MOD expr_value
- {
- result = @builder.loop_mod(:while, val[0], val[1], val[2])
- }
- | stmt kUNTIL_MOD expr_value
- {
- result = @builder.loop_mod(:until, val[0], val[1], val[2])
- }
- | stmt kRESCUE_MOD stmt
- {
- rescue_body = @builder.rescue_body(val[1],
- nil, nil, nil,
- nil, val[2])
-
- result = @builder.begin_body(val[0], [ rescue_body ])
- }
- | klEND tLCURLY compstmt tRCURLY
- {
- result = @builder.postexe(val[0], val[1], val[2], val[3])
- }
- | command_asgn
- | mlhs tEQL command_call
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN command_call
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | backref tOP_ASGN command_call
- {
- @builder.op_assign(val[0], val[1], val[2])
- }
- | lhs tEQL mrhs
- {
- result = @builder.assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | mlhs tEQL mrhs_arg
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | expr
-
- command_asgn: lhs tEQL command_call
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL command_asgn
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
-
- expr: command_call
- | expr kAND expr
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | expr kOR expr
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kNOT opt_nl expr
- {
- result = @builder.not_op(val[0], nil, val[2], nil)
- }
- | tBANG command_call
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | arg
-
- expr_value: expr
-
- command_call: command
- | block_command
-
- block_command: block_call
- | block_call dot_or_colon operation2 command_args
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
-
- cmd_brace_block: tLBRACE_ARG
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- fcall: operation
-
- command: fcall command_args =tLOWEST
- {
- result = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
- }
- | fcall command_args cmd_brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
-
- begin_t, args, body, end_t = val[2]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tDOT operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | primary_value tDOT operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tCOLON2 operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | primary_value tCOLON2 operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | kSUPER command_args
- {
- result = @builder.keyword_cmd(:super, val[0],
- nil, val[1], nil)
- }
- | kYIELD command_args
- {
- result = @builder.keyword_cmd(:yield, val[0],
- nil, val[1], nil)
- }
- | kRETURN call_args
- {
- result = @builder.keyword_cmd(:return, val[0],
- nil, val[1], nil)
- }
- | kBREAK call_args
- {
- result = @builder.keyword_cmd(:break, val[0],
- nil, val[1], nil)
- }
- | kNEXT call_args
- {
- result = @builder.keyword_cmd(:next, val[0],
- nil, val[1], nil)
- }
-
- mlhs: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_inner: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- mlhs_basic: mlhs_head
- | mlhs_head mlhs_item
- {
- result = val[0].
- push(val[1])
- }
- | mlhs_head tSTAR mlhs_node
- {
- result = val[0].
- push(@builder.splat(val[1], val[2]))
- }
- | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1], val[2])).
- concat(val[4])
- }
- | mlhs_head tSTAR
- {
- result = val[0].
- push(@builder.splat(val[1]))
- }
- | mlhs_head tSTAR tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1])).
- concat(val[3])
- }
- | tSTAR mlhs_node
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.splat(val[0]) ]
- }
- | tSTAR tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0]),
- *val[2] ]
- }
-
- mlhs_item: mlhs_node
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_head: mlhs_item tCOMMA
- {
- result = [ val[0] ]
- }
- | mlhs_head mlhs_item tCOMMA
- {
- result = val[0] << val[1]
- }
-
- mlhs_post: mlhs_item
- {
- result = [ val[0] ]
- }
- | mlhs_post tCOMMA mlhs_item
- {
- result = val[0] << val[2]
- }
-
- mlhs_node: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- lhs: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- cname: tIDENTIFIER
- {
- diagnostic :error, :module_name_const, nil, val[0]
- }
- | tCONSTANT
-
- cpath: tCOLON3 cname
- {
- result = @builder.const_global(val[0], val[1])
- }
- | cname
- {
- result = @builder.const(val[0])
- }
- | primary_value tCOLON2 cname
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
-
- fname: tIDENTIFIER | tCONSTANT | tFID
- | op
- | reswords
-
- fsym: fname
- {
- result = @builder.symbol(val[0])
- }
- | symbol
-
- fitem: fsym
- | dsym
-
- undef_list: fitem
- {
- result = [ val[0] ]
- }
- | undef_list tCOMMA
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = val[0] << val[3]
- }
-
- op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
- | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
- | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
- | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
- | tUPLUS | tUMINUS | tAREF | tASET | tDSTAR | tBACK_REF2
-
- reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
- | kALIAS | kAND | kBEGIN | kBREAK | kCASE
- | kCLASS | kDEF | kDEFINED | kDO | kELSE
- | kELSIF | kEND | kENSURE | kFALSE | kFOR
- | kIN | kMODULE | kNEXT | kNIL | kNOT
- | kOR | kREDO | kRESCUE | kRETRY | kRETURN
- | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
- | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
- | kUNTIL
-
- arg: lhs tEQL arg
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.assign(val[0], val[1], rescue_)
- }
- | var_lhs tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.op_assign(val[0], val[1], rescue_)
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
- {
- const = @builder.const_op_assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- result = @builder.op_assign(const, val[3], val[4])
- }
- | tCOLON3 tCONSTANT tOP_ASGN arg
- {
- const = @builder.const_op_assignable(
- @builder.const_global(val[0], val[1]))
- result = @builder.op_assign(const, val[2], val[3])
- }
- | backref tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | arg tDOT2 arg
- {
- result = @builder.range_inclusive(val[0], val[1], val[2])
- }
- | arg tDOT3 arg
- {
- result = @builder.range_exclusive(val[0], val[1], val[2])
- }
- | arg tPLUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMINUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tSTAR2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tDIVIDE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPERCENT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPOW arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tUMINUS_NUM simple_numeric tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- val[1], val[2], val[3]))
- }
- | tUPLUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | tUMINUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tPIPE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCARET arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tAMPER2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCMP arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tNEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMATCH arg
- {
- result = @builder.match_op(val[0], val[1], val[2])
- }
- | arg tNMATCH arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tBANG arg
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | tTILDE arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tLSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tRSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tANDOP arg
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | arg tOROP arg
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kDEFINED opt_nl arg
- {
- result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
- }
-
- | arg tEH arg opt_nl tCOLON arg
- {
- result = @builder.ternary(val[0], val[1],
- val[2], val[4], val[5])
- }
- | primary
-
- arg_value: arg
-
- aref_args: none
- | args trailer
- | args tCOMMA assocs trailer
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs trailer
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- paren_args: tLPAREN2 opt_call_args rparen
- {
- result = val
- }
-
- opt_paren_args: # nothing
- {
- result = [ nil, [], nil ]
- }
- | paren_args
-
- opt_call_args: # nothing
- {
- result = []
- }
- | call_args
- | args tCOMMA
- | args tCOMMA assocs tCOMMA
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs tCOMMA
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- call_args: command
- {
- result = [ val[0] ]
- }
- | args opt_block_arg
- {
- result = val[0].concat(val[1])
- }
- | assocs opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- result.concat(val[1])
- }
- | args tCOMMA assocs opt_block_arg
- {
- assocs = @builder.associate(nil, val[2], nil)
- result = val[0] << assocs
- result.concat(val[3])
- }
- | block_arg
- {
- result = [ val[0] ]
- }
-
- command_args: {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.push(true)
- }
- call_args
- {
- @lexer.cmdarg = val[0]
-
- result = val[1]
- }
-
- block_arg: tAMPER arg_value
- {
- result = @builder.block_pass(val[0], val[1])
- }
-
- opt_block_arg: tCOMMA block_arg
- {
- result = [ val[1] ]
- }
- | # nothing
- {
- result = []
- }
-
- args: arg_value
- {
- result = [ val[0] ]
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
-
- mrhs_arg: mrhs
- {
- result = @builder.array(nil, val[0], nil)
- }
- | arg_value
-
- mrhs: args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
-
- primary: literal
- | strings
- | xstring
- | regexp
- | words
- | qwords
- | symbols
- | qsymbols
- | var_ref
- | backref
- | tFID
- {
- result = @builder.call_method(nil, nil, val[0])
- }
- | kBEGIN
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- bodystmt kEND
- {
- @lexer.cmdarg = val[1]
-
- result = @builder.begin_keyword(val[0], val[2], val[3])
- }
- | tLPAREN_ARG
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- expr
- {
- @lexer.state = :expr_endarg
- }
- opt_nl tRPAREN
- {
- @lexer.cmdarg = val[1]
-
- result = @builder.begin(val[0], val[2], val[5])
- }
- | tLPAREN_ARG
- {
- @lexer.state = :expr_endarg
- }
- opt_nl tRPAREN
- {
- result = @builder.begin(val[0], nil, val[3])
- }
- | tLPAREN compstmt tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.const_global(val[0], val[1])
- }
- | tLBRACK aref_args tRBRACK
- {
- result = @builder.array(val[0], val[1], val[2])
- }
- | tLBRACE assoc_list tRCURLY
- {
- result = @builder.associate(val[0], val[1], val[2])
- }
- | kRETURN
- {
- result = @builder.keyword_cmd(:return, val[0])
- }
- | kYIELD tLPAREN2 call_args rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
- }
- | kYIELD tLPAREN2 rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
- }
- | kYIELD
- {
- result = @builder.keyword_cmd(:yield, val[0])
- }
- | kDEFINED opt_nl tLPAREN2 expr rparen
- {
- result = @builder.keyword_cmd(:defined?, val[0],
- val[2], [ val[3] ], val[4])
- }
- | kNOT tLPAREN2 expr rparen
- {
- result = @builder.not_op(val[0], val[1], val[2], val[3])
- }
- | kNOT tLPAREN2 rparen
- {
- result = @builder.not_op(val[0], val[1], nil, val[2])
- }
- | fcall brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0])
-
- begin_t, args, body, end_t = val[1]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | method_call
- | method_call brace_block
- {
- begin_t, args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, args, body, end_t)
- }
- | tLAMBDA lambda
- {
- lambda_call = @builder.call_lambda(val[0])
-
- args, (begin_t, body, end_t) = val[1]
- result = @builder.block(lambda_call,
- begin_t, args, body, end_t)
- }
- | kIF expr_value then compstmt if_tail kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, val[5])
- }
- | kUNLESS expr_value then compstmt opt_else kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- else_, else_t,
- val[3], val[5])
- }
- | kWHILE
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:while, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kUNTIL
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:until, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kCASE expr_value opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[3]
-
- result = @builder.case(val[0], val[1],
- when_bodies, else_t, else_body,
- val[4])
- }
- | kCASE opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[2]
-
- result = @builder.case(val[0], nil,
- when_bodies, else_t, else_body,
- val[3])
- }
- | kFOR for_var kIN
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.for(val[0], val[1],
- val[2], val[4],
- val[5], val[7], val[8])
- }
- | kCLASS cpath superclass
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :class_in_def, nil, val[0]
- end
-
- lt_t, superclass = val[2]
- result = @builder.def_class(val[0], val[1],
- lt_t, superclass,
- val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kCLASS tLSHFT expr term
- {
- result = @def_level
- @def_level = 0
-
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- result = @builder.def_sclass(val[0], val[1], val[2],
- val[5], val[6])
-
- @lexer.pop_cmdarg
- @static_env.unextend
-
- @def_level = val[4]
- }
- | kMODULE cpath
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :module_in_def, nil, val[0]
- end
-
- result = @builder.def_module(val[0], val[1],
- val[3], val[4])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kDEF fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_method(val[0], val[1],
- val[3], val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kDEF singleton dot_or_colon
- {
- @lexer.state = :expr_fname
- }
- fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_singleton(val[0], val[1], val[2],
- val[4], val[6], val[7], val[8])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kBREAK
- {
- result = @builder.keyword_cmd(:break, val[0])
- }
- | kNEXT
- {
- result = @builder.keyword_cmd(:next, val[0])
- }
- | kREDO
- {
- result = @builder.keyword_cmd(:redo, val[0])
- }
- | kRETRY
- {
- result = @builder.keyword_cmd(:retry, val[0])
- }
-
- primary_value: primary
-
- then: term
- | kTHEN
- | term kTHEN
- {
- result = val[1]
- }
-
- do: term
- | kDO_COND
-
- if_tail: opt_else
- | kELSIF expr_value then compstmt if_tail
- {
- else_t, else_ = val[4]
- result = [ val[0],
- @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, nil),
- ]
- }
-
- opt_else: none
- | kELSE compstmt
- {
- result = val
- }
-
- for_var: lhs
- | mlhs
-
- f_marg: f_norm_arg
- {
- result = @builder.arg(val[0])
- }
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_marg_list: f_marg
- {
- result = [ val[0] ]
- }
- | f_marg_list tCOMMA f_marg
- {
- result = val[0] << val[2]
- }
-
- f_margs: f_marg_list
- | f_marg_list tCOMMA tSTAR f_norm_arg
- {
- result = val[0].
- push(@builder.restarg(val[2], val[3]))
- }
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
- {
- result = val[0].
- push(@builder.restarg(val[2], val[3])).
- concat(val[5])
- }
- | f_marg_list tCOMMA tSTAR
- {
- result = val[0].
- push(@builder.restarg(val[2]))
- }
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
- {
- result = val[0].
- push(@builder.restarg(val[2])).
- concat(val[4])
- }
- | tSTAR f_norm_arg
- {
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | tSTAR f_norm_arg tCOMMA f_marg_list
- {
- result = [ @builder.restarg(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.restarg(val[0]) ]
- }
- | tSTAR tCOMMA f_marg_list
- {
- result = [ @builder.restarg(val[0]),
- *val[2] ]
- }
-
- block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[2]).concat(val[3])
- }
- | f_block_kwarg opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
-
-opt_block_args_tail:
- tCOMMA block_args_tail
- {
- result = val[1]
- }
- | # nothing
- {
- result = []
- }
-
- block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_block_optarg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_block_args_tail
- {
- result = val[0].concat(val[1])
- }
- | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_block_optarg opt_block_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_block_optarg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | block_args_tail
-
- opt_block_param: # nothing
- {
- result = @builder.args(nil, [], nil)
- }
- | block_param_def
- {
- @lexer.state = :expr_value
- }
-
- block_param_def: tPIPE opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1], val[2])
- }
- | tOROP
- {
- result = @builder.args(val[0], [], val[0])
- }
- | tPIPE block_param opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
-
- opt_bv_decl: opt_nl
- {
- result = []
- }
- | opt_nl tSEMI bv_decls opt_nl
- {
- result = val[2]
- }
-
- bv_decls: bvar
- {
- result = [ val[0] ]
- }
- | bv_decls tCOMMA bvar
- {
- result = val[0] << val[2]
- }
-
- bvar: tIDENTIFIER
- {
- result = @builder.shadowarg(val[0])
- }
- | f_bad_arg
-
- lambda: {
- @static_env.extend_dynamic
- }
- f_larglist
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- lambda_body
- {
- @lexer.cmdarg = val[2]
- @lexer.cmdarg.lexpop
-
- result = [ val[1], val[3] ]
-
- @static_env.unextend
- }
-
- f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
- | f_args
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- lambda_body: tLAMBEG compstmt tRCURLY
- {
- result = [ val[0], val[1], val[2] ]
- }
- | kDO_LAMBDA compstmt kEND
- {
- result = [ val[0], val[1], val[2] ]
- }
-
- do_block: kDO_BLOCK
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- block_call: command do_block
- {
- begin_t, block_args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, block_args, body, end_t)
- }
- | block_call dot_or_colon operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | block_call dot_or_colon operation2 opt_paren_args brace_block
- {
- lparen_t, args, rparen_t = val[3]
- method_call = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | block_call dot_or_colon operation2 command_args do_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
-
- method_call: fcall paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
- }
- | primary_value tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation2 paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation3
- {
- result = @builder.call_method(val[0], val[1], val[2])
- }
- | primary_value tDOT paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | kSUPER paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
- }
- | kSUPER
- {
- result = @builder.keyword_cmd(:zsuper, val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index(val[0], val[1], val[2], val[3])
- }
-
- brace_block: tLCURLY
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
- | kDO
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- case_body: kWHEN args then compstmt cases
- {
- result = [ @builder.when(val[0], val[1], val[2], val[3]),
- *val[4] ]
- }
-
- cases: opt_else
- {
- result = [ val[0] ]
- }
- | case_body
-
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
- {
- assoc_t, exc_var = val[2]
-
- if val[1]
- exc_list = @builder.array(nil, val[1], nil)
- end
-
- result = [ @builder.rescue_body(val[0],
- exc_list, assoc_t, exc_var,
- val[3], val[4]),
- *val[5] ]
- }
- |
- {
- result = []
- }
-
- exc_list: arg_value
- {
- result = [ val[0] ]
- }
- | mrhs
- | none
-
- exc_var: tASSOC lhs
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- opt_ensure: kENSURE compstmt
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- literal: numeric
- | symbol
- | dsym
-
- strings: string
- {
- result = @builder.string_compose(nil, val[0], nil)
- }
-
- string: string1
- {
- result = [ val[0] ]
- }
- | string string1
- {
- result = val[0] << val[1]
- }
-
- string1: tSTRING_BEG string_contents tSTRING_END
- {
- result = @builder.string_compose(val[0], val[1], val[2])
- }
- | tSTRING
- {
- result = @builder.string(val[0])
- }
- | tCHARACTER
- {
- result = @builder.character(val[0])
- }
-
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
- {
- result = @builder.xstring_compose(val[0], val[1], val[2])
- }
-
- regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
- {
- opts = @builder.regexp_options(val[3])
- result = @builder.regexp_compose(val[0], val[1], val[2], opts)
- }
-
- words: tWORDS_BEG word_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- word_list: # nothing
- {
- result = []
- }
- | word_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- word: string_content
- {
- result = [ val[0] ]
- }
- | word string_content
- {
- result = val[0] << val[1]
- }
-
- symbols: tSYMBOLS_BEG symbol_list tSTRING_END
- {
- result = @builder.symbols_compose(val[0], val[1], val[2])
- }
-
- symbol_list: # nothing
- {
- result = []
- }
- | symbol_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- qwords: tQWORDS_BEG qword_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END
- {
- result = @builder.symbols_compose(val[0], val[1], val[2])
- }
-
- qword_list: # nothing
- {
- result = []
- }
- | qword_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.string_internal(val[1])
- }
-
- qsym_list: # nothing
- {
- result = []
- }
- | qsym_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.symbol_internal(val[1])
- }
-
- string_contents: # nothing
- {
- result = []
- }
- | string_contents string_content
- {
- result = val[0] << val[1]
- }
-
-xstring_contents: # nothing
- {
- result = []
- }
- | xstring_contents string_content
- {
- result = val[0] << val[1]
- }
-
-regexp_contents: # nothing
- {
- result = []
- }
- | regexp_contents string_content
- {
- result = val[0] << val[1]
- }
-
- string_content: tSTRING_CONTENT
- {
- result = @builder.string_internal(val[0])
- }
- | tSTRING_DVAR string_dvar
- {
- result = val[1]
- }
- | tSTRING_DBEG
- {
- @lexer.cond.push(false)
- @lexer.cmdarg.push(false)
- }
- compstmt tSTRING_DEND
- {
- @lexer.cond.lexpop
- @lexer.cmdarg.lexpop
-
- result = @builder.begin(val[0], val[2], val[3])
- }
-
- string_dvar: tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
- | backref
-
-
- symbol: tSYMBOL
- {
- result = @builder.symbol(val[0])
- }
-
- dsym: tSYMBEG xstring_contents tSTRING_END
- {
- result = @builder.symbol_compose(val[0], val[1], val[2])
- }
-
- numeric: simple_numeric
- {
- result = val[0]
- }
- | tUMINUS_NUM simple_numeric =tLOWEST
- {
- result = @builder.negate(val[0], val[1])
- }
-
- simple_numeric: tINTEGER
- {
- result = @builder.integer(val[0])
- }
- | tFLOAT
- {
- result = @builder.float(val[0])
- }
- | tRATIONAL
- {
- result = @builder.rational(val[0])
- }
- | tIMAGINARY
- {
- result = @builder.complex(val[0])
- }
-
- user_variable: tIDENTIFIER
- {
- result = @builder.ident(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tCONSTANT
- {
- result = @builder.const(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
-
-keyword_variable: kNIL
- {
- result = @builder.nil(val[0])
- }
- | kSELF
- {
- result = @builder.self(val[0])
- }
- | kTRUE
- {
- result = @builder.true(val[0])
- }
- | kFALSE
- {
- result = @builder.false(val[0])
- }
- | k__FILE__
- {
- result = @builder.__FILE__(val[0])
- }
- | k__LINE__
- {
- result = @builder.__LINE__(val[0])
- }
- | k__ENCODING__
- {
- result = @builder.__ENCODING__(val[0])
- }
-
- var_ref: user_variable
- {
- result = @builder.accessible(val[0])
- }
- | keyword_variable
- {
- result = @builder.accessible(val[0])
- }
-
- var_lhs: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
-
- backref: tNTH_REF
- {
- result = @builder.nth_ref(val[0])
- }
- | tBACK_REF
- {
- result = @builder.back_ref(val[0])
- }
-
- superclass: term
- {
- result = nil
- }
- | tLT
- {
- @lexer.state = :expr_value
- }
- expr_value term
- {
- result = [ val[0], val[2] ]
- }
- | error term
- {
- yyerrok
- result = nil
- }
-
- f_arglist: tLPAREN2 f_args rparen
- {
- result = @builder.args(val[0], val[1], val[2])
-
- @lexer.state = :expr_value
- }
- | {
- result = @lexer.in_kwarg
- @lexer.in_kwarg = true
- }
- f_args term
- {
- @lexer.in_kwarg = val[0]
- result = @builder.args(nil, val[1], nil)
- }
-
-
- args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[2]).concat(val[3])
- }
- | f_kwarg opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
-
- opt_args_tail: tCOMMA args_tail
- {
- result = val[1]
- }
- | # nothing
- {
- result = []
- }
-
- f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_optarg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_optarg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | args_tail
- {
- result = val[0]
- }
- | # nothing
- {
- result = []
- }
-
- f_bad_arg: tCONSTANT
- {
- diagnostic :error, :argument_const, nil, val[0]
- }
- | tIVAR
- {
- diagnostic :error, :argument_ivar, nil, val[0]
- }
- | tGVAR
- {
- diagnostic :error, :argument_gvar, nil, val[0]
- }
- | tCVAR
- {
- diagnostic :error, :argument_cvar, nil, val[0]
- }
-
- f_norm_arg: f_bad_arg
- | tIDENTIFIER
- {
- @static_env.declare val[0][0]
-
- result = val[0]
- }
-
- f_arg_item: f_norm_arg
- {
- result = @builder.arg(val[0])
- }
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_arg: f_arg_item
- {
- result = [ val[0] ]
- }
- | f_arg tCOMMA f_arg_item
- {
- result = val[0] << val[2]
- }
-
- f_label: tLABEL
- {
- check_kwarg_name(val[0])
-
- @static_env.declare val[0][0]
-
- result = val[0]
- }
-
- f_kw: f_label arg_value
- {
- result = @builder.kwoptarg(val[0], val[1])
- }
- | f_label
- {
- result = @builder.kwarg(val[0])
- }
-
- f_block_kw: f_label primary_value
- {
- result = @builder.kwoptarg(val[0], val[1])
- }
- | f_label
- {
- result = @builder.kwarg(val[0])
- }
-
- f_block_kwarg: f_block_kw
- {
- result = [ val[0] ]
- }
- | f_block_kwarg tCOMMA f_block_kw
- {
- result = val[0] << val[2]
- }
-
- f_kwarg: f_kw
- {
- result = [ val[0] ]
- }
- | f_kwarg tCOMMA f_kw
- {
- result = val[0] << val[2]
- }
-
- kwrest_mark: tPOW | tDSTAR
-
- f_kwrest: kwrest_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.kwrestarg(val[0], val[1]) ]
- }
- | kwrest_mark
- {
- result = [ @builder.kwrestarg(val[0]) ]
- }
-
- f_opt: f_norm_arg tEQL arg_value
- {
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_opt: f_norm_arg tEQL primary_value
- {
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_optarg: f_block_opt
- {
- result = [ val[0] ]
- }
- | f_block_optarg tCOMMA f_block_opt
- {
- result = val[0] << val[2]
- }
-
- f_optarg: f_opt
- {
- result = [ val[0] ]
- }
- | f_optarg tCOMMA f_opt
- {
- result = val[0] << val[2]
- }
-
- restarg_mark: tSTAR2 | tSTAR
-
- f_rest_arg: restarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | restarg_mark
- {
- result = [ @builder.restarg(val[0]) ]
- }
-
- blkarg_mark: tAMPER2 | tAMPER
-
- f_block_arg: blkarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = @builder.blockarg(val[0], val[1])
- }
-
- opt_f_block_arg: tCOMMA f_block_arg
- {
- result = [ val[1] ]
- }
- |
- {
- result = []
- }
-
- singleton: var_ref
- | tLPAREN2 expr rparen
- {
- result = val[1]
- }
-
- assoc_list: # nothing
- {
- result = []
- }
- | assocs trailer
-
- assocs: assoc
- {
- result = [ val[0] ]
- }
- | assocs tCOMMA assoc
- {
- result = val[0] << val[2]
- }
-
- assoc: arg_value tASSOC arg_value
- {
- result = @builder.pair(val[0], val[1], val[2])
- }
- | tLABEL arg_value
- {
- result = @builder.pair_keyword(val[0], val[1])
- }
- | tDSTAR arg_value
- {
- result = @builder.kwsplat(val[0], val[1])
- }
-
- operation: tIDENTIFIER | tCONSTANT | tFID
- operation2: tIDENTIFIER | tCONSTANT | tFID | op
- operation3: tIDENTIFIER | tFID | op
- dot_or_colon: tDOT | tCOLON2
- opt_terms: | terms
- opt_nl: | tNL
- rparen: opt_nl tRPAREN
- {
- result = val[1]
- }
- rbracket: opt_nl tRBRACK
- {
- result = val[1]
- }
- trailer: | tNL | tCOMMA
-
- term: tSEMI
- {
- yyerrok
- }
- | tNL
-
- terms: term
- | terms tSEMI
-
- none: # nothing
- {
- result = nil
- }
-end
-
----- header
-
-require 'parser'
-
-Parser.check_for_encoding_support
-
----- inner
-
- def version
- 21
- end
-
- def default_encoding
- Encoding::UTF_8
- end
diff --git a/test/racc/assets/ruby22.y b/test/racc/assets/ruby22.y
deleted file mode 100644
index 751c0e866b..0000000000
--- a/test/racc/assets/ruby22.y
+++ /dev/null
@@ -1,2381 +0,0 @@
-# Copyright (c) 2013 Peter Zotov <whitequark@whitequark.org>
-#
-# Parts of the source are derived from ruby_parser:
-# Copyright (c) Ryan Davis, seattle.rb
-#
-# MIT License
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-class Parser::Ruby22
-
-token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
- kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
- kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
- kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
- kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
- k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
- tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
- tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
- tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
- tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
- tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
- tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
- tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
- tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
- tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
- tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
- tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
- tRATIONAL tIMAGINARY tLABEL_END
-
-prechigh
- right tBANG tTILDE tUPLUS
- right tPOW
- right tUMINUS_NUM tUMINUS
- left tSTAR2 tDIVIDE tPERCENT
- left tPLUS tMINUS
- left tLSHFT tRSHFT
- left tAMPER2
- left tPIPE tCARET
- left tGT tGEQ tLT tLEQ
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
- left tANDOP
- left tOROP
- nonassoc tDOT2 tDOT3
- right tEH tCOLON
- left kRESCUE_MOD
- right tEQL tOP_ASGN
- nonassoc kDEFINED
- right kNOT
- left kOR kAND
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
- nonassoc tLBRACE_ARG
- nonassoc tLOWEST
-preclow
-
-rule
-
- program: top_compstmt
-
- top_compstmt: top_stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- top_stmts: # nothing
- {
- result = []
- }
- | top_stmt
- {
- result = [ val[0] ]
- }
- | top_stmts terms top_stmt
- {
- result = val[0] << val[2]
- }
- | error top_stmt
- {
- result = [ val[1] ]
- }
-
- top_stmt: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- result = @builder.preexe(val[0], val[1], val[2], val[3])
- }
-
- bodystmt: compstmt opt_rescue opt_else opt_ensure
- {
- rescue_bodies = val[1]
- else_t, else_ = val[2]
- ensure_t, ensure_ = val[3]
-
- if rescue_bodies.empty? && !else_.nil?
- diagnostic :warning, :useless_else, nil, else_t
- end
-
- result = @builder.begin_body(val[0],
- rescue_bodies,
- else_t, else_,
- ensure_t, ensure_)
- }
-
- compstmt: stmts opt_terms
- {
- result = @builder.compstmt(val[0])
- }
-
- stmts: # nothing
- {
- result = []
- }
- | stmt_or_begin
- {
- result = [ val[0] ]
- }
- | stmts terms stmt_or_begin
- {
- result = val[0] << val[2]
- }
- | error stmt
- {
- result = [ val[1] ]
- }
-
- stmt_or_begin: stmt
- | klBEGIN tLCURLY top_compstmt tRCURLY
- {
- diagnostic :error, :begin_in_method, nil, val[0]
- }
-
- stmt: kALIAS fitem
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = @builder.alias(val[0], val[1], val[3])
- }
- | kALIAS tGVAR tGVAR
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.gvar(val[2]))
- }
- | kALIAS tGVAR tBACK_REF
- {
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.back_ref(val[2]))
- }
- | kALIAS tGVAR tNTH_REF
- {
- diagnostic :error, :nth_ref_alias, nil, val[2]
- }
- | kUNDEF undef_list
- {
- result = @builder.undef_method(val[0], val[1])
- }
- | stmt kIF_MOD expr_value
- {
- result = @builder.condition_mod(val[0], nil,
- val[1], val[2])
- }
- | stmt kUNLESS_MOD expr_value
- {
- result = @builder.condition_mod(nil, val[0],
- val[1], val[2])
- }
- | stmt kWHILE_MOD expr_value
- {
- result = @builder.loop_mod(:while, val[0], val[1], val[2])
- }
- | stmt kUNTIL_MOD expr_value
- {
- result = @builder.loop_mod(:until, val[0], val[1], val[2])
- }
- | stmt kRESCUE_MOD stmt
- {
- rescue_body = @builder.rescue_body(val[1],
- nil, nil, nil,
- nil, val[2])
-
- result = @builder.begin_body(val[0], [ rescue_body ])
- }
- | klEND tLCURLY compstmt tRCURLY
- {
- result = @builder.postexe(val[0], val[1], val[2], val[3])
- }
- | command_asgn
- | mlhs tEQL command_call
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN command_call
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | backref tOP_ASGN command_call
- {
- @builder.op_assign(val[0], val[1], val[2])
- }
- | lhs tEQL mrhs
- {
- result = @builder.assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
- }
- | mlhs tEQL mrhs_arg
- {
- result = @builder.multi_assign(val[0], val[1], val[2])
- }
- | expr
-
- command_asgn: lhs tEQL command_call
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL command_asgn
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
-
- expr: command_call
- | expr kAND expr
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | expr kOR expr
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kNOT opt_nl expr
- {
- result = @builder.not_op(val[0], nil, val[2], nil)
- }
- | tBANG command_call
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | arg
-
- expr_value: expr
-
- command_call: command
- | block_command
-
- block_command: block_call
- | block_call dot_or_colon operation2 command_args
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
-
- cmd_brace_block: tLBRACE_ARG
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- fcall: operation
-
- command: fcall command_args =tLOWEST
- {
- result = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
- }
- | fcall command_args cmd_brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
-
- begin_t, args, body, end_t = val[2]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tDOT operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | primary_value tDOT operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | primary_value tCOLON2 operation2 command_args =tLOWEST
- {
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
- }
- | primary_value tCOLON2 operation2 command_args cmd_brace_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | kSUPER command_args
- {
- result = @builder.keyword_cmd(:super, val[0],
- nil, val[1], nil)
- }
- | kYIELD command_args
- {
- result = @builder.keyword_cmd(:yield, val[0],
- nil, val[1], nil)
- }
- | kRETURN call_args
- {
- result = @builder.keyword_cmd(:return, val[0],
- nil, val[1], nil)
- }
- | kBREAK call_args
- {
- result = @builder.keyword_cmd(:break, val[0],
- nil, val[1], nil)
- }
- | kNEXT call_args
- {
- result = @builder.keyword_cmd(:next, val[0],
- nil, val[1], nil)
- }
-
- mlhs: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_inner: mlhs_basic
- {
- result = @builder.multi_lhs(nil, val[0], nil)
- }
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- mlhs_basic: mlhs_head
- | mlhs_head mlhs_item
- {
- result = val[0].
- push(val[1])
- }
- | mlhs_head tSTAR mlhs_node
- {
- result = val[0].
- push(@builder.splat(val[1], val[2]))
- }
- | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1], val[2])).
- concat(val[4])
- }
- | mlhs_head tSTAR
- {
- result = val[0].
- push(@builder.splat(val[1]))
- }
- | mlhs_head tSTAR tCOMMA mlhs_post
- {
- result = val[0].
- push(@builder.splat(val[1])).
- concat(val[3])
- }
- | tSTAR mlhs_node
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | tSTAR mlhs_node tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.splat(val[0]) ]
- }
- | tSTAR tCOMMA mlhs_post
- {
- result = [ @builder.splat(val[0]),
- *val[2] ]
- }
-
- mlhs_item: mlhs_node
- | tLPAREN mlhs_inner rparen
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
-
- mlhs_head: mlhs_item tCOMMA
- {
- result = [ val[0] ]
- }
- | mlhs_head mlhs_item tCOMMA
- {
- result = val[0] << val[1]
- }
-
- mlhs_post: mlhs_item
- {
- result = [ val[0] ]
- }
- | mlhs_post tCOMMA mlhs_item
- {
- result = val[0] << val[2]
- }
-
- mlhs_node: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- lhs: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
- }
- | primary_value tDOT tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tIDENTIFIER
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tDOT tCONSTANT
- {
- result = @builder.attr_asgn(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
- }
- | backref
- {
- result = @builder.assignable(val[0])
- }
-
- cname: tIDENTIFIER
- {
- diagnostic :error, :module_name_const, nil, val[0]
- }
- | tCONSTANT
-
- cpath: tCOLON3 cname
- {
- result = @builder.const_global(val[0], val[1])
- }
- | cname
- {
- result = @builder.const(val[0])
- }
- | primary_value tCOLON2 cname
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
-
- fname: tIDENTIFIER | tCONSTANT | tFID
- | op
- | reswords
-
- fsym: fname
- {
- result = @builder.symbol(val[0])
- }
- | symbol
-
- fitem: fsym
- | dsym
-
- undef_list: fitem
- {
- result = [ val[0] ]
- }
- | undef_list tCOMMA
- {
- @lexer.state = :expr_fname
- }
- fitem
- {
- result = val[0] << val[3]
- }
-
- op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
- | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
- | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
- | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
- | tUPLUS | tUMINUS | tAREF | tASET | tDSTAR | tBACK_REF2
-
- reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
- | kALIAS | kAND | kBEGIN | kBREAK | kCASE
- | kCLASS | kDEF | kDEFINED | kDO | kELSE
- | kELSIF | kEND | kENSURE | kFALSE | kFOR
- | kIN | kMODULE | kNEXT | kNIL | kNOT
- | kOR | kREDO | kRESCUE | kRETRY | kRETURN
- | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
- | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
- | kUNTIL
-
- arg: lhs tEQL arg
- {
- result = @builder.assign(val[0], val[1], val[2])
- }
- | lhs tEQL arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.assign(val[0], val[1], rescue_)
- }
- | var_lhs tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | var_lhs tOP_ASGN arg kRESCUE_MOD arg
- {
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.op_assign(val[0], val[1], rescue_)
- }
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
- }
- | primary_value tDOT tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tDOT tCONSTANT tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
- {
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
- }
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
- {
- const = @builder.const_op_assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- result = @builder.op_assign(const, val[3], val[4])
- }
- | tCOLON3 tCONSTANT tOP_ASGN arg
- {
- const = @builder.const_op_assignable(
- @builder.const_global(val[0], val[1]))
- result = @builder.op_assign(const, val[2], val[3])
- }
- | backref tOP_ASGN arg
- {
- result = @builder.op_assign(val[0], val[1], val[2])
- }
- | arg tDOT2 arg
- {
- result = @builder.range_inclusive(val[0], val[1], val[2])
- }
- | arg tDOT3 arg
- {
- result = @builder.range_exclusive(val[0], val[1], val[2])
- }
- | arg tPLUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMINUS arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tSTAR2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tDIVIDE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPERCENT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tPOW arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tUMINUS_NUM simple_numeric tPOW arg
- {
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- val[1], val[2], val[3]))
- }
- | tUPLUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | tUMINUS arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tPIPE arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCARET arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tAMPER2 arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tCMP arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tGEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tLEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tEQQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tNEQ arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tMATCH arg
- {
- result = @builder.match_op(val[0], val[1], val[2])
- }
- | arg tNMATCH arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | tBANG arg
- {
- result = @builder.not_op(val[0], nil, val[1], nil)
- }
- | tTILDE arg
- {
- result = @builder.unary_op(val[0], val[1])
- }
- | arg tLSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tRSHFT arg
- {
- result = @builder.binary_op(val[0], val[1], val[2])
- }
- | arg tANDOP arg
- {
- result = @builder.logical_op(:and, val[0], val[1], val[2])
- }
- | arg tOROP arg
- {
- result = @builder.logical_op(:or, val[0], val[1], val[2])
- }
- | kDEFINED opt_nl arg
- {
- result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
- }
-
- # Note: MRI eventually came to rely on disambiguation based on
- # the lexer state, but it is too contrived with the Ragel lexer,
- # so we kept this approach. See ruby/ruby@b0c03f63e5 for
- # the initial commit, and ruby/ruby@23352f62a for MRI revert,
- # which we decided not to track.
- | arg tEH
- {
- @lexer.push_cond
- @lexer.cond.push(true)
- }
- arg opt_nl tCOLON
- {
- @lexer.pop_cond
- }
- arg
- {
- result = @builder.ternary(val[0], val[1],
- val[3], val[5], val[7])
- }
- | primary
-
- arg_value: arg
-
- aref_args: none
- | args trailer
- | args tCOMMA assocs trailer
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs trailer
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- paren_args: tLPAREN2 opt_call_args rparen
- {
- result = val
- }
-
- opt_paren_args: # nothing
- {
- result = [ nil, [], nil ]
- }
- | paren_args
-
- opt_call_args: # nothing
- {
- result = []
- }
- | call_args
- | args tCOMMA
- | args tCOMMA assocs tCOMMA
- {
- result = val[0] << @builder.associate(nil, val[2], nil)
- }
- | assocs tCOMMA
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- }
-
- call_args: command
- {
- result = [ val[0] ]
- }
- | args opt_block_arg
- {
- result = val[0].concat(val[1])
- }
- | assocs opt_block_arg
- {
- result = [ @builder.associate(nil, val[0], nil) ]
- result.concat(val[1])
- }
- | args tCOMMA assocs opt_block_arg
- {
- assocs = @builder.associate(nil, val[2], nil)
- result = val[0] << assocs
- result.concat(val[3])
- }
- | block_arg
- {
- result = [ val[0] ]
- }
-
- command_args: {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.push(true)
- }
- call_args
- {
- @lexer.cmdarg = val[0]
-
- result = val[1]
- }
-
- block_arg: tAMPER arg_value
- {
- result = @builder.block_pass(val[0], val[1])
- }
-
- opt_block_arg: tCOMMA block_arg
- {
- result = [ val[1] ]
- }
- | # nothing
- {
- result = []
- }
-
- args: arg_value
- {
- result = [ val[0] ]
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
- | args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
-
- mrhs_arg: mrhs
- {
- result = @builder.array(nil, val[0], nil)
- }
- | arg_value
-
- mrhs: args tCOMMA arg_value
- {
- result = val[0] << val[2]
- }
- | args tCOMMA tSTAR arg_value
- {
- result = val[0] << @builder.splat(val[2], val[3])
- }
- | tSTAR arg_value
- {
- result = [ @builder.splat(val[0], val[1]) ]
- }
-
- primary: literal
- | strings
- | xstring
- | regexp
- | words
- | qwords
- | symbols
- | qsymbols
- | var_ref
- | backref
- | tFID
- {
- result = @builder.call_method(nil, nil, val[0])
- }
- | kBEGIN
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- bodystmt kEND
- {
- @lexer.cmdarg = val[1]
-
- result = @builder.begin_keyword(val[0], val[2], val[3])
- }
- | tLPAREN_ARG
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- expr
- {
- @lexer.state = :expr_endarg
- }
- opt_nl tRPAREN
- {
- @lexer.cmdarg = val[1]
-
- result = @builder.begin(val[0], val[2], val[5])
- }
- | tLPAREN_ARG
- {
- @lexer.state = :expr_endarg
- }
- opt_nl tRPAREN
- {
- result = @builder.begin(val[0], nil, val[3])
- }
- | tLPAREN compstmt tRPAREN
- {
- result = @builder.begin(val[0], val[1], val[2])
- }
- | primary_value tCOLON2 tCONSTANT
- {
- result = @builder.const_fetch(val[0], val[1], val[2])
- }
- | tCOLON3 tCONSTANT
- {
- result = @builder.const_global(val[0], val[1])
- }
- | tLBRACK aref_args tRBRACK
- {
- result = @builder.array(val[0], val[1], val[2])
- }
- | tLBRACE assoc_list tRCURLY
- {
- result = @builder.associate(val[0], val[1], val[2])
- }
- | kRETURN
- {
- result = @builder.keyword_cmd(:return, val[0])
- }
- | kYIELD tLPAREN2 call_args rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
- }
- | kYIELD tLPAREN2 rparen
- {
- result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
- }
- | kYIELD
- {
- result = @builder.keyword_cmd(:yield, val[0])
- }
- | kDEFINED opt_nl tLPAREN2 expr rparen
- {
- result = @builder.keyword_cmd(:defined?, val[0],
- val[2], [ val[3] ], val[4])
- }
- | kNOT tLPAREN2 expr rparen
- {
- result = @builder.not_op(val[0], val[1], val[2], val[3])
- }
- | kNOT tLPAREN2 rparen
- {
- result = @builder.not_op(val[0], val[1], nil, val[2])
- }
- | fcall brace_block
- {
- method_call = @builder.call_method(nil, nil, val[0])
-
- begin_t, args, body, end_t = val[1]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | method_call
- | method_call brace_block
- {
- begin_t, args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, args, body, end_t)
- }
- | tLAMBDA lambda
- {
- lambda_call = @builder.call_lambda(val[0])
-
- args, (begin_t, body, end_t) = val[1]
- result = @builder.block(lambda_call,
- begin_t, args, body, end_t)
- }
- | kIF expr_value then compstmt if_tail kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, val[5])
- }
- | kUNLESS expr_value then compstmt opt_else kEND
- {
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- else_, else_t,
- val[3], val[5])
- }
- | kWHILE
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:while, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kUNTIL
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.loop(:until, val[0], val[2], val[3],
- val[5], val[6])
- }
- | kCASE expr_value opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[3]
-
- result = @builder.case(val[0], val[1],
- when_bodies, else_t, else_body,
- val[4])
- }
- | kCASE opt_terms case_body kEND
- {
- *when_bodies, (else_t, else_body) = *val[2]
-
- result = @builder.case(val[0], nil,
- when_bodies, else_t, else_body,
- val[3])
- }
- | kFOR for_var kIN
- {
- @lexer.cond.push(true)
- }
- expr_value do
- {
- @lexer.cond.pop
- }
- compstmt kEND
- {
- result = @builder.for(val[0], val[1],
- val[2], val[4],
- val[5], val[7], val[8])
- }
- | kCLASS cpath superclass
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :class_in_def, nil, val[0]
- end
-
- lt_t, superclass = val[2]
- result = @builder.def_class(val[0], val[1],
- lt_t, superclass,
- val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kCLASS tLSHFT expr term
- {
- result = @def_level
- @def_level = 0
-
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- result = @builder.def_sclass(val[0], val[1], val[2],
- val[5], val[6])
-
- @lexer.pop_cmdarg
- @static_env.unextend
-
- @def_level = val[4]
- }
- | kMODULE cpath
- {
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- bodystmt kEND
- {
- if in_def?
- diagnostic :error, :module_in_def, nil, val[0]
- end
-
- result = @builder.def_module(val[0], val[1],
- val[3], val[4])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- }
- | kDEF fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_method(val[0], val[1],
- val[3], val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kDEF singleton dot_or_colon
- {
- @lexer.state = :expr_fname
- }
- fname
- {
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
- }
- f_arglist bodystmt kEND
- {
- result = @builder.def_singleton(val[0], val[1], val[2],
- val[4], val[6], val[7], val[8])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
- }
- | kBREAK
- {
- result = @builder.keyword_cmd(:break, val[0])
- }
- | kNEXT
- {
- result = @builder.keyword_cmd(:next, val[0])
- }
- | kREDO
- {
- result = @builder.keyword_cmd(:redo, val[0])
- }
- | kRETRY
- {
- result = @builder.keyword_cmd(:retry, val[0])
- }
-
- primary_value: primary
-
- then: term
- | kTHEN
- | term kTHEN
- {
- result = val[1]
- }
-
- do: term
- | kDO_COND
-
- if_tail: opt_else
- | kELSIF expr_value then compstmt if_tail
- {
- else_t, else_ = val[4]
- result = [ val[0],
- @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, nil),
- ]
- }
-
- opt_else: none
- | kELSE compstmt
- {
- result = val
- }
-
- for_var: lhs
- | mlhs
-
- f_marg: f_norm_arg
- {
- result = @builder.arg(val[0])
- }
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_marg_list: f_marg
- {
- result = [ val[0] ]
- }
- | f_marg_list tCOMMA f_marg
- {
- result = val[0] << val[2]
- }
-
- f_margs: f_marg_list
- | f_marg_list tCOMMA tSTAR f_norm_arg
- {
- result = val[0].
- push(@builder.restarg(val[2], val[3]))
- }
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
- {
- result = val[0].
- push(@builder.restarg(val[2], val[3])).
- concat(val[5])
- }
- | f_marg_list tCOMMA tSTAR
- {
- result = val[0].
- push(@builder.restarg(val[2]))
- }
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
- {
- result = val[0].
- push(@builder.restarg(val[2])).
- concat(val[4])
- }
- | tSTAR f_norm_arg
- {
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | tSTAR f_norm_arg tCOMMA f_marg_list
- {
- result = [ @builder.restarg(val[0], val[1]),
- *val[3] ]
- }
- | tSTAR
- {
- result = [ @builder.restarg(val[0]) ]
- }
- | tSTAR tCOMMA f_marg_list
- {
- result = [ @builder.restarg(val[0]),
- *val[2] ]
- }
-
- block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[2]).concat(val[3])
- }
- | f_block_kwarg opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
-
-opt_block_args_tail:
- tCOMMA block_args_tail
- {
- result = val[1]
- }
- | # nothing
- {
- result = []
- }
-
- block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_block_optarg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_block_args_tail
- {
- result = val[0].concat(val[1])
- }
- | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_block_optarg opt_block_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_block_optarg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_block_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | block_args_tail
-
- opt_block_param: # nothing
- {
- result = @builder.args(nil, [], nil)
- }
- | block_param_def
- {
- @lexer.state = :expr_value
- }
-
- block_param_def: tPIPE opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1], val[2])
- }
- | tOROP
- {
- result = @builder.args(val[0], [], val[0])
- }
- | tPIPE block_param opt_bv_decl tPIPE
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
-
- opt_bv_decl: opt_nl
- {
- result = []
- }
- | opt_nl tSEMI bv_decls opt_nl
- {
- result = val[2]
- }
-
- bv_decls: bvar
- {
- result = [ val[0] ]
- }
- | bv_decls tCOMMA bvar
- {
- result = val[0] << val[2]
- }
-
- bvar: tIDENTIFIER
- {
- result = @builder.shadowarg(val[0])
- }
- | f_bad_arg
-
- lambda: {
- @static_env.extend_dynamic
- }
- f_larglist
- {
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
- }
- lambda_body
- {
- @lexer.cmdarg = val[2]
- @lexer.cmdarg.lexpop
-
- result = [ val[1], val[3] ]
-
- @static_env.unextend
- }
-
- f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
- {
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
- }
- | f_args
- {
- result = @builder.args(nil, val[0], nil)
- }
-
- lambda_body: tLAMBEG compstmt tRCURLY
- {
- result = [ val[0], val[1], val[2] ]
- }
- | kDO_LAMBDA compstmt kEND
- {
- result = [ val[0], val[1], val[2] ]
- }
-
- do_block: kDO_BLOCK
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- block_call: command do_block
- {
- begin_t, block_args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, block_args, body, end_t)
- }
- | block_call dot_or_colon operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | block_call dot_or_colon operation2 opt_paren_args brace_block
- {
- lparen_t, args, rparen_t = val[3]
- method_call = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
- | block_call dot_or_colon operation2 command_args do_block
- {
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
- }
-
- method_call: fcall paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
- }
- | primary_value tDOT operation2 opt_paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation2 paren_args
- {
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 operation3
- {
- result = @builder.call_method(val[0], val[1], val[2])
- }
- | primary_value tDOT paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | primary_value tCOLON2 paren_args
- {
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
- }
- | kSUPER paren_args
- {
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
- }
- | kSUPER
- {
- result = @builder.keyword_cmd(:zsuper, val[0])
- }
- | primary_value tLBRACK2 opt_call_args rbracket
- {
- result = @builder.index(val[0], val[1], val[2], val[3])
- }
-
- brace_block: tLCURLY
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt tRCURLY
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
- | kDO
- {
- @static_env.extend_dynamic
- }
- opt_block_param compstmt kEND
- {
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
- }
-
- case_body: kWHEN args then compstmt cases
- {
- result = [ @builder.when(val[0], val[1], val[2], val[3]),
- *val[4] ]
- }
-
- cases: opt_else
- {
- result = [ val[0] ]
- }
- | case_body
-
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
- {
- assoc_t, exc_var = val[2]
-
- if val[1]
- exc_list = @builder.array(nil, val[1], nil)
- end
-
- result = [ @builder.rescue_body(val[0],
- exc_list, assoc_t, exc_var,
- val[3], val[4]),
- *val[5] ]
- }
- |
- {
- result = []
- }
-
- exc_list: arg_value
- {
- result = [ val[0] ]
- }
- | mrhs
- | none
-
- exc_var: tASSOC lhs
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- opt_ensure: kENSURE compstmt
- {
- result = [ val[0], val[1] ]
- }
- | none
-
- literal: numeric
- | symbol
- | dsym
-
- strings: string
- {
- result = @builder.string_compose(nil, val[0], nil)
- }
-
- string: string1
- {
- result = [ val[0] ]
- }
- | string string1
- {
- result = val[0] << val[1]
- }
-
- string1: tSTRING_BEG string_contents tSTRING_END
- {
- result = @builder.string_compose(val[0], val[1], val[2])
- }
- | tSTRING
- {
- result = @builder.string(val[0])
- }
- | tCHARACTER
- {
- result = @builder.character(val[0])
- }
-
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
- {
- result = @builder.xstring_compose(val[0], val[1], val[2])
- }
-
- regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
- {
- opts = @builder.regexp_options(val[3])
- result = @builder.regexp_compose(val[0], val[1], val[2], opts)
- }
-
- words: tWORDS_BEG word_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- word_list: # nothing
- {
- result = []
- }
- | word_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- word: string_content
- {
- result = [ val[0] ]
- }
- | word string_content
- {
- result = val[0] << val[1]
- }
-
- symbols: tSYMBOLS_BEG symbol_list tSTRING_END
- {
- result = @builder.symbols_compose(val[0], val[1], val[2])
- }
-
- symbol_list: # nothing
- {
- result = []
- }
- | symbol_list word tSPACE
- {
- result = val[0] << @builder.word(val[1])
- }
-
- qwords: tQWORDS_BEG qword_list tSTRING_END
- {
- result = @builder.words_compose(val[0], val[1], val[2])
- }
-
- qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END
- {
- result = @builder.symbols_compose(val[0], val[1], val[2])
- }
-
- qword_list: # nothing
- {
- result = []
- }
- | qword_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.string_internal(val[1])
- }
-
- qsym_list: # nothing
- {
- result = []
- }
- | qsym_list tSTRING_CONTENT tSPACE
- {
- result = val[0] << @builder.symbol_internal(val[1])
- }
-
- string_contents: # nothing
- {
- result = []
- }
- | string_contents string_content
- {
- result = val[0] << val[1]
- }
-
-xstring_contents: # nothing
- {
- result = []
- }
- | xstring_contents string_content
- {
- result = val[0] << val[1]
- }
-
-regexp_contents: # nothing
- {
- result = []
- }
- | regexp_contents string_content
- {
- result = val[0] << val[1]
- }
-
- string_content: tSTRING_CONTENT
- {
- result = @builder.string_internal(val[0])
- }
- | tSTRING_DVAR string_dvar
- {
- result = val[1]
- }
- | tSTRING_DBEG
- {
- @lexer.cond.push(false)
- @lexer.cmdarg.push(false)
- }
- compstmt tSTRING_DEND
- {
- @lexer.cond.lexpop
- @lexer.cmdarg.lexpop
-
- result = @builder.begin(val[0], val[2], val[3])
- }
-
- string_dvar: tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
- | backref
-
-
- symbol: tSYMBOL
- {
- result = @builder.symbol(val[0])
- }
-
- dsym: tSYMBEG xstring_contents tSTRING_END
- {
- result = @builder.symbol_compose(val[0], val[1], val[2])
- }
-
- numeric: simple_numeric
- {
- result = val[0]
- }
- | tUMINUS_NUM simple_numeric =tLOWEST
- {
- result = @builder.negate(val[0], val[1])
- }
-
- simple_numeric: tINTEGER
- {
- result = @builder.integer(val[0])
- }
- | tFLOAT
- {
- result = @builder.float(val[0])
- }
- | tRATIONAL
- {
- result = @builder.rational(val[0])
- }
- | tIMAGINARY
- {
- result = @builder.complex(val[0])
- }
-
- user_variable: tIDENTIFIER
- {
- result = @builder.ident(val[0])
- }
- | tIVAR
- {
- result = @builder.ivar(val[0])
- }
- | tGVAR
- {
- result = @builder.gvar(val[0])
- }
- | tCONSTANT
- {
- result = @builder.const(val[0])
- }
- | tCVAR
- {
- result = @builder.cvar(val[0])
- }
-
-keyword_variable: kNIL
- {
- result = @builder.nil(val[0])
- }
- | kSELF
- {
- result = @builder.self(val[0])
- }
- | kTRUE
- {
- result = @builder.true(val[0])
- }
- | kFALSE
- {
- result = @builder.false(val[0])
- }
- | k__FILE__
- {
- result = @builder.__FILE__(val[0])
- }
- | k__LINE__
- {
- result = @builder.__LINE__(val[0])
- }
- | k__ENCODING__
- {
- result = @builder.__ENCODING__(val[0])
- }
-
- var_ref: user_variable
- {
- result = @builder.accessible(val[0])
- }
- | keyword_variable
- {
- result = @builder.accessible(val[0])
- }
-
- var_lhs: user_variable
- {
- result = @builder.assignable(val[0])
- }
- | keyword_variable
- {
- result = @builder.assignable(val[0])
- }
-
- backref: tNTH_REF
- {
- result = @builder.nth_ref(val[0])
- }
- | tBACK_REF
- {
- result = @builder.back_ref(val[0])
- }
-
- superclass: term
- {
- result = nil
- }
- | tLT
- {
- @lexer.state = :expr_value
- }
- expr_value term
- {
- result = [ val[0], val[2] ]
- }
- | error term
- {
- yyerrok
- result = nil
- }
-
- f_arglist: tLPAREN2 f_args rparen
- {
- result = @builder.args(val[0], val[1], val[2])
-
- @lexer.state = :expr_value
- }
- | {
- result = @lexer.in_kwarg
- @lexer.in_kwarg = true
- }
- f_args term
- {
- @lexer.in_kwarg = val[0]
- result = @builder.args(nil, val[1], nil)
- }
-
- args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[2]).concat(val[3])
- }
- | f_kwarg opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_kwrest opt_f_block_arg
- {
- result = val[0].concat(val[1])
- }
- | f_block_arg
- {
- result = [ val[0] ]
- }
-
- opt_args_tail: tCOMMA args_tail
- {
- result = val[1]
- }
- | # nothing
- {
- result = []
- }
-
- f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
- }
- | f_arg tCOMMA f_optarg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_arg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
- }
- | f_optarg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_optarg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | f_rest_arg opt_args_tail
- {
- result = val[0].
- concat(val[1])
- }
- | f_rest_arg tCOMMA f_arg opt_args_tail
- {
- result = val[0].
- concat(val[2]).
- concat(val[3])
- }
- | args_tail
- {
- result = val[0]
- }
- | # nothing
- {
- result = []
- }
-
- f_bad_arg: tCONSTANT
- {
- diagnostic :error, :argument_const, nil, val[0]
- }
- | tIVAR
- {
- diagnostic :error, :argument_ivar, nil, val[0]
- }
- | tGVAR
- {
- diagnostic :error, :argument_gvar, nil, val[0]
- }
- | tCVAR
- {
- diagnostic :error, :argument_cvar, nil, val[0]
- }
-
- f_norm_arg: f_bad_arg
- | tIDENTIFIER
- {
- @static_env.declare val[0][0]
-
- result = val[0]
- }
-
- f_arg_asgn: f_norm_arg
- {
- result = val[0]
- }
-
- f_arg_item: f_arg_asgn
- {
- result = @builder.arg(val[0])
- }
- | tLPAREN f_margs rparen
- {
- result = @builder.multi_lhs(val[0], val[1], val[2])
- }
-
- f_arg: f_arg_item
- {
- result = [ val[0] ]
- }
- | f_arg tCOMMA f_arg_item
- {
- result = val[0] << val[2]
- }
-
- f_label: tLABEL
- {
- check_kwarg_name(val[0])
-
- @static_env.declare val[0][0]
-
- result = val[0]
- }
-
- f_kw: f_label arg_value
- {
- result = @builder.kwoptarg(val[0], val[1])
- }
- | f_label
- {
- result = @builder.kwarg(val[0])
- }
-
- f_block_kw: f_label primary_value
- {
- result = @builder.kwoptarg(val[0], val[1])
- }
- | f_label
- {
- result = @builder.kwarg(val[0])
- }
-
- f_block_kwarg: f_block_kw
- {
- result = [ val[0] ]
- }
- | f_block_kwarg tCOMMA f_block_kw
- {
- result = val[0] << val[2]
- }
-
- f_kwarg: f_kw
- {
- result = [ val[0] ]
- }
- | f_kwarg tCOMMA f_kw
- {
- result = val[0] << val[2]
- }
-
- kwrest_mark: tPOW | tDSTAR
-
- f_kwrest: kwrest_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.kwrestarg(val[0], val[1]) ]
- }
- | kwrest_mark
- {
- result = [ @builder.kwrestarg(val[0]) ]
- }
-
- f_opt: f_arg_asgn tEQL arg_value
- {
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_opt: f_arg_asgn tEQL primary_value
- {
- result = @builder.optarg(val[0], val[1], val[2])
- }
-
- f_block_optarg: f_block_opt
- {
- result = [ val[0] ]
- }
- | f_block_optarg tCOMMA f_block_opt
- {
- result = val[0] << val[2]
- }
-
- f_optarg: f_opt
- {
- result = [ val[0] ]
- }
- | f_optarg tCOMMA f_opt
- {
- result = val[0] << val[2]
- }
-
- restarg_mark: tSTAR2 | tSTAR
-
- f_rest_arg: restarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
- }
- | restarg_mark
- {
- result = [ @builder.restarg(val[0]) ]
- }
-
- blkarg_mark: tAMPER2 | tAMPER
-
- f_block_arg: blkarg_mark tIDENTIFIER
- {
- @static_env.declare val[1][0]
-
- result = @builder.blockarg(val[0], val[1])
- }
-
- opt_f_block_arg: tCOMMA f_block_arg
- {
- result = [ val[1] ]
- }
- |
- {
- result = []
- }
-
- singleton: var_ref
- | tLPAREN2 expr rparen
- {
- result = val[1]
- }
-
- assoc_list: # nothing
- {
- result = []
- }
- | assocs trailer
-
- assocs: assoc
- {
- result = [ val[0] ]
- }
- | assocs tCOMMA assoc
- {
- result = val[0] << val[2]
- }
-
- assoc: arg_value tASSOC arg_value
- {
- result = @builder.pair(val[0], val[1], val[2])
- }
- | tLABEL arg_value
- {
- result = @builder.pair_keyword(val[0], val[1])
- }
- | tSTRING_BEG string_contents tLABEL_END arg_value
- {
- result = @builder.pair_quoted(val[0], val[1], val[2], val[3])
- }
- | tDSTAR arg_value
- {
- result = @builder.kwsplat(val[0], val[1])
- }
-
- operation: tIDENTIFIER | tCONSTANT | tFID
- operation2: tIDENTIFIER | tCONSTANT | tFID | op
- operation3: tIDENTIFIER | tFID | op
- dot_or_colon: tDOT | tCOLON2
- opt_terms: | terms
- opt_nl: | tNL
- rparen: opt_nl tRPAREN
- {
- result = val[1]
- }
- rbracket: opt_nl tRBRACK
- {
- result = val[1]
- }
- trailer: | tNL | tCOMMA
-
- term: tSEMI
- {
- yyerrok
- }
- | tNL
-
- terms: term
- | terms tSEMI
-
- none: # nothing
- {
- result = nil
- }
-end
-
----- header
-
-require 'parser'
-
-Parser.check_for_encoding_support
-
----- inner
-
- def version
- 22
- end
-
- def default_encoding
- Encoding::UTF_8
- end
diff --git a/test/racc/assets/scan.y b/test/racc/assets/scan.y
deleted file mode 100644
index 709254ed66..0000000000
--- a/test/racc/assets/scan.y
+++ /dev/null
@@ -1,72 +0,0 @@
-class P
-
-rule
-
- a: A
- {
- # comment test
-
- # comment test
-
- # string
- @sstring = 'squote string'
- @dstring = 'dquote string'
-
- # regexp
- @regexp = /some regexp with spaces/
-
- # gvar
- /regexp/ === 'some regexp matches to this string'
- @pre_match = $`
- @matched = $&
- @post_match = $'
- @m = $~
-
- # braces
- @array = []
- [1,2,3].each {|i|
- @array.push i
- }
- 3.times { @array.push 10 }
- }
-
-end
-
----- inner
-
- def parse
- @sstring = @dstring = nil
- @regexp = nil
- @pre_match = @matched = @post_match = @m = nil
-
- @src = [[:A, 'A'], [false, '$']]
- do_parse
-
- assert_equal 'squote string', @sstring
- assert_equal 'dquote string', @dstring
- assert_equal(/some regexp with spaces/, @regexp)
- assert_equal 'some ', @pre_match
- assert_equal 'regexp', @matched
- assert_equal ' matches to this string', @post_match
- assert_instance_of MatchData, @m
- end
-
- def assert_equal(ok, data)
- unless ok == data
- raise "expected <#{ok.inspect}> but is <#{data.inspect}>"
- end
- end
-
- def assert_instance_of(klass, obj)
- unless obj.instance_of?(klass)
- raise "expected #{klass} but is #{obj.class}"
- end
- end
-
- def next_token
- @src.shift
- end
-
----- footer
-
-P.new.parse
diff --git a/test/racc/assets/syntax.y b/test/racc/assets/syntax.y
deleted file mode 100644
index 727f74a29d..0000000000
--- a/test/racc/assets/syntax.y
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# racc syntax checker
-#
-
-class M1::M2::ParserClass < S1::S2::SuperClass
-
- token A
- | B C
-
- convert
- A '5'
- end
-
- prechigh
- left B
- preclow
-
- start target
-
- expect 0
-
-rule
-
- target: A B C
- {
- print 'abc'
- }
- | B C A
- | C B A
- {
- print 'cba'
- }
- | cont
-
- cont : A c2 B c2 C
-
- c2 : C C C C C
-
-end
-
----- inner
-
- junk code !!!!
-
-kjaljlajrlaolanbla /// %%% (*((( token rule
-akiurtlajluealjflaj @@@@ end end end end __END__
- laieu2o879urkq96ga(Q#*&%Q#
- #&lkji END
-
- q395q?/// liutjqlkr7
diff --git a/test/racc/assets/tp_plus.y b/test/racc/assets/tp_plus.y
deleted file mode 100644
index 388ed1302d..0000000000
--- a/test/racc/assets/tp_plus.y
+++ /dev/null
@@ -1,622 +0,0 @@
-# Released under an MIT License (http://www.opensource.org/licenses/MIT)
-# By Jay Strybis (https://github.com/unreal)
-
-class TPPlus::Parser
-token ASSIGN AT_SYM COMMENT JUMP IO_METHOD INPUT OUTPUT
-token NUMREG POSREG VREG SREG TIME_SEGMENT ARG UALM
-token MOVE DOT TO AT TERM OFFSET SKIP GROUP
-token SEMICOLON NEWLINE STRING
-token REAL DIGIT WORD EQUAL
-token EEQUAL NOTEQUAL GTE LTE LT GT BANG
-token PLUS MINUS STAR SLASH DIV AND OR MOD
-token IF ELSE END UNLESS FOR IN WHILE
-token WAIT_FOR WAIT_UNTIL TIMEOUT AFTER
-token FANUC_USE SET_SKIP_CONDITION NAMESPACE
-token CASE WHEN INDIRECT POSITION
-token EVAL TIMER TIMER_METHOD RAISE ABORT
-token POSITION_DATA TRUE_FALSE RUN TP_HEADER PAUSE
-token LPAREN RPAREN COLON COMMA LBRACK RBRACK LBRACE RBRACE
-token LABEL ADDRESS
-token false
-
-prechigh
- right BANG
- left STAR SLASH DIV MOD
- left PLUS MINUS
- left GT GTE LT LTE
- left EEQUAL NOTEQUAL
- left AND
- left OR
- right EQUAL
-preclow
-
-rule
- program
- #: statements { @interpreter.nodes = val[0].flatten }
- : statements { @interpreter.nodes = val[0] }
- |
- ;
-
-
- statements
- : statement terminator {
- result = [val[0]]
- result << val[1] unless val[1].nil?
- }
- | statements statement terminator {
- result = val[0] << val[1]
- result << val[2] unless val[2].nil?
- }
- ;
-
- block
- : NEWLINE statements { result = val[1] }
- ;
-
- optional_newline
- : NEWLINE
- |
- ;
-
- statement
- : comment
- | definition
- | namespace
- #| assignment
- | motion_statement
- #| jump
- #| io_method
- | label_definition
- | address
- | conditional
- | inline_conditional
- | forloop
- | while_loop
- #| program_call
- | use_statement
- | set_skip_statement
- | wait_statement
- | case_statement
- | fanuc_eval
- | timer_method
- | position_data
- | raise
- | tp_header_definition
- | empty_stmt
- | PAUSE { result = PauseNode.new }
- | ABORT { result = AbortNode.new }
- ;
-
- empty_stmt
- : NEWLINE { result = EmptyStmtNode.new() }
- ;
-
- tp_header_definition
- : TP_HEADER EQUAL tp_header_value { result = HeaderNode.new(val[0],val[2]) }
- ;
-
- tp_header_value
- : STRING
- | TRUE_FALSE
- ;
-
- raise
- : RAISE var_or_indirect { result = RaiseNode.new(val[1]) }
- ;
-
- timer_method
- : TIMER_METHOD var_or_indirect { result = TimerMethodNode.new(val[0],val[1]) }
- ;
-
- fanuc_eval
- : EVAL STRING { result = EvalNode.new(val[1]) }
- ;
-
- wait_statement
- : WAIT_FOR LPAREN indirectable COMMA STRING RPAREN
- { result = WaitForNode.new(val[2], val[4]) }
- | WAIT_UNTIL LPAREN expression RPAREN
- { result = WaitUntilNode.new(val[2], nil) }
- | WAIT_UNTIL LPAREN expression RPAREN DOT wait_modifier
- { result = WaitUntilNode.new(val[2],val[5]) }
- | WAIT_UNTIL LPAREN expression RPAREN DOT wait_modifier DOT wait_modifier
- { result = WaitUntilNode.new(val[2],val[5].merge(val[7])) }
- ;
-
- wait_modifier
- : timeout_modifier
- | after_modifier
- ;
-
- timeout_modifier
- : swallow_newlines TIMEOUT LPAREN label RPAREN
- { result = { label: val[3] } }
- ;
-
- after_modifier
- : swallow_newlines AFTER LPAREN indirectable COMMA STRING RPAREN
- { result = { timeout: [val[3],val[5]] } }
- ;
-
- label
- : LABEL { result = val[0] }
- ;
-
- use_statement
- : FANUC_USE indirectable { result = UseNode.new(val[0],val[1]) }
- ;
-
- # set_skip_condition x
- set_skip_statement
- : SET_SKIP_CONDITION expression { result = SetSkipNode.new(val[1]) }
- ;
-
- program_call
- : WORD LPAREN args RPAREN { result = CallNode.new(val[0],val[2]) }
- | RUN WORD LPAREN args RPAREN { result = CallNode.new(val[1],val[3],async: true) }
- ;
-
- args
- : arg { result = [val[0]] }
- | args COMMA arg { result = val[0] << val[2] }
- | { result = [] }
- ;
-
- arg
- : number
- | var
- | string
- | address
- ;
-
- string
- : STRING { result = StringNode.new(val[0]) }
- ;
-
- io_method
- : IO_METHOD var_or_indirect { result = IOMethodNode.new(val[0],val[1]) }
- | IO_METHOD LPAREN var_or_indirect RPAREN
- { result = IOMethodNode.new(val[0],val[2]) }
- | IO_METHOD LPAREN var_or_indirect COMMA number COMMA STRING RPAREN
- { result = IOMethodNode.new(val[0],val[2],{ pulse_time: val[4], pulse_units: val[6] }) }
- ;
-
- var_or_indirect
- : var
- | indirect_thing
- ;
-
-
- jump
- : JUMP label { result = JumpNode.new(val[1]) }
- ;
-
- conditional
- : IF expression block else_block END
- { result = ConditionalNode.new("if",val[1],val[2],val[3]) }
- | UNLESS expression block else_block END
- { result = ConditionalNode.new("unless",val[1],val[2],val[3]) }
- ;
-
- forloop
- : FOR var IN LPAREN minmax_val TO minmax_val RPAREN block END
- { result = ForNode.new(val[1],val[4],val[6],val[8]) }
- ;
-
- while_loop
- : WHILE expression block END { result = WhileNode.new(val[1],val[2]) }
- ;
-
- minmax_val
- : integer
- | var
- ;
-
- namespace
- : NAMESPACE WORD block END { result = NamespaceNode.new(val[1],val[2]) }
- ;
-
- case_statement
- : CASE var swallow_newlines
- case_conditions
- case_else
- END { result = CaseNode.new(val[1],val[3],val[4]) }
- ;
-
- case_conditions
- : case_condition { result = val }
- | case_conditions case_condition
- { result = val[0] << val[1] << val[2] }
- ;
-
- case_condition
- : WHEN case_allowed_condition swallow_newlines case_allowed_statement
- terminator { result = CaseConditionNode.new(val[1],val[3]) }
- ;
-
- case_allowed_condition
- : number
- | var
- ;
-
- case_else
- : ELSE swallow_newlines case_allowed_statement terminator
- { result = CaseConditionNode.new(nil,val[2]) }
- |
- ;
-
- case_allowed_statement
- : program_call
- | jump
- ;
-
- inline_conditional
- : inlineable
- | inlineable IF expression { result = InlineConditionalNode.new(val[1], val[2], val[0]) }
- | inlineable UNLESS expression { result = InlineConditionalNode.new(val[1], val[2], val[0]) }
- ;
-
- inlineable
- : jump
- | assignment
- | io_method
- | program_call
- ;
-
- else_block
- : ELSE block { result = val[1] }
- | { result = [] }
- ;
-
- motion_statement
- : MOVE DOT swallow_newlines TO LPAREN var RPAREN motion_modifiers
- { result = MotionNode.new(val[0],val[5],val[7]) }
- ;
-
- motion_modifiers
- : motion_modifier { result = val }
- | motion_modifiers motion_modifier
- { result = val[0] << val[1] }
- ;
-
- motion_modifier
- : DOT swallow_newlines AT LPAREN speed RPAREN
- { result = SpeedNode.new(val[4]) }
- | DOT swallow_newlines TERM LPAREN valid_terminations RPAREN
- { result = TerminationNode.new(val[4]) }
- | DOT swallow_newlines OFFSET LPAREN var RPAREN
- { result = OffsetNode.new(val[2],val[4]) }
- | DOT swallow_newlines TIME_SEGMENT LPAREN time COMMA time_seg_actions RPAREN
- { result = TimeNode.new(val[2],val[4],val[6]) }
- | DOT swallow_newlines SKIP LPAREN label optional_lpos_arg RPAREN
- { result = SkipNode.new(val[4],val[5]) }
- ;
-
- valid_terminations
- : integer
- | var
- | MINUS DIGIT {
- raise Racc::ParseError, sprintf("\ninvalid termination type: (%s)", val[1]) if val[1] != 1
-
- result = DigitNode.new(val[1].to_i * -1)
- }
- ;
-
- optional_lpos_arg
- : COMMA var { result = val[1] }
- |
- ;
-
- indirectable
- : number
- | var
- ;
-
- time_seg_actions
- : program_call
- | io_method
- ;
-
- time
- : var
- | number
- ;
-
- speed
- : indirectable COMMA STRING { result = { speed: val[0], units: val[2] } }
- | STRING { result = { speed: val[0], units: nil } }
- ;
-
- label_definition
- : label { result = LabelDefinitionNode.new(val[0]) }#@interpreter.add_label(val[1]) }
- ;
-
- definition
- : WORD ASSIGN definable { result = DefinitionNode.new(val[0],val[2]) }
- ;
-
- assignment
- : var_or_indirect EQUAL expression { result = AssignmentNode.new(val[0],val[2]) }
- | var_or_indirect PLUS EQUAL expression { result = AssignmentNode.new(
- val[0],
- ExpressionNode.new(val[0],"+",val[3])
- )
- }
- | var_or_indirect MINUS EQUAL expression { result = AssignmentNode.new(
- val[0],
- ExpressionNode.new(val[0],"-",val[3])
- )
- }
- ;
-
- var
- : var_without_namespaces
- | var_with_namespaces
- ;
-
- var_without_namespaces
- : WORD { result = VarNode.new(val[0]) }
- | WORD var_method_modifiers { result = VarMethodNode.new(val[0],val[1]) }
- ;
-
- var_with_namespaces
- : namespaces var_without_namespaces
- { result = NamespacedVarNode.new(val[0],val[1]) }
- ;
-
- var_method_modifiers
- : var_method_modifier { result = val[0] }
- | var_method_modifiers var_method_modifier
- { result = val[0].merge(val[1]) }
- ;
-
- var_method_modifier
- : DOT swallow_newlines WORD { result = { method: val[2] } }
- | DOT swallow_newlines GROUP LPAREN integer RPAREN
- { result = { group: val[4] } }
- ;
-
- namespaces
- : ns { result = [val[0]] }
- | namespaces ns { result = val[0] << val[1] }
- ;
-
- ns
- : WORD COLON COLON { result = val[0] }
- ;
-
-
- expression
- : unary_expression
- | binary_expression
- ;
-
- unary_expression
- : factor { result = val[0] }
- | address
- | BANG factor { result = ExpressionNode.new(val[1], "!", nil) }
- ;
-
- binary_expression
- : expression operator expression
- { result = ExpressionNode.new(val[0], val[1], val[2]) }
- ;
-
- operator
- : EEQUAL { result = "==" }
- | NOTEQUAL { result = "<>" }
- | LT { result = "<" }
- | GT { result = ">" }
- | GTE { result = ">=" }
- | LTE { result = "<=" }
- | PLUS { result = "+" }
- | MINUS { result = "-" }
- | OR { result = "||" }
- | STAR { result = "*" }
- | SLASH { result = "/" }
- | DIV { result = "DIV" }
- | MOD { result = "%" }
- | AND { result = "&&" }
- ;
-
- factor
- : number
- | signed_number
- | var
- | indirect_thing
- | paren_expr
- ;
-
- paren_expr
- : LPAREN expression RPAREN { result = ParenExpressionNode.new(val[1]) }
- ;
-
- indirect_thing
- : INDIRECT LPAREN STRING COMMA indirectable RPAREN
- { result = IndirectNode.new(val[2].to_sym, val[4]) }
- ;
-
- signed_number
- : sign DIGIT {
- val[1] = val[1].to_i * -1 if val[0] == "-"
- result = DigitNode.new(val[1])
- }
- | sign REAL { val[1] = val[1].to_f * -1 if val[0] == "-"; result = RealNode.new(val[1]) }
- ;
-
- sign
- : MINUS { result = "-" }
- ;
-
- number
- : integer
- | REAL { result = RealNode.new(val[0]) }
- ;
-
- integer
- : DIGIT { result = DigitNode.new(val[0]) }
- ;
-
- definable
- : numreg
- | output
- | input
- | posreg
- | position
- | vreg
- | number
- | signed_number
- | argument
- | timer
- | ualm
- | sreg
- ;
-
-
- sreg
- : SREG LBRACK DIGIT RBRACK { result = StringRegisterNode.new(val[2].to_i) }
- ;
-
- ualm
- : UALM LBRACK DIGIT RBRACK { result = UserAlarmNode.new(val[2].to_i) }
- ;
-
- timer
- : TIMER LBRACK DIGIT RBRACK { result = TimerNode.new(val[2].to_i) }
- ;
-
- argument
- : ARG LBRACK DIGIT RBRACK { result = ArgumentNode.new(val[2].to_i) }
- ;
-
- vreg
- : VREG LBRACK DIGIT RBRACK { result = VisionRegisterNode.new(val[2].to_i) }
- ;
-
- position
- : POSITION LBRACK DIGIT RBRACK { result = PositionNode.new(val[2].to_i) }
- ;
-
- numreg
- : NUMREG LBRACK DIGIT RBRACK { result = NumregNode.new(val[2].to_i) }
- ;
-
- posreg
- : POSREG LBRACK DIGIT RBRACK { result = PosregNode.new(val[2].to_i) }
- ;
-
- output
- : OUTPUT LBRACK DIGIT RBRACK { result = IONode.new(val[0], val[2].to_i) }
- ;
-
- input
- : INPUT LBRACK DIGIT RBRACK { result = IONode.new(val[0], val[2].to_i) }
- ;
-
- address
- : ADDRESS { result = AddressNode.new(val[0]) }
- ;
-
- comment
- : COMMENT { result = CommentNode.new(val[0]) }
- ;
-
- terminator
- : NEWLINE { result = TerminatorNode.new }
- | comment optional_newline { result = val[0] }
- # ^-- consume newlines or else we will get an extra space from EmptyStmt in the output
- | false
- |
- ;
-
- swallow_newlines
- : NEWLINE { result = TerminatorNode.new }
- |
- ;
-
- position_data
- : POSITION_DATA sn hash sn END
- { result = PositionDataNode.new(val[2]) }
- ;
-
- sn
- : swallow_newlines
- ;
-
- hash
- : LBRACE sn hash_attributes sn RBRACE { result = val[2] }
- | LBRACE sn RBRACE { result = {} }
- ;
-
- hash_attributes
- : hash_attribute { result = val[0] }
- | hash_attributes COMMA sn hash_attribute
- { result = val[0].merge(val[3]) }
- ;
-
- hash_attribute
- : STRING COLON hash_value { result = { val[0].to_sym => val[2] } }
- ;
-
- hash_value
- : STRING
- | hash
- | array
- | optional_sign DIGIT { val[1] = val[1].to_i * -1 if val[0] == "-"; result = val[1] }
- | optional_sign REAL { val[1] = val[1].to_f * -1 if val[0] == "-"; result = val[1] }
- | TRUE_FALSE { result = val[0] == "true" }
- ;
-
- optional_sign
- : sign
- |
- ;
-
- array
- : LBRACK sn array_values sn RBRACK { result = val[2] }
- ;
-
- array_values
- : array_value { result = val }
- | array_values COMMA sn array_value { result = val[0] << val[3] }
- ;
-
- array_value
- : hash_value
- ;
-
-
-end
-
----- inner
-
- include TPPlus::Nodes
-
- attr_reader :interpreter
- def initialize(scanner, interpreter = TPPlus::Interpreter.new)
- @scanner = scanner
- @interpreter = interpreter
- super()
- end
-
- def next_token
- t = @scanner.next_token
- @interpreter.line_count += 1 if t && t[0] == :NEWLINE
-
- #puts t.inspect
- t
- end
-
- def parse
- #@yydebug =true
-
- do_parse
- @interpreter
- end
-
- def on_error(t, val, vstack)
- raise ParseError, sprintf("Parse error on line #{@scanner.tok_line} column #{@scanner.tok_col}: %s (%s)",
- val.inspect, token_to_str(t) || '?')
- end
-
- class ParseError < StandardError ; end
diff --git a/test/racc/assets/twowaysql.y b/test/racc/assets/twowaysql.y
deleted file mode 100644
index d3bc748d3a..0000000000
--- a/test/racc/assets/twowaysql.y
+++ /dev/null
@@ -1,278 +0,0 @@
-# Copyright 2008-2015 Takuto Wada
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-class TwoWaySQL::Parser
-
-rule
-
-sql : stmt_list
- {
- result = RootNode.new( val[0] )
- }
-
-stmt_list :
- {
- result = []
- }
- | stmt_list stmt
- {
- result.push val[1]
- }
-
-stmt : primary
- | if_stmt
- | begin_stmt
-
-begin_stmt : BEGIN stmt_list END
- {
- result = BeginNode.new( val[1] )
- }
-
-if_stmt : IF sub_stmt else_stmt END
- {
- result = IfNode.new( val[0][1], val[1], val[2] )
- }
-
-else_stmt : ELSE sub_stmt
- {
- result = val[1]
- }
- |
- {
- result = nil
- }
-
-sub_stmt : and_stmt
- | or_stmt
- | stmt_list
-
-and_stmt : AND stmt_list
- {
- result = SubStatementNode.new( val[0][1], val[1] )
- }
-
-or_stmt : OR stmt_list
- {
- result = SubStatementNode.new( val[0][1], val[1] )
- }
-
-primary : IDENT
- {
- result = LiteralNode.new( val[0][1] )
- }
- | STRING_LITERAL
- {
- result = LiteralNode.new( val[0][1] )
- }
- | AND
- {
- result = LiteralNode.new( val[0][1] )
- }
- | OR
- {
- result = LiteralNode.new( val[0][1] )
- }
- | SPACES
- {
- result = WhiteSpaceNode.new( val[0][1], @preserve_space )
- }
- | COMMA
- {
- result = LiteralNode.new( val[0][1] )
- }
- | LPAREN
- {
- result = LiteralNode.new( val[0][1] )
- }
- | RPAREN
- {
- result = LiteralNode.new( val[0][1] )
- }
- | QUESTION
- {
- @num_questions += 1
- result = QuestionNode.new( @num_questions )
- }
- | ACTUAL_COMMENT
- {
- result = ActualCommentNode.new( val[0][1] , val[0][2] )
- }
- | bind_var
- | embed_var
-
-bind_var : BIND_VARIABLE STRING_LITERAL
- {
- result = BindVariableNode.new( val[0][1] )
- }
- | BIND_VARIABLE SPACES STRING_LITERAL
- {
- result = BindVariableNode.new( val[0][1] )
- }
- | BIND_VARIABLE IDENT
- {
- result = BindVariableNode.new( val[0][1] )
- }
- | BIND_VARIABLE SPACES IDENT
- {
- result = BindVariableNode.new( val[0][1] )
- }
- | PAREN_BIND_VARIABLE
- {
- result = ParenBindVariableNode.new( val[0][1] )
- }
-
-embed_var : EMBED_VARIABLE IDENT
- {
- result = EmbedVariableNode.new( val[0][1] )
- }
- | EMBED_VARIABLE SPACES IDENT
- {
- result = EmbedVariableNode.new( val[0][1] )
- }
-
-end
-
-
----- inner
-
-require 'strscan'
-
-def initialize(opts={})
- opts = {
- :debug => false,
- :preserve_space => true,
- :preserve_comment => false
- }.merge(opts)
- @yydebug = opts[:debug]
- @preserve_space = opts[:preserve_space]
- @preserve_comment = opts[:preserve_comment]
- @num_questions = 0
-end
-
-
-PAREN_EXAMPLE = '\([^\)]+\)'
-BEGIN_BIND_VARIABLE = '(\/|\#)\*([^\*]+)\*\1'
-BIND_VARIABLE_PATTERN = /\A#{BEGIN_BIND_VARIABLE}\s*/
-PAREN_BIND_VARIABLE_PATTERN = /\A#{BEGIN_BIND_VARIABLE}\s*#{PAREN_EXAMPLE}/
-EMBED_VARIABLE_PATTERN = /\A(\/|\#)\*\$([^\*]+)\*\1\s*/
-
-CONDITIONAL_PATTERN = /\A(\/|\#)\*(IF)\s+([^\*]+)\s*\*\1/
-BEGIN_END_PATTERN = /\A(\/|\#)\*(BEGIN|END)\s*\*\1/
-STRING_LITERAL_PATTERN = /\A(\'(?:[^\']+|\'\')*\')/ ## quoted string
-SPLIT_TOKEN_PATTERN = /\A(\S+?)(?=\s*(?:(?:\/|\#)\*|-{2,}|\(|\)|\,))/ ## stop on delimiters --,/*,#*,',',(,)
-LITERAL_PATTERN = /\A([^;\s]+)/
-SPACES_PATTERN = /\A(\s+)/
-QUESTION_PATTERN = /\A\?/
-COMMA_PATTERN = /\A\,/
-LPAREN_PATTERN = /\A\(/
-RPAREN_PATTERN = /\A\)/
-ACTUAL_COMMENT_PATTERN = /\A(\/|\#)\*(\s{1,}(?:.*?))\*\1/m ## start with spaces
-SEMICOLON_AT_INPUT_END_PATTERN = /\A\;\s*\Z/
-UNMATCHED_COMMENT_START_PATTERN = /\A(?:(?:\/|\#)\*)/
-
-#TODO: remove trailing spaces for S2Dao compatibility, but this spec sometimes causes SQL bugs...
-ELSE_PATTERN = /\A\-{2,}\s*ELSE\s*/
-AND_PATTERN = /\A(\ *AND)\b/i
-OR_PATTERN = /\A(\ *OR)\b/i
-
-
-def parse( io )
- @q = []
- io.each_line(nil) do |whole|
- @s = StringScanner.new(whole)
- end
- scan_str
-
- # @q.push [ false, nil ]
- @q.push [ false, [@s.pos, nil] ]
-
- ## call racc's private parse method
- do_parse
-end
-
-
-## called by racc
-def next_token
- @q.shift
-end
-
-
-def scan_str
- until @s.eos? do
- case
- when @s.scan(AND_PATTERN)
- @q.push [ :AND, [@s.pos, @s[1]] ]
- when @s.scan(OR_PATTERN)
- @q.push [ :OR, [@s.pos, @s[1]] ]
- when @s.scan(SPACES_PATTERN)
- @q.push [ :SPACES, [@s.pos, @s[1]] ]
- when @s.scan(QUESTION_PATTERN)
- @q.push [ :QUESTION, [@s.pos, nil] ]
- when @s.scan(COMMA_PATTERN)
- @q.push [ :COMMA, [@s.pos, ','] ]
- when @s.scan(LPAREN_PATTERN)
- @q.push [ :LPAREN, [@s.pos, '('] ]
- when @s.scan(RPAREN_PATTERN)
- @q.push [ :RPAREN, [@s.pos, ')'] ]
- when @s.scan(ELSE_PATTERN)
- @q.push [ :ELSE, [@s.pos, nil] ]
- when @s.scan(ACTUAL_COMMENT_PATTERN)
- @q.push [ :ACTUAL_COMMENT, [@s.pos, @s[1], @s[2]] ] if @preserve_comment
- when @s.scan(BEGIN_END_PATTERN)
- @q.push [ @s[2].intern, [@s.pos, nil] ]
- when @s.scan(CONDITIONAL_PATTERN)
- @q.push [ @s[2].intern, [@s.pos, @s[3]] ]
- when @s.scan(EMBED_VARIABLE_PATTERN)
- @q.push [ :EMBED_VARIABLE, [@s.pos, @s[2]] ]
- when @s.scan(PAREN_BIND_VARIABLE_PATTERN)
- @q.push [ :PAREN_BIND_VARIABLE, [@s.pos, @s[2]] ]
- when @s.scan(BIND_VARIABLE_PATTERN)
- @q.push [ :BIND_VARIABLE, [@s.pos, @s[2]] ]
- when @s.scan(STRING_LITERAL_PATTERN)
- @q.push [ :STRING_LITERAL, [@s.pos, @s[1]] ]
- when @s.scan(SPLIT_TOKEN_PATTERN)
- @q.push [ :IDENT, [@s.pos, @s[1]] ]
- when @s.scan(UNMATCHED_COMMENT_START_PATTERN) ## unmatched comment start, '/*','#*'
- raise Racc::ParseError, "unmatched comment. line:[#{line_no(@s.pos)}], str:[#{@s.rest}]"
- when @s.scan(LITERAL_PATTERN) ## other string token
- @q.push [ :IDENT, [@s.pos, @s[1]] ]
- when @s.scan(SEMICOLON_AT_INPUT_END_PATTERN)
- #drop semicolon at input end
- else
- raise Racc::ParseError, "syntax error at or near line:[#{line_no(@s.pos)}], str:[#{@s.rest}]"
- end
- end
-end
-
-
-## override racc's default on_error method
-def on_error(t, v, vstack)
- ## cursor in value-stack is an array of two items,
- ## that have position value as 0th item. like [731, "ctx[:limit] "]
- cursor = vstack.find do |tokens|
- tokens.size == 2 and tokens[0].kind_of?(Fixnum)
- end
- pos = cursor[0]
- line = line_no(pos)
- rest = @s.string[pos .. -1]
- raise Racc::ParseError, "syntax error at or near line:[#{line}], str:[#{rest}]"
-end
-
-
-def line_no(pos)
- lines = 0
- scanned = @s.string[0..(pos)]
- scanned.each_line { lines += 1 }
- lines
-end
diff --git a/test/racc/assets/unterm.y b/test/racc/assets/unterm.y
deleted file mode 100644
index 518acc7f31..0000000000
--- a/test/racc/assets/unterm.y
+++ /dev/null
@@ -1,5 +0,0 @@
-# unterminated action
-
-class A
-rule
- a: A {
diff --git a/test/racc/assets/useless.y b/test/racc/assets/useless.y
deleted file mode 100644
index 3f172e341c..0000000000
--- a/test/racc/assets/useless.y
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-class A
-token A B C X
-rule
-
-targ : A list B
- | A B C
-
-list: list X
-
-end
diff --git a/test/racc/assets/yyerr.y b/test/racc/assets/yyerr.y
deleted file mode 100644
index 9faae89a79..0000000000
--- a/test/racc/assets/yyerr.y
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# yyerror/yyerrok/yyaccept test
-#
-
-class A
-rule
-
-target: a b c
-
-a:
- {
- yyerror
- raise ArgumentError, "yyerror failed"
- }
- | error
-
-b:
- {
- yyerrok
- }
-
-c:
- {
- yyaccept
- raise ArgumentError, "yyaccept failed"
- }
-
-end
-
----- inner
-
- def parse
- do_parse
- end
-
- def next_token
- [false, '$end']
- end
-
- def on_error( *args )
- $stderr.puts "on_error called: args=#{args.inspect}"
- end
-
----- footer
-
-A.new.parse
diff --git a/test/racc/bench.y b/test/racc/bench.y
deleted file mode 100644
index c6ba136201..0000000000
--- a/test/racc/bench.y
+++ /dev/null
@@ -1,36 +0,0 @@
-class BenchmarkParser
-
-rule
-
- target: a a a a a a a a a a;
- a: b b b b b b b b b b;
- b: c c c c c c c c c c;
- c: d d d d d d d d d d;
- d: e e e e e e e e e e;
-
-end
-
----- inner
-
-def initialize
- @old = [ :e, 'e' ]
- @i = 0
-end
-
-def next_token
- return [false, '$'] if @i >= 10_0000
- @i += 1
- @old
-end
-
-def parse
- do_parse
-end
-
----- footer
-
-require 'benchmark'
-
-Benchmark.bm do |x|
- x.report { BenchmarkParser.new.parse }
-end
diff --git a/test/racc/case.rb b/test/racc/case.rb
deleted file mode 100644
index d917f3a4e4..0000000000
--- a/test/racc/case.rb
+++ /dev/null
@@ -1,109 +0,0 @@
-verbose = $VERBOSE
-$VERBOSE = true
-begin
-
-require 'test/unit'
-require 'racc/static'
-require 'fileutils'
-require 'tempfile'
-require 'timeout'
-
-module Racc
- class TestCase < Test::Unit::TestCase
- PROJECT_DIR = File.expand_path(File.join(__dir__, '..'))
-
- test_dir = File.join(PROJECT_DIR, 'test')
- test_dir = File.join(PROJECT_DIR, 'racc') unless File.exist?(test_dir)
- TEST_DIR = test_dir
- racc = File.join(PROJECT_DIR, 'bin', 'racc')
- racc = File.join(PROJECT_DIR, '..', 'libexec', 'racc') unless File.exist?(racc)
- RACC = racc
- ASSET_DIR = File.join(TEST_DIR, 'assets') # test grammars
- REGRESS_DIR = File.join(TEST_DIR, 'regress') # known-good generated outputs
-
- INC = [
- File.join(PROJECT_DIR, 'lib'),
- File.join(PROJECT_DIR, 'ext'),
- ].join(':')
-
- def setup
- @TEMP_DIR = Dir.mktmpdir("racc")
- @OUT_DIR = File.join(@TEMP_DIR, 'out')
- @TAB_DIR = File.join(@TEMP_DIR, 'tab') # generated parsers go here
- @LOG_DIR = File.join(@TEMP_DIR, 'log')
- @ERR_DIR = File.join(@TEMP_DIR, 'err')
- FileUtils.mkdir_p([@OUT_DIR, @TAB_DIR, @LOG_DIR, @ERR_DIR])
- FileUtils.cp File.join(TEST_DIR, "src.intp"), @TEMP_DIR
- end
-
- def teardown
- FileUtils.rm_f(File.join(@TEMP_DIR, "src.intp"))
- FileUtils.rm_rf([@OUT_DIR, @TAB_DIR, @LOG_DIR, @ERR_DIR, @TEMP_DIR])
- end
-
- def assert_compile(asset, args = [], **opt)
- file = File.basename(asset, '.y')
- args = ([args].flatten) + [
- "#{ASSET_DIR}/#{file}.y",
- '-Do',
- "-O#{@OUT_DIR}/#{file}",
- "-o#{@TAB_DIR}/#{file}",
- ]
- racc(*args, **opt)
- end
-
- def assert_debugfile(asset, ok)
- file = File.basename(asset, '.y')
- Dir.chdir(@LOG_DIR) do
- File.foreach("#{file}.y") do |line|
- line.strip!
- case line
- when /sr/ then assert_equal "sr#{ok[0]}", line
- when /rr/ then assert_equal "rr#{ok[1]}", line
- when /un/ then assert_equal "un#{ok[2]}", line
- when /ur/ then assert_equal "ur#{ok[3]}", line
- when /ex/ then assert_equal "ex#{ok[4]}", line
- else
- raise TestFailed, 'racc outputs unknown debug report???'
- end
- end
- end
- end
-
- def assert_exec(asset)
- lib_path = File.expand_path("../../lib", __FILE__)
- file = File.basename(asset, '.y')
- ruby "-I#{lib_path}", "#{@TAB_DIR}/#{file}"
- end
-
- def strip_version(source)
- source.sub(/This file is automatically generated by Racc \d+\.\d+\.\d+/, '')
- end
-
- def assert_output_unchanged(asset)
- file = File.basename(asset, '.y')
-
- # Code to re-generate the expectation files
- # File.write("#{REGRESS_DIR}/#{file}", File.read("#{@TAB_DIR}/#{file}"))
-
- expected = File.read("#{REGRESS_DIR}/#{file}")
- actual = File.read("#{@TAB_DIR}/#{file}")
- result = (strip_version(expected) == strip_version(actual))
-
- assert(result, proc {`diff -u #{REGRESS_DIR}/#{file} #{@TAB_DIR}/#{file}`})
- end
-
- def racc(*arg, **opt)
- lib_path = File.expand_path("../../lib", __FILE__)
- ruby "-I#{lib_path}", "-S", RACC, *arg, **opt
- end
-
- def ruby(*arg, **opt)
- assert_ruby_status(["-C", @TEMP_DIR, *arg], **opt)
- end
- end
-end
-
-ensure
-$VERBOSE = verbose
-end
diff --git a/test/racc/infini.y b/test/racc/infini.y
deleted file mode 100644
index 88b1e1e93b..0000000000
--- a/test/racc/infini.y
+++ /dev/null
@@ -1,8 +0,0 @@
-
-class I
-
-rule
-
-list: list X
-
-end
diff --git a/test/racc/regress/README.txt b/test/racc/regress/README.txt
deleted file mode 100644
index dcab73260d..0000000000
--- a/test/racc/regress/README.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-These files are "known-good" compiler output, generated from a stable version of
-Racc. Whenever Racc is refactored, or changes are made which should not affect the
-compiler output, running "rake test" checks that the compiler output is exactly
-the same as these files.
-
-If a change is made which *should* change the compiler output, these files will
-have to be regenerated from the source in test/assets, and the results committed.
diff --git a/test/racc/regress/cadenza b/test/racc/regress/cadenza
deleted file mode 100644
index dafce3c9f3..0000000000
--- a/test/racc/regress/cadenza
+++ /dev/null
@@ -1,796 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-# racc_parser.rb : generated by racc
-
-module Cadenza
- class RaccParser < Racc::Parser
-
-module_eval(<<'...end cadenza.y/module_eval...', 'cadenza.y', 171)
-
-...end cadenza.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 37, 89, 65, 66, 20, 21, 22, 23, 24, 17,
- 106, 37, 3, 76, 4, 3, 75, 4, 50, 37,
- 29, 68, 65, 66, 33, 67, 34, 110, 9, 74,
- 35, 9, 37, 36, 71, 33, 38, 34, 77, 78,
- 79, 35, 72, 33, 36, 34, 37, 38, 3, 35,
- 39, 83, 36, 54, 55, 38, 33, 89, 34, 37,
- 90, 3, 35, 43, 9, 36, 85, 103, 38, 108,
- 33, 109, 34, 56, 57, 111, 35, 9, 3, 36,
- 46, 122, 38, 33, 112, 34, 113, 78, 79, 35,
- 114, 3, 36, 4, 9, 38, 20, 21, 22, 23,
- 24, 20, 21, 22, 23, 24, 115, 9, 65, 66,
- 65, 66, 29, 54, 55, 120, 107, 29, 20, 21,
- 22, 23, 24, 20, 21, 22, 23, 24, 20, 21,
- 22, 23, 24, 3, 29, 39, 3, 121, 4, 29,
- 3, 3, 43, 46, 29, 3, 124, 87, 125, 9,
- 54, 55, 9, 56, 57, 128, 9, 9, 3, 103,
- 116, 9, 20, 21, 22, 23, 24, 20, 21, 22,
- 23, 24, 131, 3, 9, 116, 56, 57, 29, 3,
- 89, 116, nil, 29, 20, 21, 22, 23, 24, 9,
- 20, 21, 22, 23, 24, 9, 56, 57, 56, 57,
- 29, 20, 21, 22, 23, 24, 29, 58, 59, 60,
- 61, 62, 63, 56, 57, 56, 57, 29, 58, 59,
- 60, 61, 62, 63, 20, 21, 22, 23, 24, 20,
- 21, 22, 23, 24, 20, 21, 22, 23, 24, 20,
- 21, 22, 23, 24, 20, 21, 22, 23, 24, 20,
- 21, 22, 23, 24, 20, 21, 22, 23, 24, 20,
- 21, 22, 23, 24, 20, 21, 22, 23, 24, 20,
- 21, 22, 23, 24, 20, 21, 22, 23, 24, 65,
- 66 ]
-
-racc_action_check = [
- 4, 73, 69, 69, 37, 37, 37, 37, 37, 1,
- 69, 39, 0, 38, 0, 2, 38, 2, 17, 43,
- 37, 32, 31, 31, 4, 31, 4, 73, 0, 37,
- 4, 2, 46, 4, 35, 39, 4, 39, 39, 39,
- 39, 39, 36, 43, 39, 43, 87, 39, 5, 43,
- 5, 43, 43, 26, 26, 43, 46, 52, 46, 116,
- 53, 6, 46, 6, 5, 46, 46, 67, 46, 71,
- 87, 72, 87, 27, 27, 75, 87, 6, 7, 87,
- 7, 87, 87, 116, 76, 116, 77, 116, 116, 116,
- 78, 8, 116, 8, 7, 116, 3, 3, 3, 3,
- 3, 20, 20, 20, 20, 20, 79, 8, 70, 70,
- 51, 51, 3, 93, 93, 83, 70, 20, 24, 24,
- 24, 24, 24, 33, 33, 33, 33, 33, 34, 34,
- 34, 34, 34, 41, 24, 41, 42, 85, 42, 33,
- 45, 48, 45, 48, 34, 49, 103, 49, 105, 41,
- 94, 94, 42, 95, 95, 122, 45, 48, 81, 125,
- 81, 49, 65, 65, 65, 65, 65, 66, 66, 66,
- 66, 66, 126, 82, 81, 82, 96, 96, 65, 118,
- 129, 118, nil, 66, 89, 89, 89, 89, 89, 82,
- 108, 108, 108, 108, 108, 118, 97, 97, 98, 98,
- 89, 124, 124, 124, 124, 124, 108, 28, 28, 28,
- 28, 28, 28, 99, 99, 100, 100, 124, 64, 64,
- 64, 64, 64, 64, 29, 29, 29, 29, 29, 54,
- 54, 54, 54, 54, 55, 55, 55, 55, 55, 56,
- 56, 56, 56, 56, 57, 57, 57, 57, 57, 58,
- 58, 58, 58, 58, 59, 59, 59, 59, 59, 60,
- 60, 60, 60, 60, 61, 61, 61, 61, 61, 62,
- 62, 62, 62, 62, 63, 63, 63, 63, 63, 123,
- 123 ]
-
-racc_action_pointer = [
- -12, 9, -9, 93, -3, 24, 37, 54, 67, nil,
- nil, nil, nil, nil, nil, nil, nil, 18, nil, nil,
- 98, nil, nil, nil, 115, nil, 44, 62, 194, 221,
- nil, 2, -4, 120, 125, 31, 39, 1, 10, 8,
- nil, 109, 112, 16, nil, 116, 29, nil, 117, 121,
- nil, 90, 55, 52, 226, 231, 236, 241, 246, 251,
- 256, 261, 266, 271, 205, 159, 164, 64, nil, -18,
- 88, 35, 43, -1, nil, 47, 56, 58, 62, 78,
- nil, 134, 149, 87, nil, 109, nil, 43, nil, 181,
- nil, nil, nil, 104, 141, 142, 165, 185, 187, 202,
- 204, nil, nil, 124, nil, 125, nil, nil, 187, nil,
- nil, nil, nil, nil, nil, nil, 56, nil, 155, nil,
- nil, nil, 127, 259, 198, 156, 144, nil, nil, 178,
- nil, nil ]
-
-racc_action_default = [
- -2, -70, -1, -70, -70, -70, -70, -70, -70, -60,
- -61, -62, -63, -64, -65, -66, -68, -70, -67, -69,
- -5, -7, -8, -9, -70, -11, -14, -17, -24, -70,
- -26, -33, -70, -70, -70, -70, -70, -70, -70, -70,
- -41, -70, -70, -70, -48, -70, -70, -52, -70, -70,
- 132, -3, -6, -70, -70, -70, -70, -70, -70, -70,
- -70, -70, -70, -70, -25, -70, -70, -70, -35, -70,
- -70, -70, -70, -70, -54, -70, -70, -70, -70, -70,
- -42, -70, -70, -70, -49, -70, -53, -70, -57, -70,
- -10, -12, -13, -15, -16, -18, -19, -20, -21, -22,
- -23, -27, -28, -29, -31, -34, -36, -37, -70, -50,
- -55, -58, -59, -38, -39, -40, -70, -44, -70, -43,
- -47, -51, -70, -4, -70, -70, -70, -45, -56, -30,
- -32, -46 ]
-
-racc_goto_table = [
- 19, 40, 18, 32, 104, 52, 51, 1, 2, 64,
- 47, 91, 92, 41, 45, 48, 49, 44, 42, 69,
- 70, 105, 73, 51, 53, 95, 96, 97, 98, 99,
- 100, 93, 94, 101, 102, 88, nil, 80, nil, 19,
- nil, 18, nil, 19, nil, 18, 19, 19, 18, 18,
- 82, 86, nil, nil, 81, nil, 84, nil, nil, nil,
- nil, nil, 130, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 123, nil, 117, 119, nil,
- 19, nil, 18, nil, nil, nil, nil, nil, nil, 118,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 126, 129,
- 51, nil, nil, nil, 127, nil, 19, nil, 18 ]
-
-racc_goto_check = [
- 27, 16, 28, 6, 11, 3, 4, 1, 2, 9,
- 22, 5, 5, 2, 2, 2, 2, 19, 15, 4,
- 4, 12, 3, 4, 6, 8, 8, 8, 8, 8,
- 8, 7, 7, 10, 10, 25, nil, 16, nil, 27,
- nil, 28, nil, 27, nil, 28, 27, 27, 28, 28,
- 2, 22, nil, nil, 15, nil, 19, nil, nil, nil,
- nil, nil, 11, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 4, nil, 16, 16, nil,
- 27, nil, 28, nil, nil, nil, nil, nil, nil, 2,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 6, 3,
- 4, nil, nil, nil, 16, nil, 27, nil, 28 ]
-
-racc_goto_pointer = [
- nil, 7, 8, -15, -14, -43, 0, -25, -33, -20,
- -32, -63, -46, nil, nil, 13, -4, nil, nil, 11,
- nil, nil, 3, nil, nil, -14, nil, -2, 0 ]
-
-racc_goto_default = [
- nil, nil, nil, nil, 31, 25, nil, 26, 27, 28,
- 30, nil, nil, 10, 5, nil, nil, 11, 6, nil,
- 12, 7, nil, 14, 8, nil, 13, 16, 15 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 42, :_reduce_none,
- 0, 42, :_reduce_2,
- 1, 44, :_reduce_3,
- 3, 44, :_reduce_4,
- 1, 46, :_reduce_5,
- 2, 46, :_reduce_6,
- 1, 46, :_reduce_7,
- 1, 46, :_reduce_8,
- 1, 46, :_reduce_9,
- 3, 46, :_reduce_10,
- 1, 48, :_reduce_none,
- 3, 48, :_reduce_12,
- 3, 48, :_reduce_13,
- 1, 49, :_reduce_none,
- 3, 49, :_reduce_15,
- 3, 49, :_reduce_16,
- 1, 50, :_reduce_none,
- 3, 50, :_reduce_18,
- 3, 50, :_reduce_19,
- 3, 50, :_reduce_20,
- 3, 50, :_reduce_21,
- 3, 50, :_reduce_22,
- 3, 50, :_reduce_23,
- 1, 51, :_reduce_none,
- 2, 51, :_reduce_25,
- 1, 45, :_reduce_none,
- 3, 45, :_reduce_27,
- 3, 45, :_reduce_28,
- 1, 52, :_reduce_29,
- 3, 52, :_reduce_30,
- 1, 53, :_reduce_31,
- 3, 53, :_reduce_32,
- 1, 47, :_reduce_none,
- 3, 47, :_reduce_34,
- 3, 54, :_reduce_35,
- 4, 55, :_reduce_36,
- 4, 55, :_reduce_37,
- 3, 56, :_reduce_38,
- 3, 57, :_reduce_39,
- 3, 57, :_reduce_40,
- 2, 58, :_reduce_41,
- 3, 58, :_reduce_42,
- 4, 58, :_reduce_43,
- 4, 58, :_reduce_44,
- 5, 58, :_reduce_45,
- 6, 59, :_reduce_46,
- 3, 60, :_reduce_47,
- 2, 61, :_reduce_48,
- 3, 61, :_reduce_49,
- 4, 62, :_reduce_50,
- 3, 63, :_reduce_51,
- 2, 64, :_reduce_52,
- 3, 64, :_reduce_53,
- 3, 65, :_reduce_54,
- 4, 65, :_reduce_55,
- 3, 66, :_reduce_56,
- 3, 67, :_reduce_57,
- 4, 68, :_reduce_58,
- 4, 68, :_reduce_59,
- 1, 69, :_reduce_60,
- 1, 69, :_reduce_none,
- 1, 69, :_reduce_none,
- 1, 69, :_reduce_none,
- 1, 69, :_reduce_none,
- 1, 69, :_reduce_none,
- 1, 43, :_reduce_66,
- 2, 43, :_reduce_67,
- 1, 43, :_reduce_68,
- 2, 43, :_reduce_69 ]
-
-racc_reduce_n = 70
-
-racc_shift_n = 132
-
-racc_token_table = {
- false => 0,
- :error => 1,
- "," => 2,
- :IDENTIFIER => 3,
- :INTEGER => 4,
- :REAL => 5,
- :STRING => 6,
- "(" => 7,
- ")" => 8,
- "*" => 9,
- "/" => 10,
- "+" => 11,
- "-" => 12,
- :OP_EQ => 13,
- :OP_NEQ => 14,
- :OP_LEQ => 15,
- :OP_GEQ => 16,
- ">" => 17,
- "<" => 18,
- :NOT => 19,
- :AND => 20,
- :OR => 21,
- ":" => 22,
- "|" => 23,
- :VAR_OPEN => 24,
- :VAR_CLOSE => 25,
- :STMT_OPEN => 26,
- :IF => 27,
- :STMT_CLOSE => 28,
- :UNLESS => 29,
- :ELSE => 30,
- :ENDIF => 31,
- :ENDUNLESS => 32,
- :FOR => 33,
- :IN => 34,
- :ENDFOR => 35,
- :BLOCK => 36,
- :ENDBLOCK => 37,
- :END => 38,
- :EXTENDS => 39,
- :TEXT_BLOCK => 40 }
-
-racc_nt_base = 41
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "\",\"",
- "IDENTIFIER",
- "INTEGER",
- "REAL",
- "STRING",
- "\"(\"",
- "\")\"",
- "\"*\"",
- "\"/\"",
- "\"+\"",
- "\"-\"",
- "OP_EQ",
- "OP_NEQ",
- "OP_LEQ",
- "OP_GEQ",
- "\">\"",
- "\"<\"",
- "NOT",
- "AND",
- "OR",
- "\":\"",
- "\"|\"",
- "VAR_OPEN",
- "VAR_CLOSE",
- "STMT_OPEN",
- "IF",
- "STMT_CLOSE",
- "UNLESS",
- "ELSE",
- "ENDIF",
- "ENDUNLESS",
- "FOR",
- "IN",
- "ENDFOR",
- "BLOCK",
- "ENDBLOCK",
- "END",
- "EXTENDS",
- "TEXT_BLOCK",
- "$start",
- "target",
- "document",
- "parameter_list",
- "logical_expression",
- "primary_expression",
- "filtered_expression",
- "multiplicative_expression",
- "additive_expression",
- "boolean_expression",
- "inverse_expression",
- "filter",
- "filter_list",
- "inject_statement",
- "if_tag",
- "else_tag",
- "end_if_tag",
- "if_block",
- "for_tag",
- "end_for_tag",
- "for_block",
- "block_tag",
- "end_block_tag",
- "block_block",
- "generic_block_tag",
- "end_generic_block_tag",
- "generic_block",
- "extends_statement",
- "document_component" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-# reduce 1 omitted
-
-module_eval(<<'.,.,', 'cadenza.y', 12)
- def _reduce_2(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 16)
- def _reduce_3(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 17)
- def _reduce_4(val, _values, result)
- result = val[0].push(val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 22)
- def _reduce_5(val, _values, result)
- result = VariableNode.new(val[0].value)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 23)
- def _reduce_6(val, _values, result)
- result = VariableNode.new(val[0].value, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 24)
- def _reduce_7(val, _values, result)
- result = ConstantNode.new(val[0].value)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 25)
- def _reduce_8(val, _values, result)
- result = ConstantNode.new(val[0].value)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 26)
- def _reduce_9(val, _values, result)
- result = ConstantNode.new(val[0].value)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 27)
- def _reduce_10(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-# reduce 11 omitted
-
-module_eval(<<'.,.,', 'cadenza.y', 32)
- def _reduce_12(val, _values, result)
- result = OperationNode.new(val[0], "*", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 33)
- def _reduce_13(val, _values, result)
- result = OperationNode.new(val[0], "/", val[2])
- result
- end
-.,.,
-
-# reduce 14 omitted
-
-module_eval(<<'.,.,', 'cadenza.y', 38)
- def _reduce_15(val, _values, result)
- result = OperationNode.new(val[0], "+", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 39)
- def _reduce_16(val, _values, result)
- result = OperationNode.new(val[0], "-", val[2])
- result
- end
-.,.,
-
-# reduce 17 omitted
-
-module_eval(<<'.,.,', 'cadenza.y', 44)
- def _reduce_18(val, _values, result)
- result = OperationNode.new(val[0], "==", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 45)
- def _reduce_19(val, _values, result)
- result = OperationNode.new(val[0], "!=", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 46)
- def _reduce_20(val, _values, result)
- result = OperationNode.new(val[0], "<=", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 47)
- def _reduce_21(val, _values, result)
- result = OperationNode.new(val[0], ">=", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 48)
- def _reduce_22(val, _values, result)
- result = OperationNode.new(val[0], ">", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 49)
- def _reduce_23(val, _values, result)
- result = OperationNode.new(val[0], "<", val[2])
- result
- end
-.,.,
-
-# reduce 24 omitted
-
-module_eval(<<'.,.,', 'cadenza.y', 54)
- def _reduce_25(val, _values, result)
- result = BooleanInverseNode.new(val[1])
- result
- end
-.,.,
-
-# reduce 26 omitted
-
-module_eval(<<'.,.,', 'cadenza.y', 59)
- def _reduce_27(val, _values, result)
- result = OperationNode.new(val[0], "and", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 60)
- def _reduce_28(val, _values, result)
- result = OperationNode.new(val[0], "or", val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 64)
- def _reduce_29(val, _values, result)
- result = FilterNode.new(val[0].value)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 65)
- def _reduce_30(val, _values, result)
- result = FilterNode.new(val[0].value, val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 69)
- def _reduce_31(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 70)
- def _reduce_32(val, _values, result)
- result = val[0].push(val[2])
- result
- end
-.,.,
-
-# reduce 33 omitted
-
-module_eval(<<'.,.,', 'cadenza.y', 75)
- def _reduce_34(val, _values, result)
- result = FilteredValueNode.new(val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 79)
- def _reduce_35(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 83)
- def _reduce_36(val, _values, result)
- open_scope!; result = val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 84)
- def _reduce_37(val, _values, result)
- open_scope!; result = BooleanInverseNode.new(val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 88)
- def _reduce_38(val, _values, result)
- result = close_scope!; open_scope!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 92)
- def _reduce_39(val, _values, result)
- result = close_scope!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 93)
- def _reduce_40(val, _values, result)
- result = close_scope!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 97)
- def _reduce_41(val, _values, result)
- result = IfNode.new(val[0], val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 98)
- def _reduce_42(val, _values, result)
- result = IfNode.new(val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 99)
- def _reduce_43(val, _values, result)
- result = IfNode.new(val[0], val[1], val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 100)
- def _reduce_44(val, _values, result)
- result = IfNode.new(val[0], val[2], val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 101)
- def _reduce_45(val, _values, result)
- result = IfNode.new(val[0], val[2], val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 105)
- def _reduce_46(val, _values, result)
- open_scope!; result = [val[2].value, val[4]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 109)
- def _reduce_47(val, _values, result)
- result = close_scope!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 114)
- def _reduce_48(val, _values, result)
- result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 115)
- def _reduce_49(val, _values, result)
- result = ForNode.new(VariableNode.new(val[0].first), val[0].last, val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 119)
- def _reduce_50(val, _values, result)
- result = open_block_scope!(val[2].value)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 123)
- def _reduce_51(val, _values, result)
- result = close_block_scope!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 128)
- def _reduce_52(val, _values, result)
- result = BlockNode.new(val[0], val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 129)
- def _reduce_53(val, _values, result)
- result = BlockNode.new(val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 133)
- def _reduce_54(val, _values, result)
- open_scope!; result = [val[1].value, []]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 134)
- def _reduce_55(val, _values, result)
- open_scope!; result = [val[1].value, val[2]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 138)
- def _reduce_56(val, _values, result)
- result = close_scope!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 142)
- def _reduce_57(val, _values, result)
- result = GenericBlockNode.new(val[0].first, val[2], val[0].last)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 146)
- def _reduce_58(val, _values, result)
- result = val[2].value
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 147)
- def _reduce_59(val, _values, result)
- result = VariableNode.new(val[2].value)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 151)
- def _reduce_60(val, _values, result)
- result = TextNode.new(val[0].value)
- result
- end
-.,.,
-
-# reduce 61 omitted
-
-# reduce 62 omitted
-
-# reduce 63 omitted
-
-# reduce 64 omitted
-
-# reduce 65 omitted
-
-module_eval(<<'.,.,', 'cadenza.y', 160)
- def _reduce_66(val, _values, result)
- push val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 161)
- def _reduce_67(val, _values, result)
- push val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 162)
- def _reduce_68(val, _values, result)
- document.extends = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cadenza.y', 163)
- def _reduce_69(val, _values, result)
- document.extends = val[1]
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class RaccParser
-end # module Cadenza
diff --git a/test/racc/regress/cast b/test/racc/regress/cast
deleted file mode 100644
index 60e92a0abd..0000000000
--- a/test/racc/regress/cast
+++ /dev/null
@@ -1,3945 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.2
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-
-require 'set'
-
-# Error classes
-module C
- class ParseError < StandardError; end
-end
-
-# Local variables:
-# mode: ruby
-# end:
-module C
- class Parser < Racc::Parser
-
-module_eval(<<'...end cast.y/module_eval...', 'cast.y', 564)
- # A.1.9 -- Preprocessing numbers -- skip
- # A.1.8 -- Header names -- skip
-
- # A.1.7 -- Puncuators -- we don't bother with {##,#,%:,%:%:} since
- # we don't do preprocessing
- @@punctuators = %r'\+\+|-[->]|&&|\|\||\.\.\.|(?:<<|>>|[<>=!*/%+\-&^|])=?|[\[\](){}.~?:;,]'
- @@digraphs = %r'<[:%]|[:%]>'
-
- # A.1.6 -- String Literals -- simple for us because we don't decode
- # the string (and indeed accept some illegal strings)
- @@string_literal = %r'L?"(?:[^\\]|\\.)*?"'m
-
- # A.1.5 -- Constants
- @@decimal_floating_constant = %r'(?:(?:\d*\.\d+|\d+\.)(?:e[-+]?\d+)?|\d+e[-+]?\d+)[fl]?'i
- @@hexadecimal_floating_constant = %r'0x(?:(?:[0-9a-f]*\.[0-9a-f]+|[0-9a-f]+\.)|[0-9a-f]+)p[-+]?\d+[fl]?'i
-
- @@integer_constant = %r'(?:[1-9][0-9]*|0x[0-9a-f]+|0[0-7]*)(?:ul?l?|ll?u?)?'i
- @@floating_constant = %r'#{@@decimal_floating_constant}|#{@@hexadecimal_floating_constant}'
- @@enumeration_constant = %r'[a-zA-Z_\\][a-zA-Z_\\0-9]*'
- @@character_constant = %r"L?'(?:[^\\]|\\.)+?'"
- # (note that as with string-literals, we accept some illegal
- # character-constants)
-
- # A.1.4 -- Universal character names -- skip
-
- # A.1.3 -- Identifiers -- skip, since an identifier is lexically
- # identical to an enumeration constant
-
- # A.1.2 Keywords
- keywords = %w'auto break case char const continue default do
-double else enum extern float for goto if inline int long register
-restrict return short signed sizeof static struct switch typedef union
- unsigned void volatile while _Bool _Complex _Imaginary'
- @@keywords = %r"#{keywords.join('|')}"
-
- def initialize
- @type_names = ::Set.new
-
- @warning_proc = lambda{}
- @pos = C::Node::Pos.new(nil, 1, 0)
- end
- def initialize_copy(x)
- @pos = x.pos.dup
- @type_names = x.type_names.dup
- end
- attr_accessor :pos, :type_names
-
- def parse(str)
- if str.respond_to? :read
- str = str.read
- end
- @str = str
- begin
- prepare_lexer(str)
- return do_parse
- rescue ParseError => e
- e.set_backtrace(caller)
- raise
- end
- end
-
- #
- # Error handler, as used by racc.
- #
- def on_error(error_token_id, error_value, value_stack)
- if error_value == '$'
- parse_error @pos, "unexpected EOF"
- else
- parse_error(error_value.pos,
- "parse error on #{token_to_str(error_token_id)} (#{error_value.val})")
- end
- end
-
- def self.feature(name)
- attr_writer "#{name}_enabled"
- class_eval <<-EOS
- def enable_#{name}
- @#{name}_enabled = true
- end
- def #{name}_enabled?
- @#{name}_enabled
- end
- EOS
- end
- private_class_method :feature
-
- #
- # Allow blocks in parentheses as expressions, as per the gcc
- # extension. [http://rubyurl.com/iB7]
- #
- feature :block_expressions
-
- private # ---------------------------------------------------------
-
- class Token
- attr_accessor :pos, :val
- def initialize(pos, val)
- @pos = pos
- @val = val
- end
- end
- def eat(str)
- lines = str.split(/\r\n|[\r\n]/, -1)
- if lines.length == 1
- @pos.col_num += lines[0].length
- else
- @pos.line_num += lines.length - 1
- @pos.col_num = lines[-1].length
- end
- end
-
- #
- # Make a Declaration from the given specs and declarators.
- #
- def make_declaration(pos, specs, declarators)
- specs.all?{|x| x.is_a?(Symbol) || x.is_a?(Type)} or raise specs.map{|x| x.class}.inspect
- decl = Declaration.new_at(pos, nil, declarators)
-
- # set storage class
- storage_classes = specs.find_all do |x|
- [:typedef, :extern, :static, :auto, :register].include? x
- end
- # 6.7.1p2: at most, one storage-class specifier may be given in
- # the declaration specifiers in a declaration
- storage_classes.length <= 1 or
- begin
- if declarators.length == 0
- for_name = ''
- else
- for_name = "for `#{declarators[0].name}'"
- end
- parse_error pos, "multiple or duplicate storage classes given #{for_name}'"
- end
- decl.storage = storage_classes[0]
-
- # set type (specifiers, qualifiers)
- decl.type = make_direct_type(pos, specs)
-
- # set function specifiers
- decl.inline = specs.include?(:inline)
-
- # look for new type names
- if decl.typedef?
- decl.declarators.each do |d|
- if d.name
- @type_names << d.name
- end
- end
- end
-
- return decl
- end
-
- def make_function_def(pos, specs, func_declarator, decl_list, defn)
- add_decl_type(func_declarator, make_direct_type(pos, specs))
-
- # get types from decl_list if necessary
- function = func_declarator.indirect_type
- function.is_a? Function or
- parse_error pos, "non function type for function `#{func_declarator.name}'"
- params = function.params
- if decl_list
- params.all?{|p| p.type.nil?} or
- parse_error pos, "both prototype and declaration list given for `#{func_declarator.name}'"
- decl_list.each do |declaration|
- declaration.declarators.each do |declarator|
- param = params.find{|p| p.name == declarator.name} or
- parse_error pos, "no parameter named #{declarator.name}"
- if declarator.indirect_type
- param.type = declarator.indirect_type
- param.type.direct_type = declaration.type.dup
- else
- param.type = declaration.type.dup
- end
- end
- end
- params.all?{|p| p.type} or
- begin
- s = params.find_all{|p| p.type.nil?}.map{|p| "`#{p.name}'"}.join(' and ')
- parse_error pos, "types missing for parameters #{s}"
- end
- end
-
- fd = FunctionDef.new_at(pos,
- function.detach,
- func_declarator.name,
- defn,
- :no_prototype => !decl_list.nil?)
-
- # set storage class
- # 6.9.1p4: only extern or static allowed
- specs.each do |s|
- [:typedef, :auto, :register].include?(s) and
- "`#{s}' illegal for function"
- end
- storage_classes = specs.find_all do |s|
- s == :extern || s == :static
- end
- # 6.7.1p2: at most, one storage-class specifier may be given in
- # the declaration specifiers in a declaration
- storage_classes.length <= 1 or
- "multiple or duplicate storage classes given for `#{func_declarator.name}'"
- fd.storage = storage_classes[0] if storage_classes[0]
-
- # set function specifiers
- # 6.7.4p5 'inline' can be repeated
- fd.inline = specs.include?(:inline)
-
- return fd
- end
-
- #
- # Make a direct type from the list of type specifiers and type
- # qualifiers.
- #
- def make_direct_type(pos, specs)
- specs_order = [:signed, :unsigned, :short, :long, :double, :void,
- :char, :int, :float, :_Bool, :_Complex, :_Imaginary]
-
- type_specs = specs.find_all do |x|
- specs_order.include?(x) || !x.is_a?(Symbol)
- end
- type_specs.sort! do |a, b|
- (specs_order.index(a)||100) <=> (specs_order.index(b)||100)
- end
-
- # set type specifiers
- # 6.7.2p2: the specifier list should be one of these
- type =
- case type_specs
- when [:void]
- Void.new
- when [:char]
- Char.new
- when [:signed, :char]
- Char.new :signed => true
- when [:unsigned, :char]
- Char.new :signed => false
- when [:short], [:signed, :short], [:short, :int],
- [:signed, :short, :int]
- Int.new :longness => -1
- when [:unsigned, :short], [:unsigned, :short, :int]
- Int.new :unsigned => true, :longness => -1
- when [:int], [:signed], [:signed, :int]
- Int.new
- when [:unsigned], [:unsigned, :int]
- Int.new :unsigned => true
- when [:long], [:signed, :long], [:long, :int],
- [:signed, :long, :int]
- Int.new :longness => 1
- when [:unsigned, :long], [:unsigned, :long, :int]
- Int.new :longness => 1, :unsigned => true
- when [:long, :long], [:signed, :long, :long],
- [:long, :long, :int], [:signed, :long, :long, :int]
- Int.new :longness => 2
- when [:unsigned, :long, :long], [:unsigned, :long, :long, :int]
- Int.new :longness => 2, :unsigned => true
- when [:float]
- Float.new
- when [:double]
- Float.new :longness => 1
- when [:long, :double]
- Float.new :longness => 2
- when [:_Bool]
- Bool.new
- when [:float, :_Complex]
- Complex.new
- when [:double, :_Complex]
- Complex.new :longness => 1
- when [:long, :double, :_Complex]
- Complex.new :longness => 2
- when [:float, :_Imaginary]
- Imaginary.new
- when [:double, :_Imaginary]
- Imaginary.new :longness => 1
- when [:long, :double, :_Imaginary]
- Imaginary.new :longness => 2
- else
- if type_specs.length == 1 &&
- [CustomType, Struct, Union, Enum].any?{|c| type_specs[0].is_a? c}
- type_specs[0]
- else
- if type_specs == []
- parse_error pos, "no type specifiers given"
- else
- parse_error pos, "invalid type specifier combination: #{type_specs.join(' ')}"
- end
- end
- end
- type.pos ||= pos
-
- # set type qualifiers
- # 6.7.3p4: type qualifiers can be repeated
- type.const = specs.any?{|x| x.equal? :const }
- type.restrict = specs.any?{|x| x.equal? :restrict}
- type.volatile = specs.any?{|x| x.equal? :volatile}
-
- return type
- end
-
- def make_parameter(pos, specs, indirect_type, name)
- type = indirect_type
- if type
- type.direct_type = make_direct_type(pos, specs)
- else
- type = make_direct_type(pos, specs)
- end
- [:typedef, :extern, :static, :auto, :inline].each do |sym|
- specs.include? sym and
- parse_error pos, "parameter `#{declarator.name}' declared `#{sym}'"
- end
- return Parameter.new_at(pos, type, name,
- :register => specs.include?(:register))
- end
-
- def add_type_quals(type, quals)
- type.const = quals.include?(:const )
- type.restrict = quals.include?(:restrict)
- type.volatile = quals.include?(:volatile)
- return type
- end
-
- #
- # Add te given type as the "most direct" type to the given
- # declarator. Return the declarator.
- #
- def add_decl_type(declarator, type)
- if declarator.indirect_type
- declarator.indirect_type.direct_type = type
- else
- declarator.indirect_type = type
- end
- return declarator
- end
-
- def param_list(params, var_args)
- if params.length == 1 &&
- params[0].type.is_a?(Void) &&
- params[0].name.nil?
- return NodeArray[]
- elsif params.empty?
- return nil
- else
- return params
- end
- end
-
- def parse_error(pos, str)
- raise ParseError, "#{pos}: #{str}"
- end
-
-...end cast.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 99, 100, 65, 103, 108, 109, 120, 312, 61, 110,
- 111, 112, 113, 114, 115, 116, 117, 77, 48, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 31, 32, 33, 34,
- 35, 36, 37, 72, 281, 128, 49, 38, 196, 391,
- 123, 124, 126, 127, 129, 130, 131, 132, 183, 277,
- 83, 273, 84, 238, 288, 293, 88, 196, 72, 290,
- 38, 274, 184, 372, 373, 386, 239, 240, 289, 294,
- 71, 241, 242, 50, 147, 148, 149, 150, 99, 100,
- 65, 193, 108, 109, 120, 50, 281, 110, 111, 112,
- 113, 114, 115, 116, 117, 71, 50, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 31, 32, 33, 34, 35, 36,
- 37, 56, 366, 128, 89, 38, 50, 169, 123, 124,
- 126, 127, 129, 130, 131, 132, 99, 100, 65, 88,
- 108, 109, 120, 88, 88, 110, 111, 112, 113, 114,
- 115, 116, 117, 346, 349, 238, 59, 68, 48, 365,
- 195, 50, 147, 148, 149, 150, 38, 347, 239, 240,
- 69, 178, 283, 196, 312, 366, 243, 244, 48, 262,
- 88, 128, 185, 38, 263, 284, 123, 124, 126, 127,
- 129, 130, 131, 132, 99, 100, 65, 49, 108, 109,
- 120, 38, 50, 110, 111, 112, 113, 114, 115, 116,
- 117, 281, 365, 309, 440, 249, 250, 49, 238, 50,
- 147, 148, 149, 150, 313, 379, 196, 227, 439, 178,
- 413, 239, 240, 88, 196, 50, 48, 50, 196, 128,
- 187, 38, 191, 196, 123, 124, 126, 127, 129, 130,
- 131, 132, 99, 100, 65, 50, 108, 109, 120, 416,
- 428, 110, 111, 112, 113, 114, 115, 116, 117, 255,
- 256, 192, 196, 196, 197, 49, 198, 50, 147, 148,
- 149, 150, 228, 229, 230, 231, 232, 233, 234, 235,
- 236, 237, 43, 199, 48, 241, 242, 128, 202, 38,
- 241, 242, 123, 124, 126, 127, 129, 130, 131, 132,
- 99, 100, 65, 50, 108, 109, 120, 375, 376, 110,
- 111, 112, 113, 114, 115, 116, 117, 196, 196, 205,
- 377, 387, 427, 49, 433, 50, 147, 148, 149, 150,
- 196, 388, 196, 437, 196, 206, 445, 209, 447, 450,
- 43, 251, 48, 196, 252, 128, 196, 38, 196, 196,
- 123, 124, 126, 127, 129, 130, 131, 132, 99, 100,
- 65, 50, 108, 109, 120, 454, 253, 110, 111, 112,
- 113, 114, 115, 116, 117, 196, 34, 35, 36, 243,
- 244, 49, 49, 50, 147, 148, 149, 150, 34, 35,
- 36, 243, 244, 254, 49, 245, 246, 247, 248, 67,
- 48, 243, 244, 128, 268, 38, 243, 244, 123, 124,
- 126, 127, 129, 130, 131, 132, 99, 100, 65, 50,
- 108, 109, 120, 249, 250, 110, 111, 112, 113, 114,
- 115, 116, 117, 245, 246, 247, 248, 271, 272, 49,
- 275, 50, 147, 148, 149, 150, 245, 246, 247, 248,
- 285, 296, 192, 303, 307, 308, 314, 315, 277, 50,
- 50, 128, 50, 38, 353, 355, 123, 124, 126, 127,
- 129, 130, 131, 132, 99, 100, 65, 50, 108, 109,
- 120, 357, 50, 110, 111, 112, 113, 114, 115, 116,
- 117, 378, 389, 390, 251, 281, 252, 49, 253, 50,
- 147, 148, 149, 150, 254, 395, 396, 397, 398, 399,
- 405, 406, 384, 384, 423, 424, 425, 426, 442, 128,
- nil, 38, nil, nil, 123, 124, 126, 127, 129, 130,
- 131, 132, 99, 100, 65, 50, 108, 109, 120, nil,
- nil, 110, 111, 112, 113, 114, 115, 116, 117, nil,
- nil, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 128, nil, 38,
- nil, nil, 123, 124, 126, 127, 129, 130, 131, 132,
- 99, 100, 65, nil, 108, 109, 120, nil, nil, 110,
- 111, 112, 113, 114, 115, 116, 117, nil, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 128, nil, 38, nil, nil,
- 123, 124, 126, 127, 129, 130, 131, 132, 99, 100,
- 65, nil, 108, 109, 120, nil, nil, 110, 111, 112,
- 113, 114, 115, 116, 117, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 147, 148, 149, 150, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 128, nil, 38, nil, nil, 123, 124,
- 126, 127, 129, 130, 131, 132, 99, 100, 65, nil,
- 108, 109, 120, nil, nil, 110, 111, 112, 113, 114,
- 115, 116, 117, nil, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 128, nil, 38, nil, nil, 123, 124, 126, 127,
- 129, 130, 131, 132, 99, 100, 65, nil, 108, 109,
- 120, nil, nil, 110, 111, 112, 113, 114, 115, 116,
- 117, nil, nil, nil, nil, nil, nil, nil, nil, 50,
- 147, 148, 149, 150, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 128,
- nil, 38, nil, nil, 123, 124, 126, 127, 129, 130,
- 131, 132, 99, 100, 65, nil, 108, 109, 120, nil,
- nil, 110, 111, 112, 113, 114, 115, 116, 117, nil,
- nil, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 128, nil, 38,
- nil, nil, 123, 124, 126, 127, 129, 130, 131, 132,
- 99, 100, 65, nil, 108, 109, 120, nil, nil, 110,
- 111, 112, 113, 114, 115, 116, 117, nil, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 128, nil, 38, nil, nil,
- 123, 124, 126, 127, 129, 130, 131, 132, 99, 100,
- 65, nil, 108, 109, 120, nil, nil, 110, 111, 112,
- 113, 114, 115, 116, 117, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 147, 148, 149, 150, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 128, nil, 38, nil, nil, 123, 124,
- 126, 127, 129, 130, 131, 132, 99, 100, 65, nil,
- 108, 109, 120, nil, nil, 110, 111, 112, 113, 114,
- 115, 116, 117, nil, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 128, nil, 38, nil, nil, 123, 124, 126, 127,
- 129, 130, 131, 132, 99, 100, 65, nil, 108, 109,
- 120, nil, nil, 110, 111, 112, 113, 114, 115, 116,
- 117, nil, nil, nil, nil, nil, nil, nil, nil, 50,
- 147, 148, 149, 150, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 128,
- nil, 38, nil, nil, 123, 124, 126, 127, 129, 130,
- 131, 132, 99, 100, 65, nil, 108, 109, 120, nil,
- nil, 110, 111, 112, 113, 114, 115, 116, 117, nil,
- nil, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 128, nil, 38,
- nil, nil, 123, 124, 126, 127, 129, 130, 131, 132,
- 99, 100, 65, nil, 108, 109, 120, nil, nil, 110,
- 111, 112, 113, 114, 115, 116, 117, nil, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 128, nil, 38, nil, nil,
- 123, 124, 126, 127, 129, 130, 131, 132, 99, 100,
- 65, nil, 108, 109, 120, nil, nil, 110, 111, 112,
- 113, 114, 115, 116, 117, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 147, 148, 149, 150, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 128, nil, 38, nil, nil, 123, 124,
- 126, 127, 129, 130, 131, 132, 99, 100, 65, nil,
- 108, 109, 120, nil, nil, 110, 111, 112, 113, 114,
- 115, 116, 117, 154, nil, nil, nil, 120, nil, nil,
- nil, 50, 147, 148, 149, 150, nil, nil, nil, nil,
- nil, nil, 215, nil, nil, nil, nil, nil, nil, nil,
- nil, 128, nil, 38, nil, nil, 123, 124, 126, 127,
- 129, 130, 131, 132, nil, nil, 128, nil, nil, nil,
- nil, 123, 124, 126, 127, 129, 130, 131, 132, 214,
- nil, nil, nil, nil, 216, 217, 218, 219, nil, 50,
- 147, 148, 149, 150, 65, nil, nil, nil, 120, nil,
- nil, nil, nil, nil, 50, 147, 148, 149, 150, 154,
- nil, nil, nil, 120, nil, nil, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 31, 32,
- 33, 34, 35, 36, nil, nil, nil, 128, nil, 38,
- nil, nil, 123, 124, 126, 127, 129, 130, 131, 132,
- 262, nil, 128, nil, nil, 263, nil, 123, 124, 126,
- 127, 129, 130, 131, 132, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- 65, nil, nil, nil, 120, nil, nil, nil, nil, nil,
- 50, 147, 148, 149, 150, nil, nil, nil, nil, nil,
- nil, nil, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 31, 32, 33, 34, 35, 36,
- nil, nil, nil, 128, nil, 38, nil, nil, 123, 124,
- 126, 127, 129, 130, 131, 132, nil, nil, nil, nil,
- nil, nil, nil, nil, 65, nil, nil, nil, 120, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 31, 32,
- 33, 34, 35, 36, nil, nil, nil, 128, nil, 38,
- nil, nil, 123, 124, 126, 127, 129, 130, 131, 132,
- 154, nil, nil, nil, 120, nil, nil, nil, nil, nil,
- nil, nil, nil, 384, nil, nil, nil, 120, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 128, nil, nil, nil, nil, 123, 124,
- 126, 127, 129, 130, 131, 132, 128, nil, nil, nil,
- nil, 123, 124, 126, 127, 129, 130, 131, 132, 154,
- 392, nil, nil, 120, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, 154, nil, nil, nil,
- 120, nil, nil, nil, 50, 147, 148, 149, 150, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 262, nil, 128, nil, nil, 263, nil, 123, 124, 126,
- 127, 129, 130, 131, 132, nil, nil, 262, nil, 128,
- nil, nil, 263, nil, 123, 124, 126, 127, 129, 130,
- 131, 132, 154, nil, nil, nil, 120, nil, nil, nil,
- 50, 147, 148, 149, 150, nil, nil, 154, 453, nil,
- nil, 120, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 128, nil, nil, nil, nil,
- 123, 124, 126, 127, 129, 130, 131, 132, 262, nil,
- 128, nil, 208, 263, 120, 123, 124, 126, 127, 129,
- 130, 131, 132, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 147, 148, 149, 150, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 50, 147,
- 148, 149, 150, 128, nil, nil, nil, nil, 123, 124,
- 126, 127, 129, 130, 131, 132, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 305, nil, 120, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 31, 32, 33, 34, 35, 36, 37,
- nil, nil, 128, nil, 38, nil, nil, 123, 124, 126,
- 127, 129, 130, 131, 132, 381, nil, 120, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 383, nil,
- 120, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 50, 147, 148, 149, 150, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 128, nil, nil, nil,
- nil, 123, 124, 126, 127, 129, 130, 131, 132, 128,
- nil, 412, nil, 120, 123, 124, 126, 127, 129, 130,
- 131, 132, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 50, 147, 148, 149, 150, nil,
- nil, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, 128, nil, nil, nil, nil, 123, 124, 126,
- 127, 129, 130, 131, 132, 120, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 120, nil,
- 160, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 50, 147, 148, 149, 150, nil, nil, nil, 34, 35,
- 36, nil, nil, 159, 161, nil, nil, nil, nil, 123,
- 124, 126, 127, 129, 130, 131, 132, 128, nil, nil,
- nil, 220, 123, 124, 126, 127, 129, 130, 131, 132,
- nil, nil, nil, nil, 220, nil, nil, nil, nil, nil,
- nil, nil, 50, 147, 148, 149, 150, nil, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- 128, nil, nil, nil, nil, 123, 124, 126, 127, 129,
- 130, 131, 132, 128, nil, nil, nil, 120, 123, 124,
- 126, 127, 129, 130, 131, 132, nil, nil, nil, nil,
- 224, nil, nil, nil, nil, nil, nil, nil, 50, 147,
- 148, 149, 150, nil, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, 128, nil, nil, nil,
- nil, 123, 124, 126, 127, 129, 130, 131, 132, 128,
- nil, nil, nil, nil, 123, 124, 126, 127, 129, 130,
- 131, 132, nil, nil, 120, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 50, 147, 148, 149, 150, 266,
- nil, nil, nil, 120, nil, nil, nil, 50, 147, 148,
- 149, 150, nil, nil, nil, nil, nil, 34, 35, 36,
- nil, nil, 265, 267, nil, nil, nil, 120, 123, 124,
- 126, 127, 129, 130, 131, 132, 34, 35, 36, nil,
- nil, nil, 128, nil, nil, nil, 120, 123, 124, 126,
- 127, 129, 130, 131, 132, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, 128, nil, nil, nil,
- 120, 123, 124, 126, 127, 129, 130, 131, 132, nil,
- 50, 147, 148, 149, 150, 128, nil, nil, nil, 120,
- 123, 124, 126, 127, 129, 130, 131, 132, nil, nil,
- nil, nil, nil, nil, 50, 147, 148, 149, 150, 128,
- nil, nil, nil, 120, 123, 124, 126, 127, 129, 130,
- 131, 132, nil, 50, 147, 148, 149, 150, 128, nil,
- nil, nil, 120, 123, 124, 126, 127, 129, 130, 131,
- 132, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, 128, nil, nil, nil, 120, 123, 124, 126,
- 127, 129, 130, 131, 132, nil, 50, 147, 148, 149,
- 150, 128, nil, nil, nil, nil, 123, 124, 126, 127,
- 129, 130, 131, 132, nil, nil, nil, nil, nil, nil,
- 50, 147, 148, 149, 150, 128, nil, nil, nil, nil,
- 123, 124, 126, 127, 129, 130, 131, 132, nil, 50,
- 147, 148, 149, 150, nil, nil, nil, nil, nil, nil,
- 120, 318, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 147, 148, 149, 150, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 31, 32, 33, 34, 35, 36, nil, nil, nil, 128,
- nil, 38, nil, 120, 123, 124, 126, 127, 129, 130,
- 131, 132, nil, nil, nil, nil, 120, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, 128, nil, nil, nil, nil, 123, 124, 126,
- 127, 129, 130, 131, 132, 128, nil, nil, nil, 120,
- 123, 124, 126, 127, 129, 130, 131, 132, nil, nil,
- nil, nil, 120, nil, nil, nil, nil, nil, nil, nil,
- 50, 147, 148, 149, 150, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 147, 148, 149, 150, 128, nil,
- nil, nil, nil, 123, 124, 126, 127, 129, 130, 131,
- 132, 128, nil, nil, nil, 120, 123, 124, 126, 127,
- 129, 130, 131, 132, nil, nil, nil, nil, 120, nil,
- nil, nil, nil, nil, nil, nil, 50, 147, 148, 149,
- 150, nil, nil, nil, nil, nil, nil, nil, nil, 50,
- 147, 148, 149, 150, 128, nil, nil, nil, nil, 123,
- 124, 126, 127, 129, 130, 131, 132, 128, nil, nil,
- nil, 120, 123, 124, 126, 127, 129, 130, 131, 132,
- nil, nil, nil, nil, 120, nil, nil, nil, nil, nil,
- nil, nil, 50, 147, 148, 149, 150, nil, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- 128, nil, nil, nil, nil, 123, 124, 126, 127, 129,
- 130, 131, 132, 128, nil, nil, nil, 120, 123, 124,
- 126, 127, 129, 130, 131, 132, nil, nil, nil, nil,
- 120, nil, nil, nil, nil, nil, nil, nil, 50, 147,
- 148, 149, 150, nil, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, 128, nil, nil, nil,
- nil, 123, 124, 126, 127, 129, 130, 131, 132, 128,
- nil, nil, nil, 120, 123, 124, 126, 127, 129, 130,
- 131, 132, nil, nil, nil, nil, 120, nil, nil, nil,
- nil, nil, nil, nil, 50, 147, 148, 149, 150, nil,
- nil, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, 128, nil, nil, nil, nil, 123, 124, 126,
- 127, 129, 130, 131, 132, 128, nil, nil, nil, 120,
- 123, 124, 126, 127, 129, 130, 131, 132, nil, nil,
- nil, nil, 120, nil, nil, nil, nil, nil, nil, nil,
- 50, 147, 148, 149, 150, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 147, 148, 149, 150, 128, nil,
- nil, nil, nil, 123, 124, 126, 127, 129, 130, 131,
- 132, 128, nil, nil, nil, 120, 123, 124, 126, 127,
- 129, 130, 131, 132, nil, nil, nil, nil, 120, nil,
- nil, nil, nil, nil, nil, nil, 50, 147, 148, 149,
- 150, nil, nil, nil, nil, nil, nil, nil, nil, 50,
- 147, 148, 149, 150, 128, nil, nil, nil, nil, 123,
- 124, 126, 127, 129, 130, 131, 132, 128, nil, nil,
- nil, 120, 123, 124, 126, 127, 129, 130, 131, 132,
- nil, nil, nil, nil, 120, nil, nil, nil, nil, nil,
- nil, nil, 50, 147, 148, 149, 150, nil, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- 128, nil, nil, nil, nil, 123, 124, 126, 127, 129,
- 130, 131, 132, 128, nil, nil, nil, 120, 123, 124,
- 126, 127, 129, 130, 131, 132, nil, nil, nil, nil,
- 120, nil, nil, nil, nil, nil, nil, nil, 50, 147,
- 148, 149, 150, nil, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, 128, nil, nil, nil,
- nil, 123, 124, 126, 127, 129, 130, 131, 132, 128,
- nil, nil, nil, 120, 123, 124, 126, 127, 129, 130,
- 131, 132, nil, nil, nil, nil, 120, nil, nil, nil,
- nil, nil, nil, nil, 50, 147, 148, 149, 150, nil,
- nil, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, 128, nil, nil, nil, nil, 123, 124, 126,
- 127, 129, 130, 131, 132, 128, nil, nil, nil, nil,
- 123, 124, 126, 127, 129, 130, 131, 132, 120, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 50, 147, 148, 149, 150, 120, nil, nil, nil, nil,
- nil, nil, nil, 50, 147, 148, 149, 150, nil, nil,
- nil, 34, 35, 36, nil, nil, nil, 128, nil, nil,
- nil, nil, 123, 124, 126, 127, 129, 130, 131, 132,
- nil, nil, nil, 368, 369, nil, nil, nil, 120, 123,
- 124, 126, 127, 129, 130, 131, 132, nil, nil, nil,
- nil, nil, 120, nil, nil, 50, 147, 148, 149, 150,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 50, 147, 148, 149, 150, 128, nil, nil,
- nil, nil, 123, 124, 126, 127, 129, 130, 131, 132,
- 401, 402, nil, nil, nil, 120, 123, 124, 126, 127,
- 129, 130, 131, 132, nil, nil, nil, nil, 120, 415,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 50,
- 147, 148, 149, 150, 128, nil, nil, nil, nil, 123,
- 124, 126, 127, 129, 130, 131, 132, 128, nil, nil,
- nil, nil, 123, 124, 126, 127, 129, 130, 131, 132,
- 120, 418, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 50, 147, 148, 149, 150, nil, nil, nil,
- nil, nil, nil, nil, nil, 50, 147, 148, 149, 150,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 128,
- nil, nil, nil, nil, 123, 124, 126, 127, 129, 130,
- 131, 132, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 120, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 31, 32, 33, 34, 35, 36,
- nil, nil, nil, 128, nil, 38, nil, 120, 123, 124,
- 126, 127, 129, 130, 131, 132, nil, nil, nil, nil,
- 120, 430, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 50, 147, 148, 149, 150, 128, nil, nil, nil,
- nil, 123, 124, 126, 127, 129, 130, 131, 132, 128,
- nil, nil, nil, nil, 123, 124, 126, 127, 129, 130,
- 131, 132, 120, 432, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 50, 147, 148, 149, 150, 120,
- 436, nil, nil, nil, nil, nil, nil, 50, 147, 148,
- 149, 150, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 128, nil, nil, nil, nil, 123, 124, 126, 127,
- 129, 130, 131, 132, nil, nil, nil, nil, 128, nil,
- nil, nil, nil, 123, 124, 126, 127, 129, 130, 131,
- 132, 120, 444, nil, nil, nil, nil, nil, nil, 50,
- 147, 148, 149, 150, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 50, 147, 148, 149,
- 150, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 128, nil, nil, nil, nil, 123, 124, 126, 127, 129,
- 130, 131, 132, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 277, 364, nil, nil, nil, nil, nil, nil, 50, 147,
- 148, 149, 150, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 31, 32, 33, 34, 35, 36, 37, 281, 164, 49,
- nil, 38, nil, nil, nil, nil, nil, nil, nil, nil,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 31, 32, 33,
- 34, 35, 36, 37, nil, nil, nil, 50, 38, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 50, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 31, 32, 33, 34, 35, 36, 37, 65,
- nil, nil, nil, 38, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 67, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 31, 32, 33, 34, 35, 36, 37,
- 65, nil, nil, nil, 38, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 31, 32, 33, 34, 35, 36,
- 37, 173, nil, nil, nil, 38, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 31, 32, 33, 34, 35, 36,
- 282, nil, nil, nil, nil, 38, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 31, 32, 33, 34, 35, 36, 287,
- nil, nil, nil, nil, 38, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 31, 32, 33, 34, 35, 36, 312, 364,
- nil, nil, nil, 38, nil, nil, nil, nil, nil, nil,
- nil, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 31, 32,
- 33, 34, 35, 36, 37, 281, 404, 49, nil, 38,
- nil, nil, nil, nil, nil, nil, nil, nil, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 31, 32, 33, 34, 35,
- 36, 37, nil, nil, nil, nil, 38, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 31, 32, 33, 34, 35, 36,
- 37, nil, nil, nil, nil, 38, 10, 11, 12, 13,
- 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 31, 32, 33, 34, 35, 36, 37,
- nil, nil, nil, nil, 38, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 31, 32, 33, 34, 35, 36, 37, nil,
- nil, nil, nil, 38, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 31, 32, 33, 34, 35, 36, 37, nil, nil,
- nil, nil, 38, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 31, 32, 33, 34, 35, 36, 37, nil, nil, nil,
- nil, 38, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 31,
- 32, 33, 34, 35, 36, 37, nil, nil, nil, 359,
- 38, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 31, 32, 33, 34, 35, 36, nil,
- nil, nil, nil, nil, 38, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 31, 32, 33,
- 34, 35, 36, nil, nil, nil, nil, nil, 38, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 31, 32, 33, 34, 35, 36, nil, nil, nil,
- nil, nil, 38, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 31, 32, 33, 34, 35,
- 36, nil, nil, nil, nil, nil, 38, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 31,
- 32, 33, 34, 35, 36, nil, nil, nil, nil, nil,
- 38 ]
-
-racc_action_check = [
- 65, 65, 65, 65, 65, 65, 65, 210, 39, 65,
- 65, 65, 65, 65, 65, 65, 65, 55, 45, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 46, 210, 65, 210, 65, 316, 345,
- 65, 65, 65, 65, 65, 65, 65, 65, 85, 276,
- 57, 163, 58, 135, 182, 186, 59, 345, 70, 184,
- 114, 163, 85, 289, 294, 316, 135, 135, 182, 186,
- 46, 136, 136, 65, 65, 65, 65, 65, 102, 102,
- 102, 102, 102, 102, 102, 45, 276, 102, 102, 102,
- 102, 102, 102, 102, 102, 70, 114, 102, 102, 102,
- 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
- 102, 30, 280, 102, 60, 102, 276, 73, 102, 102,
- 102, 102, 102, 102, 102, 102, 112, 112, 112, 184,
- 112, 112, 112, 289, 294, 112, 112, 112, 112, 112,
- 112, 112, 112, 257, 260, 330, 33, 42, 48, 280,
- 107, 102, 102, 102, 102, 102, 30, 257, 330, 330,
- 42, 80, 175, 107, 311, 361, 137, 137, 80, 260,
- 84, 112, 87, 112, 260, 175, 112, 112, 112, 112,
- 112, 112, 112, 112, 187, 187, 187, 48, 187, 187,
- 187, 33, 30, 187, 187, 187, 187, 187, 187, 187,
- 187, 311, 361, 207, 419, 139, 139, 80, 331, 112,
- 112, 112, 112, 112, 211, 304, 207, 133, 419, 284,
- 380, 331, 331, 89, 211, 48, 284, 33, 304, 187,
- 98, 187, 100, 380, 187, 187, 187, 187, 187, 187,
- 187, 187, 191, 191, 191, 80, 191, 191, 191, 382,
- 411, 191, 191, 191, 191, 191, 191, 191, 191, 144,
- 144, 101, 382, 411, 109, 284, 110, 187, 187, 187,
- 187, 187, 133, 133, 133, 133, 133, 133, 133, 133,
- 133, 133, 5, 111, 5, 332, 332, 191, 113, 191,
- 333, 333, 191, 191, 191, 191, 191, 191, 191, 191,
- 192, 192, 192, 284, 192, 192, 192, 300, 301, 192,
- 192, 192, 192, 192, 192, 192, 192, 300, 301, 115,
- 302, 317, 410, 5, 414, 191, 191, 191, 191, 191,
- 302, 317, 410, 417, 414, 116, 429, 119, 431, 435,
- 66, 140, 66, 417, 141, 192, 429, 192, 431, 435,
- 192, 192, 192, 192, 192, 192, 192, 192, 296, 296,
- 296, 5, 296, 296, 296, 443, 142, 296, 296, 296,
- 296, 296, 296, 296, 296, 443, 49, 49, 49, 334,
- 334, 66, 49, 192, 192, 192, 192, 192, 74, 74,
- 74, 335, 335, 143, 74, 138, 138, 138, 138, 151,
- 69, 336, 336, 296, 158, 296, 337, 337, 296, 296,
- 296, 296, 296, 296, 296, 296, 375, 375, 375, 66,
- 375, 375, 375, 340, 340, 375, 375, 375, 375, 375,
- 375, 375, 375, 338, 338, 338, 338, 161, 162, 69,
- 165, 296, 296, 296, 296, 296, 339, 339, 339, 339,
- 177, 188, 200, 201, 203, 204, 212, 213, 167, 216,
- 217, 375, 263, 375, 264, 267, 375, 375, 375, 375,
- 375, 375, 375, 375, 376, 376, 376, 69, 376, 376,
- 376, 270, 274, 376, 376, 376, 376, 376, 376, 376,
- 376, 303, 324, 325, 341, 167, 342, 167, 343, 375,
- 375, 375, 375, 375, 344, 351, 354, 356, 362, 363,
- 367, 369, 389, 390, 400, 402, 403, 407, 427, 376,
- nil, 376, nil, nil, 376, 376, 376, 376, 376, 376,
- 376, 376, 377, 377, 377, 167, 377, 377, 377, nil,
- nil, 377, 377, 377, 377, 377, 377, 377, 377, nil,
- nil, nil, nil, nil, nil, nil, nil, 376, 376, 376,
- 376, 376, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 377, nil, 377,
- nil, nil, 377, 377, 377, 377, 377, 377, 377, 377,
- 415, 415, 415, nil, 415, 415, 415, nil, nil, 415,
- 415, 415, 415, 415, 415, 415, 415, nil, nil, nil,
- nil, nil, nil, nil, nil, 377, 377, 377, 377, 377,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 415, nil, 415, nil, nil,
- 415, 415, 415, 415, 415, 415, 415, 415, 418, 418,
- 418, nil, 418, 418, 418, nil, nil, 418, 418, 418,
- 418, 418, 418, 418, 418, nil, nil, nil, nil, nil,
- nil, nil, nil, 415, 415, 415, 415, 415, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 418, nil, 418, nil, nil, 418, 418,
- 418, 418, 418, 418, 418, 418, 426, 426, 426, nil,
- 426, 426, 426, nil, nil, 426, 426, 426, 426, 426,
- 426, 426, 426, nil, nil, nil, nil, nil, nil, nil,
- nil, 418, 418, 418, 418, 418, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 426, nil, 426, nil, nil, 426, 426, 426, 426,
- 426, 426, 426, 426, 430, 430, 430, nil, 430, 430,
- 430, nil, nil, 430, 430, 430, 430, 430, 430, 430,
- 430, nil, nil, nil, nil, nil, nil, nil, nil, 426,
- 426, 426, 426, 426, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 430,
- nil, 430, nil, nil, 430, 430, 430, 430, 430, 430,
- 430, 430, 432, 432, 432, nil, 432, 432, 432, nil,
- nil, 432, 432, 432, 432, 432, 432, 432, 432, nil,
- nil, nil, nil, nil, nil, nil, nil, 430, 430, 430,
- 430, 430, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 432, nil, 432,
- nil, nil, 432, 432, 432, 432, 432, 432, 432, 432,
- 433, 433, 433, nil, 433, 433, 433, nil, nil, 433,
- 433, 433, 433, 433, 433, 433, 433, nil, nil, nil,
- nil, nil, nil, nil, nil, 432, 432, 432, 432, 432,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 433, nil, 433, nil, nil,
- 433, 433, 433, 433, 433, 433, 433, 433, 436, 436,
- 436, nil, 436, 436, 436, nil, nil, 436, 436, 436,
- 436, 436, 436, 436, 436, nil, nil, nil, nil, nil,
- nil, nil, nil, 433, 433, 433, 433, 433, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 436, nil, 436, nil, nil, 436, 436,
- 436, 436, 436, 436, 436, 436, 437, 437, 437, nil,
- 437, 437, 437, nil, nil, 437, 437, 437, 437, 437,
- 437, 437, 437, nil, nil, nil, nil, nil, nil, nil,
- nil, 436, 436, 436, 436, 436, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 437, nil, 437, nil, nil, 437, 437, 437, 437,
- 437, 437, 437, 437, 444, 444, 444, nil, 444, 444,
- 444, nil, nil, 444, 444, 444, 444, 444, 444, 444,
- 444, nil, nil, nil, nil, nil, nil, nil, nil, 437,
- 437, 437, 437, 437, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 444,
- nil, 444, nil, nil, 444, 444, 444, 444, 444, 444,
- 444, 444, 445, 445, 445, nil, 445, 445, 445, nil,
- nil, 445, 445, 445, 445, 445, 445, 445, 445, nil,
- nil, nil, nil, nil, nil, nil, nil, 444, 444, 444,
- 444, 444, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 445, nil, 445,
- nil, nil, 445, 445, 445, 445, 445, 445, 445, 445,
- 447, 447, 447, nil, 447, 447, 447, nil, nil, 447,
- 447, 447, 447, 447, 447, 447, 447, nil, nil, nil,
- nil, nil, nil, nil, nil, 445, 445, 445, 445, 445,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 447, nil, 447, nil, nil,
- 447, 447, 447, 447, 447, 447, 447, 447, 450, 450,
- 450, nil, 450, 450, 450, nil, nil, 450, 450, 450,
- 450, 450, 450, 450, 450, nil, nil, nil, nil, nil,
- nil, nil, nil, 447, 447, 447, 447, 447, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 450, nil, 450, nil, nil, 450, 450,
- 450, 450, 450, 450, 450, 450, 454, 454, 454, nil,
- 454, 454, 454, nil, nil, 454, 454, 454, 454, 454,
- 454, 454, 454, 67, nil, nil, nil, 67, nil, nil,
- nil, 450, 450, 450, 450, 450, nil, nil, nil, nil,
- nil, nil, 122, nil, nil, nil, nil, nil, nil, nil,
- nil, 454, nil, 454, nil, nil, 454, 454, 454, 454,
- 454, 454, 454, 454, nil, nil, 67, nil, nil, nil,
- nil, 67, 67, 67, 67, 67, 67, 67, 67, 122,
- nil, nil, nil, nil, 122, 122, 122, 122, nil, 454,
- 454, 454, 454, 454, 120, nil, nil, nil, 120, nil,
- nil, nil, nil, nil, 67, 67, 67, 67, 67, 154,
- nil, nil, nil, 154, nil, nil, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, nil, nil, nil, 120, nil, 120,
- nil, nil, 120, 120, 120, 120, 120, 120, 120, 120,
- 154, nil, 154, nil, nil, 154, nil, 154, 154, 154,
- 154, 154, 154, 154, 154, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 120, 120, 120, 120, 120,
- 220, nil, nil, nil, 220, nil, nil, nil, nil, nil,
- 154, 154, 154, 154, 154, nil, nil, nil, nil, nil,
- nil, nil, 220, 220, 220, 220, 220, 220, 220, 220,
- 220, 220, 220, 220, 220, 220, 220, 220, 220, 220,
- nil, nil, nil, 220, nil, 220, nil, nil, 220, 220,
- 220, 220, 220, 220, 220, 220, nil, nil, nil, nil,
- nil, nil, nil, nil, 224, nil, nil, nil, 224, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 220, 220, 220, 220, 220, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, nil, nil, nil, 224, nil, 224,
- nil, nil, 224, 224, 224, 224, 224, 224, 224, 224,
- 258, nil, nil, nil, 258, nil, nil, nil, nil, nil,
- nil, nil, nil, 315, nil, nil, nil, 315, nil, nil,
- nil, nil, nil, nil, nil, 224, 224, 224, 224, 224,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 258, nil, nil, nil, nil, 258, 258,
- 258, 258, 258, 258, 258, 258, 315, nil, nil, nil,
- nil, 315, 315, 315, 315, 315, 315, 315, 315, 347,
- 347, nil, nil, 347, nil, nil, nil, nil, nil, nil,
- nil, 258, 258, 258, 258, 258, 384, nil, nil, nil,
- 384, nil, nil, nil, 315, 315, 315, 315, 315, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 347, nil, 347, nil, nil, 347, nil, 347, 347, 347,
- 347, 347, 347, 347, 347, nil, nil, 384, nil, 384,
- nil, nil, 384, nil, 384, 384, 384, 384, 384, 384,
- 384, 384, 393, nil, nil, nil, 393, nil, nil, nil,
- 347, 347, 347, 347, 347, nil, nil, 439, 439, nil,
- nil, 439, nil, nil, nil, nil, nil, 384, 384, 384,
- 384, 384, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 393, nil, nil, nil, nil,
- 393, 393, 393, 393, 393, 393, 393, 393, 439, nil,
- 439, nil, 117, 439, 117, 439, 439, 439, 439, 439,
- 439, 439, 439, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 393, 393, 393, 393, 393, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 439, 439,
- 439, 439, 439, 117, nil, nil, nil, nil, 117, 117,
- 117, 117, 117, 117, 117, 117, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 202, nil, 202, nil, nil, nil, nil, nil, nil,
- nil, 117, 117, 117, 117, 117, 202, 202, 202, 202,
- 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
- 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
- nil, nil, 202, nil, 202, nil, nil, 202, 202, 202,
- 202, 202, 202, 202, 202, 305, nil, 305, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 306, nil,
- 306, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 202, 202, 202, 202, 202, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 305, nil, nil, nil,
- nil, 305, 305, 305, 305, 305, 305, 305, 305, 306,
- nil, 379, nil, 379, 306, 306, 306, 306, 306, 306,
- 306, 306, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 305, 305, 305, 305, 305, nil,
- nil, nil, nil, nil, nil, nil, nil, 306, 306, 306,
- 306, 306, 379, nil, nil, nil, nil, 379, 379, 379,
- 379, 379, 379, 379, 379, 71, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 99, nil,
- 71, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 379, 379, 379, 379, 379, nil, nil, nil, 71, 71,
- 71, nil, nil, 71, 71, nil, nil, nil, nil, 71,
- 71, 71, 71, 71, 71, 71, 71, 99, nil, nil,
- nil, 123, 99, 99, 99, 99, 99, 99, 99, 99,
- nil, nil, nil, nil, 124, nil, nil, nil, nil, nil,
- nil, nil, 71, 71, 71, 71, 71, nil, nil, nil,
- nil, nil, nil, nil, nil, 99, 99, 99, 99, 99,
- 123, nil, nil, nil, nil, 123, 123, 123, 123, 123,
- 123, 123, 123, 124, nil, nil, nil, 125, 124, 124,
- 124, 124, 124, 124, 124, 124, nil, nil, nil, nil,
- 126, nil, nil, nil, nil, nil, nil, nil, 123, 123,
- 123, 123, 123, nil, nil, nil, nil, nil, nil, nil,
- nil, 124, 124, 124, 124, 124, 125, nil, nil, nil,
- nil, 125, 125, 125, 125, 125, 125, 125, 125, 126,
- nil, nil, nil, nil, 126, 126, 126, 126, 126, 126,
- 126, 126, nil, nil, 157, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 125, 125, 125, 125, 125, 157,
- nil, nil, nil, 160, nil, nil, nil, 126, 126, 126,
- 126, 126, nil, nil, nil, nil, nil, 157, 157, 157,
- nil, nil, 157, 157, nil, nil, nil, 178, 157, 157,
- 157, 157, 157, 157, 157, 157, 160, 160, 160, nil,
- nil, nil, 160, nil, nil, nil, 185, 160, 160, 160,
- 160, 160, 160, 160, 160, nil, nil, nil, nil, nil,
- nil, 157, 157, 157, 157, 157, 178, nil, nil, nil,
- 196, 178, 178, 178, 178, 178, 178, 178, 178, nil,
- 160, 160, 160, 160, 160, 185, nil, nil, nil, 197,
- 185, 185, 185, 185, 185, 185, 185, 185, nil, nil,
- nil, nil, nil, nil, 178, 178, 178, 178, 178, 196,
- nil, nil, nil, 198, 196, 196, 196, 196, 196, 196,
- 196, 196, nil, 185, 185, 185, 185, 185, 197, nil,
- nil, nil, 199, 197, 197, 197, 197, 197, 197, 197,
- 197, nil, nil, nil, nil, nil, nil, 196, 196, 196,
- 196, 196, 198, nil, nil, nil, 214, 198, 198, 198,
- 198, 198, 198, 198, 198, nil, 197, 197, 197, 197,
- 197, 199, nil, nil, nil, nil, 199, 199, 199, 199,
- 199, 199, 199, 199, nil, nil, nil, nil, nil, nil,
- 198, 198, 198, 198, 198, 214, nil, nil, nil, nil,
- 214, 214, 214, 214, 214, 214, 214, 214, nil, 199,
- 199, 199, 199, 199, nil, nil, nil, nil, nil, nil,
- 215, 215, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 214, 214, 214, 214, 214, 215, 215,
- 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
- 215, 215, 215, 215, 215, 215, nil, nil, nil, 215,
- nil, 215, nil, 226, 215, 215, 215, 215, 215, 215,
- 215, 215, nil, nil, nil, nil, 238, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 215, 215, 215,
- 215, 215, 226, nil, nil, nil, nil, 226, 226, 226,
- 226, 226, 226, 226, 226, 238, nil, nil, nil, 239,
- 238, 238, 238, 238, 238, 238, 238, 238, nil, nil,
- nil, nil, 240, nil, nil, nil, nil, nil, nil, nil,
- 226, 226, 226, 226, 226, nil, nil, nil, nil, nil,
- nil, nil, nil, 238, 238, 238, 238, 238, 239, nil,
- nil, nil, nil, 239, 239, 239, 239, 239, 239, 239,
- 239, 240, nil, nil, nil, 241, 240, 240, 240, 240,
- 240, 240, 240, 240, nil, nil, nil, nil, 242, nil,
- nil, nil, nil, nil, nil, nil, 239, 239, 239, 239,
- 239, nil, nil, nil, nil, nil, nil, nil, nil, 240,
- 240, 240, 240, 240, 241, nil, nil, nil, nil, 241,
- 241, 241, 241, 241, 241, 241, 241, 242, nil, nil,
- nil, 243, 242, 242, 242, 242, 242, 242, 242, 242,
- nil, nil, nil, nil, 244, nil, nil, nil, nil, nil,
- nil, nil, 241, 241, 241, 241, 241, nil, nil, nil,
- nil, nil, nil, nil, nil, 242, 242, 242, 242, 242,
- 243, nil, nil, nil, nil, 243, 243, 243, 243, 243,
- 243, 243, 243, 244, nil, nil, nil, 245, 244, 244,
- 244, 244, 244, 244, 244, 244, nil, nil, nil, nil,
- 246, nil, nil, nil, nil, nil, nil, nil, 243, 243,
- 243, 243, 243, nil, nil, nil, nil, nil, nil, nil,
- nil, 244, 244, 244, 244, 244, 245, nil, nil, nil,
- nil, 245, 245, 245, 245, 245, 245, 245, 245, 246,
- nil, nil, nil, 247, 246, 246, 246, 246, 246, 246,
- 246, 246, nil, nil, nil, nil, 248, nil, nil, nil,
- nil, nil, nil, nil, 245, 245, 245, 245, 245, nil,
- nil, nil, nil, nil, nil, nil, nil, 246, 246, 246,
- 246, 246, 247, nil, nil, nil, nil, 247, 247, 247,
- 247, 247, 247, 247, 247, 248, nil, nil, nil, 249,
- 248, 248, 248, 248, 248, 248, 248, 248, nil, nil,
- nil, nil, 250, nil, nil, nil, nil, nil, nil, nil,
- 247, 247, 247, 247, 247, nil, nil, nil, nil, nil,
- nil, nil, nil, 248, 248, 248, 248, 248, 249, nil,
- nil, nil, nil, 249, 249, 249, 249, 249, 249, 249,
- 249, 250, nil, nil, nil, 251, 250, 250, 250, 250,
- 250, 250, 250, 250, nil, nil, nil, nil, 252, nil,
- nil, nil, nil, nil, nil, nil, 249, 249, 249, 249,
- 249, nil, nil, nil, nil, nil, nil, nil, nil, 250,
- 250, 250, 250, 250, 251, nil, nil, nil, nil, 251,
- 251, 251, 251, 251, 251, 251, 251, 252, nil, nil,
- nil, 253, 252, 252, 252, 252, 252, 252, 252, 252,
- nil, nil, nil, nil, 254, nil, nil, nil, nil, nil,
- nil, nil, 251, 251, 251, 251, 251, nil, nil, nil,
- nil, nil, nil, nil, nil, 252, 252, 252, 252, 252,
- 253, nil, nil, nil, nil, 253, 253, 253, 253, 253,
- 253, 253, 253, 254, nil, nil, nil, 255, 254, 254,
- 254, 254, 254, 254, 254, 254, nil, nil, nil, nil,
- 256, nil, nil, nil, nil, nil, nil, nil, 253, 253,
- 253, 253, 253, nil, nil, nil, nil, nil, nil, nil,
- nil, 254, 254, 254, 254, 254, 255, nil, nil, nil,
- nil, 255, 255, 255, 255, 255, 255, 255, 255, 256,
- nil, nil, nil, 262, 256, 256, 256, 256, 256, 256,
- 256, 256, nil, nil, nil, nil, 266, nil, nil, nil,
- nil, nil, nil, nil, 255, 255, 255, 255, 255, nil,
- nil, nil, nil, nil, nil, nil, nil, 256, 256, 256,
- 256, 256, 262, nil, nil, nil, nil, 262, 262, 262,
- 262, 262, 262, 262, 262, 266, nil, nil, nil, nil,
- 266, 266, 266, 266, 266, 266, 266, 266, 269, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 262, 262, 262, 262, 262, 281, nil, nil, nil, nil,
- nil, nil, nil, 266, 266, 266, 266, 266, nil, nil,
- nil, 269, 269, 269, nil, nil, nil, 269, nil, nil,
- nil, nil, 269, 269, 269, 269, 269, 269, 269, 269,
- nil, nil, nil, 281, 281, nil, nil, nil, 285, 281,
- 281, 281, 281, 281, 281, 281, 281, nil, nil, nil,
- nil, nil, 365, nil, nil, 269, 269, 269, 269, 269,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 281, 281, 281, 281, 281, 285, nil, nil,
- nil, nil, 285, 285, 285, 285, 285, 285, 285, 285,
- 365, 365, nil, nil, nil, 378, 365, 365, 365, 365,
- 365, 365, 365, 365, nil, nil, nil, nil, 381, 381,
- nil, nil, nil, nil, nil, 285, 285, 285, 285, 285,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 365,
- 365, 365, 365, 365, 378, nil, nil, nil, nil, 378,
- 378, 378, 378, 378, 378, 378, 378, 381, nil, nil,
- nil, nil, 381, 381, 381, 381, 381, 381, 381, 381,
- 383, 383, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 378, 378, 378, 378, 378, nil, nil, nil,
- nil, nil, nil, nil, nil, 381, 381, 381, 381, 381,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 383,
- nil, nil, nil, nil, 383, 383, 383, 383, 383, 383,
- 383, 383, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 388, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 383, 383, 383,
- 383, 383, 388, 388, 388, 388, 388, 388, 388, 388,
- 388, 388, 388, 388, 388, 388, 388, 388, 388, 388,
- nil, nil, nil, 388, nil, 388, nil, 391, 388, 388,
- 388, 388, 388, 388, 388, 388, nil, nil, nil, nil,
- 412, 412, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 388, 388, 388, 388, 388, 391, nil, nil, nil,
- nil, 391, 391, 391, 391, 391, 391, 391, 391, 412,
- nil, nil, nil, nil, 412, 412, 412, 412, 412, 412,
- 412, 412, 413, 413, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 391, 391, 391, 391, 391, 416,
- 416, nil, nil, nil, nil, nil, nil, 412, 412, 412,
- 412, 412, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 413, nil, nil, nil, nil, 413, 413, 413, 413,
- 413, 413, 413, 413, nil, nil, nil, nil, 416, nil,
- nil, nil, nil, 416, 416, 416, 416, 416, 416, 416,
- 416, 428, 428, nil, nil, nil, nil, nil, nil, 413,
- 413, 413, 413, 413, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 416, 416, 416, 416,
- 416, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 428, nil, nil, nil, nil, 428, 428, 428, 428, 428,
- 428, 428, 428, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 277, 277, nil, nil, nil, nil, nil, nil, 428, 428,
- 428, 428, 428, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 72, 277,
- nil, 277, nil, nil, nil, nil, nil, nil, nil, nil,
- 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
- 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
- 72, 72, 72, 72, nil, nil, nil, 277, 72, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 1, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 72, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 41,
- nil, nil, nil, 1, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
- 62, nil, nil, nil, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 62, 62, 62,
- 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
- 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
- 62, 78, nil, nil, nil, 62, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 78, 78, 78, 78, 78, 78, 78, 78,
- 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
- 172, nil, nil, nil, nil, 78, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 172, 172, 172, 172, 172, 172, 172, 172, 172,
- 172, 172, 172, 172, 172, 172, 172, 172, 172, 181,
- nil, nil, nil, nil, 172, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
- 181, 181, 181, 181, 181, 181, 181, 181, 312, 312,
- nil, nil, nil, 181, nil, nil, nil, nil, nil, nil,
- nil, 312, 312, 312, 312, 312, 312, 312, 312, 312,
- 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
- 312, 312, 312, 312, 312, 312, 366, 312, nil, 312,
- nil, nil, nil, nil, nil, nil, nil, nil, 366, 366,
- 366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
- 366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
- 366, 366, nil, nil, nil, nil, 366, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, nil, nil, nil, nil, 0, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- nil, nil, nil, nil, 6, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, nil,
- nil, nil, nil, 7, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, nil, nil,
- nil, nil, 8, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, nil, nil, nil,
- nil, 9, 275, 275, 275, 275, 275, 275, 275, 275,
- 275, 275, 275, 275, 275, 275, 275, 275, 275, 275,
- 275, 275, 275, 275, 275, 275, nil, nil, nil, 275,
- 275, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, nil,
- nil, nil, nil, nil, 56, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, nil, nil, nil, nil, nil, 77, 81,
- 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 81, nil, nil, nil,
- nil, nil, 81, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
- 82, nil, nil, nil, nil, nil, 82, 83, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, nil, nil, nil, nil, nil,
- 83 ]
-
-racc_action_pointer = [
- 4005, 3703, nil, nil, nil, 295, 4034, 4063, 4092, 4121,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 126, nil, nil, 161, nil, nil, nil, nil, nil, 8,
- nil, 3744, 160, nil, nil, 9, 34, nil, 159, 354,
- nil, nil, nil, nil, nil, 12, 4174, 55, 57, -20,
- 129, nil, 3785, nil, nil, -3, 353, 1318, nil, 411,
- 59, 2026, 3638, 127, 366, nil, nil, 4198, 3825, nil,
- 179, 4222, 4246, 4270, 104, 52, nil, 171, nil, 157,
- nil, nil, nil, nil, nil, nil, nil, nil, 248, 2039,
- 250, 279, 85, nil, nil, nil, nil, 163, nil, 275,
- 277, 294, 143, 299, 20, 332, 348, 1795, nil, 267,
- 1389, nil, 1333, 2082, 2095, 2138, 2151, nil, nil, nil,
- nil, nil, nil, 216, nil, 15, 24, 123, 350, 156,
- 305, 293, 314, 340, 205, nil, nil, nil, nil, nil,
- nil, 398, nil, nil, 1404, nil, nil, 2205, 377, nil,
- 2224, 410, 448, 51, nil, 440, nil, 469, nil, nil,
- nil, nil, 3864, nil, nil, 175, nil, 468, 2248, nil,
- nil, 3903, 58, nil, 63, 2267, 59, 201, 469, nil,
- nil, 259, 317, nil, nil, nil, 2291, 2310, 2334, 2353,
- 470, 460, 1864, 467, 468, nil, nil, 216, nil, nil,
- -2, 224, 466, 467, 2377, 2441, 393, 394, nil, nil,
- 1475, nil, nil, nil, 1539, nil, 2484, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 2497, 2540,
- 2553, 2596, 2609, 2652, 2665, 2708, 2721, 2764, 2777, 2820,
- 2833, 2876, 2889, 2932, 2945, 2988, 3001, 157, 1595, nil,
- 143, nil, 3044, 396, 437, nil, 3057, 438, nil, 3109,
- 454, nil, nil, nil, 416, 4150, 50, 3601, nil, nil,
- 123, 3126, nil, nil, 237, 3169, nil, nil, nil, 67,
- nil, nil, nil, nil, 68, nil, 375, nil, nil, nil,
- 317, 318, 330, 502, 228, 1918, 1931, nil, nil, nil,
- nil, 175, 3939, nil, nil, 1608, 28, 331, nil, nil,
- nil, nil, nil, nil, 502, 503, nil, nil, nil, nil,
- 117, 180, 248, 253, 336, 348, 358, 363, 388, 401,
- 374, 458, 445, 446, 451, 47, nil, 1664, nil, nil,
- nil, 478, nil, nil, 479, nil, 480, nil, nil, nil,
- nil, 176, 518, 519, nil, 3183, 3976, 483, nil, 484,
- nil, nil, nil, nil, nil, 433, 491, 549, 3226, 1974,
- 233, 3239, 262, 3291, 1681, nil, nil, nil, 3355, 527,
- 528, 3398, nil, 1737, nil, nil, nil, nil, nil, nil,
- 487, nil, 488, 526, nil, nil, nil, 526, nil, nil,
- 332, 263, 3411, 3463, 334, 607, 3480, 343, 665, 218,
- nil, nil, nil, nil, nil, nil, 723, 531, 3532, 346,
- 781, 348, 839, 897, nil, 349, 955, 1013, nil, 1752,
- nil, nil, nil, 375, 1071, 1129, nil, 1187, nil, nil,
- 1245, nil, nil, nil, 1303, nil, nil, nil, nil, nil ]
-
-racc_action_default = [
- -265, -265, -1, -3, -4, -265, -53, -55, -57, -59,
- -64, -65, -66, -67, -68, -69, -70, -71, -72, -73,
- -74, -75, -76, -77, -78, -79, -80, -81, -82, -83,
- -265, -89, -90, -265, -115, -116, -117, -118, -166, -265,
- -2, -62, -265, -51, -60, -265, -120, -121, -265, -136,
- -258, -52, -54, -56, -58, -86, -265, -88, -107, -265,
- -110, 460, -265, -6, -7, -265, -265, -265, -50, -265,
- -119, -265, -265, -265, -135, -138, -139, -265, -265, -91,
- -265, -95, -97, -265, -265, -265, -111, -113, -262, -265,
- -5, -8, -9, -10, -11, -12, -13, -14, -179, -265,
- -265, -83, -265, -20, -21, -23, -24, -265, -26, -265,
- -265, -265, -265, -265, -265, -265, -265, -265, -180, -181,
- -265, -184, -198, -265, -265, -265, -265, -204, -205, -206,
- -207, -208, -209, -210, -212, -216, -219, -222, -227, -230,
- -232, -234, -236, -238, -240, -242, -255, -259, -260, -261,
- -264, -62, -63, -167, -265, -179, -61, -265, -265, -126,
- -265, -205, -265, -265, -134, -141, -143, -147, -148, -122,
- -137, -140, -265, -85, -92, -265, -98, -100, -265, -94,
- -96, -265, -265, -104, -265, -265, -265, -265, -265, -210,
- -257, -265, -265, -19, -22, -25, -265, -265, -265, -265,
- -265, -265, -265, -265, -265, -45, -46, -265, -48, -263,
- -151, -265, -265, -265, -265, -265, -265, -265, -190, -191,
- -265, -199, -200, -201, -265, -202, -265, -244, -245, -246,
- -247, -248, -249, -250, -251, -252, -253, -254, -265, -265,
- -265, -265, -265, -265, -265, -265, -265, -265, -265, -265,
- -265, -265, -265, -265, -265, -265, -265, -265, -265, -171,
- -265, -175, -265, -265, -265, -124, -265, -205, -125, -265,
- -265, -131, -132, -133, -265, -265, -152, -265, -145, -146,
- -154, -265, -84, -93, -265, -265, -102, -87, -103, -265,
- -106, -112, -114, -108, -265, -15, -265, -17, -18, -256,
- -265, -265, -265, -265, -265, -265, -265, -44, -49, -47,
- -150, -152, -265, -182, -183, -265, -265, -265, -187, -194,
- -196, -197, -188, -189, -265, -265, -243, -213, -214, -215,
- -217, -218, -220, -221, -223, -224, -225, -226, -228, -229,
- -231, -233, -235, -237, -239, -265, -168, -265, -170, -174,
- -176, -265, -178, -123, -265, -130, -265, -128, -149, -142,
- -144, -153, -265, -265, -165, -265, -265, -265, -159, -205,
- -99, -101, -105, -109, -16, -265, -265, -265, -265, -265,
- -265, -265, -265, -265, -265, -211, -185, -186, -265, -265,
- -203, -265, -169, -265, -173, -177, -129, -127, -155, -164,
- -265, -157, -205, -265, -163, -158, -161, -27, -29, -30,
- -265, -265, -265, -265, -265, -265, -265, -265, -265, -265,
- -195, -241, -172, -156, -160, -162, -265, -265, -265, -265,
- -265, -265, -265, -265, -39, -265, -265, -265, -43, -265,
- -192, -28, -31, -265, -265, -265, -35, -265, -37, -38,
- -265, -41, -42, -193, -265, -33, -34, -36, -40, -32 ]
-
-racc_goto_table = [
- 47, 152, 57, 162, 75, 60, 70, 319, 153, 5,
- 5, 257, 158, 176, 174, 51, 52, 53, 54, 76,
- 393, 291, 279, 361, 74, 55, 82, 1, 58, 170,
- 62, 104, 179, 180, 190, 223, 63, 101, 102, 41,
- 47, 76, 188, 47, 171, 64, 157, 82, 82, 78,
- 156, 82, 82, 82, 213, 85, 175, 90, 361, 163,
- 98, 47, 2, 40, 47, 310, 91, 168, 194, 105,
- 172, 210, 330, 331, 101, 47, 181, 332, 333, 360,
- 182, 167, 338, 339, 200, 186, 204, 350, 317, 340,
- 82, 334, 335, 336, 337, 153, 341, 98, 264, 342,
- 151, 270, 343, 151, 344, 226, 105, 98, 174, 203,
- nil, nil, 393, 190, 177, 212, nil, 174, nil, 81,
- 190, 286, 276, nil, nil, nil, 291, 171, 292, nil,
- 76, 291, nil, nil, nil, 269, nil, 299, nil, nil,
- 81, 81, 82, nil, 81, 81, 81, nil, 327, 328,
- 329, 82, nil, nil, 324, nil, 320, nil, 325, 200,
- nil, nil, 47, 200, 200, 311, 210, 326, nil, nil,
- 201, 210, nil, nil, nil, 210, nil, nil, nil, nil,
- 420, nil, 98, 81, nil, 82, 98, 98, nil, nil,
- 82, nil, 348, nil, 82, nil, nil, 190, nil, 153,
- nil, 278, nil, nil, nil, 351, 306, 354, nil, nil,
- 356, 322, 323, nil, nil, 212, nil, 370, nil, 212,
- 190, nil, 367, nil, nil, 385, nil, nil, 371, nil,
- nil, nil, 276, nil, nil, 81, nil, 70, nil, 171,
- nil, 419, nil, nil, 81, 295, nil, nil, nil, 297,
- 298, nil, nil, nil, nil, nil, nil, nil, 352, nil,
- nil, nil, nil, nil, nil, nil, nil, 311, 200, 358,
- nil, 47, 47, nil, nil, nil, nil, nil, 81, 47,
- nil, 394, nil, 81, 167, nil, 167, 81, 153, nil,
- nil, 98, nil, nil, nil, nil, nil, 403, nil, nil,
- nil, nil, nil, nil, 207, nil, 400, 211, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 177, nil,
- nil, 167, nil, nil, nil, 153, 421, 422, nil, 320,
- nil, nil, nil, nil, 153, nil, nil, nil, nil, 210,
- nil, nil, nil, nil, nil, nil, nil, 200, 200, 200,
- nil, nil, nil, nil, 374, nil, nil, nil, 82, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 98, 98, 98, 394, nil, 167, nil, nil, nil, nil,
- 153, nil, nil, nil, 300, 301, 302, 200, nil, 304,
- 200, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 316, 200, nil, 200, 200, nil, 211, 200, 200,
- 98, 211, nil, 98, nil, nil, 200, 200, nil, 200,
- nil, 98, 200, nil, nil, 98, 200, 98, 98, nil,
- nil, 98, 98, 407, 408, 409, nil, nil, 189, 98,
- 98, nil, 98, 345, nil, 98, nil, nil, nil, 98,
- nil, 81, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 221, 222, 189, 225, nil, nil, nil, nil,
- nil, nil, nil, 434, nil, nil, 438, nil, nil, nil,
- nil, nil, nil, nil, 441, nil, nil, nil, 446, nil,
- 448, 449, 380, 382, 451, 452, nil, nil, nil, nil,
- nil, nil, 455, 456, nil, 457, nil, nil, 458, nil,
- nil, nil, 459, nil, nil, nil, nil, 189, nil, nil,
- nil, nil, nil, nil, 189, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 410, 411, nil, 414, nil,
- 417, nil, nil, nil, nil, nil, nil, 189, 189, 189,
- 189, 189, 189, 189, 189, 189, 189, 189, 189, 189,
- 189, 189, 189, 189, 189, nil, nil, nil, nil, 429,
- 431, 189, nil, 435, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 443, nil, nil, nil, nil,
- nil, nil, nil, nil, 189, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 189, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 189 ]
-
-racc_goto_check = [
- 15, 27, 17, 43, 39, 17, 40, 59, 42, 5,
- 5, 50, 42, 35, 32, 5, 5, 5, 5, 24,
- 51, 37, 47, 49, 41, 15, 24, 1, 15, 39,
- 7, 19, 33, 33, 73, 62, 8, 17, 18, 6,
- 15, 24, 16, 15, 24, 4, 41, 24, 24, 31,
- 26, 24, 24, 24, 48, 36, 34, 8, 49, 44,
- 15, 15, 2, 2, 15, 47, 4, 15, 19, 4,
- 31, 33, 63, 63, 17, 15, 31, 64, 64, 46,
- 36, 5, 66, 66, 17, 36, 17, 53, 58, 67,
- 24, 65, 65, 65, 65, 42, 68, 15, 42, 69,
- 6, 42, 70, 6, 71, 74, 4, 15, 32, 15,
- nil, nil, 51, 73, 6, 8, nil, 32, nil, 23,
- 73, 16, 39, nil, nil, nil, 37, 24, 16, nil,
- 24, 37, nil, nil, nil, 41, nil, 42, nil, nil,
- 23, 23, 24, nil, 23, 23, 23, nil, 62, 62,
- 62, 24, nil, nil, 48, nil, 42, nil, 48, 17,
- nil, nil, 15, 17, 17, 39, 33, 42, nil, nil,
- 9, 33, nil, nil, nil, 33, nil, nil, nil, nil,
- 59, nil, 15, 23, nil, 24, 15, 15, nil, nil,
- 24, nil, 27, nil, 24, nil, nil, 73, nil, 42,
- nil, 6, nil, nil, nil, 16, 4, 42, nil, nil,
- 42, 15, 15, nil, nil, 8, nil, 35, nil, 8,
- 73, nil, 42, nil, nil, 62, nil, nil, 16, nil,
- nil, nil, 39, nil, nil, 23, nil, 40, nil, 24,
- nil, 50, nil, nil, 23, 9, nil, nil, nil, 9,
- 9, nil, nil, nil, nil, nil, nil, nil, 15, nil,
- nil, nil, nil, nil, nil, nil, nil, 39, 17, 15,
- nil, 15, 15, nil, nil, nil, nil, nil, 23, 15,
- nil, 27, nil, 23, 5, nil, 5, 23, 42, nil,
- nil, 15, nil, nil, nil, nil, nil, 43, nil, nil,
- nil, nil, nil, nil, 20, nil, 42, 20, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 6, nil,
- nil, 5, nil, nil, nil, 42, 73, 27, nil, 42,
- nil, nil, nil, nil, 42, nil, nil, nil, nil, 33,
- nil, nil, nil, nil, nil, nil, nil, 17, 17, 17,
- nil, nil, nil, nil, 9, nil, nil, nil, 24, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 15, 15, 15, 27, nil, 5, nil, nil, nil, nil,
- 42, nil, nil, nil, 20, 20, 20, 17, nil, 20,
- 17, nil, nil, nil, nil, nil, nil, nil, 17, nil,
- nil, 20, 17, nil, 17, 17, nil, 20, 17, 17,
- 15, 20, nil, 15, nil, nil, 17, 17, nil, 17,
- nil, 15, 17, nil, nil, 15, 17, 15, 15, nil,
- nil, 15, 15, 9, 9, 9, nil, nil, 60, 15,
- 15, nil, 15, 20, nil, 15, nil, nil, nil, 15,
- nil, 23, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 60, 60, 60, 60, nil, nil, nil, nil,
- nil, nil, nil, 9, nil, nil, 9, nil, nil, nil,
- nil, nil, nil, nil, 9, nil, nil, nil, 9, nil,
- 9, 9, 20, 20, 9, 9, nil, nil, nil, nil,
- nil, nil, 9, 9, nil, 9, nil, nil, 9, nil,
- nil, nil, 9, nil, nil, nil, nil, 60, nil, nil,
- nil, nil, nil, nil, 60, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 20, 20, nil, 20, nil,
- 20, nil, nil, nil, nil, nil, nil, 60, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, nil, nil, nil, nil, 20,
- 20, 60, nil, 20, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 20, nil, nil, nil, nil,
- nil, nil, nil, nil, 60, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 60, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 60 ]
-
-racc_goto_pointer = [
- nil, 27, 62, nil, 4, 9, 34, -11, -5, 58,
- nil, nil, nil, nil, nil, -5, -57, -28, -27, -34,
- 187, nil, nil, 63, -30, nil, -19, -66, nil, nil,
- nil, -7, -64, -49, -24, -67, -4, -163, nil, -45,
- -39, -25, -59, -69, -13, nil, -196, -145, -66, -253,
- -143, -327, nil, -173, nil, nil, nil, nil, -127, -208,
- 339, nil, -90, -169, -166, -154, -167, -162, -156, -154,
- -152, -151, nil, -65, -28 ]
-
-racc_goto_default = [
- nil, nil, nil, 3, 4, 66, 73, nil, 93, 106,
- 92, 94, 95, 96, 97, 155, nil, 29, nil, nil,
- 107, 42, 6, 7, 8, 9, 44, 259, 27, 28,
- 30, nil, 79, 80, nil, nil, nil, 86, 87, 45,
- 46, nil, 146, 363, nil, 165, 166, 362, 321, 280,
- nil, 258, 260, 261, 121, 118, 119, 122, nil, nil,
- 133, 125, 134, 135, 136, 137, 138, 139, 140, 141,
- 142, 143, 144, 145, nil ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 92, :_reduce_1,
- 2, 92, :_reduce_2,
- 1, 93, :_reduce_3,
- 1, 93, :_reduce_4,
- 4, 94, :_reduce_5,
- 3, 94, :_reduce_6,
- 1, 98, :_reduce_7,
- 2, 98, :_reduce_8,
- 1, 100, :_reduce_9,
- 1, 100, :_reduce_10,
- 1, 100, :_reduce_11,
- 1, 100, :_reduce_12,
- 1, 100, :_reduce_13,
- 1, 100, :_reduce_14,
- 3, 101, :_reduce_15,
- 4, 101, :_reduce_16,
- 3, 101, :_reduce_17,
- 3, 101, :_reduce_18,
- 3, 99, :_reduce_19,
- 2, 99, :_reduce_20,
- 1, 109, :_reduce_21,
- 2, 109, :_reduce_22,
- 1, 110, :_reduce_23,
- 1, 110, :_reduce_24,
- 2, 102, :_reduce_25,
- 1, 102, :_reduce_26,
- 5, 103, :_reduce_27,
- 7, 103, :_reduce_28,
- 5, 103, :_reduce_29,
- 5, 104, :_reduce_30,
- 7, 104, :_reduce_31,
- 9, 104, :_reduce_32,
- 8, 104, :_reduce_33,
- 8, 104, :_reduce_34,
- 7, 104, :_reduce_35,
- 8, 104, :_reduce_36,
- 7, 104, :_reduce_37,
- 7, 104, :_reduce_38,
- 6, 104, :_reduce_39,
- 8, 104, :_reduce_40,
- 7, 104, :_reduce_41,
- 7, 104, :_reduce_42,
- 6, 104, :_reduce_43,
- 3, 105, :_reduce_44,
- 2, 105, :_reduce_45,
- 2, 105, :_reduce_46,
- 3, 105, :_reduce_47,
- 2, 105, :_reduce_48,
- 3, 105, :_reduce_49,
- 3, 95, :_reduce_50,
- 2, 95, :_reduce_51,
- 2, 96, :_reduce_52,
- 1, 96, :_reduce_53,
- 2, 96, :_reduce_54,
- 1, 96, :_reduce_55,
- 2, 96, :_reduce_56,
- 1, 96, :_reduce_57,
- 2, 96, :_reduce_58,
- 1, 96, :_reduce_59,
- 1, 112, :_reduce_60,
- 3, 112, :_reduce_61,
- 1, 117, :_reduce_62,
- 3, 117, :_reduce_63,
- 1, 113, :_reduce_64,
- 1, 113, :_reduce_65,
- 1, 113, :_reduce_66,
- 1, 113, :_reduce_67,
- 1, 113, :_reduce_68,
- 1, 114, :_reduce_69,
- 1, 114, :_reduce_70,
- 1, 114, :_reduce_71,
- 1, 114, :_reduce_72,
- 1, 114, :_reduce_73,
- 1, 114, :_reduce_74,
- 1, 114, :_reduce_75,
- 1, 114, :_reduce_76,
- 1, 114, :_reduce_77,
- 1, 114, :_reduce_78,
- 1, 114, :_reduce_79,
- 1, 114, :_reduce_80,
- 1, 114, :_reduce_81,
- 1, 114, :_reduce_82,
- 1, 114, :_reduce_83,
- 5, 119, :_reduce_84,
- 4, 119, :_reduce_85,
- 2, 119, :_reduce_86,
- 5, 119, :_reduce_87,
- 2, 119, :_reduce_88,
- 1, 121, :_reduce_89,
- 1, 121, :_reduce_90,
- 1, 122, :_reduce_91,
- 2, 122, :_reduce_92,
- 3, 123, :_reduce_93,
- 2, 124, :_reduce_94,
- 1, 124, :_reduce_95,
- 2, 124, :_reduce_96,
- 1, 124, :_reduce_97,
- 1, 125, :_reduce_98,
- 3, 125, :_reduce_99,
- 1, 126, :_reduce_100,
- 3, 126, :_reduce_101,
- 2, 126, :_reduce_102,
- 5, 120, :_reduce_103,
- 4, 120, :_reduce_104,
- 6, 120, :_reduce_105,
- 5, 120, :_reduce_106,
- 2, 120, :_reduce_107,
- 5, 120, :_reduce_108,
- 6, 120, :_reduce_109,
- 2, 120, :_reduce_110,
- 1, 127, :_reduce_111,
- 3, 127, :_reduce_112,
- 1, 128, :_reduce_113,
- 3, 128, :_reduce_114,
- 1, 115, :_reduce_115,
- 1, 115, :_reduce_116,
- 1, 115, :_reduce_117,
- 1, 116, :_reduce_118,
- 2, 97, :_reduce_119,
- 1, 97, :_reduce_120,
- 1, 131, :_reduce_121,
- 3, 131, :_reduce_122,
- 5, 131, :_reduce_123,
- 4, 131, :_reduce_124,
- 4, 131, :_reduce_125,
- 3, 131, :_reduce_126,
- 6, 131, :_reduce_127,
- 5, 131, :_reduce_128,
- 6, 131, :_reduce_129,
- 5, 131, :_reduce_130,
- 4, 131, :_reduce_131,
- 4, 131, :_reduce_132,
- 4, 131, :_reduce_133,
- 3, 131, :_reduce_134,
- 2, 130, :_reduce_135,
- 1, 130, :_reduce_136,
- 3, 130, :_reduce_137,
- 2, 130, :_reduce_138,
- 1, 132, :_reduce_139,
- 2, 132, :_reduce_140,
- 1, 134, :_reduce_141,
- 3, 134, :_reduce_142,
- 1, 136, :_reduce_143,
- 3, 136, :_reduce_144,
- 2, 137, :_reduce_145,
- 2, 137, :_reduce_146,
- 1, 137, :_reduce_147,
- 1, 135, :_reduce_148,
- 3, 135, :_reduce_149,
- 2, 139, :_reduce_150,
- 1, 139, :_reduce_151,
- 1, 138, :_reduce_152,
- 2, 138, :_reduce_153,
- 1, 138, :_reduce_154,
- 3, 140, :_reduce_155,
- 4, 140, :_reduce_156,
- 3, 140, :_reduce_157,
- 3, 140, :_reduce_158,
- 2, 140, :_reduce_159,
- 4, 140, :_reduce_160,
- 3, 140, :_reduce_161,
- 4, 140, :_reduce_162,
- 3, 140, :_reduce_163,
- 3, 140, :_reduce_164,
- 2, 140, :_reduce_165,
- 1, 108, :_reduce_166,
- 1, 118, :_reduce_167,
- 3, 118, :_reduce_168,
- 4, 118, :_reduce_169,
- 2, 141, :_reduce_170,
- 1, 141, :_reduce_171,
- 4, 141, :_reduce_172,
- 3, 141, :_reduce_173,
- 2, 142, :_reduce_174,
- 1, 143, :_reduce_175,
- 2, 143, :_reduce_176,
- 3, 144, :_reduce_177,
- 2, 144, :_reduce_178,
- 1, 145, :_reduce_179,
- 1, 145, :_reduce_180,
- 1, 145, :_reduce_181,
- 3, 145, :_reduce_182,
- 3, 145, :_reduce_183,
- 1, 148, :_reduce_184,
- 4, 148, :_reduce_185,
- 4, 148, :_reduce_186,
- 3, 148, :_reduce_187,
- 3, 148, :_reduce_188,
- 3, 148, :_reduce_189,
- 2, 148, :_reduce_190,
- 2, 148, :_reduce_191,
- 6, 148, :_reduce_192,
- 7, 148, :_reduce_193,
- 1, 149, :_reduce_194,
- 3, 149, :_reduce_195,
- 1, 150, :_reduce_196,
- 1, 150, :_reduce_197,
- 1, 151, :_reduce_198,
- 2, 151, :_reduce_199,
- 2, 151, :_reduce_200,
- 2, 151, :_reduce_201,
- 2, 151, :_reduce_202,
- 4, 151, :_reduce_203,
- 1, 152, :_reduce_204,
- 1, 152, :_reduce_205,
- 1, 152, :_reduce_206,
- 1, 152, :_reduce_207,
- 1, 152, :_reduce_208,
- 1, 152, :_reduce_209,
- 1, 153, :_reduce_210,
- 4, 153, :_reduce_211,
- 1, 154, :_reduce_212,
- 3, 154, :_reduce_213,
- 3, 154, :_reduce_214,
- 3, 154, :_reduce_215,
- 1, 155, :_reduce_216,
- 3, 155, :_reduce_217,
- 3, 155, :_reduce_218,
- 1, 156, :_reduce_219,
- 3, 156, :_reduce_220,
- 3, 156, :_reduce_221,
- 1, 157, :_reduce_222,
- 3, 157, :_reduce_223,
- 3, 157, :_reduce_224,
- 3, 157, :_reduce_225,
- 3, 157, :_reduce_226,
- 1, 158, :_reduce_227,
- 3, 158, :_reduce_228,
- 3, 158, :_reduce_229,
- 1, 159, :_reduce_230,
- 3, 159, :_reduce_231,
- 1, 160, :_reduce_232,
- 3, 160, :_reduce_233,
- 1, 161, :_reduce_234,
- 3, 161, :_reduce_235,
- 1, 162, :_reduce_236,
- 3, 162, :_reduce_237,
- 1, 163, :_reduce_238,
- 3, 163, :_reduce_239,
- 1, 164, :_reduce_240,
- 5, 164, :_reduce_241,
- 1, 133, :_reduce_242,
- 3, 133, :_reduce_243,
- 1, 165, :_reduce_244,
- 1, 165, :_reduce_245,
- 1, 165, :_reduce_246,
- 1, 165, :_reduce_247,
- 1, 165, :_reduce_248,
- 1, 165, :_reduce_249,
- 1, 165, :_reduce_250,
- 1, 165, :_reduce_251,
- 1, 165, :_reduce_252,
- 1, 165, :_reduce_253,
- 1, 165, :_reduce_254,
- 1, 111, :_reduce_255,
- 3, 111, :_reduce_256,
- 1, 107, :_reduce_257,
- 1, 106, :_reduce_258,
- 1, 146, :_reduce_259,
- 1, 146, :_reduce_260,
- 1, 146, :_reduce_261,
- 1, 129, :_reduce_262,
- 2, 147, :_reduce_263,
- 1, 147, :_reduce_264 ]
-
-racc_reduce_n = 265
-
-racc_shift_n = 460
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :COLON => 2,
- :CASE => 3,
- :DEFAULT => 4,
- :LBRACE => 5,
- :RBRACE => 6,
- :SEMICOLON => 7,
- :IF => 8,
- :LPAREN => 9,
- :RPAREN => 10,
- :ELSE => 11,
- :SWITCH => 12,
- :WHILE => 13,
- :DO => 14,
- :FOR => 15,
- :GOTO => 16,
- :CONTINUE => 17,
- :BREAK => 18,
- :RETURN => 19,
- :COMMA => 20,
- :EQ => 21,
- :TYPEDEF => 22,
- :EXTERN => 23,
- :STATIC => 24,
- :AUTO => 25,
- :REGISTER => 26,
- :VOID => 27,
- :CHAR => 28,
- :SHORT => 29,
- :INT => 30,
- :LONG => 31,
- :FLOAT => 32,
- :DOUBLE => 33,
- :SIGNED => 34,
- :UNSIGNED => 35,
- :BOOL => 36,
- :COMPLEX => 37,
- :IMAGINARY => 38,
- :STRUCT => 39,
- :UNION => 40,
- :ENUM => 41,
- :CONST => 42,
- :RESTRICT => 43,
- :VOLATILE => 44,
- :INLINE => 45,
- :LBRACKET => 46,
- :RBRACKET => 47,
- :MUL => 48,
- :ELLIPSIS => 49,
- :TYPENAME => 50,
- :DOT => 51,
- :ARROW => 52,
- :INC => 53,
- :DEC => 54,
- :SIZEOF => 55,
- :AND => 56,
- :ADD => 57,
- :SUB => 58,
- :NOT => 59,
- :BANG => 60,
- :DIV => 61,
- :MOD => 62,
- :LSHIFT => 63,
- :RSHIFT => 64,
- :LT => 65,
- :GT => 66,
- :LEQ => 67,
- :GEQ => 68,
- :EQEQ => 69,
- :NEQ => 70,
- :XOR => 71,
- :OR => 72,
- :ANDAND => 73,
- :OROR => 74,
- :QUESTION => 75,
- :MULEQ => 76,
- :DIVEQ => 77,
- :MODEQ => 78,
- :ADDEQ => 79,
- :SUBEQ => 80,
- :LSHIFTEQ => 81,
- :RSHIFTEQ => 82,
- :ANDEQ => 83,
- :XOREQ => 84,
- :OREQ => 85,
- :ID => 86,
- :ICON => 87,
- :FCON => 88,
- :CCON => 89,
- :SCON => 90 }
-
-racc_nt_base = 91
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "COLON",
- "CASE",
- "DEFAULT",
- "LBRACE",
- "RBRACE",
- "SEMICOLON",
- "IF",
- "LPAREN",
- "RPAREN",
- "ELSE",
- "SWITCH",
- "WHILE",
- "DO",
- "FOR",
- "GOTO",
- "CONTINUE",
- "BREAK",
- "RETURN",
- "COMMA",
- "EQ",
- "TYPEDEF",
- "EXTERN",
- "STATIC",
- "AUTO",
- "REGISTER",
- "VOID",
- "CHAR",
- "SHORT",
- "INT",
- "LONG",
- "FLOAT",
- "DOUBLE",
- "SIGNED",
- "UNSIGNED",
- "BOOL",
- "COMPLEX",
- "IMAGINARY",
- "STRUCT",
- "UNION",
- "ENUM",
- "CONST",
- "RESTRICT",
- "VOLATILE",
- "INLINE",
- "LBRACKET",
- "RBRACKET",
- "MUL",
- "ELLIPSIS",
- "TYPENAME",
- "DOT",
- "ARROW",
- "INC",
- "DEC",
- "SIZEOF",
- "AND",
- "ADD",
- "SUB",
- "NOT",
- "BANG",
- "DIV",
- "MOD",
- "LSHIFT",
- "RSHIFT",
- "LT",
- "GT",
- "LEQ",
- "GEQ",
- "EQEQ",
- "NEQ",
- "XOR",
- "OR",
- "ANDAND",
- "OROR",
- "QUESTION",
- "MULEQ",
- "DIVEQ",
- "MODEQ",
- "ADDEQ",
- "SUBEQ",
- "LSHIFTEQ",
- "RSHIFTEQ",
- "ANDEQ",
- "XOREQ",
- "OREQ",
- "ID",
- "ICON",
- "FCON",
- "CCON",
- "SCON",
- "$start",
- "translation_unit",
- "external_declaration",
- "function_definition",
- "declaration",
- "declaration_specifiers",
- "declarator",
- "declaration_list",
- "compound_statement",
- "statement",
- "labeled_statement",
- "expression_statement",
- "selection_statement",
- "iteration_statement",
- "jump_statement",
- "identifier",
- "constant_expression",
- "typedef_name",
- "block_item_list",
- "block_item",
- "expression",
- "init_declarator_list",
- "storage_class_specifier",
- "type_specifier",
- "type_qualifier",
- "function_specifier",
- "init_declarator",
- "initializer",
- "struct_or_union_specifier",
- "enum_specifier",
- "struct_or_union",
- "struct_declaration_list",
- "struct_declaration",
- "specifier_qualifier_list",
- "struct_declarator_list",
- "struct_declarator",
- "enumerator_list",
- "enumerator",
- "enumeration_constant",
- "pointer",
- "direct_declarator",
- "type_qualifier_list",
- "assignment_expression",
- "parameter_type_list",
- "identifier_list",
- "parameter_list",
- "parameter_declaration",
- "abstract_declarator",
- "type_name",
- "direct_abstract_declarator",
- "initializer_list",
- "designation",
- "designator_list",
- "designator",
- "primary_expression",
- "constant",
- "string_literal",
- "postfix_expression",
- "argument_expression_list",
- "argument_expression",
- "unary_expression",
- "unary_operator",
- "cast_expression",
- "multiplicative_expression",
- "additive_expression",
- "shift_expression",
- "relational_expression",
- "equality_expression",
- "and_expression",
- "exclusive_or_expression",
- "inclusive_or_expression",
- "logical_and_expression",
- "logical_or_expression",
- "conditional_expression",
- "assignment_operator" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'cast.y', 32)
- def _reduce_1(val, _values, result)
- result = TranslationUnit.new_at(val[0].pos, NodeChain[val[0]])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 33)
- def _reduce_2(val, _values, result)
- result = val[0]; result.entities << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 37)
- def _reduce_3(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 38)
- def _reduce_4(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 42)
- def _reduce_5(val, _values, result)
- result = make_function_def(val[0][0], val[0][1], val[1], val[2], val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 43)
- def _reduce_6(val, _values, result)
- result = make_function_def(val[0][0], val[0][1], val[1], nil , val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 47)
- def _reduce_7(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 48)
- def _reduce_8(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 54)
- def _reduce_9(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 55)
- def _reduce_10(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 56)
- def _reduce_11(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 57)
- def _reduce_12(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 58)
- def _reduce_13(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 59)
- def _reduce_14(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 63)
- def _reduce_15(val, _values, result)
- val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].val)); result = val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 64)
- def _reduce_16(val, _values, result)
- val[3].labels.unshift(Case .new_at(val[0].pos, val[1] )); result = val[3]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 65)
- def _reduce_17(val, _values, result)
- val[2].labels.unshift(Default .new_at(val[0].pos )); result = val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 67)
- def _reduce_18(val, _values, result)
- val[2].labels.unshift(PlainLabel.new_at(val[0].pos, val[0].name)); result = val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 71)
- def _reduce_19(val, _values, result)
- result = Block.new_at(val[0].pos, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 72)
- def _reduce_20(val, _values, result)
- result = Block.new_at(val[0].pos )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 76)
- def _reduce_21(val, _values, result)
- result = NodeChain[val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 77)
- def _reduce_22(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 81)
- def _reduce_23(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 82)
- def _reduce_24(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 86)
- def _reduce_25(val, _values, result)
- result = ExpressionStatement.new_at(val[0].pos, val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 87)
- def _reduce_26(val, _values, result)
- result = ExpressionStatement.new_at(val[0].pos )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 91)
- def _reduce_27(val, _values, result)
- result = If .new_at(val[0].pos, val[2], val[4] )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 92)
- def _reduce_28(val, _values, result)
- result = If .new_at(val[0].pos, val[2], val[4], val[6])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 93)
- def _reduce_29(val, _values, result)
- result = Switch.new_at(val[0].pos, val[2], val[4] )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 97)
- def _reduce_30(val, _values, result)
- result = While.new_at(val[0].pos, val[2], val[4] )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 98)
- def _reduce_31(val, _values, result)
- result = While.new_at(val[0].pos, val[4], val[1], :do => true )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 99)
- def _reduce_32(val, _values, result)
- result = For.new_at(val[0].pos, val[2], val[4], val[6], val[8])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 100)
- def _reduce_33(val, _values, result)
- result = For.new_at(val[0].pos, val[2], val[4], nil , val[7])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 101)
- def _reduce_34(val, _values, result)
- result = For.new_at(val[0].pos, val[2], nil , val[5], val[7])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 102)
- def _reduce_35(val, _values, result)
- result = For.new_at(val[0].pos, val[2], nil , nil , val[6])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 103)
- def _reduce_36(val, _values, result)
- result = For.new_at(val[0].pos, nil , val[3], val[5], val[7])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 104)
- def _reduce_37(val, _values, result)
- result = For.new_at(val[0].pos, nil , val[3], nil , val[6])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 105)
- def _reduce_38(val, _values, result)
- result = For.new_at(val[0].pos, nil , nil , val[4], val[6])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 106)
- def _reduce_39(val, _values, result)
- result = For.new_at(val[0].pos, nil , nil , nil , val[5])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 107)
- def _reduce_40(val, _values, result)
- result = For.new_at(val[0].pos, val[2], val[3], val[5], val[7])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 108)
- def _reduce_41(val, _values, result)
- result = For.new_at(val[0].pos, val[2], val[3], nil , val[6])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 109)
- def _reduce_42(val, _values, result)
- result = For.new_at(val[0].pos, val[2], nil , val[4], val[6])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 110)
- def _reduce_43(val, _values, result)
- result = For.new_at(val[0].pos, val[2], nil , nil , val[5])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 114)
- def _reduce_44(val, _values, result)
- result = Goto .new_at(val[0].pos, val[1].val)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 115)
- def _reduce_45(val, _values, result)
- result = Continue.new_at(val[0].pos )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 116)
- def _reduce_46(val, _values, result)
- result = Break .new_at(val[0].pos )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 117)
- def _reduce_47(val, _values, result)
- result = Return .new_at(val[0].pos, val[1] )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 118)
- def _reduce_48(val, _values, result)
- result = Return .new_at(val[0].pos )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 120)
- def _reduce_49(val, _values, result)
- result = Goto .new_at(val[0].pos, val[1].name)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 126)
- def _reduce_50(val, _values, result)
- result = make_declaration(val[0][0], val[0][1], val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 127)
- def _reduce_51(val, _values, result)
- result = make_declaration(val[0][0], val[0][1], NodeArray[])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 131)
- def _reduce_52(val, _values, result)
- val[1][1] << val[0][1]; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 132)
- def _reduce_53(val, _values, result)
- result = [val[0][0], [val[0][1]]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 133)
- def _reduce_54(val, _values, result)
- val[1][1] << val[0][1]; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 134)
- def _reduce_55(val, _values, result)
- result = [val[0][0], [val[0][1]]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 135)
- def _reduce_56(val, _values, result)
- val[1][1] << val[0][1]; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 136)
- def _reduce_57(val, _values, result)
- result = [val[0][0], [val[0][1]]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 137)
- def _reduce_58(val, _values, result)
- val[1][1] << val[0][1]; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 138)
- def _reduce_59(val, _values, result)
- result = [val[0][0], [val[0][1]]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 142)
- def _reduce_60(val, _values, result)
- result = NodeArray[val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 143)
- def _reduce_61(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 147)
- def _reduce_62(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 148)
- def _reduce_63(val, _values, result)
- val[0].init = val[2]; result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 152)
- def _reduce_64(val, _values, result)
- result = [val[0].pos, :typedef ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 153)
- def _reduce_65(val, _values, result)
- result = [val[0].pos, :extern ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 154)
- def _reduce_66(val, _values, result)
- result = [val[0].pos, :static ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 155)
- def _reduce_67(val, _values, result)
- result = [val[0].pos, :auto ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 156)
- def _reduce_68(val, _values, result)
- result = [val[0].pos, :register]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 160)
- def _reduce_69(val, _values, result)
- result = [val[0].pos, :void ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 161)
- def _reduce_70(val, _values, result)
- result = [val[0].pos, :char ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 162)
- def _reduce_71(val, _values, result)
- result = [val[0].pos, :short ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 163)
- def _reduce_72(val, _values, result)
- result = [val[0].pos, :int ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 164)
- def _reduce_73(val, _values, result)
- result = [val[0].pos, :long ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 165)
- def _reduce_74(val, _values, result)
- result = [val[0].pos, :float ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 166)
- def _reduce_75(val, _values, result)
- result = [val[0].pos, :double ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 167)
- def _reduce_76(val, _values, result)
- result = [val[0].pos, :signed ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 168)
- def _reduce_77(val, _values, result)
- result = [val[0].pos, :unsigned ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 169)
- def _reduce_78(val, _values, result)
- result = [val[0].pos, :_Bool ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 170)
- def _reduce_79(val, _values, result)
- result = [val[0].pos, :_Complex ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 171)
- def _reduce_80(val, _values, result)
- result = [val[0].pos, :_Imaginary]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 172)
- def _reduce_81(val, _values, result)
- result = [val[0].pos, val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 173)
- def _reduce_82(val, _values, result)
- result = [val[0].pos, val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 174)
- def _reduce_83(val, _values, result)
- result = [val[0].pos, val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 178)
- def _reduce_84(val, _values, result)
- result = val[0][1].new_at(val[0][0], val[1].val, val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 179)
- def _reduce_85(val, _values, result)
- result = val[0][1].new_at(val[0][0], nil , val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 180)
- def _reduce_86(val, _values, result)
- result = val[0][1].new_at(val[0][0], val[1].val, nil )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 182)
- def _reduce_87(val, _values, result)
- result = val[0][1].new_at(val[0][0], val[1].name, val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 183)
- def _reduce_88(val, _values, result)
- result = val[0][1].new_at(val[0][0], val[1].name, nil )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 187)
- def _reduce_89(val, _values, result)
- result = [val[0].pos, Struct]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 188)
- def _reduce_90(val, _values, result)
- result = [val[0].pos, Union ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 192)
- def _reduce_91(val, _values, result)
- result = NodeArray[val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 193)
- def _reduce_92(val, _values, result)
- val[0] << val[1]; result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 197)
- def _reduce_93(val, _values, result)
- result = make_declaration(val[0][0], val[0][1], val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 201)
- def _reduce_94(val, _values, result)
- val[1][1] << val[0][1]; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 202)
- def _reduce_95(val, _values, result)
- result = [val[0][0], [val[0][1]]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 203)
- def _reduce_96(val, _values, result)
- val[1][1] << val[0][1]; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 204)
- def _reduce_97(val, _values, result)
- result = [val[0][0], [val[0][1]]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 208)
- def _reduce_98(val, _values, result)
- result = NodeArray[val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 209)
- def _reduce_99(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 213)
- def _reduce_100(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 214)
- def _reduce_101(val, _values, result)
- result = val[0]; val[0].num_bits = val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 215)
- def _reduce_102(val, _values, result)
- result = Declarator.new_at(val[0].pos, :num_bits => val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 219)
- def _reduce_103(val, _values, result)
- result = Enum.new_at(val[0].pos, val[1].val, val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 220)
- def _reduce_104(val, _values, result)
- result = Enum.new_at(val[0].pos, nil , val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 221)
- def _reduce_105(val, _values, result)
- result = Enum.new_at(val[0].pos, val[1].val, val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 222)
- def _reduce_106(val, _values, result)
- result = Enum.new_at(val[0].pos, nil , val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 223)
- def _reduce_107(val, _values, result)
- result = Enum.new_at(val[0].pos, val[1].val, nil )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 225)
- def _reduce_108(val, _values, result)
- result = Enum.new_at(val[0].pos, val[1].name, val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 226)
- def _reduce_109(val, _values, result)
- result = Enum.new_at(val[0].pos, val[1].name, val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 227)
- def _reduce_110(val, _values, result)
- result = Enum.new_at(val[0].pos, val[1].name, nil )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 231)
- def _reduce_111(val, _values, result)
- result = NodeArray[val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 232)
- def _reduce_112(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 236)
- def _reduce_113(val, _values, result)
- result = Enumerator.new_at(val[0].pos, val[0].val, nil )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 237)
- def _reduce_114(val, _values, result)
- result = Enumerator.new_at(val[0].pos, val[0].val, val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 241)
- def _reduce_115(val, _values, result)
- result = [val[0].pos, :const ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 242)
- def _reduce_116(val, _values, result)
- result = [val[0].pos, :restrict]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 243)
- def _reduce_117(val, _values, result)
- result = [val[0].pos, :volatile]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 247)
- def _reduce_118(val, _values, result)
- result = [val[0].pos, :inline]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 251)
- def _reduce_119(val, _values, result)
- result = add_decl_type(val[1], val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 252)
- def _reduce_120(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 256)
- def _reduce_121(val, _values, result)
- result = Declarator.new_at(val[0].pos, nil, val[0].val)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 257)
- def _reduce_122(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 258)
- def _reduce_123(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 259)
- def _reduce_124(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 260)
- def _reduce_125(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos, nil, val[2]))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 261)
- def _reduce_126(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 262)
- def _reduce_127(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 263)
- def _reduce_128(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 264)
- def _reduce_129(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 265)
- def _reduce_130(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 266)
- def _reduce_131(val, _values, result)
- result = add_decl_type(val[0], Array.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 267)
- def _reduce_132(val, _values, result)
- result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, param_list(*val[2]), :var_args => val[2][1]))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 268)
- def _reduce_133(val, _values, result)
- result = add_decl_type(val[0], Function.new_at(val[0].pos, nil, val[2]))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 269)
- def _reduce_134(val, _values, result)
- result = add_decl_type(val[0], Function.new_at(val[0].pos ))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 273)
- def _reduce_135(val, _values, result)
- result = add_type_quals(Pointer.new_at(val[0].pos), val[1][1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 274)
- def _reduce_136(val, _values, result)
- result = Pointer.new_at(val[0].pos)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 275)
- def _reduce_137(val, _values, result)
- p = add_type_quals(Pointer.new_at(val[0].pos), val[1][1]); val[2].direct_type = p; result = val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 276)
- def _reduce_138(val, _values, result)
- p = Pointer.new_at(val[0].pos) ; val[1].direct_type = p; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 280)
- def _reduce_139(val, _values, result)
- result = [val[0][0], [val[0][1]]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 281)
- def _reduce_140(val, _values, result)
- val[0][1] << val[1][1]; result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 285)
- def _reduce_141(val, _values, result)
- result = [val[0], false]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 286)
- def _reduce_142(val, _values, result)
- result = [val[0], true ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 290)
- def _reduce_143(val, _values, result)
- result = NodeArray[val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 291)
- def _reduce_144(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 295)
- def _reduce_145(val, _values, result)
- ind_type = val[1].indirect_type and ind_type.detach
- result = make_parameter(val[0][0], val[0][1], ind_type, val[1].name)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 297)
- def _reduce_146(val, _values, result)
- result = make_parameter(val[0][0], val[0][1], val[1] , nil )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 298)
- def _reduce_147(val, _values, result)
- result = make_parameter(val[0][0], val[0][1], nil , nil )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 302)
- def _reduce_148(val, _values, result)
- result = NodeArray[Parameter.new_at(val[0].pos, nil, val[0].val)]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 303)
- def _reduce_149(val, _values, result)
- result = val[0] << Parameter.new_at(val[2].pos, nil, val[2].val)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 307)
- def _reduce_150(val, _values, result)
- val[1].direct_type = make_direct_type(val[0][0], val[0][1]); result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 308)
- def _reduce_151(val, _values, result)
- result = make_direct_type(val[0][0], val[0][1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 312)
- def _reduce_152(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 313)
- def _reduce_153(val, _values, result)
- val[1].direct_type = val[0]; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 314)
- def _reduce_154(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 318)
- def _reduce_155(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 319)
- def _reduce_156(val, _values, result)
- val[0].direct_type = Array.new_at(val[0].pos, nil, val[2]); result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 320)
- def _reduce_157(val, _values, result)
- val[0].direct_type = Array.new_at(val[0].pos, nil, nil ); result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 321)
- def _reduce_158(val, _values, result)
- result = Array.new_at(val[0].pos, nil, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 322)
- def _reduce_159(val, _values, result)
- result = Array.new_at(val[0].pos )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 323)
- def _reduce_160(val, _values, result)
- val[0].direct_type = Array.new_at(val[0].pos); result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 324)
- def _reduce_161(val, _values, result)
- result = Array.new_at(val[0].pos)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 325)
- def _reduce_162(val, _values, result)
- val[0].direct_type = Function.new_at(val[0].pos, nil, param_list(*val[2]), val[2][1]); result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 326)
- def _reduce_163(val, _values, result)
- val[0].direct_type = Function.new_at(val[0].pos ); result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 327)
- def _reduce_164(val, _values, result)
- result = Function.new_at(val[0].pos, nil, param_list(*val[1]), val[1][1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 328)
- def _reduce_165(val, _values, result)
- result = Function.new_at(val[0].pos )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 334)
- def _reduce_166(val, _values, result)
- result = CustomType.new_at(val[0].pos, val[0].val)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 338)
- def _reduce_167(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 339)
- def _reduce_168(val, _values, result)
- result = CompoundLiteral.new_at(val[0].pos, nil, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 340)
- def _reduce_169(val, _values, result)
- result = CompoundLiteral.new_at(val[0].pos, nil, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 344)
- def _reduce_170(val, _values, result)
- result = NodeArray[MemberInit.new_at(val[0][0] , val[0][1], val[1])]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 345)
- def _reduce_171(val, _values, result)
- result = NodeArray[MemberInit.new_at(val[0].pos, nil , val[0])]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 346)
- def _reduce_172(val, _values, result)
- result = val[0] << MemberInit.new_at(val[2][0] , val[2][1], val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 347)
- def _reduce_173(val, _values, result)
- result = val[0] << MemberInit.new_at(val[2].pos, nil , val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 351)
- def _reduce_174(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 355)
- def _reduce_175(val, _values, result)
- result = val[0]; val[0][1] = NodeArray[val[0][1]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 356)
- def _reduce_176(val, _values, result)
- result = val[0]; val[0][1] << val[1][1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 360)
- def _reduce_177(val, _values, result)
- result = [val[1].pos, val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 361)
- def _reduce_178(val, _values, result)
- result = [val[1].pos, Member.new_at(val[1].pos, val[1].val)]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 367)
- def _reduce_179(val, _values, result)
- result = Variable.new_at(val[0].pos, val[0].val)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 368)
- def _reduce_180(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 369)
- def _reduce_181(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 371)
- def _reduce_182(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 372)
- def _reduce_183(val, _values, result)
- block_expressions_enabled? or parse_error val[0].pos, "compound statement found where expression expected"
- result = BlockExpression.new(val[1]); result.pos = val[0].pos
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 377)
- def _reduce_184(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 378)
- def _reduce_185(val, _values, result)
- result = Index .new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 379)
- def _reduce_186(val, _values, result)
- result = Call .new_at(val[0].pos, val[0], val[2] )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 380)
- def _reduce_187(val, _values, result)
- result = Call .new_at(val[0].pos, val[0], NodeArray[])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 381)
- def _reduce_188(val, _values, result)
- result = Dot .new_at(val[0].pos, val[0], Member.new(val[2].val))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 382)
- def _reduce_189(val, _values, result)
- result = Arrow .new_at(val[0].pos, val[0], Member.new(val[2].val))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 383)
- def _reduce_190(val, _values, result)
- result = PostInc .new_at(val[0].pos, val[0] )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 384)
- def _reduce_191(val, _values, result)
- result = PostDec .new_at(val[0].pos, val[0] )
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 385)
- def _reduce_192(val, _values, result)
- result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 386)
- def _reduce_193(val, _values, result)
- result = CompoundLiteral.new_at(val[0].pos, val[1], val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 390)
- def _reduce_194(val, _values, result)
- result = NodeArray[val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 391)
- def _reduce_195(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 395)
- def _reduce_196(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 396)
- def _reduce_197(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 400)
- def _reduce_198(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 401)
- def _reduce_199(val, _values, result)
- result = PreInc.new_at(val[0].pos, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 402)
- def _reduce_200(val, _values, result)
- result = PreDec.new_at(val[0].pos, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 403)
- def _reduce_201(val, _values, result)
- result = val[0][0].new_at(val[0][1], val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 404)
- def _reduce_202(val, _values, result)
- result = Sizeof.new_at(val[0].pos, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 405)
- def _reduce_203(val, _values, result)
- result = Sizeof.new_at(val[0].pos, val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 409)
- def _reduce_204(val, _values, result)
- result = [Address , val[0].pos]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 410)
- def _reduce_205(val, _values, result)
- result = [Dereference, val[0].pos]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 411)
- def _reduce_206(val, _values, result)
- result = [Positive , val[0].pos]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 412)
- def _reduce_207(val, _values, result)
- result = [Negative , val[0].pos]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 413)
- def _reduce_208(val, _values, result)
- result = [BitNot , val[0].pos]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 414)
- def _reduce_209(val, _values, result)
- result = [Not , val[0].pos]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 418)
- def _reduce_210(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 419)
- def _reduce_211(val, _values, result)
- result = Cast.new_at(val[0].pos, val[1], val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 423)
- def _reduce_212(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 424)
- def _reduce_213(val, _values, result)
- result = Multiply.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 425)
- def _reduce_214(val, _values, result)
- result = Divide .new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 426)
- def _reduce_215(val, _values, result)
- result = Mod .new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 430)
- def _reduce_216(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 431)
- def _reduce_217(val, _values, result)
- result = Add .new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 432)
- def _reduce_218(val, _values, result)
- result = Subtract.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 436)
- def _reduce_219(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 437)
- def _reduce_220(val, _values, result)
- result = ShiftLeft .new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 438)
- def _reduce_221(val, _values, result)
- result = ShiftRight.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 442)
- def _reduce_222(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 443)
- def _reduce_223(val, _values, result)
- result = Less.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 444)
- def _reduce_224(val, _values, result)
- result = More.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 445)
- def _reduce_225(val, _values, result)
- result = LessOrEqual.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 446)
- def _reduce_226(val, _values, result)
- result = MoreOrEqual.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 450)
- def _reduce_227(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 451)
- def _reduce_228(val, _values, result)
- result = Equal .new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 452)
- def _reduce_229(val, _values, result)
- result = NotEqual.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 456)
- def _reduce_230(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 457)
- def _reduce_231(val, _values, result)
- result = BitAnd.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 461)
- def _reduce_232(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 462)
- def _reduce_233(val, _values, result)
- result = BitXor.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 466)
- def _reduce_234(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 467)
- def _reduce_235(val, _values, result)
- result = BitOr.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 471)
- def _reduce_236(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 472)
- def _reduce_237(val, _values, result)
- result = And.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 476)
- def _reduce_238(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 477)
- def _reduce_239(val, _values, result)
- result = Or.new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 481)
- def _reduce_240(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 482)
- def _reduce_241(val, _values, result)
- result = Conditional.new_at(val[0].pos, val[0], val[2], val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 486)
- def _reduce_242(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 487)
- def _reduce_243(val, _values, result)
- result = val[1].new_at(val[0].pos, val[0], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 491)
- def _reduce_244(val, _values, result)
- result = Assign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 492)
- def _reduce_245(val, _values, result)
- result = MultiplyAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 493)
- def _reduce_246(val, _values, result)
- result = DivideAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 494)
- def _reduce_247(val, _values, result)
- result = ModAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 495)
- def _reduce_248(val, _values, result)
- result = AddAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 496)
- def _reduce_249(val, _values, result)
- result = SubtractAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 497)
- def _reduce_250(val, _values, result)
- result = ShiftLeftAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 498)
- def _reduce_251(val, _values, result)
- result = ShiftRightAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 499)
- def _reduce_252(val, _values, result)
- result = BitAndAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 500)
- def _reduce_253(val, _values, result)
- result = BitXorAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 501)
- def _reduce_254(val, _values, result)
- result = BitOrAssign
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 505)
- def _reduce_255(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 507)
- def _reduce_256(val, _values, result)
- if val[0].is_a? Comma
- if val[2].is_a? Comma
- val[0].exprs.push(*val[2].exprs)
- else
- val[0].exprs << val[2]
- end
- result = val[0]
- else
- if val[2].is_a? Comma
- val[2].exprs.unshift(val[0])
- val[2].pos = val[0].pos
- result = val[2]
- else
- result = Comma.new_at(val[0].pos, NodeArray[val[0], val[2]])
- end
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 527)
- def _reduce_257(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 542)
- def _reduce_258(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 546)
- def _reduce_259(val, _values, result)
- result = val[0].val; result.pos = val[0].pos
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 547)
- def _reduce_260(val, _values, result)
- result = val[0].val; result.pos = val[0].pos
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 550)
- def _reduce_261(val, _values, result)
- result = val[0].val; result.pos = val[0].pos
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 554)
- def _reduce_262(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 559)
- def _reduce_263(val, _values, result)
- val[0].val << val[1].val.val; result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'cast.y', 560)
- def _reduce_264(val, _values, result)
- result = val[0].val; result.pos = val[0].pos
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module C
diff --git a/test/racc/regress/csspool b/test/racc/regress/csspool
deleted file mode 100644
index a3d14a9b34..0000000000
--- a/test/racc/regress/csspool
+++ /dev/null
@@ -1,2314 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-module CSSPool
- module CSS
- class Parser < Racc::Parser
-
-module_eval(<<'...end csspool.y/module_eval...', 'csspool.y', 670)
-
-def numeric thing
- thing = thing.gsub(/[^\d.]/, '')
- Integer(thing) rescue Float(thing)
-end
-
-def interpret_identifier s
- interpret_escapes s
-end
-
-def interpret_uri s
- interpret_escapes s.match(/^url\((.*)\)$/mui)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
-end
-
-def interpret_string_no_quote s
- interpret_escapes s.match(/^(.*)\)$/mu)[1].strip.match(/^(['"]?)((?:\\.|.)*)\1$/mu)[2]
-end
-
-def interpret_string s
- interpret_escapes s.match(/^(['"])((?:\\.|.)*)\1$/mu)[2]
-end
-
-def interpret_escapes s
- token_exp = /\\(?:([0-9a-fA-F]{1,6}(?:\r\n|\s)?)|(.))/mu
- return s.gsub(token_exp) do |escape_sequence|
- if !$1.nil?
- code = $1.chomp.to_i 16
- code = 0xFFFD if code > 0x10FFFF
- next [code].pack('U')
- end
- next '' if $2 == "\n"
- next $2
- end
-end
-
-# override racc's on_error so we can have context in our error messages
-def on_error(t, val, vstack)
- errcontext = (@ss.pre_match[-10..-1] || @ss.pre_match) +
- @ss.matched + @ss.post_match[0..9]
- line_number = @ss.pre_match.lines.count
- raise ParseError, sprintf("parse error on value %s (%s) " +
- "on line %s around \"%s\"",
- val.inspect, token_to_str(t) || '?',
- line_number, errcontext)
-end
-
-def before_pos(val)
- # don't include leading whitespace
- return current_pos - val.last.length + val.last[/\A\s*/].size
-end
-
-def after_pos(val)
- # don't include trailing whitespace
- return current_pos - val.last[/\s*\z/].size
-end
-
-# charpos will work with multibyte strings but is not available until ruby 2
-def current_pos
- @ss.respond_to?('charpos') ? @ss.charpos : @ss.pos
-end
-...end csspool.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 9, 10, 137, 129, 37, 31, 55, 139, 130, 39,
- 45, 47, 45, 47, 123, 9, 10, 103, 3, 37,
- 31, 98, 229, 103, 39, 45, 47, 230, 124, 125,
- 224, 20, 113, 56, 37, 31, 23, 114, 104, 39,
- 45, 47, 245, 27, 104, 11, 20, 126, 48, 25,
- 48, 23, 242, 29, 138, 244, 38, 46, 27, 46,
- 11, 108, 113, 48, 25, 9, 10, 114, 29, 37,
- 31, 38, 46, 223, 39, 45, 47, 49, 48, 115,
- 9, 10, 108, 113, 37, 31, 38, 46, 114, 39,
- 45, 47, 55, 339, 243, 155, 20, 108, 113, 37,
- 31, 23, 107, 114, 39, 45, 47, 231, 27, 115,
- 11, 20, 232, 48, 25, 55, 23, 59, 29, 56,
- 344, 38, 46, 27, 340, 11, 20, 53, 48, 25,
- 115, 23, 345, 29, 37, 31, 38, 46, 27, 39,
- 45, 47, 56, 48, 25, 115, -28, 105, 29, 37,
- 31, 38, 46, 116, 39, 45, 47, 250, 75, 120,
- 251, 20, 108, 113, 37, 31, 23, 118, 114, 39,
- 45, 47, 121, 27, 74, 73, 20, 313, 48, 25,
- 314, 23, 128, 29, 108, 113, 38, 46, 27, 215,
- 114, 20, 131, 48, 25, 75, 23, 136, 29, 37,
- 64, 38, 46, 27, 39, 45, 47, 92, 48, 25,
- 115, 74, 73, 29, 37, 31, 38, 46, 77, 39,
- 45, 47, 148, 94, 103, 156, 20, -89, 83, 37,
- 31, 23, 115, 87, 39, 45, 47, 160, 27, 85,
- 153, 20, 151, 48, 25, 104, 23, 84, 29, 157,
- 158, 38, 46, 27, 163, 252, 20, 151, 48, 25,
- 201, 23, 164, 29, 37, 31, 38, 46, 27, 39,
- 45, 47, 203, 48, 25, 188, 202, 59, 29, 37,
- 165, 38, 46, 187, 39, 45, 47, 201, 204, 166,
- 184, 83, 288, 198, 287, 190, 197, 192, 191, 193,
- 194, 195, 85, 202, 37, 45, 47, 37, 48, 39,
- 45, 47, 39, 45, 47, 167, 38, 46, 168, 83,
- 170, 113, 210, 48, 181, 186, 114, 185, 196, 37,
- 85, 38, 46, 92, 39, 45, 47, 203, 84, 150,
- 152, 151, 289, 48, 290, 292, 163, 291, 48, 94,
- -33, 48, 46, 204, 169, 199, 38, 46, 37, 38,
- 46, 200, -33, 39, 45, 47, 92, 188, 115, 59,
- 294, 258, 293, 48, 296, 187, 295, 298, 260, 297,
- 212, 38, 46, 83, 216, 198, 259, 190, 197, 192,
- 191, 193, 194, 195, 85, 45, 47, 45, 47, 45,
- 47, 217, 48, 218, 219, 188, 108, 59, 285, 108,
- 38, 46, 170, 187, 225, 226, 181, 186, 233, 185,
- 196, 83, 129, 198, 234, 190, 197, 192, 191, 193,
- 194, 195, 85, 48, 163, 48, 255, 48, 256, 155,
- 263, 169, 46, 188, 46, 59, 46, 264, 168, 265,
- 170, 187, 266, 92, 181, 186, 92, 185, 196, 83,
- 92, 198, 92, 190, 197, 192, 191, 193, 194, 195,
- 85, 198, 278, 190, 197, 192, 191, 193, 194, 195,
- 279, 188, 281, 59, 241, 235, 236, 237, 170, 187,
- 286, 229, 181, 186, 231, 185, 196, 83, 163, 198,
- 300, 190, 197, 192, 191, 193, 194, 195, 85, 301,
- 302, 238, 239, 240, 303, 306, 307, 255, 141, 188,
- 75, 59, 322, 163, 185, 168, 170, 187, 312, 317,
- 181, 186, 143, 185, 196, 83, 319, 198, 323, 190,
- 197, 192, 191, 193, 194, 195, 85, 324, 325, 145,
- 326, 327, 328, 329, 330, 331, 144, 188, 146, 59,
- 147, 332, 142, 333, 170, 187, 334, 306, 181, 186,
- 163, 185, 196, 83, 338, 198, 163, 190, 197, 192,
- 191, 193, 194, 195, 85, 346, 319, 319, 163, 351,
- 306, 163, 319, 357, 359, 188, nil, 59, nil, nil,
- nil, nil, 170, 187, nil, nil, 181, 186, nil, 185,
- 196, 83, nil, 198, nil, 190, 197, 192, 191, 193,
- 194, 195, 85, 272, nil, 83, nil, 198, nil, 190,
- 197, 192, 191, 193, 194, 195, nil, nil, nil, nil,
- 170, nil, nil, nil, 181, 186, nil, 185, 196, 272,
- nil, 83, nil, 198, nil, 190, 197, 192, 191, 193,
- 194, 195, 272, nil, 83, nil, 198, nil, 190, 197,
- 192, 191, 193, 194, 195, 272, nil, 83, nil, 198,
- nil, 190, 197, 192, 191, 193, 194, 195, 272, nil,
- 83, nil, 198, nil, 190, 197, 192, 191, 193, 194,
- 195, 272, nil, 83, nil, 198, nil, 190, 197, 192,
- 191, 193, 194, 195 ]
-
-racc_action_check = [
- 2, 2, 47, 38, 2, 2, 10, 47, 38, 2,
- 2, 2, 35, 35, 34, 5, 5, 26, 1, 5,
- 5, 26, 128, 217, 5, 5, 5, 128, 34, 34,
- 112, 2, 210, 10, 31, 31, 2, 210, 26, 31,
- 31, 31, 143, 2, 217, 2, 5, 34, 2, 2,
- 35, 5, 142, 2, 47, 143, 2, 2, 5, 35,
- 5, 110, 110, 5, 5, 6, 6, 110, 5, 6,
- 6, 5, 5, 112, 6, 6, 6, 3, 31, 210,
- 7, 7, 221, 221, 7, 7, 31, 31, 221, 7,
- 7, 7, 58, 309, 142, 58, 6, 28, 28, 12,
- 12, 6, 28, 28, 12, 12, 12, 131, 6, 110,
- 6, 7, 131, 6, 6, 11, 7, 11, 6, 58,
- 315, 6, 6, 7, 309, 7, 12, 9, 7, 7,
- 221, 12, 315, 7, 13, 13, 7, 7, 12, 13,
- 13, 13, 11, 12, 12, 28, 20, 27, 12, 14,
- 14, 12, 12, 29, 14, 14, 14, 149, 20, 32,
- 149, 13, 30, 30, 15, 15, 13, 30, 30, 15,
- 15, 15, 33, 13, 20, 20, 14, 269, 13, 13,
- 269, 14, 37, 13, 100, 100, 13, 13, 14, 100,
- 100, 15, 39, 14, 14, 157, 15, 46, 14, 19,
- 19, 14, 14, 15, 19, 19, 19, 25, 15, 15,
- 30, 157, 157, 15, 21, 21, 15, 15, 21, 21,
- 21, 21, 53, 25, 99, 67, 19, 99, 22, 24,
- 24, 19, 100, 24, 24, 24, 24, 71, 19, 22,
- 57, 21, 57, 19, 19, 99, 21, 22, 19, 70,
- 70, 19, 19, 21, 75, 154, 24, 154, 21, 21,
- 90, 24, 76, 21, 64, 64, 21, 21, 24, 64,
- 64, 64, 91, 24, 24, 83, 90, 83, 24, 121,
- 78, 24, 24, 83, 121, 121, 121, 206, 91, 79,
- 83, 83, 235, 83, 235, 83, 83, 83, 83, 83,
- 83, 83, 83, 206, 122, 41, 41, 144, 64, 122,
- 122, 122, 144, 144, 144, 80, 64, 64, 81, 166,
- 83, 92, 92, 121, 83, 83, 92, 83, 83, 146,
- 166, 121, 121, 92, 146, 146, 146, 207, 166, 54,
- 54, 54, 236, 41, 236, 237, 270, 237, 122, 92,
- 270, 144, 41, 207, 82, 86, 122, 122, 302, 144,
- 144, 88, 270, 302, 302, 302, 94, 171, 92, 171,
- 238, 171, 238, 146, 239, 171, 239, 240, 171, 240,
- 97, 146, 146, 171, 101, 171, 171, 171, 171, 171,
- 171, 171, 171, 171, 171, 42, 42, 43, 43, 44,
- 44, 102, 302, 105, 106, 223, 108, 223, 223, 109,
- 302, 302, 171, 223, 114, 117, 171, 171, 137, 171,
- 171, 223, 138, 223, 139, 223, 223, 223, 223, 223,
- 223, 223, 223, 42, 147, 43, 161, 44, 162, 172,
- 175, 176, 42, 261, 43, 261, 44, 177, 179, 183,
- 223, 261, 185, 201, 223, 223, 202, 223, 223, 261,
- 203, 261, 204, 261, 261, 261, 261, 261, 261, 261,
- 261, 189, 208, 189, 189, 189, 189, 189, 189, 189,
- 209, 285, 214, 285, 140, 140, 140, 140, 261, 285,
- 224, 233, 261, 261, 234, 261, 261, 285, 243, 285,
- 245, 285, 285, 285, 285, 285, 285, 285, 285, 246,
- 247, 140, 140, 140, 248, 249, 251, 254, 48, 286,
- 255, 286, 286, 256, 266, 267, 285, 286, 268, 280,
- 285, 285, 48, 285, 285, 286, 284, 286, 287, 286,
- 286, 286, 286, 286, 286, 286, 286, 288, 289, 48,
- 290, 291, 292, 293, 294, 295, 48, 322, 48, 322,
- 48, 296, 48, 297, 286, 322, 298, 299, 286, 286,
- 304, 286, 286, 322, 306, 322, 312, 322, 322, 322,
- 322, 322, 322, 322, 322, 316, 320, 321, 335, 337,
- 338, 340, 349, 350, 358, 353, nil, 353, nil, nil,
- nil, nil, 322, 353, nil, nil, 322, 322, nil, 322,
- 322, 353, nil, 353, nil, 353, 353, 353, 353, 353,
- 353, 353, 353, 186, nil, 186, nil, 186, nil, 186,
- 186, 186, 186, 186, 186, 186, nil, nil, nil, nil,
- 353, nil, nil, nil, 353, 353, nil, 353, 353, 272,
- nil, 272, nil, 272, nil, 272, 272, 272, 272, 272,
- 272, 272, 313, nil, 313, nil, 313, nil, 313, 313,
- 313, 313, 313, 313, 313, 314, nil, 314, nil, 314,
- nil, 314, 314, 314, 314, 314, 314, 314, 344, nil,
- 344, nil, 344, nil, 344, 344, 344, 344, 344, 344,
- 344, 345, nil, 345, nil, 345, nil, 345, 345, 345,
- 345, 345, 345, 345 ]
-
-racc_action_pointer = [
- nil, 18, -2, 77, nil, 13, 63, 78, nil, 123,
- 2, 111, 93, 128, 143, 158, nil, nil, nil, 193,
- 140, 208, 208, nil, 223, 189, 11, 141, 92, 144,
- 157, 28, 150, 164, 7, 0, nil, 124, -3, 134,
- nil, 293, 383, 385, 387, nil, 191, -4, 512, nil,
- nil, nil, nil, 217, 334, nil, nil, 235, 88, nil,
- nil, nil, nil, nil, 258, nil, nil, 215, nil, nil,
- 241, 231, nil, nil, nil, 247, 252, nil, 271, 281,
- 308, 311, 347, 271, nil, nil, 345, nil, 352, nil,
- 224, 236, 315, nil, 348, nil, nil, 370, nil, 218,
- 179, 375, 393, nil, nil, 394, 394, nil, 401, 404,
- 56, nil, 23, nil, 408, nil, nil, 405, nil, nil,
- nil, 273, 298, nil, nil, nil, nil, nil, 16, nil,
- nil, 101, nil, nil, nil, nil, nil, 360, 416, 366,
- 470, nil, 46, 36, 301, nil, 323, 427, nil, 152,
- nil, nil, nil, nil, 250, nil, nil, 177, nil, nil,
- nil, 400, 432, nil, nil, nil, 299, nil, nil, nil,
- nil, 363, 432, nil, nil, 433, 434, 440, nil, 441,
- nil, nil, nil, 430, nil, 444, 605, nil, nil, 449,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 435, 438, 442, 444, nil, 251, 301, 453, 461,
- 26, nil, nil, nil, 472, nil, nil, 17, nil, nil,
- nil, 77, nil, 401, 440, nil, nil, nil, nil, nil,
- nil, nil, nil, 485, 488, 288, 338, 341, 366, 370,
- 373, nil, nil, 491, nil, 481, 490, 502, 495, 509,
- nil, 510, nil, nil, 481, 502, 516, nil, nil, nil,
- nil, 439, nil, nil, nil, nil, 468, 518, 509, 155,
- 339, nil, 631, nil, nil, nil, nil, nil, nil, nil,
- 510, nil, nil, nil, 504, 477, 515, 524, 533, 534,
- 536, 537, 538, 539, 540, 541, 547, 549, 552, 561,
- nil, nil, 352, nil, 563, nil, 566, nil, nil, 74,
- nil, nil, 569, 644, 657, 109, 566, nil, nil, nil,
- 554, 555, 553, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 581, nil, 570, 584, nil,
- 584, nil, nil, nil, 670, 683, nil, nil, nil, 560,
- 574, nil, nil, 591, nil, nil, nil, nil, 575, nil ]
-
-racc_action_default = [
- -1, -229, -10, -229, -2, -6, -7, -8, -9, -229,
- -229, -229, -41, -42, -43, -44, -45, -46, -47, -33,
- -23, -229, -229, -55, -229, -229, -89, -229, -229, -229,
- -229, -229, -229, -103, -105, -111, -112, -115, -229, -120,
- -119, -124, -125, -126, -127, -132, -229, -229, -229, 360,
- -3, -4, -5, -229, -229, -15, -16, -229, -229, -228,
- -37, -38, -39, -40, -32, -48, -49, -229, -99, -21,
- -229, -229, -35, -26, -27, -33, -229, -53, -229, -57,
- -58, -59, -60, -229, -198, -214, -229, -62, -229, -64,
- -65, -66, -229, -71, -229, -73, -74, -229, -82, -85,
- -229, -229, -91, -92, -93, -229, -229, -95, -160, -165,
- -166, -167, -229, -174, -229, -176, -96, -229, -98, -100,
- -101, -229, -229, -106, -107, -108, -109, -110, -229, -117,
- -121, -229, -128, -129, -130, -131, -133, -115, -229, -229,
- -229, -147, -229, -229, -229, -152, -229, -33, -11, -229,
- -13, -14, -20, -18, -229, -227, -50, -28, -51, -35,
- -29, -25, -229, -32, -52, -54, -229, -197, -194, -213,
- -36, -182, -183, -184, -185, -186, -187, -188, -189, -190,
- -191, -192, -193, -229, -196, -200, -229, -212, -216, -229,
- -218, -219, -220, -221, -222, -223, -224, -225, -226, -61,
- -63, -229, -229, -229, -229, -67, -68, -69, -229, -229,
- -229, -72, -81, -84, -229, -87, -88, -89, -83, -94,
- -161, -164, -163, -229, -229, -175, -97, -102, -104, -116,
- -123, -118, -122, -229, -229, -229, -229, -229, -229, -229,
- -229, -146, -148, -33, -149, -229, -229, -114, -229, -156,
- -12, -229, -17, -22, -24, -229, -33, -56, -177, -178,
- -179, -229, -181, -215, -211, -195, -229, -209, -229, -202,
- -205, -208, -229, -217, -76, -78, -75, -77, -70, -79,
- -229, -86, -90, -162, -173, -229, -229, -229, -229, -229,
- -229, -229, -229, -229, -229, -229, -229, -229, -229, -156,
- -150, -151, -229, -153, -33, -157, -158, -19, -34, -229,
- -180, -199, -33, -229, -229, -229, -229, -80, -168, -172,
- -173, -173, -229, -134, -135, -136, -137, -138, -139, -140,
- -141, -142, -143, -144, -145, -33, -113, -229, -229, -30,
- -33, -201, -203, -204, -229, -229, -210, -169, -170, -173,
- -229, -154, -159, -229, -206, -207, -171, -155, -229, -31 ]
-
-racc_goto_table = [
- 81, 248, 183, 68, 106, 91, 117, 271, 78, 246,
- 273, 247, 82, 69, 209, 161, 97, 89, 268, 304,
- 90, 119, 54, 57, 220, 221, 318, 60, 61, 62,
- 63, 354, 355, 1, 65, 127, 76, 2, 149, 86,
- 58, 132, 133, 134, 135, 4, 70, 159, 50, 51,
- 52, 308, 67, 66, 119, 88, 208, 282, 227, 162,
- 228, 122, 347, 348, 140, 352, 261, 311, nil, 335,
- 154, nil, 207, nil, 211, nil, 214, nil, nil, nil,
- nil, nil, nil, nil, 205, nil, 222, 206, nil, 213,
- 262, 356, nil, 271, nil, nil, nil, nil, nil, nil,
- nil, nil, 254, nil, 316, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 249, 280, nil, 271, 271, nil, nil, nil, nil,
- nil, nil, 284, nil, 81, 342, 343, nil, nil, nil,
- 253, nil, 257, nil, nil, nil, 82, 336, nil, nil,
- nil, nil, nil, nil, 267, 271, 271, 247, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 310, 274, 275, 276, 277, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 283, nil, nil,
- nil, nil, nil, nil, 320, 321, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 299, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 309, 349, nil, nil, nil, nil, nil, nil, nil, nil,
- 267, nil, nil, nil, 315, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 358, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 337, nil,
- nil, 267, 267, nil, nil, nil, 341, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 350,
- nil, nil, 267, 267, 353 ]
-
-racc_goto_check = [
- 35, 62, 18, 17, 51, 41, 51, 77, 32, 58,
- 77, 58, 36, 12, 46, 15, 48, 39, 82, 68,
- 40, 55, 8, 8, 70, 70, 73, 7, 7, 7,
- 7, 84, 84, 1, 7, 61, 7, 3, 9, 7,
- 10, 61, 61, 61, 61, 2, 11, 14, 2, 2,
- 2, 16, 27, 28, 55, 38, 42, 52, 56, 17,
- 57, 59, 73, 73, 63, 69, 74, 81, nil, 68,
- 8, nil, 41, nil, 41, nil, 51, nil, nil, nil,
- nil, nil, nil, nil, 39, nil, 51, 40, nil, 48,
- 18, 73, nil, 77, nil, nil, nil, nil, nil, nil,
- nil, nil, 15, nil, 82, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 17, 46, nil, 77, 77, nil, nil, nil, nil,
- nil, nil, 18, nil, 35, 82, 82, nil, nil, nil,
- 12, nil, 32, nil, nil, nil, 36, 62, nil, nil,
- nil, nil, nil, nil, 35, 77, 77, 58, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 18, 41, 41, 41, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 51, nil, nil,
- nil, nil, nil, nil, 18, 18, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 17, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 17, 18, nil, nil, nil, nil, nil, nil, nil, nil,
- 35, nil, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 18, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 17, nil,
- nil, 35, 35, nil, nil, nil, 17, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 17,
- nil, nil, 35, 35, 17 ]
-
-racc_goto_pointer = [
- nil, 33, 43, 37, nil, nil, nil, 15, 12, -16,
- 29, 26, -7, nil, -24, -57, -204, -16, -81, nil,
- nil, nil, nil, nil, nil, nil, nil, 33, 34, nil,
- nil, nil, -14, nil, nil, -22, -10, nil, 30, -8,
- -5, -20, -36, nil, nil, nil, -78, nil, -10, nil,
- nil, -24, -160, nil, nil, -10, -63, -62, -135, 27,
- nil, 0, -145, 17, nil, nil, nil, nil, -230, -273,
- -84, nil, nil, -258, -105, nil, nil, -179, nil, nil,
- nil, -199, -168, nil, -313, nil ]
-
-racc_goto_default = [
- nil, nil, nil, nil, 5, 6, 7, 8, nil, nil,
- 172, nil, nil, 71, nil, nil, 72, nil, nil, 180,
- 12, 13, 14, 15, 16, 17, 18, nil, nil, 19,
- 21, 22, nil, 79, 80, 179, 176, 24, nil, nil,
- nil, nil, nil, 93, 95, 96, 111, 26, nil, 99,
- 100, nil, 101, 102, 28, 30, 32, 33, 34, nil,
- 35, 36, nil, 40, 41, 42, 43, 44, nil, 305,
- 110, 109, 112, nil, nil, 171, 173, 174, 175, 177,
- 178, 182, nil, 269, 270, 189 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 0, 63, :_reduce_1,
- 2, 61, :_reduce_2,
- 2, 62, :_reduce_none,
- 2, 62, :_reduce_none,
- 2, 62, :_reduce_none,
- 1, 62, :_reduce_none,
- 1, 62, :_reduce_none,
- 1, 62, :_reduce_none,
- 1, 62, :_reduce_none,
- 0, 62, :_reduce_none,
- 3, 64, :_reduce_11,
- 4, 65, :_reduce_12,
- 3, 65, :_reduce_13,
- 2, 68, :_reduce_none,
- 1, 68, :_reduce_15,
- 1, 68, :_reduce_16,
- 4, 66, :_reduce_17,
- 3, 66, :_reduce_18,
- 3, 69, :_reduce_19,
- 1, 69, :_reduce_20,
- 1, 71, :_reduce_21,
- 3, 71, :_reduce_22,
- 0, 71, :_reduce_23,
- 3, 72, :_reduce_24,
- 2, 72, :_reduce_25,
- 1, 73, :_reduce_26,
- 1, 73, :_reduce_27,
- 0, 73, :_reduce_28,
- 1, 74, :_reduce_29,
- 5, 76, :_reduce_30,
- 8, 76, :_reduce_31,
- 1, 77, :_reduce_32,
- 0, 77, :_reduce_33,
- 3, 75, :_reduce_34,
- 0, 75, :_reduce_35,
- 1, 79, :_reduce_36,
- 2, 67, :_reduce_none,
- 2, 67, :_reduce_none,
- 2, 67, :_reduce_none,
- 2, 67, :_reduce_none,
- 1, 67, :_reduce_none,
- 1, 67, :_reduce_none,
- 1, 67, :_reduce_none,
- 1, 67, :_reduce_none,
- 1, 81, :_reduce_none,
- 1, 81, :_reduce_none,
- 1, 81, :_reduce_none,
- 1, 87, :_reduce_none,
- 1, 87, :_reduce_none,
- 3, 84, :_reduce_50,
- 3, 89, :_reduce_51,
- 3, 85, :_reduce_52,
- 2, 85, :_reduce_53,
- 3, 90, :_reduce_54,
- 1, 91, :_reduce_55,
- 3, 92, :_reduce_56,
- 1, 92, :_reduce_57,
- 1, 93, :_reduce_none,
- 1, 93, :_reduce_none,
- 1, 93, :_reduce_none,
- 3, 86, :_reduce_61,
- 2, 86, :_reduce_62,
- 3, 97, :_reduce_63,
- 1, 98, :_reduce_64,
- 1, 98, :_reduce_65,
- 1, 98, :_reduce_66,
- 1, 102, :_reduce_67,
- 1, 102, :_reduce_68,
- 1, 102, :_reduce_69,
- 3, 101, :_reduce_70,
- 1, 101, :_reduce_71,
- 2, 99, :_reduce_72,
- 1, 100, :_reduce_none,
- 1, 100, :_reduce_none,
- 3, 104, :_reduce_75,
- 3, 104, :_reduce_76,
- 3, 105, :_reduce_77,
- 3, 105, :_reduce_78,
- 3, 103, :_reduce_79,
- 4, 103, :_reduce_80,
- 3, 82, :_reduce_none,
- 2, 82, :_reduce_none,
- 3, 107, :_reduce_83,
- 2, 108, :_reduce_none,
- 1, 108, :_reduce_none,
- 3, 109, :_reduce_86,
- 2, 109, :_reduce_87,
- 2, 110, :_reduce_88,
- 0, 112, :_reduce_none,
- 3, 112, :_reduce_90,
- 1, 112, :_reduce_none,
- 1, 113, :_reduce_none,
- 1, 113, :_reduce_93,
- 3, 83, :_reduce_94,
- 2, 83, :_reduce_95,
- 2, 114, :_reduce_96,
- 3, 80, :_reduce_97,
- 2, 80, :_reduce_98,
- 1, 88, :_reduce_99,
- 2, 115, :_reduce_100,
- 2, 115, :_reduce_101,
- 3, 116, :_reduce_102,
- 1, 116, :_reduce_103,
- 3, 117, :_reduce_104,
- 1, 117, :_reduce_none,
- 1, 119, :_reduce_106,
- 1, 119, :_reduce_107,
- 1, 119, :_reduce_108,
- 1, 119, :_reduce_109,
- 2, 118, :_reduce_110,
- 1, 118, :_reduce_111,
- 1, 118, :_reduce_112,
- 3, 122, :_reduce_113,
- 1, 122, :_reduce_none,
- 1, 123, :_reduce_115,
- 3, 123, :_reduce_116,
- 2, 123, :_reduce_117,
- 3, 123, :_reduce_118,
- 1, 120, :_reduce_119,
- 1, 120, :_reduce_120,
- 2, 120, :_reduce_121,
- 3, 120, :_reduce_122,
- 3, 120, :_reduce_123,
- 1, 121, :_reduce_124,
- 1, 121, :_reduce_125,
- 1, 121, :_reduce_126,
- 1, 121, :_reduce_127,
- 2, 121, :_reduce_128,
- 2, 121, :_reduce_129,
- 2, 121, :_reduce_130,
- 2, 121, :_reduce_131,
- 1, 124, :_reduce_132,
- 2, 125, :_reduce_133,
- 5, 126, :_reduce_134,
- 5, 126, :_reduce_135,
- 5, 126, :_reduce_136,
- 5, 126, :_reduce_137,
- 5, 126, :_reduce_138,
- 5, 126, :_reduce_139,
- 5, 126, :_reduce_140,
- 5, 126, :_reduce_141,
- 5, 126, :_reduce_142,
- 5, 126, :_reduce_143,
- 5, 126, :_reduce_144,
- 5, 126, :_reduce_145,
- 3, 126, :_reduce_146,
- 2, 127, :_reduce_147,
- 3, 127, :_reduce_148,
- 3, 127, :_reduce_149,
- 4, 127, :_reduce_150,
- 4, 127, :_reduce_151,
- 2, 127, :_reduce_152,
- 4, 127, :_reduce_153,
- 6, 127, :_reduce_154,
- 7, 127, :_reduce_155,
- 0, 128, :_reduce_none,
- 1, 128, :_reduce_none,
- 1, 129, :_reduce_none,
- 3, 129, :_reduce_none,
- 1, 130, :_reduce_none,
- 2, 130, :_reduce_none,
- 3, 111, :_reduce_none,
- 2, 111, :_reduce_none,
- 2, 111, :_reduce_none,
- 1, 111, :_reduce_none,
- 1, 111, :_reduce_none,
- 1, 131, :_reduce_167,
- 4, 106, :_reduce_168,
- 5, 106, :_reduce_169,
- 5, 106, :_reduce_170,
- 6, 106, :_reduce_171,
- 1, 133, :_reduce_172,
- 0, 133, :_reduce_173,
- 1, 132, :_reduce_174,
- 2, 132, :_reduce_175,
- 1, 132, :_reduce_176,
- 1, 134, :_reduce_none,
- 1, 134, :_reduce_none,
- 1, 134, :_reduce_none,
- 3, 78, :_reduce_180,
- 2, 78, :_reduce_181,
- 1, 78, :_reduce_182,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 1, 135, :_reduce_none,
- 2, 95, :_reduce_194,
- 3, 95, :_reduce_195,
- 2, 95, :_reduce_196,
- 2, 94, :_reduce_197,
- 1, 94, :_reduce_198,
- 3, 141, :_reduce_none,
- 1, 141, :_reduce_none,
- 4, 140, :_reduce_201,
- 1, 142, :_reduce_none,
- 3, 142, :_reduce_203,
- 3, 142, :_reduce_204,
- 1, 143, :_reduce_none,
- 4, 143, :_reduce_206,
- 4, 143, :_reduce_207,
- 1, 144, :_reduce_208,
- 1, 144, :_reduce_209,
- 3, 144, :_reduce_210,
- 2, 139, :_reduce_211,
- 1, 139, :_reduce_212,
- 2, 96, :_reduce_213,
- 1, 96, :_reduce_214,
- 2, 138, :_reduce_215,
- 1, 138, :_reduce_216,
- 2, 137, :_reduce_217,
- 1, 137, :_reduce_218,
- 1, 137, :_reduce_219,
- 1, 137, :_reduce_220,
- 1, 137, :_reduce_221,
- 1, 137, :_reduce_222,
- 1, 137, :_reduce_223,
- 1, 136, :_reduce_224,
- 1, 145, :_reduce_225,
- 1, 145, :_reduce_226,
- 2, 70, :_reduce_227,
- 1, 70, :_reduce_228 ]
-
-racc_reduce_n = 229
-
-racc_shift_n = 360
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :CHARSET_SYM => 2,
- :IMPORT_SYM => 3,
- :STRING => 4,
- :SEMI => 5,
- :IDENT => 6,
- :S => 7,
- :COMMA => 8,
- :LBRACE => 9,
- :RBRACE => 10,
- :STAR => 11,
- :HASH => 12,
- :LSQUARE => 13,
- :RSQUARE => 14,
- :EQUAL => 15,
- :INCLUDES => 16,
- :DASHMATCH => 17,
- :LPAREN => 18,
- :RPAREN => 19,
- :FUNCTION => 20,
- :GREATER => 21,
- :PLUS => 22,
- :SLASH => 23,
- :NUMBER => 24,
- :MINUS => 25,
- :LENGTH => 26,
- :PERCENTAGE => 27,
- :ANGLE => 28,
- :TIME => 29,
- :FREQ => 30,
- :URI => 31,
- :IMPORTANT_SYM => 32,
- :MEDIA_SYM => 33,
- :NOT => 34,
- :ONLY => 35,
- :AND => 36,
- :NTH_PSEUDO_CLASS => 37,
- :DOCUMENT_QUERY_SYM => 38,
- :FUNCTION_NO_QUOTE => 39,
- :TILDE => 40,
- :PREFIXMATCH => 41,
- :SUFFIXMATCH => 42,
- :SUBSTRINGMATCH => 43,
- :NOT_PSEUDO_CLASS => 44,
- :KEYFRAMES_SYM => 45,
- :MATCHES_PSEUDO_CLASS => 46,
- :NAMESPACE_SYM => 47,
- :MOZ_PSEUDO_ELEMENT => 48,
- :RESOLUTION => 49,
- :COLON => 50,
- :SUPPORTS_SYM => 51,
- :OR => 52,
- :VARIABLE_NAME => 53,
- :CALC_SYM => 54,
- :FONTFACE_SYM => 55,
- :UNICODE_RANGE => 56,
- :RATIO => 57,
- "|" => 58,
- "." => 59 }
-
-racc_nt_base = 60
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "CHARSET_SYM",
- "IMPORT_SYM",
- "STRING",
- "SEMI",
- "IDENT",
- "S",
- "COMMA",
- "LBRACE",
- "RBRACE",
- "STAR",
- "HASH",
- "LSQUARE",
- "RSQUARE",
- "EQUAL",
- "INCLUDES",
- "DASHMATCH",
- "LPAREN",
- "RPAREN",
- "FUNCTION",
- "GREATER",
- "PLUS",
- "SLASH",
- "NUMBER",
- "MINUS",
- "LENGTH",
- "PERCENTAGE",
- "ANGLE",
- "TIME",
- "FREQ",
- "URI",
- "IMPORTANT_SYM",
- "MEDIA_SYM",
- "NOT",
- "ONLY",
- "AND",
- "NTH_PSEUDO_CLASS",
- "DOCUMENT_QUERY_SYM",
- "FUNCTION_NO_QUOTE",
- "TILDE",
- "PREFIXMATCH",
- "SUFFIXMATCH",
- "SUBSTRINGMATCH",
- "NOT_PSEUDO_CLASS",
- "KEYFRAMES_SYM",
- "MATCHES_PSEUDO_CLASS",
- "NAMESPACE_SYM",
- "MOZ_PSEUDO_ELEMENT",
- "RESOLUTION",
- "COLON",
- "SUPPORTS_SYM",
- "OR",
- "VARIABLE_NAME",
- "CALC_SYM",
- "FONTFACE_SYM",
- "UNICODE_RANGE",
- "RATIO",
- "\"|\"",
- "\".\"",
- "$start",
- "document",
- "stylesheet",
- "@1",
- "charset",
- "import",
- "namespace",
- "body",
- "import_location",
- "medium",
- "ident",
- "media_query_list",
- "media_query",
- "optional_only_or_not",
- "media_type",
- "optional_and_exprs",
- "media_expr",
- "optional_space",
- "expr",
- "resolution",
- "ruleset",
- "conditional_rule",
- "keyframes_rule",
- "fontface_rule",
- "media",
- "document_query",
- "supports",
- "body_in_media",
- "empty_ruleset",
- "start_media",
- "start_document_query",
- "start_document_query_pos",
- "url_match_fns",
- "url_match_fn",
- "function_no_quote",
- "function",
- "uri",
- "start_supports",
- "supports_condition_root",
- "supports_negation",
- "supports_conjunction_or_disjunction",
- "supports_condition_in_parens",
- "supports_condition",
- "supports_declaration_condition",
- "supports_conjunction",
- "supports_disjunction",
- "declaration_internal",
- "start_keyframes_rule",
- "keyframes_blocks",
- "keyframes_block",
- "start_keyframes_block",
- "declarations",
- "keyframes_selectors",
- "keyframes_selector",
- "start_fontface_rule",
- "start_selector",
- "selectors",
- "selector",
- "simple_selector",
- "combinator",
- "element_name",
- "hcap",
- "simple_selectors",
- "ident_with_namespace",
- "hash",
- "class",
- "attrib",
- "pseudo",
- "any_number_of_idents",
- "multiple_idents",
- "one_or_more_semis",
- "declaration",
- "property",
- "prio",
- "operator",
- "term",
- "ratio",
- "numeric",
- "string",
- "hexcolor",
- "calc",
- "uranges",
- "calc_sum",
- "calc_product",
- "calc_value",
- "unary_operator" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 26)
- def _reduce_1(val, _values, result)
- @handler.start_document
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 28)
- def _reduce_2(val, _values, result)
- @handler.end_document
- result
- end
-.,.,
-
-# reduce 3 omitted
-
-# reduce 4 omitted
-
-# reduce 5 omitted
-
-# reduce 6 omitted
-
-# reduce 7 omitted
-
-# reduce 8 omitted
-
-# reduce 9 omitted
-
-# reduce 10 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 41)
- def _reduce_11(val, _values, result)
- @handler.charset interpret_string(val[1]), {}
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 45)
- def _reduce_12(val, _values, result)
- @handler.import_style val[2], val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 48)
- def _reduce_13(val, _values, result)
- @handler.import_style [], val[1]
-
- result
- end
-.,.,
-
-# reduce 14 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 53)
- def _reduce_15(val, _values, result)
- result = Terms::String.new interpret_string val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 54)
- def _reduce_16(val, _values, result)
- result = Terms::URI.new interpret_uri val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 58)
- def _reduce_17(val, _values, result)
- @handler.namespace val[1], val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 61)
- def _reduce_18(val, _values, result)
- @handler.namespace nil, val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 66)
- def _reduce_19(val, _values, result)
- result = val[0] << MediaType.new(val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 69)
- def _reduce_20(val, _values, result)
- result = [MediaType.new(val[0])]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 73)
- def _reduce_21(val, _values, result)
- result = MediaQueryList.new([ val[0] ])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 74)
- def _reduce_22(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 75)
- def _reduce_23(val, _values, result)
- result = MediaQueryList.new
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 78)
- def _reduce_24(val, _values, result)
- result = MediaQuery.new(val[0], val[1], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 79)
- def _reduce_25(val, _values, result)
- result = MediaQuery.new(nil, val[0], val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 82)
- def _reduce_26(val, _values, result)
- result = :only
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 83)
- def _reduce_27(val, _values, result)
- result = :not
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 84)
- def _reduce_28(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 87)
- def _reduce_29(val, _values, result)
- result = MediaType.new(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 90)
- def _reduce_30(val, _values, result)
- result = MediaType.new(val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 91)
- def _reduce_31(val, _values, result)
- result = MediaFeature.new(val[2], val[6][0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 94)
- def _reduce_32(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 95)
- def _reduce_33(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 98)
- def _reduce_34(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 99)
- def _reduce_35(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 103)
- def _reduce_36(val, _values, result)
- unit = val.first.gsub(/[\s\d.]/, '')
- number = numeric(val.first)
- result = Terms::Resolution.new(number, unit)
-
- result
- end
-.,.,
-
-# reduce 37 omitted
-
-# reduce 38 omitted
-
-# reduce 39 omitted
-
-# reduce 40 omitted
-
-# reduce 41 omitted
-
-# reduce 42 omitted
-
-# reduce 43 omitted
-
-# reduce 44 omitted
-
-# reduce 45 omitted
-
-# reduce 46 omitted
-
-# reduce 47 omitted
-
-# reduce 48 omitted
-
-# reduce 49 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 128)
- def _reduce_50(val, _values, result)
- @handler.end_media val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 132)
- def _reduce_51(val, _values, result)
- result = val[1]
- @handler.start_media result
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 137)
- def _reduce_52(val, _values, result)
- @handler.end_document_query(before_pos(val), after_pos(val))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 138)
- def _reduce_53(val, _values, result)
- @handler.end_document_query(before_pos(val), after_pos(val))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 142)
- def _reduce_54(val, _values, result)
- @handler.start_document_query(val[1], after_pos(val))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 147)
- def _reduce_55(val, _values, result)
- @handler.node_start_pos = before_pos(val)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 152)
- def _reduce_56(val, _values, result)
- result = [val[0], val[2]].flatten
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 155)
- def _reduce_57(val, _values, result)
- result = val
-
- result
- end
-.,.,
-
-# reduce 58 omitted
-
-# reduce 59 omitted
-
-# reduce 60 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 164)
- def _reduce_61(val, _values, result)
- @handler.end_supports
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 165)
- def _reduce_62(val, _values, result)
- @handler.end_supports
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 169)
- def _reduce_63(val, _values, result)
- @handler.start_supports val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 173)
- def _reduce_64(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 174)
- def _reduce_65(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 175)
- def _reduce_66(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 178)
- def _reduce_67(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 179)
- def _reduce_68(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 180)
- def _reduce_69(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 183)
- def _reduce_70(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 184)
- def _reduce_71(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 187)
- def _reduce_72(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-# reduce 73 omitted
-
-# reduce 74 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 194)
- def _reduce_75(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 195)
- def _reduce_76(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 198)
- def _reduce_77(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 199)
- def _reduce_78(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 202)
- def _reduce_79(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 203)
- def _reduce_80(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-# reduce 81 omitted
-
-# reduce 82 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 211)
- def _reduce_83(val, _values, result)
- @handler.start_keyframes_rule val[1]
-
- result
- end
-.,.,
-
-# reduce 84 omitted
-
-# reduce 85 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 219)
- def _reduce_86(val, _values, result)
- @handler.end_keyframes_block
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 220)
- def _reduce_87(val, _values, result)
- @handler.end_keyframes_block
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 224)
- def _reduce_88(val, _values, result)
- @handler.start_keyframes_block val[0]
-
- result
- end
-.,.,
-
-# reduce 89 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 229)
- def _reduce_90(val, _values, result)
- result = val[0] + ', ' + val[2]
-
- result
- end
-.,.,
-
-# reduce 91 omitted
-
-# reduce 92 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 235)
- def _reduce_93(val, _values, result)
- result = val[0].strip
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 238)
- def _reduce_94(val, _values, result)
- @handler.end_fontface_rule
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 239)
- def _reduce_95(val, _values, result)
- @handler.end_fontface_rule
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 243)
- def _reduce_96(val, _values, result)
- @handler.start_fontface_rule
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 248)
- def _reduce_97(val, _values, result)
- @handler.end_selector val.first
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 251)
- def _reduce_98(val, _values, result)
- @handler.end_selector val.first
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 256)
- def _reduce_99(val, _values, result)
- start = @handler.start_selector([])
- @handler.end_selector(start)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 261)
- def _reduce_100(val, _values, result)
- result = val.last
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 263)
- def _reduce_101(val, _values, result)
- @handler.start_selector val.first
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 269)
- def _reduce_102(val, _values, result)
- sel = Selector.new(val.first, {})
- result = [sel].concat(val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 274)
- def _reduce_103(val, _values, result)
- result = [Selector.new(val.first, {})]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 280)
- def _reduce_104(val, _values, result)
- val.flatten!
- val[2].combinator = val.delete_at 1
- result = val
-
- result
- end
-.,.,
-
-# reduce 105 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 287)
- def _reduce_106(val, _values, result)
- result = :s
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 288)
- def _reduce_107(val, _values, result)
- result = :>
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 289)
- def _reduce_108(val, _values, result)
- result = :+
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 290)
- def _reduce_109(val, _values, result)
- result = :~
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 294)
- def _reduce_110(val, _values, result)
- selector = val.first
- selector.additional_selectors = val.last
- result = [selector]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 298)
- def _reduce_111(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 301)
- def _reduce_112(val, _values, result)
- ss = Selectors::Simple.new nil, nil
- ss.additional_selectors = val.flatten
- result = [ss]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 307)
- def _reduce_113(val, _values, result)
- result = [val[0], val[2]].flatten
- result
- end
-.,.,
-
-# reduce 114 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 311)
- def _reduce_115(val, _values, result)
- result = [interpret_identifier(val[0]), nil]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 312)
- def _reduce_116(val, _values, result)
- result = [interpret_identifier(val[2]), interpret_identifier(val[0])]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 313)
- def _reduce_117(val, _values, result)
- result = [interpret_identifier(val[1]), nil]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 314)
- def _reduce_118(val, _values, result)
- result = [interpret_identifier(val[2]), '*']
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 317)
- def _reduce_119(val, _values, result)
- result = Selectors::Type.new val.first[0], nil, val.first[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 318)
- def _reduce_120(val, _values, result)
- result = Selectors::Universal.new val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 319)
- def _reduce_121(val, _values, result)
- result = Selectors::Universal.new val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 320)
- def _reduce_122(val, _values, result)
- result = Selectors::Universal.new val[2], nil, val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 321)
- def _reduce_123(val, _values, result)
- result = Selectors::Universal.new val[2], nil, interpret_identifier(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 324)
- def _reduce_124(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 325)
- def _reduce_125(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 326)
- def _reduce_126(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 327)
- def _reduce_127(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 328)
- def _reduce_128(val, _values, result)
- result = val.flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 329)
- def _reduce_129(val, _values, result)
- result = val.flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 330)
- def _reduce_130(val, _values, result)
- result = val.flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 331)
- def _reduce_131(val, _values, result)
- result = val.flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 335)
- def _reduce_132(val, _values, result)
- result = Selectors::Id.new interpret_identifier val.first.sub(/^#/, '')
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 339)
- def _reduce_133(val, _values, result)
- result = Selectors::Class.new interpret_identifier val.last
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 344)
- def _reduce_134(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::EQUALS,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 352)
- def _reduce_135(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::EQUALS,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 360)
- def _reduce_136(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::INCLUDES,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 368)
- def _reduce_137(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::INCLUDES,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 376)
- def _reduce_138(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::DASHMATCH,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 384)
- def _reduce_139(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::DASHMATCH,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 392)
- def _reduce_140(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::PREFIXMATCH,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 400)
- def _reduce_141(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::PREFIXMATCH,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 408)
- def _reduce_142(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::SUFFIXMATCH,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 416)
- def _reduce_143(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::SUFFIXMATCH,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 424)
- def _reduce_144(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_identifier(val[3]),
- Selectors::Attribute::SUBSTRINGMATCH,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 432)
- def _reduce_145(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- interpret_string(val[3]),
- Selectors::Attribute::SUBSTRINGMATCH,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 440)
- def _reduce_146(val, _values, result)
- result = Selectors::Attribute.new(
- val[1][0],
- nil,
- Selectors::Attribute::SET,
- val[1][1]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 450)
- def _reduce_147(val, _values, result)
- result = Selectors::pseudo interpret_identifier(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 453)
- def _reduce_148(val, _values, result)
- result = Selectors::PseudoElement.new(
- interpret_identifier(val[2])
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 458)
- def _reduce_149(val, _values, result)
- result = Selectors::PseudoClass.new(
- interpret_identifier(val[1].sub(/\($/, '')),
- ''
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 464)
- def _reduce_150(val, _values, result)
- result = Selectors::PseudoClass.new(
- interpret_identifier(val[1].sub(/\($/, '')),
- interpret_identifier(val[2])
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 470)
- def _reduce_151(val, _values, result)
- result = Selectors::PseudoClass.new(
- 'not',
- val[2].first.to_s
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 476)
- def _reduce_152(val, _values, result)
- result = Selectors::PseudoClass.new(
- interpret_identifier(val[1].sub(/\(.*/, '')),
- interpret_identifier(val[1].sub(/.*\(/, '').sub(/\).*/, ''))
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 482)
- def _reduce_153(val, _values, result)
- result = Selectors::PseudoClass.new(
- val[1].split('(').first.strip,
- val[2].join(', ')
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 488)
- def _reduce_154(val, _values, result)
- result = Selectors::PseudoElement.new(
- interpret_identifier(val[1].sub(/\($/, ''))
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 493)
- def _reduce_155(val, _values, result)
- result = Selectors::PseudoElement.new(
- interpret_identifier(val[2].sub(/\($/, ''))
- )
-
- result
- end
-.,.,
-
-# reduce 156 omitted
-
-# reduce 157 omitted
-
-# reduce 158 omitted
-
-# reduce 159 omitted
-
-# reduce 160 omitted
-
-# reduce 161 omitted
-
-# reduce 162 omitted
-
-# reduce 163 omitted
-
-# reduce 164 omitted
-
-# reduce 165 omitted
-
-# reduce 166 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 519)
- def _reduce_167(val, _values, result)
- @handler.property val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 523)
- def _reduce_168(val, _values, result)
- result = Declaration.new(val.first, val[2], val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 525)
- def _reduce_169(val, _values, result)
- result = Declaration.new(val.first, val[3], val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 527)
- def _reduce_170(val, _values, result)
- result = Declaration.new(val.first, val[3], val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 529)
- def _reduce_171(val, _values, result)
- result = Declaration.new(val.first, val[4], val[5])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 532)
- def _reduce_172(val, _values, result)
- result = true
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 533)
- def _reduce_173(val, _values, result)
- result = false
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 536)
- def _reduce_174(val, _values, result)
- result = interpret_identifier val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 537)
- def _reduce_175(val, _values, result)
- result = interpret_identifier val.join
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 538)
- def _reduce_176(val, _values, result)
- result = interpret_identifier val[0]
- result
- end
-.,.,
-
-# reduce 177 omitted
-
-# reduce 178 omitted
-
-# reduce 179 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 547)
- def _reduce_180(val, _values, result)
- result = [val.first, val.last].flatten
- val.last.first.operator = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 550)
- def _reduce_181(val, _values, result)
- result = val.flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 551)
- def _reduce_182(val, _values, result)
- result = val
- result
- end
-.,.,
-
-# reduce 183 omitted
-
-# reduce 184 omitted
-
-# reduce 185 omitted
-
-# reduce 186 omitted
-
-# reduce 187 omitted
-
-# reduce 188 omitted
-
-# reduce 189 omitted
-
-# reduce 190 omitted
-
-# reduce 191 omitted
-
-# reduce 192 omitted
-
-# reduce 193 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 567)
- def _reduce_194(val, _values, result)
- result = val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 569)
- def _reduce_195(val, _values, result)
- name = interpret_identifier val.first.sub(/\($/, '')
- if name == 'rgb'
- result = Terms::Rgb.new(*val[1])
- else
- result = Terms::Function.new name, val[1]
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 577)
- def _reduce_196(val, _values, result)
- name = interpret_identifier val.first.sub(/\($/, '')
- result = Terms::Function.new name
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 582)
- def _reduce_197(val, _values, result)
- result = val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 584)
- def _reduce_198(val, _values, result)
- parts = val.first.split('(')
- name = interpret_identifier parts.first
- result = Terms::Function.new(name, [Terms::String.new(interpret_string_no_quote(parts.last))])
-
- result
- end
-.,.,
-
-# reduce 199 omitted
-
-# reduce 200 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 595)
- def _reduce_201(val, _values, result)
- result = Terms::Math.new(val.first.split('(').first, val[1])
-
- result
- end
-.,.,
-
-# reduce 202 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 601)
- def _reduce_203(val, _values, result)
- val.insert(1, ' '); result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 602)
- def _reduce_204(val, _values, result)
- val.insert(1, ' '); result = val.join('')
- result
- end
-.,.,
-
-# reduce 205 omitted
-
-module_eval(<<'.,.,', 'csspool.y', 606)
- def _reduce_206(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 607)
- def _reduce_207(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 610)
- def _reduce_208(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 611)
- def _reduce_209(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 612)
- def _reduce_210(val, _values, result)
- result = val.join('')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 615)
- def _reduce_211(val, _values, result)
- result = val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 616)
- def _reduce_212(val, _values, result)
- result = Terms::Hash.new val.first.sub(/^#/, '')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 619)
- def _reduce_213(val, _values, result)
- result = val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 620)
- def _reduce_214(val, _values, result)
- result = Terms::URI.new interpret_uri val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 623)
- def _reduce_215(val, _values, result)
- result = val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 624)
- def _reduce_216(val, _values, result)
- result = Terms::String.new interpret_string val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 628)
- def _reduce_217(val, _values, result)
- result = val[1]
- val[1].unary_operator = val.first
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 632)
- def _reduce_218(val, _values, result)
- result = Terms::Number.new numeric val.first
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 635)
- def _reduce_219(val, _values, result)
- result = Terms::Number.new numeric(val.first), nil, '%'
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 638)
- def _reduce_220(val, _values, result)
- unit = val.first.gsub(/[\s\d.]/, '')
- result = Terms::Number.new numeric(val.first), nil, unit
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 642)
- def _reduce_221(val, _values, result)
- unit = val.first.gsub(/[\s\d.]/, '')
- result = Terms::Number.new numeric(val.first), nil, unit
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 646)
- def _reduce_222(val, _values, result)
- unit = val.first.gsub(/[\s\d.]/, '')
- result = Terms::Number.new numeric(val.first), nil, unit
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 650)
- def _reduce_223(val, _values, result)
- unit = val.first.gsub(/[\s\d.]/, '')
- result = Terms::Number.new numeric(val.first), nil, unit
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 656)
- def _reduce_224(val, _values, result)
- result = Terms::Ratio.new(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 660)
- def _reduce_225(val, _values, result)
- result = :minus
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 661)
- def _reduce_226(val, _values, result)
- result = :plus
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 664)
- def _reduce_227(val, _values, result)
- result = val.first
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'csspool.y', 665)
- def _reduce_228(val, _values, result)
- result = Terms::Ident.new interpret_identifier val.first
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
- end # module CSS
-end # module CSSPool
diff --git a/test/racc/regress/edtf b/test/racc/regress/edtf
deleted file mode 100644
index 5947931260..0000000000
--- a/test/racc/regress/edtf
+++ /dev/null
@@ -1,1794 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-require 'strscan'
-
-module EDTF
- class Parser < Racc::Parser
-
-module_eval(<<'...end edtf.y/module_eval...', 'edtf.y', 468)
-
- @defaults = {
- :level => 2,
- :debug => false
- }.freeze
-
- class << self; attr_reader :defaults; end
-
- attr_reader :options
-
- def initialize(options = {})
- @options = Parser.defaults.merge(options)
- end
-
- def debug?
- !!(options[:debug] || ENV['DEBUG'])
- end
-
- def parse(input)
- parse!(input)
- rescue => e
- warn e.message if debug?
- nil
- end
-
- def parse!(input)
- @yydebug = debug?
- @src = StringScanner.new(input)
- do_parse
- end
-
- def on_error(tid, value, stack)
- raise ArgumentError,
- "failed to parse date: unexpected '#{value}' at #{stack.inspect}"
- end
-
- def apply_uncertainty(date, uncertainty, scope = nil)
- uncertainty.each do |u|
- scope.nil? ? date.send(u) : date.send(u, scope)
- end
- date
- end
-
- alias uoa apply_uncertainty
-
- def next_token
- case
- when @src.eos?
- nil
- # when @src.scan(/\s+/)
- # ignore whitespace
- when @src.scan(/\(/)
- ['(', @src.matched]
- # when @src.scan(/\)\?~-/)
- # [:PUA, [:uncertain!, :approximate!]]
- # when @src.scan(/\)\?-/)
- # [:PUA, [:uncertain!]]
- # when @src.scan(/\)~-/)
- # [:PUA, [:approximate!]]
- when @src.scan(/\)/)
- [')', @src.matched]
- when @src.scan(/\[/)
- ['[', @src.matched]
- when @src.scan(/\]/)
- [']', @src.matched]
- when @src.scan(/\{/)
- ['{', @src.matched]
- when @src.scan(/\}/)
- ['}', @src.matched]
- when @src.scan(/T/)
- [:T, @src.matched]
- when @src.scan(/Z/)
- [:Z, @src.matched]
- when @src.scan(/\?~/)
- [:UA, [:uncertain!, :approximate!]]
- when @src.scan(/\?/)
- [:UA, [:uncertain!]]
- when @src.scan(/~/)
- [:UA, [:approximate!]]
- when @src.scan(/open/i)
- [:OPEN, :open]
- when @src.scan(/unkn?own/i) # matches 'unkown' typo too
- [:UNKNOWN, :unknown]
- when @src.scan(/u/)
- [:U, @src.matched]
- when @src.scan(/x/i)
- [:X, @src.matched]
- when @src.scan(/y/)
- [:LONGYEAR, @src.matched]
- when @src.scan(/e/)
- [:E, @src.matched]
- when @src.scan(/\+/)
- ['+', @src.matched]
- when @src.scan(/-\(/)
- ['-(', @src.matched]
- when @src.scan(/-/)
- ['-', @src.matched]
- when @src.scan(/:/)
- [':', @src.matched]
- when @src.scan(/\//)
- ['/', @src.matched]
- when @src.scan(/\s*\.\.\s*/)
- [:DOTS, '..']
- when @src.scan(/\s*,\s*/)
- [',', ',']
- when @src.scan(/\^\w+/)
- ['^', @src.matched[1..-1]]
- when @src.scan(/\d/)
- [@src.matched, @src.matched.to_i]
- else @src.scan(/./)
- [:UNMATCHED, @src.rest]
- end
- end
-
-
-# -*- racc -*-
-...end edtf.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 129, 128, 52, 111, 51, 112, 149, 208, 207, 57,
- -50, 43, 45, 40, 55, 42, 54, 44, 43, 45,
- 40, -48, 42, 53, 44, 64, 58, 46, 47, 48,
- 49, 50, 128, 56, 46, 47, 48, 49, 50, 207,
- 57, 65, 43, 45, 40, 55, 42, 157, 44, 43,
- 45, 40, 55, 42, 214, 44, 92, 58, 46, 47,
- 48, 49, 50, 66, 56, 46, 47, 48, 49, 50,
- 25, 56, 26, 93, 94, 67, 108, 12, -65, 43,
- 45, 40, -66, 42, 159, 44, 110, 33, 111, 34,
- 112, 95, 36, 25, 141, 46, 47, 48, 49, 50,
- 12, 58, 43, 45, 40, 101, 42, 103, 44, 104,
- 96, 148, 55, 133, 147, 36, 124, 125, 46, 47,
- 48, 49, 50, 87, 165, 111, 12, 112, 43, 45,
- 40, 56, 42, 146, 44, 166, 111, 150, 112, 218,
- 167, 36, 152, 153, 46, 47, 48, 49, 50, 87,
- 108, 111, 12, 112, 43, 45, 40, 188, 42, 186,
- 44, 187, 111, 190, 112, 154, 111, 36, 112, 156,
- 46, 47, 48, 49, 50, 69, 158, 43, 45, 189,
- 191, 42, 12, 44, 43, 45, 40, 200, 42, 201,
- 44, 168, 177, 46, 47, 48, 49, 50, 233, 178,
- 46, 47, 48, 49, 50, 12, 180, 43, 45, 40,
- 111, 42, 112, 44, 232, 234, 111, 240, 112, 239,
- 36, 192, 193, 46, 47, 48, 49, 50, 12, 202,
- 43, 45, 40, 118, 42, 117, 44, 104, 118, 121,
- 117, 209, 104, 36, 121, 210, 46, 47, 48, 49,
- 50, 12, 212, 43, 45, 40, 244, 42, 239, 44,
- 213, 43, 45, 40, 215, 42, 36, 44, 229, 46,
- 47, 48, 49, 50, 180, 180, 236, 46, 47, 48,
- 49, 50, 43, 45, 40, 253, 42, 254, 44, 43,
- 45, 40, 255, 42, 258, 44, 261, 264, 46, 47,
- 48, 49, 50, 124, 125, 46, 47, 48, 49, 50,
- 43, 45, 40, 265, 42, 192, 44, 43, 45, 266,
- 269, 42, 270, 44, 275, 280, 46, 47, 48, 49,
- 50, 284, 285, 46, 47, 48, 49, 50, 43, 45,
- 40, 286, 42, 290, 44, 43, 45, 292, 293, 42,
- 295, 44, 296, 297, 46, 47, 48, 49, 50, 300,
- 301, 46, 47, 48, 49, 50, 43, 45, 40, 180,
- 42, 303, 44, 43, 45, 40, 304, 42, 305, 44,
- 281, 306, 46, 47, 48, 49, 50, 307, 308, 46,
- 47, 48, 49, 50, 43, 45, 175, 311, 42, 312,
- 44, 43, 45, 40, 313, 42, 314, 44, 316, 317,
- 46, 47, 48, 49, 50, 318, 319, 46, 47, 48,
- 49, 50, 43, 45, nil, nil, 42, nil, 44, 43,
- 45, nil, nil, 42, nil, 44, nil, nil, 46, 47,
- 48, 49, 50, nil, nil, 46, 47, 48, 49, 50,
- 172, 194, 170, nil, 171, nil, 173, 43, 45, 40,
- nil, 42, nil, 44, nil, nil, 195, 196, 197, 198,
- 199, nil, nil, 46, 47, 48, 49, 50, 43, 45,
- 40, nil, 42, nil, 44, 43, 45, 40, nil, 42,
- nil, 44, nil, nil, 46, 47, 48, 49, 50, nil,
- nil, 46, 47, 48, 49, 50, 43, 45, 40, nil,
- 42, nil, 44, 43, 45, nil, nil, 42, nil, 44,
- nil, nil, 46, 47, 48, 49, 50, nil, nil, 46,
- 47, 48, 49, 50, 43, 45, 40, nil, 42, nil,
- 44, 43, 45, 40, nil, 42, nil, 44, nil, nil,
- 46, 47, 48, 49, 50, nil, nil, 46, 47, 48,
- 49, 50, 43, 45, 40, nil, 42, nil, 44, 43,
- 45, 40, nil, 42, nil, 44, nil, nil, 46, 47,
- 48, 49, 50, nil, nil, 46, 47, 48, 49, 50,
- 43, 45, nil, nil, 42, nil, 44, 43, 45, 40,
- nil, 42, nil, 44, nil, nil, 46, 47, 48, 49,
- 50, nil, nil, 46, 47, 48, 49, 50, 43, 45,
- 40, nil, 42, nil, 44, 43, 45, 273, nil, 42,
- nil, 44, nil, nil, 46, 47, 48, 49, 50, nil,
- nil, 46, 47, 48, 49, 50, 43, 45, 274, nil,
- 42, nil, 44, 43, 45, 276, nil, 42, nil, 44,
- nil, nil, 46, 47, 48, 49, 50, nil, nil, 46,
- 47, 48, 49, 50, 43, 45, 40, nil, 42, nil,
- 44, 43, 45, 40, nil, 42, nil, 44, nil, nil,
- 46, 47, 48, 49, 50, nil, nil, 46, 47, 48,
- 49, 50, 43, 45, 40, nil, 42, nil, 44, 43,
- 45, 40, nil, 42, nil, 44, nil, nil, 46, 47,
- 48, 49, 50, nil, nil, 46, 47, 48, 49, 50,
- 43, 45, 40, nil, 42, nil, 44, 43, 45, 315,
- nil, 42, nil, 44, nil, nil, 46, 47, 48, 49,
- 50, 116, nil, 46, 47, 48, 49, 50, 118, 250,
- 247, 118, 104, 117, 249, 104, 260, 121, nil, 281,
- nil, nil, nil, nil, 251, nil, 118, 288, 117, 118,
- 104, 117, 121, 104, 118, 121, 117, 118, 104, 117,
- 121, 104, nil, 121, 118, 250, 247, nil, 104, nil,
- 249, 118, 250, 247, nil, 104, nil, 249, nil, nil,
- 251, nil, 118, 250, 117, nil, 104, 251, 249, 118,
- 250, 310, nil, 104, nil, 249, nil, nil, 251, nil,
- 172, 169, 170, nil, 171, 251, 173, 182, 184, nil,
- 118, 181, 117, 183, 104, 118, 121, 117, 118, 104,
- 117, 121, 104, 118, 121, 117, 118, 104, 117, 121,
- 104, 118, 121, 117, nil, 104, nil, 121, 188, 271,
- 186, 118, 187, 117, 272, 104, nil, 121 ]
-
-racc_action_check = [
- 63, 63, 5, 56, 1, 56, 73, 127, 127, 73,
- 14, 63, 63, 63, 9, 63, 9, 63, 127, 127,
- 127, 5, 127, 5, 127, 16, 73, 63, 63, 63,
- 63, 63, 151, 9, 127, 127, 127, 127, 127, 224,
- 10, 17, 151, 151, 151, 89, 151, 89, 151, 224,
- 224, 224, 134, 224, 134, 224, 37, 10, 151, 151,
- 151, 151, 151, 18, 89, 224, 224, 224, 224, 224,
- 0, 134, 0, 37, 38, 22, 54, 0, 23, 0,
- 0, 0, 24, 0, 91, 0, 54, 0, 54, 0,
- 54, 38, 0, 67, 67, 0, 0, 0, 0, 0,
- 67, 91, 67, 67, 67, 52, 67, 52, 67, 52,
- 51, 72, 72, 66, 72, 67, 59, 60, 67, 67,
- 67, 67, 67, 33, 98, 66, 33, 66, 33, 33,
- 33, 72, 33, 71, 33, 98, 92, 74, 92, 147,
- 98, 33, 77, 78, 33, 33, 33, 33, 33, 34,
- 214, 147, 34, 147, 34, 34, 34, 112, 34, 112,
- 34, 112, 214, 113, 214, 79, 93, 34, 93, 88,
- 34, 34, 34, 34, 34, 26, 90, 26, 26, 113,
- 113, 26, 87, 26, 87, 87, 87, 121, 87, 121,
- 87, 99, 107, 26, 26, 26, 26, 26, 161, 108,
- 87, 87, 87, 87, 87, 153, 109, 153, 153, 153,
- 124, 153, 124, 153, 161, 161, 157, 166, 157, 166,
- 153, 115, 116, 153, 153, 153, 153, 153, 154, 123,
- 154, 154, 154, 58, 154, 58, 154, 58, 94, 58,
- 94, 128, 94, 154, 94, 129, 154, 154, 154, 154,
- 154, 265, 132, 265, 265, 265, 167, 265, 167, 265,
- 133, 12, 12, 12, 144, 12, 265, 12, 158, 265,
- 265, 265, 265, 265, 160, 162, 163, 12, 12, 12,
- 12, 12, 13, 13, 13, 169, 13, 178, 13, 36,
- 36, 36, 189, 36, 202, 36, 213, 218, 13, 13,
- 13, 13, 13, 220, 222, 36, 36, 36, 36, 36,
- 62, 62, 62, 225, 62, 230, 62, 64, 64, 232,
- 236, 64, 238, 64, 245, 253, 62, 62, 62, 62,
- 62, 256, 257, 64, 64, 64, 64, 64, 68, 68,
- 68, 260, 68, 264, 68, 69, 69, 267, 268, 69,
- 271, 69, 273, 274, 68, 68, 68, 68, 68, 280,
- 281, 69, 69, 69, 69, 69, 70, 70, 70, 283,
- 70, 284, 70, 75, 75, 75, 285, 75, 288, 75,
- 290, 292, 70, 70, 70, 70, 70, 293, 295, 75,
- 75, 75, 75, 75, 103, 103, 103, 300, 103, 304,
- 103, 104, 104, 104, 307, 104, 308, 104, 311, 312,
- 103, 103, 103, 103, 103, 313, 316, 104, 104, 104,
- 104, 104, 111, 111, nil, nil, 111, nil, 111, 117,
- 117, nil, nil, 117, nil, 117, nil, nil, 111, 111,
- 111, 111, 111, nil, nil, 117, 117, 117, 117, 117,
- 118, 118, 118, nil, 118, nil, 118, 126, 126, 126,
- nil, 126, nil, 126, nil, nil, 118, 118, 118, 118,
- 118, nil, nil, 126, 126, 126, 126, 126, 130, 130,
- 130, nil, 130, nil, 130, 143, 143, 143, nil, 143,
- nil, 143, nil, nil, 130, 130, 130, 130, 130, nil,
- nil, 143, 143, 143, 143, 143, 145, 145, 145, nil,
- 145, nil, 145, 146, 146, nil, nil, 146, nil, 146,
- nil, nil, 145, 145, 145, 145, 145, nil, nil, 146,
- 146, 146, 146, 146, 148, 148, 148, nil, 148, nil,
- 148, 149, 149, 149, nil, 149, nil, 149, nil, nil,
- 148, 148, 148, 148, 148, nil, nil, 149, 149, 149,
- 149, 149, 150, 150, 150, nil, 150, nil, 150, 205,
- 205, 205, nil, 205, nil, 205, nil, nil, 150, 150,
- 150, 150, 150, nil, nil, 205, 205, 205, 205, 205,
- 215, 215, nil, nil, 215, nil, 215, 216, 216, 216,
- nil, 216, nil, 216, nil, nil, 215, 215, 215, 215,
- 215, nil, nil, 216, 216, 216, 216, 216, 217, 217,
- 217, nil, 217, nil, 217, 240, 240, 240, nil, 240,
- nil, 240, nil, nil, 217, 217, 217, 217, 217, nil,
- nil, 240, 240, 240, 240, 240, 244, 244, 244, nil,
- 244, nil, 244, 247, 247, 247, nil, 247, nil, 247,
- nil, nil, 244, 244, 244, 244, 244, nil, nil, 247,
- 247, 247, 247, 247, 249, 249, 249, nil, 249, nil,
- 249, 250, 250, 250, nil, 250, nil, 250, nil, nil,
- 249, 249, 249, 249, 249, nil, nil, 250, 250, 250,
- 250, 250, 251, 251, 251, nil, 251, nil, 251, 262,
- 262, 262, nil, 262, nil, 262, nil, nil, 251, 251,
- 251, 251, 251, nil, nil, 262, 262, 262, 262, 262,
- 263, 263, 263, nil, 263, nil, 263, 310, 310, 310,
- nil, 310, nil, 310, nil, nil, 263, 263, 263, 263,
- 263, 57, nil, 310, 310, 310, 310, 310, 168, 168,
- 168, 57, 168, 57, 168, 57, 212, 57, nil, 254,
- nil, nil, nil, nil, 168, nil, 212, 261, 212, 254,
- 212, 254, 212, 254, 95, 254, 95, 261, 95, 261,
- 95, 261, nil, 261, 270, 270, 270, nil, 270, nil,
- 270, 275, 275, 275, nil, 275, nil, 275, nil, nil,
- 270, nil, 296, 296, 296, nil, 296, 275, 296, 297,
- 297, 297, nil, 297, nil, 297, nil, nil, 296, nil,
- 101, 101, 101, nil, 101, 297, 101, 110, 110, nil,
- 125, 110, 125, 110, 125, 159, 125, 159, 190, 159,
- 190, 159, 190, 191, 190, 191, 233, 191, 233, 191,
- 233, 234, 233, 234, nil, 234, nil, 234, 239, 239,
- 239, 255, 239, 255, 239, 255, nil, 255 ]
-
-racc_action_pointer = [
- 63, 4, nil, nil, nil, 0, nil, nil, nil, 2,
- 26, nil, 245, 266, -11, nil, 21, 18, 49, nil,
- nil, nil, 54, 78, 82, nil, 161, nil, nil, nil,
- nil, nil, nil, 112, 138, nil, 273, 42, 60, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 110, 89, nil, 70, nil, -15, 745, 217, 102,
- 103, nil, 294, -5, 301, nil, 107, 86, 322, 329,
- 350, 129, 100, -5, 126, 357, nil, 117, 115, 137,
- nil, nil, nil, nil, nil, nil, nil, 168, 142, 33,
- 146, 70, 118, 148, 222, 768, nil, nil, 121, 176,
- nil, 814, nil, 378, 385, nil, nil, 180, 193, 194,
- 821, 406, 141, 149, nil, 209, 216, 413, 434, nil,
- nil, 169, nil, 199, 192, 824, 441, 2, 235, 240,
- 462, nil, 238, 254, 40, nil, nil, nil, nil, nil,
- nil, nil, nil, 469, 260, 490, 497, 133, 518, 525,
- 546, 26, nil, 191, 214, nil, nil, 198, 256, 829,
- 262, 184, 263, 246, nil, nil, 199, 238, 742, 270,
- nil, nil, nil, nil, nil, nil, nil, nil, 273, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 280,
- 832, 837, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 282, nil, nil, 553, nil, nil, nil, nil,
- nil, nil, 760, 282, 144, 574, 581, 602, 291, nil,
- 289, nil, 290, nil, 33, 285, nil, nil, nil, nil,
- 303, nil, 307, 840, 845, nil, 308, nil, 307, 852,
- 609, nil, nil, nil, 630, 309, nil, 637, nil, 658,
- 665, 686, nil, 307, 763, 855, 301, 302, nil, nil,
- 335, 771, 693, 714, 329, 237, nil, 317, 318, nil,
- 778, 335, nil, 337, 338, 785, nil, nil, nil, nil,
- 341, 354, nil, 357, 359, 364, nil, nil, 372, nil,
- 374, nil, 369, 375, nil, 370, 796, 803, nil, nil,
- 382, nil, nil, nil, 369, nil, nil, 374, 388, nil,
- 721, 390, 397, 403, nil, nil, 398, nil, nil, nil ]
-
-racc_action_default = [
- -176, -176, -1, -2, -3, -4, -5, -6, -7, -8,
- -9, -10, -176, -176, -34, -35, -36, -37, -38, -39,
- -40, -41, -176, -49, -51, -52, -176, -64, -67, -68,
- -69, -70, -71, -176, -176, -107, -176, -109, -110, -111,
- -128, -129, -130, -131, -132, -133, -134, -135, -136, -137,
- -138, -176, -176, -76, -176, -112, -176, -176, -176, -8,
- -9, -11, -176, -176, -176, -72, -176, -176, -55, -176,
- -170, -176, -8, -9, -10, -176, -38, -176, -81, -86,
- -87, -88, -90, -91, -92, -93, -94, -176, -176, -176,
- -176, -176, -176, -176, -176, -176, 320, -12, -13, -176,
- -16, -176, -31, -176, -176, -152, -27, -29, -176, -126,
- -176, -176, -176, -176, -28, -30, -176, -176, -176, -153,
- -160, -176, -162, -176, -176, -176, -176, -176, -176, -176,
- -73, -174, -176, -176, -8, -47, -48, -49, -50, -51,
- -53, -54, -58, -56, -176, -171, -176, -176, -98, -97,
- -96, -176, -79, -176, -176, -95, -80, -176, -176, -176,
- -126, -176, -126, -176, -14, -18, -176, -176, -176, -176,
- -147, -148, -149, -150, -145, -151, -146, -114, -44, -59,
- -127, -60, -61, -62, -63, -139, -140, -141, -142, -176,
- -176, -176, -120, -45, -154, -155, -156, -157, -158, -159,
- -161, -163, -176, -29, -30, -176, -26, -42, -77, -43,
- -78, -175, -176, -176, -176, -176, -172, -74, -176, -101,
- -176, -100, -176, -99, -176, -83, -84, -85, -89, -108,
- -176, -113, -176, -176, -176, -117, -176, -19, -176, -176,
- -176, -143, -20, -21, -176, -176, -32, -176, -164, -176,
- -176, -176, -169, -176, -176, -115, -176, -176, -121, -102,
- -176, -176, -75, -173, -44, -176, -116, -176, -176, -118,
- -176, -176, -144, -176, -176, -176, -168, -165, -166, -167,
- -176, -176, -106, -126, -176, -176, -105, -103, -176, -57,
- -176, -82, -176, -176, -23, -176, -176, -176, -15, -33,
- -176, -46, -119, -122, -176, -104, -124, -176, -176, -25,
- -176, -176, -176, -176, -24, -22, -176, -123, -125, -17 ]
-
-racc_goto_table = [
- 70, 179, 130, 13, 228, 11, 248, 115, 123, 226,
- 227, 113, 245, 5, 14, 9, 63, 11, 68, 10,
- 18, 132, 22, 23, 71, 1, 24, 59, 237, 243,
- 2, 60, 309, 309, 241, 241, 75, 75, 131, 77,
- 88, 3, 4, 70, 162, 163, 6, 160, 161, 61,
- 97, 89, 231, 98, 235, 91, 164, 99, 298, 100,
- 242, 143, 102, 299, 15, 126, 127, 144, 16, 17,
- 75, 142, 11, 145, 135, 204, 109, 174, 151, 203,
- 136, 138, 134, 27, 217, 185, 10, 18, 28, 140,
- 137, 174, 11, 139, 29, 30, 31, 32, 225, 90,
- 155, 105, 59, nil, nil, nil, 60, 176, 248, 230,
- nil, nil, nil, 248, 294, 228, nil, nil, nil, nil,
- 131, 291, nil, nil, nil, nil, nil, nil, nil, 205,
- 206, nil, nil, 211, 248, 248, nil, nil, nil, nil,
- 256, 257, nil, nil, nil, nil, 142, nil, 216, nil,
- nil, nil, nil, 262, 224, 223, 75, 75, nil, nil,
- nil, nil, 259, 219, 220, 220, nil, nil, 221, 222,
- nil, nil, nil, nil, nil, 302, nil, nil, nil, nil,
- nil, nil, nil, 267, 268, nil, nil, nil, nil, 131,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 282, 283, nil, nil, 206, nil,
- nil, 287, nil, nil, 185, nil, nil, nil, 185, 263,
- 211, 174, nil, nil, nil, nil, nil, 206, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 277, 278, 279, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 211, 289, nil, 75, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 174 ]
-
-racc_goto_check = [
- 43, 45, 52, 23, 58, 11, 66, 26, 26, 57,
- 57, 24, 16, 5, 30, 9, 23, 11, 42, 10,
- 34, 24, 38, 40, 53, 1, 41, 9, 19, 19,
- 2, 10, 22, 22, 25, 25, 23, 23, 43, 54,
- 54, 3, 4, 43, 26, 26, 6, 24, 24, 7,
- 12, 9, 45, 13, 45, 10, 14, 15, 17, 18,
- 20, 42, 28, 29, 31, 23, 23, 53, 32, 33,
- 23, 23, 11, 23, 39, 26, 44, 43, 23, 24,
- 5, 30, 9, 46, 52, 43, 10, 34, 47, 38,
- 40, 43, 11, 41, 48, 49, 50, 51, 56, 61,
- 5, 65, 9, nil, nil, nil, 10, 23, 66, 26,
- nil, nil, nil, 66, 16, 58, nil, nil, nil, nil,
- 43, 57, nil, nil, nil, nil, nil, nil, nil, 23,
- 23, nil, nil, 23, 66, 66, nil, nil, nil, nil,
- 26, 26, nil, nil, nil, nil, 23, nil, 23, nil,
- nil, nil, nil, 52, 23, 11, 23, 23, nil, nil,
- nil, nil, 26, 9, 9, 9, nil, nil, 10, 10,
- nil, nil, nil, nil, nil, 45, nil, nil, nil, nil,
- nil, nil, nil, 26, 26, nil, nil, nil, nil, 43,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 26, 26, nil, nil, 23, nil,
- nil, 26, nil, nil, 43, nil, nil, nil, 43, 23,
- 23, 43, nil, nil, nil, nil, nil, 23, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 23, 23, 23, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 23, 23, nil, 23, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 43 ]
-
-racc_goto_pointer = [
- nil, 25, 30, 41, 42, 13, 46, 37, nil, 15,
- 19, 5, -2, 1, -42, 5, -156, -217, 7, -138,
- -107, nil, -264, 3, -45, -132, -50, nil, 10, -212,
- 14, 64, 68, 69, 20, nil, nil, nil, 22, 7,
- 23, 26, -8, -26, 22, -108, 83, 88, 94, 95,
- 96, 97, -62, -2, 6, nil, -55, -144, -150, nil,
- nil, 63, nil, nil, nil, 49, -162, nil ]
-
-racc_goto_default = [
- nil, nil, nil, nil, nil, 84, nil, 7, 8, 72,
- 73, 74, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 238, 252, 62, 107, 106, nil, 114, nil, 246,
- 86, nil, nil, nil, 76, 19, 20, 21, nil, nil,
- 85, nil, nil, 41, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 78, 79, 80, 81, 82,
- 83, 35, 37, 38, 39, 119, 120, 122 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 38, :_reduce_none,
- 1, 38, :_reduce_none,
- 1, 38, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 42, :_reduce_none,
- 1, 42, :_reduce_none,
- 1, 44, :_reduce_8,
- 1, 44, :_reduce_9,
- 1, 44, :_reduce_10,
- 2, 45, :_reduce_11,
- 3, 43, :_reduce_12,
- 1, 49, :_reduce_none,
- 2, 49, :_reduce_14,
- 5, 50, :_reduce_15,
- 1, 50, :_reduce_none,
- 8, 55, :_reduce_17,
- 1, 51, :_reduce_18,
- 2, 51, :_reduce_19,
- 2, 51, :_reduce_20,
- 1, 57, :_reduce_none,
- 5, 57, :_reduce_22,
- 3, 56, :_reduce_23,
- 5, 56, :_reduce_24,
- 4, 56, :_reduce_25,
- 4, 46, :_reduce_26,
- 1, 61, :_reduce_none,
- 1, 63, :_reduce_none,
- 3, 47, :_reduce_29,
- 3, 48, :_reduce_30,
- 1, 52, :_reduce_none,
- 1, 53, :_reduce_none,
- 1, 54, :_reduce_none,
- 1, 40, :_reduce_none,
- 1, 40, :_reduce_none,
- 1, 40, :_reduce_none,
- 1, 40, :_reduce_none,
- 1, 67, :_reduce_38,
- 1, 67, :_reduce_none,
- 1, 67, :_reduce_none,
- 1, 67, :_reduce_none,
- 4, 71, :_reduce_42,
- 4, 71, :_reduce_43,
- 4, 72, :_reduce_44,
- 4, 73, :_reduce_45,
- 7, 74, :_reduce_46,
- 3, 68, :_reduce_47,
- 1, 75, :_reduce_none,
- 1, 75, :_reduce_none,
- 1, 75, :_reduce_none,
- 1, 75, :_reduce_none,
- 1, 75, :_reduce_none,
- 1, 76, :_reduce_none,
- 1, 76, :_reduce_none,
- 2, 69, :_reduce_55,
- 3, 69, :_reduce_56,
- 5, 79, :_reduce_57,
- 2, 79, :_reduce_58,
- 4, 70, :_reduce_59,
- 2, 81, :_reduce_60,
- 2, 81, :_reduce_61,
- 2, 81, :_reduce_62,
- 2, 81, :_reduce_63,
- 1, 41, :_reduce_none,
- 1, 41, :_reduce_none,
- 1, 41, :_reduce_none,
- 1, 41, :_reduce_none,
- 1, 41, :_reduce_none,
- 1, 41, :_reduce_none,
- 1, 41, :_reduce_none,
- 1, 41, :_reduce_none,
- 2, 83, :_reduce_72,
- 3, 88, :_reduce_73,
- 4, 88, :_reduce_74,
- 5, 88, :_reduce_75,
- 2, 87, :_reduce_76,
- 4, 86, :_reduce_77,
- 4, 86, :_reduce_78,
- 3, 84, :_reduce_79,
- 3, 85, :_reduce_80,
- 1, 91, :_reduce_81,
- 5, 91, :_reduce_82,
- 3, 91, :_reduce_83,
- 3, 91, :_reduce_84,
- 3, 91, :_reduce_85,
- 1, 91, :_reduce_86,
- 1, 91, :_reduce_87,
- 1, 93, :_reduce_88,
- 3, 93, :_reduce_89,
- 1, 95, :_reduce_none,
- 1, 95, :_reduce_none,
- 1, 96, :_reduce_none,
- 1, 96, :_reduce_none,
- 1, 96, :_reduce_none,
- 2, 92, :_reduce_95,
- 2, 94, :_reduce_96,
- 2, 94, :_reduce_97,
- 2, 94, :_reduce_98,
- 3, 97, :_reduce_99,
- 3, 97, :_reduce_100,
- 3, 97, :_reduce_101,
- 5, 78, :_reduce_102,
- 6, 78, :_reduce_103,
- 7, 78, :_reduce_104,
- 6, 78, :_reduce_105,
- 6, 78, :_reduce_106,
- 1, 77, :_reduce_none,
- 4, 77, :_reduce_108,
- 1, 98, :_reduce_109,
- 1, 98, :_reduce_110,
- 1, 98, :_reduce_111,
- 2, 99, :_reduce_112,
- 4, 100, :_reduce_113,
- 4, 100, :_reduce_114,
- 5, 100, :_reduce_115,
- 5, 100, :_reduce_116,
- 4, 101, :_reduce_117,
- 5, 101, :_reduce_118,
- 7, 101, :_reduce_119,
- 4, 101, :_reduce_120,
- 5, 101, :_reduce_121,
- 7, 101, :_reduce_122,
- 9, 101, :_reduce_123,
- 7, 101, :_reduce_124,
- 9, 101, :_reduce_125,
- 0, 82, :_reduce_126,
- 1, 82, :_reduce_none,
- 1, 60, :_reduce_128,
- 1, 60, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_none,
- 2, 62, :_reduce_139,
- 2, 62, :_reduce_140,
- 2, 62, :_reduce_141,
- 2, 62, :_reduce_142,
- 1, 58, :_reduce_none,
- 2, 58, :_reduce_144,
- 2, 102, :_reduce_145,
- 2, 102, :_reduce_146,
- 2, 102, :_reduce_147,
- 2, 102, :_reduce_148,
- 2, 102, :_reduce_149,
- 2, 102, :_reduce_150,
- 2, 65, :_reduce_none,
- 1, 65, :_reduce_none,
- 1, 103, :_reduce_none,
- 2, 103, :_reduce_154,
- 2, 103, :_reduce_155,
- 2, 103, :_reduce_156,
- 2, 103, :_reduce_157,
- 2, 103, :_reduce_158,
- 2, 103, :_reduce_159,
- 1, 104, :_reduce_none,
- 2, 104, :_reduce_161,
- 1, 64, :_reduce_none,
- 2, 64, :_reduce_163,
- 1, 59, :_reduce_none,
- 2, 59, :_reduce_165,
- 2, 59, :_reduce_166,
- 2, 59, :_reduce_167,
- 2, 66, :_reduce_none,
- 1, 66, :_reduce_none,
- 1, 90, :_reduce_170,
- 2, 90, :_reduce_171,
- 3, 90, :_reduce_172,
- 4, 90, :_reduce_173,
- 1, 89, :_reduce_174,
- 2, 89, :_reduce_175 ]
-
-racc_reduce_n = 176
-
-racc_shift_n = 320
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :T => 2,
- :Z => 3,
- :E => 4,
- :X => 5,
- :U => 6,
- :UNKNOWN => 7,
- :OPEN => 8,
- :LONGYEAR => 9,
- :UNMATCHED => 10,
- :DOTS => 11,
- :UA => 12,
- :PUA => 13,
- "-" => 14,
- ":" => 15,
- "2" => 16,
- "4" => 17,
- "0" => 18,
- "+" => 19,
- "1" => 20,
- "/" => 21,
- "3" => 22,
- "^" => 23,
- "[" => 24,
- "]" => 25,
- "{" => 26,
- "}" => 27,
- "," => 28,
- "(" => 29,
- ")" => 30,
- "-(" => 31,
- "5" => 32,
- "6" => 33,
- "7" => 34,
- "8" => 35,
- "9" => 36 }
-
-racc_nt_base = 37
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "T",
- "Z",
- "E",
- "X",
- "U",
- "UNKNOWN",
- "OPEN",
- "LONGYEAR",
- "UNMATCHED",
- "DOTS",
- "UA",
- "PUA",
- "\"-\"",
- "\":\"",
- "\"2\"",
- "\"4\"",
- "\"0\"",
- "\"+\"",
- "\"1\"",
- "\"/\"",
- "\"3\"",
- "\"^\"",
- "\"[\"",
- "\"]\"",
- "\"{\"",
- "\"}\"",
- "\",\"",
- "\"(\"",
- "\")\"",
- "\"-(\"",
- "\"5\"",
- "\"6\"",
- "\"7\"",
- "\"8\"",
- "\"9\"",
- "$start",
- "edtf",
- "level_0_expression",
- "level_1_expression",
- "level_2_expression",
- "date",
- "date_time",
- "positive_date",
- "negative_date",
- "year",
- "year_month",
- "year_month_day",
- "time",
- "base_time",
- "zone_offset",
- "hour",
- "minute",
- "second",
- "midnight",
- "zone_offset_hour",
- "positive_zone_offset",
- "d01_13",
- "d01_59",
- "digit",
- "month",
- "d01_12",
- "day",
- "d01_31",
- "d00_23",
- "d00_59",
- "unspecified",
- "level_1_interval",
- "long_year_simple",
- "season",
- "unspecified_year",
- "unspecified_month",
- "unspecified_day",
- "unspecified_day_and_month",
- "level_1_start",
- "level_1_end",
- "partial_uncertain_or_approximate",
- "partial_unspecified",
- "long_year",
- "positive_digit",
- "season_number",
- "ua",
- "season_qualified",
- "choice_list",
- "inclusive_list",
- "masked_precision",
- "date_and_calendar",
- "long_year_scientific",
- "integer",
- "int1_4",
- "list",
- "earlier",
- "list_elements",
- "later",
- "list_element",
- "atomic",
- "consecutives",
- "pua_base",
- "pua_year",
- "pua_year_month",
- "pua_year_month_day",
- "d01_23",
- "d01_29",
- "d01_30" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-# reduce 1 omitted
-
-# reduce 2 omitted
-
-# reduce 3 omitted
-
-# reduce 4 omitted
-
-# reduce 5 omitted
-
-# reduce 6 omitted
-
-# reduce 7 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 54)
- def _reduce_8(val, _values, result)
- result = Date.new(val[0]).year_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 55)
- def _reduce_9(val, _values, result)
- result = Date.new(*val.flatten).month_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 56)
- def _reduce_10(val, _values, result)
- result = Date.new(*val.flatten).day_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 59)
- def _reduce_11(val, _values, result)
- result = -val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 63)
- def _reduce_12(val, _values, result)
- result = DateTime.new(val[0].year, val[0].month, val[0].day, *val[2])
- result.skip_timezone = (val[2].length == 3)
-
- result
- end
-.,.,
-
-# reduce 13 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 68)
- def _reduce_14(val, _values, result)
- result = val.flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 70)
- def _reduce_15(val, _values, result)
- result = val.values_at(0, 2, 4)
- result
- end
-.,.,
-
-# reduce 16 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 73)
- def _reduce_17(val, _values, result)
- result = [24, 0, 0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 75)
- def _reduce_18(val, _values, result)
- result = 0
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 76)
- def _reduce_19(val, _values, result)
- result = -1 * val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 77)
- def _reduce_20(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-# reduce 21 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 81)
- def _reduce_22(val, _values, result)
- result = 0
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 85)
- def _reduce_23(val, _values, result)
- result = Rational(val[0] * 60 + val[2], 1440)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 86)
- def _reduce_24(val, _values, result)
- result = Rational(840, 1440)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 87)
- def _reduce_25(val, _values, result)
- result = Rational(val[3], 1440)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 91)
- def _reduce_26(val, _values, result)
- result = val.zip([1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
-
- result
- end
-.,.,
-
-# reduce 27 omitted
-
-# reduce 28 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 97)
- def _reduce_29(val, _values, result)
- result = [val[0], val[2]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 104)
- def _reduce_30(val, _values, result)
- result = val[0] << val[2]
- if result[2] > 31 || (result[2] > 30 && [2,4,6,9,11].include?(result[1])) || (result[2] > 29 && result[1] == 2)
- raise ArgumentError, "invalid date (invalid days #{result[2]} for month #{result[1]})"
- end
-
- result
- end
-.,.,
-
-# reduce 31 omitted
-
-# reduce 32 omitted
-
-# reduce 33 omitted
-
-# reduce 34 omitted
-
-# reduce 35 omitted
-
-# reduce 36 omitted
-
-# reduce 37 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 127)
- def _reduce_38(val, _values, result)
- result = Date.new(val[0][0]).year_precision!
- result.unspecified.year[2,2] = val[0][1]
-
- result
- end
-.,.,
-
-# reduce 39 omitted
-
-# reduce 40 omitted
-
-# reduce 41 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 138)
- def _reduce_42(val, _values, result)
- result = [val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b }, [false,true]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 142)
- def _reduce_43(val, _values, result)
- result = [val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b }, [true, true]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 146)
- def _reduce_44(val, _values, result)
- result = Date.new(val[0]).unspecified!(:month)
- result.precision = :month
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 151)
- def _reduce_45(val, _values, result)
- result = Date.new(*val[0]).unspecified!(:day)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 155)
- def _reduce_46(val, _values, result)
- result = Date.new(val[0]).unspecified!([:day,:month])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 160)
- def _reduce_47(val, _values, result)
- result = Interval.new(val[0], val[2])
-
- result
- end
-.,.,
-
-# reduce 48 omitted
-
-# reduce 49 omitted
-
-# reduce 50 omitted
-
-# reduce 51 omitted
-
-# reduce 52 omitted
-
-# reduce 53 omitted
-
-# reduce 54 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 171)
- def _reduce_55(val, _values, result)
- result = Date.new(val[1])
- result.precision = :year
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 176)
- def _reduce_56(val, _values, result)
- result = Date.new(-1 * val[2])
- result.precision = :year
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 183)
- def _reduce_57(val, _values, result)
- result = val.zip([10000,1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 185)
- def _reduce_58(val, _values, result)
- result = 10 * val[0] + val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 190)
- def _reduce_59(val, _values, result)
- result = Season.new(val[0], val[2])
- val[3].each { |ua| result.send(ua) }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 194)
- def _reduce_60(val, _values, result)
- result = 21
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 195)
- def _reduce_61(val, _values, result)
- result = 22
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 196)
- def _reduce_62(val, _values, result)
- result = 23
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 197)
- def _reduce_63(val, _values, result)
- result = 24
- result
- end
-.,.,
-
-# reduce 64 omitted
-
-# reduce 65 omitted
-
-# reduce 66 omitted
-
-# reduce 67 omitted
-
-# reduce 68 omitted
-
-# reduce 69 omitted
-
-# reduce 70 omitted
-
-# reduce 71 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 215)
- def _reduce_72(val, _values, result)
- result = val[0]; result.qualifier = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 221)
- def _reduce_73(val, _values, result)
- result = Date.new(val[0].year * 10 ** val[2]).year_precision!
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 225)
- def _reduce_74(val, _values, result)
- result = Date.new(val[1] * 10 ** val[3]).year_precision!
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 229)
- def _reduce_75(val, _values, result)
- result = Date.new(-1 * val[2] * 10 ** val[4]).year_precision!
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 234)
- def _reduce_76(val, _values, result)
- result = val[0]; result.calendar = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 240)
- def _reduce_77(val, _values, result)
- d = val[0,3].zip([1000,100,10]).reduce(0) { |s,(a,b)| s += a * b }
- result = EDTF::Decade.new(d)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 245)
- def _reduce_78(val, _values, result)
- d = val[0,2].zip([1000,100]).reduce(0) { |s,(a,b)| s += a * b }
- result = EDTF::Century.new(d)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 251)
- def _reduce_79(val, _values, result)
- result = val[1].choice!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 253)
- def _reduce_80(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 255)
- def _reduce_81(val, _values, result)
- result = EDTF::Set.new(val[0]).earlier!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 256)
- def _reduce_82(val, _values, result)
- result = EDTF::Set.new([val[0]] + val[2] + [val[4]]).earlier!.later!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 257)
- def _reduce_83(val, _values, result)
- result = EDTF::Set.new([val[0]] + val[2]).earlier!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 258)
- def _reduce_84(val, _values, result)
- result = EDTF::Set.new([val[0]] + [val[2]]).earlier!.later!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 259)
- def _reduce_85(val, _values, result)
- result = EDTF::Set.new(val[0] + [val[2]]).later!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 260)
- def _reduce_86(val, _values, result)
- result = EDTF::Set.new(*val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 261)
- def _reduce_87(val, _values, result)
- result = EDTF::Set.new(val[0]).later!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 264)
- def _reduce_88(val, _values, result)
- result = [val[0]].flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 265)
- def _reduce_89(val, _values, result)
- result = val[0] + [val[2]].flatten
- result
- end
-.,.,
-
-# reduce 90 omitted
-
-# reduce 91 omitted
-
-# reduce 92 omitted
-
-# reduce 93 omitted
-
-# reduce 94 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 277)
- def _reduce_95(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 279)
- def _reduce_96(val, _values, result)
- result = Date.new(*val[0]).year_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 280)
- def _reduce_97(val, _values, result)
- result = Date.new(*val[0]).month_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 281)
- def _reduce_98(val, _values, result)
- result = Date.new(val[0]).year_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 284)
- def _reduce_99(val, _values, result)
- result = (Date.new(val[0]).day_precision! .. Date.new(val[2]).day_precision!)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 285)
- def _reduce_100(val, _values, result)
- result = (Date.new(val[0]).month_precision! .. Date.new(val[2]).month_precision!)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 286)
- def _reduce_101(val, _values, result)
- result = (Date.new(val[0]).year_precision! .. Date.new(val[2]).year_precision!)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 292)
- def _reduce_102(val, _values, result)
- result = Date.new(val[0][0], val[2], val[4])
- result.unspecified.year[2,2] = val[0][1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 297)
- def _reduce_103(val, _values, result)
- result = Date.new(val[0][0], 1, val[5])
- result.unspecified.year[2,2] = val[0][1]
- result.unspecified!(:month)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 303)
- def _reduce_104(val, _values, result)
- result = Date.new(val[0][0], 1, 1)
- result.unspecified.year[2,2] = val[0][1]
- result.unspecified!([:month, :day])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 309)
- def _reduce_105(val, _values, result)
- result = Date.new(val[0][0], val[2], 1)
- result.unspecified.year[2,2] = val[0][1]
- result.unspecified!(:day)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 315)
- def _reduce_106(val, _values, result)
- result = Date.new(val[0], 1, val[5])
- result.unspecified!(:month)
-
- result
- end
-.,.,
-
-# reduce 107 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 322)
- def _reduce_108(val, _values, result)
- result = uoa(val[1], val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 325)
- def _reduce_109(val, _values, result)
- result = val[0].year_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 326)
- def _reduce_110(val, _values, result)
- result = val[0][0].month_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 327)
- def _reduce_111(val, _values, result)
- result = val[0].day_precision!
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 329)
- def _reduce_112(val, _values, result)
- result = uoa(Date.new(val[0]), val[1], :year)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 333)
- def _reduce_113(val, _values, result)
- result = [uoa(val[0].change(:month => val[2]), val[3], [:month, :year])]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 336)
- def _reduce_114(val, _values, result)
- result = [uoa(Date.new(val[0], val[2]), val[3], [:year, :month])]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 339)
- def _reduce_115(val, _values, result)
- result = [uoa(Date.new(val[0], val[2]), val[4], [:month]), true]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 342)
- def _reduce_116(val, _values, result)
- result = [uoa(val[0].change(:month => val[2]), val[4], [:month]), true]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 348)
- def _reduce_117(val, _values, result)
- result = uoa(val[0][0].change(:day => val[2]), val[3], val[0][1] ? [:day] : nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 351)
- def _reduce_118(val, _values, result)
- result = uoa(val[0][0].change(:day => val[2]), val[4], [:day])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 354)
- def _reduce_119(val, _values, result)
- result = uoa(uoa(Date.new(val[0], val[2], val[5]), val[4], :month), val[6], :day)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 357)
- def _reduce_120(val, _values, result)
- result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 360)
- def _reduce_121(val, _values, result)
- result = uoa(Date.new(val[0][0], val[0][1], val[2]), val[4], [:day])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 363)
- def _reduce_122(val, _values, result)
- result = uoa(Date.new(val[0], val[2], val[4]), val[6], [:month, :day])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 366)
- def _reduce_123(val, _values, result)
- result = Date.new(val[0], val[2], val[4])
- result = uoa(result, val[6], [:day])
- result = uoa(result, val[8], [:month, :day])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 371)
- def _reduce_124(val, _values, result)
- result = val[0].change(:month => val[2], :day => val[4])
- result = uoa(result, val[6], [:month, :day])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 375)
- def _reduce_125(val, _values, result)
- result = val[0].change(:month => val[2], :day => val[4])
- result = uoa(result, val[6], [:day])
- result = uoa(result, val[8], [:month, :day])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 386)
- def _reduce_126(val, _values, result)
- result = []
- result
- end
-.,.,
-
-# reduce 127 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 390)
- def _reduce_128(val, _values, result)
- result = 0
- result
- end
-.,.,
-
-# reduce 129 omitted
-
-# reduce 130 omitted
-
-# reduce 131 omitted
-
-# reduce 132 omitted
-
-# reduce 133 omitted
-
-# reduce 134 omitted
-
-# reduce 135 omitted
-
-# reduce 136 omitted
-
-# reduce 137 omitted
-
-# reduce 138 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 396)
- def _reduce_139(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 397)
- def _reduce_140(val, _values, result)
- result = 10
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 398)
- def _reduce_141(val, _values, result)
- result = 11
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 399)
- def _reduce_142(val, _values, result)
- result = 12
- result
- end
-.,.,
-
-# reduce 143 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 403)
- def _reduce_144(val, _values, result)
- result = 13
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 406)
- def _reduce_145(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 407)
- def _reduce_146(val, _values, result)
- result = 10 + val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 408)
- def _reduce_147(val, _values, result)
- result = 20
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 409)
- def _reduce_148(val, _values, result)
- result = 21
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 410)
- def _reduce_149(val, _values, result)
- result = 22
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 411)
- def _reduce_150(val, _values, result)
- result = 23
- result
- end
-.,.,
-
-# reduce 151 omitted
-
-# reduce 152 omitted
-
-# reduce 153 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 419)
- def _reduce_154(val, _values, result)
- result = 24
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 420)
- def _reduce_155(val, _values, result)
- result = 25
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 421)
- def _reduce_156(val, _values, result)
- result = 26
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 422)
- def _reduce_157(val, _values, result)
- result = 27
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 423)
- def _reduce_158(val, _values, result)
- result = 28
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 424)
- def _reduce_159(val, _values, result)
- result = 29
- result
- end
-.,.,
-
-# reduce 160 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 428)
- def _reduce_161(val, _values, result)
- result = 30
- result
- end
-.,.,
-
-# reduce 162 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 432)
- def _reduce_163(val, _values, result)
- result = 31
- result
- end
-.,.,
-
-# reduce 164 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 436)
- def _reduce_165(val, _values, result)
- result = 30 + val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 437)
- def _reduce_166(val, _values, result)
- result = 40 + val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 438)
- def _reduce_167(val, _values, result)
- result = 50 + val[1]
- result
- end
-.,.,
-
-# reduce 168 omitted
-
-# reduce 169 omitted
-
-module_eval(<<'.,.,', 'edtf.y', 445)
- def _reduce_170(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 446)
- def _reduce_171(val, _values, result)
- result = 10 * val[0] + val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 449)
- def _reduce_172(val, _values, result)
- result = val.zip([100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 453)
- def _reduce_173(val, _values, result)
- result = val.zip([1000,100,10,1]).reduce(0) { |s,(a,b)| s += a * b }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 457)
- def _reduce_174(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'edtf.y', 458)
- def _reduce_175(val, _values, result)
- result = 10 * val[0] + val[1]
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module EDTF
diff --git a/test/racc/regress/huia b/test/racc/regress/huia
deleted file mode 100644
index cac22873df..0000000000
--- a/test/racc/regress/huia
+++ /dev/null
@@ -1,1681 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.2
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-module Huia
- class Parser < Racc::Parser
-
-module_eval(<<'...end huia.y/module_eval...', 'huia.y', 211)
-
-attr_accessor :lexer, :scopes, :state
-
-def initialize lexer
- @lexer = lexer
- @state = []
- @scopes = []
- push_scope
-end
-
-def ast
- @ast ||= do_parse
- @scopes.first
-end
-
-def on_error t, val, vstack
- line = lexer.line
- col = lexer.column
- message = "Unexpected #{token_to_str t} at #{lexer.filename} line #{line}:#{col}:\n\n"
-
- start = line - 5 > 0 ? line - 5 : 0
- i_size = line.to_s.size
- (start..(start + 5)).each do |i|
- message << sprintf("\t%#{i_size}d: %s\n", i, lexer.get_line(i))
- message << "\t#{' ' * i_size} #{'-' * (col - 1)}^\n" if i == line
- end
-
- raise SyntaxError, message
-end
-
-def next_token
- nt = lexer.next_computed_token
- # just use a state stack for now, we'll have to do something
- # more sophisticated soon.
- if nt && nt.first == :state
- if nt.last
- state.push << nt.last
- else
- state.pop
- end
- next_token
- else
- nt
- end
-end
-
-def push_scope
- new_scope = Huia::AST::Scope.new scope
- new_scope.file = lexer.filename
- new_scope.line = lexer.line
- new_scope.column = lexer.column
- scopes.push new_scope
- new_scope
-end
-
-def pop_scope
- scopes.pop
-end
-
-def scope
- scopes.last
-end
-
-def binary left, right, method
- node(:MethodCall, left, node(:CallSignature, method, [right]))
-end
-
-def unary left, method
- node(:MethodCall, left, node(:CallSignature, method))
-end
-
-def node type, *args
- Huia::AST.const_get(type).new(*args).tap do |n|
- n.file = lexer.filename
- n.line = lexer.line
- n.column = lexer.column
- end
-end
-alias n node
-
-def allocate_local name
- node(:Variable, name).tap do |n|
- scope.allocate_local n
- end
-end
-
-def allocate_local_assignment name, value
- node(:Assignment, name, value).tap do |n|
- scope.allocate_local n
- end
-end
-
-def this_closure
- allocate_local('@')
-end
-
-def scope_instance
- node(:ScopeInstance, scope)
-end
-
-def constant name
- return scope_instance if name == 'self'
- node(:Constant, name)
-end
-
-def to_string expr
- node(:MethodCall, expr, node(:CallSignature, 'toString'))
-end
-...end huia.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 81, 106, 40, 37, 61, 62, 123, 153, 135, 71,
- 72, 77, 155, 178, 179, 39, 164, 37, 37, 5,
- 6, 137, 152, 73, 74, 75, 36, 36, 76, 28,
- 154, 80, 166, 172, 180, 22, 23, 37, 26, 27,
- 182, 60, 63, 19, 164, 40, 36, 61, 62, 186,
- nil, 33, 71, 72, 77, nil, nil, 134, 39, 133,
- 129, 37, 5, 6, nil, nil, 73, 74, 75, nil,
- 36, 76, 28, 134, 80, 169, 129, nil, 22, 23,
- nil, 26, 27, nil, 60, 63, 19, nil, 40, nil,
- 61, 62, nil, nil, 33, 71, 72, 77, nil, nil,
- nil, 39, nil, nil, 37, nil, nil, nil, nil, 73,
- 74, 75, nil, 36, 76, 28, nil, 80, nil, nil,
- nil, 22, 23, nil, 26, 27, nil, 60, 63, 19,
- nil, 40, nil, 61, 62, nil, nil, 33, 71, 72,
- 77, nil, nil, nil, 39, nil, nil, 37, nil, nil,
- nil, nil, 73, 74, 75, nil, 36, 76, 28, nil,
- 80, nil, nil, nil, 22, 23, nil, 26, 27, nil,
- 60, 63, 19, nil, 40, nil, 61, 62, nil, nil,
- 33, 71, 72, 77, nil, nil, nil, 39, nil, nil,
- 37, nil, nil, nil, nil, 73, 74, 75, nil, 36,
- 76, 28, nil, 80, nil, nil, nil, 22, 23, nil,
- 26, 27, nil, 60, 63, 19, nil, 40, nil, 61,
- 62, nil, nil, 33, 71, 72, 77, nil, 114, nil,
- 39, nil, nil, 37, nil, nil, 113, nil, 73, 74,
- 75, nil, 36, 76, 28, nil, 80, nil, nil, nil,
- 22, 23, nil, 26, 27, nil, 60, 63, 19, nil,
- 40, nil, 61, 62, nil, nil, 33, 71, 72, 77,
- nil, nil, nil, 39, nil, nil, 37, nil, nil, nil,
- nil, 73, 74, 75, nil, 36, 76, 28, nil, 80,
- nil, nil, nil, 22, 23, nil, 26, 27, nil, 60,
- 63, 19, nil, 40, nil, 61, 62, nil, nil, 33,
- 71, 72, 77, nil, nil, nil, 39, nil, nil, 37,
- nil, nil, nil, nil, 73, 74, 75, nil, 36, 76,
- 28, nil, 80, nil, nil, nil, 22, 23, nil, 26,
- 27, nil, 60, 63, 19, nil, 40, nil, 61, 62,
- nil, nil, 33, 71, 72, 77, nil, nil, nil, 39,
- nil, nil, 37, nil, nil, nil, nil, 73, 74, 75,
- nil, 36, 76, 28, nil, 80, nil, nil, nil, 22,
- 23, nil, 26, 27, nil, 60, 63, 19, nil, 40,
- nil, 61, 62, nil, nil, 33, 71, 72, 77, nil,
- nil, nil, 39, nil, nil, 37, nil, nil, nil, nil,
- 73, 74, 75, nil, 36, 76, 28, nil, 80, nil,
- nil, nil, 22, 23, nil, 26, 27, nil, 60, 63,
- 19, nil, 40, nil, 61, 62, nil, nil, 33, 71,
- 72, 77, nil, nil, nil, 39, nil, nil, 37, nil,
- nil, nil, nil, 73, 74, 75, nil, 36, 76, 28,
- nil, 80, nil, nil, nil, 22, 23, nil, 26, 27,
- nil, 60, 63, 19, nil, 40, nil, 61, 62, nil,
- nil, 33, 71, 72, 77, nil, nil, nil, 39, nil,
- nil, 37, nil, nil, nil, nil, 73, 74, 75, nil,
- 36, 76, 28, nil, 80, nil, nil, nil, 22, 23,
- nil, 26, 27, nil, 60, 63, 19, nil, 40, nil,
- 61, 62, nil, nil, 33, 71, 72, 77, nil, nil,
- nil, 39, nil, nil, 37, nil, nil, nil, nil, 73,
- 74, 75, nil, 36, 76, 28, nil, 80, nil, nil,
- nil, 22, 23, nil, 26, 27, nil, 60, 63, 19,
- nil, 40, nil, 61, 62, nil, nil, 33, 71, 72,
- 77, nil, nil, nil, 39, nil, nil, 37, nil, nil,
- nil, nil, 73, 74, 75, nil, 36, 76, 28, nil,
- 80, nil, nil, nil, 22, 23, nil, 26, 27, nil,
- 60, 63, 19, nil, 40, nil, 61, 62, nil, nil,
- 33, 71, 72, 77, nil, nil, nil, 39, nil, nil,
- 37, nil, nil, nil, nil, 73, 74, 75, nil, 36,
- 76, 28, nil, 80, nil, nil, nil, 22, 23, nil,
- 26, 27, nil, 60, 63, 19, nil, 40, nil, 61,
- 62, nil, nil, 33, 71, 72, 77, nil, nil, nil,
- 39, nil, nil, 37, nil, nil, nil, nil, 73, 74,
- 75, nil, 36, 76, 28, nil, 80, nil, nil, nil,
- 22, 23, nil, 26, 27, nil, 60, 63, 19, nil,
- 40, nil, 61, 62, nil, nil, 33, 71, 72, 77,
- nil, nil, nil, 39, nil, nil, 37, nil, nil, nil,
- nil, 73, 74, 75, nil, 36, 76, 28, nil, 80,
- nil, nil, nil, 22, 23, nil, 26, 27, nil, 60,
- 63, 19, nil, 40, nil, 61, 62, nil, nil, 33,
- 71, 72, 77, nil, nil, nil, 39, nil, nil, 37,
- nil, nil, nil, nil, 73, 74, 75, nil, 36, 76,
- 28, nil, 80, nil, nil, nil, 22, 23, nil, 26,
- 27, nil, 60, 63, 19, nil, 40, nil, 61, 62,
- nil, nil, 33, 71, 72, 77, nil, nil, nil, 39,
- nil, nil, 37, nil, nil, nil, nil, 73, 74, 75,
- nil, 36, 76, 28, nil, 80, nil, nil, nil, 22,
- 23, nil, 26, 27, nil, 60, 63, 19, nil, 40,
- nil, 61, 62, nil, nil, 33, 71, 72, 77, nil,
- nil, nil, 39, nil, nil, 37, nil, nil, nil, nil,
- 73, 74, 75, nil, 36, 76, 28, nil, 80, nil,
- nil, nil, 22, 23, nil, 26, 27, nil, 60, 63,
- 19, nil, 40, nil, 61, 62, nil, nil, 33, 71,
- 72, 77, nil, nil, nil, 39, nil, nil, 37, nil,
- nil, nil, nil, 73, 74, 75, nil, 36, 76, 28,
- nil, 80, nil, nil, nil, 22, 23, nil, 26, 27,
- nil, 60, 63, 19, nil, 40, nil, 61, 62, nil,
- nil, 33, 71, 72, 77, nil, nil, nil, 39, nil,
- nil, 37, nil, nil, nil, nil, 73, 74, 75, nil,
- 36, 76, 28, nil, 80, nil, nil, nil, 22, 23,
- nil, 26, 27, nil, 60, 63, 19, nil, 40, nil,
- 61, 62, nil, nil, 33, 71, 72, 77, nil, nil,
- nil, 39, nil, nil, 37, nil, nil, nil, nil, 73,
- 74, 75, nil, 36, 76, 28, nil, 80, nil, nil,
- nil, 22, 23, nil, 26, 27, nil, 60, 63, 19,
- nil, 40, nil, 61, 62, nil, nil, 33, 71, 72,
- 77, nil, nil, nil, 39, nil, nil, 37, nil, nil,
- nil, nil, 73, 74, 75, nil, 36, 76, 28, nil,
- 80, nil, nil, nil, 22, 23, nil, 26, 27, nil,
- 60, 63, 19, nil, 40, nil, 61, 62, nil, nil,
- 33, 71, 72, 77, nil, nil, nil, 39, nil, nil,
- 37, nil, nil, nil, nil, 73, 74, 75, nil, 36,
- 76, 28, nil, 80, nil, nil, nil, 22, 23, nil,
- 26, 27, nil, 60, 63, 19, nil, 40, nil, 61,
- 62, nil, nil, 33, 71, 72, 77, nil, nil, 160,
- 39, nil, nil, 37, 5, 6, nil, nil, 73, 74,
- 75, nil, 36, 76, 28, nil, 80, nil, nil, nil,
- 22, 23, nil, 26, 27, nil, 60, 63, 19, nil,
- 40, nil, 61, 62, nil, nil, 33, 71, 72, 77,
- nil, nil, nil, 39, nil, nil, 37, nil, nil, nil,
- nil, 73, 74, 75, nil, 36, 76, 28, nil, 80,
- nil, nil, nil, 22, 23, nil, 26, 27, nil, 60,
- 63, 19, nil, 40, nil, 61, 62, nil, nil, 33,
- 71, 72, 77, nil, nil, nil, 39, nil, nil, 37,
- nil, nil, nil, nil, 73, 74, 75, nil, 36, 76,
- 28, nil, 80, nil, nil, nil, 22, 23, nil, 26,
- 27, nil, 60, 63, 19, nil, 40, nil, 61, 62,
- nil, nil, 33, 71, 72, 77, nil, nil, nil, 39,
- nil, nil, 37, nil, nil, nil, nil, 73, 74, 75,
- nil, 36, 76, 28, nil, 80, nil, nil, nil, 22,
- 23, nil, 26, 27, nil, 60, 63, 19, nil, 40,
- nil, 61, 62, nil, nil, 33, 71, 72, 77, nil,
- nil, nil, 39, nil, nil, 37, nil, nil, nil, nil,
- 73, 74, 75, nil, 36, 76, 28, nil, 80, nil,
- nil, nil, 22, 23, nil, 26, 27, nil, 60, 63,
- 19, nil, 40, nil, 61, 62, nil, nil, 33, 71,
- 72, 77, nil, nil, nil, 39, nil, nil, 37, nil,
- nil, nil, nil, 73, 74, 75, nil, 36, 76, 28,
- nil, 80, nil, nil, nil, 22, 23, nil, 26, 27,
- nil, 60, 63, 19, nil, 40, nil, 61, 62, nil,
- nil, 33, 71, 72, 77, nil, nil, 160, 39, nil,
- nil, 37, 5, 6, nil, nil, 73, 74, 75, nil,
- 36, 76, 28, nil, 80, nil, nil, nil, 22, 23,
- nil, 26, 27, nil, 60, 63, 19, nil, 40, nil,
- 61, 62, nil, nil, 33, 71, 72, 77, nil, nil,
- nil, 39, nil, nil, 37, nil, nil, nil, nil, 73,
- 74, 75, nil, 36, 76, 28, nil, 80, nil, nil,
- nil, 22, 23, nil, 26, 27, nil, 60, 63, 19,
- 85, 86, 87, 88, nil, 84, nil, 33, 89, nil,
- nil, nil, nil, 84, 91, 5, 6, 85, 86, 87,
- 88, nil, 91, nil, nil, 89, nil, nil, nil, nil,
- 84, nil, 92, 93, 94, 95, 96, 97, 98, 91,
- 92, 93, 94, 95, 96, 97, 98, nil, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, 92, 93, 94,
- 95, 96, 97, 98, nil, 90, 85, 86, 87, 88,
- nil, nil, nil, nil, 89, nil, nil, nil, nil, 84,
- nil, 85, 86, 87, 88, 156, nil, nil, 91, 89,
- nil, nil, nil, nil, 84, nil, nil, nil, nil, nil,
- nil, nil, nil, 91, nil, nil, 92, 93, 94, 95,
- 96, 97, 98, nil, 90, nil, nil, nil, nil, nil,
- nil, 92, 93, 94, 95, 96, 97, 98, nil, 90,
- 85, 86, 87, 88, nil, nil, nil, nil, 89, nil,
- nil, nil, nil, 84, nil, 165, 85, 86, 87, 88,
- nil, nil, 91, nil, 89, nil, nil, nil, 167, 84,
- nil, nil, nil, nil, nil, nil, nil, nil, 91, nil,
- 92, 93, 94, 95, 96, 97, 98, nil, 90, nil,
- nil, nil, nil, nil, nil, nil, 92, 93, 94, 95,
- 96, 97, 98, nil, 90, 85, 86, 87, 88, nil,
- nil, nil, nil, 89, nil, nil, nil, nil, 84, nil,
- 85, 86, 87, 88, nil, nil, nil, 91, 89, nil,
- nil, nil, nil, 84, nil, nil, nil, nil, nil, nil,
- nil, nil, 91, nil, nil, 92, 93, 94, 95, 96,
- 97, 98, nil, 90, nil, nil, nil, nil, nil, nil,
- 92, 93, 94, 95, 96, 97, 98, nil, 90, 85,
- 86, 87, 88, nil, nil, nil, nil, 89, nil, nil,
- nil, nil, 84, nil, 85, 86, 87, 88, nil, nil,
- nil, 91, 89, nil, nil, nil, nil, 84, nil, nil,
- nil, nil, nil, nil, nil, nil, 91, nil, nil, 92,
- 93, 94, 95, 96, 97, 98, nil, 90, nil, nil,
- nil, nil, nil, nil, 92, 93, 94, 95, 96, 97,
- 98, nil, 90, 85, 86, 87, 88, nil, nil, nil,
- nil, 89, nil, nil, nil, nil, 84, nil, 85, 86,
- 87, 88, nil, nil, nil, 91, 89, nil, nil, nil,
- nil, 84, nil, nil, nil, nil, nil, nil, nil, nil,
- 91, nil, nil, 92, 93, 94, 95, 96, 97, 98,
- nil, 90, nil, nil, nil, nil, nil, nil, 92, 93,
- 94, 95, 96, 97, 98, nil, 90, 85, 86, 87,
- 88, nil, nil, nil, nil, 89, nil, nil, nil, nil,
- 84, nil, 85, 86, 87, 88, nil, nil, nil, 91,
- 89, nil, nil, nil, nil, 84, nil, nil, nil, nil,
- nil, nil, nil, nil, 91, nil, nil, 92, 93, 94,
- 95, 96, 97, 98, nil, 90, nil, nil, nil, nil,
- nil, nil, 92, 93, 94, 95, 96, 97, 98, nil,
- 90, 85, 86, 87, 88, nil, nil, nil, nil, 89,
- nil, 160, nil, nil, 84, nil, 5, 6, 85, 86,
- 87, 88, nil, 91, nil, nil, 89, nil, nil, nil,
- nil, 84, nil, nil, nil, nil, nil, nil, nil, nil,
- 91, 92, 93, 94, 95, 96, 97, 98, nil, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, 92, 93,
- 94, 95, 96, 97, 98, nil, 90, 85, 86, 87,
- 88, nil, nil, nil, nil, 89, nil, nil, nil, nil,
- 84, nil, 85, 86, 87, 88, nil, nil, nil, 91,
- 89, nil, nil, nil, nil, 84, nil, 181, nil, nil,
- nil, nil, nil, nil, 91, nil, nil, 92, 93, 94,
- 95, 96, 97, 98, nil, 90, nil, nil, nil, nil,
- nil, nil, 92, 93, 94, 95, 96, 97, 98, nil,
- 90, 85, 86, 87, 88, nil, nil, nil, nil, 89,
- nil, nil, nil, nil, 84, nil, 85, 86, 87, 88,
- nil, nil, nil, 91, 89, nil, nil, nil, nil, 84,
- nil, nil, nil, nil, nil, nil, nil, nil, 91, nil,
- nil, 92, 93, 94, 95, 96, 97, 98, nil, 90,
- nil, nil, nil, nil, nil, nil, 92, 93, 94, 95,
- 96, 97, 98, nil, 90, 87, 88, nil, nil, nil,
- nil, 89, nil, nil, nil, nil, 84, 87, 88, nil,
- nil, nil, nil, 89, nil, 91, nil, nil, 84, nil,
- 87, 88, nil, nil, nil, nil, 89, 91, nil, nil,
- nil, 84, nil, 92, 93, 94, 95, 96, 97, 98,
- 91, 90, nil, nil, nil, 92, 93, 94, 95, 96,
- 97, 98, nil, 90, nil, nil, nil, nil, 92, 93,
- 94, 95, 96, 97, 98, 89, 90, 87, 88, nil,
- 84, nil, nil, 89, nil, nil, nil, nil, 84, 91,
- nil, nil, nil, nil, nil, nil, nil, 91, nil, nil,
- 89, nil, nil, nil, nil, 84, nil, 92, 93, 94,
- 95, 96, 97, 98, 91, 92, 93, 94, 95, 96,
- 97, 98, nil, 90, nil, 89, nil, nil, nil, nil,
- 84, nil, 92, 93, 94, 95, 96, 97, 98, 91,
- 89, nil, nil, nil, nil, 84, nil, nil, nil, nil,
- 89, nil, nil, nil, 91, 84, nil, 92, 93, 94,
- 95, 96, 97, 98, 91, nil, nil, nil, nil, nil,
- nil, nil, 92, 93, 94, 95, 96, 97, 98, nil,
- nil, nil, 92, 93, 94, 95, 96, 97, 98 ]
-
-racc_action_check = [
- 1, 33, 1, 34, 1, 1, 40, 100, 81, 1,
- 1, 1, 102, 161, 161, 1, 112, 33, 1, 1,
- 1, 84, 100, 1, 1, 1, 33, 1, 1, 1,
- 102, 1, 121, 131, 163, 1, 1, 84, 1, 1,
- 178, 1, 1, 1, 179, 0, 84, 0, 0, 183,
- nil, 1, 0, 0, 0, nil, nil, 80, 0, 80,
- 80, 0, 0, 0, nil, nil, 0, 0, 0, nil,
- 0, 0, 0, 128, 0, 128, 128, nil, 0, 0,
- nil, 0, 0, nil, 0, 0, 0, nil, 19, nil,
- 19, 19, nil, nil, 0, 19, 19, 19, nil, nil,
- nil, 19, nil, nil, 19, nil, nil, nil, nil, 19,
- 19, 19, nil, 19, 19, 19, nil, 19, nil, nil,
- nil, 19, 19, nil, 19, 19, nil, 19, 19, 19,
- nil, 23, nil, 23, 23, nil, nil, 19, 23, 23,
- 23, nil, nil, nil, 23, nil, nil, 23, nil, nil,
- nil, nil, 23, 23, 23, nil, 23, 23, 23, nil,
- 23, nil, nil, nil, 23, 23, nil, 23, 23, nil,
- 23, 23, 23, nil, 27, nil, 27, 27, nil, nil,
- 23, 27, 27, 27, nil, nil, nil, 27, nil, nil,
- 27, nil, nil, nil, nil, 27, 27, 27, nil, 27,
- 27, 27, nil, 27, nil, nil, nil, 27, 27, nil,
- 27, 27, nil, 27, 27, 27, nil, 37, nil, 37,
- 37, nil, nil, 27, 37, 37, 37, nil, 37, nil,
- 37, nil, nil, 37, nil, nil, 37, nil, 37, 37,
- 37, nil, 37, 37, 37, nil, 37, nil, nil, nil,
- 37, 37, nil, 37, 37, nil, 37, 37, 37, nil,
- 39, nil, 39, 39, nil, nil, 37, 39, 39, 39,
- nil, nil, nil, 39, nil, nil, 39, nil, nil, nil,
- nil, 39, 39, 39, nil, 39, 39, 39, nil, 39,
- nil, nil, nil, 39, 39, nil, 39, 39, nil, 39,
- 39, 39, nil, 60, nil, 60, 60, nil, nil, 39,
- 60, 60, 60, nil, nil, nil, 60, nil, nil, 60,
- nil, nil, nil, nil, 60, 60, 60, nil, 60, 60,
- 60, nil, 60, nil, nil, nil, 60, 60, nil, 60,
- 60, nil, 60, 60, 60, nil, 61, nil, 61, 61,
- nil, nil, 60, 61, 61, 61, nil, nil, nil, 61,
- nil, nil, 61, nil, nil, nil, nil, 61, 61, 61,
- nil, 61, 61, 61, nil, 61, nil, nil, nil, 61,
- 61, nil, 61, 61, nil, 61, 61, 61, nil, 62,
- nil, 62, 62, nil, nil, 61, 62, 62, 62, nil,
- nil, nil, 62, nil, nil, 62, nil, nil, nil, nil,
- 62, 62, 62, nil, 62, 62, 62, nil, 62, nil,
- nil, nil, 62, 62, nil, 62, 62, nil, 62, 62,
- 62, nil, 63, nil, 63, 63, nil, nil, 62, 63,
- 63, 63, nil, nil, nil, 63, nil, nil, 63, nil,
- nil, nil, nil, 63, 63, 63, nil, 63, 63, 63,
- nil, 63, nil, nil, nil, 63, 63, nil, 63, 63,
- nil, 63, 63, 63, nil, 85, nil, 85, 85, nil,
- nil, 63, 85, 85, 85, nil, nil, nil, 85, nil,
- nil, 85, nil, nil, nil, nil, 85, 85, 85, nil,
- 85, 85, 85, nil, 85, nil, nil, nil, 85, 85,
- nil, 85, 85, nil, 85, 85, 85, nil, 86, nil,
- 86, 86, nil, nil, 85, 86, 86, 86, nil, nil,
- nil, 86, nil, nil, 86, nil, nil, nil, nil, 86,
- 86, 86, nil, 86, 86, 86, nil, 86, nil, nil,
- nil, 86, 86, nil, 86, 86, nil, 86, 86, 86,
- nil, 87, nil, 87, 87, nil, nil, 86, 87, 87,
- 87, nil, nil, nil, 87, nil, nil, 87, nil, nil,
- nil, nil, 87, 87, 87, nil, 87, 87, 87, nil,
- 87, nil, nil, nil, 87, 87, nil, 87, 87, nil,
- 87, 87, 87, nil, 88, nil, 88, 88, nil, nil,
- 87, 88, 88, 88, nil, nil, nil, 88, nil, nil,
- 88, nil, nil, nil, nil, 88, 88, 88, nil, 88,
- 88, 88, nil, 88, nil, nil, nil, 88, 88, nil,
- 88, 88, nil, 88, 88, 88, nil, 89, nil, 89,
- 89, nil, nil, 88, 89, 89, 89, nil, nil, nil,
- 89, nil, nil, 89, nil, nil, nil, nil, 89, 89,
- 89, nil, 89, 89, 89, nil, 89, nil, nil, nil,
- 89, 89, nil, 89, 89, nil, 89, 89, 89, nil,
- 90, nil, 90, 90, nil, nil, 89, 90, 90, 90,
- nil, nil, nil, 90, nil, nil, 90, nil, nil, nil,
- nil, 90, 90, 90, nil, 90, 90, 90, nil, 90,
- nil, nil, nil, 90, 90, nil, 90, 90, nil, 90,
- 90, 90, nil, 91, nil, 91, 91, nil, nil, 90,
- 91, 91, 91, nil, nil, nil, 91, nil, nil, 91,
- nil, nil, nil, nil, 91, 91, 91, nil, 91, 91,
- 91, nil, 91, nil, nil, nil, 91, 91, nil, 91,
- 91, nil, 91, 91, 91, nil, 92, nil, 92, 92,
- nil, nil, 91, 92, 92, 92, nil, nil, nil, 92,
- nil, nil, 92, nil, nil, nil, nil, 92, 92, 92,
- nil, 92, 92, 92, nil, 92, nil, nil, nil, 92,
- 92, nil, 92, 92, nil, 92, 92, 92, nil, 93,
- nil, 93, 93, nil, nil, 92, 93, 93, 93, nil,
- nil, nil, 93, nil, nil, 93, nil, nil, nil, nil,
- 93, 93, 93, nil, 93, 93, 93, nil, 93, nil,
- nil, nil, 93, 93, nil, 93, 93, nil, 93, 93,
- 93, nil, 94, nil, 94, 94, nil, nil, 93, 94,
- 94, 94, nil, nil, nil, 94, nil, nil, 94, nil,
- nil, nil, nil, 94, 94, 94, nil, 94, 94, 94,
- nil, 94, nil, nil, nil, 94, 94, nil, 94, 94,
- nil, 94, 94, 94, nil, 95, nil, 95, 95, nil,
- nil, 94, 95, 95, 95, nil, nil, nil, 95, nil,
- nil, 95, nil, nil, nil, nil, 95, 95, 95, nil,
- 95, 95, 95, nil, 95, nil, nil, nil, 95, 95,
- nil, 95, 95, nil, 95, 95, 95, nil, 96, nil,
- 96, 96, nil, nil, 95, 96, 96, 96, nil, nil,
- nil, 96, nil, nil, 96, nil, nil, nil, nil, 96,
- 96, 96, nil, 96, 96, 96, nil, 96, nil, nil,
- nil, 96, 96, nil, 96, 96, nil, 96, 96, 96,
- nil, 97, nil, 97, 97, nil, nil, 96, 97, 97,
- 97, nil, nil, nil, 97, nil, nil, 97, nil, nil,
- nil, nil, 97, 97, 97, nil, 97, 97, 97, nil,
- 97, nil, nil, nil, 97, 97, nil, 97, 97, nil,
- 97, 97, 97, nil, 98, nil, 98, 98, nil, nil,
- 97, 98, 98, 98, nil, nil, nil, 98, nil, nil,
- 98, nil, nil, nil, nil, 98, 98, 98, nil, 98,
- 98, 98, nil, 98, nil, nil, nil, 98, 98, nil,
- 98, 98, nil, 98, 98, 98, nil, 111, nil, 111,
- 111, nil, nil, 98, 111, 111, 111, nil, nil, 111,
- 111, nil, nil, 111, 111, 111, nil, nil, 111, 111,
- 111, nil, 111, 111, 111, nil, 111, nil, nil, nil,
- 111, 111, nil, 111, 111, nil, 111, 111, 111, nil,
- 123, nil, 123, 123, nil, nil, 111, 123, 123, 123,
- nil, nil, nil, 123, nil, nil, 123, nil, nil, nil,
- nil, 123, 123, 123, nil, 123, 123, 123, nil, 123,
- nil, nil, nil, 123, 123, nil, 123, 123, nil, 123,
- 123, 123, nil, 129, nil, 129, 129, nil, nil, 123,
- 129, 129, 129, nil, nil, nil, 129, nil, nil, 129,
- nil, nil, nil, nil, 129, 129, 129, nil, 129, 129,
- 129, nil, 129, nil, nil, nil, 129, 129, nil, 129,
- 129, nil, 129, 129, 129, nil, 153, nil, 153, 153,
- nil, nil, 129, 153, 153, 153, nil, nil, nil, 153,
- nil, nil, 153, nil, nil, nil, nil, 153, 153, 153,
- nil, 153, 153, 153, nil, 153, nil, nil, nil, 153,
- 153, nil, 153, 153, nil, 153, 153, 153, nil, 155,
- nil, 155, 155, nil, nil, 153, 155, 155, 155, nil,
- nil, nil, 155, nil, nil, 155, nil, nil, nil, nil,
- 155, 155, 155, nil, 155, 155, 155, nil, 155, nil,
- nil, nil, 155, 155, nil, 155, 155, nil, 155, 155,
- 155, nil, 156, nil, 156, 156, nil, nil, 155, 156,
- 156, 156, nil, nil, nil, 156, nil, nil, 156, nil,
- nil, nil, nil, 156, 156, 156, nil, 156, 156, 156,
- nil, 156, nil, nil, nil, 156, 156, nil, 156, 156,
- nil, 156, 156, 156, nil, 157, nil, 157, 157, nil,
- nil, 156, 157, 157, 157, nil, nil, 157, 157, nil,
- nil, 157, 157, 157, nil, nil, 157, 157, 157, nil,
- 157, 157, 157, nil, 157, nil, nil, nil, 157, 157,
- nil, 157, 157, nil, 157, 157, 157, nil, 180, nil,
- 180, 180, nil, nil, 157, 180, 180, 180, nil, nil,
- nil, 180, nil, nil, 180, nil, nil, nil, nil, 180,
- 180, 180, nil, 180, 180, 180, nil, 180, nil, nil,
- nil, 180, 180, nil, 180, 180, nil, 180, 180, 180,
- 3, 3, 3, 3, nil, 142, nil, 180, 3, nil,
- nil, nil, nil, 3, 142, 3, 3, 99, 99, 99,
- 99, nil, 3, nil, nil, 99, nil, nil, nil, nil,
- 99, nil, 142, 142, 142, 142, 142, 142, 142, 99,
- 3, 3, 3, 3, 3, 3, 3, nil, 3, nil,
- nil, nil, nil, nil, nil, nil, nil, 99, 99, 99,
- 99, 99, 99, 99, nil, 99, 101, 101, 101, 101,
- nil, nil, nil, nil, 101, nil, nil, nil, nil, 101,
- nil, 104, 104, 104, 104, 104, nil, nil, 101, 104,
- nil, nil, nil, nil, 104, nil, nil, nil, nil, nil,
- nil, nil, nil, 104, nil, nil, 101, 101, 101, 101,
- 101, 101, 101, nil, 101, nil, nil, nil, nil, nil,
- nil, 104, 104, 104, 104, 104, 104, 104, nil, 104,
- 117, 117, 117, 117, nil, nil, nil, nil, 117, nil,
- nil, nil, nil, 117, nil, 117, 122, 122, 122, 122,
- nil, nil, 117, nil, 122, nil, nil, nil, 122, 122,
- nil, nil, nil, nil, nil, nil, nil, nil, 122, nil,
- 117, 117, 117, 117, 117, 117, 117, nil, 117, nil,
- nil, nil, nil, nil, nil, nil, 122, 122, 122, 122,
- 122, 122, 122, nil, 122, 144, 144, 144, 144, nil,
- nil, nil, nil, 144, nil, nil, nil, nil, 144, nil,
- 145, 145, 145, 145, nil, nil, nil, 144, 145, nil,
- nil, nil, nil, 145, nil, nil, nil, nil, nil, nil,
- nil, nil, 145, nil, nil, 144, 144, 144, 144, 144,
- 144, 144, nil, 144, nil, nil, nil, nil, nil, nil,
- 145, 145, 145, 145, 145, 145, 145, nil, 145, 146,
- 146, 146, 146, nil, nil, nil, nil, 146, nil, nil,
- nil, nil, 146, nil, 147, 147, 147, 147, nil, nil,
- nil, 146, 147, nil, nil, nil, nil, 147, nil, nil,
- nil, nil, nil, nil, nil, nil, 147, nil, nil, 146,
- 146, 146, 146, 146, 146, 146, nil, 146, nil, nil,
- nil, nil, nil, nil, 147, 147, 147, 147, 147, 147,
- 147, nil, 147, 148, 148, 148, 148, nil, nil, nil,
- nil, 148, nil, nil, nil, nil, 148, nil, 149, 149,
- 149, 149, nil, nil, nil, 148, 149, nil, nil, nil,
- nil, 149, nil, nil, nil, nil, nil, nil, nil, nil,
- 149, nil, nil, 148, 148, 148, 148, 148, 148, 148,
- nil, 148, nil, nil, nil, nil, nil, nil, 149, 149,
- 149, 149, 149, 149, 149, nil, 149, 150, 150, 150,
- 150, nil, nil, nil, nil, 150, nil, nil, nil, nil,
- 150, nil, 151, 151, 151, 151, nil, nil, nil, 150,
- 151, nil, nil, nil, nil, 151, nil, nil, nil, nil,
- nil, nil, nil, nil, 151, nil, nil, 150, 150, 150,
- 150, 150, 150, 150, nil, 150, nil, nil, nil, nil,
- nil, nil, 151, 151, 151, 151, 151, 151, 151, nil,
- 151, 158, 158, 158, 158, nil, nil, nil, nil, 158,
- nil, 158, nil, nil, 158, nil, 158, 158, 168, 168,
- 168, 168, nil, 158, nil, nil, 168, nil, nil, nil,
- nil, 168, nil, nil, nil, nil, nil, nil, nil, nil,
- 168, 158, 158, 158, 158, 158, 158, 158, nil, 158,
- nil, nil, nil, nil, nil, nil, nil, nil, 168, 168,
- 168, 168, 168, 168, 168, nil, 168, 171, 171, 171,
- 171, nil, nil, nil, nil, 171, nil, nil, nil, nil,
- 171, nil, 173, 173, 173, 173, nil, nil, nil, 171,
- 173, nil, nil, nil, nil, 173, nil, 171, nil, nil,
- nil, nil, nil, nil, 173, nil, nil, 171, 171, 171,
- 171, 171, 171, 171, nil, 171, nil, nil, nil, nil,
- nil, nil, 173, 173, 173, 173, 173, 173, 173, nil,
- 173, 175, 175, 175, 175, nil, nil, nil, nil, 175,
- nil, nil, nil, nil, 175, nil, 185, 185, 185, 185,
- nil, nil, nil, 175, 185, nil, nil, nil, nil, 185,
- nil, nil, nil, nil, nil, nil, nil, nil, 185, nil,
- nil, 175, 175, 175, 175, 175, 175, 175, nil, 175,
- nil, nil, nil, nil, nil, nil, 185, 185, 185, 185,
- 185, 185, 185, nil, 185, 125, 125, nil, nil, nil,
- nil, 125, nil, nil, nil, nil, 125, 126, 126, nil,
- nil, nil, nil, 126, nil, 125, nil, nil, 126, nil,
- 138, 138, nil, nil, nil, nil, 138, 126, nil, nil,
- nil, 138, nil, 125, 125, 125, 125, 125, 125, 125,
- 138, 125, nil, nil, nil, 126, 126, 126, 126, 126,
- 126, 126, nil, 126, nil, nil, nil, nil, 138, 138,
- 138, 138, 138, 138, 138, 124, 138, 139, 139, nil,
- 124, nil, nil, 139, nil, nil, nil, nil, 139, 124,
- nil, nil, nil, nil, nil, nil, nil, 139, nil, nil,
- 127, nil, nil, nil, nil, 127, nil, 124, 124, 124,
- 124, 124, 124, 124, 127, 139, 139, 139, 139, 139,
- 139, 139, nil, 139, nil, 140, nil, nil, nil, nil,
- 140, nil, 127, 127, 127, 127, 127, 127, 127, 140,
- 141, nil, nil, nil, nil, 141, nil, nil, nil, nil,
- 143, nil, nil, nil, 141, 143, nil, 140, 140, 140,
- 140, 140, 140, 140, 143, nil, nil, nil, nil, nil,
- nil, nil, 141, 141, 141, 141, 141, 141, 141, nil,
- nil, nil, 143, 143, 143, 143, 143, 143, 143 ]
-
-racc_action_pointer = [
- 43, 0, nil, 1416, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 86,
- nil, nil, nil, 129, nil, nil, nil, 172, nil, nil,
- nil, nil, nil, -1, -15, nil, nil, 215, nil, 258,
- 3, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 301, 344, 387, 430, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 27, 8, nil, nil, 19, 473, 516, 559, 602, 645,
- 688, 731, 774, 817, 860, 903, 946, 989, 1032, 1433,
- -15, 1482, -10, nil, 1497, nil, nil, nil, nil, nil,
- nil, 1075, 14, nil, nil, nil, nil, 1546, nil, nil,
- nil, 13, 1562, 1118, 2123, 2059, 2071, 2148, 43, 1161,
- nil, 3, nil, nil, nil, nil, nil, nil, 2084, 2131,
- 2173, 2188, 1408, 2198, 1611, 1626, 1675, 1690, 1739, 1754,
- 1803, 1818, nil, 1204, nil, 1247, 1290, 1333, 1867, nil,
- nil, -8, nil, 31, nil, nil, nil, nil, 1884, nil,
- nil, 1933, nil, 1948, nil, 1997, nil, nil, 21, 42,
- 1376, nil, nil, 36, nil, 2012, nil ]
-
-racc_action_default = [
- -140, -140, -1, -4, -5, -6, -7, -10, -11, -12,
- -13, -14, -15, -16, -17, -18, -19, -20, -21, -23,
- -24, -25, -26, -140, -30, -31, -32, -140, -37, -55,
- -56, -57, -60, -140, -63, -64, -65, -140, -73, -140,
- -76, -77, -78, -79, -80, -81, -82, -83, -84, -85,
- -86, -87, -88, -89, -90, -91, -107, -108, -109, -110,
- -140, -140, -140, -140, -115, -116, -117, -118, -119, -120,
- -121, -122, -123, -124, -125, -126, -127, -128, -129, -130,
- -140, -140, -2, -3, -140, -140, -140, -140, -140, -140,
- -140, -140, -140, -140, -140, -140, -140, -140, -140, -22,
- -140, -28, -140, -34, -140, -61, -62, -74, -38, -39,
- -40, -140, -140, -46, -47, -48, -49, -69, -66, -67,
- -68, -71, -140, -140, -111, -112, -113, -114, -140, -140,
- -133, -135, -136, -137, -138, 187, -58, -59, -93, -94,
- -95, -96, -97, -98, -99, -100, -101, -102, -103, -104,
- -105, -106, -27, -140, -33, -140, -140, -140, -4, -43,
- -44, -140, -50, -52, -54, -70, -72, -75, -92, -131,
- -134, -140, -139, -29, -35, -36, -41, -42, -9, -140,
- -140, -132, -8, -140, -51, -53, -45 ]
-
-racc_goto_table = [
- 99, 82, 103, 83, 101, 1, 105, 130, 104, 183,
- 100, 102, 159, 162, 121, 108, 109, 110, 117, 111,
- 122, 115, 112, 161, 116, 107, 118, 119, 120, 128,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 124, 125, 126, 127, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 170, nil, 136, 176, 177,
- nil, nil, nil, nil, nil, nil, 138, 139, 140, 141,
- 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
- 184, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 158, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 168, nil, nil, nil, nil, nil,
- 171, nil, nil, nil, nil, nil, 157, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 174, nil, nil, nil, 173, nil, 104, 175, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 82, 83, nil,
- nil, 185 ]
-
-racc_goto_check = [
- 3, 2, 24, 4, 3, 1, 40, 77, 3, 5,
- 20, 23, 30, 35, 25, 26, 27, 28, 3, 29,
- 3, 31, 32, 33, 34, 43, 44, 45, 46, 75,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 3, 3, 3, 3, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 77, nil, 40, 30, 30,
- nil, nil, nil, nil, nil, nil, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 35, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 3, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 3, nil, nil, nil, nil, nil,
- 3, nil, nil, nil, nil, nil, 1, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 24, nil, nil, nil, 3, nil, 3, 3, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 2, 4, nil,
- nil, 3 ]
-
-racc_goto_pointer = [
- nil, 5, 0, -19, 0, -169, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- -13, nil, nil, -16, -25, -23, -22, -21, -20, -18,
- -99, -16, -15, -89, -13, -99, nil, nil, nil, nil,
- -27, nil, nil, -9, -11, -10, -9, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, -51, nil, -73, nil ]
-
-racc_goto_default = [
- nil, nil, 2, 3, 4, nil, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 20, 21,
- nil, 24, 25, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 163, 29, 30, 31,
- 32, 34, 35, 38, nil, nil, nil, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59, 64, 65, 66, 67,
- 68, 69, 70, 78, 79, nil, 132, nil, 131 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 54, :_reduce_none,
- 2, 54, :_reduce_2,
- 2, 55, :_reduce_3,
- 1, 55, :_reduce_4,
- 1, 55, :_reduce_5,
- 1, 57, :_reduce_none,
- 1, 57, :_reduce_none,
- 1, 58, :_reduce_none,
- 0, 58, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 56, :_reduce_none,
- 1, 68, :_reduce_none,
- 1, 68, :_reduce_none,
- 2, 69, :_reduce_22,
- 1, 70, :_reduce_23,
- 1, 66, :_reduce_none,
- 1, 66, :_reduce_none,
- 1, 71, :_reduce_26,
- 3, 72, :_reduce_27,
- 1, 73, :_reduce_28,
- 3, 73, :_reduce_29,
- 1, 67, :_reduce_none,
- 1, 67, :_reduce_none,
- 1, 74, :_reduce_32,
- 3, 75, :_reduce_33,
- 1, 76, :_reduce_34,
- 3, 76, :_reduce_35,
- 3, 77, :_reduce_36,
- 1, 64, :_reduce_37,
- 1, 78, :_reduce_none,
- 1, 78, :_reduce_none,
- 1, 78, :_reduce_none,
- 3, 79, :_reduce_41,
- 3, 80, :_reduce_42,
- 2, 81, :_reduce_43,
- 1, 83, :_reduce_44,
- 5, 84, :_reduce_45,
- 1, 85, :_reduce_46,
- 1, 87, :_reduce_47,
- 1, 82, :_reduce_none,
- 1, 82, :_reduce_none,
- 1, 86, :_reduce_none,
- 3, 86, :_reduce_none,
- 1, 88, :_reduce_52,
- 3, 88, :_reduce_53,
- 1, 89, :_reduce_54,
- 1, 63, :_reduce_none,
- 1, 63, :_reduce_none,
- 1, 63, :_reduce_none,
- 3, 90, :_reduce_58,
- 3, 90, :_reduce_59,
- 1, 91, :_reduce_60,
- 2, 92, :_reduce_61,
- 2, 92, :_reduce_62,
- 1, 93, :_reduce_none,
- 1, 93, :_reduce_none,
- 1, 95, :_reduce_65,
- 2, 96, :_reduce_66,
- 1, 97, :_reduce_none,
- 1, 97, :_reduce_none,
- 1, 98, :_reduce_none,
- 2, 98, :_reduce_none,
- 1, 99, :_reduce_none,
- 2, 99, :_reduce_none,
- 1, 94, :_reduce_73,
- 2, 94, :_reduce_74,
- 3, 60, :_reduce_75,
- 1, 65, :_reduce_76,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 1, 61, :_reduce_none,
- 3, 100, :_reduce_92,
- 3, 101, :_reduce_93,
- 3, 102, :_reduce_94,
- 3, 103, :_reduce_95,
- 3, 104, :_reduce_96,
- 3, 105, :_reduce_97,
- 3, 106, :_reduce_98,
- 3, 107, :_reduce_99,
- 3, 108, :_reduce_100,
- 3, 109, :_reduce_101,
- 3, 110, :_reduce_102,
- 3, 111, :_reduce_103,
- 3, 112, :_reduce_104,
- 3, 113, :_reduce_105,
- 3, 114, :_reduce_106,
- 1, 62, :_reduce_none,
- 1, 62, :_reduce_none,
- 1, 62, :_reduce_none,
- 1, 62, :_reduce_none,
- 2, 115, :_reduce_111,
- 2, 116, :_reduce_112,
- 2, 117, :_reduce_113,
- 2, 118, :_reduce_114,
- 1, 59, :_reduce_none,
- 1, 59, :_reduce_none,
- 1, 59, :_reduce_none,
- 1, 59, :_reduce_none,
- 1, 59, :_reduce_none,
- 1, 59, :_reduce_none,
- 1, 59, :_reduce_none,
- 1, 120, :_reduce_122,
- 1, 119, :_reduce_123,
- 1, 122, :_reduce_124,
- 1, 123, :_reduce_125,
- 1, 124, :_reduce_126,
- 1, 125, :_reduce_127,
- 1, 121, :_reduce_128,
- 1, 121, :_reduce_none,
- 1, 121, :_reduce_none,
- 3, 126, :_reduce_131,
- 3, 129, :_reduce_132,
- 1, 128, :_reduce_133,
- 2, 128, :_reduce_134,
- 1, 130, :_reduce_135,
- 1, 130, :_reduce_136,
- 2, 127, :_reduce_137,
- 1, 131, :_reduce_138,
- 2, 131, :_reduce_139 ]
-
-racc_reduce_n = 140
-
-racc_shift_n = 187
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :IDENTIFIER => 2,
- :EQUAL => 3,
- :PLUS => 4,
- :MINUS => 5,
- :ASTERISK => 6,
- :FWD_SLASH => 7,
- :COLON => 8,
- :FLOAT => 9,
- :INTEGER => 10,
- :STRING => 11,
- :EXPO => 12,
- :INDENT => 13,
- :OUTDENT => 14,
- :OPAREN => 15,
- :CPAREN => 16,
- :DOT => 17,
- :SIGNATURE => 18,
- :NL => 19,
- :EOF => 20,
- :PIPE => 21,
- :COMMA => 22,
- :NIL => 23,
- :TRUE => 24,
- :FALSE => 25,
- :EQUALITY => 26,
- :CALL => 27,
- :SELF => 28,
- :CONSTANT => 29,
- :CHAR => 30,
- :DOUBLE_TICK_STRING => 31,
- :DOUBLE_TICK_STRING_END => 32,
- :INTERPOLATE_START => 33,
- :INTERPOLATE_END => 34,
- :BOX => 35,
- :LSQUARE => 36,
- :RSQUARE => 37,
- :FACES => 38,
- :LFACE => 39,
- :RFACE => 40,
- :BANG => 41,
- :TILDE => 42,
- :RETURN => 43,
- :NOT_EQUALITY => 44,
- :OR => 45,
- :AND => 46,
- :GT => 47,
- :LT => 48,
- :GTE => 49,
- :LTE => 50,
- :AT => 51,
- :PERCENT => 52 }
-
-racc_nt_base = 53
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "IDENTIFIER",
- "EQUAL",
- "PLUS",
- "MINUS",
- "ASTERISK",
- "FWD_SLASH",
- "COLON",
- "FLOAT",
- "INTEGER",
- "STRING",
- "EXPO",
- "INDENT",
- "OUTDENT",
- "OPAREN",
- "CPAREN",
- "DOT",
- "SIGNATURE",
- "NL",
- "EOF",
- "PIPE",
- "COMMA",
- "NIL",
- "TRUE",
- "FALSE",
- "EQUALITY",
- "CALL",
- "SELF",
- "CONSTANT",
- "CHAR",
- "DOUBLE_TICK_STRING",
- "DOUBLE_TICK_STRING_END",
- "INTERPOLATE_START",
- "INTERPOLATE_END",
- "BOX",
- "LSQUARE",
- "RSQUARE",
- "FACES",
- "LFACE",
- "RFACE",
- "BANG",
- "TILDE",
- "RETURN",
- "NOT_EQUALITY",
- "OR",
- "AND",
- "GT",
- "LT",
- "GTE",
- "LTE",
- "AT",
- "PERCENT",
- "$start",
- "statements",
- "statement",
- "expr",
- "eol",
- "nlq",
- "literal",
- "grouped_expr",
- "binary_op",
- "unary_op",
- "method_call",
- "constant",
- "variable",
- "array",
- "hash",
- "return",
- "return_expr",
- "return_nil",
- "empty_array",
- "array_list",
- "array_items",
- "empty_hash",
- "hash_list",
- "hash_items",
- "hash_item",
- "indented",
- "indented_w_stmts",
- "indented_w_expr",
- "indented_wo_stmts",
- "indent",
- "outdent",
- "indent_w_args",
- "indent_pipe",
- "indent_args",
- "indent_wo_args",
- "indent_arg",
- "arg_var",
- "method_call_on_object",
- "method_call_on_self",
- "method_call_on_closure",
- "call_signature",
- "call_arguments",
- "call_simple_name",
- "call_argument",
- "call_passed_arg",
- "call_passed_simple",
- "call_passed_indented",
- "assignment",
- "addition",
- "subtraction",
- "multiplication",
- "division",
- "exponentiation",
- "modulo",
- "equality",
- "not_equality",
- "logical_or",
- "logical_and",
- "greater_than",
- "less_than",
- "greater_or_eq",
- "less_or_eq",
- "unary_not",
- "unary_plus",
- "unary_minus",
- "unary_complement",
- "integer",
- "float",
- "string",
- "nil",
- "true",
- "false",
- "self",
- "interpolated_string",
- "empty_string",
- "interpolated_string_contents",
- "interpolation",
- "interpolated_string_chunk",
- "chars" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-# reduce 1 omitted
-
-module_eval(<<'.,.,', 'huia.y', 44)
- def _reduce_2(val, _values, result)
- return scope
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 46)
- def _reduce_3(val, _values, result)
- return scope.append val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 47)
- def _reduce_4(val, _values, result)
- return scope.append val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 48)
- def _reduce_5(val, _values, result)
- return scope
- result
- end
-.,.,
-
-# reduce 6 omitted
-
-# reduce 7 omitted
-
-# reduce 8 omitted
-
-# reduce 9 omitted
-
-# reduce 10 omitted
-
-# reduce 11 omitted
-
-# reduce 12 omitted
-
-# reduce 13 omitted
-
-# reduce 14 omitted
-
-# reduce 15 omitted
-
-# reduce 16 omitted
-
-# reduce 17 omitted
-
-# reduce 18 omitted
-
-# reduce 19 omitted
-
-# reduce 20 omitted
-
-# reduce 21 omitted
-
-module_eval(<<'.,.,', 'huia.y', 66)
- def _reduce_22(val, _values, result)
- return n(:Return, val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 67)
- def _reduce_23(val, _values, result)
- return n(:Return, n(:Nil))
- result
- end
-.,.,
-
-# reduce 24 omitted
-
-# reduce 25 omitted
-
-module_eval(<<'.,.,', 'huia.y', 72)
- def _reduce_26(val, _values, result)
- return n :Array
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 74)
- def _reduce_27(val, _values, result)
- return val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 75)
- def _reduce_28(val, _values, result)
- return n :Array, [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 76)
- def _reduce_29(val, _values, result)
- val[0].append(val[2]); return val[0]
- result
- end
-.,.,
-
-# reduce 30 omitted
-
-# reduce 31 omitted
-
-module_eval(<<'.,.,', 'huia.y', 80)
- def _reduce_32(val, _values, result)
- return n :Hash
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 81)
- def _reduce_33(val, _values, result)
- return val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 82)
- def _reduce_34(val, _values, result)
- return n :Hash, val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 83)
- def _reduce_35(val, _values, result)
- val[0].append(val[2]); return val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 84)
- def _reduce_36(val, _values, result)
- return n :HashItem, val[0], val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 86)
- def _reduce_37(val, _values, result)
- return constant val[0]
- result
- end
-.,.,
-
-# reduce 38 omitted
-
-# reduce 39 omitted
-
-# reduce 40 omitted
-
-module_eval(<<'.,.,', 'huia.y', 91)
- def _reduce_41(val, _values, result)
- return val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 92)
- def _reduce_42(val, _values, result)
- return val[0].append(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 93)
- def _reduce_43(val, _values, result)
- return val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 94)
- def _reduce_44(val, _values, result)
- return pop_scope
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 97)
- def _reduce_45(val, _values, result)
- return val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 98)
- def _reduce_46(val, _values, result)
- return push_scope
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 99)
- def _reduce_47(val, _values, result)
- return push_scope
- result
- end
-.,.,
-
-# reduce 48 omitted
-
-# reduce 49 omitted
-
-# reduce 50 omitted
-
-# reduce 51 omitted
-
-module_eval(<<'.,.,', 'huia.y', 105)
- def _reduce_52(val, _values, result)
- return scope.add_argument val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 106)
- def _reduce_53(val, _values, result)
- return n :Assignment, val[0], val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 107)
- def _reduce_54(val, _values, result)
- return n :Variable, val[0]
- result
- end
-.,.,
-
-# reduce 55 omitted
-
-# reduce 56 omitted
-
-# reduce 57 omitted
-
-module_eval(<<'.,.,', 'huia.y', 112)
- def _reduce_58(val, _values, result)
- return n :MethodCall, val[0], val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 113)
- def _reduce_59(val, _values, result)
- return n :MethodCall, val[0], n(:CallSignature, val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 114)
- def _reduce_60(val, _values, result)
- return n :MethodCall, scope_instance, val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 116)
- def _reduce_61(val, _values, result)
- return n :MethodCall, this_closure, val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 117)
- def _reduce_62(val, _values, result)
- return n :MethodCall, this_closure, n(:CallSignature, val[1])
- result
- end
-.,.,
-
-# reduce 63 omitted
-
-# reduce 64 omitted
-
-module_eval(<<'.,.,', 'huia.y', 121)
- def _reduce_65(val, _values, result)
- return n :CallSignature, val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 122)
- def _reduce_66(val, _values, result)
- return n :CallSignature, val[0], [val[1]]
- result
- end
-.,.,
-
-# reduce 67 omitted
-
-# reduce 68 omitted
-
-# reduce 69 omitted
-
-# reduce 70 omitted
-
-# reduce 71 omitted
-
-# reduce 72 omitted
-
-module_eval(<<'.,.,', 'huia.y', 129)
- def _reduce_73(val, _values, result)
- return val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 130)
- def _reduce_74(val, _values, result)
- return val[0].concat_signature val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 132)
- def _reduce_75(val, _values, result)
- return n :Expression, val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 134)
- def _reduce_76(val, _values, result)
- return allocate_local val[0]
- result
- end
-.,.,
-
-# reduce 77 omitted
-
-# reduce 78 omitted
-
-# reduce 79 omitted
-
-# reduce 80 omitted
-
-# reduce 81 omitted
-
-# reduce 82 omitted
-
-# reduce 83 omitted
-
-# reduce 84 omitted
-
-# reduce 85 omitted
-
-# reduce 86 omitted
-
-# reduce 87 omitted
-
-# reduce 88 omitted
-
-# reduce 89 omitted
-
-# reduce 90 omitted
-
-# reduce 91 omitted
-
-module_eval(<<'.,.,', 'huia.y', 152)
- def _reduce_92(val, _values, result)
- return allocate_local_assignment val[0], val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 153)
- def _reduce_93(val, _values, result)
- return binary val[0], val[2], 'plus:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 154)
- def _reduce_94(val, _values, result)
- return binary val[0], val[2], 'minus:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 155)
- def _reduce_95(val, _values, result)
- return binary val[0], val[2], 'multiplyBy:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 156)
- def _reduce_96(val, _values, result)
- return binary val[0], val[2], 'divideBy:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 157)
- def _reduce_97(val, _values, result)
- return binary val[0], val[2], 'toThePowerOf:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 158)
- def _reduce_98(val, _values, result)
- return binary val[0], val[2], 'moduloOf:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 159)
- def _reduce_99(val, _values, result)
- return binary val[0], val[2], 'isEqualTo:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 160)
- def _reduce_100(val, _values, result)
- return binary val[0], val[2], 'isNotEqualTo:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 161)
- def _reduce_101(val, _values, result)
- return binary val[0], val[2], 'logicalOr:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 162)
- def _reduce_102(val, _values, result)
- return binary val[0], val[2], 'logicalAnd:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 163)
- def _reduce_103(val, _values, result)
- return binary val[0], val[2], 'isGreaterThan:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 164)
- def _reduce_104(val, _values, result)
- return binary val[0], val[2], 'isLessThan:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 165)
- def _reduce_105(val, _values, result)
- return binary val[0], val[2], 'isGreaterOrEqualTo:'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 166)
- def _reduce_106(val, _values, result)
- return binary val[0], val[2], 'isLessOrEqualTo:'
- result
- end
-.,.,
-
-# reduce 107 omitted
-
-# reduce 108 omitted
-
-# reduce 109 omitted
-
-# reduce 110 omitted
-
-module_eval(<<'.,.,', 'huia.y', 173)
- def _reduce_111(val, _values, result)
- return unary val[1], 'unaryNot'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 174)
- def _reduce_112(val, _values, result)
- return unary val[1], 'unaryPlus'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 175)
- def _reduce_113(val, _values, result)
- return unary val[1], 'unaryMinus'
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 176)
- def _reduce_114(val, _values, result)
- return unary val[1], 'unaryComplement'
- result
- end
-.,.,
-
-# reduce 115 omitted
-
-# reduce 116 omitted
-
-# reduce 117 omitted
-
-# reduce 118 omitted
-
-# reduce 119 omitted
-
-# reduce 120 omitted
-
-# reduce 121 omitted
-
-module_eval(<<'.,.,', 'huia.y', 186)
- def _reduce_122(val, _values, result)
- return n :Float, val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 187)
- def _reduce_123(val, _values, result)
- return n :Integer, val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 188)
- def _reduce_124(val, _values, result)
- return n :Nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 189)
- def _reduce_125(val, _values, result)
- return n :True
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 190)
- def _reduce_126(val, _values, result)
- return n :False
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 191)
- def _reduce_127(val, _values, result)
- return n :Self
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 193)
- def _reduce_128(val, _values, result)
- return n :String, val[0]
- result
- end
-.,.,
-
-# reduce 129 omitted
-
-# reduce 130 omitted
-
-module_eval(<<'.,.,', 'huia.y', 197)
- def _reduce_131(val, _values, result)
- return val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 198)
- def _reduce_132(val, _values, result)
- return val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 199)
- def _reduce_133(val, _values, result)
- return n :InterpolatedString, val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 200)
- def _reduce_134(val, _values, result)
- val[0].append(val[1]); return val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 201)
- def _reduce_135(val, _values, result)
- return val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 202)
- def _reduce_136(val, _values, result)
- return to_string(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 203)
- def _reduce_137(val, _values, result)
- return n :String, ''
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 205)
- def _reduce_138(val, _values, result)
- return n :String, val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'huia.y', 206)
- def _reduce_139(val, _values, result)
- val[0].append(val[1]); return val[0]
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module Huia
diff --git a/test/racc/regress/journey b/test/racc/regress/journey
deleted file mode 100644
index 3daf81dac0..0000000000
--- a/test/racc/regress/journey
+++ /dev/null
@@ -1,222 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-
-require 'journey/parser_extras'
-module Journey
- class Parser < Racc::Parser
-##### State transition tables begin ###
-
-racc_action_table = [
- 17, 21, 13, 15, 14, 7, nil, 16, 8, 19,
- 13, 15, 14, 7, 23, 16, 8, 19, 13, 15,
- 14, 7, nil, 16, 8, 13, 15, 14, 7, nil,
- 16, 8, 13, 15, 14, 7, nil, 16, 8 ]
-
-racc_action_check = [
- 1, 17, 1, 1, 1, 1, nil, 1, 1, 1,
- 20, 20, 20, 20, 20, 20, 20, 20, 0, 0,
- 0, 0, nil, 0, 0, 7, 7, 7, 7, nil,
- 7, 7, 19, 19, 19, 19, nil, 19, 19 ]
-
-racc_action_pointer = [
- 16, 0, nil, nil, nil, nil, nil, 23, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 1, nil, 30,
- 8, nil, nil, nil ]
-
-racc_action_default = [
- -18, -18, -2, -3, -4, -5, -6, -18, -9, -10,
- -11, -12, -13, -14, -15, -16, -17, -18, -1, -18,
- -18, 24, -8, -7 ]
-
-racc_goto_table = [
- 18, 1, nil, nil, nil, nil, nil, nil, 20, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 22, 18 ]
-
-racc_goto_check = [
- 2, 1, nil, nil, nil, nil, nil, nil, 1, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 2, 2 ]
-
-racc_goto_pointer = [
- nil, 1, -1, nil, nil, nil, nil, nil, nil, nil,
- nil ]
-
-racc_goto_default = [
- nil, nil, 2, 3, 4, 5, 6, 9, 10, 11,
- 12 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 2, 11, :_reduce_1,
- 1, 11, :_reduce_2,
- 1, 11, :_reduce_none,
- 1, 12, :_reduce_none,
- 1, 12, :_reduce_none,
- 1, 12, :_reduce_none,
- 3, 15, :_reduce_7,
- 3, 13, :_reduce_8,
- 1, 16, :_reduce_9,
- 1, 14, :_reduce_none,
- 1, 14, :_reduce_none,
- 1, 14, :_reduce_none,
- 1, 14, :_reduce_none,
- 1, 19, :_reduce_14,
- 1, 17, :_reduce_15,
- 1, 18, :_reduce_16,
- 1, 20, :_reduce_17 ]
-
-racc_reduce_n = 18
-
-racc_shift_n = 24
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :SLASH => 2,
- :LITERAL => 3,
- :SYMBOL => 4,
- :LPAREN => 5,
- :RPAREN => 6,
- :DOT => 7,
- :STAR => 8,
- :OR => 9 }
-
-racc_nt_base = 10
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "SLASH",
- "LITERAL",
- "SYMBOL",
- "LPAREN",
- "RPAREN",
- "DOT",
- "STAR",
- "OR",
- "$start",
- "expressions",
- "expression",
- "or",
- "terminal",
- "group",
- "star",
- "symbol",
- "literal",
- "slash",
- "dot" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'journey.y', 6)
- def _reduce_1(val, _values, result)
- result = Cat.new(val.first, val.last)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'journey.y', 7)
- def _reduce_2(val, _values, result)
- result = val.first
- result
- end
-.,.,
-
-# reduce 3 omitted
-
-# reduce 4 omitted
-
-# reduce 5 omitted
-
-# reduce 6 omitted
-
-module_eval(<<'.,.,', 'journey.y', 16)
- def _reduce_7(val, _values, result)
- result = Group.new(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'journey.y', 19)
- def _reduce_8(val, _values, result)
- result = Or.new([val.first, val.last])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'journey.y', 22)
- def _reduce_9(val, _values, result)
- result = Star.new(Symbol.new(val.last))
- result
- end
-.,.,
-
-# reduce 10 omitted
-
-# reduce 11 omitted
-
-# reduce 12 omitted
-
-# reduce 13 omitted
-
-module_eval(<<'.,.,', 'journey.y', 31)
- def _reduce_14(val, _values, result)
- result = Slash.new('/')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'journey.y', 34)
- def _reduce_15(val, _values, result)
- result = Symbol.new(val.first)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'journey.y', 37)
- def _reduce_16(val, _values, result)
- result = Literal.new(val.first)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'journey.y', 39)
- def _reduce_17(val, _values, result)
- result = Dot.new(val.first)
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module Journey
diff --git a/test/racc/regress/liquor b/test/racc/regress/liquor
deleted file mode 100644
index 9fa2ca4da0..0000000000
--- a/test/racc/regress/liquor
+++ /dev/null
@@ -1,885 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-module Liquor
- class Parser < Racc::Parser
-
-module_eval(<<'...end liquor.y/module_eval...', 'liquor.y', 216)
- attr_reader :errors, :ast
-
- def initialize(tags={})
- super()
-
- @errors = []
- @ast = nil
- @tags = tags
- end
-
- def success?
- @errors.empty?
- end
-
- def parse(string, name='(code)')
- @errors.clear
- @name = name
- @ast = nil
-
- begin
- @stream = Lexer.lex(string, @name, @tags)
- @ast = do_parse
- rescue Liquor::SyntaxError => e
- @errors << e
- end
-
- success?
- end
-
- def next_token
- tok = @stream.shift
- [ tok[0], tok ] if tok
- end
-
- TOKEN_NAME_MAP = {
- :comma => ',',
- :dot => '.',
- :lblock => '{%',
- :rblock => '%}',
- :linterp => '{{',
- :rinterp => '}}',
- :lbracket => '[',
- :rbracket => ']',
- :lparen => '(',
- :rparen => ')',
- :pipe => '|',
- :op_not => '!',
- :op_mul => '*',
- :op_div => '/',
- :op_mod => '%',
- :op_plus => '+',
- :op_minus => '-',
- :op_eq => '==',
- :op_neq => '!=',
- :op_lt => '<',
- :op_leq => '<=',
- :op_gt => '>',
- :op_geq => '>=',
- :keyword => 'keyword argument name',
- :kwarg => 'keyword argument',
- :ident => 'identifier',
- }
-
- def on_error(error_token_id, error_token, value_stack)
- if token_to_str(error_token_id) == "$end"
- raise Liquor::SyntaxError.new("unexpected end of program", {
- file: @name
- })
- else
- type, (loc, value) = error_token
- type = TOKEN_NAME_MAP[type] || type
-
- raise Liquor::SyntaxError.new("unexpected token `#{type}'", loc)
- end
- end
-
- def retag(nodes)
- loc = nodes.map { |node| node[1] }.compact
- first, *, last = loc
- return first if last.nil?
-
- {
- file: first[:file],
- line: first[:line],
- start: first[:start],
- end: last[:end],
- }
- end
-
- def reduce_tag_args(list)
- list.each_slice(2).reduce([]) { |args, (k, v)|
- if v[0] == :block
- args << [ :blockarg, retag([ k, v ]), k, v[2] || [] ]
- else
- args << [ :kwarg, retag([ k, v ]), k, v ]
- end
- }
- end
-...end liquor.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 76, 26, 26, 6, 7, 22, 5, 6, 25, 25,
- 5, 28, 32, 36, 37, 34, 35, 31, 29, 27,
- 33, 2, 30, 26, 26, 2, 6, 23, 41, 5,
- 25, 25, 38, 39, 28, 32, 36, 37, 34, 35,
- 31, 29, 27, 33, 2, 30, 40, 26, 96, 6,
- 24, 97, 5, 43, 25, 38, 39, 28, 32, 36,
- 37, 34, 35, 31, 29, 27, 33, 2, 30, 26,
- 54, 70, 77, 26, 75, 26, 25, 52, 38, 39,
- 25, 43, 25, 28, 32, 36, 37, 34, 35, 31,
- 29, 27, 33, 26, 30, 84, 26, 51, 6, 96,
- 25, 5, 97, 25, 38, 39, 28, 32, 36, 37,
- 34, 35, 31, 29, 27, 33, 2, 30, 74, 26,
- 87, 82, 96, 74, 70, 97, 25, 38, 39, 28,
- 32, 36, 37, 34, 35, 31, 29, 27, 33, 94,
- 30, 98, 26, 107, 6, 111, 52, 5, nil, 25,
- 38, 39, 28, 32, 36, 37, 34, 35, 31, 29,
- 27, 33, 2, 30, nil, 26, 51, 6, nil, 74,
- 5, nil, 25, 38, 39, 28, 32, 36, 37, 34,
- 35, 31, 29, 27, 33, 2, 30, nil, 26, nil,
- nil, nil, 102, nil, nil, 25, 38, 39, 28, 32,
- 36, 37, 34, 35, 31, 29, 27, 33, nil, 30,
- nil, 26, 96, nil, nil, 97, nil, nil, 25, 38,
- 39, 28, 32, 36, 37, 34, 35, 31, 29, 27,
- 33, nil, 30, nil, 26, nil, nil, nil, nil, nil,
- nil, 25, 38, 39, 28, 32, 36, 37, 34, 35,
- 31, 29, 27, 33, nil, 30, 13, 15, nil, 13,
- 15, 21, nil, 14, 21, 38, 14, nil, nil, nil,
- 18, nil, nil, 18, 19, nil, nil, 19, nil, 13,
- 15, nil, 16, nil, 21, 16, 14, nil, nil, 13,
- 15, nil, nil, 18, 21, nil, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, 52, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, 51, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, 74, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, 81, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, nil, 18, 21, 16, 14, 19, nil, 13,
- 15, nil, 26, 18, 21, 16, 14, 19, nil, 25,
- nil, 101, 28, 18, nil, 16, nil, 19, 31, 29,
- 27, 106, 26, 30, nil, 16, nil, nil, nil, 25,
- nil, nil, 28, nil, 26, nil, nil, nil, 31, 29,
- 27, 25, nil, 30, 28, nil, 26, nil, nil, nil,
- 31, 29, 27, 25, nil, 30, 28, nil, 26, nil,
- nil, nil, 31, 29, 27, 25, nil, 30, 28, nil,
- 26, nil, nil, nil, 31, 29, 27, 25, nil, 30,
- 28, nil, 26, nil, nil, nil, 31, 29, 27, 25,
- nil, 30, 28, 32, 36, 37, 34, 35, 31, 29,
- 27, 33, 26, 30, 26, nil, nil, nil, nil, 25,
- nil, 25, 28, nil, 28, nil, nil, nil, nil, 29,
- 27, 29, 27 ]
-
-racc_action_check = [
- 47, 47, 45, 0, 1, 6, 0, 2, 47, 45,
- 2, 47, 47, 47, 47, 47, 47, 47, 47, 47,
- 47, 0, 47, 46, 11, 2, 3, 7, 12, 3,
- 46, 11, 47, 47, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 3, 11, 11, 44, 94, 4,
- 11, 94, 4, 13, 44, 11, 11, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 4, 44, 55,
- 26, 40, 48, 49, 44, 56, 55, 49, 44, 44,
- 49, 54, 56, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 57, 49, 69, 53, 49, 81, 107,
- 57, 81, 107, 53, 49, 49, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, 53, 81, 53, 70, 71,
- 72, 53, 111, 71, 84, 111, 71, 53, 53, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 91,
- 71, 96, 79, 103, 101, 109, 79, 101, nil, 79,
- 71, 71, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 101, 79, nil, 88, 79, 106, nil, 88,
- 106, nil, 88, 79, 79, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 106, 88, nil, 99, nil,
- nil, nil, 99, nil, nil, 99, 88, 88, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, nil, 99,
- nil, 104, 104, nil, nil, 104, nil, nil, 104, 99,
- 99, 104, 104, 104, 104, 104, 104, 104, 104, 104,
- 104, nil, 104, nil, 67, nil, nil, nil, nil, nil,
- nil, 67, 104, 104, 67, 67, 67, 67, 67, 67,
- 67, 67, 67, 67, nil, 67, 5, 5, nil, 14,
- 14, 5, nil, 5, 14, 67, 14, nil, nil, nil,
- 5, nil, nil, 14, 5, nil, nil, 14, nil, 18,
- 18, nil, 5, nil, 18, 14, 18, nil, nil, 19,
- 19, nil, nil, 18, 19, nil, 19, 18, nil, 21,
- 21, nil, nil, 19, 21, 18, 21, 19, nil, 22,
- 22, 22, nil, 21, 22, 19, 22, 21, nil, 25,
- 25, nil, nil, 22, 25, 21, 25, 22, nil, 27,
- 27, 22, nil, 25, 27, 22, 27, 25, nil, 28,
- 28, nil, nil, 27, 28, 25, 28, 27, nil, 29,
- 29, nil, nil, 28, 29, 27, 29, 28, nil, 30,
- 30, nil, nil, 29, 30, 28, 30, 29, nil, 31,
- 31, nil, nil, 30, 31, 29, 31, 30, nil, 32,
- 32, nil, nil, 31, 32, 30, 32, 31, nil, 33,
- 33, nil, nil, 32, 33, 31, 33, 32, nil, 34,
- 34, nil, nil, 33, 34, 32, 34, 33, nil, 35,
- 35, nil, nil, 34, 35, 33, 35, 34, nil, 36,
- 36, nil, nil, 35, 36, 34, 36, 35, nil, 37,
- 37, nil, nil, 36, 37, 35, 37, 36, nil, 38,
- 38, nil, nil, 37, 38, 36, 38, 37, nil, 39,
- 39, nil, nil, 38, 39, 37, 39, 38, nil, 43,
- 43, 43, nil, 39, 43, 38, 43, 39, nil, 52,
- 52, nil, nil, 43, 52, 39, 52, 43, nil, 74,
- 74, nil, nil, 52, 74, 43, 74, 52, nil, 76,
- 76, 52, nil, 74, 76, 52, 76, 74, nil, 97,
- 97, nil, nil, 76, 97, 74, 97, 76, nil, 102,
- 102, nil, 60, 97, 102, 76, 102, 97, nil, 60,
- nil, 97, 60, 102, nil, 97, nil, 102, 60, 60,
- 60, 102, 61, 60, nil, 102, nil, nil, nil, 61,
- nil, nil, 61, nil, 62, nil, nil, nil, 61, 61,
- 61, 62, nil, 61, 62, nil, 63, nil, nil, nil,
- 62, 62, 62, 63, nil, 62, 63, nil, 64, nil,
- nil, nil, 63, 63, 63, 64, nil, 63, 64, nil,
- 65, nil, nil, nil, 64, 64, 64, 65, nil, 64,
- 65, nil, 66, nil, nil, nil, 65, 65, 65, 66,
- nil, 65, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 66, 58, 66, 59, nil, nil, nil, nil, 58,
- nil, 59, 58, nil, 59, nil, nil, nil, nil, 58,
- 58, 59, 59 ]
-
-racc_action_pointer = [
- -5, 4, -1, 18, 41, 251, 0, 27, nil, nil,
- nil, 21, -1, 41, 254, nil, nil, nil, 274, 284,
- nil, 294, 304, nil, nil, 314, 65, 324, 334, 344,
- 354, 364, 374, 384, 394, 404, 414, 424, 434, 444,
- 66, nil, nil, 454, 44, -1, 20, -2, 44, 70,
- nil, nil, 464, 93, 69, 66, 72, 90, 609, 611,
- 509, 529, 541, 553, 565, 577, 589, 231, nil, 70,
- 111, 116, 90, nil, 474, nil, 484, nil, nil, 139,
- nil, 90, nil, nil, 119, nil, nil, nil, 162, nil,
- nil, 130, nil, nil, 44, nil, 114, 494, nil, 185,
- nil, 136, 504, 134, 208, nil, 159, 95, nil, 136,
- nil, 118, nil ]
-
-racc_action_default = [
- -1, -57, -1, -1, -1, -57, -57, -57, -2, -3,
- -4, -57, -57, -7, -57, -9, -10, -11, -57, -57,
- -31, -35, -57, 113, -5, -57, -57, -57, -57, -57,
- -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
- -57, -6, -12, -40, -57, -16, -17, -34, -57, -57,
- -46, -47, -57, -57, -15, -18, -19, -20, -21, -22,
- -23, -24, -25, -26, -27, -28, -29, -30, -41, -43,
- -40, -40, -57, -38, -57, -8, -35, -32, -45, -57,
- -48, -1, -13, -14, -57, -44, -37, -36, -40, -33,
- -50, -57, -42, -39, -57, -49, -57, -57, -51, -57,
- -52, -1, -57, -57, -57, -54, -1, -57, -56, -57,
- -53, -57, -55 ]
-
-racc_goto_table = [
- 1, 11, 8, 9, 10, 48, 68, 12, 42, 50,
- 44, 72, 80, 73, 45, 46, 100, 105, 49, nil,
- nil, 53, nil, 55, 56, 57, 58, 59, 60, 61,
- 62, 63, 64, 65, 66, 67, 78, nil, nil, 71,
- 85, 86, 95, nil, nil, nil, nil, nil, 79, 83,
- 92, nil, 108, nil, nil, 110, nil, nil, 93, 112,
- 89, nil, nil, nil, nil, nil, 90, nil, nil, nil,
- 88, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 91, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 99, nil, nil, nil, nil, 104, nil,
- nil, 103, nil, nil, nil, nil, 109 ]
-
-racc_goto_check = [
- 1, 4, 1, 1, 1, 9, 12, 5, 8, 14,
- 4, 10, 15, 11, 4, 4, 17, 18, 4, nil,
- nil, 4, nil, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 14, nil, nil, 4,
- 11, 11, 16, nil, nil, nil, nil, nil, 4, 8,
- 12, nil, 16, nil, nil, 16, nil, nil, 11, 16,
- 9, nil, nil, nil, nil, nil, 14, nil, nil, nil,
- 4, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 1, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 4, nil, nil, nil, nil, 4, nil,
- nil, 1, nil, nil, nil, nil, 1 ]
-
-racc_goto_pointer = [
- nil, 0, nil, nil, -4, 2, nil, nil, -5, -16,
- -32, -30, -34, nil, -13, -40, -52, -81, -85 ]
-
-racc_goto_default = [
- nil, nil, 3, 4, 47, nil, 20, 17, nil, nil,
- nil, nil, nil, 69, nil, nil, nil, nil, nil ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 0, 37, :_reduce_1,
- 2, 37, :_reduce_2,
- 2, 37, :_reduce_3,
- 2, 37, :_reduce_4,
- 3, 38, :_reduce_5,
- 3, 38, :_reduce_6,
- 1, 42, :_reduce_none,
- 3, 42, :_reduce_8,
- 1, 40, :_reduce_none,
- 1, 40, :_reduce_none,
- 1, 40, :_reduce_none,
- 2, 40, :_reduce_12,
- 4, 40, :_reduce_13,
- 4, 40, :_reduce_14,
- 3, 40, :_reduce_15,
- 2, 40, :_reduce_16,
- 2, 40, :_reduce_17,
- 3, 40, :_reduce_18,
- 3, 40, :_reduce_19,
- 3, 40, :_reduce_20,
- 3, 40, :_reduce_21,
- 3, 40, :_reduce_22,
- 3, 40, :_reduce_23,
- 3, 40, :_reduce_24,
- 3, 40, :_reduce_25,
- 3, 40, :_reduce_26,
- 3, 40, :_reduce_27,
- 3, 40, :_reduce_28,
- 3, 40, :_reduce_29,
- 3, 40, :_reduce_30,
- 1, 40, :_reduce_none,
- 3, 43, :_reduce_32,
- 3, 45, :_reduce_33,
- 1, 45, :_reduce_34,
- 0, 45, :_reduce_35,
- 3, 44, :_reduce_36,
- 2, 46, :_reduce_37,
- 1, 46, :_reduce_38,
- 3, 47, :_reduce_39,
- 0, 47, :_reduce_40,
- 3, 41, :_reduce_41,
- 3, 48, :_reduce_42,
- 1, 48, :_reduce_43,
- 2, 49, :_reduce_44,
- 4, 39, :_reduce_45,
- 3, 39, :_reduce_46,
- 1, 50, :_reduce_47,
- 2, 50, :_reduce_48,
- 4, 51, :_reduce_49,
- 2, 51, :_reduce_50,
- 2, 52, :_reduce_51,
- 2, 52, :_reduce_52,
- 4, 53, :_reduce_53,
- 3, 53, :_reduce_54,
- 4, 54, :_reduce_55,
- 2, 54, :_reduce_56 ]
-
-racc_reduce_n = 57
-
-racc_shift_n = 113
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :comma => 2,
- :dot => 3,
- :endtag => 4,
- :ident => 5,
- :integer => 6,
- :keyword => 7,
- :lblock => 8,
- :lblock2 => 9,
- :lbracket => 10,
- :linterp => 11,
- :lparen => 12,
- :op_div => 13,
- :op_eq => 14,
- :op_gt => 15,
- :op_geq => 16,
- :op_lt => 17,
- :op_leq => 18,
- :op_minus => 19,
- :op_mod => 20,
- :op_mul => 21,
- :op_neq => 22,
- :op_not => 23,
- :op_plus => 24,
- :pipe => 25,
- :plaintext => 26,
- :rblock => 27,
- :rbracket => 28,
- :rinterp => 29,
- :rparen => 30,
- :string => 31,
- :tag_ident => 32,
- :op_uminus => 33,
- :op_and => 34,
- :op_or => 35 }
-
-racc_nt_base = 36
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "comma",
- "dot",
- "endtag",
- "ident",
- "integer",
- "keyword",
- "lblock",
- "lblock2",
- "lbracket",
- "linterp",
- "lparen",
- "op_div",
- "op_eq",
- "op_gt",
- "op_geq",
- "op_lt",
- "op_leq",
- "op_minus",
- "op_mod",
- "op_mul",
- "op_neq",
- "op_not",
- "op_plus",
- "pipe",
- "plaintext",
- "rblock",
- "rbracket",
- "rinterp",
- "rparen",
- "string",
- "tag_ident",
- "op_uminus",
- "op_and",
- "op_or",
- "$start",
- "block",
- "interp",
- "tag",
- "expr",
- "filter_chain",
- "primary_expr",
- "tuple",
- "function_args",
- "tuple_content",
- "function_args_inside",
- "function_keywords",
- "filter_chain_cont",
- "filter_call",
- "tag_first_cont",
- "tag_first_cont2",
- "tag_next_cont",
- "tag_next_cont2",
- "tag_next_cont3" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'liquor.y', 47)
- def _reduce_1(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 49)
- def _reduce_2(val, _values, result)
- result = [ val[0], *val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 51)
- def _reduce_3(val, _values, result)
- result = [ val[0], *val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 53)
- def _reduce_4(val, _values, result)
- result = [ val[0], *val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 57)
- def _reduce_5(val, _values, result)
- result = [ :interp, retag(val), val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 59)
- def _reduce_6(val, _values, result)
- result = [ :interp, retag(val), val[1] ]
- result
- end
-.,.,
-
-# reduce 7 omitted
-
-module_eval(<<'.,.,', 'liquor.y', 64)
- def _reduce_8(val, _values, result)
- result = [ val[1][0], retag(val), *val[1][2..-1] ]
- result
- end
-.,.,
-
-# reduce 9 omitted
-
-# reduce 10 omitted
-
-# reduce 11 omitted
-
-module_eval(<<'.,.,', 'liquor.y', 71)
- def _reduce_12(val, _values, result)
- result = [ :call, retag(val), val[0], val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 73)
- def _reduce_13(val, _values, result)
- result = [ :index, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 75)
- def _reduce_14(val, _values, result)
- result = [ :external, retag(val), val[0], val[2], val[3] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 77)
- def _reduce_15(val, _values, result)
- result = [ :external, retag(val), val[0], val[2], nil ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 79)
- def _reduce_16(val, _values, result)
- result = [ :uminus, retag(val), val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 81)
- def _reduce_17(val, _values, result)
- result = [ :not, retag(val), val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 83)
- def _reduce_18(val, _values, result)
- result = [ :mul, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 85)
- def _reduce_19(val, _values, result)
- result = [ :div, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 87)
- def _reduce_20(val, _values, result)
- result = [ :mod, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 89)
- def _reduce_21(val, _values, result)
- result = [ :plus, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 91)
- def _reduce_22(val, _values, result)
- result = [ :minus, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 93)
- def _reduce_23(val, _values, result)
- result = [ :eq, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 95)
- def _reduce_24(val, _values, result)
- result = [ :neq, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 97)
- def _reduce_25(val, _values, result)
- result = [ :lt, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 99)
- def _reduce_26(val, _values, result)
- result = [ :leq, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 101)
- def _reduce_27(val, _values, result)
- result = [ :gt, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 103)
- def _reduce_28(val, _values, result)
- result = [ :geq, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 105)
- def _reduce_29(val, _values, result)
- result = [ :and, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 107)
- def _reduce_30(val, _values, result)
- result = [ :or, retag(val), val[0], val[2] ]
- result
- end
-.,.,
-
-# reduce 31 omitted
-
-module_eval(<<'.,.,', 'liquor.y', 112)
- def _reduce_32(val, _values, result)
- result = [ :tuple, retag(val), val[1].compact ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 116)
- def _reduce_33(val, _values, result)
- result = [ val[0], *val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 118)
- def _reduce_34(val, _values, result)
- result = [ val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 120)
- def _reduce_35(val, _values, result)
- result = [ ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 124)
- def _reduce_36(val, _values, result)
- result = [ :args, retag(val), *val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 128)
- def _reduce_37(val, _values, result)
- result = [ val[0], val[1][2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 130)
- def _reduce_38(val, _values, result)
- result = [ nil, val[0][2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 134)
- def _reduce_39(val, _values, result)
- name = val[0][2].to_sym
- tail = val[2][2]
- loc = retag([ val[0], val[1] ])
-
- if tail.include? name
- @errors << SyntaxError.new("duplicate keyword argument `#{val[0][2]}'",
- tail[name][1])
- end
-
- hash = {
- name => [ val[1][0], loc, *val[1][2..-1] ]
- }.merge(tail)
-
- result = [ :keywords, retag([ loc, val[2] ]), hash ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 150)
- def _reduce_40(val, _values, result)
- result = [ :keywords, nil, {} ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 154)
- def _reduce_41(val, _values, result)
- result = [ val[0], *val[2] ].
- reduce { |tree, node| node[3][2] = tree; node }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 160)
- def _reduce_42(val, _values, result)
- result = [ val[0], *val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 162)
- def _reduce_43(val, _values, result)
- result = [ val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 166)
- def _reduce_44(val, _values, result)
- ident_loc = val[0][1]
- empty_args_loc = { line: ident_loc[:line],
- start: ident_loc[:end] + 1,
- end: ident_loc[:end] + 1, }
- result = [ :call, val[0][1], val[0],
- [ :args, val[1][1] || empty_args_loc, nil, val[1][2] ] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 176)
- def _reduce_45(val, _values, result)
- result = [ :tag, retag(val), val[1], val[2], *reduce_tag_args(val[3][2]) ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 178)
- def _reduce_46(val, _values, result)
- result = [ :tag, retag(val), val[1], nil, *reduce_tag_args(val[2][2]) ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 186)
- def _reduce_47(val, _values, result)
- result = [ :cont, retag(val), [] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 188)
- def _reduce_48(val, _values, result)
- result = [ :cont, retag(val), [ val[0], *val[1][2] ] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 192)
- def _reduce_49(val, _values, result)
- result = [ :cont2, val[0][1], [ [:block, val[0][1], val[1] ], *val[3] ] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 194)
- def _reduce_50(val, _values, result)
- result = [ :cont2, retag(val), [ val[0], *val[1][2] ] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 198)
- def _reduce_51(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 200)
- def _reduce_52(val, _values, result)
- result = [ val[0], *val[1] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 204)
- def _reduce_53(val, _values, result)
- result = [ [:block, val[0][1], val[1] ], *val[3] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 206)
- def _reduce_54(val, _values, result)
- result = [ val[0], val[1], *val[2] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 210)
- def _reduce_55(val, _values, result)
- result = [ [:block, val[0][1], val[1] ], *val[3] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'liquor.y', 212)
- def _reduce_56(val, _values, result)
- result = [ val[0], *val[1] ]
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module Liquor
diff --git a/test/racc/regress/machete b/test/racc/regress/machete
deleted file mode 100644
index 6297fe2ac9..0000000000
--- a/test/racc/regress/machete
+++ /dev/null
@@ -1,833 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-module Machete
- class Parser < Racc::Parser
-
-module_eval(<<'...end machete.y/module_eval...', 'machete.y', 175)
-
-include Matchers
-
-class SyntaxError < StandardError; end
-
-def parse(input)
- @input = input
- @pos = 0
-
- do_parse
-end
-
-private
-
-def integer_value(value)
- if value =~ /^0[bB]/
- value[2..-1].to_i(2)
- elsif value =~ /^0[oO]/
- value[2..-1].to_i(8)
- elsif value =~ /^0[dD]/
- value[2..-1].to_i(10)
- elsif value =~ /^0[xX]/
- value[2..-1].to_i(16)
- elsif value =~ /^0/
- value.to_i(8)
- else
- value.to_i
- end
-end
-
-def symbol_value(value)
- value[1..-1].to_sym
-end
-
-def string_value(value)
- quote = value[0..0]
- if quote == "'"
- value[1..-2].gsub("\\\\", "\\").gsub("\\'", "'")
- elsif quote == '"'
- value[1..-2].
- gsub("\\\\", "\\").
- gsub('\\"', '"').
- gsub("\\n", "\n").
- gsub("\\t", "\t").
- gsub("\\r", "\r").
- gsub("\\f", "\f").
- gsub("\\v", "\v").
- gsub("\\a", "\a").
- gsub("\\e", "\e").
- gsub("\\b", "\b").
- gsub("\\s", "\s").
- gsub(/\\([0-7]{1,3})/) { $1.to_i(8).chr }.
- gsub(/\\x([0-9a-fA-F]{1,2})/) { $1.to_i(16).chr }
- else
- raise "Unknown quote: #{quote.inspect}."
- end
-end
-
-REGEXP_OPTIONS = {
- 'i' => Regexp::IGNORECASE,
- 'm' => Regexp::MULTILINE,
- 'x' => Regexp::EXTENDED
-}
-
-def regexp_value(value)
- /\A\/(.*)\/([imx]*)\z/ =~ value
- pattern, options = $1, $2
-
- Regexp.new(pattern, options.chars.map { |ch| REGEXP_OPTIONS[ch] }.inject(:|))
-end
-
-# "^" needs to be here because if it were among operators recognized by
-# METHOD_NAME, "^=" would be recognized as two tokens.
-SIMPLE_TOKENS = [
- "|",
- "<",
- ">",
- ",",
- "=",
- "^=",
- "^",
- "$=",
- "[",
- "]",
- "*=",
- "*",
- "+",
- "?",
- "{",
- "}"
-]
-
-COMPLEX_TOKENS = [
- [:NIL, /^nil/],
- [:TRUE, /^true/],
- [:FALSE, /^false/],
- # INTEGER needs to be before METHOD_NAME, otherwise e.g. "+1" would be
- # recognized as two tokens.
- [
- :INTEGER,
- /^
- [+-]? # sign
- (
- 0[bB][01]+(_[01]+)* # binary (prefixed)
- |
- 0[oO][0-7]+(_[0-7]+)* # octal (prefixed)
- |
- 0[dD]\d+(_\d+)* # decimal (prefixed)
- |
- 0[xX][0-9a-fA-F]+(_[0-9a-fA-F]+)* # hexadecimal (prefixed)
- |
- 0[0-7]*(_[0-7]+)* # octal (unprefixed)
- |
- [1-9]\d*(_\d+)* # decimal (unprefixed)
- )
- /x
- ],
- [
- :SYMBOL,
- /^
- :
- (
- # class name
- [A-Z][a-zA-Z0-9_]*
- |
- # regular method name
- [a-z_][a-zA-Z0-9_]*[?!=]?
- |
- # instance variable name
- @[a-zA-Z_][a-zA-Z0-9_]*
- |
- # class variable name
- @@[a-zA-Z_][a-zA-Z0-9_]*
- |
- # operator (sorted by length, then alphabetically)
- (<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&*+\-\/<>^`|~])
- )
- /x
- ],
- [
- :STRING,
- /^
- (
- ' # sinqle-quoted string
- (
- \\[\\'] # escape
- |
- [^'] # regular character
- )*
- '
- |
- " # double-quoted string
- (
- \\ # escape
- (
- [\\"ntrfvaebs] # one-character escape
- |
- [0-7]{1,3} # octal number escape
- |
- x[0-9a-fA-F]{1,2} # hexadecimal number escape
- )
- |
- [^"] # regular character
- )*
- "
- )
- /x
- ],
- [
- :REGEXP,
- /^
- \/
- (
- \\ # escape
- (
- [\\\/ntrfvaebs\(\)\[\]\{\}\-\.\?\*\+\|\^\$] # one-character escape
- |
- [0-7]{2,3} # octal number escape
- |
- x[0-9a-fA-F]{1,2} # hexadecimal number escape
- )
- |
- [^\/] # regular character
- )*
- \/
- [imx]*
- /x
- ],
- # ANY, EVEN and ODD need to be before METHOD_NAME, otherwise they would be
- # recognized as method names.
- [:ANY, /^any/],
- [:EVEN, /^even/],
- [:ODD, /^odd/],
- # We exclude "*", "+", "<", ">", "^" and "|" from method names since they are
- # lexed as simple tokens. This is because they have also other meanings in
- # Machette patterns beside Ruby method names.
- [
- :METHOD_NAME,
- /^
- (
- # regular name
- [a-z_][a-zA-Z0-9_]*[?!=]?
- |
- # operator (sorted by length, then alphabetically)
- (<=>|===|\[\]=|\*\*|\+@|-@|<<|<=|==|=~|>=|>>|\[\]|[%&\-\/`~])
- )
- /x
- ],
- [:CLASS_NAME, /^[A-Z][a-zA-Z0-9_]*/]
-]
-
-def next_token
- skip_whitespace
-
- return false if remaining_input.empty?
-
- # Complex tokens need to be before simple tokens, otherwise e.g. "<<" would be
- # recognized as two tokens.
-
- COMPLEX_TOKENS.each do |type, regexp|
- if remaining_input =~ regexp
- @pos += $&.length
- return [type, $&]
- end
- end
-
- SIMPLE_TOKENS.each do |token|
- if remaining_input[0...token.length] == token
- @pos += token.length
- return [token, token]
- end
- end
-
- raise SyntaxError, "Unexpected character: #{remaining_input[0..0].inspect}."
-end
-
-def skip_whitespace
- if remaining_input =~ /\A^[ \t\r\n]+/
- @pos += $&.length
- end
-end
-
-def remaining_input
- @input[@pos..-1]
-end
-
-def on_error(error_token_id, error_value, value_stack)
- raise SyntaxError, "Unexpected token: #{error_value.inspect}."
-end
-...end machete.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 75, 19, 9, 10, 11, 12, 13, 14, 15, 16,
- 66, 67, 68, 7, 24, 9, 10, 11, 12, 13,
- 14, 15, 16, 17, 74, 8, 7, 47, 9, 10,
- 11, 12, 13, 14, 15, 16, 48, 18, 8, 7,
- 71, 9, 10, 11, 12, 13, 14, 15, 16, 72,
- 70, 8, 7, 73, 9, 10, 11, 12, 13, 14,
- 15, 16, 69, 18, 8, 7, 30, 31, 32, 51,
- 52, 53, 54, 33, 34, 35, 29, 8, 41, 38,
- 39, 76, 30, 31, 32, 77, 36, 37, 40, 33,
- 34, 35, 29, nil, 41, 38, 39, 18, 49, 50,
- 62, 63, 36, 37, 40, 43, 44, 55, 64, 65,
- 45, 46, 57, 58, nil, nil, nil, nil, nil, 56 ]
-
-racc_action_check = [
- 70, 7, 0, 0, 0, 0, 0, 0, 0, 0,
- 54, 54, 54, 0, 17, 8, 8, 8, 8, 8,
- 8, 8, 8, 1, 70, 0, 8, 21, 18, 18,
- 18, 18, 18, 18, 18, 18, 22, 1, 8, 18,
- 56, 48, 48, 48, 48, 48, 48, 48, 48, 57,
- 55, 18, 48, 58, 51, 51, 51, 51, 51, 51,
- 51, 51, 55, 61, 48, 51, 19, 19, 19, 28,
- 28, 28, 28, 19, 19, 19, 19, 51, 19, 19,
- 19, 71, 50, 50, 50, 75, 19, 19, 19, 50,
- 50, 50, 50, nil, 50, 50, 50, 20, 26, 26,
- 52, 52, 50, 50, 50, 20, 20, 46, 53, 53,
- 20, 20, 46, 46, nil, nil, nil, nil, nil, 46 ]
-
-racc_action_pointer = [
- 0, 23, nil, nil, nil, nil, nil, -14, 13, nil,
- nil, nil, nil, nil, nil, nil, nil, 14, 26, 64,
- 83, 1, 19, nil, nil, nil, 82, nil, 51, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 102, nil, 39, nil,
- 80, 52, 94, 102, 4, 33, 35, 20, 24, nil,
- nil, 49, nil, nil, nil, nil, nil, nil, nil, nil,
- -5, 52, nil, nil, nil, 56, nil, nil ]
-
-racc_action_default = [
- -56, -56, -1, -3, -4, -5, -6, -7, -33, -48,
- -49, -50, -51, -52, -53, -54, -55, -56, -56, -56,
- -37, -56, -34, -35, 78, -2, -56, -9, -56, -19,
- -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
- -30, -31, -38, -39, -40, -41, -56, -32, -56, -8,
- -56, -56, -56, -56, -56, -56, -56, -56, -56, -36,
- -10, -11, -12, -15, -13, -16, -14, -17, -18, -42,
- -56, -56, -46, -47, -43, -56, -44, -45 ]
-
-racc_goto_table = [
- 1, 23, 27, 25, 26, 21, 22, 42, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 60, nil, nil, nil, nil, nil, nil,
- nil, 59, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 61 ]
-
-racc_goto_check = [
- 1, 12, 8, 2, 7, 10, 11, 13, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 8, nil, nil, nil, nil, nil, nil,
- nil, 12, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 1 ]
-
-racc_goto_pointer = [
- nil, 0, -15, nil, nil, nil, nil, -15, -17, nil,
- -3, -2, -7, -13 ]
-
-racc_goto_default = [
- nil, 20, 2, 3, 4, 5, 6, nil, nil, 28,
- nil, nil, nil, nil ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 31, :_reduce_none,
- 3, 31, :_reduce_2,
- 1, 32, :_reduce_none,
- 1, 32, :_reduce_none,
- 1, 32, :_reduce_none,
- 1, 32, :_reduce_none,
- 1, 33, :_reduce_7,
- 4, 33, :_reduce_8,
- 1, 37, :_reduce_none,
- 3, 37, :_reduce_10,
- 3, 38, :_reduce_11,
- 3, 38, :_reduce_12,
- 3, 38, :_reduce_13,
- 3, 38, :_reduce_14,
- 3, 38, :_reduce_15,
- 3, 38, :_reduce_16,
- 3, 38, :_reduce_17,
- 3, 38, :_reduce_18,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 1, 39, :_reduce_none,
- 3, 34, :_reduce_32,
- 0, 40, :_reduce_33,
- 1, 40, :_reduce_none,
- 1, 41, :_reduce_35,
- 3, 41, :_reduce_36,
- 1, 42, :_reduce_none,
- 2, 42, :_reduce_38,
- 1, 43, :_reduce_39,
- 1, 43, :_reduce_40,
- 1, 43, :_reduce_41,
- 3, 43, :_reduce_42,
- 4, 43, :_reduce_43,
- 4, 43, :_reduce_44,
- 5, 43, :_reduce_45,
- 3, 43, :_reduce_46,
- 3, 43, :_reduce_47,
- 1, 35, :_reduce_48,
- 1, 35, :_reduce_49,
- 1, 35, :_reduce_50,
- 1, 35, :_reduce_51,
- 1, 35, :_reduce_52,
- 1, 35, :_reduce_53,
- 1, 35, :_reduce_54,
- 1, 36, :_reduce_55 ]
-
-racc_reduce_n = 56
-
-racc_shift_n = 78
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :NIL => 2,
- :TRUE => 3,
- :FALSE => 4,
- :INTEGER => 5,
- :SYMBOL => 6,
- :STRING => 7,
- :REGEXP => 8,
- :ANY => 9,
- :EVEN => 10,
- :ODD => 11,
- :METHOD_NAME => 12,
- :CLASS_NAME => 13,
- "|" => 14,
- "<" => 15,
- ">" => 16,
- "," => 17,
- "=" => 18,
- "^=" => 19,
- "$=" => 20,
- "*=" => 21,
- "*" => 22,
- "+" => 23,
- "^" => 24,
- "[" => 25,
- "]" => 26,
- "?" => 27,
- "{" => 28,
- "}" => 29 }
-
-racc_nt_base = 30
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "NIL",
- "TRUE",
- "FALSE",
- "INTEGER",
- "SYMBOL",
- "STRING",
- "REGEXP",
- "ANY",
- "EVEN",
- "ODD",
- "METHOD_NAME",
- "CLASS_NAME",
- "\"|\"",
- "\"<\"",
- "\">\"",
- "\",\"",
- "\"=\"",
- "\"^=\"",
- "\"$=\"",
- "\"*=\"",
- "\"*\"",
- "\"+\"",
- "\"^\"",
- "\"[\"",
- "\"]\"",
- "\"?\"",
- "\"{\"",
- "\"}\"",
- "$start",
- "expression",
- "primary",
- "node",
- "array",
- "literal",
- "any",
- "attrs",
- "attr",
- "method_name",
- "items_opt",
- "items",
- "item",
- "quantifier" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-# reduce 1 omitted
-
-module_eval(<<'.,.,', 'machete.y', 44)
- def _reduce_2(val, _values, result)
- result = if val[0].is_a?(ChoiceMatcher)
- ChoiceMatcher.new(val[0].alternatives << val[2])
- else
- ChoiceMatcher.new([val[0], val[2]])
- end
-
- result
- end
-.,.,
-
-# reduce 3 omitted
-
-# reduce 4 omitted
-
-# reduce 5 omitted
-
-# reduce 6 omitted
-
-module_eval(<<'.,.,', 'machete.y', 57)
- def _reduce_7(val, _values, result)
- result = NodeMatcher.new(val[0].to_sym)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 60)
- def _reduce_8(val, _values, result)
- result = NodeMatcher.new(val[0].to_sym, val[2])
-
- result
- end
-.,.,
-
-# reduce 9 omitted
-
-module_eval(<<'.,.,', 'machete.y', 64)
- def _reduce_10(val, _values, result)
- result = val[0].merge(val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 66)
- def _reduce_11(val, _values, result)
- result = { val[0].to_sym => val[2] }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 68)
- def _reduce_12(val, _values, result)
- result = {
- val[0].to_sym => SymbolRegexpMatcher.new(
- Regexp.new("^" + Regexp.escape(symbol_value(val[2]).to_s))
- )
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 75)
- def _reduce_13(val, _values, result)
- result = {
- val[0].to_sym => SymbolRegexpMatcher.new(
- Regexp.new(Regexp.escape(symbol_value(val[2]).to_s) + "$")
- )
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 82)
- def _reduce_14(val, _values, result)
- result = {
- val[0].to_sym => SymbolRegexpMatcher.new(
- Regexp.new(Regexp.escape(symbol_value(val[2]).to_s))
- )
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 89)
- def _reduce_15(val, _values, result)
- result = {
- val[0].to_sym => StringRegexpMatcher.new(
- Regexp.new("^" + Regexp.escape(string_value(val[2])))
- )
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 96)
- def _reduce_16(val, _values, result)
- result = {
- val[0].to_sym => StringRegexpMatcher.new(
- Regexp.new(Regexp.escape(string_value(val[2])) + "$")
- )
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 103)
- def _reduce_17(val, _values, result)
- result = {
- val[0].to_sym => StringRegexpMatcher.new(
- Regexp.new(Regexp.escape(string_value(val[2])))
- )
- }
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 110)
- def _reduce_18(val, _values, result)
- result = {
- val[0].to_sym => IndifferentRegexpMatcher.new(
- Regexp.new(regexp_value(val[2]))
- )
- }
-
- result
- end
-.,.,
-
-# reduce 19 omitted
-
-# reduce 20 omitted
-
-# reduce 21 omitted
-
-# reduce 22 omitted
-
-# reduce 23 omitted
-
-# reduce 24 omitted
-
-# reduce 25 omitted
-
-# reduce 26 omitted
-
-# reduce 27 omitted
-
-# reduce 28 omitted
-
-# reduce 29 omitted
-
-# reduce 30 omitted
-
-# reduce 31 omitted
-
-module_eval(<<'.,.,', 'machete.y', 134)
- def _reduce_32(val, _values, result)
- result = ArrayMatcher.new(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 136)
- def _reduce_33(val, _values, result)
- result = []
- result
- end
-.,.,
-
-# reduce 34 omitted
-
-module_eval(<<'.,.,', 'machete.y', 139)
- def _reduce_35(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 140)
- def _reduce_36(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-# reduce 37 omitted
-
-module_eval(<<'.,.,', 'machete.y', 143)
- def _reduce_38(val, _values, result)
- result = Quantifier.new(val[0], *val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 145)
- def _reduce_39(val, _values, result)
- result = [0, nil, 1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 146)
- def _reduce_40(val, _values, result)
- result = [1, nil, 1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 147)
- def _reduce_41(val, _values, result)
- result = [0, 1, 1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 149)
- def _reduce_42(val, _values, result)
- result = [integer_value(val[1]), integer_value(val[1]), 1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 152)
- def _reduce_43(val, _values, result)
- result = [integer_value(val[1]), nil, 1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 155)
- def _reduce_44(val, _values, result)
- result = [0, integer_value(val[2]), 1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 158)
- def _reduce_45(val, _values, result)
- result = [integer_value(val[1]), integer_value(val[3]), 1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 160)
- def _reduce_46(val, _values, result)
- result = [0, nil, 2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 161)
- def _reduce_47(val, _values, result)
- result = [1, nil, 2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 163)
- def _reduce_48(val, _values, result)
- result = LiteralMatcher.new(nil)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 164)
- def _reduce_49(val, _values, result)
- result = LiteralMatcher.new(true)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 165)
- def _reduce_50(val, _values, result)
- result = LiteralMatcher.new(false)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 166)
- def _reduce_51(val, _values, result)
- result = LiteralMatcher.new(integer_value(val[0]))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 167)
- def _reduce_52(val, _values, result)
- result = LiteralMatcher.new(symbol_value(val[0]))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 168)
- def _reduce_53(val, _values, result)
- result = LiteralMatcher.new(string_value(val[0]))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 169)
- def _reduce_54(val, _values, result)
- result = LiteralMatcher.new(regexp_value(val[0]))
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'machete.y', 171)
- def _reduce_55(val, _values, result)
- result = AnyMatcher.new
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module Machete
diff --git a/test/racc/regress/mediacloth b/test/racc/regress/mediacloth
deleted file mode 100644
index cca7d3c7e4..0000000000
--- a/test/racc/regress/mediacloth
+++ /dev/null
@@ -1,1463 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-require 'mediacloth/mediawikiast'
-
-class MediaWikiParser < Racc::Parser
-
-module_eval(<<'...end mediacloth.y/module_eval...', 'mediacloth.y', 564)
-
-attr_accessor :lexer
-
-def initialize
- @nodes = []
- @context = []
- @wiki_ast_length = 0
- super
-end
-
-#Tokenizes input string and parses it.
-def parse(input)
- @yydebug=true
- lexer.tokenize(input)
- do_parse
- return @nodes.last
-end
-
-#Asks the lexer to return the next token.
-def next_token
- token = @lexer.lex
- if token[0].to_s.upcase.include? "_START"
- @context << token[2..3]
- elsif token[0].to_s.upcase.include? "_END"
- @ast_index = @context.last[0]
- @ast_length = token[2] + token[3] - @context.last[0]
- @context.pop
- else
- @ast_index = token[2]
- @ast_length = token[3]
- end
-
- @wiki_ast_length += token[3]
-
- return token[0..1]
-end
-...end mediacloth.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 22, 28, 50, 29, 61, 13, 63, 132, 15, 86,
- 37, 87, 24, 33, 86, 34, 87, 35, 85, 23,
- 26, 25, 27, 12, 86, 30, 87, 31, 86, 42,
- 87, 32, 44, 86, 48, 87, 57, 17, 57, 22,
- 28, 21, 29, 46, 13, 51, 67, 15, 68, 11,
- 36, 24, 33, 14, 34, 69, 35, 36, 23, 26,
- 25, 27, 12, 86, 30, 87, 31, 75, 73, 70,
- 32, 48, 81, 71, 72, 76, 17, 77, 22, 28,
- 21, 29, 82, 13, 45, 51, 15, -65, 11, 36,
- 24, 33, 14, 34, -65, 35, 63, 23, 26, 25,
- 27, 12, 96, 30, 63, 31, 106, 109, 110, 32,
- 113, 114, 48, 117, 118, 17, 124, 22, 28, 21,
- 29, 57, 13, 127, 128, 15, 131, 11, 36, 24,
- 33, 14, 34, 136, 35, 137, 23, 26, 25, 27,
- 12, 138, 30, 75, 31, 51, 141, -63, 32, 106,
- 106, 150, 153, 51, 17, nil, nil, nil, 21, nil,
- 22, 28, 53, 29, nil, 13, 11, 36, 15, nil,
- 14, nil, 24, 33, nil, 34, nil, 35, nil, 23,
- 26, 25, 27, 12, nil, 30, nil, 31, nil, nil,
- nil, 32, nil, nil, nil, nil, nil, 17, nil, 22,
- 28, 21, 29, 55, 13, nil, nil, 15, nil, 11,
- 36, 24, 33, 14, 34, nil, 35, nil, 23, 26,
- 25, 27, 12, nil, 30, nil, 31, nil, nil, nil,
- 32, nil, nil, nil, nil, nil, 17, nil, 22, 28,
- 21, 29, nil, 13, nil, nil, 15, nil, 11, 36,
- 24, 33, 14, 34, nil, 35, nil, 23, 26, 25,
- 27, 12, nil, 30, nil, 31, nil, nil, nil, 32,
- nil, nil, nil, nil, nil, 17, nil, 22, 28, 21,
- 29, nil, 13, nil, nil, 15, nil, 11, 36, 24,
- 33, 14, 34, nil, 35, nil, 23, 26, 25, 27,
- 12, nil, 30, nil, 31, nil, nil, nil, 32, nil,
- nil, nil, nil, nil, 17, nil, 22, 28, 21, 29,
- nil, 13, nil, nil, 15, nil, 11, 36, 24, 33,
- 14, 34, nil, 35, nil, 23, 26, 25, 27, 12,
- nil, 30, nil, 31, nil, nil, nil, 32, nil, nil,
- nil, nil, nil, 17, nil, 22, 28, 21, 29, nil,
- 13, nil, nil, 15, nil, 11, 36, 24, 33, 14,
- 34, nil, 35, nil, 23, 26, 25, 27, 12, nil,
- 30, nil, 31, nil, nil, nil, 32, nil, nil, nil,
- nil, nil, 17, nil, 22, 28, 21, 29, nil, 13,
- nil, nil, 15, nil, 11, 36, 24, 33, 14, 34,
- nil, 35, nil, 23, 26, 25, 27, 12, nil, 30,
- nil, 31, nil, nil, nil, 32, nil, nil, nil, nil,
- nil, 17, 78, nil, nil, 21, nil, 22, 28, 88,
- 29, nil, 13, 11, 36, 15, nil, 14, nil, 24,
- 33, nil, 34, nil, 35, nil, 23, 26, 25, 27,
- 12, nil, 30, nil, 31, nil, nil, nil, 32, nil,
- nil, nil, nil, nil, 17, nil, 22, 28, 21, 29,
- 89, 13, nil, nil, 15, nil, 11, 36, 24, 33,
- 14, 34, nil, 35, nil, 23, 26, 25, 27, 12,
- nil, 30, nil, 31, nil, nil, nil, 32, nil, nil,
- nil, nil, nil, 17, nil, 22, 28, 21, 29, nil,
- 13, nil, nil, 15, nil, 11, 36, 24, 33, 14,
- 34, nil, 35, nil, 23, 26, 25, 27, 12, nil,
- 30, nil, 31, nil, nil, 93, 32, nil, nil, nil,
- nil, nil, 17, nil, 22, 28, 21, 29, nil, 13,
- nil, nil, 15, nil, 11, 36, 24, 33, 14, 34,
- nil, 35, nil, 23, 26, 25, 27, 12, nil, 30,
- nil, 31, nil, nil, nil, 32, nil, nil, 98, nil,
- nil, 17, nil, 22, 28, 21, 29, nil, 13, nil,
- nil, 15, nil, 11, 36, 24, 33, 14, 34, nil,
- 35, nil, 23, 26, 25, 27, 12, nil, 30, nil,
- 31, nil, nil, nil, 32, nil, nil, nil, nil, 101,
- 17, nil, nil, nil, 21, nil, 22, 28, nil, 29,
- nil, 13, 11, 36, 15, nil, 14, nil, 24, 33,
- 102, 34, nil, 35, nil, 23, 26, 25, 27, 12,
- nil, 30, nil, 31, nil, nil, nil, 32, nil, nil,
- nil, nil, nil, 17, nil, 22, 28, 21, 29, nil,
- 13, nil, nil, 15, nil, 11, 36, 24, 33, 14,
- 34, 103, 35, nil, 23, 26, 25, 27, 12, nil,
- 30, nil, 31, nil, nil, nil, 32, nil, nil, nil,
- nil, nil, 17, nil, 22, 28, 21, 29, nil, 13,
- nil, nil, 15, nil, 11, 36, 24, 33, 14, 34,
- nil, 35, 104, 23, 26, 25, 27, 12, nil, 30,
- nil, 31, nil, nil, nil, 32, nil, nil, nil, nil,
- nil, 17, nil, 22, 28, 21, 29, nil, 13, nil,
- nil, 15, nil, 11, 36, 24, 33, 14, 34, nil,
- 35, nil, 23, 26, 25, 27, 12, nil, 30, nil,
- 31, nil, nil, nil, 32, nil, nil, nil, nil, nil,
- 17, nil, 22, 28, 21, 29, nil, 13, nil, nil,
- 15, nil, 11, 36, 24, 33, 14, 34, nil, 35,
- nil, 23, 26, 25, 27, 12, nil, 30, nil, 31,
- nil, nil, nil, 32, nil, nil, nil, nil, nil, 17,
- nil, 22, 28, 21, 29, nil, 13, nil, nil, 15,
- nil, 11, 36, 24, 33, 14, 34, nil, 35, nil,
- 23, 26, 25, 27, 12, nil, 30, nil, 31, nil,
- nil, nil, 32, nil, nil, nil, nil, nil, 17, 115,
- 22, 28, 21, 29, nil, 13, nil, nil, 15, nil,
- 11, 36, 24, 33, 14, 34, nil, 35, nil, 23,
- 26, 25, 27, 12, nil, 30, nil, 31, nil, nil,
- nil, 32, nil, nil, nil, nil, nil, 17, nil, 22,
- 28, 21, 29, nil, 13, nil, 121, 15, nil, 11,
- 36, 24, 33, 14, 34, nil, 35, nil, 23, 26,
- 25, 27, 12, nil, 30, nil, 31, nil, nil, nil,
- 32, nil, nil, nil, nil, nil, 17, nil, 22, 28,
- 21, 29, nil, 13, nil, nil, 15, 123, 11, 36,
- 24, 33, 14, 34, nil, 35, nil, 23, 26, 25,
- 27, 12, nil, 30, nil, 31, nil, nil, 126, 32,
- nil, nil, nil, nil, nil, 17, nil, 22, 28, 21,
- 29, nil, 13, nil, nil, 15, nil, 11, 36, 24,
- 33, 14, 34, nil, 35, nil, 23, 26, 25, 27,
- 12, nil, 30, nil, 31, nil, nil, nil, 32, nil,
- nil, 129, nil, nil, 17, nil, 22, 28, 21, 29,
- nil, 13, nil, nil, 15, nil, 11, 36, 24, 33,
- 14, 34, nil, 35, nil, 23, 26, 25, 27, 12,
- nil, 30, nil, 31, nil, nil, nil, 32, nil, nil,
- nil, nil, 130, 17, nil, 22, 28, 21, 29, nil,
- 13, nil, 134, 15, nil, 11, 36, 24, 33, 14,
- 34, nil, 35, nil, 23, 26, 25, 27, 12, nil,
- 30, nil, 31, nil, nil, nil, 32, nil, nil, nil,
- nil, nil, 17, nil, 22, 28, 21, 29, nil, 13,
- nil, nil, 15, nil, 11, 36, 24, 33, 14, 34,
- nil, 35, nil, 23, 26, 25, 27, 12, nil, 30,
- nil, 31, nil, nil, nil, 32, nil, nil, nil, nil,
- nil, 17, nil, 22, 28, 21, 29, nil, 13, nil,
- nil, 15, nil, 11, 36, 24, 33, 14, 34, nil,
- 35, nil, 23, 26, 25, 27, 12, nil, 30, nil,
- 31, nil, nil, nil, 32, nil, nil, nil, nil, nil,
- 17, nil, 22, 28, 21, 29, nil, 13, nil, 142,
- 15, nil, 11, 36, 24, 33, 14, 34, nil, 35,
- nil, 23, 26, 25, 27, 12, nil, 30, nil, 31,
- nil, nil, nil, 32, nil, nil, nil, nil, nil, 17,
- nil, 22, 28, 21, 29, nil, 13, nil, nil, 15,
- 144, 11, 36, 24, 33, 14, 34, nil, 35, nil,
- 23, 26, 25, 27, 12, nil, 30, nil, 31, nil,
- nil, nil, 32, nil, nil, nil, nil, nil, 17, nil,
- nil, nil, 21, nil, nil, nil, nil, nil, nil, nil,
- 11, 36, 22, 28, 14, 29, nil, 13, nil, nil,
- 15, nil, 136, nil, 24, 33, nil, 34, nil, 35,
- nil, 23, 26, 25, 27, 12, nil, 30, nil, 31,
- nil, nil, nil, 32, nil, nil, nil, nil, nil, 17,
- nil, nil, nil, 21, nil, nil, nil, nil, nil, nil,
- nil, 11, 36, 22, 28, 14, 29, nil, 13, nil,
- nil, 15, nil, 136, nil, 24, 33, nil, 34, nil,
- 35, nil, 23, 26, 25, 27, 12, nil, 30, nil,
- 31, nil, nil, nil, 32, nil, nil, nil, nil, nil,
- 17, nil, nil, nil, 21, nil, nil, nil, nil, nil,
- nil, nil, 11, 36, nil, nil, 14 ]
-
-racc_action_check = [
- 0, 0, 21, 0, 32, 0, 32, 106, 0, 85,
- 1, 85, 0, 0, 121, 0, 121, 0, 51, 0,
- 0, 0, 0, 0, 123, 0, 123, 0, 142, 13,
- 142, 0, 15, 144, 17, 144, 30, 0, 31, 2,
- 2, 0, 2, 15, 2, 21, 36, 2, 37, 0,
- 0, 2, 2, 0, 2, 39, 2, 106, 2, 2,
- 2, 2, 2, 51, 2, 51, 2, 44, 44, 41,
- 2, 48, 48, 42, 43, 45, 2, 46, 12, 12,
- 2, 12, 49, 12, 15, 50, 12, 56, 2, 2,
- 12, 12, 2, 12, 58, 12, 59, 12, 12, 12,
- 12, 12, 60, 12, 62, 12, 67, 73, 74, 12,
- 76, 77, 81, 83, 84, 12, 90, 14, 14, 12,
- 14, 91, 14, 94, 95, 14, 105, 12, 12, 14,
- 14, 12, 14, 109, 14, 112, 14, 14, 14, 14,
- 14, 113, 14, 114, 14, 118, 119, 125, 14, 132,
- 133, 135, 139, 141, 14, nil, nil, nil, 14, nil,
- 28, 28, 28, 28, nil, 28, 14, 14, 28, nil,
- 14, nil, 28, 28, nil, 28, nil, 28, nil, 28,
- 28, 28, 28, 28, nil, 28, nil, 28, nil, nil,
- nil, 28, nil, nil, nil, nil, nil, 28, nil, 29,
- 29, 28, 29, 29, 29, nil, nil, 29, nil, 28,
- 28, 29, 29, 28, 29, nil, 29, nil, 29, 29,
- 29, 29, 29, nil, 29, nil, 29, nil, nil, nil,
- 29, nil, nil, nil, nil, nil, 29, nil, 33, 33,
- 29, 33, nil, 33, nil, nil, 33, nil, 29, 29,
- 33, 33, 29, 33, nil, 33, nil, 33, 33, 33,
- 33, 33, nil, 33, nil, 33, nil, nil, nil, 33,
- nil, nil, nil, nil, nil, 33, nil, 34, 34, 33,
- 34, nil, 34, nil, nil, 34, nil, 33, 33, 34,
- 34, 33, 34, nil, 34, nil, 34, 34, 34, 34,
- 34, nil, 34, nil, 34, nil, nil, nil, 34, nil,
- nil, nil, nil, nil, 34, nil, 35, 35, 34, 35,
- nil, 35, nil, nil, 35, nil, 34, 34, 35, 35,
- 34, 35, nil, 35, nil, 35, 35, 35, 35, 35,
- nil, 35, nil, 35, nil, nil, nil, 35, nil, nil,
- nil, nil, nil, 35, nil, 40, 40, 35, 40, nil,
- 40, nil, nil, 40, nil, 35, 35, 40, 40, 35,
- 40, nil, 40, nil, 40, 40, 40, 40, 40, nil,
- 40, nil, 40, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, 40, nil, 47, 47, 40, 47, nil, 47,
- nil, nil, 47, nil, 40, 40, 47, 47, 40, 47,
- nil, 47, nil, 47, 47, 47, 47, 47, nil, 47,
- nil, 47, nil, nil, nil, 47, nil, nil, nil, nil,
- nil, 47, 47, nil, nil, 47, nil, 52, 52, 52,
- 52, nil, 52, 47, 47, 52, nil, 47, nil, 52,
- 52, nil, 52, nil, 52, nil, 52, 52, 52, 52,
- 52, nil, 52, nil, 52, nil, nil, nil, 52, nil,
- nil, nil, nil, nil, 52, nil, 54, 54, 52, 54,
- 54, 54, nil, nil, 54, nil, 52, 52, 54, 54,
- 52, 54, nil, 54, nil, 54, 54, 54, 54, 54,
- nil, 54, nil, 54, nil, nil, nil, 54, nil, nil,
- nil, nil, nil, 54, nil, 57, 57, 54, 57, nil,
- 57, nil, nil, 57, nil, 54, 54, 57, 57, 54,
- 57, nil, 57, nil, 57, 57, 57, 57, 57, nil,
- 57, nil, 57, nil, nil, 57, 57, nil, nil, nil,
- nil, nil, 57, nil, 61, 61, 57, 61, nil, 61,
- nil, nil, 61, nil, 57, 57, 61, 61, 57, 61,
- nil, 61, nil, 61, 61, 61, 61, 61, nil, 61,
- nil, 61, nil, nil, nil, 61, nil, nil, 61, nil,
- nil, 61, nil, 63, 63, 61, 63, nil, 63, nil,
- nil, 63, nil, 61, 61, 63, 63, 61, 63, nil,
- 63, nil, 63, 63, 63, 63, 63, nil, 63, nil,
- 63, nil, nil, nil, 63, nil, nil, nil, nil, 63,
- 63, nil, nil, nil, 63, nil, 64, 64, nil, 64,
- nil, 64, 63, 63, 64, nil, 63, nil, 64, 64,
- 64, 64, nil, 64, nil, 64, 64, 64, 64, 64,
- nil, 64, nil, 64, nil, nil, nil, 64, nil, nil,
- nil, nil, nil, 64, nil, 65, 65, 64, 65, nil,
- 65, nil, nil, 65, nil, 64, 64, 65, 65, 64,
- 65, 65, 65, nil, 65, 65, 65, 65, 65, nil,
- 65, nil, 65, nil, nil, nil, 65, nil, nil, nil,
- nil, nil, 65, nil, 66, 66, 65, 66, nil, 66,
- nil, nil, 66, nil, 65, 65, 66, 66, 65, 66,
- nil, 66, 66, 66, 66, 66, 66, 66, nil, 66,
- nil, 66, nil, nil, nil, 66, nil, nil, nil, nil,
- nil, 66, nil, 71, 71, 66, 71, nil, 71, nil,
- nil, 71, nil, 66, 66, 71, 71, 66, 71, nil,
- 71, nil, 71, 71, 71, 71, 71, nil, 71, nil,
- 71, nil, nil, nil, 71, nil, nil, nil, nil, nil,
- 71, nil, 75, 75, 71, 75, nil, 75, nil, nil,
- 75, nil, 71, 71, 75, 75, 71, 75, nil, 75,
- nil, 75, 75, 75, 75, 75, nil, 75, nil, 75,
- nil, nil, nil, 75, nil, nil, nil, nil, nil, 75,
- nil, 79, 79, 75, 79, nil, 79, nil, nil, 79,
- nil, 75, 75, 79, 79, 75, 79, nil, 79, nil,
- 79, 79, 79, 79, 79, nil, 79, nil, 79, nil,
- nil, nil, 79, nil, nil, nil, nil, nil, 79, 79,
- 86, 86, 79, 86, nil, 86, nil, nil, 86, nil,
- 79, 79, 86, 86, 79, 86, nil, 86, nil, 86,
- 86, 86, 86, 86, nil, 86, nil, 86, nil, nil,
- nil, 86, nil, nil, nil, nil, nil, 86, nil, 87,
- 87, 86, 87, nil, 87, nil, 86, 87, nil, 86,
- 86, 87, 87, 86, 87, nil, 87, nil, 87, 87,
- 87, 87, 87, nil, 87, nil, 87, nil, nil, nil,
- 87, nil, nil, nil, nil, nil, 87, nil, 92, 92,
- 87, 92, nil, 92, nil, nil, 92, 87, 87, 87,
- 92, 92, 87, 92, nil, 92, nil, 92, 92, 92,
- 92, 92, nil, 92, nil, 92, nil, nil, 92, 92,
- nil, nil, nil, nil, nil, 92, nil, 97, 97, 92,
- 97, nil, 97, nil, nil, 97, nil, 92, 92, 97,
- 97, 92, 97, nil, 97, nil, 97, 97, 97, 97,
- 97, nil, 97, nil, 97, nil, nil, nil, 97, nil,
- nil, 97, nil, nil, 97, nil, 100, 100, 97, 100,
- nil, 100, nil, nil, 100, nil, 97, 97, 100, 100,
- 97, 100, nil, 100, nil, 100, 100, 100, 100, 100,
- nil, 100, nil, 100, nil, nil, nil, 100, nil, nil,
- nil, nil, 100, 100, nil, 108, 108, 100, 108, nil,
- 108, nil, 108, 108, nil, 100, 100, 108, 108, 100,
- 108, nil, 108, nil, 108, 108, 108, 108, 108, nil,
- 108, nil, 108, nil, nil, nil, 108, nil, nil, nil,
- nil, nil, 108, nil, 111, 111, 108, 111, nil, 111,
- nil, nil, 111, nil, 108, 108, 111, 111, 108, 111,
- nil, 111, nil, 111, 111, 111, 111, 111, nil, 111,
- nil, 111, nil, nil, nil, 111, nil, nil, nil, nil,
- nil, 111, nil, 120, 120, 111, 120, nil, 120, nil,
- nil, 120, nil, 111, 111, 120, 120, 111, 120, nil,
- 120, nil, 120, 120, 120, 120, 120, nil, 120, nil,
- 120, nil, nil, nil, 120, nil, nil, nil, nil, nil,
- 120, nil, 122, 122, 120, 122, nil, 122, nil, 120,
- 122, nil, 120, 120, 122, 122, 120, 122, nil, 122,
- nil, 122, 122, 122, 122, 122, nil, 122, nil, 122,
- nil, nil, nil, 122, nil, nil, nil, nil, nil, 122,
- nil, 134, 134, 122, 134, nil, 134, nil, nil, 134,
- 122, 122, 122, 134, 134, 122, 134, nil, 134, nil,
- 134, 134, 134, 134, 134, nil, 134, nil, 134, nil,
- nil, nil, 134, nil, nil, nil, nil, nil, 134, nil,
- nil, nil, 134, nil, nil, nil, nil, nil, nil, nil,
- 134, 134, 136, 136, 134, 136, nil, 136, nil, nil,
- 136, nil, 136, nil, 136, 136, nil, 136, nil, 136,
- nil, 136, 136, 136, 136, 136, nil, 136, nil, 136,
- nil, nil, nil, 136, nil, nil, nil, nil, nil, 136,
- nil, nil, nil, 136, nil, nil, nil, nil, nil, nil,
- nil, 136, 136, 152, 152, 136, 152, nil, 152, nil,
- nil, 152, nil, 152, nil, 152, 152, nil, 152, nil,
- 152, nil, 152, 152, 152, 152, 152, nil, 152, nil,
- 152, nil, nil, nil, 152, nil, nil, nil, nil, nil,
- 152, nil, nil, nil, 152, nil, nil, nil, nil, nil,
- nil, nil, 152, 152, nil, nil, 152 ]
-
-racc_action_pointer = [
- -2, 10, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 76, 27, 115, 30, nil, -7, nil, nil,
- nil, 0, nil, nil, nil, nil, nil, nil, 158, 197,
- 5, 7, -31, 236, 275, 314, 44, 48, nil, 29,
- 353, 61, 64, 18, 55, 73, 23, 392, 30, 38,
- 40, 16, 435, nil, 474, nil, 59, 513, 64, 59,
- 68, 552, 67, 591, 634, 673, 712, 94, nil, nil,
- nil, 751, nil, 105, 97, 790, 98, 109, nil, 829,
- nil, 71, nil, 69, 68, -38, 868, 907, nil, nil,
- 88, 90, 946, nil, 93, 90, nil, 985, nil, nil,
- 1024, nil, nil, nil, nil, 73, 5, nil, 1063, 121,
- nil, 1102, 124, 139, 131, nil, nil, nil, 100, 100,
- 1141, -33, 1180, -23, nil, 116, nil, nil, nil, nil,
- nil, nil, 137, 138, 1219, 140, 1270, nil, nil, 141,
- nil, 108, -19, nil, -14, nil, nil, nil, nil, nil,
- nil, nil, 1321, nil, nil, nil, nil, nil ]
-
-racc_action_default = [
- -83, -83, -1, -2, -3, -4, -5, -6, -7, -8,
- -9, -10, -19, -83, -19, -83, -18, -23, -37, -39,
- -40, -43, -51, -52, -53, -54, -55, -56, -83, -83,
- -83, -83, -73, -83, -83, -83, -83, -83, -38, -83,
- -20, -83, -26, -83, -30, -83, -83, -83, -23, -83,
- -43, -46, -83, -57, -83, -58, -63, -83, -63, -73,
- -83, -83, -73, -83, -83, -83, -83, -80, 158, -11,
- -12, -83, -13, -83, -83, -83, -32, -83, -21, -83,
- -24, -23, -41, -83, -83, -46, -83, -83, -59, -60,
- -83, -83, -83, -66, -83, -83, -69, -83, -70, -72,
- -83, -74, -76, -77, -78, -83, -83, -27, -28, -34,
- -15, -31, -83, -83, -30, -22, -25, -42, -43, -83,
- -83, -46, -83, -46, -61, -65, -67, -62, -68, -71,
- -75, -79, -80, -80, -83, -83, -34, -16, -33, -83,
- -44, -43, -46, -47, -46, -49, -64, -81, -82, -29,
- -14, -35, -34, -17, -45, -48, -50, -36 ]
-
-racc_goto_table = [
- 38, 84, 74, 105, 49, 39, 90, 43, 94, 60,
- 135, 1, 133, 2, 47, 41, 107, 112, 59, 56,
- 58, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 83, nil, 119, 95, 151, 38, 99,
- nil, 52, 54, nil, nil, 80, 64, 65, 66, nil,
- 38, nil, 38, 157, nil, nil, nil, nil, nil, nil,
- 79, nil, 38, 38, 38, nil, nil, nil, 147, 148,
- 92, 143, 139, 145, 97, 146, 100, 38, 116, 149,
- 125, nil, nil, nil, 108, nil, nil, nil, 111, nil,
- 38, nil, 155, nil, 156, 38, nil, nil, 38, 120,
- 122, 140, nil, nil, nil, nil, 38, nil, nil, 38,
- nil, nil, nil, nil, nil, nil, nil, nil, 38, nil,
- 38, nil, nil, nil, 154, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 108, nil, 152,
- 38 ]
-
-racc_goto_check = [
- 3, 23, 15, 30, 22, 12, 25, 12, 25, 28,
- 14, 1, 11, 2, 18, 13, 19, 16, 27, 24,
- 24, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 22, nil, 23, 28, 14, 3, 28,
- nil, 2, 2, nil, nil, 18, 2, 2, 2, nil,
- 3, nil, 3, 14, nil, nil, nil, nil, nil, nil,
- 2, nil, 3, 3, 3, nil, nil, nil, 30, 30,
- 2, 23, 15, 23, 2, 25, 2, 3, 18, 19,
- 24, nil, nil, nil, 2, nil, nil, nil, 2, nil,
- 3, nil, 23, nil, 23, 3, nil, nil, 3, 2,
- 2, 22, nil, nil, nil, nil, 3, nil, nil, 3,
- nil, nil, nil, nil, nil, nil, nil, nil, 3, nil,
- 3, nil, nil, nil, 22, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 2, nil, 2,
- 3 ]
-
-racc_goto_pointer = [
- nil, 11, 13, -2, nil, nil, nil, nil, nil, nil,
- nil, -94, -7, 2, -99, -42, -59, nil, -3, -55,
- nil, nil, -17, -50, -11, -50, nil, -14, -23, nil,
- -64 ]
-
-racc_goto_default = [
- nil, nil, 40, 18, 3, 4, 5, 6, 7, 8,
- 9, 10, nil, nil, nil, nil, nil, 16, nil, nil,
- 19, 20, nil, nil, nil, nil, 91, nil, nil, 62,
- nil ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 58, :_reduce_1,
- 1, 60, :_reduce_2,
- 1, 60, :_reduce_3,
- 1, 60, :_reduce_4,
- 1, 60, :_reduce_5,
- 1, 60, :_reduce_6,
- 1, 60, :_reduce_7,
- 1, 60, :_reduce_8,
- 1, 60, :_reduce_9,
- 1, 60, :_reduce_10,
- 3, 60, :_reduce_11,
- 3, 60, :_reduce_12,
- 3, 60, :_reduce_13,
- 6, 60, :_reduce_14,
- 4, 60, :_reduce_15,
- 5, 60, :_reduce_16,
- 6, 60, :_reduce_17,
- 1, 60, :_reduce_none,
- 0, 69, :_reduce_19,
- 1, 69, :_reduce_20,
- 3, 67, :_reduce_21,
- 4, 67, :_reduce_22,
- 0, 75, :_reduce_23,
- 2, 75, :_reduce_24,
- 3, 75, :_reduce_25,
- 1, 70, :_reduce_26,
- 3, 70, :_reduce_27,
- 1, 76, :_reduce_28,
- 3, 76, :_reduce_29,
- 0, 72, :_reduce_30,
- 2, 72, :_reduce_31,
- 0, 73, :_reduce_32,
- 2, 73, :_reduce_33,
- 0, 71, :_reduce_34,
- 2, 71, :_reduce_35,
- 3, 71, :_reduce_36,
- 1, 59, :_reduce_37,
- 2, 59, :_reduce_38,
- 1, 61, :_reduce_39,
- 1, 61, :_reduce_40,
- 3, 74, :_reduce_41,
- 4, 74, :_reduce_42,
- 0, 79, :_reduce_43,
- 4, 79, :_reduce_44,
- 5, 79, :_reduce_45,
- 0, 80, :_reduce_46,
- 3, 80, :_reduce_47,
- 4, 80, :_reduce_48,
- 3, 80, :_reduce_49,
- 4, 80, :_reduce_50,
- 1, 77, :_reduce_51,
- 1, 77, :_reduce_52,
- 1, 77, :_reduce_53,
- 1, 77, :_reduce_54,
- 1, 77, :_reduce_55,
- 1, 77, :_reduce_56,
- 2, 78, :_reduce_57,
- 2, 78, :_reduce_58,
- 3, 78, :_reduce_59,
- 3, 78, :_reduce_60,
- 4, 62, :_reduce_61,
- 4, 63, :_reduce_62,
- 0, 83, :_reduce_63,
- 3, 82, :_reduce_64,
- 0, 82, :_reduce_65,
- 2, 81, :_reduce_66,
- 3, 81, :_reduce_67,
- 4, 64, :_reduce_68,
- 3, 64, :_reduce_69,
- 2, 84, :_reduce_70,
- 3, 84, :_reduce_71,
- 2, 85, :_reduce_72,
- 0, 85, :_reduce_73,
- 2, 86, :_reduce_74,
- 3, 86, :_reduce_75,
- 3, 65, :_reduce_76,
- 3, 65, :_reduce_77,
- 3, 66, :_reduce_78,
- 4, 68, :_reduce_79,
- 0, 87, :_reduce_80,
- 3, 87, :_reduce_81,
- 3, 87, :_reduce_82 ]
-
-racc_reduce_n = 83
-
-racc_shift_n = 158
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :TEXT => 2,
- :BOLD_START => 3,
- :BOLD_END => 4,
- :ITALIC_START => 5,
- :ITALIC_END => 6,
- :LINK_START => 7,
- :LINK_END => 8,
- :LINKSEP => 9,
- :INTLINK_START => 10,
- :INTLINK_END => 11,
- :INTLINKSEP => 12,
- :RESOURCESEP => 13,
- :CHAR_ENT => 14,
- :PRE_START => 15,
- :PRE_END => 16,
- :PREINDENT_START => 17,
- :PREINDENT_END => 18,
- :SECTION_START => 19,
- :SECTION_END => 20,
- :HLINE => 21,
- :SIGNATURE_NAME => 22,
- :SIGNATURE_DATE => 23,
- :SIGNATURE_FULL => 24,
- :PARA_START => 25,
- :PARA_END => 26,
- :UL_START => 27,
- :UL_END => 28,
- :OL_START => 29,
- :OL_END => 30,
- :LI_START => 31,
- :LI_END => 32,
- :DL_START => 33,
- :DL_END => 34,
- :DT_START => 35,
- :DT_END => 36,
- :DD_START => 37,
- :DD_END => 38,
- :TAG_START => 39,
- :TAG_END => 40,
- :ATTR_NAME => 41,
- :ATTR_VALUE => 42,
- :TABLE_START => 43,
- :TABLE_END => 44,
- :ROW_START => 45,
- :ROW_END => 46,
- :HEAD_START => 47,
- :HEAD_END => 48,
- :CELL_START => 49,
- :CELL_END => 50,
- :KEYWORD => 51,
- :TEMPLATE_START => 52,
- :TEMPLATE_END => 53,
- :CATEGORY => 54,
- :PASTE_START => 55,
- :PASTE_END => 56 }
-
-racc_nt_base = 57
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "TEXT",
- "BOLD_START",
- "BOLD_END",
- "ITALIC_START",
- "ITALIC_END",
- "LINK_START",
- "LINK_END",
- "LINKSEP",
- "INTLINK_START",
- "INTLINK_END",
- "INTLINKSEP",
- "RESOURCESEP",
- "CHAR_ENT",
- "PRE_START",
- "PRE_END",
- "PREINDENT_START",
- "PREINDENT_END",
- "SECTION_START",
- "SECTION_END",
- "HLINE",
- "SIGNATURE_NAME",
- "SIGNATURE_DATE",
- "SIGNATURE_FULL",
- "PARA_START",
- "PARA_END",
- "UL_START",
- "UL_END",
- "OL_START",
- "OL_END",
- "LI_START",
- "LI_END",
- "DL_START",
- "DL_END",
- "DT_START",
- "DT_END",
- "DD_START",
- "DD_END",
- "TAG_START",
- "TAG_END",
- "ATTR_NAME",
- "ATTR_VALUE",
- "TABLE_START",
- "TABLE_END",
- "ROW_START",
- "ROW_END",
- "HEAD_START",
- "HEAD_END",
- "CELL_START",
- "CELL_END",
- "KEYWORD",
- "TEMPLATE_START",
- "TEMPLATE_END",
- "CATEGORY",
- "PASTE_START",
- "PASTE_END",
- "$start",
- "wiki",
- "repeated_contents",
- "contents",
- "text",
- "bulleted_list",
- "numbered_list",
- "dictionary_list",
- "preformatted",
- "section",
- "tag",
- "template",
- "para_contents",
- "link_contents",
- "reslink_repeated_contents",
- "intlink_repeated_contents",
- "cat_sort_contents",
- "table",
- "tag_attributes",
- "link_repeated_contents",
- "element",
- "formatted_element",
- "table_contents",
- "row_contents",
- "list_item",
- "list_contents",
- "@1",
- "dictionary_term",
- "dictionary_contents",
- "dictionary_definition",
- "template_parameters" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'mediacloth.y', 47)
- def _reduce_1(val, _values, result)
- @nodes.push WikiAST.new(0, @wiki_ast_length)
- #@nodes.last.children.insert(0, val[0])
- #puts val[0]
- @nodes.last.children += val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 57)
- def _reduce_2(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 61)
- def _reduce_3(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 65)
- def _reduce_4(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 69)
- def _reduce_5(val, _values, result)
- list = ListAST.new(@ast_index, @ast_length)
- list.list_type = :Dictionary
- list.children = val[0]
- result = list
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 76)
- def _reduce_6(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 80)
- def _reduce_7(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 84)
- def _reduce_8(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 88)
- def _reduce_9(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 92)
- def _reduce_10(val, _values, result)
- k = KeywordAST.new(@ast_index, @ast_length)
- k.text = val[0]
- result = k
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 98)
- def _reduce_11(val, _values, result)
- p = ParagraphAST.new(@ast_index, @ast_length)
- p.children = val[1]
- result = p
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 104)
- def _reduce_12(val, _values, result)
- l = LinkAST.new(@ast_index, @ast_length)
- l.link_type = val[0]
- l.url = val[1][0]
- l.children += val[1][1..-1] if val[1].length > 1
- result = l
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 112)
- def _reduce_13(val, _values, result)
- p = PasteAST.new(@ast_index, @ast_length)
- p.children = val[1]
- result = p
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 118)
- def _reduce_14(val, _values, result)
- l = ResourceLinkAST.new(@ast_index, @ast_length)
- l.prefix = val[1]
- l.locator = val[3]
- l.children = val[4] unless val[4].nil? or val[4].empty?
- result = l
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 126)
- def _reduce_15(val, _values, result)
- l = InternalLinkAST.new(@ast_index, @ast_length)
- l.locator = val[1]
- l.children = val[2] unless val[2].nil? or val[2].empty?
- result = l
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 133)
- def _reduce_16(val, _values, result)
- l = CategoryAST.new(@ast_index, @ast_length)
- l.locator = val[2]
- l.sort_as = val[3]
- result = l
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 140)
- def _reduce_17(val, _values, result)
- l = CategoryLinkAST.new(@ast_index, @ast_length)
- l.locator = val[3]
- l.children = val[4] unless val[4].nil? or val[4].empty?
- result = l
-
- result
- end
-.,.,
-
-# reduce 18 omitted
-
-module_eval(<<'.,.,', 'mediacloth.y', 150)
- def _reduce_19(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 154)
- def _reduce_20(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 161)
- def _reduce_21(val, _values, result)
- if val[0] != val[2]
- raise Racc::ParseError.new("XHTML end tag #{val[2]} does not match start tag #{val[0]}")
- end
- elem = ElementAST.new(@ast_index, @ast_length)
- elem.name = val[0]
- elem.attributes = val[1]
- result = elem
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 171)
- def _reduce_22(val, _values, result)
- if val[0] != val[3]
- raise Racc::ParseError.new("XHTML end tag #{val[3]} does not match start tag #{val[0]}")
- end
- elem = ElementAST.new(@ast_index, @ast_length)
- elem.name = val[0]
- elem.attributes = val[1]
- elem.children += val[2]
- result = elem
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 184)
- def _reduce_23(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 188)
- def _reduce_24(val, _values, result)
- attr_map = val[2] ? val[2] : {}
- attr_map[val[0]] = true
- result = attr_map
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 194)
- def _reduce_25(val, _values, result)
- attr_map = val[2] ? val[2] : {}
- attr_map[val[0]] = val[1]
- result = attr_map
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 204)
- def _reduce_26(val, _values, result)
- result = val
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 208)
- def _reduce_27(val, _values, result)
- result = [val[0]]
- result += val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 217)
- def _reduce_28(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 221)
- def _reduce_29(val, _values, result)
- result = val[0]
- result += val[2] if val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 229)
- def _reduce_30(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 233)
- def _reduce_31(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 239)
- def _reduce_32(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 243)
- def _reduce_33(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 249)
- def _reduce_34(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 253)
- def _reduce_35(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 257)
- def _reduce_36(val, _values, result)
- i = InternalLinkItemAST.new(@ast_index, @ast_length)
- i.children = val[1]
- result = [i]
- result += val[2] if val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 266)
- def _reduce_37(val, _values, result)
- result = []
- result << val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 271)
- def _reduce_38(val, _values, result)
- result = []
- result += val[0]
- result << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 279)
- def _reduce_39(val, _values, result)
- p = TextAST.new(@ast_index, @ast_length)
- p.formatting = val[0][0]
- p.contents = val[0][1]
- result = p
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 286)
- def _reduce_40(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 293)
- def _reduce_41(val, _values, result)
- table = TableAST.new(@ast_index, @ast_length)
- table.children = val[1] unless val[1].nil? or val[1].empty?
- result = table
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 299)
- def _reduce_42(val, _values, result)
- table = TableAST.new(@ast_index, @ast_length)
- table.options = val[1]
- table.children = val[2] unless val[2].nil? or val[2].empty?
- result = table
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 307)
- def _reduce_43(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 311)
- def _reduce_44(val, _values, result)
- row = TableRowAST.new(@ast_index, @ast_length)
- row.children = val[1] unless val[1].nil? or val[1].empty?
- result = [row]
- result += val[3] unless val[3].nil? or val[3].empty?
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 318)
- def _reduce_45(val, _values, result)
- row = TableRowAST.new(@ast_index, @ast_length)
- row.children = val[2] unless val[2].nil? or val[2].empty?
- row.options = val[1]
- result = [row]
- result += val[4] unless val[4].nil? or val[4].empty?
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 327)
- def _reduce_46(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 331)
- def _reduce_47(val, _values, result)
- cell = TableCellAST.new(@ast_index, @ast_length)
- cell.type = :head
- result = [cell]
- result += val[2] unless val[2].nil? or val[2].empty?
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 338)
- def _reduce_48(val, _values, result)
- cell = TableCellAST.new(@ast_index, @ast_length)
- cell.children = val[1] unless val[1].nil? or val[1].empty?
- cell.type = :head
- result = [cell]
- result += val[3] unless val[3].nil? or val[3].empty?
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 346)
- def _reduce_49(val, _values, result)
- cell = TableCellAST.new(@ast_index, @ast_length)
- cell.type = :body
- result = [cell]
- result += val[2] unless val[2].nil? or val[2].empty?
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 353)
- def _reduce_50(val, _values, result)
- if val[2] == 'attributes'
- result = []
- else
- cell = TableCellAST.new(@ast_index, @ast_length)
- cell.children = val[1] unless val[1].nil? or val[1].empty?
- cell.type = :body
- result = [cell]
- end
- result += val[3] unless val[3].nil? or val[3].empty?
- if val[2] == 'attributes' and val[3] and val[3].first.class == TableCellAST
- val[3].first.attributes = val[1]
- end
- result
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 371)
- def _reduce_51(val, _values, result)
- return [:None, val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 373)
- def _reduce_52(val, _values, result)
- return [:HLine, val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 375)
- def _reduce_53(val, _values, result)
- return [:CharacterEntity, val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 377)
- def _reduce_54(val, _values, result)
- return [:SignatureDate, val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 379)
- def _reduce_55(val, _values, result)
- return [:SignatureName, val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 381)
- def _reduce_56(val, _values, result)
- return [:SignatureFull, val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 387)
- def _reduce_57(val, _values, result)
- result = FormattedAST.new(@ast_index, @ast_length)
- result.formatting = :Bold
- result
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 393)
- def _reduce_58(val, _values, result)
- result = FormattedAST.new(@ast_index, @ast_length)
- result.formatting = :Italic
- result
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 399)
- def _reduce_59(val, _values, result)
- p = FormattedAST.new(@ast_index, @ast_length)
- p.formatting = :Bold
- p.children += val[1]
- result = p
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 406)
- def _reduce_60(val, _values, result)
- p = FormattedAST.new(@ast_index, @ast_length)
- p.formatting = :Italic
- p.children += val[1]
- result = p
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 415)
- def _reduce_61(val, _values, result)
- list = ListAST.new(@ast_index, @ast_length)
- list.list_type = :Bulleted
- list.children << val[1]
- list.children += val[2]
- result = list
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 425)
- def _reduce_62(val, _values, result)
- list = ListAST.new(@ast_index, @ast_length)
- list.list_type = :Numbered
- list.children << val[1]
- list.children += val[2]
- result = list
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 434)
- def _reduce_63(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 437)
- def _reduce_64(val, _values, result)
- result << val[1]
- result += val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 441)
- def _reduce_65(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 447)
- def _reduce_66(val, _values, result)
- result = ListItemAST.new(@ast_index, @ast_length)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 451)
- def _reduce_67(val, _values, result)
- li = ListItemAST.new(@ast_index, @ast_length)
- li.children += val[1]
- result = li
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 460)
- def _reduce_68(val, _values, result)
- result = [val[1]]
- result += val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 465)
- def _reduce_69(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 472)
- def _reduce_70(val, _values, result)
- result = ListTermAST.new(@ast_index, @ast_length)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 476)
- def _reduce_71(val, _values, result)
- term = ListTermAST.new(@ast_index, @ast_length)
- term.children += val[1]
- result = term
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 484)
- def _reduce_72(val, _values, result)
- result = [val[0]]
- result += val[1] if val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 489)
- def _reduce_73(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 495)
- def _reduce_74(val, _values, result)
- result = ListDefinitionAST.new(@ast_index, @ast_length)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 499)
- def _reduce_75(val, _values, result)
- term = ListDefinitionAST.new(@ast_index, @ast_length)
- term.children += val[1]
- result = term
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 506)
- def _reduce_76(val, _values, result)
- p = PreformattedAST.new(@ast_index, @ast_length)
- p.children += val[1]
- result = p
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 512)
- def _reduce_77(val, _values, result)
- p = PreformattedAST.new(@ast_index, @ast_length)
- p.indented = true
- p.children += val[1]
- result = p
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 520)
- def _reduce_78(val, _values, result)
- result = [val[1], val[0].length]
- s = SectionAST.new(@ast_index, @ast_length)
- s.children = val[1]
- s.level = val[0].length
- result = s
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 530)
- def _reduce_79(val, _values, result)
- t = TemplateAST.new(@ast_index, @ast_length)
- t.template_name = val[1]
- t.children = val[2] unless val[2].nil? or val[2].empty?
- result = t
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 539)
- def _reduce_80(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 543)
- def _reduce_81(val, _values, result)
- p = TemplateParameterAST.new(@ast_index, @ast_length)
- p.parameter_value = val[1]
- result = [p]
- result += val[2] if val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mediacloth.y', 550)
- def _reduce_82(val, _values, result)
- p = TemplateParameterAST.new(@ast_index, @ast_length)
- p.children << val[1]
- result = [p]
- result += val[2] if val[2]
-
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
-end # class MediaWikiParser
diff --git a/test/racc/regress/mof b/test/racc/regress/mof
deleted file mode 100644
index d702292e51..0000000000
--- a/test/racc/regress/mof
+++ /dev/null
@@ -1,1368 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-
-# parser.rb - generated by racc
-
-require 'strscan'
-require 'rubygems'
-require 'cim'
-require File.join(__dir__, 'result')
-require File.join(__dir__, 'scanner')
-require File.join(__dir__, 'case')
-
-module MOF
- class Parser < Racc::Parser
-
-module_eval(<<'...end mof.y/module_eval...', 'mof.y', 571)
-
-#
-# Initialize MOF::Parser
-# MOF::Parser.new options = {}
-#
-# options -> Hash of options
-# :debug -> boolean
-# :includes -> array of include dirs
-# :style -> :cim or :wmi
-#
-def initialize options = {}
- @yydebug = options[:debug]
- @includes = options[:includes] || []
- @quiet = options[:quiet]
- @style = options[:style] || :cim # default to style CIM v2.2 syntax
-
- @lineno = 1
- @file = nil
- @iconv = nil
- @eol = "\n"
- @fname = nil
- @fstack = []
- @in_comment = false
- @seen_files = []
- @qualifiers = {}
-end
-
-#
-# Make options hash from argv
-#
-# returns [ files, options ]
-#
-
- def self.argv_handler name, argv
- files = []
- options = { :namespace => "" }
- while argv.size > 0
- case opt = argv.shift
- when "-h"
- $stderr.puts "Ruby MOF compiler"
- $stderr.puts "#{name} [-h] [-d] [-I <dir>] [<moffiles>]"
- $stderr.puts "Compiles <moffile>"
- $stderr.puts "\t-d debug"
- $stderr.puts "\t-h this help"
- $stderr.puts "\t-I <dir> include dir"
- $stderr.puts "\t-f force"
- $stderr.puts "\t-n <namespace>"
- $stderr.puts "\t-o <output>"
- $stderr.puts "\t-s <style> syntax style (wmi,cim)"
- $stderr.puts "\t-q quiet"
- $stderr.puts "\t<moffiles> file(s) to read (else use $stdin)"
- exit 0
- when "-f" then options[:force] = true
- when "-s" then options[:style] = argv.shift.to_sym
- when "-d" then options[:debug] = true
- when "-q" then options[:quiet] = true
- when "-I"
- options[:includes] ||= []
- dirname = argv.shift
- unless File.directory?(dirname)
- files << dirname
- dirname = File.dirname(dirname)
- end
- options[:includes] << Pathname.new(dirname)
- when "-n" then options[:namespace] = argv.shift
- when "-o" then options[:output] = argv.shift
- when /^-.+/
- $stderr.puts "Undefined option #{opt}"
- else
- files << opt
- end
- end
- [ files, options ]
- end
-
-include Helper
-include Scanner
-
-...end mof.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 13, 172, 163, 197, 174, 27, 63, 17, 145, 146,
- 147, 62, 28, 172, 11, 173, 174, 173, 148, 11,
- 144, 149, 150, 151, 152, 18, 163, 173, 33, 153,
- 106, 107, 108, 109, 110, 112, 111, 40, 15, 16,
- 42, 55, 57, 68, 69, 71, 72, 52, 53, 54,
- 56, 163, 7, 199, 35, 42, 174, 7, 10, 10,
- 115, 102, 114, 36, 10, 55, 57, 68, 69, 71,
- 72, 52, 53, 54, 56, 51, 190, 44, -77, 42,
- 33, 189, 10, 10, 33, 102, 51, 164, 60, 10,
- 55, 57, 68, 69, 71, 72, 52, 53, 54, 56,
- 170, 35, 10, 21, 42, 22, 23, 10, 29, 31,
- 102, 35, 95, 96, 55, 57, 25, 65, 24, 78,
- 52, 53, 54, 56, 97, 55, 57, 35, 180, 181,
- 100, 52, 53, 54, 56, 93, 79, 80, 81, 82,
- 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- -25, 93, 79, 80, 81, 82, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, 92, 191, 192, 102, 60,
- 55, 57, 68, 69, 71, 72, 52, 53, 54, 56,
- 145, 146, 147, 172, 113, 97, 174, 10, 18, 118,
- 148, 119, 144, 149, 150, 151, 152, 173, 121, 124,
- 35, 153, 55, 57, 68, 69, 71, 72, 52, 53,
- 54, 56, 106, 107, 108, 109, 110, 112, 111, 10,
- 55, 57, 68, 69, 71, 72, 52, 53, 54, 56,
- 21, 126, 22, 23, 127, 129, 21, 10, 22, 23,
- 130, 131, 133, 25, 135, 24, 10, 141, 154, 25,
- 35, 24, 93, 79, 80, 81, 82, 83, 84, 85,
- 86, 87, 88, 89, 90, 91, 92, 106, 107, 108,
- 109, 110, 112, 111, 184, 185, 194, 200, 121, 207,
- -59, 121, 209, 211, 135, 135, 218, 220, 221, 226,
- 228, 229, 231, 10, 121, 135 ]
-
-racc_action_check = [
- 1, 140, 135, 186, 140, 12, 37, 8, 131, 131,
- 131, 37, 13, 194, 0, 140, 194, 186, 131, 1,
- 131, 131, 131, 131, 131, 8, 189, 194, 16, 131,
- 65, 65, 65, 65, 65, 65, 65, 20, 7, 7,
- 20, 135, 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 211, 0, 187, 17, 135, 187, 1, 135, 0,
- 75, 135, 75, 18, 1, 189, 189, 189, 189, 189,
- 189, 189, 189, 189, 189, 33, 177, 26, 207, 189,
- 29, 177, 189, 207, 30, 189, 96, 137, 34, 137,
- 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
- 138, 36, 138, 10, 211, 10, 10, 211, 15, 15,
- 211, 169, 47, 47, 33, 33, 10, 38, 10, 43,
- 33, 33, 33, 33, 49, 96, 96, 216, 142, 142,
- 58, 96, 96, 96, 96, 169, 169, 169, 169, 169,
- 169, 169, 169, 169, 169, 169, 169, 169, 169, 169,
- 42, 216, 216, 216, 216, 216, 216, 216, 216, 216,
- 216, 216, 216, 216, 216, 216, 178, 178, 60, 61,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 181, 181, 181, 218, 66, 70, 218, 42, 74, 77,
- 181, 78, 181, 181, 181, 181, 181, 218, 94, 98,
- 100, 181, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 141, 141, 141, 141, 141, 141, 141, 40,
- 115, 115, 115, 115, 115, 115, 115, 115, 115, 115,
- 11, 102, 11, 11, 103, 116, 63, 115, 63, 63,
- 118, 119, 121, 11, 122, 11, 127, 130, 132, 63,
- 161, 63, 44, 44, 44, 44, 44, 44, 44, 44,
- 44, 44, 44, 44, 44, 44, 44, 192, 192, 192,
- 192, 192, 192, 192, 162, 164, 183, 188, 195, 196,
- 197, 198, 201, 205, 206, 208, 210, 212, 213, 217,
- 221, 222, 223, 229, 230, 233 ]
-
-racc_action_pointer = [
- -5, 0, nil, nil, nil, nil, nil, 32, -2, nil,
- 95, 222, -58, 12, nil, 101, -30, 46, 32, nil,
- -21, nil, nil, nil, nil, nil, 11, nil, nil, 22,
- 26, nil, nil, 67, 60, nil, 93, -54, 51, nil,
- 155, nil, 123, 59, 220, nil, nil, 53, nil, 76,
- nil, nil, nil, nil, nil, nil, nil, nil, 64, nil,
- 101, 141, nil, 228, nil, 18, 125, nil, nil, nil,
- 137, nil, nil, nil, 161, 0, nil, 129, 171, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 134, nil, 78, nil, 138, nil,
- 192, nil, 223, 173, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 173, 172, nil, 214, 183,
- nil, 195, 176, nil, nil, nil, nil, 182, nil, nil,
- 189, -1, 183, nil, nil, -6, nil, 25, 38, nil,
- -7, 200, 69, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 242, 208, nil, 212, nil, nil, nil, nil, 103,
- nil, nil, nil, nil, nil, nil, nil, 13, 107, nil,
- nil, 171, nil, 207, nil, nil, -5, 45, 248, 18,
- nil, nil, 255, nil, 5, 214, 221, 222, 217, nil,
- nil, 219, nil, nil, nil, 215, 216, 19, 217, nil,
- 226, 43, 224, 229, nil, nil, 119, 226, 175, nil,
- nil, 227, 231, 284, nil, nil, nil, nil, nil, 229,
- 230, nil, nil, 227, nil, nil ]
-
-racc_action_default = [
- -1, -25, -2, -4, -5, -6, -7, -161, -161, -26,
- -161, -161, -161, -161, -3, -161, -12, -161, -161, -28,
- -33, -133, -134, -135, -136, -137, -161, -155, 236, -12,
- -12, -11, -10, -161, -44, -48, -161, -161, -31, -34,
- -25, -36, -100, -161, -161, -8, -9, -161, -14, -16,
- -17, -18, -110, -111, -112, -113, -114, -115, -46, -45,
- -161, -44, -27, -161, -30, -161, -161, -103, -104, -105,
- -106, -107, -108, -109, -161, -161, -101, -131, -161, -60,
- -61, -62, -63, -64, -65, -66, -67, -68, -69, -70,
- -71, -72, -73, -74, -86, -13, -161, -116, -161, -47,
- -161, -49, -161, -161, -29, -32, -37, -38, -39, -40,
- -41, -42, -43, -35, -99, -25, -161, -132, -161, -161,
- -87, -91, -93, -15, -20, -51, -50, -25, -102, -130,
- -161, -161, -161, -92, -94, -25, -138, -25, -25, -157,
- -161, -161, -161, -140, -142, -143, -144, -145, -146, -147,
- -148, -149, -150, -151, -90, -95, -96, -97, -98, -117,
- -118, -161, -161, -122, -161, -21, -22, -23, -24, -161,
- -156, -158, -55, -56, -58, -128, -129, -161, -161, -153,
- -139, -161, -119, -161, -121, -19, -161, -161, -75, -25,
- -160, -152, -161, -141, -161, -86, -161, -55, -86, -57,
- -76, -161, -154, -123, -125, -161, -93, -25, -93, -159,
- -124, -25, -161, -161, -78, -80, -161, -161, -161, -127,
- -52, -161, -79, -161, -83, -84, -53, -126, -54, -25,
- -86, -85, -81, -88, -82, -89 ]
-
-racc_goto_table = [
- 8, 8, 34, 94, 122, 105, 136, 155, 48, 66,
- 49, 76, 50, 19, 143, 187, 58, 204, 215, 32,
- 139, 61, 2, 14, 12, 12, 1, 30, 47, 98,
- 137, 171, 45, 46, 165, 166, 167, 168, 37, 26,
- 232, 227, 38, 103, 64, 39, 41, 99, 101, 195,
- 198, 196, 213, 214, 222, 223, 230, 234, 235, 132,
- 75, 201, 225, 182, 193, 203, 104, 210, 177, 43,
- 77, 123, 116, 49, 117, 50, 142, 178, 138, nil,
- nil, 179, nil, 219, 128, 125, nil, nil, nil, nil,
- 212, nil, 217, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 206, nil, nil, 208, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 140, 186, nil,
- nil, nil, 202, nil, nil, nil, nil, 169, 140, nil,
- 233, nil, nil, nil, nil, nil, 183, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 224, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 216, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 216 ]
-
-racc_goto_check = [
- 13, 13, 14, 35, 37, 28, 38, 52, 10, 30,
- 11, 30, 12, 23, 69, 39, 15, 61, 44, 7,
- 72, 14, 2, 2, 55, 55, 1, 8, 9, 16,
- 17, 72, 7, 7, 18, 19, 20, 21, 24, 25,
- 44, 61, 26, 15, 27, 29, 31, 33, 34, 36,
- 40, 41, 42, 43, 45, 46, 47, 48, 50, 51,
- 54, 52, 39, 58, 69, 60, 23, 62, 63, 64,
- 65, 10, 66, 11, 67, 12, 68, 70, 71, nil,
- nil, 28, nil, 52, 30, 14, nil, nil, nil, nil,
- 38, nil, 38, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 37, nil, nil, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 13, 35, nil,
- nil, nil, 28, nil, nil, nil, nil, 13, 13, nil,
- 37, nil, nil, nil, nil, nil, 14, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 35, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 13, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 13 ]
-
-racc_goto_pointer = [
- nil, 26, 22, nil, nil, nil, nil, 3, 12, -5,
- -25, -23, -21, 0, -15, -18, -29, -94, -103, -102,
- -101, -100, nil, 3, 19, 28, 22, 6, -60, 25,
- -31, 26, nil, -11, -12, -41, -137, -90, -116, -154,
- -137, -135, -155, -154, -189, -161, -161, -167, -176, nil,
- -175, -62, -128, nil, 18, 24, nil, nil, -98, nil,
- -129, -177, -137, -72, 43, 27, -5, -3, -55, -117,
- -64, -49, -107 ]
-
-racc_goto_default = [
- nil, nil, nil, 3, 4, 5, 6, nil, nil, nil,
- nil, 70, 67, 74, 188, nil, nil, nil, nil, nil,
- nil, nil, 9, nil, nil, 20, nil, nil, nil, nil,
- 156, 157, 59, nil, 160, nil, 175, nil, nil, nil,
- 176, nil, nil, nil, nil, nil, nil, nil, nil, 120,
- 134, nil, nil, 158, nil, 73, 159, 161, nil, 162,
- nil, nil, nil, 205, nil, nil, nil, nil, nil, nil,
- nil, nil, nil ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 0, 71, :_reduce_1,
- 1, 71, :_reduce_2,
- 2, 71, :_reduce_3,
- 1, 72, :_reduce_none,
- 1, 72, :_reduce_5,
- 1, 72, :_reduce_6,
- 1, 72, :_reduce_7,
- 4, 73, :_reduce_8,
- 4, 73, :_reduce_none,
- 3, 73, :_reduce_10,
- 1, 78, :_reduce_none,
- 0, 77, :_reduce_12,
- 3, 77, :_reduce_13,
- 1, 79, :_reduce_none,
- 3, 79, :_reduce_none,
- 1, 80, :_reduce_none,
- 1, 80, :_reduce_17,
- 1, 80, :_reduce_none,
- 9, 74, :_reduce_19,
- 0, 87, :_reduce_20,
- 2, 87, :_reduce_21,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 0, 83, :_reduce_none,
- 1, 83, :_reduce_26,
- 4, 92, :_reduce_27,
- 0, 94, :_reduce_28,
- 3, 94, :_reduce_29,
- 3, 93, :_reduce_30,
- 0, 97, :_reduce_none,
- 2, 97, :_reduce_32,
- 0, 96, :_reduce_none,
- 1, 96, :_reduce_none,
- 3, 99, :_reduce_35,
- 1, 99, :_reduce_none,
- 1, 98, :_reduce_none,
- 1, 98, :_reduce_none,
- 1, 98, :_reduce_none,
- 1, 98, :_reduce_none,
- 1, 98, :_reduce_none,
- 1, 98, :_reduce_none,
- 1, 98, :_reduce_43,
- 0, 85, :_reduce_none,
- 1, 85, :_reduce_none,
- 0, 86, :_reduce_none,
- 1, 86, :_reduce_none,
- 1, 84, :_reduce_48,
- 2, 102, :_reduce_49,
- 2, 104, :_reduce_50,
- 2, 103, :_reduce_51,
- 6, 89, :_reduce_52,
- 6, 91, :_reduce_53,
- 7, 90, :_reduce_54,
- 1, 106, :_reduce_none,
- 1, 106, :_reduce_56,
- 1, 110, :_reduce_none,
- 1, 110, :_reduce_58,
- 1, 111, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_none,
- 1, 105, :_reduce_74,
- 1, 109, :_reduce_75,
- 2, 109, :_reduce_76,
- 0, 112, :_reduce_none,
- 1, 112, :_reduce_none,
- 2, 113, :_reduce_79,
- 0, 115, :_reduce_80,
- 3, 115, :_reduce_81,
- 5, 114, :_reduce_82,
- 1, 116, :_reduce_none,
- 1, 116, :_reduce_none,
- 1, 117, :_reduce_none,
- 0, 107, :_reduce_none,
- 1, 107, :_reduce_none,
- 0, 118, :_reduce_none,
- 1, 118, :_reduce_89,
- 3, 119, :_reduce_90,
- 0, 121, :_reduce_91,
- 1, 121, :_reduce_none,
- 0, 108, :_reduce_none,
- 1, 108, :_reduce_none,
- 2, 120, :_reduce_95,
- 1, 122, :_reduce_none,
- 1, 122, :_reduce_none,
- 1, 122, :_reduce_none,
- 3, 101, :_reduce_99,
- 0, 124, :_reduce_none,
- 1, 124, :_reduce_101,
- 3, 124, :_reduce_102,
- 1, 100, :_reduce_none,
- 1, 100, :_reduce_none,
- 1, 100, :_reduce_none,
- 1, 100, :_reduce_none,
- 1, 100, :_reduce_none,
- 1, 100, :_reduce_none,
- 1, 100, :_reduce_109,
- 1, 82, :_reduce_none,
- 1, 82, :_reduce_none,
- 1, 82, :_reduce_none,
- 1, 82, :_reduce_none,
- 1, 82, :_reduce_none,
- 1, 81, :_reduce_none,
- 2, 81, :_reduce_116,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 2, 126, :_reduce_none,
- 0, 127, :_reduce_none,
- 2, 127, :_reduce_none,
- 1, 129, :_reduce_none,
- 3, 128, :_reduce_none,
- 2, 130, :_reduce_none,
- 0, 132, :_reduce_none,
- 3, 132, :_reduce_none,
- 3, 131, :_reduce_none,
- 1, 133, :_reduce_none,
- 1, 133, :_reduce_none,
- 6, 75, :_reduce_130,
- 0, 136, :_reduce_none,
- 1, 136, :_reduce_none,
- 1, 95, :_reduce_none,
- 1, 95, :_reduce_none,
- 1, 95, :_reduce_none,
- 1, 95, :_reduce_none,
- 1, 95, :_reduce_none,
- 4, 134, :_reduce_138,
- 5, 135, :_reduce_139,
- 1, 138, :_reduce_140,
- 3, 138, :_reduce_141,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 1, 139, :_reduce_none,
- 5, 137, :_reduce_152,
- 1, 140, :_reduce_153,
- 3, 140, :_reduce_154,
- 2, 76, :_reduce_none,
- 8, 125, :_reduce_none,
- 1, 141, :_reduce_none,
- 2, 141, :_reduce_none,
- 5, 142, :_reduce_none,
- 3, 142, :_reduce_160 ]
-
-racc_reduce_n = 161
-
-racc_shift_n = 236
-
-racc_token_table = {
- false => 0,
- :error => 1,
- "*" => 2,
- "/" => 3,
- "+" => 4,
- "-" => 5,
- :PRAGMA => 6,
- :INCLUDE => 7,
- :IDENTIFIER => 8,
- :CLASS => 9,
- :ASSOCIATION => 10,
- :INDICATION => 11,
- :AMENDED => 12,
- :ENABLEOVERRIDE => 13,
- :DISABLEOVERRIDE => 14,
- :RESTRICTED => 15,
- :TOSUBCLASS => 16,
- :TOINSTANCE => 17,
- :TRANSLATABLE => 18,
- :QUALIFIER => 19,
- :SCOPE => 20,
- :SCHEMA => 21,
- :PROPERTY => 22,
- :REFERENCE => 23,
- :METHOD => 24,
- :PARAMETER => 25,
- :FLAVOR => 26,
- :INSTANCE => 27,
- :AS => 28,
- :REF => 29,
- :ANY => 30,
- :OF => 31,
- :DT_VOID => 32,
- :DT_UINT8 => 33,
- :DT_SINT8 => 34,
- :DT_UINT16 => 35,
- :DT_SINT16 => 36,
- :DT_UINT32 => 37,
- :DT_SINT32 => 38,
- :DT_UINT64 => 39,
- :DT_SINT64 => 40,
- :DT_REAL32 => 41,
- :DT_REAL64 => 42,
- :DT_CHAR16 => 43,
- :DT_STR => 44,
- :DT_BOOLEAN => 45,
- :DT_DATETIME => 46,
- :positiveDecimalValue => 47,
- :stringValue => 48,
- :realValue => 49,
- :charValue => 50,
- :booleanValue => 51,
- :nullValue => 52,
- :binaryValue => 53,
- :octalValue => 54,
- :decimalValue => 55,
- :hexValue => 56,
- "#" => 57,
- "(" => 58,
- ")" => 59,
- "," => 60,
- "{" => 61,
- "}" => 62,
- ";" => 63,
- "[" => 64,
- "]" => 65,
- ":" => 66,
- "$" => 67,
- "=" => 68,
- "." => 69 }
-
-racc_nt_base = 70
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "\"*\"",
- "\"/\"",
- "\"+\"",
- "\"-\"",
- "PRAGMA",
- "INCLUDE",
- "IDENTIFIER",
- "CLASS",
- "ASSOCIATION",
- "INDICATION",
- "AMENDED",
- "ENABLEOVERRIDE",
- "DISABLEOVERRIDE",
- "RESTRICTED",
- "TOSUBCLASS",
- "TOINSTANCE",
- "TRANSLATABLE",
- "QUALIFIER",
- "SCOPE",
- "SCHEMA",
- "PROPERTY",
- "REFERENCE",
- "METHOD",
- "PARAMETER",
- "FLAVOR",
- "INSTANCE",
- "AS",
- "REF",
- "ANY",
- "OF",
- "DT_VOID",
- "DT_UINT8",
- "DT_SINT8",
- "DT_UINT16",
- "DT_SINT16",
- "DT_UINT32",
- "DT_SINT32",
- "DT_UINT64",
- "DT_SINT64",
- "DT_REAL32",
- "DT_REAL64",
- "DT_CHAR16",
- "DT_STR",
- "DT_BOOLEAN",
- "DT_DATETIME",
- "positiveDecimalValue",
- "stringValue",
- "realValue",
- "charValue",
- "booleanValue",
- "nullValue",
- "binaryValue",
- "octalValue",
- "decimalValue",
- "hexValue",
- "\"#\"",
- "\"(\"",
- "\")\"",
- "\",\"",
- "\"{\"",
- "\"}\"",
- "\";\"",
- "\"[\"",
- "\"]\"",
- "\":\"",
- "\"$\"",
- "\"=\"",
- "\".\"",
- "$start",
- "mofSpecification",
- "mofProduction",
- "compilerDirective",
- "classDeclaration",
- "qualifierDeclaration",
- "instanceDeclaration",
- "pragmaParameters_opt",
- "pragmaName",
- "pragmaParameterValues",
- "pragmaParameterValue",
- "string",
- "integerValue",
- "qualifierList_opt",
- "className",
- "alias_opt",
- "superClass_opt",
- "classFeatures",
- "classFeature",
- "propertyDeclaration",
- "methodDeclaration",
- "referenceDeclaration",
- "qualifierList",
- "qualifier",
- "qualifiers",
- "qualifierName",
- "qualifierParameter_opt",
- "flavor_opt",
- "flavor",
- "qualifierParameter",
- "constantValue",
- "arrayInitializer",
- "alias",
- "superClass",
- "aliasIdentifier",
- "dataType",
- "propertyName",
- "array_opt",
- "defaultValue_opt",
- "objectRef",
- "referenceName",
- "methodName",
- "parameterList_opt",
- "parameterList",
- "parameter",
- "parameters",
- "typespec",
- "parameterName",
- "parameterValue_opt",
- "array",
- "defaultValue",
- "positiveDecimalValue_opt",
- "initializer",
- "referenceInitializer",
- "constantValues",
- "instance",
- "objectHandle",
- "namespace_opt",
- "modelPath",
- "namespaceHandle",
- "keyValuePairList",
- "keyValuePair",
- "keyValuePairs",
- "keyname",
- "qualifierType",
- "scope",
- "defaultFlavor_opt",
- "defaultFlavor",
- "metaElements",
- "metaElement",
- "flavors",
- "valueInitializers",
- "valueInitializer" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'mof.y', 41)
- def _reduce_1(val, _values, result)
- result = Hash.new
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 43)
- def _reduce_2(val, _values, result)
- result = { @name => @result }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 45)
- def _reduce_3(val, _values, result)
- result = val[0]
- result[@name] = @result
-
- result
- end
-.,.,
-
-# reduce 4 omitted
-
-module_eval(<<'.,.,', 'mof.y', 53)
- def _reduce_5(val, _values, result)
- #puts "Class '#{val[0].name}'"
- @result.classes << val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 57)
- def _reduce_6(val, _values, result)
- @result.qualifiers << val[0]
- @qualifiers[val[0].name.downcase] = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 61)
- def _reduce_7(val, _values, result)
- @result.instances << val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 71)
- def _reduce_8(val, _values, result)
- raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#pragma include'") unless val[3]
- open val[3], :pragma
-
- result
- end
-.,.,
-
-# reduce 9 omitted
-
-module_eval(<<'.,.,', 'mof.y', 76)
- def _reduce_10(val, _values, result)
- raise StyleError.new(@name,@lineno,@line,"Use '#pragma include' instead of '#include'") unless @style == :wmi
- raise MOF::Helper::Error.new(@name,@lineno,@line,"Missing filename after '#include'") unless val[2]
- open val[2], :pragma
-
- result
- end
-.,.,
-
-# reduce 11 omitted
-
-module_eval(<<'.,.,', 'mof.y', 88)
- def _reduce_12(val, _values, result)
- raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 90)
- def _reduce_13(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-# reduce 14 omitted
-
-# reduce 15 omitted
-
-# reduce 16 omitted
-
-module_eval(<<'.,.,', 'mof.y', 101)
- def _reduce_17(val, _values, result)
- raise StyleError.new(@name,@lineno,@line,"#pragma parameter missing") unless @style == :wmi
- result
- end
-.,.,
-
-# reduce 18 omitted
-
-module_eval(<<'.,.,', 'mof.y', 112)
- def _reduce_19(val, _values, result)
- qualifiers = val[0]
- features = val[6]
- # FIXME: features must not include references
- result = CIM::Class.new(val[2],qualifiers,val[3],val[4],features)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 121)
- def _reduce_20(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 123)
- def _reduce_21(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-# reduce 22 omitted
-
-# reduce 23 omitted
-
-# reduce 24 omitted
-
-# reduce 25 omitted
-
-module_eval(<<'.,.,', 'mof.y', 136)
- def _reduce_26(val, _values, result)
- result = CIM::QualifierSet.new val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 141)
- def _reduce_27(val, _values, result)
- result = val[2]
- result.unshift val[1] if val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 147)
- def _reduce_28(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 149)
- def _reduce_29(val, _values, result)
- result = val[0]
- result << val[2] if val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 156)
- def _reduce_30(val, _values, result)
- # Get qualifier decl
- qualifier = case val[0]
- when CIM::Qualifier then val[0].definition
- when CIM::QualifierDeclaration then val[0]
- when String then @qualifiers[val[0].downcase]
- else
- nil
- end
- raise MOF::Helper::Error.new(@name,@lineno,@line,"'#{val[0]}' is not a valid qualifier") unless qualifier
- value = val[1]
- raise MOF::Helper::Error.new(@name,@lineno,@line,"#{value.inspect} does not match qualifier type '#{qualifier.type}'") unless qualifier.type.matches?(value)||@style == :wmi
- # Don't propagate a boolean 'false'
- if qualifier.type == :boolean && value == false
- result = nil
- else
- result = CIM::Qualifier.new(qualifier,value,val[2])
- end
-
- result
- end
-.,.,
-
-# reduce 31 omitted
-
-module_eval(<<'.,.,', 'mof.y', 179)
- def _reduce_32(val, _values, result)
- result = CIM::QualifierFlavors.new val[1]
- result
- end
-.,.,
-
-# reduce 33 omitted
-
-# reduce 34 omitted
-
-module_eval(<<'.,.,', 'mof.y', 189)
- def _reduce_35(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-# reduce 36 omitted
-
-# reduce 37 omitted
-
-# reduce 38 omitted
-
-# reduce 39 omitted
-
-# reduce 40 omitted
-
-# reduce 41 omitted
-
-# reduce 42 omitted
-
-module_eval(<<'.,.,', 'mof.y', 196)
- def _reduce_43(val, _values, result)
- case val[0].to_sym
- when :amended, :toinstance
- raise StyleError.new(@name,@lineno,@line,"'#{val[0]}' is not a valid flavor") unless @style == :wmi
- end
-
- result
- end
-.,.,
-
-# reduce 44 omitted
-
-# reduce 45 omitted
-
-# reduce 46 omitted
-
-# reduce 47 omitted
-
-module_eval(<<'.,.,', 'mof.y', 215)
- def _reduce_48(val, _values, result)
- raise ParseError.new("Class name must be prefixed by '<schema>_'") unless val[0].include?("_") || @style == :wmi
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 220)
- def _reduce_49(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 225)
- def _reduce_50(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 230)
- def _reduce_51(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 236)
- def _reduce_52(val, _values, result)
- if val[3]
- type = CIM::Array.new val[3],val[1]
- else
- type = val[1]
- end
- result = CIM::Property.new(type,val[2],val[0],val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 247)
- def _reduce_53(val, _values, result)
- if val[4]
- raise StyleError.new(@name,@lineno,@line,"Array not allowed in reference declaration") unless @style == :wmi
- end
- result = CIM::Reference.new(val[1],val[2],val[0],val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 255)
- def _reduce_54(val, _values, result)
- result = CIM::Method.new(val[1],val[2],val[0],val[4])
- result
- end
-.,.,
-
-# reduce 55 omitted
-
-module_eval(<<'.,.,', 'mof.y', 261)
- def _reduce_56(val, _values, result)
- # tmplprov.mof has 'string Property;'
- raise StyleError.new(@name,@lineno,@line,"Invalid keyword '#{val[0]}' used for property name") unless @style == :wmi
-
- result
- end
-.,.,
-
-# reduce 57 omitted
-
-module_eval(<<'.,.,', 'mof.y', 269)
- def _reduce_58(val, _values, result)
- result = "Indication"
- result
- end
-.,.,
-
-# reduce 59 omitted
-
-# reduce 60 omitted
-
-# reduce 61 omitted
-
-# reduce 62 omitted
-
-# reduce 63 omitted
-
-# reduce 64 omitted
-
-# reduce 65 omitted
-
-# reduce 66 omitted
-
-# reduce 67 omitted
-
-# reduce 68 omitted
-
-# reduce 69 omitted
-
-# reduce 70 omitted
-
-# reduce 71 omitted
-
-# reduce 72 omitted
-
-# reduce 73 omitted
-
-module_eval(<<'.,.,', 'mof.y', 292)
- def _reduce_74(val, _values, result)
- raise StyleError.new(@name,@lineno,@line,"'void' is not a valid datatype") unless @style == :wmi
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 297)
- def _reduce_75(val, _values, result)
- # WMI uses class names as data types (without REF ?!)
- raise StyleError.new(@name,@lineno,@line,"Expected 'ref' keyword after classname '#{val[0]}'") unless @style == :wmi
- result = CIM::ReferenceType.new val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 303)
- def _reduce_76(val, _values, result)
- result = CIM::ReferenceType.new val[0]
- result
- end
-.,.,
-
-# reduce 77 omitted
-
-# reduce 78 omitted
-
-module_eval(<<'.,.,', 'mof.y', 313)
- def _reduce_79(val, _values, result)
- result = val[1].unshift val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 318)
- def _reduce_80(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 320)
- def _reduce_81(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 325)
- def _reduce_82(val, _values, result)
- if val[3]
- type = CIM::Array.new val[3], val[1]
- else
- type = val[1]
- end
- result = CIM::Property.new(type,val[2],val[0])
-
- result
- end
-.,.,
-
-# reduce 83 omitted
-
-# reduce 84 omitted
-
-# reduce 85 omitted
-
-# reduce 86 omitted
-
-# reduce 87 omitted
-
-# reduce 88 omitted
-
-module_eval(<<'.,.,', 'mof.y', 351)
- def _reduce_89(val, _values, result)
- raise "Default parameter value not allowed in syntax style '{@style}'" unless @style == :wmi
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 356)
- def _reduce_90(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 361)
- def _reduce_91(val, _values, result)
- result = -1
- result
- end
-.,.,
-
-# reduce 92 omitted
-
-# reduce 93 omitted
-
-# reduce 94 omitted
-
-module_eval(<<'.,.,', 'mof.y', 372)
- def _reduce_95(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-# reduce 96 omitted
-
-# reduce 97 omitted
-
-# reduce 98 omitted
-
-module_eval(<<'.,.,', 'mof.y', 383)
- def _reduce_99(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-# reduce 100 omitted
-
-module_eval(<<'.,.,', 'mof.y', 389)
- def _reduce_101(val, _values, result)
- result = [ val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 391)
- def _reduce_102(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-# reduce 103 omitted
-
-# reduce 104 omitted
-
-# reduce 105 omitted
-
-# reduce 106 omitted
-
-# reduce 107 omitted
-
-# reduce 108 omitted
-
-module_eval(<<'.,.,', 'mof.y', 402)
- def _reduce_109(val, _values, result)
- raise "Instance as property value not allowed in syntax style '{@style}'" unless @style == :wmi
- result
- end
-.,.,
-
-# reduce 110 omitted
-
-# reduce 111 omitted
-
-# reduce 112 omitted
-
-# reduce 113 omitted
-
-# reduce 114 omitted
-
-# reduce 115 omitted
-
-module_eval(<<'.,.,', 'mof.y', 416)
- def _reduce_116(val, _values, result)
- result = val[0] + val[1]
- result
- end
-.,.,
-
-# reduce 117 omitted
-
-# reduce 118 omitted
-
-# reduce 119 omitted
-
-# reduce 120 omitted
-
-# reduce 121 omitted
-
-# reduce 122 omitted
-
-# reduce 123 omitted
-
-# reduce 124 omitted
-
-# reduce 125 omitted
-
-# reduce 126 omitted
-
-# reduce 127 omitted
-
-# reduce 128 omitted
-
-# reduce 129 omitted
-
-module_eval(<<'.,.,', 'mof.y', 471)
- def _reduce_130(val, _values, result)
- result = CIM::QualifierDeclaration.new( val[1], val[2][0], val[2][1], val[3], val[4])
- result
- end
-.,.,
-
-# reduce 131 omitted
-
-# reduce 132 omitted
-
-# reduce 133 omitted
-
-# reduce 134 omitted
-
-# reduce 135 omitted
-
-# reduce 136 omitted
-
-# reduce 137 omitted
-
-module_eval(<<'.,.,', 'mof.y', 490)
- def _reduce_138(val, _values, result)
- type = val[2].nil? ? val[1] : CIM::Array.new(val[2],val[1])
- result = [ type, val[3] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 497)
- def _reduce_139(val, _values, result)
- result = CIM::QualifierScopes.new(val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 502)
- def _reduce_140(val, _values, result)
- result = [ val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 504)
- def _reduce_141(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-# reduce 142 omitted
-
-# reduce 143 omitted
-
-# reduce 144 omitted
-
-# reduce 145 omitted
-
-# reduce 146 omitted
-
-# reduce 147 omitted
-
-# reduce 148 omitted
-
-# reduce 149 omitted
-
-# reduce 150 omitted
-
-# reduce 151 omitted
-
-module_eval(<<'.,.,', 'mof.y', 522)
- def _reduce_152(val, _values, result)
- result = CIM::QualifierFlavors.new val[3]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 527)
- def _reduce_153(val, _values, result)
- result = [ val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'mof.y', 529)
- def _reduce_154(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-# reduce 155 omitted
-
-# reduce 156 omitted
-
-# reduce 157 omitted
-
-# reduce 158 omitted
-
-# reduce 159 omitted
-
-module_eval(<<'.,.,', 'mof.y', 553)
- def _reduce_160(val, _values, result)
- raise "Instance property '#{val[1]} must have a value" unless @style == :wmi
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module MOF
-
-
diff --git a/test/racc/regress/namae b/test/racc/regress/namae
deleted file mode 100644
index 5a795e4579..0000000000
--- a/test/racc/regress/namae
+++ /dev/null
@@ -1,634 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-require 'singleton'
-require 'strscan'
-
-module Namae
- class Parser < Racc::Parser
-
-module_eval(<<'...end namae.y/module_eval...', 'namae.y', 135)
-
- include Singleton
-
- attr_reader :options, :input
-
- def initialize
- @input, @options = StringScanner.new(''), {
- :debug => false,
- :prefer_comma_as_separator => false,
- :comma => ',',
- :stops => ',;',
- :separator => /\s*(\band\b|\&|;)\s*/i,
- :title => /\s*\b(sir|lord|count(ess)?|(gen|adm|col|maj|capt|cmdr|lt|sgt|cpl|pvt|prof|dr|md|ph\.?d)\.?)(\s+|$)/i,
- :suffix => /\s*\b(JR|Jr|jr|SR|Sr|sr|[IVX]{2,})(\.|\b)/,
- :appellation => /\s*\b((mrs?|ms|fr|hr)\.?|miss|herr|frau)(\s+|$)/i
- }
- end
-
- def debug?
- options[:debug] || ENV['DEBUG']
- end
-
- def separator
- options[:separator]
- end
-
- def comma
- options[:comma]
- end
-
- def stops
- options[:stops]
- end
-
- def title
- options[:title]
- end
-
- def suffix
- options[:suffix]
- end
-
- def appellation
- options[:appellation]
- end
-
- def prefer_comma_as_separator?
- options[:prefer_comma_as_separator]
- end
-
- def parse(input)
- parse!(input)
- rescue => e
- warn e.message if debug?
- []
- end
-
- def parse!(string)
- input.string = normalize(string)
- reset
- do_parse
- end
-
- def normalize(string)
- string = string.strip
- string
- end
-
- def reset
- @commas, @words, @initials, @suffices, @yydebug = 0, 0, 0, 0, debug?
- self
- end
-
- private
-
- def stack
- @vstack || @racc_vstack || []
- end
-
- def last_token
- stack[-1]
- end
-
- def consume_separator
- return next_token if seen_separator?
- @commas, @words, @initials, @suffices = 0, 0, 0, 0
- [:AND, :AND]
- end
-
- def consume_comma
- @commas += 1
- [:COMMA, :COMMA]
- end
-
- def consume_word(type, word)
- @words += 1
-
- case type
- when :UWORD
- @initials += 1 if word =~ /^[[:upper:]]+\b/
- when :SUFFIX
- @suffices += 1
- end
-
- [type, word]
- end
-
- def seen_separator?
- !stack.empty? && last_token == :AND
- end
-
- def suffix?
- !@suffices.zero? || will_see_suffix?
- end
-
- def will_see_suffix?
- input.peek(8).to_s.strip.split(/\s+/)[0] =~ suffix
- end
-
- def will_see_initial?
- input.peek(6).to_s.strip.split(/\s+/)[0] =~ /^[[:upper:]]+\b/
- end
-
- def seen_full_name?
- prefer_comma_as_separator? && @words > 1 &&
- (@initials > 0 || !will_see_initial?) && !will_see_suffix?
- end
-
- def next_token
- case
- when input.nil?, input.eos?
- nil
- when input.scan(separator)
- consume_separator
- when input.scan(/\s*#{comma}\s*/)
- if @commas.zero? && !seen_full_name? || @commas == 1 && suffix?
- consume_comma
- else
- consume_separator
- end
- when input.scan(/\s+/)
- next_token
- when input.scan(title)
- consume_word(:TITLE, input.matched.strip)
- when input.scan(suffix)
- consume_word(:SUFFIX, input.matched.strip)
- when input.scan(appellation)
- [:APPELLATION, input.matched.strip]
- when input.scan(/((\\\w+)?\{[^\}]*\})*[[:upper:]][^\s#{stops}]*/)
- consume_word(:UWORD, input.matched)
- when input.scan(/((\\\w+)?\{[^\}]*\})*[[:lower:]][^\s#{stops}]*/)
- consume_word(:LWORD, input.matched)
- when input.scan(/(\\\w+)?\{[^\}]*\}[^\s#{stops}]*/)
- consume_word(:PWORD, input.matched)
- when input.scan(/('[^'\n]+')|("[^"\n]+")/)
- consume_word(:NICK, input.matched[1...-1])
- else
- raise ArgumentError,
- "Failed to parse name #{input.string.inspect}: unmatched data at offset #{input.pos}"
- end
- end
-
- def on_error(tid, value, stack)
- raise ArgumentError,
- "Failed to parse name: unexpected '#{value}' at #{stack.inspect}"
- end
-
-# -*- racc -*-
-...end namae.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- -39, 16, 32, 30, -40, 31, 33, -39, 17, -39,
- -39, -40, 67, -40, -40, 66, 53, 52, 54, -38,
- 59, -22, 39, -34, 45, 58, -38, 53, 52, 54,
- 53, 52, 54, 59, 39, 39, 62, 39, 53, 52,
- 54, 14, 12, 15, 68, 39, 7, 8, 14, 12,
- 15, 58, 39, 7, 8, 14, 22, 15, 24, 14,
- 22, 15, 24, 14, 22, 15, 30, 28, 31, 30,
- 28, 31, -19, -19, -19, 30, 42, 31, 30, 28,
- 31, -20, -20, -20, 30, 46, 31, 30, 28, 31,
- 30, 28, 31, -19, -19, -19, 53, 52, 54, 53,
- 52, 54, 39, 58, 59 ]
-
-racc_action_check = [
- 14, 1, 11, 43, 15, 43, 16, 14, 1, 14,
- 14, 15, 50, 15, 15, 49, 49, 49, 49, 12,
- 50, 12, 23, 49, 27, 37, 12, 32, 32, 32,
- 45, 45, 45, 38, 32, 40, 44, 45, 62, 62,
- 62, 0, 0, 0, 57, 62, 0, 0, 17, 17,
- 17, 60, 61, 17, 17, 9, 9, 9, 9, 20,
- 20, 20, 20, 5, 5, 5, 10, 10, 10, 21,
- 21, 21, 22, 22, 22, 24, 24, 24, 25, 25,
- 25, 28, 28, 28, 29, 29, 29, 35, 35, 35,
- 41, 41, 41, 42, 42, 42, 67, 67, 67, 73,
- 73, 73, 64, 70, 72 ]
-
-racc_action_pointer = [
- 38, 1, nil, nil, nil, 60, nil, nil, nil, 52,
- 63, 0, 19, nil, 0, 4, 6, 45, nil, nil,
- 56, 66, 69, 12, 72, 75, nil, 22, 78, 81,
- nil, nil, 24, nil, nil, 84, nil, 16, 23, nil,
- 25, 87, 90, 0, 34, 27, nil, nil, nil, 13,
- 10, nil, nil, nil, nil, nil, nil, 35, nil, nil,
- 42, 42, 35, nil, 92, nil, nil, 93, nil, nil,
- 94, nil, 94, 96, nil ]
-
-racc_action_default = [
- -1, -49, -2, -4, -5, -49, -8, -9, -10, -23,
- -49, -49, -19, -28, -30, -31, -49, -49, -6, -7,
- -49, -49, -38, -41, -49, -49, -29, -15, -22, -23,
- -30, -31, -36, 75, -3, -49, -15, -45, -42, -43,
- -41, -49, -22, -23, -14, -36, -21, -16, -24, -37,
- -26, -32, -38, -39, -40, -14, -11, -46, -47, -44,
- -45, -41, -36, -17, -49, -33, -35, -49, -48, -12,
- -45, -18, -25, -27, -13 ]
-
-racc_goto_table = [
- 3, 37, 26, 50, 56, 18, 2, 9, 47, 23,
- 1, 19, 20, 26, 73, 27, 50, 3, 60, 64,
- 23, 63, 26, 34, 9, nil, 36, 69, 21, 40,
- 44, 43, 25, 50, nil, 72, 26, 74, 71, 70,
- 55, nil, nil, 35, nil, nil, 61, 41, nil, 65,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 65 ]
-
-racc_goto_check = [
- 3, 8, 17, 16, 9, 3, 2, 7, 12, 3,
- 1, 4, 7, 17, 14, 10, 16, 3, 8, 15,
- 3, 12, 17, 2, 7, nil, 10, 9, 11, 10,
- 10, 7, 11, 16, nil, 16, 17, 9, 12, 8,
- 10, nil, nil, 11, nil, nil, 10, 11, nil, 3,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 3 ]
-
-racc_goto_pointer = [
- nil, 10, 6, 0, 6, nil, nil, 7, -22, -33,
- 5, 23, -24, nil, -53, -30, -29, -7, nil ]
-
-racc_goto_default = [
- nil, nil, nil, 51, 4, 5, 6, 29, nil, nil,
- 11, 10, nil, 48, 49, nil, 38, 13, 57 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 0, 12, :_reduce_1,
- 1, 12, :_reduce_2,
- 3, 12, :_reduce_3,
- 1, 13, :_reduce_4,
- 1, 13, :_reduce_none,
- 2, 13, :_reduce_6,
- 2, 13, :_reduce_7,
- 1, 13, :_reduce_none,
- 1, 16, :_reduce_9,
- 1, 16, :_reduce_10,
- 4, 15, :_reduce_11,
- 5, 15, :_reduce_12,
- 6, 15, :_reduce_13,
- 3, 15, :_reduce_14,
- 2, 15, :_reduce_15,
- 3, 17, :_reduce_16,
- 4, 17, :_reduce_17,
- 5, 17, :_reduce_18,
- 1, 22, :_reduce_none,
- 2, 22, :_reduce_20,
- 3, 22, :_reduce_21,
- 1, 21, :_reduce_none,
- 1, 21, :_reduce_none,
- 1, 23, :_reduce_24,
- 3, 23, :_reduce_25,
- 1, 23, :_reduce_26,
- 3, 23, :_reduce_27,
- 1, 18, :_reduce_none,
- 2, 18, :_reduce_29,
- 1, 28, :_reduce_none,
- 1, 28, :_reduce_none,
- 1, 25, :_reduce_none,
- 2, 25, :_reduce_33,
- 0, 26, :_reduce_none,
- 1, 26, :_reduce_none,
- 0, 24, :_reduce_none,
- 1, 24, :_reduce_none,
- 1, 14, :_reduce_none,
- 1, 14, :_reduce_none,
- 1, 14, :_reduce_none,
- 0, 19, :_reduce_none,
- 1, 19, :_reduce_none,
- 1, 27, :_reduce_none,
- 2, 27, :_reduce_44,
- 0, 20, :_reduce_none,
- 1, 20, :_reduce_none,
- 1, 29, :_reduce_none,
- 2, 29, :_reduce_48 ]
-
-racc_reduce_n = 49
-
-racc_shift_n = 75
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :COMMA => 2,
- :UWORD => 3,
- :LWORD => 4,
- :PWORD => 5,
- :NICK => 6,
- :AND => 7,
- :APPELLATION => 8,
- :TITLE => 9,
- :SUFFIX => 10 }
-
-racc_nt_base = 11
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "COMMA",
- "UWORD",
- "LWORD",
- "PWORD",
- "NICK",
- "AND",
- "APPELLATION",
- "TITLE",
- "SUFFIX",
- "$start",
- "names",
- "name",
- "word",
- "display_order",
- "honorific",
- "sort_order",
- "u_words",
- "opt_suffices",
- "opt_titles",
- "last",
- "von",
- "first",
- "opt_words",
- "words",
- "opt_comma",
- "suffices",
- "u_word",
- "titles" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'namae.y', 39)
- def _reduce_1(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 40)
- def _reduce_2(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 41)
- def _reduce_3(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 43)
- def _reduce_4(val, _values, result)
- result = Name.new(:given => val[0])
- result
- end
-.,.,
-
-# reduce 5 omitted
-
-module_eval(<<'.,.,', 'namae.y', 45)
- def _reduce_6(val, _values, result)
- result = val[0].merge(:family => val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 46)
- def _reduce_7(val, _values, result)
- result = val[1].merge(val[0])
- result
- end
-.,.,
-
-# reduce 8 omitted
-
-module_eval(<<'.,.,', 'namae.y', 49)
- def _reduce_9(val, _values, result)
- result = Name.new(:appellation => val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 50)
- def _reduce_10(val, _values, result)
- result = Name.new(:title => val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 54)
- def _reduce_11(val, _values, result)
- result = Name.new(:given => val[0], :family => val[1],
- :suffix => val[2], :title => val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 59)
- def _reduce_12(val, _values, result)
- result = Name.new(:given => val[0], :nick => val[1],
- :family => val[2], :suffix => val[3], :title => val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 64)
- def _reduce_13(val, _values, result)
- result = Name.new(:given => val[0], :nick => val[1],
- :particle => val[2], :family => val[3],
- :suffix => val[4], :title => val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 70)
- def _reduce_14(val, _values, result)
- result = Name.new(:given => val[0], :particle => val[1],
- :family => val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 75)
- def _reduce_15(val, _values, result)
- result = Name.new(:particle => val[0], :family => val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 80)
- def _reduce_16(val, _values, result)
- result = Name.new({ :family => val[0], :suffix => val[2][0],
- :given => val[2][1] }, !!val[2][0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 85)
- def _reduce_17(val, _values, result)
- result = Name.new({ :particle => val[0], :family => val[1],
- :suffix => val[3][0], :given => val[3][1] }, !!val[3][0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 90)
- def _reduce_18(val, _values, result)
- result = Name.new({ :particle => val[0,2].join(' '), :family => val[2],
- :suffix => val[4][0], :given => val[4][1] }, !!val[4][0])
-
- result
- end
-.,.,
-
-# reduce 19 omitted
-
-module_eval(<<'.,.,', 'namae.y', 96)
- def _reduce_20(val, _values, result)
- result = val.join(' ')
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 97)
- def _reduce_21(val, _values, result)
- result = val.join(' ')
- result
- end
-.,.,
-
-# reduce 22 omitted
-
-# reduce 23 omitted
-
-module_eval(<<'.,.,', 'namae.y', 101)
- def _reduce_24(val, _values, result)
- result = [nil,val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 102)
- def _reduce_25(val, _values, result)
- result = [val[2],val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 103)
- def _reduce_26(val, _values, result)
- result = [val[0],nil]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'namae.y', 104)
- def _reduce_27(val, _values, result)
- result = [val[0],val[2]]
- result
- end
-.,.,
-
-# reduce 28 omitted
-
-module_eval(<<'.,.,', 'namae.y', 107)
- def _reduce_29(val, _values, result)
- result = val.join(' ')
- result
- end
-.,.,
-
-# reduce 30 omitted
-
-# reduce 31 omitted
-
-# reduce 32 omitted
-
-module_eval(<<'.,.,', 'namae.y', 112)
- def _reduce_33(val, _values, result)
- result = val.join(' ')
- result
- end
-.,.,
-
-# reduce 34 omitted
-
-# reduce 35 omitted
-
-# reduce 36 omitted
-
-# reduce 37 omitted
-
-# reduce 38 omitted
-
-# reduce 39 omitted
-
-# reduce 40 omitted
-
-# reduce 41 omitted
-
-# reduce 42 omitted
-
-# reduce 43 omitted
-
-module_eval(<<'.,.,', 'namae.y', 122)
- def _reduce_44(val, _values, result)
- result = val.join(' ')
- result
- end
-.,.,
-
-# reduce 45 omitted
-
-# reduce 46 omitted
-
-# reduce 47 omitted
-
-module_eval(<<'.,.,', 'namae.y', 127)
- def _reduce_48(val, _values, result)
- result = val.join(' ')
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module Namae
diff --git a/test/racc/regress/nasl b/test/racc/regress/nasl
deleted file mode 100644
index 52a329d20a..0000000000
--- a/test/racc/regress/nasl
+++ /dev/null
@@ -1,2548 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.2
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-
-require 'nasl/parser/tree'
-
-require 'nasl/parser/argument'
-require 'nasl/parser/array'
-require 'nasl/parser/assigment'
-require 'nasl/parser/block'
-require 'nasl/parser/break'
-require 'nasl/parser/call'
-require 'nasl/parser/comment'
-require 'nasl/parser/continue'
-require 'nasl/parser/decrement'
-require 'nasl/parser/empty'
-require 'nasl/parser/export'
-require 'nasl/parser/expression'
-require 'nasl/parser/for'
-require 'nasl/parser/foreach'
-require 'nasl/parser/function'
-require 'nasl/parser/global'
-require 'nasl/parser/identifier'
-require 'nasl/parser/if'
-require 'nasl/parser/import'
-require 'nasl/parser/include'
-require 'nasl/parser/increment'
-require 'nasl/parser/integer'
-require 'nasl/parser/ip'
-require 'nasl/parser/key_value_pair'
-require 'nasl/parser/list'
-require 'nasl/parser/local'
-require 'nasl/parser/lvalue'
-require 'nasl/parser/parameter'
-require 'nasl/parser/reference'
-require 'nasl/parser/repeat'
-require 'nasl/parser/repetition'
-require 'nasl/parser/return'
-require 'nasl/parser/string'
-require 'nasl/parser/undefined'
-require 'nasl/parser/while'
-
-module Nasl
- class Grammar < Racc::Parser
-
-module_eval(<<'...end nasl.y/module_eval...', 'nasl.y', 582)
-
-def n(cls, *args)
- begin
- Nasl.const_get(cls).new(@tree, *args)
- rescue
- puts "An exception occurred during the creation of a #{cls} instance."
- puts
- puts "The arguments passed to the constructor were:"
- puts args
- puts
- puts @tok.last.context
- puts
- raise
- end
-end
-
-def c(*args)
- n(:Comment, *args)
- args[1]
-end
-
-def on_error(type, value, stack)
- raise ParseException, "The language's grammar does not permit #{value.name} to appear here", value.context
-end
-
-def next_token
- @tok = @tkz.get_token
-
- if @first && @tok.first == :COMMENT
- n(:Comment, @tok.last)
- @tok = @tkz.get_token
- end
- @first = false
-
- return @tok
-end
-
-def parse(env, code, path)
- @first = true
- @tree = Tree.new(env)
- @tkz = Tokenizer.new(code, path)
- @tree.concat(do_parse)
-end
-
-...end nasl.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 144, 143, 161, 162, 163, 164, 165, 166, 157, 158,
- 159, 160, 153, 152, 151, 154, 155, 156, 145, 146,
- 147, 149, 150, 82, 54, 111, 148, 81, 218, 83,
- 55, 51, 50, 56, 54, 54, 80, 11, 78, 65,
- 55, 55, 53, 63, 54, 54, 66, 95, 102, 103,
- 55, 55, 53, 53, 64, 54, 218, 269, 67, 94,
- 96, 55, 53, 53, 97, 98, 99, 100, 101, 102,
- 103, 104, 82, 53, 267, 217, 81, 130, 83, 131,
- 51, 50, 130, 54, 131, 80, 130, 54, 131, 55,
- 51, 50, 68, 55, 54, 72, 95, 147, 149, 150,
- 55, 53, 73, 148, 54, 53, 102, 103, 74, 96,
- 55, 109, 53, 97, 98, 99, 100, 101, 102, 103,
- 104, 82, 53, 112, 114, 81, 54, 83, 133, 51,
- 50, 134, 55, 136, 80, 137, 54, 138, 141, 51,
- 50, 167, 55, 54, 53, 95, 147, 149, 150, 55,
- 10, 11, 148, 54, 53, 172, 37, 37, 96, 55,
- 185, 53, 97, 98, 99, 100, 101, 102, 103, 104,
- 82, 53, 192, 195, 81, 225, 83, 226, 51, 50,
- 148, 54, 148, 80, 179, 148, 253, 55, 254, 255,
- 54, 54, 54, 256, 95, 257, 55, 55, 55, 53,
- 97, 98, 99, 100, 101, 102, 103, 96, 53, 53,
- 53, 97, 98, 99, 100, 101, 102, 103, 104, 82,
- 54, 258, 259, 81, 260, 83, 55, 51, 50, 262,
- 54, 266, 80, 268, 270, 43, 55, 273, 53, 54,
- 274, 54, 275, 95, 148, 55, 148, 55, 53, 97,
- 98, 99, 100, 101, 102, 103, 96, 53, 148, 53,
- 97, 98, 99, 100, 101, 102, 103, 104, 82, 148,
- 276, 43, 81, 300, 83, 301, 51, 50, 306, nil,
- nil, 80, 154, 155, 156, 145, 146, 147, 149, 150,
- 54, nil, 95, 148, nil, nil, 55, nil, 145, 146,
- 147, 149, 150, nil, nil, 96, 148, nil, 53, 97,
- 98, 99, 100, 101, 102, 103, 104, 82, nil, nil,
- nil, 81, nil, 83, nil, 51, 50, nil, nil, nil,
- 80, nil, 145, 146, 147, 149, 150, nil, nil, 54,
- 148, 95, nil, nil, nil, 55, nil, nil, 145, 146,
- 147, 149, 150, 94, 96, 184, 148, 53, 97, 98,
- 99, 100, 101, 102, 103, 104, 82, nil, nil, nil,
- 81, nil, 83, nil, 51, 50, nil, nil, nil, 80,
- 97, 98, 99, 100, 101, nil, nil, nil, 54, nil,
- 95, nil, nil, nil, 55, 97, 98, 99, 100, 101,
- nil, nil, nil, 96, nil, nil, 53, 97, 98, 99,
- 100, 101, 102, 103, 104, 82, nil, nil, nil, 81,
- nil, 83, nil, 51, 50, nil, nil, nil, 80, 97,
- 98, 99, 100, 101, nil, nil, nil, 54, nil, 95,
- nil, nil, nil, 55, nil, nil, nil, nil, nil, nil,
- nil, nil, 96, nil, nil, 53, 97, 98, 99, 100,
- 101, 102, 103, 104, 82, nil, nil, nil, 81, nil,
- 83, nil, 51, 50, nil, nil, nil, 80, nil, nil,
- nil, nil, nil, nil, nil, nil, 54, nil, 95, nil,
- nil, nil, 55, nil, nil, nil, nil, nil, nil, nil,
- 94, 96, nil, nil, 53, 97, 98, 99, 100, 101,
- 102, 103, 104, 82, nil, nil, nil, 81, nil, 83,
- nil, 51, 50, nil, nil, nil, 80, nil, nil, nil,
- nil, nil, nil, nil, nil, 54, nil, 95, nil, nil,
- nil, 55, nil, nil, nil, nil, nil, nil, nil, nil,
- 96, nil, nil, 53, 97, 98, 99, 100, 101, 102,
- 103, 104, 82, nil, nil, nil, 81, nil, 83, nil,
- 51, 50, nil, nil, nil, 80, nil, nil, nil, nil,
- nil, nil, nil, nil, 54, nil, 95, nil, nil, nil,
- 55, nil, nil, nil, nil, nil, nil, nil, nil, 96,
- nil, nil, 53, 97, 98, 99, 100, 101, 102, 103,
- 104, 82, nil, nil, nil, 81, nil, 83, nil, 51,
- 50, nil, nil, nil, 80, nil, nil, nil, nil, nil,
- nil, nil, nil, 54, nil, 95, nil, nil, nil, 55,
- nil, nil, nil, nil, nil, nil, nil, nil, 96, nil,
- nil, 53, 97, 98, 99, 100, 101, 102, 103, 104,
- 82, nil, nil, nil, 81, nil, 83, nil, 51, 50,
- nil, nil, nil, 80, nil, nil, nil, nil, nil, nil,
- nil, nil, 54, nil, 95, nil, nil, nil, 55, nil,
- nil, nil, nil, nil, nil, nil, nil, 96, nil, nil,
- 53, 97, 98, 99, 100, 101, 102, 103, 104, 82,
- nil, nil, nil, 81, nil, 83, nil, 51, 50, nil,
- nil, nil, 80, nil, nil, nil, nil, nil, nil, nil,
- nil, 54, nil, 95, nil, nil, nil, 55, nil, nil,
- nil, nil, nil, nil, nil, nil, 96, nil, nil, 53,
- 97, 98, 99, 100, 101, 102, 103, 104, 82, nil,
- nil, nil, 81, nil, 83, nil, 51, 50, nil, nil,
- nil, 80, nil, nil, nil, nil, nil, nil, nil, nil,
- 54, nil, 95, nil, nil, nil, 55, nil, nil, nil,
- nil, nil, nil, nil, nil, 96, nil, nil, 53, 97,
- 98, 99, 100, 101, 102, 103, 104, 82, nil, nil,
- nil, 81, nil, 83, nil, 51, 50, nil, nil, nil,
- 80, nil, nil, nil, nil, nil, nil, nil, nil, 54,
- nil, 95, nil, nil, nil, 55, nil, nil, nil, nil,
- nil, nil, nil, nil, 96, nil, nil, 53, 97, 98,
- 99, 100, 101, 102, 103, 104, 82, nil, nil, nil,
- 81, nil, 83, nil, 51, 50, nil, nil, nil, 80,
- nil, nil, nil, nil, nil, nil, nil, nil, 54, nil,
- 95, nil, nil, nil, 55, nil, nil, nil, nil, nil,
- nil, nil, nil, 96, nil, nil, 53, 97, 98, 99,
- 100, 101, 102, 103, 104, 82, nil, nil, nil, 81,
- nil, 83, nil, 51, 50, nil, nil, nil, 80, 208,
- nil, nil, nil, nil, nil, nil, nil, 54, nil, 95,
- nil, nil, nil, 55, nil, nil, nil, nil, nil, nil,
- nil, 94, 96, nil, nil, 53, 97, 98, 99, 100,
- 101, 102, 103, 104, 82, nil, nil, nil, 81, nil,
- 83, nil, 51, 50, nil, nil, nil, 80, nil, nil,
- nil, nil, nil, nil, nil, nil, 54, nil, 95, nil,
- nil, nil, 55, nil, nil, nil, nil, nil, nil, nil,
- nil, 96, nil, nil, 53, 97, 98, 99, 100, 101,
- 102, 103, 104, 82, nil, nil, nil, 81, nil, 83,
- nil, 51, 50, nil, nil, nil, 80, nil, nil, nil,
- nil, nil, nil, nil, nil, 54, nil, 95, nil, nil,
- nil, 55, nil, nil, nil, nil, nil, nil, nil, 94,
- 96, nil, nil, 53, 97, 98, 99, 100, 101, 102,
- 103, 104, 82, nil, nil, nil, 81, nil, 83, nil,
- 51, 50, nil, nil, nil, 80, nil, nil, nil, nil,
- nil, nil, nil, nil, 54, nil, 95, nil, nil, nil,
- 55, nil, nil, nil, nil, nil, nil, nil, nil, 96,
- nil, nil, 53, 97, 98, 99, 100, 101, 102, 103,
- 104, 82, nil, nil, nil, 81, nil, 83, nil, 51,
- 50, nil, nil, nil, 80, nil, nil, nil, nil, nil,
- nil, nil, nil, 54, nil, 95, nil, nil, nil, 55,
- nil, nil, nil, nil, nil, nil, nil, nil, 96, nil,
- nil, 53, 97, 98, 99, 100, 101, 102, 103, 104,
- 82, nil, nil, nil, 81, nil, 83, nil, 51, 50,
- nil, nil, nil, 80, nil, nil, nil, nil, nil, nil,
- nil, nil, 54, nil, 95, nil, nil, nil, 55, nil,
- nil, nil, nil, nil, nil, nil, nil, 96, nil, nil,
- 53, 97, 98, 99, 100, 101, 102, 103, 104, 82,
- nil, nil, nil, 81, nil, 83, nil, 51, 50, nil,
- nil, nil, 80, nil, nil, nil, nil, nil, nil, nil,
- nil, 54, nil, 95, nil, nil, nil, 55, nil, nil,
- nil, nil, nil, nil, nil, nil, 96, nil, nil, 53,
- 97, 98, 99, 100, 101, 102, 103, 104, 82, nil,
- nil, nil, 81, nil, 83, nil, 51, 50, nil, nil,
- nil, 80, nil, nil, nil, nil, nil, nil, nil, nil,
- 54, nil, 95, nil, nil, nil, 55, nil, nil, nil,
- nil, nil, nil, nil, nil, 96, nil, nil, 53, 97,
- 98, 99, 100, 101, 102, 103, 104, 82, nil, nil,
- nil, 81, nil, 83, nil, 51, 50, nil, nil, nil,
- 80, nil, nil, nil, nil, nil, nil, nil, nil, 54,
- nil, 95, nil, nil, nil, 55, nil, nil, nil, nil,
- nil, nil, nil, nil, 96, nil, nil, 53, 97, 98,
- 99, 100, 101, 102, 103, 104, 82, nil, nil, nil,
- 81, nil, 83, nil, 51, 50, nil, nil, nil, 80,
- nil, nil, nil, nil, nil, nil, nil, nil, 54, nil,
- 95, nil, nil, nil, 55, nil, nil, nil, nil, nil,
- nil, nil, nil, 96, nil, nil, 53, 97, 98, 99,
- 100, 101, 102, 103, 104, 82, nil, nil, nil, 81,
- nil, 83, nil, 51, 50, nil, nil, nil, 80, nil,
- nil, nil, nil, nil, nil, nil, nil, 54, nil, 95,
- nil, nil, nil, 55, nil, nil, nil, nil, nil, nil,
- nil, nil, 96, nil, nil, 53, 97, 98, 99, 100,
- 101, 102, 103, 104, 82, nil, nil, nil, 81, nil,
- 83, nil, 51, 50, nil, nil, nil, 80, nil, nil,
- nil, nil, nil, nil, nil, nil, 54, nil, 95, nil,
- nil, nil, 55, nil, nil, nil, nil, nil, nil, nil,
- nil, 96, nil, nil, 53, 97, 98, 99, 100, 101,
- 102, 103, 104, 82, nil, nil, nil, 81, nil, 83,
- nil, 51, 50, nil, nil, nil, 80, nil, nil, nil,
- nil, nil, nil, nil, nil, 54, nil, 95, nil, nil,
- nil, 55, nil, nil, nil, nil, nil, nil, nil, nil,
- 96, nil, nil, 53, 97, 98, 99, 100, 101, 102,
- 103, 104, 82, nil, nil, nil, 81, nil, 83, nil,
- 51, 50, nil, nil, nil, 80, nil, nil, nil, nil,
- nil, nil, nil, nil, 54, nil, 95, nil, nil, nil,
- 55, nil, nil, nil, nil, nil, nil, nil, nil, 96,
- nil, nil, 53, 97, 98, 99, 100, 101, 102, 103,
- 104, 82, nil, nil, nil, 81, nil, 83, nil, 51,
- 50, nil, nil, nil, 80, nil, nil, nil, nil, nil,
- nil, nil, nil, 54, nil, 95, nil, nil, nil, 55,
- nil, nil, nil, nil, nil, nil, nil, nil, 96, nil,
- nil, 53, 97, 98, 99, 100, 101, 102, 103, 104,
- 82, nil, nil, nil, 81, nil, 83, nil, 51, 50,
- nil, nil, nil, 80, nil, nil, nil, nil, nil, nil,
- nil, nil, 54, nil, 95, nil, nil, nil, 55, nil,
- nil, nil, nil, nil, nil, nil, nil, 96, nil, nil,
- 53, 97, 98, 99, 100, 101, 102, 103, 104, 82,
- nil, nil, nil, 81, nil, 83, nil, 51, 50, nil,
- nil, nil, 80, nil, nil, nil, nil, nil, nil, nil,
- nil, 54, nil, 95, nil, nil, nil, 55, nil, nil,
- nil, nil, nil, nil, nil, nil, 96, nil, nil, 53,
- 97, 98, 99, 100, 101, 102, 103, 104, 82, nil,
- nil, nil, 81, nil, 83, nil, 51, 50, nil, nil,
- nil, 80, nil, nil, nil, nil, nil, nil, nil, nil,
- 54, nil, 95, nil, nil, nil, 55, nil, nil, nil,
- nil, nil, nil, nil, nil, 96, nil, nil, 53, 97,
- 98, 99, 100, 101, 102, 103, 104, 82, nil, nil,
- nil, 81, nil, 83, nil, 51, 50, nil, nil, nil,
- 80, nil, nil, nil, nil, nil, nil, nil, nil, 54,
- nil, 95, nil, nil, nil, 55, nil, nil, nil, nil,
- nil, nil, nil, nil, 96, nil, nil, 53, 97, 98,
- 99, 100, 101, 102, 103, 104, 82, nil, nil, nil,
- 81, nil, 83, nil, 51, 50, nil, nil, nil, 80,
- nil, nil, nil, nil, nil, nil, nil, nil, 54, nil,
- 95, nil, nil, nil, 55, nil, nil, nil, nil, nil,
- nil, nil, nil, 96, nil, nil, 53, 97, 98, 99,
- 100, 101, 102, 103, 104, 82, nil, nil, nil, 81,
- nil, 83, nil, 51, 50, nil, nil, nil, 80, nil,
- nil, nil, nil, nil, nil, nil, nil, 54, nil, 95,
- nil, nil, nil, 55, nil, nil, nil, nil, nil, nil,
- nil, nil, 96, nil, nil, 53, 97, 98, 99, 100,
- 101, 102, 103, 104, 82, nil, nil, nil, 81, nil,
- 83, nil, 51, 50, nil, nil, nil, 80, nil, nil,
- nil, nil, nil, nil, nil, nil, 54, nil, 95, nil,
- nil, nil, 55, nil, nil, nil, nil, nil, nil, nil,
- nil, 96, nil, nil, 53, 97, 98, 99, 100, 101,
- 102, 103, 104, 82, nil, nil, nil, 81, nil, 83,
- nil, 51, 50, nil, nil, nil, 80, nil, nil, nil,
- nil, nil, nil, nil, nil, 54, nil, 95, nil, nil,
- nil, 55, nil, nil, nil, nil, nil, nil, nil, nil,
- 96, nil, nil, 53, 97, 98, 99, 100, 101, 102,
- 103, 104, 82, nil, nil, nil, 81, nil, 83, nil,
- 51, 50, nil, nil, nil, 80, nil, nil, nil, nil,
- nil, nil, nil, nil, 54, nil, 95, nil, nil, nil,
- 55, nil, nil, nil, nil, nil, nil, nil, nil, 96,
- nil, nil, 53, 97, 98, 99, 100, 101, 102, 103,
- 104, 82, nil, nil, nil, 81, nil, 83, nil, 51,
- 50, nil, nil, nil, 80, nil, nil, nil, nil, nil,
- nil, nil, nil, 54, nil, 95, nil, nil, nil, 55,
- nil, nil, nil, nil, nil, nil, nil, nil, 96, nil,
- nil, 53, 97, 98, 99, 100, 101, 102, 103, 104,
- 82, nil, nil, nil, 81, nil, 83, nil, 51, 50,
- nil, nil, nil, 80, nil, nil, nil, nil, nil, nil,
- nil, nil, 54, nil, 95, nil, nil, nil, 55, nil,
- nil, nil, nil, nil, nil, nil, nil, 96, nil, nil,
- 53, 97, 98, 99, 100, 101, 102, 103, 104, 82,
- nil, nil, nil, 81, nil, 83, nil, 51, 50, nil,
- nil, nil, 80, nil, nil, nil, nil, nil, nil, nil,
- nil, 54, nil, 95, nil, nil, nil, 55, nil, nil,
- nil, nil, nil, nil, nil, nil, 96, nil, nil, 53,
- 97, 98, 99, 100, 101, 102, 103, 104, 82, nil,
- nil, nil, 81, nil, 83, nil, 51, 50, nil, nil,
- nil, 80, nil, nil, nil, nil, nil, nil, nil, nil,
- 54, nil, 95, nil, nil, nil, 55, nil, nil, nil,
- nil, nil, nil, nil, nil, 96, nil, nil, 53, 97,
- 98, 99, 100, 101, 102, 103, 104, 82, nil, nil,
- nil, 81, nil, 83, nil, 51, 50, nil, nil, nil,
- 80, nil, nil, nil, nil, nil, nil, nil, nil, 54,
- nil, 95, nil, nil, nil, 55, nil, nil, nil, nil,
- nil, nil, nil, nil, 96, nil, nil, 53, 97, 98,
- 99, 100, 101, 102, 103, 104, 82, nil, nil, nil,
- 81, nil, 83, nil, 51, 50, nil, nil, nil, 80,
- nil, nil, nil, nil, nil, nil, nil, nil, 54, nil,
- 95, nil, nil, nil, 55, nil, nil, nil, nil, nil,
- nil, nil, 94, 96, nil, nil, 53, 97, 98, 99,
- 100, 101, 102, 103, 104, 82, nil, nil, nil, 81,
- nil, 83, nil, 51, 50, nil, nil, nil, 80, nil,
- nil, nil, nil, nil, nil, nil, nil, 54, nil, 95,
- nil, nil, nil, 55, nil, nil, nil, nil, nil, nil,
- nil, 94, 96, nil, nil, 53, 97, 98, 99, 100,
- 101, 102, 103, 104, 82, nil, nil, nil, 81, nil,
- 83, nil, 51, 50, nil, nil, nil, 80, nil, nil,
- nil, nil, nil, nil, nil, nil, 54, nil, 95, nil,
- nil, nil, 55, nil, nil, nil, nil, nil, nil, nil,
- 94, 96, nil, nil, 53, 97, 98, 99, 100, 101,
- 102, 103, 104, 82, nil, nil, nil, 81, nil, 83,
- nil, 51, 50, nil, nil, nil, 80, nil, nil, nil,
- nil, nil, nil, nil, nil, 54, nil, 95, nil, nil,
- nil, 55, nil, nil, nil, nil, nil, nil, nil, 94,
- 96, nil, nil, 53, 97, 98, 99, 100, 101, 102,
- 103, 104, 82, nil, nil, nil, 81, nil, 83, nil,
- 51, 50, nil, nil, nil, 80, nil, nil, nil, nil,
- nil, nil, nil, nil, 54, nil, 95, nil, nil, nil,
- 55, nil, nil, nil, nil, nil, nil, nil, nil, 96,
- nil, nil, 53, 97, 98, 99, 100, 101, 102, 103,
- 104, 82, nil, nil, nil, 81, nil, 83, nil, 51,
- 50, nil, nil, nil, 80, nil, nil, nil, nil, nil,
- nil, nil, nil, 54, nil, 95, nil, nil, nil, 55,
- nil, nil, nil, nil, nil, nil, nil, nil, 96, nil,
- nil, 53, 97, 98, 99, 100, 101, 102, 103, 104,
- 82, nil, nil, nil, 81, nil, 83, nil, 51, 50,
- nil, nil, nil, 80, nil, nil, nil, nil, nil, nil,
- nil, nil, 54, nil, 95, nil, nil, nil, 55, nil,
- nil, nil, nil, nil, nil, nil, 94, 96, nil, nil,
- 53, 97, 98, 99, 100, 101, 102, 103, 104, 82,
- nil, nil, nil, 81, nil, 83, nil, 51, 50, nil,
- nil, nil, 80, nil, nil, nil, nil, nil, nil, nil,
- nil, 54, nil, 95, nil, nil, nil, 55, nil, nil,
- nil, nil, nil, nil, nil, 94, 96, nil, nil, 53,
- 97, 98, 99, 100, 101, 102, 103, 104, 115, 116,
- 117, 118, 119, 120, 123, 122, 121, 115, 116, 117,
- 118, 119, 120, 123, 122, 121, 153, 152, 151, 154,
- 155, 156, 145, 146, 147, 149, 150, nil, nil, nil,
- 148, nil, nil, nil, 126, 125, nil, nil, nil, 124,
- nil, nil, nil, 126, 125, nil, nil, nil, 124, 144,
- 143, 161, 162, 163, 164, 165, 166, 157, 158, 159,
- 160, 153, 152, 151, 154, 155, 156, 145, 146, 147,
- 149, 150, nil, nil, nil, 148, nil, nil, nil, nil,
- nil, nil, nil, 142, 144, 143, 161, 162, 163, 164,
- 165, 166, 157, 158, 159, 160, 153, 152, 151, 154,
- 155, 156, 145, 146, 147, 149, 150, nil, nil, nil,
- 148, nil, nil, nil, nil, nil, nil, nil, 221, 144,
- 143, 161, 162, 163, 164, 165, 166, 157, 158, 159,
- 160, 153, 152, 151, 154, 155, 156, 145, 146, 147,
- 149, 150, nil, nil, nil, 148, nil, nil, nil, nil,
- nil, nil, nil, 289, 144, 143, 161, 162, 163, 164,
- 165, 166, 157, 158, 159, 160, 153, 152, 151, 154,
- 155, 156, 145, 146, 147, 149, 150, nil, nil, nil,
- 148, nil, nil, nil, nil, nil, nil, nil, 297, 144,
- 143, 161, 162, 163, 164, 165, 166, 157, 158, 159,
- 160, 153, 152, 151, 154, 155, 156, 145, 146, 147,
- 149, 150, nil, nil, nil, 148, nil, nil, nil, nil,
- nil, nil, 251, 144, 143, 161, 162, 163, 164, 165,
- 166, 157, 158, 159, 160, 153, 152, 151, 154, 155,
- 156, 145, 146, 147, 149, 150, nil, nil, nil, 148,
- nil, nil, nil, nil, nil, nil, 263, 144, 143, 161,
- 162, 163, 164, 165, 166, 157, 158, 159, 160, 153,
- 152, 151, 154, 155, 156, 145, 146, 147, 149, 150,
- nil, nil, nil, 148, nil, nil, nil, nil, nil, nil,
- 265, 144, 143, 161, 162, 163, 164, 165, 166, 157,
- 158, 159, 160, 153, 152, 151, 154, 155, 156, 145,
- 146, 147, 149, 150, nil, nil, nil, 148, nil, nil,
- nil, nil, nil, nil, 286, 144, 143, 161, 162, 163,
- 164, 165, 166, 157, 158, 159, 160, 153, 152, 151,
- 154, 155, 156, 145, 146, 147, 149, 150, nil, nil,
- nil, 148, 51, 50, 4, 10, 11, nil, 299, 36,
- 32, 34, 37, 39, 40, 41, 54, 42, 43, nil,
- 44, 45, 55, 46, nil, 47, nil, 48, 51, 50,
- 4, 10, 11, nil, 53, 36, 32, 34, 37, 39,
- 40, 41, 54, 42, 43, nil, 44, 45, 55, 46,
- nil, 47, nil, 48, 51, 50, 105, nil, nil, nil,
- 53, 36, 32, 34, 37, 39, 40, 41, 54, 42,
- 43, 107, 44, 45, 55, 46, nil, 47, nil, 48,
- 51, 50, 105, nil, nil, nil, 53, 36, 32, 34,
- 37, 39, 40, 41, 54, 42, 43, nil, 44, 45,
- 55, 46, nil, 47, nil, 48, 51, 50, 105, nil,
- nil, nil, 53, 36, 32, 34, 37, 39, 40, 41,
- 54, 42, 43, nil, 44, 45, 55, 46, nil, 47,
- nil, 48, 51, 50, 105, nil, nil, nil, 53, 36,
- 32, 34, 37, 39, 40, 41, 54, 42, 43, nil,
- 44, 45, 55, 46, nil, 47, nil, 48, 51, 50,
- 105, nil, nil, nil, 53, 36, 32, 34, 37, 39,
- 40, 41, 54, 42, 43, nil, 44, 45, 55, 46,
- nil, 47, nil, 48, 51, 50, 105, nil, nil, nil,
- 53, 36, 32, 34, 37, 39, 40, 41, 54, 42,
- 43, nil, 44, 45, 55, 46, nil, 47, nil, 48,
- 51, 50, 105, nil, nil, nil, 53, 36, 32, 34,
- 37, 39, 40, 41, 54, 42, 43, nil, 44, 45,
- 55, 46, nil, 47, nil, 48, 51, 50, 105, nil,
- nil, nil, 53, 36, 32, 34, 37, 39, 40, 41,
- 54, 42, 43, nil, 44, 45, 55, 46, nil, 47,
- nil, 48, 51, 50, 105, nil, nil, nil, 53, 36,
- 32, 34, 37, 39, 40, 41, 54, 42, 43, nil,
- 44, 45, 55, 46, nil, 47, nil, 48, nil, nil,
- nil, nil, nil, nil, 53, 144, 143, 161, 162, 163,
- 164, 165, 166, 157, 158, 159, 160, 153, 152, 151,
- 154, 155, 156, 145, 146, 147, 149, 150, nil, nil,
- nil, 148, 144, 143, 161, 162, 163, 164, 165, 166,
- 157, 158, 159, 160, 153, 152, 151, 154, 155, 156,
- 145, 146, 147, 149, 150, nil, nil, nil, 148, 144,
- 143, 161, 162, 163, 164, 165, 166, 157, 158, 159,
- 160, 153, 152, 151, 154, 155, 156, 145, 146, 147,
- 149, 150, nil, nil, nil, 148, 144, 143, 161, 162,
- 163, 164, 165, 166, 157, 158, 159, 160, 153, 152,
- 151, 154, 155, 156, 145, 146, 147, 149, 150, nil,
- nil, nil, 148, 144, 143, 161, 162, 163, 164, 165,
- 166, 157, 158, 159, 160, 153, 152, 151, 154, 155,
- 156, 145, 146, 147, 149, 150, nil, nil, nil, 148,
- 144, 143, 161, 162, 163, 164, 165, 166, 157, 158,
- 159, 160, 153, 152, 151, 154, 155, 156, 145, 146,
- 147, 149, 150, nil, nil, nil, 148, 144, 143, 161,
- 162, 163, 164, 165, 166, 157, 158, 159, 160, 153,
- 152, 151, 154, 155, 156, 145, 146, 147, 149, 150,
- nil, nil, nil, 148, 144, 143, 161, 162, 163, 164,
- 165, 166, 157, 158, 159, 160, 153, 152, 151, 154,
- 155, 156, 145, 146, 147, 149, 150, nil, nil, nil,
- 148, 144, 143, 161, 162, 163, 164, 165, 166, 157,
- 158, 159, 160, 153, 152, 151, 154, 155, 156, 145,
- 146, 147, 149, 150, nil, nil, nil, 148, 144, 143,
- 161, 162, 163, 164, 165, 166, 157, 158, 159, 160,
- 153, 152, 151, 154, 155, 156, 145, 146, 147, 149,
- 150, nil, nil, nil, 148, 144, 143, 161, 162, 163,
- 164, 165, 166, 157, 158, 159, 160, 153, 152, 151,
- 154, 155, 156, 145, 146, 147, 149, 150, nil, nil,
- nil, 148, 144, 143, 161, 162, 163, 164, 165, 166,
- 157, 158, 159, 160, 153, 152, 151, 154, 155, 156,
- 145, 146, 147, 149, 150, nil, nil, nil, 148, 144,
- 143, 161, 162, 163, 164, 165, 166, 157, 158, 159,
- 160, 153, 152, 151, 154, 155, 156, 145, 146, 147,
- 149, 150, nil, nil, nil, 148, 144, 143, 161, 162,
- 163, 164, 165, 166, 157, 158, 159, 160, 153, 152,
- 151, 154, 155, 156, 145, 146, 147, 149, 150, nil,
- nil, nil, 148, 144, 143, 161, 162, 163, 164, 165,
- 166, 157, 158, 159, 160, 153, 152, 151, 154, 155,
- 156, 145, 146, 147, 149, 150, nil, nil, nil, 148,
- 144, 143, 161, 162, 163, 164, 165, 166, 157, 158,
- 159, 160, 153, 152, 151, 154, 155, 156, 145, 146,
- 147, 149, 150, nil, nil, nil, 148, 143, 161, 162,
- 163, 164, 165, 166, 157, 158, 159, 160, 153, 152,
- 151, 154, 155, 156, 145, 146, 147, 149, 150, nil,
- nil, nil, 148, 161, 162, 163, 164, 165, 166, 157,
- 158, 159, 160, 153, 152, 151, 154, 155, 156, 145,
- 146, 147, 149, 150, nil, nil, nil, 148, 153, 152,
- 151, 154, 155, 156, 145, 146, 147, 149, 150, nil,
- nil, nil, 148, 153, 152, 151, 154, 155, 156, 145,
- 146, 147, 149, 150, nil, nil, nil, 148, 153, 152,
- 151, 154, 155, 156, 145, 146, 147, 149, 150, nil,
- nil, nil, 148, 153, 152, 151, 154, 155, 156, 145,
- 146, 147, 149, 150, nil, nil, nil, 148, 153, 152,
- 151, 154, 155, 156, 145, 146, 147, 149, 150, nil,
- nil, nil, 148, 153, 152, 151, 154, 155, 156, 145,
- 146, 147, 149, 150, nil, nil, nil, 148, 153, 152,
- 151, 154, 155, 156, 145, 146, 147, 149, 150, nil,
- nil, nil, 148, 153, 152, 151, 154, 155, 156, 145,
- 146, 147, 149, 150, nil, nil, nil, 148, 153, 152,
- 151, 154, 155, 156, 145, 146, 147, 149, 150, nil,
- nil, nil, 148, 152, 151, 154, 155, 156, 145, 146,
- 147, 149, 150, nil, nil, nil, 148, 151, 154, 155,
- 156, 145, 146, 147, 149, 150, nil, nil, nil, 148 ]
-
-racc_action_check = [
- 213, 213, 213, 213, 213, 213, 213, 213, 213, 213,
- 213, 213, 213, 213, 213, 213, 213, 213, 213, 213,
- 213, 213, 213, 42, 11, 45, 213, 42, 273, 42,
- 11, 42, 42, 1, 45, 37, 42, 10, 42, 33,
- 45, 37, 11, 31, 41, 42, 33, 42, 73, 73,
- 41, 42, 45, 37, 32, 273, 134, 213, 34, 42,
- 42, 273, 41, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 66, 273, 210, 134, 66, 210, 66, 210,
- 66, 66, 52, 134, 52, 66, 132, 50, 132, 134,
- 109, 109, 35, 50, 66, 38, 66, 229, 229, 229,
- 66, 134, 39, 229, 109, 50, 74, 74, 40, 66,
- 109, 44, 66, 66, 66, 66, 66, 66, 66, 66,
- 66, 80, 109, 46, 48, 80, 51, 80, 56, 80,
- 80, 62, 51, 69, 80, 70, 94, 71, 75, 297,
- 297, 77, 94, 80, 51, 80, 230, 230, 230, 80,
- 4, 4, 230, 297, 94, 90, 105, 4, 80, 297,
- 106, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 81, 297, 110, 113, 81, 139, 81, 140, 81, 81,
- 169, 95, 170, 81, 95, 171, 174, 95, 175, 176,
- 111, 131, 81, 177, 81, 178, 111, 131, 81, 95,
- 95, 95, 95, 95, 95, 95, 95, 81, 111, 131,
- 81, 81, 81, 81, 81, 81, 81, 81, 81, 82,
- 138, 182, 183, 82, 187, 82, 138, 82, 82, 193,
- 256, 207, 82, 212, 216, 217, 256, 220, 138, 218,
- 225, 82, 226, 82, 231, 218, 232, 82, 256, 256,
- 256, 256, 256, 256, 256, 256, 82, 218, 233, 82,
- 82, 82, 82, 82, 82, 82, 82, 82, 83, 234,
- 252, 270, 83, 288, 83, 296, 83, 83, 302, nil,
- nil, 83, 235, 235, 235, 235, 235, 235, 235, 235,
- 83, nil, 83, 235, nil, nil, 83, nil, 238, 238,
- 238, 238, 238, nil, nil, 83, 238, nil, 83, 83,
- 83, 83, 83, 83, 83, 83, 83, 96, nil, nil,
- nil, 96, nil, 96, nil, 96, 96, nil, nil, nil,
- 96, nil, 239, 239, 239, 239, 239, nil, nil, 96,
- 239, 96, nil, nil, nil, 96, nil, nil, 240, 240,
- 240, 240, 240, 96, 96, 96, 240, 96, 96, 96,
- 96, 96, 96, 96, 96, 96, 112, nil, nil, nil,
- 112, nil, 112, nil, 112, 112, nil, nil, nil, 112,
- 172, 172, 172, 172, 172, nil, nil, nil, 112, nil,
- 112, nil, nil, nil, 112, 276, 276, 276, 276, 276,
- nil, nil, nil, 112, nil, nil, 112, 112, 112, 112,
- 112, 112, 112, 112, 112, 114, nil, nil, nil, 114,
- nil, 114, nil, 114, 114, nil, nil, nil, 114, 301,
- 301, 301, 301, 301, nil, nil, nil, 114, nil, 114,
- nil, nil, nil, 114, nil, nil, nil, nil, nil, nil,
- nil, nil, 114, nil, nil, 114, 114, 114, 114, 114,
- 114, 114, 114, 114, 115, nil, nil, nil, 115, nil,
- 115, nil, 115, 115, nil, nil, nil, 115, nil, nil,
- nil, nil, nil, nil, nil, nil, 115, nil, 115, nil,
- nil, nil, 115, nil, nil, nil, nil, nil, nil, nil,
- 115, 115, nil, nil, 115, 115, 115, 115, 115, 115,
- 115, 115, 115, 116, nil, nil, nil, 116, nil, 116,
- nil, 116, 116, nil, nil, nil, 116, nil, nil, nil,
- nil, nil, nil, nil, nil, 116, nil, 116, nil, nil,
- nil, 116, nil, nil, nil, nil, nil, nil, nil, nil,
- 116, nil, nil, 116, 116, 116, 116, 116, 116, 116,
- 116, 116, 117, nil, nil, nil, 117, nil, 117, nil,
- 117, 117, nil, nil, nil, 117, nil, nil, nil, nil,
- nil, nil, nil, nil, 117, nil, 117, nil, nil, nil,
- 117, nil, nil, nil, nil, nil, nil, nil, nil, 117,
- nil, nil, 117, 117, 117, 117, 117, 117, 117, 117,
- 117, 118, nil, nil, nil, 118, nil, 118, nil, 118,
- 118, nil, nil, nil, 118, nil, nil, nil, nil, nil,
- nil, nil, nil, 118, nil, 118, nil, nil, nil, 118,
- nil, nil, nil, nil, nil, nil, nil, nil, 118, nil,
- nil, 118, 118, 118, 118, 118, 118, 118, 118, 118,
- 119, nil, nil, nil, 119, nil, 119, nil, 119, 119,
- nil, nil, nil, 119, nil, nil, nil, nil, nil, nil,
- nil, nil, 119, nil, 119, nil, nil, nil, 119, nil,
- nil, nil, nil, nil, nil, nil, nil, 119, nil, nil,
- 119, 119, 119, 119, 119, 119, 119, 119, 119, 120,
- nil, nil, nil, 120, nil, 120, nil, 120, 120, nil,
- nil, nil, 120, nil, nil, nil, nil, nil, nil, nil,
- nil, 120, nil, 120, nil, nil, nil, 120, nil, nil,
- nil, nil, nil, nil, nil, nil, 120, nil, nil, 120,
- 120, 120, 120, 120, 120, 120, 120, 120, 121, nil,
- nil, nil, 121, nil, 121, nil, 121, 121, nil, nil,
- nil, 121, nil, nil, nil, nil, nil, nil, nil, nil,
- 121, nil, 121, nil, nil, nil, 121, nil, nil, nil,
- nil, nil, nil, nil, nil, 121, nil, nil, 121, 121,
- 121, 121, 121, 121, 121, 121, 121, 122, nil, nil,
- nil, 122, nil, 122, nil, 122, 122, nil, nil, nil,
- 122, nil, nil, nil, nil, nil, nil, nil, nil, 122,
- nil, 122, nil, nil, nil, 122, nil, nil, nil, nil,
- nil, nil, nil, nil, 122, nil, nil, 122, 122, 122,
- 122, 122, 122, 122, 122, 122, 123, nil, nil, nil,
- 123, nil, 123, nil, 123, 123, nil, nil, nil, 123,
- nil, nil, nil, nil, nil, nil, nil, nil, 123, nil,
- 123, nil, nil, nil, 123, nil, nil, nil, nil, nil,
- nil, nil, nil, 123, nil, nil, 123, 123, 123, 123,
- 123, 123, 123, 123, 123, 124, nil, nil, nil, 124,
- nil, 124, nil, 124, 124, nil, nil, nil, 124, 124,
- nil, nil, nil, nil, nil, nil, nil, 124, nil, 124,
- nil, nil, nil, 124, nil, nil, nil, nil, nil, nil,
- nil, 124, 124, nil, nil, 124, 124, 124, 124, 124,
- 124, 124, 124, 124, 130, nil, nil, nil, 130, nil,
- 130, nil, 130, 130, nil, nil, nil, 130, nil, nil,
- nil, nil, nil, nil, nil, nil, 130, nil, 130, nil,
- nil, nil, 130, nil, nil, nil, nil, nil, nil, nil,
- nil, 130, nil, nil, 130, 130, 130, 130, 130, 130,
- 130, 130, 130, 137, nil, nil, nil, 137, nil, 137,
- nil, 137, 137, nil, nil, nil, 137, nil, nil, nil,
- nil, nil, nil, nil, nil, 137, nil, 137, nil, nil,
- nil, 137, nil, nil, nil, nil, nil, nil, nil, 137,
- 137, nil, nil, 137, 137, 137, 137, 137, 137, 137,
- 137, 137, 143, nil, nil, nil, 143, nil, 143, nil,
- 143, 143, nil, nil, nil, 143, nil, nil, nil, nil,
- nil, nil, nil, nil, 143, nil, 143, nil, nil, nil,
- 143, nil, nil, nil, nil, nil, nil, nil, nil, 143,
- nil, nil, 143, 143, 143, 143, 143, 143, 143, 143,
- 143, 144, nil, nil, nil, 144, nil, 144, nil, 144,
- 144, nil, nil, nil, 144, nil, nil, nil, nil, nil,
- nil, nil, nil, 144, nil, 144, nil, nil, nil, 144,
- nil, nil, nil, nil, nil, nil, nil, nil, 144, nil,
- nil, 144, 144, 144, 144, 144, 144, 144, 144, 144,
- 145, nil, nil, nil, 145, nil, 145, nil, 145, 145,
- nil, nil, nil, 145, nil, nil, nil, nil, nil, nil,
- nil, nil, 145, nil, 145, nil, nil, nil, 145, nil,
- nil, nil, nil, nil, nil, nil, nil, 145, nil, nil,
- 145, 145, 145, 145, 145, 145, 145, 145, 145, 146,
- nil, nil, nil, 146, nil, 146, nil, 146, 146, nil,
- nil, nil, 146, nil, nil, nil, nil, nil, nil, nil,
- nil, 146, nil, 146, nil, nil, nil, 146, nil, nil,
- nil, nil, nil, nil, nil, nil, 146, nil, nil, 146,
- 146, 146, 146, 146, 146, 146, 146, 146, 147, nil,
- nil, nil, 147, nil, 147, nil, 147, 147, nil, nil,
- nil, 147, nil, nil, nil, nil, nil, nil, nil, nil,
- 147, nil, 147, nil, nil, nil, 147, nil, nil, nil,
- nil, nil, nil, nil, nil, 147, nil, nil, 147, 147,
- 147, 147, 147, 147, 147, 147, 147, 148, nil, nil,
- nil, 148, nil, 148, nil, 148, 148, nil, nil, nil,
- 148, nil, nil, nil, nil, nil, nil, nil, nil, 148,
- nil, 148, nil, nil, nil, 148, nil, nil, nil, nil,
- nil, nil, nil, nil, 148, nil, nil, 148, 148, 148,
- 148, 148, 148, 148, 148, 148, 149, nil, nil, nil,
- 149, nil, 149, nil, 149, 149, nil, nil, nil, 149,
- nil, nil, nil, nil, nil, nil, nil, nil, 149, nil,
- 149, nil, nil, nil, 149, nil, nil, nil, nil, nil,
- nil, nil, nil, 149, nil, nil, 149, 149, 149, 149,
- 149, 149, 149, 149, 149, 150, nil, nil, nil, 150,
- nil, 150, nil, 150, 150, nil, nil, nil, 150, nil,
- nil, nil, nil, nil, nil, nil, nil, 150, nil, 150,
- nil, nil, nil, 150, nil, nil, nil, nil, nil, nil,
- nil, nil, 150, nil, nil, 150, 150, 150, 150, 150,
- 150, 150, 150, 150, 151, nil, nil, nil, 151, nil,
- 151, nil, 151, 151, nil, nil, nil, 151, nil, nil,
- nil, nil, nil, nil, nil, nil, 151, nil, 151, nil,
- nil, nil, 151, nil, nil, nil, nil, nil, nil, nil,
- nil, 151, nil, nil, 151, 151, 151, 151, 151, 151,
- 151, 151, 151, 152, nil, nil, nil, 152, nil, 152,
- nil, 152, 152, nil, nil, nil, 152, nil, nil, nil,
- nil, nil, nil, nil, nil, 152, nil, 152, nil, nil,
- nil, 152, nil, nil, nil, nil, nil, nil, nil, nil,
- 152, nil, nil, 152, 152, 152, 152, 152, 152, 152,
- 152, 152, 153, nil, nil, nil, 153, nil, 153, nil,
- 153, 153, nil, nil, nil, 153, nil, nil, nil, nil,
- nil, nil, nil, nil, 153, nil, 153, nil, nil, nil,
- 153, nil, nil, nil, nil, nil, nil, nil, nil, 153,
- nil, nil, 153, 153, 153, 153, 153, 153, 153, 153,
- 153, 154, nil, nil, nil, 154, nil, 154, nil, 154,
- 154, nil, nil, nil, 154, nil, nil, nil, nil, nil,
- nil, nil, nil, 154, nil, 154, nil, nil, nil, 154,
- nil, nil, nil, nil, nil, nil, nil, nil, 154, nil,
- nil, 154, 154, 154, 154, 154, 154, 154, 154, 154,
- 155, nil, nil, nil, 155, nil, 155, nil, 155, 155,
- nil, nil, nil, 155, nil, nil, nil, nil, nil, nil,
- nil, nil, 155, nil, 155, nil, nil, nil, 155, nil,
- nil, nil, nil, nil, nil, nil, nil, 155, nil, nil,
- 155, 155, 155, 155, 155, 155, 155, 155, 155, 156,
- nil, nil, nil, 156, nil, 156, nil, 156, 156, nil,
- nil, nil, 156, nil, nil, nil, nil, nil, nil, nil,
- nil, 156, nil, 156, nil, nil, nil, 156, nil, nil,
- nil, nil, nil, nil, nil, nil, 156, nil, nil, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 157, nil,
- nil, nil, 157, nil, 157, nil, 157, 157, nil, nil,
- nil, 157, nil, nil, nil, nil, nil, nil, nil, nil,
- 157, nil, 157, nil, nil, nil, 157, nil, nil, nil,
- nil, nil, nil, nil, nil, 157, nil, nil, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 158, nil, nil,
- nil, 158, nil, 158, nil, 158, 158, nil, nil, nil,
- 158, nil, nil, nil, nil, nil, nil, nil, nil, 158,
- nil, 158, nil, nil, nil, 158, nil, nil, nil, nil,
- nil, nil, nil, nil, 158, nil, nil, 158, 158, 158,
- 158, 158, 158, 158, 158, 158, 159, nil, nil, nil,
- 159, nil, 159, nil, 159, 159, nil, nil, nil, 159,
- nil, nil, nil, nil, nil, nil, nil, nil, 159, nil,
- 159, nil, nil, nil, 159, nil, nil, nil, nil, nil,
- nil, nil, nil, 159, nil, nil, 159, 159, 159, 159,
- 159, 159, 159, 159, 159, 160, nil, nil, nil, 160,
- nil, 160, nil, 160, 160, nil, nil, nil, 160, nil,
- nil, nil, nil, nil, nil, nil, nil, 160, nil, 160,
- nil, nil, nil, 160, nil, nil, nil, nil, nil, nil,
- nil, nil, 160, nil, nil, 160, 160, 160, 160, 160,
- 160, 160, 160, 160, 161, nil, nil, nil, 161, nil,
- 161, nil, 161, 161, nil, nil, nil, 161, nil, nil,
- nil, nil, nil, nil, nil, nil, 161, nil, 161, nil,
- nil, nil, 161, nil, nil, nil, nil, nil, nil, nil,
- nil, 161, nil, nil, 161, 161, 161, 161, 161, 161,
- 161, 161, 161, 162, nil, nil, nil, 162, nil, 162,
- nil, 162, 162, nil, nil, nil, 162, nil, nil, nil,
- nil, nil, nil, nil, nil, 162, nil, 162, nil, nil,
- nil, 162, nil, nil, nil, nil, nil, nil, nil, nil,
- 162, nil, nil, 162, 162, 162, 162, 162, 162, 162,
- 162, 162, 163, nil, nil, nil, 163, nil, 163, nil,
- 163, 163, nil, nil, nil, 163, nil, nil, nil, nil,
- nil, nil, nil, nil, 163, nil, 163, nil, nil, nil,
- 163, nil, nil, nil, nil, nil, nil, nil, nil, 163,
- nil, nil, 163, 163, 163, 163, 163, 163, 163, 163,
- 163, 164, nil, nil, nil, 164, nil, 164, nil, 164,
- 164, nil, nil, nil, 164, nil, nil, nil, nil, nil,
- nil, nil, nil, 164, nil, 164, nil, nil, nil, 164,
- nil, nil, nil, nil, nil, nil, nil, nil, 164, nil,
- nil, 164, 164, 164, 164, 164, 164, 164, 164, 164,
- 165, nil, nil, nil, 165, nil, 165, nil, 165, 165,
- nil, nil, nil, 165, nil, nil, nil, nil, nil, nil,
- nil, nil, 165, nil, 165, nil, nil, nil, 165, nil,
- nil, nil, nil, nil, nil, nil, nil, 165, nil, nil,
- 165, 165, 165, 165, 165, 165, 165, 165, 165, 166,
- nil, nil, nil, 166, nil, 166, nil, 166, 166, nil,
- nil, nil, 166, nil, nil, nil, nil, nil, nil, nil,
- nil, 166, nil, 166, nil, nil, nil, 166, nil, nil,
- nil, nil, nil, nil, nil, nil, 166, nil, nil, 166,
- 166, 166, 166, 166, 166, 166, 166, 166, 192, nil,
- nil, nil, 192, nil, 192, nil, 192, 192, nil, nil,
- nil, 192, nil, nil, nil, nil, nil, nil, nil, nil,
- 192, nil, 192, nil, nil, nil, 192, nil, nil, nil,
- nil, nil, nil, nil, nil, 192, nil, nil, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 195, nil, nil,
- nil, 195, nil, 195, nil, 195, 195, nil, nil, nil,
- 195, nil, nil, nil, nil, nil, nil, nil, nil, 195,
- nil, 195, nil, nil, nil, 195, nil, nil, nil, nil,
- nil, nil, nil, nil, 195, nil, nil, 195, 195, 195,
- 195, 195, 195, 195, 195, 195, 253, nil, nil, nil,
- 253, nil, 253, nil, 253, 253, nil, nil, nil, 253,
- nil, nil, nil, nil, nil, nil, nil, nil, 253, nil,
- 253, nil, nil, nil, 253, nil, nil, nil, nil, nil,
- nil, nil, 253, 253, nil, nil, 253, 253, 253, 253,
- 253, 253, 253, 253, 253, 254, nil, nil, nil, 254,
- nil, 254, nil, 254, 254, nil, nil, nil, 254, nil,
- nil, nil, nil, nil, nil, nil, nil, 254, nil, 254,
- nil, nil, nil, 254, nil, nil, nil, nil, nil, nil,
- nil, 254, 254, nil, nil, 254, 254, 254, 254, 254,
- 254, 254, 254, 254, 255, nil, nil, nil, 255, nil,
- 255, nil, 255, 255, nil, nil, nil, 255, nil, nil,
- nil, nil, nil, nil, nil, nil, 255, nil, 255, nil,
- nil, nil, 255, nil, nil, nil, nil, nil, nil, nil,
- 255, 255, nil, nil, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 258, nil, nil, nil, 258, nil, 258,
- nil, 258, 258, nil, nil, nil, 258, nil, nil, nil,
- nil, nil, nil, nil, nil, 258, nil, 258, nil, nil,
- nil, 258, nil, nil, nil, nil, nil, nil, nil, 258,
- 258, nil, nil, 258, 258, 258, 258, 258, 258, 258,
- 258, 258, 260, nil, nil, nil, 260, nil, 260, nil,
- 260, 260, nil, nil, nil, 260, nil, nil, nil, nil,
- nil, nil, nil, nil, 260, nil, 260, nil, nil, nil,
- 260, nil, nil, nil, nil, nil, nil, nil, nil, 260,
- nil, nil, 260, 260, 260, 260, 260, 260, 260, 260,
- 260, 262, nil, nil, nil, 262, nil, 262, nil, 262,
- 262, nil, nil, nil, 262, nil, nil, nil, nil, nil,
- nil, nil, nil, 262, nil, 262, nil, nil, nil, 262,
- nil, nil, nil, nil, nil, nil, nil, nil, 262, nil,
- nil, 262, 262, 262, 262, 262, 262, 262, 262, 262,
- 267, nil, nil, nil, 267, nil, 267, nil, 267, 267,
- nil, nil, nil, 267, nil, nil, nil, nil, nil, nil,
- nil, nil, 267, nil, 267, nil, nil, nil, 267, nil,
- nil, nil, nil, nil, nil, nil, 267, 267, nil, nil,
- 267, 267, 267, 267, 267, 267, 267, 267, 267, 268,
- nil, nil, nil, 268, nil, 268, nil, 268, 268, nil,
- nil, nil, 268, nil, nil, nil, nil, nil, nil, nil,
- nil, 268, nil, 268, nil, nil, nil, 268, nil, nil,
- nil, nil, nil, nil, nil, 268, 268, nil, nil, 268,
- 268, 268, 268, 268, 268, 268, 268, 268, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 241, 241, 241, 241,
- 241, 241, 241, 241, 241, 241, 241, nil, nil, nil,
- 241, nil, nil, nil, 49, 49, nil, nil, nil, 49,
- nil, nil, nil, 79, 79, nil, nil, nil, 79, 76,
- 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
- 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
- 76, 76, nil, nil, nil, 76, nil, nil, nil, nil,
- nil, nil, nil, 76, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 135, 135, 135, 135, 135, 135, nil, nil, nil,
- 135, nil, nil, nil, nil, nil, nil, nil, 135, 264,
- 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
- 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
- 264, 264, nil, nil, nil, 264, nil, nil, nil, nil,
- nil, nil, nil, 264, 285, 285, 285, 285, 285, 285,
- 285, 285, 285, 285, 285, 285, 285, 285, 285, 285,
- 285, 285, 285, 285, 285, 285, 285, nil, nil, nil,
- 285, nil, nil, nil, nil, nil, nil, nil, 285, 168,
- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
- 168, 168, nil, nil, nil, 168, nil, nil, nil, nil,
- nil, nil, 168, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, nil, nil, nil, 194,
- nil, nil, nil, nil, nil, nil, 194, 196, 196, 196,
- 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
- 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
- nil, nil, nil, 196, nil, nil, nil, nil, nil, nil,
- 196, 261, 261, 261, 261, 261, 261, 261, 261, 261,
- 261, 261, 261, 261, 261, 261, 261, 261, 261, 261,
- 261, 261, 261, 261, nil, nil, nil, 261, nil, nil,
- nil, nil, nil, nil, 261, 287, 287, 287, 287, 287,
- 287, 287, 287, 287, 287, 287, 287, 287, 287, 287,
- 287, 287, 287, 287, 287, 287, 287, 287, nil, nil,
- nil, 287, 0, 0, 0, 0, 0, nil, 287, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, nil,
- 0, 0, 0, 0, nil, 0, nil, 0, 3, 3,
- 3, 3, 3, nil, 0, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, nil, 3, 3, 3, 3,
- nil, 3, nil, 3, 43, 43, 43, nil, nil, nil,
- 3, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, nil, 43, nil, 43,
- 47, 47, 47, nil, nil, nil, 43, 47, 47, 47,
- 47, 47, 47, 47, 47, 47, 47, nil, 47, 47,
- 47, 47, nil, 47, nil, 47, 108, 108, 108, nil,
- nil, nil, 47, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, nil, 108, 108, 108, 108, nil, 108,
- nil, 108, 263, 263, 263, nil, nil, nil, 108, 263,
- 263, 263, 263, 263, 263, 263, 263, 263, 263, nil,
- 263, 263, 263, 263, nil, 263, nil, 263, 265, 265,
- 265, nil, nil, nil, 263, 265, 265, 265, 265, 265,
- 265, 265, 265, 265, 265, nil, 265, 265, 265, 265,
- nil, 265, nil, 265, 286, 286, 286, nil, nil, nil,
- 265, 286, 286, 286, 286, 286, 286, 286, 286, 286,
- 286, nil, 286, 286, 286, 286, nil, 286, nil, 286,
- 299, 299, 299, nil, nil, nil, 286, 299, 299, 299,
- 299, 299, 299, 299, 299, 299, 299, nil, 299, 299,
- 299, 299, nil, 299, nil, 299, 300, 300, 300, nil,
- nil, nil, 299, 300, 300, 300, 300, 300, 300, 300,
- 300, 300, 300, nil, 300, 300, 300, 300, nil, 300,
- nil, 300, 306, 306, 306, nil, nil, nil, 300, 306,
- 306, 306, 306, 306, 306, 306, 306, 306, 306, nil,
- 306, 306, 306, 306, nil, 306, nil, 306, nil, nil,
- nil, nil, nil, nil, 306, 180, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
- 180, 180, 180, 180, 180, 180, 180, 180, nil, nil,
- nil, 180, 197, 197, 197, 197, 197, 197, 197, 197,
- 197, 197, 197, 197, 197, 197, 197, 197, 197, 197,
- 197, 197, 197, 197, 197, nil, nil, nil, 197, 199,
- 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
- 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
- 199, 199, nil, nil, nil, 199, 200, 200, 200, 200,
- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
- 200, 200, 200, 200, 200, 200, 200, 200, 200, nil,
- nil, nil, 200, 201, 201, 201, 201, 201, 201, 201,
- 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
- 201, 201, 201, 201, 201, 201, nil, nil, nil, 201,
- 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
- 202, 202, 202, 202, 202, 202, 202, 202, 202, 202,
- 202, 202, 202, nil, nil, nil, 202, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
- nil, nil, nil, 203, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, nil, nil, nil,
- 204, 205, 205, 205, 205, 205, 205, 205, 205, 205,
- 205, 205, 205, 205, 205, 205, 205, 205, 205, 205,
- 205, 205, 205, 205, nil, nil, nil, 205, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, nil, nil, nil, 206, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, nil, nil,
- nil, 209, 222, 222, 222, 222, 222, 222, 222, 222,
- 222, 222, 222, 222, 222, 222, 222, 222, 222, 222,
- 222, 222, 222, 222, 222, nil, nil, nil, 222, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
- 277, 277, nil, nil, nil, 277, 279, 279, 279, 279,
- 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
- 279, 279, 279, 279, 279, 279, 279, 279, 279, nil,
- nil, nil, 279, 281, 281, 281, 281, 281, 281, 281,
- 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
- 281, 281, 281, 281, 281, 281, nil, nil, nil, 281,
- 291, 291, 291, 291, 291, 291, 291, 291, 291, 291,
- 291, 291, 291, 291, 291, 291, 291, 291, 291, 291,
- 291, 291, 291, nil, nil, nil, 291, 228, 228, 228,
- 228, 228, 228, 228, 228, 228, 228, 228, 228, 228,
- 228, 228, 228, 228, 228, 228, 228, 228, 228, nil,
- nil, nil, 228, 227, 227, 227, 227, 227, 227, 227,
- 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
- 227, 227, 227, 227, nil, nil, nil, 227, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242, 242, nil,
- nil, nil, 242, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, nil, nil, nil, 243, 244, 244,
- 244, 244, 244, 244, 244, 244, 244, 244, 244, nil,
- nil, nil, 244, 245, 245, 245, 245, 245, 245, 245,
- 245, 245, 245, 245, nil, nil, nil, 245, 246, 246,
- 246, 246, 246, 246, 246, 246, 246, 246, 246, nil,
- nil, nil, 246, 247, 247, 247, 247, 247, 247, 247,
- 247, 247, 247, 247, nil, nil, nil, 247, 248, 248,
- 248, 248, 248, 248, 248, 248, 248, 248, 248, nil,
- nil, nil, 248, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, 249, 249, nil, nil, nil, 249, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, nil,
- nil, nil, 250, 237, 237, 237, 237, 237, 237, 237,
- 237, 237, 237, nil, nil, nil, 237, 236, 236, 236,
- 236, 236, 236, 236, 236, 236, nil, nil, nil, 236 ]
-
-racc_action_pointer = [
- 3034, 33, nil, 3060, 109, nil, nil, nil, nil, nil,
- -5, -28, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, -2, 9, -6, 13, 47, nil, -17, 50, 59,
- 65, -8, -7, 3086, 68, -18, 80, 3112, 81, 2716,
- 35, 74, 15, nil, nil, nil, 128, nil, nil, nil,
- nil, nil, 88, nil, nil, nil, 42, nil, nil, 88,
- 133, 72, nil, -28, 30, 93, 2758, 96, nil, 2725,
- 91, 140, 189, 238, nil, nil, nil, nil, nil, nil,
- 86, nil, nil, nil, 84, 129, 287, nil, nil, nil,
- nil, nil, nil, nil, nil, 108, 105, nil, 3138, 52,
- 129, 138, 336, 111, 385, 434, 483, 532, 581, 630,
- 679, 728, 777, 826, 875, nil, nil, nil, nil, nil,
- 924, 139, 19, nil, 31, 2793, nil, 973, 168, 131,
- 133, nil, nil, 1022, 1071, 1120, 1169, 1218, 1267, 1316,
- 1365, 1414, 1463, 1512, 1561, 1610, 1659, 1708, 1757, 1806,
- 1855, 1904, 1953, 2002, 2051, 2100, 2149, nil, 2898, 143,
- 145, 148, 309, nil, 122, 124, 125, 128, 140, nil,
- 3354, nil, 156, 154, nil, nil, nil, 179, nil, nil,
- nil, nil, 2198, 171, 2932, 2247, 2966, 3381, nil, 3408,
- 3435, 3462, 3489, 3516, 3543, 3570, 3597, 187, nil, 3624,
- 10, nil, 168, -11, nil, nil, 190, 181, 187, nil,
- 172, nil, 3651, nil, nil, 195, 197, 3810, 3785, 66,
- 115, 207, 209, 221, 232, 256, 3972, 3959, 269, 303,
- 319, 2713, 3825, 3840, 3855, 3870, 3885, 3900, 3915, 3930,
- 3945, nil, 201, 2296, 2345, 2394, 178, nil, 2443, nil,
- 2492, 3000, 2541, 3164, 2828, 3190, nil, 2590, 2639, nil,
- 217, nil, nil, 3, nil, nil, 324, 3678, nil, 3705,
- nil, 3732, nil, nil, nil, 2863, 3216, 3034, 213, nil,
- nil, 3759, nil, nil, nil, nil, 206, 101, nil, 3242,
- 3268, 358, 234, nil, nil, nil, 3294, nil ]
-
-racc_action_default = [
- -2, -172, -1, -4, -172, -6, -8, -9, -10, -11,
- -172, -172, -15, -16, -17, -18, -19, -20, -22, -23,
- -24, -25, -26, -27, -28, -29, -30, -31, -32, -33,
- -34, -172, -172, -172, -172, -172, -40, -172, -172, -172,
- -172, -172, -172, -172, -172, -172, -172, -172, -172, -172,
- -172, -172, -128, -160, -161, -162, -172, -3, -5, -7,
- -21, -12, -172, -35, -36, -37, -172, -38, -39, -172,
- -157, -159, -42, -172, -172, -172, -172, -172, -49, -108,
- -172, -172, -172, -172, -93, -94, -105, -106, -107, -109,
- -110, -111, -112, -113, -172, -172, -172, -163, -164, -165,
- -166, -167, -169, -170, -171, -172, -172, -51, -154, -138,
- -172, -172, -172, -172, -172, -172, -172, -172, -172, -172,
- -172, -172, -172, -172, -172, -72, -74, -71, -73, -127,
- -172, -172, -142, 308, -172, -172, -41, -172, -172, -172,
- -172, -45, -47, -172, -172, -172, -172, -172, -172, -172,
- -172, -172, -172, -172, -172, -172, -172, -172, -172, -172,
- -172, -172, -172, -172, -172, -172, -172, -48, -172, -77,
- -81, -82, -172, -129, -172, -172, -172, -126, -172, -133,
- -143, -144, -146, -172, -148, -50, -153, -172, -134, -135,
- -136, -137, -172, -172, -172, -172, -172, -59, -60, -61,
- -62, -63, -64, -65, -66, -67, -68, -172, -70, -116,
- -128, -117, -131, -172, -140, -141, -172, -172, -172, -150,
- -152, -46, -155, -156, -158, -172, -172, -76, -78, -79,
- -80, -83, -84, -85, -86, -87, -88, -89, -90, -91,
- -92, -95, -96, -97, -98, -99, -100, -101, -102, -103,
- -104, -75, -172, -172, -172, -172, -125, -132, -172, -147,
- -172, -172, -172, -172, -172, -172, -69, -172, -172, -139,
- -172, -14, -149, -172, -43, -44, -172, -118, -121, -119,
- -122, -120, -123, -124, -145, -172, -172, -172, -55, -57,
- -58, -114, -115, -130, -13, -151, -172, -138, -53, -172,
- -172, -172, -172, -54, -56, -168, -172, -52 ]
-
-racc_goto_table = [
- 31, 187, 62, 31, 175, 33, 77, 183, 33, 178,
- 35, 139, 140, 35, 207, 38, 216, 106, 38, 60,
- 69, 1, 271, 59, 75, 58, 215, 49, 70, 61,
- 49, 108, 70, 174, 2, 113, 110, 57, nil, nil,
- nil, nil, nil, 31, nil, nil, nil, 31, 33, nil,
- nil, nil, 33, 35, nil, nil, nil, 35, 38, nil,
- nil, nil, 38, nil, nil, nil, nil, nil, nil, nil,
- 49, nil, nil, nil, 49, 294, nil, 127, 128, 198,
- nil, 252, 186, nil, nil, 173, 176, nil, 211, nil,
- nil, nil, nil, nil, nil, nil, 108, nil, nil, nil,
- nil, 223, 193, nil, nil, nil, nil, nil, 31, 188,
- nil, nil, nil, 33, 189, 210, nil, nil, 35, 190,
- 60, 224, 214, 38, 191, 219, nil, nil, nil, 70,
- nil, nil, nil, nil, nil, 49, 49, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 295, nil, nil, 293, nil,
- nil, nil, nil, nil, nil, 175, nil, nil, nil, 284,
- 283, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 296, nil, nil, nil, 302,
- nil, nil, nil, nil, 174, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 272,
- 305, nil, nil, nil, nil, nil, nil, 278, 280, 282,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 292, 211, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 176, nil, nil,
- nil, 288, nil, 290, nil, nil, nil, nil, nil, 210,
- nil, nil, nil, 31, 219, 31, nil, nil, 33, nil,
- 33, nil, nil, 35, 298, 35, nil, nil, 38, 76,
- 38, nil, nil, nil, nil, nil, 31, 303, 304, nil,
- 49, 33, 49, nil, 307, nil, 35, 188, nil, 31,
- 31, 38, 189, 135, 33, 33, 31, 190, nil, 35,
- 35, 33, 191, 49, 38, 38, 35, 168, 169, 170,
- 171, 38, nil, nil, 49, nil, 49, 49, nil, nil,
- nil, nil, nil, 49, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 194,
- nil, 196, 197, 199, 200, 201, 202, 203, 204, 205,
- 206, 209, nil, nil, nil, nil, nil, 213, nil, nil,
- nil, nil, nil, nil, 222, nil, nil, nil, nil, nil,
- 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
- 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
- 247, 248, 249, 250, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 261,
- nil, nil, 264, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 277, 279, 281, nil, nil, nil, nil, 285, nil, 287,
- nil, nil, nil, nil, 291, 209 ]
-
-racc_goto_check = [
- 30, 39, 9, 30, 43, 31, 37, 53, 31, 49,
- 32, 35, 35, 32, 41, 34, 10, 38, 34, 18,
- 33, 1, 11, 5, 33, 4, 50, 40, 9, 5,
- 40, 6, 9, 35, 2, 6, 9, 2, nil, nil,
- nil, nil, nil, 30, nil, nil, nil, 30, 31, nil,
- nil, nil, 31, 32, nil, nil, nil, 32, 34, nil,
- nil, nil, 34, nil, nil, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, 40, 11, nil, 40, 40, 37,
- nil, 43, 38, nil, nil, 9, 9, nil, 37, nil,
- nil, nil, nil, nil, nil, nil, 6, nil, nil, nil,
- nil, 37, 9, nil, nil, nil, nil, nil, 30, 30,
- nil, nil, nil, 31, 31, 9, nil, nil, 32, 32,
- 18, 33, 9, 34, 34, 9, nil, nil, nil, 9,
- nil, nil, nil, nil, nil, 40, 40, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 10, nil, nil, 41, nil,
- nil, nil, nil, nil, nil, 43, nil, nil, nil, 53,
- 49, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 43, nil, nil, nil, 39,
- nil, nil, nil, nil, 35, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 9,
- 43, nil, nil, nil, nil, nil, nil, 37, 37, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 37, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 9, nil, nil,
- nil, 6, nil, 6, nil, nil, nil, nil, nil, 9,
- nil, nil, nil, 30, 9, 30, nil, nil, 31, nil,
- 31, nil, nil, 32, 6, 32, nil, nil, 34, 36,
- 34, nil, nil, nil, nil, nil, 30, 6, 6, nil,
- 40, 31, 40, nil, 6, nil, 32, 30, nil, 30,
- 30, 34, 31, 36, 31, 31, 30, 32, nil, 32,
- 32, 31, 34, 40, 34, 34, 32, 36, 36, 36,
- 36, 34, nil, nil, 40, nil, 40, 40, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 36,
- nil, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, nil, nil, nil, nil, nil, 36, nil, nil,
- nil, nil, nil, nil, 36, nil, nil, nil, nil, nil,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 36,
- nil, nil, 36, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, 36, 36, nil, nil, nil, nil, 36, nil, 36,
- nil, nil, nil, nil, 36, 36 ]
-
-racc_goto_pointer = [
- nil, 21, 34, nil, 21, 19, -12, nil, nil, -9,
- -118, -195, nil, nil, nil, nil, nil, nil, 15, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 0, 5, 10, -17, 15, -62, 237, -36, -26, -108,
- 27, -110, nil, -91, nil, nil, nil, nil, nil, -86,
- -106, nil, nil, -89, nil, nil ]
-
-racc_goto_default = [
- nil, nil, nil, 3, 5, 6, 7, 8, 9, 52,
- nil, 25, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 26, 27, 28, 29, 30,
- 86, 88, 85, nil, 84, 87, 180, 181, nil, nil,
- 79, nil, 89, 90, 91, 92, 93, 212, 177, nil,
- 129, 132, 182, nil, 220, 71 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 80, :_reduce_1,
- 0, 80, :_reduce_2,
- 2, 81, :_reduce_3,
- 1, 81, :_reduce_4,
- 2, 82, :_reduce_5,
- 1, 82, :_reduce_6,
- 2, 82, :_reduce_7,
- 1, 82, :_reduce_8,
- 1, 82, :_reduce_9,
- 1, 85, :_reduce_10,
- 1, 85, :_reduce_11,
- 2, 83, :_reduce_12,
- 6, 84, :_reduce_13,
- 5, 84, :_reduce_14,
- 1, 86, :_reduce_15,
- 1, 86, :_reduce_16,
- 1, 86, :_reduce_17,
- 1, 86, :_reduce_18,
- 1, 86, :_reduce_19,
- 1, 86, :_reduce_20,
- 2, 86, :_reduce_21,
- 1, 86, :_reduce_22,
- 1, 86, :_reduce_23,
- 1, 86, :_reduce_24,
- 1, 86, :_reduce_25,
- 1, 86, :_reduce_26,
- 1, 86, :_reduce_27,
- 1, 86, :_reduce_28,
- 1, 87, :_reduce_29,
- 1, 87, :_reduce_30,
- 1, 87, :_reduce_31,
- 1, 87, :_reduce_32,
- 1, 87, :_reduce_33,
- 1, 87, :_reduce_34,
- 2, 91, :_reduce_35,
- 2, 92, :_reduce_36,
- 2, 93, :_reduce_37,
- 2, 94, :_reduce_38,
- 2, 95, :_reduce_39,
- 1, 96, :_reduce_40,
- 3, 97, :_reduce_41,
- 2, 100, :_reduce_42,
- 5, 98, :_reduce_43,
- 5, 99, :_reduce_44,
- 3, 101, :_reduce_45,
- 4, 102, :_reduce_46,
- 3, 103, :_reduce_47,
- 3, 103, :_reduce_48,
- 2, 103, :_reduce_49,
- 3, 90, :_reduce_50,
- 2, 90, :_reduce_51,
- 9, 104, :_reduce_52,
- 6, 105, :_reduce_53,
- 7, 105, :_reduce_54,
- 5, 106, :_reduce_55,
- 7, 106, :_reduce_56,
- 5, 107, :_reduce_57,
- 5, 108, :_reduce_58,
- 3, 109, :_reduce_59,
- 3, 109, :_reduce_60,
- 3, 109, :_reduce_61,
- 3, 109, :_reduce_62,
- 3, 109, :_reduce_63,
- 3, 109, :_reduce_64,
- 3, 109, :_reduce_65,
- 3, 109, :_reduce_66,
- 3, 109, :_reduce_67,
- 3, 109, :_reduce_68,
- 4, 110, :_reduce_69,
- 3, 110, :_reduce_70,
- 2, 111, :_reduce_71,
- 2, 111, :_reduce_72,
- 2, 113, :_reduce_73,
- 2, 113, :_reduce_74,
- 3, 115, :_reduce_75,
- 3, 115, :_reduce_76,
- 2, 115, :_reduce_77,
- 3, 115, :_reduce_78,
- 3, 115, :_reduce_79,
- 3, 115, :_reduce_80,
- 2, 115, :_reduce_81,
- 2, 115, :_reduce_82,
- 3, 115, :_reduce_83,
- 3, 115, :_reduce_84,
- 3, 115, :_reduce_85,
- 3, 115, :_reduce_86,
- 3, 115, :_reduce_87,
- 3, 115, :_reduce_88,
- 3, 115, :_reduce_89,
- 3, 115, :_reduce_90,
- 3, 115, :_reduce_91,
- 3, 115, :_reduce_92,
- 1, 115, :_reduce_93,
- 1, 115, :_reduce_94,
- 3, 115, :_reduce_95,
- 3, 115, :_reduce_96,
- 3, 115, :_reduce_97,
- 3, 115, :_reduce_98,
- 3, 115, :_reduce_99,
- 3, 115, :_reduce_100,
- 3, 115, :_reduce_101,
- 3, 115, :_reduce_102,
- 3, 115, :_reduce_103,
- 3, 115, :_reduce_104,
- 1, 115, :_reduce_105,
- 1, 115, :_reduce_106,
- 1, 115, :_reduce_107,
- 1, 115, :_reduce_108,
- 1, 115, :_reduce_109,
- 1, 115, :_reduce_110,
- 1, 115, :_reduce_111,
- 1, 115, :_reduce_112,
- 1, 115, :_reduce_113,
- 3, 126, :_reduce_114,
- 3, 126, :_reduce_115,
- 1, 126, :_reduce_116,
- 1, 126, :_reduce_117,
- 3, 127, :_reduce_118,
- 3, 127, :_reduce_119,
- 3, 127, :_reduce_120,
- 3, 127, :_reduce_121,
- 3, 127, :_reduce_122,
- 3, 127, :_reduce_123,
- 3, 128, :_reduce_124,
- 2, 128, :_reduce_125,
- 1, 128, :_reduce_126,
- 2, 119, :_reduce_127,
- 1, 119, :_reduce_128,
- 2, 116, :_reduce_129,
- 3, 120, :_reduce_130,
- 1, 120, :_reduce_131,
- 3, 125, :_reduce_132,
- 2, 125, :_reduce_133,
- 1, 118, :_reduce_134,
- 1, 118, :_reduce_135,
- 1, 118, :_reduce_136,
- 1, 118, :_reduce_137,
- 0, 118, :_reduce_138,
- 3, 130, :_reduce_139,
- 2, 130, :_reduce_140,
- 2, 129, :_reduce_141,
- 1, 129, :_reduce_142,
- 1, 131, :_reduce_143,
- 1, 131, :_reduce_144,
- 3, 132, :_reduce_145,
- 1, 132, :_reduce_146,
- 3, 124, :_reduce_147,
- 2, 124, :_reduce_148,
- 2, 133, :_reduce_149,
- 1, 133, :_reduce_150,
- 3, 89, :_reduce_151,
- 1, 89, :_reduce_152,
- 2, 117, :_reduce_153,
- 1, 117, :_reduce_154,
- 3, 134, :_reduce_155,
- 3, 134, :_reduce_156,
- 1, 134, :_reduce_157,
- 3, 112, :_reduce_158,
- 1, 112, :_reduce_159,
- 1, 88, :_reduce_160,
- 1, 88, :_reduce_161,
- 1, 88, :_reduce_162,
- 1, 122, :_reduce_163,
- 1, 122, :_reduce_164,
- 1, 122, :_reduce_165,
- 1, 122, :_reduce_166,
- 1, 122, :_reduce_167,
- 7, 121, :_reduce_168,
- 1, 114, :_reduce_169,
- 1, 114, :_reduce_170,
- 1, 123, :_reduce_171 ]
-
-racc_reduce_n = 172
-
-racc_shift_n = 308
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :ASS_EQ => 2,
- :ADD_EQ => 3,
- :SUB_EQ => 4,
- :MUL_EQ => 5,
- :DIV_EQ => 6,
- :MOD_EQ => 7,
- :SLL_EQ => 8,
- :SRA_EQ => 9,
- :SRL_EQ => 10,
- :OR => 11,
- :AND => 12,
- :CMP_LT => 13,
- :CMP_GT => 14,
- :CMP_EQ => 15,
- :CMP_NE => 16,
- :CMP_GE => 17,
- :CMP_LE => 18,
- :SUBSTR_EQ => 19,
- :SUBSTR_NE => 20,
- :REGEX_EQ => 21,
- :REGEX_NE => 22,
- :BIT_OR => 23,
- :BIT_XOR => 24,
- :AMPERSAND => 25,
- :BIT_SRA => 26,
- :BIT_SRL => 27,
- :BIT_SLL => 28,
- :ADD => 29,
- :SUB => 30,
- :MUL => 31,
- :DIV => 32,
- :MOD => 33,
- :NOT => 34,
- :UMINUS => 35,
- :BIT_NOT => 36,
- :EXP => 37,
- :INCR => 38,
- :DECR => 39,
- :COMMENT => 40,
- :EXPORT => 41,
- :FUNCTION => 42,
- :LPAREN => 43,
- :RPAREN => 44,
- :SEMICOLON => 45,
- :BREAK => 46,
- :CONTINUE => 47,
- :GLOBAL => 48,
- :IMPORT => 49,
- :INCLUDE => 50,
- :LOCAL => 51,
- :REP => 52,
- :RETURN => 53,
- :LBRACE => 54,
- :RBRACE => 55,
- :FOR => 56,
- :FOREACH => 57,
- :IN => 58,
- :IF => 59,
- :ELSE => 60,
- :REPEAT => 61,
- :UNTIL => 62,
- :WHILE => 63,
- :COLON => 64,
- :COMMA => 65,
- :AT_SIGN => 66,
- :LBRACK => 67,
- :RBRACK => 68,
- :PERIOD => 69,
- :IDENT => 70,
- :INT_DEC => 71,
- :INT_HEX => 72,
- :INT_OCT => 73,
- :FALSE => 74,
- :TRUE => 75,
- :DATA => 76,
- :STRING => 77,
- :UNDEF => 78 }
-
-racc_nt_base = 79
-
-racc_use_result_var = false
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "ASS_EQ",
- "ADD_EQ",
- "SUB_EQ",
- "MUL_EQ",
- "DIV_EQ",
- "MOD_EQ",
- "SLL_EQ",
- "SRA_EQ",
- "SRL_EQ",
- "OR",
- "AND",
- "CMP_LT",
- "CMP_GT",
- "CMP_EQ",
- "CMP_NE",
- "CMP_GE",
- "CMP_LE",
- "SUBSTR_EQ",
- "SUBSTR_NE",
- "REGEX_EQ",
- "REGEX_NE",
- "BIT_OR",
- "BIT_XOR",
- "AMPERSAND",
- "BIT_SRA",
- "BIT_SRL",
- "BIT_SLL",
- "ADD",
- "SUB",
- "MUL",
- "DIV",
- "MOD",
- "NOT",
- "UMINUS",
- "BIT_NOT",
- "EXP",
- "INCR",
- "DECR",
- "COMMENT",
- "EXPORT",
- "FUNCTION",
- "LPAREN",
- "RPAREN",
- "SEMICOLON",
- "BREAK",
- "CONTINUE",
- "GLOBAL",
- "IMPORT",
- "INCLUDE",
- "LOCAL",
- "REP",
- "RETURN",
- "LBRACE",
- "RBRACE",
- "FOR",
- "FOREACH",
- "IN",
- "IF",
- "ELSE",
- "REPEAT",
- "UNTIL",
- "WHILE",
- "COLON",
- "COMMA",
- "AT_SIGN",
- "LBRACK",
- "RBRACK",
- "PERIOD",
- "IDENT",
- "INT_DEC",
- "INT_HEX",
- "INT_OCT",
- "FALSE",
- "TRUE",
- "DATA",
- "STRING",
- "UNDEF",
- "$start",
- "start",
- "roots",
- "root",
- "export",
- "function",
- "statement",
- "simple",
- "compound",
- "ident",
- "params",
- "block",
- "assign",
- "break",
- "call",
- "continue",
- "decr",
- "empty",
- "global",
- "import",
- "include",
- "incr",
- "local",
- "rep",
- "return",
- "for",
- "foreach",
- "if",
- "repeat",
- "while",
- "assign_exp",
- "call_exp",
- "decr_exp",
- "var_decls",
- "incr_exp",
- "string",
- "expr",
- "ref",
- "statements",
- "field",
- "lval",
- "args",
- "ip",
- "int",
- "undef",
- "list_expr",
- "array_expr",
- "arg",
- "kv_pair",
- "kv_pairs",
- "indexes",
- "index",
- "list_elem",
- "list_elems",
- "param",
- "var_decl" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'nasl.y', 61)
- def _reduce_1(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 63)
- def _reduce_2(val, _values)
- []
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 67)
- def _reduce_3(val, _values)
- [val[0]] + val[1]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 69)
- def _reduce_4(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 73)
- def _reduce_5(val, _values)
- c(*val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 75)
- def _reduce_6(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 77)
- def _reduce_7(val, _values)
- c(*val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 79)
- def _reduce_8(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 81)
- def _reduce_9(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 85)
- def _reduce_10(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 87)
- def _reduce_11(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 95)
- def _reduce_12(val, _values)
- n(:Export, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 99)
- def _reduce_13(val, _values)
- n(:Function, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 101)
- def _reduce_14(val, _values)
- n(:Function, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 105)
- def _reduce_15(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 107)
- def _reduce_16(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 109)
- def _reduce_17(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 111)
- def _reduce_18(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 113)
- def _reduce_19(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 115)
- def _reduce_20(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 117)
- def _reduce_21(val, _values)
- c(*val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 119)
- def _reduce_22(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 121)
- def _reduce_23(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 123)
- def _reduce_24(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 125)
- def _reduce_25(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 127)
- def _reduce_26(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 129)
- def _reduce_27(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 131)
- def _reduce_28(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 135)
- def _reduce_29(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 137)
- def _reduce_30(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 139)
- def _reduce_31(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 141)
- def _reduce_32(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 143)
- def _reduce_33(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 145)
- def _reduce_34(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 153)
- def _reduce_35(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 157)
- def _reduce_36(val, _values)
- n(:Break, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 161)
- def _reduce_37(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 165)
- def _reduce_38(val, _values)
- n(:Continue, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 169)
- def _reduce_39(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 173)
- def _reduce_40(val, _values)
- n(:Empty, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 177)
- def _reduce_41(val, _values)
- n(:Global, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 181)
- def _reduce_42(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 185)
- def _reduce_43(val, _values)
- n(:Import, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 189)
- def _reduce_44(val, _values)
- n(:Include, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 193)
- def _reduce_45(val, _values)
- n(:Local, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 197)
- def _reduce_46(val, _values)
- n(:Repetition, *val[0..-1])
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 201)
- def _reduce_47(val, _values)
- n(:Return, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 203)
- def _reduce_48(val, _values)
- n(:Return, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 205)
- def _reduce_49(val, _values)
- n(:Return, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 213)
- def _reduce_50(val, _values)
- n(:Block, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 215)
- def _reduce_51(val, _values)
- n(:Block, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 219)
- def _reduce_52(val, _values)
- n(:For, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 223)
- def _reduce_53(val, _values)
- n(:Foreach, val[0], val[1], val[3], val[5])
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 225)
- def _reduce_54(val, _values)
- n(:Foreach, val[0], val[2], val[4], val[6])
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 229)
- def _reduce_55(val, _values)
- n(:If, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 231)
- def _reduce_56(val, _values)
- n(:If, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 235)
- def _reduce_57(val, _values)
- n(:Repeat, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 239)
- def _reduce_58(val, _values)
- n(:While, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 247)
- def _reduce_59(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 249)
- def _reduce_60(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 251)
- def _reduce_61(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 253)
- def _reduce_62(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 255)
- def _reduce_63(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 257)
- def _reduce_64(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 259)
- def _reduce_65(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 261)
- def _reduce_66(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 263)
- def _reduce_67(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 265)
- def _reduce_68(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 269)
- def _reduce_69(val, _values)
- n(:Call, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 271)
- def _reduce_70(val, _values)
- n(:Call, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 275)
- def _reduce_71(val, _values)
- n(:Decrement, val[0])
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 277)
- def _reduce_72(val, _values)
- n(:Decrement, val[0])
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 281)
- def _reduce_73(val, _values)
- n(:Increment, val[0])
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 283)
- def _reduce_74(val, _values)
- n(:Increment, val[0])
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 287)
- def _reduce_75(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 289)
- def _reduce_76(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 291)
- def _reduce_77(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 293)
- def _reduce_78(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 295)
- def _reduce_79(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 297)
- def _reduce_80(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 299)
- def _reduce_81(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 301)
- def _reduce_82(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 303)
- def _reduce_83(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 305)
- def _reduce_84(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 307)
- def _reduce_85(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 309)
- def _reduce_86(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 311)
- def _reduce_87(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 313)
- def _reduce_88(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 315)
- def _reduce_89(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 317)
- def _reduce_90(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 319)
- def _reduce_91(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 321)
- def _reduce_92(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 323)
- def _reduce_93(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 325)
- def _reduce_94(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 327)
- def _reduce_95(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 329)
- def _reduce_96(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 331)
- def _reduce_97(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 333)
- def _reduce_98(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 335)
- def _reduce_99(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 337)
- def _reduce_100(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 339)
- def _reduce_101(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 341)
- def _reduce_102(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 343)
- def _reduce_103(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 345)
- def _reduce_104(val, _values)
- n(:Expression, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 347)
- def _reduce_105(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 349)
- def _reduce_106(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 351)
- def _reduce_107(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 353)
- def _reduce_108(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 355)
- def _reduce_109(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 357)
- def _reduce_110(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 359)
- def _reduce_111(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 361)
- def _reduce_112(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 363)
- def _reduce_113(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 371)
- def _reduce_114(val, _values)
- n(:Argument, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 373)
- def _reduce_115(val, _values)
- n(:Argument, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 375)
- def _reduce_116(val, _values)
- n(:Argument, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 377)
- def _reduce_117(val, _values)
- n(:Argument, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 381)
- def _reduce_118(val, _values)
- n(:KeyValuePair, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 383)
- def _reduce_119(val, _values)
- n(:KeyValuePair, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 385)
- def _reduce_120(val, _values)
- n(:KeyValuePair, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 387)
- def _reduce_121(val, _values)
- n(:KeyValuePair, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 389)
- def _reduce_122(val, _values)
- n(:KeyValuePair, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 391)
- def _reduce_123(val, _values)
- n(:KeyValuePair, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 395)
- def _reduce_124(val, _values)
- [val[0]] + val[2]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 397)
- def _reduce_125(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 399)
- def _reduce_126(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 403)
- def _reduce_127(val, _values)
- n(:Lvalue, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 405)
- def _reduce_128(val, _values)
- n(:Lvalue, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 409)
- def _reduce_129(val, _values)
- n(:Reference, val[1])
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 417)
- def _reduce_130(val, _values)
- [val[0]] + val[2]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 419)
- def _reduce_131(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 423)
- def _reduce_132(val, _values)
- n(:Array, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 425)
- def _reduce_133(val, _values)
- n(:Array, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 429)
- def _reduce_134(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 431)
- def _reduce_135(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 433)
- def _reduce_136(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 435)
- def _reduce_137(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 437)
- def _reduce_138(val, _values)
- nil
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 441)
- def _reduce_139(val, _values)
- val[1]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 443)
- def _reduce_140(val, _values)
- val[1]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 447)
- def _reduce_141(val, _values)
- [val[0]] + val[1]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 449)
- def _reduce_142(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 453)
- def _reduce_143(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 455)
- def _reduce_144(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 459)
- def _reduce_145(val, _values)
- [val[0]] + val[2]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 461)
- def _reduce_146(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 465)
- def _reduce_147(val, _values)
- n(:List, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 467)
- def _reduce_148(val, _values)
- n(:List, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 471)
- def _reduce_149(val, _values)
- n(:Parameter, val[1], 'reference')
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 473)
- def _reduce_150(val, _values)
- n(:Parameter, val[0], 'value')
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 477)
- def _reduce_151(val, _values)
- [val[0]] + val[2]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 479)
- def _reduce_152(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 483)
- def _reduce_153(val, _values)
- [val[0]] + val[1]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 485)
- def _reduce_154(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 489)
- def _reduce_155(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 491)
- def _reduce_156(val, _values)
- n(:Assignment, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 493)
- def _reduce_157(val, _values)
- val[0]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 497)
- def _reduce_158(val, _values)
- [val[0]] + val[2]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 499)
- def _reduce_159(val, _values)
- [val[0]]
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 507)
- def _reduce_160(val, _values)
- n(:Identifier, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 509)
- def _reduce_161(val, _values)
- n(:Identifier, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 511)
- def _reduce_162(val, _values)
- n(:Identifier, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 515)
- def _reduce_163(val, _values)
- n(:Integer, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 517)
- def _reduce_164(val, _values)
- n(:Integer, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 519)
- def _reduce_165(val, _values)
- n(:Integer, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 521)
- def _reduce_166(val, _values)
- n(:Integer, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 523)
- def _reduce_167(val, _values)
- n(:Integer, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 527)
- def _reduce_168(val, _values)
- n(:Ip, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 530)
- def _reduce_169(val, _values)
- n(:String, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 532)
- def _reduce_170(val, _values)
- n(:String, *val)
- end
-.,.,
-
-module_eval(<<'.,.,', 'nasl.y', 536)
- def _reduce_171(val, _values)
- n(:Undefined, *val)
- end
-.,.,
-
-def _reduce_none(val, _values)
- val[0]
-end
-
- end # class Grammar
-end # module Nasl
-
-
diff --git a/test/racc/regress/nokogiri-css b/test/racc/regress/nokogiri-css
deleted file mode 100644
index bc2faf8702..0000000000
--- a/test/racc/regress/nokogiri-css
+++ /dev/null
@@ -1,836 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-
-require 'nokogiri/css/parser_extras'
-module Nokogiri
- module CSS
- class Parser < Racc::Parser
-##### State transition tables begin ###
-
-racc_action_table = [
- 24, 93, 56, 57, 33, 55, 94, 23, 24, 22,
- 12, 93, 33, 27, 35, 52, 44, 22, -23, 25,
- 45, 98, 23, 33, 26, 18, 20, 25, 27, -23,
- 23, 24, 26, 18, 20, 33, 27, 11, 39, 24,
- 22, 23, 74, 33, 18, 91, 90, 27, 22, 12,
- 25, 24, -23, 23, 85, 26, 18, 20, 25, 27,
- 66, 23, 24, 26, 18, 20, 33, 27, 101, 100,
- 51, 22, 86, 88, 24, 26, 56, 87, 89, 60,
- 92, 25, 95, 46, 23, 49, 26, 18, 20, 90,
- 27, 33, 33, 51, 96, 99, 56, 58, 26, 60,
- 102, 103, 33, 33, 33, 93, 39, 39, 105, 23,
- 23, 108, 18, 18, 20, 27, 27, 39, 39, 39,
- 23, 23, 23, 18, 18, 18, 27, 27, 27, 33,
- 33, 56, 87, 109, 60, 22, 56, 87, nil, 60,
- 33, nil, nil, nil, 39, 39, nil, 23, 23, nil,
- 18, 18, 20, 27, 27, 39, 82, 83, 23, 56,
- 87, 18, 60, nil, 27, 82, 83, 78, 79, 80,
- nil, 81, nil, nil, nil, 77, 78, 79, 80, nil,
- 81, 4, 5, 10, 77, 4, 5, 43, nil, nil,
- nil, 6, nil, 8, 7, 6, nil, 8, 7, 4,
- 5, 10, nil, nil, nil, nil, nil, nil, nil, 6,
- nil, 8, 7 ]
-
-racc_action_check = [
- 3, 58, 24, 24, 3, 24, 57, 15, 9, 3,
- 64, 57, 9, 15, 11, 24, 18, 9, 58, 3,
- 21, 64, 3, 14, 3, 3, 3, 9, 3, 22,
- 9, 12, 9, 9, 9, 12, 9, 1, 14, 42,
- 12, 14, 45, 42, 14, 55, 55, 14, 42, 1,
- 12, 27, 46, 12, 49, 12, 12, 12, 42, 12,
- 27, 42, 43, 42, 42, 42, 43, 42, 76, 76,
- 27, 43, 50, 53, 23, 27, 51, 51, 54, 51,
- 56, 43, 59, 23, 43, 23, 43, 43, 43, 60,
- 43, 28, 25, 23, 61, 75, 25, 25, 23, 25,
- 84, 86, 29, 30, 31, 87, 28, 25, 91, 28,
- 25, 94, 28, 25, 25, 28, 25, 29, 30, 31,
- 29, 30, 31, 29, 30, 31, 29, 30, 31, 32,
- 39, 90, 90, 105, 90, 39, 92, 92, nil, 92,
- 62, nil, nil, nil, 32, 39, nil, 32, 39, nil,
- 32, 39, 39, 32, 39, 62, 47, 47, 62, 93,
- 93, 62, 93, nil, 62, 48, 48, 47, 47, 47,
- nil, 47, nil, nil, nil, 47, 48, 48, 48, nil,
- 48, 0, 0, 0, 48, 17, 17, 17, nil, nil,
- nil, 0, nil, 0, 0, 17, nil, 17, 17, 26,
- 26, 26, nil, nil, nil, nil, nil, nil, nil, 26,
- nil, 26, 26 ]
-
-racc_action_pointer = [
- 174, 37, nil, -2, nil, nil, nil, nil, nil, 6,
- nil, 14, 29, nil, 17, -17, nil, 178, 5, nil,
- nil, -9, 0, 72, -8, 86, 192, 49, 85, 96,
- 97, 98, 123, nil, nil, nil, nil, nil, nil, 124,
- nil, nil, 37, 60, nil, 31, 23, 153, 162, 29,
- 43, 66, nil, 50, 55, 34, 68, -1, -11, 59,
- 77, 71, 134, nil, -2, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 70, 58, nil, nil, nil,
- nil, nil, nil, nil, 75, nil, 90, 93, nil, nil,
- 121, 101, 126, 149, 98, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 120, nil, nil, nil, nil ]
-
-racc_action_default = [
- -74, -75, -2, -24, -4, -5, -6, -7, -8, -24,
- -73, -75, -24, -3, -47, -10, -13, -17, -75, -19,
- -20, -75, -22, -24, -75, -24, -74, -75, -53, -54,
- -55, -56, -57, -58, -14, 110, -1, -9, -46, -24,
- -11, -12, -24, -24, -18, -75, -29, -61, -61, -75,
- -75, -75, -30, -75, -75, -38, -39, -40, -22, -75,
- -38, -75, -70, -72, -75, -44, -45, -48, -49, -50,
- -51, -52, -15, -16, -21, -75, -75, -62, -63, -64,
- -65, -66, -67, -68, -75, -27, -75, -40, -31, -32,
- -75, -43, -75, -75, -75, -33, -69, -71, -34, -25,
- -59, -60, -26, -28, -35, -75, -36, -37, -42, -41 ]
-
-racc_goto_table = [
- 53, 38, 13, 1, 42, 48, 62, 37, 34, 65,
- 40, 36, 63, 75, 84, 67, 68, 69, 70, 71,
- 62, 41, 50, 47, 54, nil, 63, nil, nil, 64,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 72, 73, nil, nil, nil, nil, nil, nil, 97,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 104, nil, 106, 107 ]
-
-racc_goto_check = [
- 18, 12, 2, 1, 5, 9, 7, 8, 2, 9,
- 10, 2, 12, 17, 17, 12, 12, 12, 12, 12,
- 7, 11, 15, 16, 19, nil, 12, nil, nil, 1,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 2, 2, nil, nil, nil, nil, nil, nil, 12,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, 18, 18 ]
-
-racc_goto_pointer = [
- nil, 3, -1, nil, nil, -13, nil, -19, -7, -18,
- -5, 6, -13, nil, nil, -1, 0, -34, -24, 0,
- nil, nil, nil, nil ]
-
-racc_goto_default = [
- nil, nil, nil, 2, 3, 9, 17, 14, nil, 15,
- 31, 30, 16, 29, 19, 21, nil, nil, 59, nil,
- 28, 32, 76, 61 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 3, 32, :_reduce_1,
- 1, 32, :_reduce_2,
- 2, 32, :_reduce_3,
- 1, 36, :_reduce_4,
- 1, 36, :_reduce_5,
- 1, 36, :_reduce_6,
- 1, 36, :_reduce_7,
- 1, 36, :_reduce_8,
- 2, 37, :_reduce_9,
- 1, 37, :_reduce_none,
- 2, 37, :_reduce_11,
- 2, 37, :_reduce_12,
- 1, 37, :_reduce_13,
- 2, 34, :_reduce_14,
- 3, 33, :_reduce_15,
- 3, 33, :_reduce_16,
- 1, 33, :_reduce_none,
- 2, 44, :_reduce_18,
- 1, 38, :_reduce_none,
- 1, 38, :_reduce_20,
- 3, 45, :_reduce_21,
- 1, 45, :_reduce_22,
- 1, 46, :_reduce_23,
- 0, 46, :_reduce_none,
- 4, 42, :_reduce_25,
- 4, 42, :_reduce_26,
- 3, 42, :_reduce_27,
- 3, 47, :_reduce_28,
- 1, 47, :_reduce_29,
- 2, 40, :_reduce_30,
- 3, 40, :_reduce_31,
- 3, 40, :_reduce_32,
- 3, 40, :_reduce_33,
- 3, 40, :_reduce_34,
- 3, 49, :_reduce_35,
- 3, 49, :_reduce_36,
- 3, 49, :_reduce_37,
- 1, 49, :_reduce_none,
- 1, 49, :_reduce_none,
- 1, 49, :_reduce_40,
- 4, 50, :_reduce_41,
- 3, 50, :_reduce_42,
- 2, 50, :_reduce_43,
- 2, 41, :_reduce_44,
- 2, 41, :_reduce_45,
- 1, 39, :_reduce_none,
- 0, 39, :_reduce_none,
- 2, 43, :_reduce_48,
- 2, 43, :_reduce_49,
- 2, 43, :_reduce_50,
- 2, 43, :_reduce_51,
- 2, 43, :_reduce_52,
- 1, 43, :_reduce_none,
- 1, 43, :_reduce_none,
- 1, 43, :_reduce_none,
- 1, 43, :_reduce_none,
- 1, 43, :_reduce_none,
- 1, 51, :_reduce_58,
- 2, 48, :_reduce_59,
- 2, 48, :_reduce_60,
- 0, 48, :_reduce_none,
- 1, 53, :_reduce_62,
- 1, 53, :_reduce_63,
- 1, 53, :_reduce_64,
- 1, 53, :_reduce_65,
- 1, 53, :_reduce_66,
- 1, 53, :_reduce_67,
- 1, 53, :_reduce_68,
- 3, 52, :_reduce_69,
- 1, 54, :_reduce_none,
- 2, 54, :_reduce_none,
- 1, 54, :_reduce_none,
- 1, 35, :_reduce_none,
- 0, 35, :_reduce_none ]
-
-racc_reduce_n = 75
-
-racc_shift_n = 110
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :FUNCTION => 2,
- :INCLUDES => 3,
- :DASHMATCH => 4,
- :LBRACE => 5,
- :HASH => 6,
- :PLUS => 7,
- :GREATER => 8,
- :S => 9,
- :STRING => 10,
- :IDENT => 11,
- :COMMA => 12,
- :NUMBER => 13,
- :PREFIXMATCH => 14,
- :SUFFIXMATCH => 15,
- :SUBSTRINGMATCH => 16,
- :TILDE => 17,
- :NOT_EQUAL => 18,
- :SLASH => 19,
- :DOUBLESLASH => 20,
- :NOT => 21,
- :EQUAL => 22,
- :RPAREN => 23,
- :LSQUARE => 24,
- :RSQUARE => 25,
- :HAS => 26,
- "." => 27,
- "*" => 28,
- "|" => 29,
- ":" => 30 }
-
-racc_nt_base = 31
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "FUNCTION",
- "INCLUDES",
- "DASHMATCH",
- "LBRACE",
- "HASH",
- "PLUS",
- "GREATER",
- "S",
- "STRING",
- "IDENT",
- "COMMA",
- "NUMBER",
- "PREFIXMATCH",
- "SUFFIXMATCH",
- "SUBSTRINGMATCH",
- "TILDE",
- "NOT_EQUAL",
- "SLASH",
- "DOUBLESLASH",
- "NOT",
- "EQUAL",
- "RPAREN",
- "LSQUARE",
- "RSQUARE",
- "HAS",
- "\".\"",
- "\"*\"",
- "\"|\"",
- "\":\"",
- "$start",
- "selector",
- "simple_selector_1toN",
- "prefixless_combinator_selector",
- "optional_S",
- "combinator",
- "simple_selector",
- "element_name",
- "hcap_0toN",
- "function",
- "pseudo",
- "attrib",
- "hcap_1toN",
- "class",
- "namespaced_ident",
- "namespace",
- "attrib_name",
- "attrib_val_0or1",
- "expr",
- "nth",
- "attribute_id",
- "negation",
- "eql_incl_dash",
- "negation_arg" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 9)
- def _reduce_1(val, _values, result)
- result = [val.first, val.last].flatten
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 11)
- def _reduce_2(val, _values, result)
- result = val.flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 12)
- def _reduce_3(val, _values, result)
- result = [val.last].flatten
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 15)
- def _reduce_4(val, _values, result)
- result = :DIRECT_ADJACENT_SELECTOR
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 16)
- def _reduce_5(val, _values, result)
- result = :CHILD_SELECTOR
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 17)
- def _reduce_6(val, _values, result)
- result = :FOLLOWING_SELECTOR
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 18)
- def _reduce_7(val, _values, result)
- result = :DESCENDANT_SELECTOR
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 19)
- def _reduce_8(val, _values, result)
- result = :CHILD_SELECTOR
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 23)
- def _reduce_9(val, _values, result)
- result = if val[1].nil?
- val.first
- else
- Node.new(:CONDITIONAL_SELECTOR, [val.first, val[1]])
- end
-
- result
- end
-.,.,
-
-# reduce 10 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 31)
- def _reduce_11(val, _values, result)
- result = Node.new(:CONDITIONAL_SELECTOR, val)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 34)
- def _reduce_12(val, _values, result)
- result = Node.new(:CONDITIONAL_SELECTOR, val)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 37)
- def _reduce_13(val, _values, result)
- result = Node.new(:CONDITIONAL_SELECTOR,
- [Node.new(:ELEMENT_NAME, ['*']), val.first]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 44)
- def _reduce_14(val, _values, result)
- result = Node.new(val.first, [nil, val.last])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 49)
- def _reduce_15(val, _values, result)
- result = Node.new(val[1], [val.first, val.last])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 52)
- def _reduce_16(val, _values, result)
- result = Node.new(:DESCENDANT_SELECTOR, [val.first, val.last])
-
- result
- end
-.,.,
-
-# reduce 17 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 57)
- def _reduce_18(val, _values, result)
- result = Node.new(:CLASS_CONDITION, [val[1]])
- result
- end
-.,.,
-
-# reduce 19 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 61)
- def _reduce_20(val, _values, result)
- result = Node.new(:ELEMENT_NAME, val)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 65)
- def _reduce_21(val, _values, result)
- result = Node.new(:ELEMENT_NAME,
- [[val.first, val.last].compact.join(':')]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 70)
- def _reduce_22(val, _values, result)
- name = @namespaces.key?('xmlns') ? "xmlns:#{val.first}" : val.first
- result = Node.new(:ELEMENT_NAME, [name])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 75)
- def _reduce_23(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-# reduce 24 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 80)
- def _reduce_25(val, _values, result)
- result = Node.new(:ATTRIBUTE_CONDITION,
- [val[1]] + (val[2] || [])
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 85)
- def _reduce_26(val, _values, result)
- result = Node.new(:ATTRIBUTE_CONDITION,
- [val[1]] + (val[2] || [])
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 90)
- def _reduce_27(val, _values, result)
- # Non standard, but hpricot supports it.
- result = Node.new(:PSEUDO_CLASS,
- [Node.new(:FUNCTION, ['nth-child(', val[1]])]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 98)
- def _reduce_28(val, _values, result)
- result = Node.new(:ELEMENT_NAME,
- [[val.first, val.last].compact.join(':')]
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 103)
- def _reduce_29(val, _values, result)
- # Default namespace is not applied to attributes.
- # So we don't add prefix "xmlns:" as in namespaced_ident.
- result = Node.new(:ELEMENT_NAME, [val.first])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 110)
- def _reduce_30(val, _values, result)
- result = Node.new(:FUNCTION, [val.first.strip])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 113)
- def _reduce_31(val, _values, result)
- result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 116)
- def _reduce_32(val, _values, result)
- result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 119)
- def _reduce_33(val, _values, result)
- result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 122)
- def _reduce_34(val, _values, result)
- result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 126)
- def _reduce_35(val, _values, result)
- result = [val.first, val.last]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 127)
- def _reduce_36(val, _values, result)
- result = [val.first, val.last]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 128)
- def _reduce_37(val, _values, result)
- result = [val.first, val.last]
- result
- end
-.,.,
-
-# reduce 38 omitted
-
-# reduce 39 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 133)
- def _reduce_40(val, _values, result)
- case val[0]
- when 'even'
- result = Node.new(:NTH, ['2','n','+','0'])
- when 'odd'
- result = Node.new(:NTH, ['2','n','+','1'])
- when 'n'
- result = Node.new(:NTH, ['1','n','+','0'])
- else
- # This is not CSS standard. It allows us to support this:
- # assert_xpath("//a[foo(., @href)]", @parser.parse('a:foo(@href)'))
- # assert_xpath("//a[foo(., @a, b)]", @parser.parse('a:foo(@a, b)'))
- # assert_xpath("//a[foo(., a, 10)]", @parser.parse('a:foo(a, 10)'))
- result = val
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 152)
- def _reduce_41(val, _values, result)
- if val[1] == 'n'
- result = Node.new(:NTH, val)
- else
- raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 158)
- def _reduce_42(val, _values, result)
- # n+3, -n+3
- if val[0] == 'n'
- val.unshift("1")
- result = Node.new(:NTH, val)
- elsif val[0] == '-n'
- val[0] = 'n'
- val.unshift("-1")
- result = Node.new(:NTH, val)
- else
- raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 170)
- def _reduce_43(val, _values, result)
- # 5n, -5n, 10n-1
- n = val[1]
- if n[0, 2] == 'n-'
- val[1] = 'n'
- val << "-"
- # b is contained in n as n is the string "n-b"
- val << n[2, n.size]
- result = Node.new(:NTH, val)
- elsif n == 'n'
- val << "+"
- val << "0"
- result = Node.new(:NTH, val)
- else
- raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 189)
- def _reduce_44(val, _values, result)
- result = Node.new(:PSEUDO_CLASS, [val[1]])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 191)
- def _reduce_45(val, _values, result)
- result = Node.new(:PSEUDO_CLASS, [val[1]])
- result
- end
-.,.,
-
-# reduce 46 omitted
-
-# reduce 47 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 199)
- def _reduce_48(val, _values, result)
- result = Node.new(:COMBINATOR, val)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 202)
- def _reduce_49(val, _values, result)
- result = Node.new(:COMBINATOR, val)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 205)
- def _reduce_50(val, _values, result)
- result = Node.new(:COMBINATOR, val)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 208)
- def _reduce_51(val, _values, result)
- result = Node.new(:COMBINATOR, val)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 211)
- def _reduce_52(val, _values, result)
- result = Node.new(:COMBINATOR, val)
-
- result
- end
-.,.,
-
-# reduce 53 omitted
-
-# reduce 54 omitted
-
-# reduce 55 omitted
-
-# reduce 56 omitted
-
-# reduce 57 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 220)
- def _reduce_58(val, _values, result)
- result = Node.new(:ID, val)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 223)
- def _reduce_59(val, _values, result)
- result = [val.first, val[1]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 224)
- def _reduce_60(val, _values, result)
- result = [val.first, val[1]]
- result
- end
-.,.,
-
-# reduce 61 omitted
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 228)
- def _reduce_62(val, _values, result)
- result = :equal
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 229)
- def _reduce_63(val, _values, result)
- result = :prefix_match
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 230)
- def _reduce_64(val, _values, result)
- result = :suffix_match
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 231)
- def _reduce_65(val, _values, result)
- result = :substring_match
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 232)
- def _reduce_66(val, _values, result)
- result = :not_equal
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 233)
- def _reduce_67(val, _values, result)
- result = :includes
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 234)
- def _reduce_68(val, _values, result)
- result = :dash_match
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'nokogiri-css.y', 238)
- def _reduce_69(val, _values, result)
- result = Node.new(:NOT, [val[1]])
-
- result
- end
-.,.,
-
-# reduce 70 omitted
-
-# reduce 71 omitted
-
-# reduce 72 omitted
-
-# reduce 73 omitted
-
-# reduce 74 omitted
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
- end # module CSS
-end # module Nokogiri
diff --git a/test/racc/regress/opal b/test/racc/regress/opal
deleted file mode 100644
index 53420a8f0e..0000000000
--- a/test/racc/regress/opal
+++ /dev/null
@@ -1,10107 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.2
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-module Opal
- class Parser < Racc::Parser
-
-module_eval(<<'...end opal.y/module_eval...', 'opal.y', 1808)
-
-...end opal.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 63, 64, 65, 8, 51, 575, 552, -92, 57, 58,
- 619, 205, 206, 61, 73, 59, 60, 62, 23, 24,
- 66, 67, 74, 544, 754, 607, 543, 22, 28, 27,
- 90, 89, 91, 92, 97, 751, 17, 607, 273, -458,
- 612, 653, 7, 41, 6, 9, 94, 93, 575, 84,
- 50, 86, 85, 87, 273, 88, 95, 96, 653, 81,
- 82, -100, 38, 39, -99, -68, 597, -446, 344, 343,
- -95, 205, 206, 618, -446, 652, -97, 581, 575, 582,
- -94, 205, 206, -96, 575, 36, 609, 608, 30, -92,
- 575, 52, 652, 108, 54, 770, 32, -84, 609, 608,
- 40, 101, -79, -92, 268, 752, 100, 195, 18, -100,
- -99, 551, -84, 79, 73, 75, 76, 77, 78, 101,
- -95, 574, 74, 80, 100, 272, -98, 63, 64, 65,
- 56, 51, -97, 53, 653, 57, 58, 196, 37, 83,
- 61, 272, 59, 60, 62, 23, 24, 66, 67, 454,
- -534, 205, 206, 197, 22, 28, 27, 90, 89, 91,
- 92, 308, 101, 17, 574, -84, -91, 100, 652, -90,
- 41, 308, 596, 94, 93, -86, 84, 50, 86, 85,
- 87, -88, 88, 95, 96, -85, 81, 82, -87, 38,
- 39, 101, 101, -535, 574, 900, 100, 100, 101, -100,
- 574, -449, -84, 100, 101, 198, 574, 649, -449, 100,
- -96, -84, 210, 246, -98, 214, 215, -92, 52, -92,
- -91, 54, -92, -100, -99, -100, -99, 40, -100, -99,
- -94, -89, 273, 607, -95, 18, -95, 299, 726, -95,
- 79, 73, 75, 76, 77, 78, -97, -90, -97, 74,
- 80, -97, -86, 726, 63, 64, 65, 56, 51, -88,
- 53, 544, 57, 58, 546, 37, 83, 61, 531, 59,
- 60, 62, 23, 24, 66, 67, 205, 206, 653, 205,
- 206, 22, 28, 27, 90, 89, 91, 92, -91, -534,
- 219, 777, 300, -535, 609, 608, 605, 41, 268, 227,
- 94, 93, 308, 84, 50, 86, 85, 87, 388, 88,
- 95, 96, 652, 81, 82, -90, 38, 39, -99, 272,
- -86, 726, 301, 302, -96, -91, -96, -88, -98, -96,
- -98, 224, 810, -98, -91, 226, 225, -87, 101, 210,
- 725, -93, 214, 100, -94, 52, -94, -85, 54, -94,
- 391, -89, -90, 101, 40, 725, 788, -86, 100, 402,
- 101, -90, 218, 415, -88, 100, -86, 79, 73, 75,
- 76, 77, 78, -88, 453, 101, 74, 80, 455, 204,
- 100, 63, 64, 65, 56, 51, 607, 53, 544, 57,
- 58, 546, 37, 83, 61, 789, 59, 60, 62, 258,
- 259, 66, 67, 876, -534, -87, -95, 877, 257, 28,
- 27, 90, 89, 91, 92, -85, 456, 219, -535, -89,
- -91, 101, 607, 725, 41, 607, 100, 94, 93, -100,
- 84, 50, 86, 85, 87, 261, 88, 95, 96, -456,
- 81, 82, -87, 38, 39, -97, -456, 609, 608, 610,
- 101, -87, -85, -93, 215, 100, -89, -94, 487, 264,
- 265, -85, 754, -455, -454, -89, 210, 266, 489, 214,
- -455, -454, 52, 751, 813, 54, 582, 256, 491, 254,
- 497, 40, -67, 609, 608, 614, 609, 608, 620, 218,
- 400, 401, 203, 201, 79, 73, 75, 76, 77, 78,
- 202, 514, 544, 74, 80, 546, 344, 343, 63, 64,
- 65, 56, 51, 101, 53, -451, 57, 58, 100, 37,
- 83, 61, -451, 59, 60, 62, 258, 259, 66, 67,
- 515, -532, 527, 528, 516, 257, 28, 27, 90, 89,
- 91, 92, 101, 752, 219, -331, -331, 100, 199, 625,
- 200, 41, 525, -331, 94, 93, 277, 84, 50, 86,
- 85, 87, 261, 88, 95, 96, 308, 81, 82, 268,
- 38, 39, 532, 227, 231, 236, 237, 238, 233, 235,
- 243, 244, 239, 240, -449, -449, 220, 221, -452, 101,
- 241, 242, -449, 210, 100, -452, 214, -532, 533, 52,
- 227, -331, 54, -331, 256, 224, 254, 230, 40, 226,
- 225, 222, 223, 234, 232, 228, 218, 229, -532, 203,
- 449, 79, 73, 75, 76, 77, 78, 450, 308, -458,
- 74, 80, 547, 245, 548, 63, 64, 65, 56, 51,
- -449, 53, -449, 57, 58, 491, 37, 83, 61, 555,
- 59, 60, 62, 258, 259, 66, 67, 103, 104, 105,
- 106, 107, 257, 28, 27, 90, 89, 91, 92, -453,
- -84, 219, 524, 521, 531, 452, -453, 451, 41, -92,
- 522, 94, 93, 558, 84, 50, 86, 85, 87, 261,
- 88, 95, 96, 559, 81, 82, 561, 38, 39, 570,
- 227, 231, 236, 237, 238, 233, 235, 243, 244, 239,
- 240, 524, 534, 220, 221, -90, 412, 241, 242, 535,
- 210, 414, 413, 214, -99, 571, 52, 404, 520, 54,
- 523, 256, 224, 254, 230, 40, 226, 225, 222, 223,
- 234, 232, 228, 218, 229, 587, 524, 584, 79, 73,
- 75, 76, 77, 78, 585, 588, 630, 74, 80, 589,
- 245, 650, -255, -255, -255, 56, -255, 452, 53, 451,
- -255, -255, 613, 37, 83, -255, 617, -255, -255, -255,
- -255, -255, -255, -255, 103, 104, 105, 106, 107, -255,
- -255, -255, -255, -255, -255, -255, 621, -86, -255, 524,
- 593, 624, 583, 625, 586, -255, -95, 591, -255, -255,
- 627, -255, -255, -255, -255, -255, -255, -255, -255, -255,
- -263, -255, -255, 628, -255, -255, 629, 227, 231, 236,
- 237, 238, 233, 235, 243, 244, 239, 240, -284, -284,
- 220, 221, 205, 206, 241, 242, -284, -255, 268, 631,
- -255, 268, 227, -255, 227, 592, -255, 523, -255, 224,
- -255, 230, -255, 226, 225, 222, 223, 234, 232, 228,
- -255, 229, 344, 343, 602, -255, -255, -255, -255, -255,
- -255, 603, 832, 813, -255, -255, 776, 245, 227, -233,
- -88, 227, -255, 915, -284, -255, -284, 308, 754, -97,
- -255, -255, 63, 64, 65, 8, 51, 344, 343, 751,
- 57, 58, 832, 813, 670, 61, 671, 59, 60, 62,
- 23, 24, 66, 67, 679, 681, -79, -85, 682, 22,
- 28, 27, 90, 89, 91, 92, -94, 684, 17, 537,
- 341, 340, 344, 343, 7, 41, 227, 9, 94, 93,
- 694, 84, 50, 86, 85, 87, 700, 88, 95, 96,
- 701, 81, 82, 702, 38, 39, 706, 227, 231, 236,
- 237, 238, 233, 235, 243, 244, 239, 240, 224, 752,
- 220, 221, 226, 225, 241, 242, 716, 36, 718, 721,
- 281, 582, 729, 52, 772, -264, 54, 497, 32, 224,
- 497, 230, 40, 226, 225, 222, 223, 234, 232, 228,
- 18, 229, 497, 524, 593, 79, 73, 75, 76, 77,
- 78, 822, 791, 792, 74, 80, 489, 245, 491, 63,
- 64, 65, 56, 51, 800, 53, 802, 57, 58, 803,
- 37, 83, 61, 694, 59, 60, 62, 258, 259, 66,
- 67, 708, 807, 268, 268, 808, 257, 291, 295, 90,
- 89, 91, 92, 268, 227, 219, -286, -286, 227, 592,
- 813, 523, 292, 819, -286, 94, 93, 820, 84, 50,
- 86, 85, 87, 558, 88, 95, 96, 561, 81, 82,
- 823, 327, 824, 336, 334, 333, 561, 335, 341, 340,
- 344, 343, 827, 866, 867, -283, -283, 868, 95, 96,
- 813, 836, 837, -283, 289, 839, 840, 286, -535, -534,
- 52, 842, -286, 54, -286, 285, 850, 852, 855, 856,
- 338, 858, 915, 860, 862, 864, -265, 754, 341, 340,
- 344, 343, 79, 73, 75, 76, 77, 78, 751, 794,
- 878, 74, 80, 879, 880, 881, 63, 64, 65, 56,
- 51, -283, 53, -283, 57, 58, 883, 296, 83, 61,
- 884, 59, 60, 62, 258, 259, 66, 67, 708, 341,
- 340, 344, 343, 257, 291, 295, 90, 89, 91, 92,
- 524, 946, 219, 103, 104, 105, 106, 107, 947, 292,
- 227, 694, 94, 93, 886, 84, 50, 86, 85, 87,
- -263, 88, 95, 96, 890, 81, 82, 764, 752, 336,
- 334, 333, 754, 335, 895, 341, 340, 344, 343, 897,
- 903, 905, 224, 751, 906, 308, 226, 225, 222, 223,
- 919, 289, -266, 921, 214, -535, 945, 52, 586, 563,
- 54, 336, 334, 333, 561, 335, 338, 749, 931, 932,
- 937, 855, 939, 860, 341, 340, 344, 343, 860, 79,
- 73, 75, 76, 77, 78, 862, 948, 954, 74, 80,
- 700, 964, 860, 298, 966, 967, 56, nil, nil, 53,
- nil, nil, nil, nil, 296, 83, 63, 64, 65, 227,
- 51, nil, nil, 752, 57, 58, nil, nil, nil, 61,
- nil, 59, 60, 62, 258, 259, 66, 67, nil, nil,
- nil, nil, nil, 257, 291, 295, 90, 89, 91, 92,
- nil, 224, 219, nil, nil, 226, 225, 222, 223, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, 227, 231, 236, 237, 238, 233, 235, 243, 244,
- 239, 240, nil, nil, 220, 221, nil, nil, 241, 242,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, 224, nil, 230, 40, 226, 225, 222,
- 223, 234, 232, 228, 218, 229, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, 245, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, 563, 219,
- 336, 334, 333, nil, 335, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, 227, 231,
- 236, 237, 238, 233, 235, 243, 244, 239, 240, nil,
- nil, 220, 221, nil, nil, 241, 242, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- 224, nil, 230, 40, 226, 225, 222, 223, 234, 232,
- 228, 218, 229, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, 245, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, 227, 231, 236, 237, 238,
- 233, 235, 243, 244, 239, 240, nil, nil, 220, 221,
- nil, nil, 241, 242, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, 224, nil, 230,
- 40, 226, 225, 222, 223, 234, 232, 228, 218, 229,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, 245, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 23, 24, 66, 67, nil,
- nil, nil, nil, nil, 22, 28, 27, 90, 89, 91,
- 92, nil, nil, 17, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, 227, 231, 236, 237, 238, 233, 235, 243,
- 244, 239, 240, nil, nil, 220, 221, nil, nil, 241,
- 242, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, 224, nil, 230, 40, 226, 225,
- 222, 223, 234, 232, 228, 18, 229, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, 245, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 28, 27, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, 261, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, 227,
- 231, 236, 237, 238, 233, 235, 243, 244, 239, 240,
- nil, nil, 220, 221, nil, nil, 241, 242, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- 256, 224, nil, 230, 40, 226, 225, 222, 223, 234,
- 232, 228, 218, 229, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, 245,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 258,
- 259, 66, 67, nil, nil, nil, nil, nil, 257, 291,
- 295, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, 261, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, 227, 231, 236, 237,
- 238, 233, 235, 243, 244, 239, 240, nil, nil, 220,
- 221, nil, nil, 241, 242, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, nil, 224, nil,
- 230, 40, 226, 225, 222, 223, 234, 232, 228, 218,
- 229, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, 245, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, 227, 231, 236, 237, 238, 233, 235,
- 243, 244, 239, 240, nil, nil, 220, 221, nil, nil,
- 241, 242, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, 224, nil, 230, 40, 226,
- 225, 222, 223, 234, 232, 228, 18, 229, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, 245, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 23, 24, 66, 67, nil, nil, nil,
- nil, nil, 22, 28, 27, 90, 89, 91, 92, nil,
- nil, 17, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- 227, 231, 236, 237, 238, 233, 235, 243, 244, 239,
- 240, nil, nil, 220, 221, nil, nil, 241, 242, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, 224, nil, 230, 40, 226, 225, 222, 223,
- 234, 232, 228, 18, 229, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- 245, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 23, 24, 66, 67, nil, nil, nil, nil, nil, 22,
- 28, 27, 90, 89, 91, 92, nil, nil, 17, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, 227, 231, 236,
- 237, 238, 233, 235, 243, 244, 239, 240, nil, nil,
- 220, 221, nil, nil, 241, 242, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, nil, 224,
- nil, 230, 40, 226, 225, 222, 223, 234, 232, 228,
- 18, 229, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, 101, 245, nil, -233,
- nil, 100, 56, nil, nil, 53, nil, nil, nil, nil,
- 37, 83, 63, 64, 65, nil, 51, nil, nil, nil,
- 57, 58, nil, nil, nil, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 291, 295, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 292, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, 227, 231, 236, 237, 238, 233, 235,
- 243, 244, 239, 240, 227, nil, 220, 221, nil, nil,
- 241, 242, nil, nil, nil, nil, nil, 356, nil, nil,
- 30, 241, 242, 52, nil, 224, 54, 230, 32, 226,
- 225, 222, 223, 234, 232, 228, 224, 229, 230, nil,
- 226, 225, 222, 223, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, 245, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 296, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 291, 295, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 292, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 361, nil, 88, 95, 96, nil, 81, 82,
- 227, 231, 236, 237, 238, 233, 235, 243, 244, 239,
- 240, 227, nil, 220, 221, nil, nil, 241, 242, nil,
- nil, 367, nil, nil, 362, nil, nil, 214, 241, 242,
- 52, nil, 224, 54, 230, nil, 226, 225, 222, 223,
- 234, 232, 228, 224, 229, 230, nil, 226, 225, 222,
- 223, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- 245, 74, 80, nil, nil, nil, -531, -531, -531, 56,
- -531, nil, 53, nil, -531, -531, nil, 296, 83, -531,
- nil, -531, -531, -531, -531, -531, -531, -531, nil, -531,
- nil, nil, nil, -531, -531, -531, -531, -531, -531, -531,
- nil, nil, -531, nil, nil, nil, nil, nil, nil, -531,
- nil, nil, -531, -531, nil, -531, -531, -531, -531, -531,
- -531, -531, -531, -531, nil, -531, -531, nil, -531, -531,
- nil, 227, 231, 236, 237, 238, 233, 235, 243, 244,
- 239, 240, nil, nil, 220, 221, nil, nil, 241, 242,
- nil, -531, nil, nil, -531, -531, nil, -531, nil, nil,
- -531, nil, -531, 224, -531, 230, -531, 226, 225, 222,
- 223, 234, 232, 228, -531, 229, -531, nil, nil, -531,
- -531, -531, -531, -531, -531, nil, nil, nil, -531, -531,
- nil, 245, nil, -532, -532, -532, -531, -532, nil, -531,
- nil, -532, -532, nil, -531, -531, -532, nil, -532, -532,
- -532, -532, -532, -532, -532, nil, -532, nil, nil, nil,
- -532, -532, -532, -532, -532, -532, -532, nil, nil, -532,
- nil, nil, nil, nil, nil, nil, -532, nil, nil, -532,
- -532, nil, -532, -532, -532, -532, -532, -532, -532, -532,
- -532, nil, -532, -532, nil, -532, -532, nil, 227, 231,
- 236, 237, 238, 233, 235, 243, 244, 239, 240, nil,
- nil, 220, 221, nil, nil, 241, 242, nil, -532, nil,
- nil, -532, -532, nil, -532, nil, nil, -532, nil, -532,
- 224, -532, 230, -532, 226, 225, 222, 223, 234, 232,
- 228, -532, 229, -532, nil, nil, -532, -532, -532, -532,
- -532, -532, nil, nil, nil, -532, -532, nil, 245, nil,
- nil, nil, nil, -532, nil, nil, -532, nil, nil, nil,
- nil, -532, -532, 63, 64, 65, 8, 51, nil, nil,
- nil, 57, 58, nil, nil, nil, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, nil, 17,
- nil, nil, nil, nil, nil, 7, 41, 6, 9, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, 227, 231,
- 236, 237, 238, 233, 235, 243, 244, 239, 240, nil,
- nil, 220, 221, nil, nil, 241, 242, nil, 36, nil,
- nil, 30, nil, nil, 52, nil, nil, 54, nil, 32,
- 224, nil, 230, 40, 226, 225, 222, 223, 234, 232,
- 228, 18, 229, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, 245, nil,
- nil, nil, 404, 56, nil, nil, 53, nil, nil, nil,
- nil, 37, 83, 63, 64, 65, nil, 51, nil, nil,
- nil, 57, 58, nil, nil, nil, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, 563, 17,
- 336, 334, 333, nil, 335, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, 563, nil, 336,
- 334, 333, nil, 335, nil, nil, 563, 566, 336, 334,
- 333, nil, 335, nil, nil, 569, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, 566, nil, nil, nil,
- nil, 18, nil, nil, 569, 566, 79, 73, 75, 76,
- 77, 78, nil, 829, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 23, 24,
- 66, 67, nil, nil, nil, nil, nil, 22, 28, 27,
- 90, 89, 91, 92, nil, nil, 17, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, 227, 231, 236, 237, 238,
- 233, 235, 243, 244, 239, 240, nil, nil, -555, -555,
- nil, nil, 241, 242, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, 224, nil, 230,
- 40, 226, 225, 222, 223, 234, 232, 228, 18, 229,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 23, 24, 66, 67, nil,
- nil, nil, nil, nil, 22, 28, 27, 90, 89, 91,
- 92, nil, nil, 17, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, 227, 231, 236, 237, 238, 233, 235, 243,
- 244, 239, 240, nil, nil, -555, -555, nil, nil, 241,
- 242, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, 224, nil, 230, 40, 226, 225,
- 222, 223, 234, 232, 228, 18, 229, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 23, 24, 66, 67, nil, nil, nil, nil,
- nil, 22, 28, 27, 90, 89, 91, 92, nil, nil,
- 17, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, 227,
- -555, -555, -555, -555, 233, 235, nil, nil, -555, -555,
- nil, nil, nil, nil, nil, nil, 241, 242, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- nil, 224, nil, 230, 40, 226, 225, 222, 223, 234,
- 232, 228, 18, 229, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, nil, nil, nil, 56, nil, nil, 53, nil, nil,
- nil, nil, 37, 83, 63, 64, 65, 8, 51, nil,
- nil, nil, 57, 58, nil, nil, nil, 61, nil, 59,
- 60, 62, 23, 24, 66, 67, nil, nil, nil, nil,
- nil, 22, 28, 27, 90, 89, 91, 92, nil, nil,
- 17, nil, nil, nil, nil, nil, 7, 41, nil, 9,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, 227,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 241, 242, nil, 36,
- nil, nil, 30, nil, nil, 52, nil, nil, 54, nil,
- 32, 224, nil, 230, 40, 226, 225, 222, 223, nil,
- nil, 228, 18, 229, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, nil, nil, nil, 56, nil, nil, 53, nil, nil,
- nil, nil, 37, 83, 63, 64, 65, 8, 51, nil,
- nil, nil, 57, 58, nil, nil, nil, 61, nil, 59,
- 60, 62, 23, 24, 66, 67, nil, nil, nil, nil,
- nil, 22, 28, 27, 90, 89, 91, 92, nil, nil,
- 17, nil, nil, nil, nil, nil, 7, 41, 6, 9,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, 227,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 241, 242, nil, 36,
- nil, nil, 30, nil, nil, 52, nil, nil, 54, nil,
- 32, 224, nil, 230, 40, 226, 225, 222, 223, nil,
- nil, 228, 18, 229, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, nil, nil, nil, 56, nil, nil, 53, nil, nil,
- nil, nil, 37, 83, 63, 64, 65, 8, 51, nil,
- nil, nil, 57, 58, nil, nil, nil, 61, nil, 59,
- 60, 62, 23, 24, 66, 67, nil, nil, nil, nil,
- nil, 22, 28, 27, 90, 89, 91, 92, nil, nil,
- 17, nil, nil, nil, nil, nil, 7, 41, nil, 9,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, 227,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 241, 242, nil, 36,
- nil, nil, 30, nil, nil, 52, nil, nil, 54, nil,
- 32, 224, nil, 230, 40, 226, 225, 222, 223, nil,
- nil, 228, 18, 229, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 23,
- 24, 66, 67, nil, nil, nil, nil, nil, 22, 28,
- 27, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, 227, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 241, 242, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, 421, 224, nil,
- 230, 40, 226, 225, 222, 223, nil, nil, 228, 218,
- 229, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, 227, -555, -555, -555, -555, 233, 235,
- nil, nil, -555, -555, nil, nil, nil, nil, nil, nil,
- 241, 242, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, 421, 224, nil, 230, 40, 226,
- 225, 222, 223, 234, 232, 228, 218, 229, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 23, 24, 66, 67, nil, nil, nil,
- nil, nil, 22, 28, 27, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- 227, -555, -555, -555, -555, 233, 235, nil, nil, -555,
- -555, nil, nil, nil, nil, nil, nil, 241, 242, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, 224, nil, 230, 40, 226, 225, 222, 223,
- 234, 232, 228, 218, 229, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 28, 27, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, 261, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, 227, -555, -555,
- -555, -555, 233, 235, nil, nil, -555, -555, nil, nil,
- nil, nil, nil, nil, 241, 242, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, 256, 224,
- nil, 230, 40, 226, 225, 222, 223, 234, 232, 228,
- 218, 229, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 28, 27, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, 261, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, 227, -555, -555, -555, -555, 233,
- 235, nil, nil, -555, -555, nil, nil, nil, nil, nil,
- nil, 241, 242, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, 256, 224, nil, 230, 40,
- 226, 225, 222, 223, 234, 232, 228, 218, 229, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 23, 24, 66, 67, nil, nil,
- nil, nil, nil, 22, 28, 27, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, 227, -555, -555, -555, -555, 233, 235, nil, nil,
- -555, -555, nil, nil, nil, nil, nil, nil, 241, 242,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, 224, nil, 230, 40, 226, 225, 222,
- 223, 234, 232, 228, 218, 229, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, nil, 17,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, 227, 231,
- 236, 237, 238, 233, 235, nil, nil, 239, 240, nil,
- nil, nil, nil, nil, nil, 241, 242, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- 224, nil, 230, 40, 226, 225, 222, 223, 234, 232,
- 228, 18, 229, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 23, 24,
- 66, 67, nil, nil, nil, nil, nil, 22, 28, 27,
- 90, 89, 91, 92, nil, nil, 17, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, 227, 231, 236, 237, 238,
- 233, 235, 243, nil, 239, 240, nil, nil, nil, nil,
- nil, nil, 241, 242, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, 224, nil, 230,
- 40, 226, 225, 222, 223, 234, 232, 228, 18, 229,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, nil, nil, nil,
- 56, nil, nil, 53, nil, nil, nil, nil, 37, 83,
- 63, 64, 65, 8, 51, nil, nil, nil, 57, 58,
- nil, nil, nil, 61, nil, 59, 60, 62, 23, 24,
- 66, 67, nil, nil, nil, nil, nil, 22, 28, 27,
- 90, 89, 91, 92, nil, nil, 17, nil, nil, nil,
- nil, nil, 7, 41, nil, 9, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, 227, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 241, 242, nil, 36, nil, nil, 30, nil,
- nil, 52, nil, nil, 54, nil, 32, 224, nil, nil,
- 40, 226, 225, 222, 223, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 23, 24, 66, 67, nil,
- nil, nil, nil, nil, 22, 28, 27, 90, 89, 91,
- 92, nil, nil, 17, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, 458, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 18, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 291, 295, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 258,
- 259, 66, 67, nil, nil, nil, nil, nil, 257, 291,
- 295, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 258, 259, 66, 67,
- nil, nil, nil, nil, nil, 257, 291, 295, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 218, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 291, 295, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 218, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 291, 295, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 218, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 291, 295, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 258, 259, 66, 67, nil, nil,
- nil, nil, nil, 257, 291, 295, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 218, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, nil, 219,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 218, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 218, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 258, 259, 66, 67, nil,
- nil, nil, nil, nil, 257, 291, 295, 90, 89, 91,
- 92, nil, nil, 219, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 218, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 291, 295, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 258,
- 259, 66, 67, nil, nil, nil, nil, nil, 257, 291,
- 295, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 258, 259, 66, 67,
- nil, nil, nil, nil, nil, 257, 291, 295, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 218, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 291, 295, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 218, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 291, 295, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 218, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 291, 295, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 258, 259, 66, 67, nil, nil,
- nil, nil, nil, 257, 291, 295, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 218, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, nil, 219,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 218, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 218, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 258, 259, 66, 67, nil,
- nil, nil, nil, nil, 257, 291, 295, 90, 89, 91,
- 92, nil, nil, 219, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 218, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 291, 295, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 258,
- 259, 66, 67, nil, nil, nil, nil, nil, 257, 291,
- 295, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 258, 259, 66, 67,
- nil, nil, nil, nil, nil, 257, 291, 295, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 218, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 291, 295, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 218, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 291, 295, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 218, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 291, 295, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 258, 259, 66, 67, nil, nil,
- nil, nil, nil, 257, 291, 295, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 218, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, nil, 219,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 218, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 218, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 258, 259, 66, 67, nil,
- nil, nil, nil, nil, 257, 291, 295, 90, 89, 91,
- 92, nil, nil, 219, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 218, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 28, 27, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, 261, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- 256, nil, 254, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 258,
- 259, 66, 67, nil, nil, nil, nil, nil, 257, 28,
- 27, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, 261, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 506, nil, nil, 54, nil, 256, nil, 254,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 258, 259, 66, 67,
- nil, nil, nil, nil, nil, 257, 28, 27, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, 261, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 210, nil, nil, 214, nil, 510, 52,
- nil, nil, 54, nil, 256, nil, 254, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 218, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, nil, nil, nil, 56, nil,
- nil, 53, nil, nil, nil, nil, 37, 83, 63, 64,
- 65, 8, 51, nil, nil, nil, 57, 58, nil, nil,
- nil, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- 7, 41, nil, 9, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 36, nil, nil, 281, nil, nil, 52,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 291, 295, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 292, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, 764, nil, 336, 334,
- 333, 754, 335, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 751, nil, nil, nil, nil, nil, nil, nil,
- 289, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, nil, nil, nil, 338, nil, nil, nil, nil,
- nil, nil, nil, 341, 340, 344, 343, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 518, nil, nil, 56, nil, nil, 53, nil,
- nil, nil, nil, 296, 83, 63, 64, 65, 8, 51,
- nil, nil, 752, 57, 58, nil, nil, nil, 61, nil,
- 59, 60, 62, 23, 24, 66, 67, nil, nil, nil,
- nil, nil, 22, 28, 27, 90, 89, 91, 92, nil,
- nil, 17, nil, nil, nil, nil, nil, 7, 41, nil,
- 9, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, nil, nil, 281, nil, nil, 52, nil, nil, 54,
- nil, 32, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 18, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 291, 295, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 292, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, 327, nil, 336, 334, 333, nil, 335,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 289, nil, nil,
- 286, nil, nil, 52, nil, nil, 54, nil, nil, nil,
- nil, nil, 338, 322, nil, nil, nil, nil, nil, nil,
- 341, 340, 344, 343, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 296, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 291, 295, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, 537, nil,
- 52, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, nil, nil, nil, 56,
- nil, nil, 53, nil, nil, nil, nil, 37, 83, 63,
- 64, 65, 8, 51, nil, nil, nil, 57, 58, nil,
- nil, nil, 61, nil, 59, 60, 62, 23, 24, 66,
- 67, nil, nil, nil, nil, nil, 22, 28, 27, 90,
- 89, 91, 92, nil, nil, 17, nil, nil, nil, nil,
- nil, 7, 41, nil, 9, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 36, nil, nil, 30, nil, nil,
- 52, nil, nil, 54, nil, 32, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 18, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 23, 24, 66, 67, nil, nil,
- nil, nil, nil, 22, 28, 27, 90, 89, 91, 92,
- nil, nil, 17, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, nil, 17,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 18, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 292, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 361, nil, 88, 95, 96, nil, 81,
- 82, 327, nil, 336, 334, 333, nil, 335, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 362, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- 338, nil, 554, nil, nil, nil, nil, nil, 341, 340,
- 344, 343, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 296, 83,
- 61, nil, 59, 60, 62, 23, 24, 66, 67, nil,
- nil, nil, nil, nil, 22, 28, 27, 90, 89, 91,
- 92, nil, nil, 17, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 18, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 291, 295, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, -255, -255, -255, 56, -255, nil, 53, nil, -255,
- -255, nil, 37, 83, -255, nil, -255, -255, -255, -255,
- -255, -255, -255, nil, nil, nil, nil, nil, -255, -255,
- -255, -255, -255, -255, -255, nil, nil, -255, nil, nil,
- nil, nil, nil, nil, -255, nil, nil, -255, -255, nil,
- -255, -255, -255, -255, -255, -255, -255, -255, -255, nil,
- -255, -255, nil, -255, -255, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, -255, nil, nil, -255,
- 268, nil, -255, nil, nil, -255, nil, -255, nil, -255,
- nil, -255, nil, nil, nil, nil, nil, nil, nil, -255,
- nil, nil, nil, nil, -255, -255, -255, -255, -255, -255,
- nil, nil, nil, -255, -255, nil, nil, nil, -536, -536,
- -536, -255, -536, nil, -255, nil, -536, -536, nil, -255,
- -255, -536, nil, -536, -536, -536, -536, -536, -536, -536,
- nil, nil, nil, nil, nil, -536, -536, -536, -536, -536,
- -536, -536, nil, nil, -536, nil, nil, nil, nil, nil,
- nil, -536, nil, nil, -536, -536, nil, -536, -536, -536,
- -536, -536, -536, -536, -536, -536, nil, -536, -536, nil,
- -536, -536, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -536, nil, nil, -536, -536, nil, -536,
- nil, nil, -536, nil, -536, nil, -536, nil, -536, nil,
- nil, nil, nil, nil, nil, nil, -536, nil, nil, nil,
- nil, -536, -536, -536, -536, -536, -536, nil, nil, nil,
- -536, -536, nil, nil, nil, -537, -537, -537, -536, -537,
- nil, -536, nil, -537, -537, nil, -536, -536, -537, nil,
- -537, -537, -537, -537, -537, -537, -537, nil, nil, nil,
- nil, nil, -537, -537, -537, -537, -537, -537, -537, nil,
- nil, -537, nil, nil, nil, nil, nil, nil, -537, nil,
- nil, -537, -537, nil, -537, -537, -537, -537, -537, -537,
- -537, -537, -537, nil, -537, -537, nil, -537, -537, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- -537, nil, nil, -537, -537, nil, -537, nil, nil, -537,
- nil, -537, nil, -537, nil, -537, nil, nil, nil, nil,
- nil, nil, nil, -537, nil, nil, nil, nil, -537, -537,
- -537, -537, -537, -537, nil, nil, nil, -537, -537, nil,
- nil, nil, -255, -255, -255, -537, -255, nil, -537, nil,
- -255, -255, nil, -537, -537, -255, nil, -255, -255, -255,
- -255, -255, -255, -255, nil, nil, nil, nil, nil, -255,
- -255, -255, -255, -255, -255, -255, nil, nil, -255, nil,
- nil, nil, nil, nil, nil, -255, nil, nil, -255, -255,
- nil, -255, -255, -255, -255, -255, -255, -255, -255, -255,
- nil, -255, -255, nil, -255, -255, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, -255, nil, nil,
- -255, 268, nil, -255, nil, nil, -255, nil, -255, nil,
- -255, nil, -255, nil, nil, nil, nil, nil, nil, nil,
- -255, nil, nil, nil, nil, -255, -255, -255, -255, -255,
- -255, nil, nil, nil, -255, -255, nil, nil, nil, 63,
- 64, 65, -255, 51, nil, -255, nil, 57, 58, nil,
- -255, -255, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 28, 27, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, 261, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, 256, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 258, 259, 66, 67, nil, nil,
- nil, nil, nil, 257, 28, 27, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- 261, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, 256, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 218, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, nil, 219,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 218, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 218, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 258, 259, 66, 67, nil,
- nil, nil, nil, nil, 257, 291, 295, 90, 89, 91,
- 92, nil, nil, 219, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 218, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 291, 295, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, 261, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- 658, nil, 254, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 258,
- 259, 66, 67, nil, nil, nil, nil, nil, 257, 291,
- 295, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, 261, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, nil, nil, 254,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 258, 259, 66, 67,
- nil, nil, nil, nil, nil, 257, 291, 295, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 218, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 23, 24, 66, 67, nil, nil, nil,
- nil, nil, 22, 28, 27, 90, 89, 91, 92, nil,
- nil, 17, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 210, nil, nil, 214, nil, 675, 52, nil, nil, 54,
- nil, nil, nil, 254, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 18, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, nil, nil, nil, 56, nil, nil, 53, nil,
- nil, nil, nil, 37, 83, 63, 64, 65, 8, 51,
- nil, nil, nil, 57, 58, nil, nil, nil, 61, nil,
- 59, 60, 62, 23, 24, 66, 67, nil, nil, nil,
- nil, nil, 22, 28, 27, 90, 89, 91, 92, nil,
- nil, 17, nil, nil, nil, nil, nil, 7, 41, nil,
- 9, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, nil, nil, 30, nil, nil, 52, nil, nil, 54,
- nil, 32, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 18, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, nil, nil, 404, 56, nil, nil, 53, nil,
- nil, nil, nil, 37, 83, 63, 64, 65, nil, 51,
- nil, nil, nil, 57, 58, nil, nil, nil, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 291, 295, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 292, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, 327, nil, 336, 334,
- 333, nil, 335, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 289, nil, nil, 286, nil, nil, 52, nil, nil, 54,
- nil, nil, nil, nil, nil, 338, nil, nil, nil, nil,
- nil, nil, nil, 341, 340, 344, 343, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 296, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 28, 27, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, 261, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, 256, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 218, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 28, 27, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, 261, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, 256, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 258, 259, 66, 67, nil, nil,
- nil, nil, nil, 257, 291, 295, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 218, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, nil, 219,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 218, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 218, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 23, 24, 66, 67, nil,
- nil, nil, nil, nil, 22, 28, 27, 90, 89, 91,
- 92, nil, nil, 17, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 18, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 291, 295, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, 261, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- 658, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 258,
- 259, 66, 67, nil, nil, nil, nil, nil, 257, 291,
- 295, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, 261, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, nil, nil,
- nil, 56, nil, nil, 53, nil, nil, nil, nil, 37,
- 83, 63, 64, 65, 8, 51, nil, nil, nil, 57,
- 58, nil, nil, nil, 61, nil, 59, 60, 62, 23,
- 24, 66, 67, nil, nil, nil, nil, nil, 22, 28,
- 27, 90, 89, 91, 92, nil, nil, 17, nil, nil,
- nil, nil, nil, 7, 41, nil, 9, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 36, nil, nil, 30,
- nil, nil, 52, nil, nil, 54, nil, 32, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 18,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, nil, nil,
- nil, 56, nil, nil, 53, nil, nil, nil, nil, 37,
- 83, 63, 64, 65, 8, 51, nil, nil, nil, 57,
- 58, nil, nil, nil, 61, nil, 59, 60, 62, 23,
- 24, 66, 67, nil, nil, nil, nil, nil, 22, 28,
- 27, 90, 89, 91, 92, nil, nil, 17, nil, nil,
- nil, nil, nil, 7, 41, nil, 9, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 36, nil, nil, 30,
- nil, nil, 52, nil, nil, 54, nil, 32, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 18,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 258, 259, 66, 67,
- nil, nil, nil, nil, nil, 257, 291, 295, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 292, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, 764,
- nil, 336, 334, 333, 754, 335, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 751, nil, nil, nil, nil,
- nil, nil, nil, 712, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, nil, nil, nil, 338, nil,
- nil, nil, nil, nil, nil, nil, 341, 340, 344, 343,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, nil, nil, nil, 56, nil,
- nil, 53, nil, nil, nil, nil, 296, 83, 63, 64,
- 65, 8, 51, nil, nil, 752, 57, 58, nil, nil,
- nil, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- 7, 41, nil, 9, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 36, nil, nil, 30, nil, nil, 52,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, nil, nil, nil, 56, nil,
- nil, 53, nil, nil, nil, nil, 37, 83, 63, 64,
- 65, 8, 51, nil, nil, nil, 57, 58, nil, nil,
- nil, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- 7, 41, nil, 9, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 36, nil, nil, 30, nil, nil, 52,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, nil, nil, nil, 56, nil,
- nil, 53, nil, nil, nil, nil, 37, 83, 63, 64,
- 65, 8, 51, nil, nil, nil, 57, 58, nil, nil,
- nil, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- 7, 41, nil, 9, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 36, nil, nil, 30, nil, nil, 52,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 28, 27, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, 261,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, 256, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 218, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 28, 27, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, 261, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, 256, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 218, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 28, 27, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, 261, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, 256, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 23, 24, 66, 67, nil, nil,
- nil, nil, nil, 22, 28, 27, 90, 89, 91, 92,
- nil, nil, 17, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, nil, 17,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 18, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 218, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 258, 259, 66, 67, nil,
- nil, nil, nil, nil, 257, 291, 295, 90, 89, 91,
- 92, nil, nil, 219, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, 775, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 218, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 23, 24, 66, 67, nil, nil, nil, nil,
- nil, 22, 28, 27, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 23,
- 24, 66, 67, nil, nil, nil, nil, nil, 22, 28,
- 27, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 218, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 291, 295, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 218, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 291, 295, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 218, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, nil,
- nil, nil, 56, nil, nil, 53, nil, nil, nil, nil,
- 37, 83, 63, 64, 65, 8, 51, nil, nil, nil,
- 57, 58, nil, nil, nil, 61, nil, 59, 60, 62,
- 23, 24, 66, 67, nil, nil, nil, nil, nil, 22,
- 28, 27, 90, 89, 91, 92, nil, nil, 17, nil,
- nil, nil, nil, nil, 7, 41, nil, 9, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 36, nil, nil,
- 30, nil, nil, 52, nil, nil, 54, nil, 32, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 18, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 291, 295, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, nil, nil, nil, 56,
- nil, nil, 53, nil, nil, nil, nil, 37, 83, 63,
- 64, 65, 8, 51, nil, nil, nil, 57, 58, nil,
- nil, nil, 61, nil, 59, 60, 62, 23, 24, 66,
- 67, nil, nil, nil, nil, nil, 22, 28, 27, 90,
- 89, 91, 92, nil, nil, 17, nil, nil, nil, nil,
- nil, 7, 41, nil, 9, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 36, nil, nil, 30, nil, nil,
- 52, nil, nil, 54, nil, 32, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 18, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 258, 259, 66, 67, nil, nil,
- nil, nil, nil, 257, 291, 295, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- 261, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, 658, nil, 254, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 218, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, nil, 219,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, 261, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, 254, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 218, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- nil, nil, nil, 56, nil, nil, 53, nil, nil, nil,
- nil, 37, 83, 63, 64, 65, 8, 51, nil, nil,
- nil, 57, 58, nil, nil, nil, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, nil, 17,
- nil, nil, nil, nil, nil, 7, 41, nil, 9, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 36, nil,
- nil, 30, nil, nil, 52, nil, nil, 54, nil, 32,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 18, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- nil, nil, nil, 56, nil, nil, 53, nil, nil, nil,
- nil, 37, 83, 63, 64, 65, 8, 51, nil, nil,
- nil, 57, 58, nil, nil, nil, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, nil, 17,
- nil, nil, nil, nil, nil, 7, 41, nil, 9, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 36, nil,
- nil, 30, nil, nil, 52, nil, nil, 54, nil, 32,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 18, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 292, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 289, nil, nil, 286, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 296, 83,
- 61, nil, 59, 60, 62, 258, 259, 66, 67, nil,
- nil, nil, nil, nil, 257, 291, 295, 90, 89, 91,
- 92, nil, nil, 219, nil, nil, nil, nil, nil, nil,
- 292, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 289, nil, nil, 286, nil, nil, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 296, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 291, 295, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- 421, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 258,
- 259, 66, 67, nil, nil, nil, nil, nil, 257, 291,
- 295, 90, 89, 91, 92, nil, nil, 219, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, 256, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, nil, nil, nil, 56, nil,
- nil, 53, nil, nil, nil, nil, 37, 83, 63, 64,
- 65, 8, 51, nil, nil, nil, 57, 58, nil, nil,
- nil, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- 7, 41, nil, 9, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 36, nil, nil, 30, nil, nil, 52,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, nil, nil, nil, 56, nil,
- nil, 53, nil, nil, nil, nil, 37, 83, 63, 64,
- 65, 8, 51, nil, nil, nil, 57, 58, nil, nil,
- nil, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- 7, 41, nil, 9, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 36, nil, nil, 30, nil, nil, 52,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, nil, nil, nil, 56, nil,
- nil, 53, nil, nil, nil, nil, 37, 83, 63, 64,
- 65, 8, 51, nil, nil, nil, 57, 58, nil, nil,
- nil, 61, nil, 59, 60, 62, 23, 24, 66, 67,
- nil, nil, nil, nil, nil, 22, 28, 27, 90, 89,
- 91, 92, nil, nil, 17, nil, nil, nil, nil, nil,
- 7, 41, nil, 9, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 36, nil, nil, 30, nil, nil, 52,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 291, 295, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 218, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, nil, nil, nil, 56, nil, nil, 53, nil,
- nil, nil, nil, 37, 83, 63, 64, 65, 8, 51,
- nil, nil, nil, 57, 58, nil, nil, nil, 61, nil,
- 59, 60, 62, 23, 24, 66, 67, nil, nil, nil,
- nil, nil, 22, 28, 27, 90, 89, 91, 92, nil,
- nil, 17, nil, nil, nil, nil, nil, 7, 41, nil,
- 9, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, nil, nil, 30, nil, nil, 52, nil, nil, 54,
- nil, 32, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 18, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 291, 295, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 218, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 23, 24, 66,
- 67, nil, nil, nil, nil, nil, 22, 28, 27, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 23, 24, 66, 67, nil, nil,
- nil, nil, nil, 22, 28, 27, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, 38, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 210, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 218, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 37, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, nil, 219,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 218, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 218, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 258, 259, 66, 67, nil,
- nil, nil, nil, nil, 257, 291, 295, 90, 89, 91,
- 92, nil, nil, 219, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, nil, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 218, nil, nil, nil, nil,
- 79, 73, 75, 76, 77, 78, nil, nil, nil, 74,
- 80, nil, nil, nil, 63, 64, 65, 56, 51, nil,
- 53, nil, 57, 58, nil, 37, 83, 61, nil, 59,
- 60, 62, 258, 259, 66, 67, nil, nil, nil, nil,
- nil, 257, 291, 295, 90, 89, 91, 92, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, 214, nil, nil, 52, nil, nil, 54, nil,
- 256, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, nil, nil, nil, 56, nil, nil, 53, nil, nil,
- nil, nil, 37, 83, 63, 64, 65, 8, 51, nil,
- nil, nil, 57, 58, nil, nil, nil, 61, nil, 59,
- 60, 62, 23, 24, 66, 67, nil, nil, nil, nil,
- nil, 22, 28, 27, 90, 89, 91, 92, nil, nil,
- 17, nil, nil, nil, nil, nil, 7, 41, nil, 9,
- 94, 93, nil, 84, 50, 86, 85, 87, nil, 88,
- 95, 96, nil, 81, 82, nil, 38, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 36,
- nil, nil, 30, nil, nil, 52, nil, nil, 54, nil,
- 32, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 18, nil, nil, nil, nil, 79, 73, 75,
- 76, 77, 78, nil, nil, nil, 74, 80, nil, nil,
- nil, 63, 64, 65, 56, 51, nil, 53, nil, 57,
- 58, nil, 37, 83, 61, nil, 59, 60, 62, 23,
- 24, 66, 67, nil, nil, nil, nil, nil, 22, 28,
- 27, 90, 89, 91, 92, nil, nil, 17, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 214,
- nil, nil, 52, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 18,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, nil, nil,
- nil, 56, nil, nil, 53, nil, nil, nil, nil, 37,
- 83, 63, 64, 65, 8, 51, nil, nil, nil, 57,
- 58, nil, nil, nil, 61, nil, 59, 60, 62, 23,
- 24, 66, 67, nil, nil, nil, nil, nil, 22, 28,
- 27, 90, 89, 91, 92, nil, nil, 17, nil, nil,
- nil, nil, nil, 7, 41, nil, 9, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 36, nil, nil, 30,
- nil, nil, 52, nil, nil, 54, nil, 32, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 18,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, nil, nil,
- nil, 56, nil, nil, 53, nil, nil, nil, nil, 37,
- 83, 63, 64, 65, 8, 51, nil, nil, nil, 57,
- 58, nil, nil, nil, 61, nil, 59, 60, 62, 23,
- 24, 66, 67, nil, nil, nil, nil, nil, 22, 28,
- 27, 90, 89, 91, 92, nil, nil, 17, nil, nil,
- nil, nil, nil, 7, 41, nil, 9, 94, 93, nil,
- 84, 50, 86, 85, 87, nil, 88, 95, 96, nil,
- 81, 82, nil, 38, 39, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 36, nil, nil, 30,
- nil, nil, 52, nil, nil, 54, nil, 32, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 18,
- nil, nil, nil, nil, 79, 73, 75, 76, 77, 78,
- nil, nil, nil, 74, 80, nil, nil, nil, 63, 64,
- 65, 56, 51, nil, 53, nil, 57, 58, nil, 37,
- 83, 61, nil, 59, 60, 62, 258, 259, 66, 67,
- nil, nil, nil, nil, nil, 257, 291, 295, 90, 89,
- 91, 92, nil, nil, 219, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 94, 93, nil, 84, 50, 86,
- 85, 87, nil, 88, 95, 96, nil, 81, 82, nil,
- 38, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 210, nil, nil, 214, nil, nil, 52,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 218, nil, nil, nil,
- nil, 79, 73, 75, 76, 77, 78, nil, nil, nil,
- 74, 80, nil, nil, nil, 63, 64, 65, 56, 51,
- nil, 53, nil, 57, 58, nil, 37, 83, 61, nil,
- 59, 60, 62, 258, 259, 66, 67, nil, nil, nil,
- nil, nil, 257, 291, 295, 90, 89, 91, 92, nil,
- nil, 219, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 94, 93, nil, 84, 50, 86, 85, 87, nil,
- 88, 95, 96, nil, 81, 82, nil, 38, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 210, nil, nil, 214, nil, nil, 52, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 218, nil, nil, nil, nil, 79, 73,
- 75, 76, 77, 78, nil, nil, nil, 74, 80, nil,
- nil, nil, 63, 64, 65, 56, 51, nil, 53, nil,
- 57, 58, nil, 37, 83, 61, nil, 59, 60, 62,
- 258, 259, 66, 67, nil, nil, nil, nil, nil, 257,
- 291, 295, 90, 89, 91, 92, nil, nil, 219, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 94, 93,
- nil, 84, 50, 86, 85, 87, nil, 88, 95, 96,
- nil, 81, 82, nil, 38, 39, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 210, nil, nil,
- 214, nil, nil, 52, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 218, nil, nil, nil, nil, 79, 73, 75, 76, 77,
- 78, nil, nil, nil, 74, 80, nil, nil, nil, 63,
- 64, 65, 56, 51, nil, 53, nil, 57, 58, nil,
- 37, 83, 61, nil, 59, 60, 62, 258, 259, 66,
- 67, nil, nil, nil, nil, nil, 257, 291, 295, 90,
- 89, 91, 92, nil, nil, 219, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 94, 93, nil, 84, 50,
- 86, 85, 87, 261, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 210, nil, nil, 214, nil, nil,
- 52, nil, nil, 54, nil, nil, nil, 254, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, nil, nil, nil, 56,
- nil, nil, 53, nil, nil, nil, nil, 37, 83, 63,
- 64, 65, 8, 51, nil, nil, nil, 57, 58, nil,
- nil, nil, 61, nil, 59, 60, 62, 23, 24, 66,
- 67, nil, nil, nil, nil, nil, 22, 28, 27, 90,
- 89, 91, 92, nil, nil, 17, nil, nil, nil, nil,
- nil, 7, 41, nil, 9, 94, 93, nil, 84, 50,
- 86, 85, 87, nil, 88, 95, 96, nil, 81, 82,
- nil, 38, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 36, nil, nil, 30, nil, nil,
- 52, nil, nil, 54, nil, 32, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 18, nil, nil,
- nil, nil, 79, 73, 75, 76, 77, 78, nil, nil,
- nil, 74, 80, nil, nil, nil, 63, 64, 65, 56,
- 51, nil, 53, nil, 57, 58, nil, 37, 83, 61,
- nil, 59, 60, 62, 258, 259, 66, 67, nil, nil,
- nil, nil, nil, 257, 291, 295, 90, 89, 91, 92,
- nil, nil, 219, nil, nil, nil, nil, nil, nil, 292,
- nil, nil, 94, 93, nil, 84, 50, 86, 85, 87,
- nil, 88, 95, 96, nil, 81, 82, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 926, nil, nil, 214, nil, nil, 52, nil, nil,
- 54, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 79,
- 73, 75, 76, 77, 78, nil, nil, nil, 74, 80,
- nil, nil, nil, 63, 64, 65, 56, 51, nil, 53,
- nil, 57, 58, nil, 296, 83, 61, nil, 59, 60,
- 62, 258, 259, 66, 67, nil, nil, nil, nil, nil,
- 257, 291, 295, 90, 89, 91, 92, nil, nil, 219,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 210, nil,
- nil, 214, nil, nil, 52, nil, nil, 54, nil, 658,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 218, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- nil, nil, nil, 56, nil, nil, 53, nil, nil, nil,
- nil, 37, 83, 63, 64, 65, 8, 51, nil, nil,
- nil, 57, 58, nil, nil, nil, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, nil, 17,
- nil, nil, nil, nil, nil, 7, 41, nil, 9, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 36, nil,
- nil, 30, nil, nil, 52, nil, nil, 54, nil, 32,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 18, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- nil, nil, nil, 56, nil, nil, 53, nil, nil, nil,
- nil, 37, 83, 63, 64, 65, 8, 51, nil, nil,
- nil, 57, 58, nil, nil, nil, 61, nil, 59, 60,
- 62, 23, 24, 66, 67, nil, nil, nil, nil, nil,
- 22, 28, 27, 90, 89, 91, 92, nil, nil, 17,
- nil, nil, nil, nil, nil, 7, 41, nil, 9, 94,
- 93, nil, 84, 50, 86, 85, 87, nil, 88, 95,
- 96, nil, 81, 82, nil, 38, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 36, nil,
- nil, 30, nil, nil, 52, nil, nil, 54, nil, 32,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 18, nil, nil, nil, nil, 79, 73, 75, 76,
- 77, 78, nil, nil, nil, 74, 80, nil, nil, nil,
- 63, 64, 65, 56, 51, nil, 53, nil, 57, 58,
- nil, 37, 83, 61, nil, 59, 60, 62, 258, 259,
- 66, 67, nil, nil, nil, nil, nil, 257, 291, 295,
- 90, 89, 91, 92, nil, nil, 219, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 214, nil,
- nil, 52, nil, nil, 54, nil, 658, nil, 254, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 218, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, nil, nil, nil,
- 56, nil, nil, 53, nil, nil, nil, nil, 37, 83,
- 63, 64, 65, 8, 51, nil, nil, nil, 57, 58,
- nil, nil, nil, 61, nil, 59, 60, 62, 23, 24,
- 66, 67, nil, nil, nil, nil, nil, 22, 28, 27,
- 90, 89, 91, 92, nil, nil, 17, nil, nil, nil,
- nil, nil, 7, 41, nil, 9, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 36, nil, nil, 30, nil,
- nil, 52, nil, nil, 54, nil, 32, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, nil, nil, nil,
- 56, nil, nil, 53, nil, nil, nil, nil, 37, 83,
- 63, 64, 65, 8, 51, nil, nil, nil, 57, 58,
- nil, nil, nil, 61, nil, 59, 60, 62, 23, 24,
- 66, 67, nil, nil, nil, nil, nil, 22, 28, 27,
- 90, 89, 91, 92, nil, nil, 17, nil, nil, nil,
- nil, nil, 7, 41, nil, 9, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 36, nil, nil, 30, nil,
- nil, 52, nil, nil, 54, nil, 32, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, nil, nil, nil,
- 56, nil, nil, 53, nil, nil, nil, nil, 37, 83,
- 63, 64, 65, 8, 51, nil, nil, nil, 57, 58,
- nil, nil, nil, 61, nil, 59, 60, 62, 23, 24,
- 66, 67, nil, nil, nil, nil, nil, 22, 28, 27,
- 90, 89, 91, 92, nil, nil, 17, nil, nil, nil,
- nil, nil, 7, 41, nil, 9, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 36, nil, nil, 30, nil,
- nil, 52, nil, nil, 54, nil, 32, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, nil, nil, nil,
- 56, nil, nil, 53, nil, nil, nil, nil, 37, 83,
- 63, 64, 65, 8, 51, nil, nil, nil, 57, 58,
- nil, nil, nil, 61, nil, 59, 60, 62, 23, 24,
- 66, 67, nil, nil, nil, nil, nil, 22, 28, 27,
- 90, 89, 91, 92, nil, nil, 17, nil, nil, nil,
- nil, nil, 7, 41, nil, 9, 94, 93, nil, 84,
- 50, 86, 85, 87, nil, 88, 95, 96, nil, 81,
- 82, nil, 38, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 36, nil, nil, 30, nil,
- nil, 52, nil, nil, 54, nil, 32, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 73, 75, 76, 77, 78, nil,
- nil, nil, 74, 80, nil, nil, nil, 63, 64, 65,
- 56, 51, nil, 53, nil, 57, 58, nil, 37, 83,
- 61, nil, 59, 60, 62, 258, 259, 66, 67, nil,
- nil, nil, nil, nil, 257, 28, 27, 90, 89, 91,
- 92, nil, nil, 219, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 94, 93, nil, 84, 50, 86, 85,
- 87, 261, 88, 95, 96, nil, 81, 82, nil, 38,
- 39, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 210, nil, nil, 214, nil, nil, 52, nil,
- nil, 54, nil, 256, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 218, nil, nil, nil, -538,
- 79, 73, 75, 76, 77, 78, -538, -538, -538, 74,
- 80, nil, -538, -538, nil, -538, nil, 56, nil, nil,
- 53, nil, nil, nil, -538, 37, 83, nil, nil, nil,
- nil, nil, nil, nil, nil, -538, -538, nil, -538, -538,
- -538, -538, -538, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, -538, -538, -538, -538,
- -538, -538, -538, -538, -538, -538, -538, -538, -538, -538,
- -538, -283, nil, -538, -538, -538, nil, 636, -283, -283,
- -283, -538, nil, nil, -283, -283, nil, -283, -538, nil,
- -538, nil, -538, -538, -538, -538, -538, -538, -538, nil,
- -538, -538, -538, nil, nil, nil, nil, -283, -283, nil,
- -283, -283, -283, -283, -283, -538, -538, nil, -87, nil,
- -538, nil, nil, -538, nil, -538, nil, -96, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, -283, -283,
- -283, -283, -283, -283, -283, -283, -283, -283, -283, -283,
- -283, -283, -283, nil, nil, -283, -283, -283, nil, 639,
- nil, nil, nil, -283, nil, nil, nil, nil, nil, nil,
- -283, nil, -283, nil, -283, -283, -283, -283, -283, -283,
- -283, nil, -283, nil, -283, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, -283, -283, nil,
- -89, nil, -283, -538, nil, -283, nil, -283, nil, -98,
- -538, -538, -538, nil, nil, -538, -538, -538, nil, -538,
- nil, nil, nil, nil, nil, nil, nil, nil, -538, -538,
- -538, nil, nil, nil, nil, nil, nil, nil, nil, -538,
- -538, nil, -538, -538, -538, -538, -538, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- -538, -538, -538, -538, -538, -538, -538, -538, -538, -538,
- -538, -538, -538, -538, -538, nil, nil, -538, -538, -538,
- nil, 790, -538, nil, nil, -538, nil, nil, -538, nil,
- -538, nil, -538, nil, -538, nil, -538, -538, -538, -538,
- -538, -538, -538, nil, -538, -538, -538, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, -538,
- -538, -538, -538, nil, -538, -283, nil, -538, nil, -538,
- nil, -96, -283, -283, -283, nil, nil, -283, -283, -283,
- nil, -283, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, -283, -283, nil, nil, nil, nil, nil, nil, nil,
- nil, -283, -283, nil, -283, -283, -283, -283, -283, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, -283, -283, -283, -283, -283, -283, -283, -283,
- -283, -283, -283, -283, -283, -283, -283, nil, nil, -283,
- -283, -283, nil, 639, -283, nil, nil, -283, nil, nil,
- -283, nil, -283, nil, -283, nil, -283, nil, -283, -283,
- -283, -283, -283, -283, -283, nil, -283, nil, -283, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, -283, -283, -283, -283, nil, -283, -292, nil, -283,
- nil, -283, nil, -98, -292, -292, -292, nil, nil, -292,
- -292, -292, nil, -292, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -292, -292, nil, nil, nil, nil, nil,
- nil, nil, nil, -292, -292, nil, -292, -292, -292, -292,
- -292, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, -292, -292, -292, -292, -292, -292,
- -292, -292, -292, -292, -292, -292, -292, -292, -292, nil,
- nil, -292, -292, -292, nil, nil, -292, nil, 277, -292,
- nil, nil, -292, nil, -292, nil, -292, nil, -292, nil,
- -292, -292, -292, -292, -292, -292, -292, nil, -292, nil,
- -292, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -292, -292, -292, -292, -278, -292, nil,
- nil, -292, nil, -292, -278, -278, -278, nil, nil, -278,
- -278, -278, nil, -278, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -278, -278, -278, nil, nil, nil, nil,
- nil, nil, nil, -278, -278, nil, -278, -278, -278, -278,
- -278, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, -278, -278, -278, -278, -278, -278,
- -278, -278, -278, -278, -278, -278, -278, -278, -278, nil,
- nil, -278, -278, -278, nil, nil, -278, nil, nil, -278,
- nil, nil, -278, nil, -278, nil, -278, nil, -278, nil,
- -278, -278, -278, -278, -278, -278, -278, nil, -278, nil,
- -278, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -278, -278, -278, -278, -554, -278, nil,
- -278, -278, nil, -278, -554, -554, -554, nil, nil, -554,
- -554, -554, nil, -554, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -554, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -554, -554, nil, -554, -554, -554, -554,
- -554, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, -554, nil, nil, nil, nil, nil,
- nil, -554, -554, -554, nil, nil, -554, -554, -554, nil,
- -554, nil, nil, nil, nil, -554, -554, nil, nil, nil,
- -554, nil, nil, -554, nil, nil, nil, nil, 268, -554,
- -554, -554, nil, -554, -554, -554, -554, -554, nil, nil,
- nil, nil, 764, nil, 336, 334, 333, 754, 335, nil,
- -554, nil, nil, nil, nil, nil, nil, nil, 751, nil,
- nil, nil, -554, -554, nil, -554, nil, nil, -554, -554,
- -554, -554, -554, -554, -554, -554, -554, nil, -554, nil,
- -554, 338, 749, nil, nil, 268, -554, nil, -554, 341,
- 340, 344, 343, nil, nil, nil, nil, nil, -554, -554,
- nil, -554, -554, -554, -554, -554, nil, -554, nil, nil,
- nil, nil, nil, 436, 440, nil, nil, 438, nil, nil,
- -554, nil, -554, nil, nil, -554, 142, 143, 752, 139,
- 121, 122, 123, 130, 127, 129, nil, nil, 124, 125,
- -554, -554, nil, nil, 144, 145, 131, 132, -554, nil,
- nil, nil, nil, 268, -554, nil, nil, nil, nil, nil,
- 136, 135, nil, 120, 141, 138, 137, 133, 134, 128,
- 126, 118, 140, 119, nil, -554, 146, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, -554, nil,
- -554, nil, nil, -554, 156, 167, 157, 180, 153, 173,
- 163, 162, 188, 191, 178, 161, 160, 155, 181, 189,
- 190, 165, 154, 168, 172, 174, 166, 159, nil, nil,
- nil, 175, 182, 177, 176, 169, 179, 164, 152, 171,
- 170, 183, 184, 185, 186, 187, 151, 158, 149, 150,
- 147, 148, nil, 111, 113, 110, nil, 112, nil, nil,
- nil, nil, nil, nil, nil, nil, 142, 143, nil, 139,
- 121, 122, 123, 130, 127, 129, nil, nil, 124, 125,
- nil, nil, nil, nil, 144, 145, 131, 132, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 136, 135, nil, 120, 141, 138, 137, 133, 134, 128,
- 126, 118, 140, 119, nil, nil, 146, 192, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 80, 156, 167,
- 157, 180, 153, 173, 163, 162, 188, 191, 178, 161,
- 160, 155, 181, 189, 190, 165, 154, 168, 172, 174,
- 166, 159, nil, nil, nil, 175, 182, 177, 176, 169,
- 179, 164, 152, 171, 170, 183, 184, 185, 186, 187,
- 151, 158, 149, 150, 147, 148, nil, 111, 113, nil,
- nil, 112, nil, nil, nil, nil, nil, nil, nil, nil,
- 142, 143, nil, 139, 121, 122, 123, 130, 127, 129,
- nil, nil, 124, 125, nil, nil, nil, nil, 144, 145,
- 131, 132, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 136, 135, nil, 120, 141, 138,
- 137, 133, 134, 128, 126, 118, 140, 119, nil, nil,
- 146, 192, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 80, 156, 167, 157, 180, 153, 173, 163, 162,
- 188, 191, 178, 161, 160, 155, 181, 189, 190, 165,
- 154, 168, 172, 174, 166, 159, nil, nil, nil, 175,
- 182, 177, 176, 169, 179, 164, 152, 171, 170, 183,
- 184, 185, 186, 187, 151, 158, 149, 150, 147, 148,
- nil, 111, 113, nil, nil, 112, nil, nil, nil, nil,
- nil, nil, nil, nil, 142, 143, nil, 139, 121, 122,
- 123, 130, 127, 129, nil, nil, 124, 125, nil, nil,
- nil, nil, 144, 145, 131, 132, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 136, 135,
- nil, 120, 141, 138, 137, 133, 134, 128, 126, 118,
- 140, 119, nil, nil, 146, 192, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 80, 156, 167, 157, 180,
- 153, 173, 163, 162, 188, 191, 178, 161, 160, 155,
- 181, 189, 190, 165, 154, 168, 172, 174, 166, 159,
- nil, nil, nil, 175, 182, 177, 176, 169, 179, 164,
- 152, 171, 170, 183, 184, 185, 186, 187, 151, 158,
- 149, 150, 147, 148, nil, 111, 113, nil, nil, 112,
- nil, nil, nil, nil, nil, nil, nil, nil, 142, 143,
- nil, 139, 121, 122, 123, 130, 127, 129, nil, nil,
- 124, 125, nil, nil, nil, nil, 144, 145, 131, 132,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 136, 135, nil, 120, 141, 138, 137, 133,
- 134, 128, 126, 118, 140, 119, nil, nil, 146, 192,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 80,
- 156, 167, 157, 180, 153, 173, 163, 162, 188, 191,
- 178, 161, 160, 155, 181, 189, 190, 165, 154, 168,
- 172, 174, 166, 159, nil, nil, nil, 175, 182, 177,
- 376, 375, 377, 374, 152, 171, 170, 183, 184, 185,
- 186, 187, 151, 158, 149, 150, 372, 373, nil, 370,
- 113, 86, 85, 371, nil, 88, nil, nil, nil, nil,
- nil, nil, 142, 143, nil, 139, 121, 122, 123, 130,
- 127, 129, nil, nil, 124, 125, nil, nil, nil, nil,
- 144, 145, 131, 132, nil, nil, nil, nil, nil, 381,
- nil, nil, nil, nil, nil, nil, 136, 135, nil, 120,
- 141, 138, 137, 133, 134, 128, 126, 118, 140, 119,
- nil, nil, 146, 156, 167, 157, 180, 153, 173, 163,
- 162, 188, 191, 178, 161, 160, 155, 181, 189, 190,
- 165, 154, 168, 172, 174, 166, 159, nil, nil, nil,
- 175, 182, 177, 176, 169, 179, 164, 152, 171, 170,
- 183, 184, 185, 186, 187, 151, 158, 149, 150, 147,
- 148, nil, 111, 113, 398, 397, 112, nil, 399, nil,
- nil, nil, nil, nil, nil, 142, 143, nil, 139, 121,
- 122, 123, 130, 127, 129, nil, nil, 124, 125, nil,
- nil, nil, nil, 144, 145, 131, 132, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 136,
- 135, nil, 120, 141, 138, 137, 133, 134, 128, 126,
- 118, 140, 119, nil, nil, 146, 156, 167, 157, 180,
- 153, 173, 163, 162, 188, 191, 178, 161, 160, 155,
- 181, 189, 190, 165, 154, 168, 172, 174, 166, 159,
- nil, nil, nil, 175, 182, 177, 176, 169, 179, 164,
- 152, 171, 170, 183, 184, 185, 186, 187, 151, 158,
- 149, 150, 147, 148, nil, 111, 113, 398, 397, 112,
- nil, 399, nil, nil, nil, nil, nil, nil, 142, 143,
- nil, 139, 121, 122, 123, 130, 127, 129, nil, nil,
- 124, 125, nil, nil, nil, nil, 144, 145, 131, 132,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 136, 135, nil, 120, 141, 138, 137, 133,
- 134, 128, 126, 118, 140, 119, nil, nil, 146, 156,
- 167, 157, 180, 153, 173, 163, 162, 188, 191, 178,
- 161, 160, 155, 181, 189, 190, 165, 154, 168, 172,
- 174, 166, 159, nil, nil, nil, 175, 182, 177, 176,
- 169, 179, 164, 152, 171, 170, 183, 184, 185, 186,
- 187, 151, 158, 149, 150, 147, 148, nil, 111, 113,
- nil, nil, 112, nil, nil, nil, nil, nil, nil, nil,
- nil, 142, 143, nil, 139, 121, 122, 123, 130, 127,
- 129, nil, nil, 124, 125, nil, nil, nil, nil, 144,
- 145, 131, 132, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 136, 135, nil, 120, 141,
- 138, 137, 133, 134, 128, 126, 118, 140, 119, 430,
- 434, 146, nil, 431, nil, nil, nil, nil, nil, nil,
- nil, nil, 142, 143, nil, 139, 121, 122, 123, 130,
- 127, 129, nil, nil, 124, 125, nil, nil, nil, nil,
- 144, 145, 131, 132, nil, nil, nil, nil, nil, 268,
- nil, nil, nil, nil, nil, nil, 136, 135, nil, 120,
- 141, 138, 137, 133, 134, 128, 126, 118, 140, 119,
- 443, 434, 146, nil, 444, nil, nil, nil, nil, nil,
- nil, nil, nil, 142, 143, nil, 139, 121, 122, 123,
- 130, 127, 129, nil, nil, 124, 125, nil, nil, nil,
- nil, 144, 145, 131, 132, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 136, 135, nil,
- 120, 141, 138, 137, 133, 134, 128, 126, 118, 140,
- 119, 443, 434, 146, nil, 444, nil, nil, nil, nil,
- nil, nil, nil, nil, 142, 143, nil, 139, 121, 122,
- 123, 130, 127, 129, nil, nil, 124, 125, nil, nil,
- nil, nil, 144, 145, 131, 132, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 136, 135,
- nil, 120, 141, 138, 137, 133, 134, 128, 126, 118,
- 140, 119, 443, 434, 146, nil, 444, nil, nil, nil,
- nil, nil, nil, nil, nil, 142, 143, nil, 139, 121,
- 122, 123, 130, 127, 129, nil, nil, 124, 125, nil,
- nil, nil, nil, 144, 145, 131, 132, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 136,
- 135, nil, 120, 141, 138, 137, 133, 134, 128, 126,
- 118, 140, 119, 443, 434, 146, nil, 444, nil, nil,
- nil, nil, nil, nil, nil, nil, 142, 143, nil, 139,
- 121, 122, 123, 130, 127, 129, nil, nil, 124, 125,
- nil, nil, nil, nil, 144, 145, 131, 132, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 136, 135, nil, 120, 141, 138, 137, 133, 134, 128,
- 126, 118, 140, 119, 642, 434, 146, nil, 643, nil,
- nil, nil, nil, nil, nil, nil, nil, 142, 143, nil,
- 139, 121, 122, 123, 130, 127, 129, nil, nil, 124,
- 125, nil, nil, nil, nil, 144, 145, 131, 132, nil,
- nil, nil, nil, nil, 268, nil, nil, nil, nil, nil,
- nil, 136, 135, nil, 120, 141, 138, 137, 133, 134,
- 128, 126, 118, 140, 119, 644, 440, 146, nil, 645,
- nil, nil, nil, nil, nil, nil, nil, nil, 142, 143,
- nil, 139, 121, 122, 123, 130, 127, 129, nil, nil,
- 124, 125, nil, nil, nil, nil, 144, 145, 131, 132,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 136, 135, nil, 120, 141, 138, 137, 133,
- 134, 128, 126, 118, 140, 119, 686, 434, 146, nil,
- 687, nil, nil, nil, nil, nil, nil, nil, nil, 142,
- 143, nil, 139, 121, 122, 123, 130, 127, 129, nil,
- nil, 124, 125, nil, nil, nil, nil, 144, 145, 131,
- 132, nil, nil, nil, nil, nil, 268, nil, nil, nil,
- nil, nil, nil, 136, 135, nil, 120, 141, 138, 137,
- 133, 134, 128, 126, 118, 140, 119, 689, 440, 146,
- nil, 690, nil, nil, nil, nil, nil, nil, nil, nil,
- 142, 143, nil, 139, 121, 122, 123, 130, 127, 129,
- nil, nil, 124, 125, nil, nil, nil, nil, 144, 145,
- 131, 132, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 136, 135, nil, 120, 141, 138,
- 137, 133, 134, 128, 126, 118, 140, 119, 443, 434,
- 146, nil, 444, nil, nil, nil, nil, nil, nil, nil,
- nil, 142, 143, nil, 139, 121, 122, 123, 130, 127,
- 129, nil, nil, 124, 125, nil, nil, nil, nil, 144,
- 145, 131, 132, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 136, 135, nil, 120, 141,
- 138, 137, 133, 134, 128, 126, 118, 140, 119, 642,
- 434, 146, nil, 643, nil, nil, nil, nil, nil, nil,
- nil, nil, 142, 143, nil, 139, 121, 122, 123, 130,
- 127, 129, nil, nil, 124, 125, nil, nil, nil, nil,
- 144, 145, 131, 132, nil, nil, nil, nil, nil, 268,
- nil, nil, nil, nil, nil, nil, 136, 135, nil, 120,
- 141, 138, 137, 133, 134, 128, 126, 118, 140, 119,
- 644, 440, 146, nil, 645, nil, nil, nil, nil, nil,
- nil, nil, nil, 142, 143, nil, 139, 121, 122, 123,
- 130, 127, 129, nil, nil, 124, 125, nil, nil, nil,
- nil, 144, 145, 131, 132, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 136, 135, nil,
- 120, 141, 138, 137, 133, 134, 128, 126, 118, 140,
- 119, 733, 434, 146, nil, 734, nil, nil, nil, nil,
- nil, nil, nil, nil, 142, 143, nil, 139, 121, 122,
- 123, 130, 127, 129, nil, nil, 124, 125, nil, nil,
- nil, nil, 144, 145, 131, 132, nil, nil, nil, nil,
- nil, 268, nil, nil, nil, nil, nil, nil, 136, 135,
- nil, 120, 141, 138, 137, 133, 134, 128, 126, 118,
- 140, 119, 735, 440, 146, nil, 736, nil, nil, nil,
- nil, nil, nil, nil, nil, 142, 143, nil, 139, 121,
- 122, 123, 130, 127, 129, nil, nil, 124, 125, nil,
- nil, nil, nil, 144, 145, 131, 132, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 136,
- 135, nil, 120, 141, 138, 137, 133, 134, 128, 126,
- 118, 140, 119, 741, 440, 146, nil, 739, nil, nil,
- nil, nil, nil, nil, nil, nil, 142, 143, nil, 139,
- 121, 122, 123, 130, 127, 129, nil, nil, 124, 125,
- nil, nil, nil, nil, 144, 145, 131, 132, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 136, 135, nil, 120, 141, 138, 137, 133, 134, 128,
- 126, 118, 140, 119, 443, 434, 146, nil, 444, nil,
- nil, nil, nil, nil, nil, nil, nil, 142, 143, nil,
- 139, 121, 122, 123, 130, 127, 129, nil, nil, 124,
- 125, nil, nil, nil, nil, 144, 145, 131, 132, nil,
- nil, nil, nil, nil, 268, nil, nil, nil, nil, nil,
- nil, 136, 135, nil, 120, 141, 138, 137, 133, 134,
- 128, 126, 118, 140, 119, 741, 440, 146, nil, 892,
- nil, nil, nil, nil, nil, nil, nil, nil, 142, 143,
- nil, 139, 121, 122, 123, 130, 127, 129, nil, nil,
- 124, 125, nil, nil, nil, nil, 144, 145, 131, 132,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 136, 135, nil, 120, 141, 138, 137, 133,
- 134, 128, 126, 118, 140, 119, 959, 434, 146, nil,
- 960, nil, nil, nil, nil, nil, nil, nil, nil, 142,
- 143, nil, 139, 121, 122, 123, 130, 127, 129, nil,
- nil, 124, 125, nil, nil, nil, nil, 144, 145, 131,
- 132, nil, nil, nil, nil, nil, 268, nil, nil, nil,
- nil, nil, nil, 136, 135, nil, 120, 141, 138, 137,
- 133, 134, 128, 126, 118, 140, 119, 961, 440, 146,
- nil, 962, nil, nil, nil, nil, nil, nil, nil, nil,
- 142, 143, nil, 139, 121, 122, 123, 130, 127, 129,
- nil, nil, 124, 125, nil, nil, nil, nil, 144, 145,
- 131, 132, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 136, 135, nil, 120, 141, 138,
- 137, 133, 134, 128, 126, 118, 140, 119, nil, nil,
- 146 ]
-
-racc_action_check = [
- 0, 0, 0, 0, 0, 347, 321, 354, 0, 0,
- 392, 746, 746, 0, 71, 0, 0, 0, 0, 0,
- 0, 0, 71, 313, 852, 615, 313, 0, 0, 0,
- 0, 0, 0, 0, 1, 852, 0, 387, 26, 209,
- 387, 485, 0, 0, 0, 0, 0, 0, 348, 0,
- 0, 0, 0, 0, 55, 0, 0, 0, 497, 0,
- 0, 357, 0, 0, 587, 681, 366, 370, 852, 852,
- 733, 310, 310, 392, 370, 485, 734, 352, 838, 352,
- 839, 604, 604, 735, 889, 0, 615, 615, 0, 209,
- 896, 0, 497, 6, 0, 615, 0, 287, 387, 387,
- 0, 746, 681, 924, 26, 852, 746, 9, 0, 927,
- 948, 321, 354, 0, 0, 0, 0, 0, 0, 347,
- 959, 347, 0, 0, 347, 26, 736, 17, 17, 17,
- 0, 17, 960, 0, 507, 17, 17, 10, 0, 0,
- 17, 55, 17, 17, 17, 17, 17, 17, 17, 211,
- 735, 457, 457, 11, 17, 17, 17, 17, 17, 17,
- 17, 310, 348, 17, 348, 287, 357, 348, 507, 587,
- 17, 604, 366, 17, 17, 733, 17, 17, 17, 17,
- 17, 734, 17, 17, 17, 839, 17, 17, 735, 17,
- 17, 366, 838, 736, 838, 838, 366, 838, 889, 211,
- 889, 371, 287, 889, 896, 12, 896, 457, 371, 896,
- 961, 287, 17, 20, 962, 17, 17, 924, 17, 924,
- 290, 17, 924, 927, 948, 927, 948, 17, 927, 948,
- 967, 736, 293, 383, 959, 17, 959, 34, 577, 959,
- 17, 17, 17, 17, 17, 17, 960, 525, 960, 17,
- 17, 960, 686, 578, 18, 18, 18, 17, 18, 687,
- 17, 314, 18, 18, 314, 17, 17, 18, 453, 18,
- 18, 18, 18, 18, 18, 18, 698, 698, 508, 15,
- 15, 18, 18, 18, 18, 18, 18, 18, 290, 961,
- 18, 629, 36, 962, 383, 383, 383, 18, 293, 461,
- 18, 18, 41, 18, 18, 18, 18, 18, 77, 18,
- 18, 18, 508, 18, 18, 525, 18, 18, 453, 293,
- 686, 841, 37, 37, 961, 290, 961, 687, 962, 961,
- 962, 461, 698, 962, 290, 461, 461, 689, 577, 18,
- 577, 629, 18, 577, 967, 18, 967, 807, 18, 967,
- 78, 690, 525, 578, 18, 578, 642, 686, 578, 97,
- 3, 525, 18, 193, 687, 3, 686, 18, 18, 18,
- 18, 18, 18, 687, 210, 278, 18, 18, 212, 14,
- 278, 22, 22, 22, 18, 22, 385, 18, 317, 22,
- 22, 317, 18, 18, 22, 643, 22, 22, 22, 22,
- 22, 22, 22, 791, 689, 689, 642, 792, 22, 22,
- 22, 22, 22, 22, 22, 807, 213, 22, 690, 690,
- 14, 841, 389, 841, 22, 394, 841, 22, 22, 14,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 372,
- 22, 22, 689, 22, 22, 643, 372, 385, 385, 385,
- 351, 689, 807, 791, 219, 351, 690, 792, 251, 25,
- 25, 807, 860, 373, 374, 690, 22, 25, 252, 22,
- 373, 374, 22, 860, 934, 22, 934, 22, 255, 22,
- 267, 22, 280, 389, 389, 389, 394, 394, 394, 22,
- 83, 83, 13, 13, 22, 22, 22, 22, 22, 22,
- 13, 282, 703, 22, 22, 703, 860, 860, 23, 23,
- 23, 22, 23, 597, 22, 375, 23, 23, 597, 22,
- 22, 23, 375, 23, 23, 23, 23, 23, 23, 23,
- 283, 361, 296, 296, 284, 23, 23, 23, 23, 23,
- 23, 23, 744, 860, 23, 42, 42, 744, 13, 648,
- 13, 23, 289, 42, 23, 23, 291, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 292, 23, 23, 295,
- 23, 23, 301, 648, 648, 648, 648, 648, 648, 648,
- 648, 648, 648, 648, 361, 361, 648, 648, 376, 750,
- 648, 648, 361, 23, 750, 376, 23, 361, 302, 23,
- 305, 42, 23, 42, 23, 648, 23, 648, 23, 648,
- 648, 648, 648, 648, 648, 648, 23, 648, 361, 208,
- 208, 23, 23, 23, 23, 23, 23, 208, 312, 35,
- 23, 23, 315, 648, 316, 24, 24, 24, 23, 24,
- 361, 23, 361, 24, 24, 318, 23, 23, 24, 326,
- 24, 24, 24, 24, 24, 24, 24, 5, 5, 5,
- 5, 5, 24, 24, 24, 24, 24, 24, 24, 377,
- 35, 24, 288, 288, 300, 208, 377, 208, 24, 35,
- 288, 24, 24, 327, 24, 24, 24, 24, 24, 24,
- 24, 24, 24, 329, 24, 24, 330, 24, 24, 342,
- 484, 484, 484, 484, 484, 484, 484, 484, 484, 484,
- 484, 303, 303, 484, 484, 300, 110, 484, 484, 303,
- 24, 110, 110, 24, 300, 345, 24, 353, 288, 24,
- 288, 24, 484, 24, 484, 24, 484, 484, 484, 484,
- 484, 484, 484, 24, 484, 356, 355, 355, 24, 24,
- 24, 24, 24, 24, 355, 358, 430, 24, 24, 362,
- 484, 484, 27, 27, 27, 24, 27, 303, 24, 303,
- 27, 27, 388, 24, 24, 27, 391, 27, 27, 27,
- 27, 27, 27, 27, 279, 279, 279, 279, 279, 27,
- 27, 27, 27, 27, 27, 27, 410, 430, 27, 364,
- 364, 416, 355, 419, 355, 27, 430, 364, 27, 27,
- 422, 27, 27, 27, 27, 27, 27, 27, 27, 27,
- 424, 27, 27, 428, 27, 27, 429, 419, 419, 419,
- 419, 419, 419, 419, 419, 419, 419, 419, 589, 589,
- 419, 419, 346, 346, 419, 419, 589, 27, 437, 431,
- 27, 27, 463, 27, 464, 364, 27, 364, 27, 419,
- 27, 419, 27, 419, 419, 419, 419, 419, 419, 419,
- 27, 419, 561, 561, 379, 27, 27, 27, 27, 27,
- 27, 379, 720, 720, 27, 27, 628, 419, 465, 419,
- 431, 466, 27, 858, 589, 27, 589, 499, 858, 431,
- 27, 27, 30, 30, 30, 30, 30, 855, 855, 858,
- 30, 30, 949, 949, 502, 30, 503, 30, 30, 30,
- 30, 30, 30, 30, 509, 513, 514, 628, 517, 30,
- 30, 30, 30, 30, 30, 30, 628, 519, 30, 526,
- 858, 858, 858, 858, 30, 30, 462, 30, 30, 30,
- 529, 30, 30, 30, 30, 30, 538, 30, 30, 30,
- 539, 30, 30, 540, 30, 30, 553, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 462, 858,
- 19, 19, 462, 462, 19, 19, 564, 30, 568, 573,
- 30, 579, 580, 30, 619, 626, 30, 632, 30, 19,
- 637, 19, 30, 19, 19, 19, 19, 19, 19, 19,
- 30, 19, 640, 711, 711, 30, 30, 30, 30, 30,
- 30, 711, 646, 647, 30, 30, 655, 19, 657, 31,
- 31, 31, 30, 31, 669, 30, 673, 31, 31, 676,
- 30, 30, 31, 683, 31, 31, 31, 31, 31, 31,
- 31, 555, 685, 688, 691, 692, 31, 31, 31, 31,
- 31, 31, 31, 693, 696, 31, 840, 840, 697, 711,
- 699, 711, 31, 704, 840, 31, 31, 705, 31, 31,
- 31, 31, 31, 708, 31, 31, 31, 710, 31, 31,
- 712, 652, 713, 652, 652, 652, 714, 652, 555, 555,
- 555, 555, 717, 768, 768, 739, 739, 768, 768, 768,
- 722, 728, 730, 739, 31, 732, 737, 31, 739, 741,
- 31, 742, 840, 31, 840, 31, 753, 757, 758, 760,
- 652, 761, 939, 762, 764, 767, 774, 939, 652, 652,
- 652, 652, 31, 31, 31, 31, 31, 31, 939, 652,
- 795, 31, 31, 796, 799, 801, 32, 32, 32, 31,
- 32, 739, 31, 739, 32, 32, 804, 31, 31, 32,
- 805, 32, 32, 32, 32, 32, 32, 32, 824, 939,
- 939, 939, 939, 32, 32, 32, 32, 32, 32, 32,
- 925, 925, 32, 680, 680, 680, 680, 680, 925, 32,
- 480, 806, 32, 32, 811, 32, 32, 32, 32, 32,
- 814, 32, 32, 32, 815, 32, 32, 600, 939, 600,
- 600, 600, 600, 600, 830, 824, 824, 824, 824, 833,
- 843, 846, 480, 600, 847, 848, 480, 480, 480, 480,
- 870, 32, 871, 882, 32, 892, 925, 32, 925, 569,
- 32, 569, 569, 569, 893, 569, 600, 600, 898, 899,
- 907, 909, 912, 913, 600, 600, 600, 600, 914, 32,
- 32, 32, 32, 32, 32, 915, 926, 936, 32, 32,
- 944, 953, 955, 32, 956, 958, 32, nil, nil, 32,
- nil, nil, nil, nil, 32, 32, 38, 38, 38, 481,
- 38, nil, nil, 600, 38, 38, nil, nil, nil, 38,
- nil, 38, 38, 38, 38, 38, 38, 38, nil, nil,
- nil, nil, nil, 38, 38, 38, 38, 38, 38, 38,
- nil, 481, 38, nil, nil, 481, 481, 481, 481, 38,
- nil, nil, 38, 38, nil, 38, 38, 38, 38, 38,
- nil, 38, 38, 38, nil, 38, 38, nil, 38, 38,
- nil, 249, 249, 249, 249, 249, 249, 249, 249, 249,
- 249, 249, nil, nil, 249, 249, nil, nil, 249, 249,
- nil, 38, nil, nil, 38, nil, nil, 38, nil, nil,
- 38, nil, nil, 249, nil, 249, 38, 249, 249, 249,
- 249, 249, 249, 249, 38, 249, nil, nil, nil, 38,
- 38, 38, 38, 38, 38, nil, nil, nil, 38, 38,
- nil, 249, nil, 39, 39, 39, 38, 39, nil, 38,
- nil, 39, 39, nil, 38, 38, 39, nil, 39, 39,
- 39, 39, 39, 39, 39, nil, nil, nil, nil, nil,
- 39, 39, 39, 39, 39, 39, 39, nil, 829, 39,
- 829, 829, 829, nil, 829, nil, 39, nil, nil, 39,
- 39, nil, 39, 39, 39, 39, 39, nil, 39, 39,
- 39, nil, 39, 39, nil, 39, 39, nil, 427, 427,
- 427, 427, 427, 427, 427, 427, 427, 427, 427, nil,
- nil, 427, 427, nil, nil, 427, 427, nil, 39, nil,
- nil, 39, nil, nil, 39, nil, nil, 39, nil, nil,
- 427, nil, 427, 39, 427, 427, 427, 427, 427, 427,
- 427, 39, 427, nil, nil, nil, 39, 39, 39, 39,
- 39, 39, nil, nil, nil, 39, 39, nil, 427, nil,
- 40, 40, 40, 39, 40, nil, 39, nil, 40, 40,
- nil, 39, 39, 40, nil, 40, 40, 40, 40, 40,
- 40, 40, nil, nil, nil, nil, nil, 40, 40, 40,
- 40, 40, 40, 40, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, 40, nil, nil, 40, 40, nil, 40,
- 40, 40, 40, 40, nil, 40, 40, 40, nil, 40,
- 40, nil, 40, 40, nil, 446, 446, 446, 446, 446,
- 446, 446, 446, 446, 446, 446, nil, nil, 446, 446,
- nil, nil, 446, 446, nil, 40, nil, nil, 40, nil,
- nil, 40, nil, nil, 40, nil, nil, 446, nil, 446,
- 40, 446, 446, 446, 446, 446, 446, 446, 40, 446,
- nil, nil, nil, 40, 40, 40, 40, 40, 40, nil,
- nil, nil, 40, 40, nil, 446, nil, 52, 52, 52,
- 40, 52, nil, 40, nil, 52, 52, nil, 40, 40,
- 52, nil, 52, 52, 52, 52, 52, 52, 52, nil,
- nil, nil, nil, nil, 52, 52, 52, 52, 52, 52,
- 52, nil, nil, 52, nil, nil, nil, nil, nil, nil,
- 52, nil, nil, 52, 52, nil, 52, 52, 52, 52,
- 52, nil, 52, 52, 52, nil, 52, 52, nil, 52,
- 52, nil, 536, 536, 536, 536, 536, 536, 536, 536,
- 536, 536, 536, nil, nil, 536, 536, nil, nil, 536,
- 536, nil, 52, nil, nil, 52, nil, nil, 52, nil,
- nil, 52, nil, nil, 536, nil, 536, 52, 536, 536,
- 536, 536, 536, 536, 536, 52, 536, nil, nil, nil,
- 52, 52, 52, 52, 52, 52, nil, nil, nil, 52,
- 52, nil, 536, nil, 53, 53, 53, 52, 53, nil,
- 52, nil, 53, 53, nil, 52, 52, 53, nil, 53,
- 53, 53, 53, 53, 53, 53, nil, nil, nil, nil,
- nil, 53, 53, 53, 53, 53, 53, 53, nil, nil,
- 53, nil, nil, nil, nil, nil, nil, 53, nil, nil,
- 53, 53, nil, 53, 53, 53, 53, 53, 53, 53,
- 53, 53, nil, 53, 53, nil, 53, 53, nil, 695,
- 695, 695, 695, 695, 695, 695, 695, 695, 695, 695,
- nil, nil, 695, 695, nil, nil, 695, 695, nil, 53,
- nil, nil, 53, nil, nil, 53, nil, nil, 53, nil,
- 53, 695, nil, 695, 53, 695, 695, 695, 695, 695,
- 695, 695, 53, 695, nil, nil, nil, 53, 53, 53,
- 53, 53, 53, nil, nil, nil, 53, 53, nil, 695,
- nil, 54, 54, 54, 53, 54, nil, 53, nil, 54,
- 54, nil, 53, 53, 54, nil, 54, 54, 54, 54,
- 54, 54, 54, nil, nil, nil, nil, nil, 54, 54,
- 54, 54, 54, 54, 54, nil, nil, 54, nil, nil,
- nil, nil, nil, nil, 54, nil, nil, 54, 54, nil,
- 54, 54, 54, 54, 54, 54, 54, 54, 54, nil,
- 54, 54, nil, 54, 54, nil, 773, 773, 773, 773,
- 773, 773, 773, 773, 773, 773, 773, nil, nil, 773,
- 773, nil, nil, 773, 773, nil, 54, nil, nil, 54,
- nil, nil, 54, nil, nil, 54, nil, nil, 773, nil,
- 773, 54, 773, 773, 773, 773, 773, 773, 773, 54,
- 773, nil, nil, nil, 54, 54, 54, 54, 54, 54,
- nil, nil, nil, 54, 54, nil, 773, nil, 57, 57,
- 57, 54, 57, nil, 54, nil, 57, 57, nil, 54,
- 54, 57, nil, 57, 57, 57, 57, 57, 57, 57,
- nil, nil, nil, nil, nil, 57, 57, 57, 57, 57,
- 57, 57, nil, nil, 57, nil, nil, nil, nil, nil,
- nil, 57, nil, nil, 57, 57, nil, 57, 57, 57,
- 57, 57, nil, 57, 57, 57, nil, 57, 57, nil,
- 57, 57, nil, 779, 779, 779, 779, 779, 779, 779,
- 779, 779, 779, 779, nil, nil, 779, 779, nil, nil,
- 779, 779, nil, 57, nil, nil, 57, nil, nil, 57,
- nil, nil, 57, nil, nil, 779, nil, 779, 57, 779,
- 779, 779, 779, 779, 779, 779, 57, 779, nil, nil,
- nil, 57, 57, 57, 57, 57, 57, nil, nil, nil,
- 57, 57, nil, 779, nil, 58, 58, 58, 57, 58,
- nil, 57, nil, 58, 58, nil, 57, 57, 58, nil,
- 58, 58, 58, 58, 58, 58, 58, nil, nil, nil,
- nil, nil, 58, 58, 58, 58, 58, 58, 58, nil,
- nil, 58, nil, nil, nil, nil, nil, nil, 58, nil,
- nil, 58, 58, nil, 58, 58, 58, 58, 58, nil,
- 58, 58, 58, nil, 58, 58, nil, 58, 58, nil,
- 781, 781, 781, 781, 781, 781, 781, 781, 781, 781,
- 781, nil, nil, 781, 781, nil, nil, 781, 781, nil,
- 58, nil, nil, 58, nil, nil, 58, nil, nil, 58,
- nil, nil, 781, nil, 781, 58, 781, 781, 781, 781,
- 781, 781, 781, 58, 781, nil, nil, nil, 58, 58,
- 58, 58, 58, 58, nil, nil, nil, 58, 58, nil,
- 781, nil, 61, 61, 61, 58, 61, nil, 58, nil,
- 61, 61, nil, 58, 58, 61, nil, 61, 61, 61,
- 61, 61, 61, 61, nil, nil, nil, nil, nil, 61,
- 61, 61, 61, 61, 61, 61, nil, nil, 61, nil,
- nil, nil, nil, nil, nil, 61, nil, nil, 61, 61,
- nil, 61, 61, 61, 61, 61, nil, 61, 61, 61,
- nil, 61, 61, nil, 61, 61, nil, 672, 672, 672,
- 672, 672, 672, 672, 672, 672, 672, 672, nil, nil,
- 672, 672, nil, nil, 672, 672, nil, 61, nil, nil,
- 61, nil, nil, 61, nil, nil, 61, nil, nil, 672,
- nil, 672, 61, 672, 672, 672, 672, 672, 672, 672,
- 61, 672, nil, nil, nil, 61, 61, 61, 61, 61,
- 61, nil, nil, nil, 61, 61, 61, 672, nil, 672,
- nil, 61, 61, nil, nil, 61, nil, nil, nil, nil,
- 61, 61, 62, 62, 62, nil, 62, nil, nil, nil,
- 62, 62, nil, nil, nil, 62, nil, 62, 62, 62,
- 62, 62, 62, 62, nil, nil, nil, nil, nil, 62,
- 62, 62, 62, 62, 62, 62, nil, nil, 62, nil,
- nil, nil, nil, nil, nil, 62, nil, nil, 62, 62,
- nil, 62, 62, 62, 62, 62, nil, 62, 62, 62,
- nil, 62, 62, 784, 784, 784, 784, 784, 784, 784,
- 784, 784, 784, 784, 467, nil, 784, 784, nil, nil,
- 784, 784, nil, nil, nil, nil, nil, 62, nil, nil,
- 62, 467, 467, 62, nil, 784, 62, 784, 62, 784,
- 784, 784, 784, 784, 784, 784, 467, 784, 467, nil,
- 467, 467, 467, 467, nil, 62, 62, 62, 62, 62,
- 62, nil, nil, 784, 62, 62, nil, nil, nil, 63,
- 63, 63, 62, 63, nil, 62, nil, 63, 63, nil,
- 62, 62, 63, nil, 63, 63, 63, 63, 63, 63,
- 63, nil, nil, nil, nil, nil, 63, 63, 63, 63,
- 63, 63, 63, nil, nil, 63, nil, nil, nil, nil,
- nil, nil, 63, nil, nil, 63, 63, nil, 63, 63,
- 63, 63, 63, nil, 63, 63, 63, nil, 63, 63,
- 786, 786, 786, 786, 786, 786, 786, 786, 786, 786,
- 786, 468, nil, 786, 786, nil, nil, 786, 786, nil,
- nil, 63, nil, nil, 63, nil, nil, 63, 468, 468,
- 63, nil, 786, 63, 786, nil, 786, 786, 786, 786,
- 786, 786, 786, 468, 786, 468, nil, 468, 468, 468,
- 468, nil, 63, 63, 63, 63, 63, 63, nil, nil,
- 786, 63, 63, nil, nil, nil, 84, 84, 84, 63,
- 84, nil, 63, nil, 84, 84, nil, 63, 63, 84,
- nil, 84, 84, 84, 84, 84, 84, 84, nil, 84,
- nil, nil, nil, 84, 84, 84, 84, 84, 84, 84,
- nil, nil, 84, nil, nil, nil, nil, nil, nil, 84,
- nil, nil, 84, 84, nil, 84, 84, 84, 84, 84,
- 84, 84, 84, 84, nil, 84, 84, nil, 84, 84,
- nil, 793, 793, 793, 793, 793, 793, 793, 793, 793,
- 793, 793, nil, nil, 793, 793, nil, nil, 793, 793,
- nil, 84, nil, nil, 84, 84, nil, 84, nil, nil,
- 84, nil, 84, 793, 84, 793, 84, 793, 793, 793,
- 793, 793, 793, 793, 84, 793, 84, nil, nil, 84,
- 84, 84, 84, 84, 84, nil, nil, nil, 84, 84,
- nil, 793, nil, 87, 87, 87, 84, 87, nil, 84,
- nil, 87, 87, nil, 84, 84, 87, nil, 87, 87,
- 87, 87, 87, 87, 87, nil, 87, nil, nil, nil,
- 87, 87, 87, 87, 87, 87, 87, nil, nil, 87,
- nil, nil, nil, nil, nil, nil, 87, nil, nil, 87,
- 87, nil, 87, 87, 87, 87, 87, 87, 87, 87,
- 87, nil, 87, 87, nil, 87, 87, nil, 873, 873,
- 873, 873, 873, 873, 873, 873, 873, 873, 873, nil,
- nil, 873, 873, nil, nil, 873, 873, nil, 87, nil,
- nil, 87, 87, nil, 87, nil, nil, 87, nil, 87,
- 873, 87, 873, 87, 873, 873, 873, 873, 873, 873,
- 873, 87, 873, 87, nil, nil, 87, 87, 87, 87,
- 87, 87, nil, nil, nil, 87, 87, nil, 873, nil,
- nil, nil, nil, 87, nil, nil, 87, nil, nil, nil,
- nil, 87, 87, 99, 99, 99, 99, 99, nil, nil,
- nil, 99, 99, nil, nil, nil, 99, nil, 99, 99,
- 99, 99, 99, 99, 99, nil, nil, nil, nil, nil,
- 99, 99, 99, 99, 99, 99, 99, nil, nil, 99,
- nil, nil, nil, nil, nil, 99, 99, 99, 99, 99,
- 99, nil, 99, 99, 99, 99, 99, nil, 99, 99,
- 99, nil, 99, 99, nil, 99, 99, nil, 875, 875,
- 875, 875, 875, 875, 875, 875, 875, 875, 875, nil,
- nil, 875, 875, nil, nil, 875, 875, nil, 99, nil,
- nil, 99, nil, nil, 99, nil, nil, 99, nil, 99,
- 875, nil, 875, 99, 875, 875, 875, 875, 875, 875,
- 875, 99, 875, nil, nil, nil, 99, 99, 99, 99,
- 99, 99, nil, nil, nil, 99, 99, nil, 875, nil,
- nil, nil, 99, 99, nil, nil, 99, nil, nil, nil,
- nil, 99, 99, 103, 103, 103, nil, 103, nil, nil,
- nil, 103, 103, nil, nil, nil, 103, nil, 103, 103,
- 103, 103, 103, 103, 103, nil, nil, nil, nil, nil,
- 103, 103, 103, 103, 103, 103, 103, nil, 338, 103,
- 338, 338, 338, nil, 338, nil, 103, nil, nil, 103,
- 103, nil, 103, 103, 103, 103, 103, nil, 103, 103,
- 103, nil, 103, 103, nil, 103, 103, 566, nil, 566,
- 566, 566, nil, 566, nil, nil, 718, 338, 718, 718,
- 718, nil, 718, nil, nil, 338, nil, nil, 103, nil,
- nil, 103, nil, nil, 103, nil, nil, 103, nil, nil,
- nil, nil, nil, 103, nil, nil, 566, nil, nil, nil,
- nil, 103, nil, nil, 566, 718, 103, 103, 103, 103,
- 103, 103, nil, 718, nil, 103, 103, nil, nil, nil,
- 104, 104, 104, 103, 104, nil, 103, nil, 104, 104,
- nil, 103, 103, 104, nil, 104, 104, 104, 104, 104,
- 104, 104, nil, nil, nil, nil, nil, 104, 104, 104,
- 104, 104, 104, 104, nil, nil, 104, nil, nil, nil,
- nil, nil, nil, 104, nil, nil, 104, 104, nil, 104,
- 104, 104, 104, 104, nil, 104, 104, 104, nil, 104,
- 104, nil, 104, 104, nil, 459, 459, 459, 459, 459,
- 459, 459, 459, 459, 459, 459, nil, nil, 459, 459,
- nil, nil, 459, 459, nil, 104, nil, nil, 104, nil,
- nil, 104, nil, nil, 104, nil, nil, 459, nil, 459,
- 104, 459, 459, 459, 459, 459, 459, 459, 104, 459,
- nil, nil, nil, 104, 104, 104, 104, 104, 104, nil,
- nil, nil, 104, 104, nil, nil, nil, 105, 105, 105,
- 104, 105, nil, 104, nil, 105, 105, nil, 104, 104,
- 105, nil, 105, 105, 105, 105, 105, 105, 105, nil,
- nil, nil, nil, nil, 105, 105, 105, 105, 105, 105,
- 105, nil, nil, 105, nil, nil, nil, nil, nil, nil,
- 105, nil, nil, 105, 105, nil, 105, 105, 105, 105,
- 105, nil, 105, 105, 105, nil, 105, 105, nil, 105,
- 105, nil, 460, 460, 460, 460, 460, 460, 460, 460,
- 460, 460, 460, nil, nil, 460, 460, nil, nil, 460,
- 460, nil, 105, nil, nil, 105, nil, nil, 105, nil,
- nil, 105, nil, nil, 460, nil, 460, 105, 460, 460,
- 460, 460, 460, 460, 460, 105, 460, nil, nil, nil,
- 105, 105, 105, 105, 105, 105, nil, nil, nil, 105,
- 105, nil, nil, nil, 106, 106, 106, 105, 106, nil,
- 105, nil, 106, 106, nil, 105, 105, 106, nil, 106,
- 106, 106, 106, 106, 106, 106, nil, nil, nil, nil,
- nil, 106, 106, 106, 106, 106, 106, 106, nil, nil,
- 106, nil, nil, nil, nil, nil, nil, 106, nil, nil,
- 106, 106, nil, 106, 106, 106, 106, 106, nil, 106,
- 106, 106, nil, 106, 106, nil, 106, 106, nil, 470,
- 470, 470, 470, 470, 470, 470, nil, nil, 470, 470,
- nil, nil, nil, nil, nil, nil, 470, 470, nil, 106,
- nil, nil, 106, nil, nil, 106, nil, nil, 106, nil,
- nil, 470, nil, 470, 106, 470, 470, 470, 470, 470,
- 470, 470, 106, 470, nil, nil, nil, 106, 106, 106,
- 106, 106, 106, nil, nil, nil, 106, 106, nil, nil,
- nil, nil, nil, nil, 106, nil, nil, 106, nil, nil,
- nil, nil, 106, 106, 107, 107, 107, 107, 107, nil,
- nil, nil, 107, 107, nil, nil, nil, 107, nil, 107,
- 107, 107, 107, 107, 107, 107, nil, nil, nil, nil,
- nil, 107, 107, 107, 107, 107, 107, 107, nil, nil,
- 107, nil, nil, nil, nil, nil, 107, 107, nil, 107,
- 107, 107, nil, 107, 107, 107, 107, 107, nil, 107,
- 107, 107, nil, 107, 107, nil, 107, 107, nil, 471,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 471, 471, nil, 107,
- nil, nil, 107, nil, nil, 107, nil, nil, 107, nil,
- 107, 471, nil, 471, 107, 471, 471, 471, 471, nil,
- nil, 471, 107, 471, nil, nil, nil, 107, 107, 107,
- 107, 107, 107, nil, nil, nil, 107, 107, nil, nil,
- nil, nil, nil, nil, 107, nil, nil, 107, nil, nil,
- nil, nil, 107, 107, 108, 108, 108, 108, 108, nil,
- nil, nil, 108, 108, nil, nil, nil, 108, nil, 108,
- 108, 108, 108, 108, 108, 108, nil, nil, nil, nil,
- nil, 108, 108, 108, 108, 108, 108, 108, nil, nil,
- 108, nil, nil, nil, nil, nil, 108, 108, 108, 108,
- 108, 108, nil, 108, 108, 108, 108, 108, nil, 108,
- 108, 108, nil, 108, 108, nil, 108, 108, nil, 472,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 472, 472, nil, 108,
- nil, nil, 108, nil, nil, 108, nil, nil, 108, nil,
- 108, 472, nil, 472, 108, 472, 472, 472, 472, nil,
- nil, 472, 108, 472, nil, nil, nil, 108, 108, 108,
- 108, 108, 108, nil, nil, nil, 108, 108, nil, nil,
- nil, nil, nil, nil, 108, nil, nil, 108, nil, nil,
- nil, nil, 108, 108, 195, 195, 195, 195, 195, nil,
- nil, nil, 195, 195, nil, nil, nil, 195, nil, 195,
- 195, 195, 195, 195, 195, 195, nil, nil, nil, nil,
- nil, 195, 195, 195, 195, 195, 195, 195, nil, nil,
- 195, nil, nil, nil, nil, nil, 195, 195, nil, 195,
- 195, 195, nil, 195, 195, 195, 195, 195, nil, 195,
- 195, 195, nil, 195, 195, nil, 195, 195, nil, 473,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 473, 473, nil, 195,
- nil, nil, 195, nil, nil, 195, nil, nil, 195, nil,
- 195, 473, nil, 473, 195, 473, 473, 473, 473, nil,
- nil, 473, 195, 473, nil, nil, nil, 195, 195, 195,
- 195, 195, 195, nil, nil, nil, 195, 195, nil, nil,
- nil, 196, 196, 196, 195, 196, nil, 195, nil, 196,
- 196, nil, 195, 195, 196, nil, 196, 196, 196, 196,
- 196, 196, 196, nil, nil, nil, nil, nil, 196, 196,
- 196, 196, 196, 196, 196, nil, nil, 196, nil, nil,
- nil, nil, nil, nil, 196, nil, nil, 196, 196, nil,
- 196, 196, 196, 196, 196, nil, 196, 196, 196, nil,
- 196, 196, nil, 196, 196, nil, 474, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 474, 474, nil, 196, nil, nil, 196,
- nil, nil, 196, nil, nil, 196, nil, 196, 474, nil,
- 474, 196, 474, 474, 474, 474, nil, nil, 474, 196,
- 474, nil, nil, nil, 196, 196, 196, 196, 196, 196,
- nil, nil, nil, 196, 196, nil, nil, nil, 197, 197,
- 197, 196, 197, nil, 196, nil, 197, 197, nil, 196,
- 196, 197, nil, 197, 197, 197, 197, 197, 197, 197,
- nil, nil, nil, nil, nil, 197, 197, 197, 197, 197,
- 197, 197, nil, nil, 197, nil, nil, nil, nil, nil,
- nil, 197, nil, nil, 197, 197, nil, 197, 197, 197,
- 197, 197, nil, 197, 197, 197, nil, 197, 197, nil,
- 197, 197, nil, 475, 475, 475, 475, 475, 475, 475,
- nil, nil, 475, 475, nil, nil, nil, nil, nil, nil,
- 475, 475, nil, 197, nil, nil, 197, nil, nil, 197,
- nil, nil, 197, nil, 197, 475, nil, 475, 197, 475,
- 475, 475, 475, 475, 475, 475, 197, 475, nil, nil,
- nil, 197, 197, 197, 197, 197, 197, nil, nil, nil,
- 197, 197, nil, nil, nil, 198, 198, 198, 197, 198,
- nil, 197, nil, 198, 198, nil, 197, 197, 198, nil,
- 198, 198, 198, 198, 198, 198, 198, nil, nil, nil,
- nil, nil, 198, 198, 198, 198, 198, 198, 198, nil,
- nil, 198, nil, nil, nil, nil, nil, nil, 198, nil,
- nil, 198, 198, nil, 198, 198, 198, 198, 198, nil,
- 198, 198, 198, nil, 198, 198, nil, 198, 198, nil,
- 476, 476, 476, 476, 476, 476, 476, nil, nil, 476,
- 476, nil, nil, nil, nil, nil, nil, 476, 476, nil,
- 198, nil, nil, 198, nil, nil, 198, nil, nil, 198,
- nil, nil, 476, nil, 476, 198, 476, 476, 476, 476,
- 476, 476, 476, 198, 476, nil, nil, nil, 198, 198,
- 198, 198, 198, 198, nil, nil, nil, 198, 198, nil,
- nil, nil, 199, 199, 199, 198, 199, nil, 198, nil,
- 199, 199, nil, 198, 198, 199, nil, 199, 199, 199,
- 199, 199, 199, 199, nil, nil, nil, nil, nil, 199,
- 199, 199, 199, 199, 199, 199, nil, nil, 199, nil,
- nil, nil, nil, nil, nil, 199, nil, nil, 199, 199,
- nil, 199, 199, 199, 199, 199, 199, 199, 199, 199,
- nil, 199, 199, nil, 199, 199, nil, 477, 477, 477,
- 477, 477, 477, 477, nil, nil, 477, 477, nil, nil,
- nil, nil, nil, nil, 477, 477, nil, 199, nil, nil,
- 199, nil, nil, 199, nil, nil, 199, nil, 199, 477,
- nil, 477, 199, 477, 477, 477, 477, 477, 477, 477,
- 199, 477, nil, nil, nil, 199, 199, 199, 199, 199,
- 199, nil, nil, nil, 199, 199, nil, nil, nil, 200,
- 200, 200, 199, 200, nil, 199, nil, 200, 200, nil,
- 199, 199, 200, nil, 200, 200, 200, 200, 200, 200,
- 200, nil, nil, nil, nil, nil, 200, 200, 200, 200,
- 200, 200, 200, nil, nil, 200, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 200, 200, nil, 200, 200,
- 200, 200, 200, 200, 200, 200, 200, nil, 200, 200,
- nil, 200, 200, nil, 478, 478, 478, 478, 478, 478,
- 478, nil, nil, 478, 478, nil, nil, nil, nil, nil,
- nil, 478, 478, nil, 200, nil, nil, 200, nil, nil,
- 200, nil, nil, 200, nil, 200, 478, nil, 478, 200,
- 478, 478, 478, 478, 478, 478, 478, 200, 478, nil,
- nil, nil, 200, 200, 200, 200, 200, 200, nil, nil,
- nil, 200, 200, nil, nil, nil, 204, 204, 204, 200,
- 204, nil, 200, nil, 204, 204, nil, 200, 200, 204,
- nil, 204, 204, 204, 204, 204, 204, 204, nil, nil,
- nil, nil, nil, 204, 204, 204, 204, 204, 204, 204,
- nil, nil, 204, nil, nil, nil, nil, nil, nil, 204,
- nil, nil, 204, 204, nil, 204, 204, 204, 204, 204,
- nil, 204, 204, 204, nil, 204, 204, nil, 204, 204,
- nil, 479, 479, 479, 479, 479, 479, 479, nil, nil,
- 479, 479, nil, nil, nil, nil, nil, nil, 479, 479,
- nil, 204, nil, nil, 204, nil, nil, 204, nil, nil,
- 204, nil, nil, 479, nil, 479, 204, 479, 479, 479,
- 479, 479, 479, 479, 204, 479, nil, nil, nil, 204,
- 204, 204, 204, 204, 204, nil, nil, nil, 204, 204,
- nil, nil, nil, 205, 205, 205, 204, 205, nil, 204,
- nil, 205, 205, nil, 204, 204, 205, nil, 205, 205,
- 205, 205, 205, 205, 205, nil, nil, nil, nil, nil,
- 205, 205, 205, 205, 205, 205, 205, nil, nil, 205,
- nil, nil, nil, nil, nil, nil, 205, nil, nil, 205,
- 205, nil, 205, 205, 205, 205, 205, nil, 205, 205,
- 205, nil, 205, 205, nil, 205, 205, nil, 482, 482,
- 482, 482, 482, 482, 482, nil, nil, 482, 482, nil,
- nil, nil, nil, nil, nil, 482, 482, nil, 205, nil,
- nil, 205, nil, nil, 205, nil, nil, 205, nil, nil,
- 482, nil, 482, 205, 482, 482, 482, 482, 482, 482,
- 482, 205, 482, nil, nil, nil, 205, 205, 205, 205,
- 205, 205, nil, nil, nil, 205, 205, nil, nil, nil,
- 206, 206, 206, 205, 206, nil, 205, nil, 206, 206,
- nil, 205, 205, 206, nil, 206, 206, 206, 206, 206,
- 206, 206, nil, nil, nil, nil, nil, 206, 206, 206,
- 206, 206, 206, 206, nil, nil, 206, nil, nil, nil,
- nil, nil, nil, 206, nil, nil, 206, 206, nil, 206,
- 206, 206, 206, 206, nil, 206, 206, 206, nil, 206,
- 206, nil, 206, 206, nil, 483, 483, 483, 483, 483,
- 483, 483, 483, nil, 483, 483, nil, nil, nil, nil,
- nil, nil, 483, 483, nil, 206, nil, nil, 206, nil,
- nil, 206, nil, nil, 206, nil, nil, 483, nil, 483,
- 206, 483, 483, 483, 483, 483, 483, 483, 206, 483,
- nil, nil, nil, 206, 206, 206, 206, 206, 206, nil,
- nil, nil, 206, 206, nil, nil, nil, nil, nil, nil,
- 206, nil, nil, 206, nil, nil, nil, nil, 206, 206,
- 214, 214, 214, 214, 214, nil, nil, nil, 214, 214,
- nil, nil, nil, 214, nil, 214, 214, 214, 214, 214,
- 214, 214, nil, nil, nil, nil, nil, 214, 214, 214,
- 214, 214, 214, 214, nil, nil, 214, nil, nil, nil,
- nil, nil, 214, 214, nil, 214, 214, 214, nil, 214,
- 214, 214, 214, 214, nil, 214, 214, 214, nil, 214,
- 214, nil, 214, 214, nil, 469, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 469, 469, nil, 214, nil, nil, 214, nil,
- nil, 214, nil, nil, 214, nil, 214, 469, nil, nil,
- 214, 469, 469, 469, 469, nil, nil, nil, 214, nil,
- nil, nil, nil, 214, 214, 214, 214, 214, 214, nil,
- nil, nil, 214, 214, nil, nil, nil, 215, 215, 215,
- 214, 215, nil, 214, nil, 215, 215, nil, 214, 214,
- 215, nil, 215, 215, 215, 215, 215, 215, 215, nil,
- nil, nil, nil, nil, 215, 215, 215, 215, 215, 215,
- 215, nil, nil, 215, nil, nil, nil, nil, nil, nil,
- 215, nil, nil, 215, 215, nil, 215, 215, 215, 215,
- 215, nil, 215, 215, 215, nil, 215, 215, nil, 215,
- 215, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 215, nil, nil, 215, nil, 215, 215, nil,
- nil, 215, nil, nil, nil, nil, nil, 215, nil, nil,
- nil, nil, nil, nil, nil, 215, nil, nil, nil, nil,
- 215, 215, 215, 215, 215, 215, nil, nil, nil, 215,
- 215, nil, nil, nil, 218, 218, 218, 215, 218, nil,
- 215, nil, 218, 218, nil, 215, 215, 218, nil, 218,
- 218, 218, 218, 218, 218, 218, nil, nil, nil, nil,
- nil, 218, 218, 218, 218, 218, 218, 218, nil, nil,
- 218, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- 218, 218, nil, 218, 218, 218, 218, 218, nil, 218,
- 218, 218, nil, 218, 218, nil, 218, 218, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 218,
- nil, nil, 218, nil, nil, 218, nil, nil, 218, nil,
- nil, nil, nil, nil, 218, nil, nil, nil, nil, nil,
- nil, nil, 218, nil, nil, nil, nil, 218, 218, 218,
- 218, 218, 218, nil, nil, nil, 218, 218, nil, nil,
- nil, 220, 220, 220, 218, 220, nil, 218, nil, 220,
- 220, nil, 218, 218, 220, nil, 220, 220, 220, 220,
- 220, 220, 220, nil, nil, nil, nil, nil, 220, 220,
- 220, 220, 220, 220, 220, nil, nil, 220, nil, nil,
- nil, nil, nil, nil, 220, nil, nil, 220, 220, nil,
- 220, 220, 220, 220, 220, nil, 220, 220, 220, nil,
- 220, 220, nil, 220, 220, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 220, nil, nil, 220,
- nil, nil, 220, nil, nil, 220, nil, nil, nil, nil,
- nil, 220, nil, nil, nil, nil, nil, nil, nil, 220,
- nil, nil, nil, nil, 220, 220, 220, 220, 220, 220,
- nil, nil, nil, 220, 220, nil, nil, nil, 221, 221,
- 221, 220, 221, nil, 220, nil, 221, 221, nil, 220,
- 220, 221, nil, 221, 221, 221, 221, 221, 221, 221,
- nil, nil, nil, nil, nil, 221, 221, 221, 221, 221,
- 221, 221, nil, nil, 221, nil, nil, nil, nil, nil,
- nil, 221, nil, nil, 221, 221, nil, 221, 221, 221,
- 221, 221, nil, 221, 221, 221, nil, 221, 221, nil,
- 221, 221, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 221, nil, nil, 221, nil, nil, 221,
- nil, nil, 221, nil, nil, nil, nil, nil, 221, nil,
- nil, nil, nil, nil, nil, nil, 221, nil, nil, nil,
- nil, 221, 221, 221, 221, 221, 221, nil, nil, nil,
- 221, 221, nil, nil, nil, 222, 222, 222, 221, 222,
- nil, 221, nil, 222, 222, nil, 221, 221, 222, nil,
- 222, 222, 222, 222, 222, 222, 222, nil, nil, nil,
- nil, nil, 222, 222, 222, 222, 222, 222, 222, nil,
- nil, 222, nil, nil, nil, nil, nil, nil, 222, nil,
- nil, 222, 222, nil, 222, 222, 222, 222, 222, nil,
- 222, 222, 222, nil, 222, 222, nil, 222, 222, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 222, nil, nil, 222, nil, nil, 222, nil, nil, 222,
- nil, nil, nil, nil, nil, 222, nil, nil, nil, nil,
- nil, nil, nil, 222, nil, nil, nil, nil, 222, 222,
- 222, 222, 222, 222, nil, nil, nil, 222, 222, nil,
- nil, nil, 223, 223, 223, 222, 223, nil, 222, nil,
- 223, 223, nil, 222, 222, 223, nil, 223, 223, 223,
- 223, 223, 223, 223, nil, nil, nil, nil, nil, 223,
- 223, 223, 223, 223, 223, 223, nil, nil, 223, nil,
- nil, nil, nil, nil, nil, 223, nil, nil, 223, 223,
- nil, 223, 223, 223, 223, 223, nil, 223, 223, 223,
- nil, 223, 223, nil, 223, 223, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 223, nil, nil,
- 223, nil, nil, 223, nil, nil, 223, nil, nil, nil,
- nil, nil, 223, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, nil, nil, 223, 223, 223, 223, 223,
- 223, nil, nil, nil, 223, 223, nil, nil, nil, 224,
- 224, 224, 223, 224, nil, 223, nil, 224, 224, nil,
- 223, 223, 224, nil, 224, 224, 224, 224, 224, 224,
- 224, nil, nil, nil, nil, nil, 224, 224, 224, 224,
- 224, 224, 224, nil, nil, 224, nil, nil, nil, nil,
- nil, nil, 224, nil, nil, 224, 224, nil, 224, 224,
- 224, 224, 224, nil, 224, 224, 224, nil, 224, 224,
- nil, 224, 224, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 224, nil, nil, 224, nil, nil,
- 224, nil, nil, 224, nil, nil, nil, nil, nil, 224,
- nil, nil, nil, nil, nil, nil, nil, 224, nil, nil,
- nil, nil, 224, 224, 224, 224, 224, 224, nil, nil,
- nil, 224, 224, nil, nil, nil, 225, 225, 225, 224,
- 225, nil, 224, nil, 225, 225, nil, 224, 224, 225,
- nil, 225, 225, 225, 225, 225, 225, 225, nil, nil,
- nil, nil, nil, 225, 225, 225, 225, 225, 225, 225,
- nil, nil, 225, nil, nil, nil, nil, nil, nil, 225,
- nil, nil, 225, 225, nil, 225, 225, 225, 225, 225,
- nil, 225, 225, 225, nil, 225, 225, nil, 225, 225,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 225, nil, nil, 225, nil, nil, 225, nil, nil,
- 225, nil, nil, nil, nil, nil, 225, nil, nil, nil,
- nil, nil, nil, nil, 225, nil, nil, nil, nil, 225,
- 225, 225, 225, 225, 225, nil, nil, nil, 225, 225,
- nil, nil, nil, 226, 226, 226, 225, 226, nil, 225,
- nil, 226, 226, nil, 225, 225, 226, nil, 226, 226,
- 226, 226, 226, 226, 226, nil, nil, nil, nil, nil,
- 226, 226, 226, 226, 226, 226, 226, nil, nil, 226,
- nil, nil, nil, nil, nil, nil, 226, nil, nil, 226,
- 226, nil, 226, 226, 226, 226, 226, nil, 226, 226,
- 226, nil, 226, 226, nil, 226, 226, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 226, nil,
- nil, 226, nil, nil, 226, nil, nil, 226, nil, nil,
- nil, nil, nil, 226, nil, nil, nil, nil, nil, nil,
- nil, 226, nil, nil, nil, nil, 226, 226, 226, 226,
- 226, 226, nil, nil, nil, 226, 226, nil, nil, nil,
- 227, 227, 227, 226, 227, nil, 226, nil, 227, 227,
- nil, 226, 226, 227, nil, 227, 227, 227, 227, 227,
- 227, 227, nil, nil, nil, nil, nil, 227, 227, 227,
- 227, 227, 227, 227, nil, nil, 227, nil, nil, nil,
- nil, nil, nil, 227, nil, nil, 227, 227, nil, 227,
- 227, 227, 227, 227, nil, 227, 227, 227, nil, 227,
- 227, nil, 227, 227, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 227, nil, nil, 227, nil,
- nil, 227, nil, nil, 227, nil, nil, nil, nil, nil,
- 227, nil, nil, nil, nil, nil, nil, nil, 227, nil,
- nil, nil, nil, 227, 227, 227, 227, 227, 227, nil,
- nil, nil, 227, 227, nil, nil, nil, 228, 228, 228,
- 227, 228, nil, 227, nil, 228, 228, nil, 227, 227,
- 228, nil, 228, 228, 228, 228, 228, 228, 228, nil,
- nil, nil, nil, nil, 228, 228, 228, 228, 228, 228,
- 228, nil, nil, 228, nil, nil, nil, nil, nil, nil,
- 228, nil, nil, 228, 228, nil, 228, 228, 228, 228,
- 228, nil, 228, 228, 228, nil, 228, 228, nil, 228,
- 228, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 228, nil, nil, 228, nil, nil, 228, nil,
- nil, 228, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 228, 228, 228, 228, 228, 228, nil, nil, nil, 228,
- 228, nil, nil, nil, 229, 229, 229, 228, 229, nil,
- 228, nil, 229, 229, nil, 228, 228, 229, nil, 229,
- 229, 229, 229, 229, 229, 229, nil, nil, nil, nil,
- nil, 229, 229, 229, 229, 229, 229, 229, nil, nil,
- 229, nil, nil, nil, nil, nil, nil, 229, nil, nil,
- 229, 229, nil, 229, 229, 229, 229, 229, nil, 229,
- 229, 229, nil, 229, 229, nil, 229, 229, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 229,
- nil, nil, 229, nil, nil, 229, nil, nil, 229, nil,
- nil, nil, nil, nil, 229, nil, nil, nil, nil, nil,
- nil, nil, 229, nil, nil, nil, nil, 229, 229, 229,
- 229, 229, 229, nil, nil, nil, 229, 229, nil, nil,
- nil, 230, 230, 230, 229, 230, nil, 229, nil, 230,
- 230, nil, 229, 229, 230, nil, 230, 230, 230, 230,
- 230, 230, 230, nil, nil, nil, nil, nil, 230, 230,
- 230, 230, 230, 230, 230, nil, nil, 230, nil, nil,
- nil, nil, nil, nil, 230, nil, nil, 230, 230, nil,
- 230, 230, 230, 230, 230, nil, 230, 230, 230, nil,
- 230, 230, nil, 230, 230, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 230, nil, nil, 230,
- nil, nil, 230, nil, nil, 230, nil, nil, nil, nil,
- nil, 230, nil, nil, nil, nil, nil, nil, nil, 230,
- nil, nil, nil, nil, 230, 230, 230, 230, 230, 230,
- nil, nil, nil, 230, 230, nil, nil, nil, 231, 231,
- 231, 230, 231, nil, 230, nil, 231, 231, nil, 230,
- 230, 231, nil, 231, 231, 231, 231, 231, 231, 231,
- nil, nil, nil, nil, nil, 231, 231, 231, 231, 231,
- 231, 231, nil, nil, 231, nil, nil, nil, nil, nil,
- nil, 231, nil, nil, 231, 231, nil, 231, 231, 231,
- 231, 231, nil, 231, 231, 231, nil, 231, 231, nil,
- 231, 231, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 231, nil, nil, 231, nil, nil, 231,
- nil, nil, 231, nil, nil, nil, nil, nil, 231, nil,
- nil, nil, nil, nil, nil, nil, 231, nil, nil, nil,
- nil, 231, 231, 231, 231, 231, 231, nil, nil, nil,
- 231, 231, nil, nil, nil, 232, 232, 232, 231, 232,
- nil, 231, nil, 232, 232, nil, 231, 231, 232, nil,
- 232, 232, 232, 232, 232, 232, 232, nil, nil, nil,
- nil, nil, 232, 232, 232, 232, 232, 232, 232, nil,
- nil, 232, nil, nil, nil, nil, nil, nil, 232, nil,
- nil, 232, 232, nil, 232, 232, 232, 232, 232, nil,
- 232, 232, 232, nil, 232, 232, nil, 232, 232, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 232, nil, nil, 232, nil, nil, 232, nil, nil, 232,
- nil, nil, nil, nil, nil, 232, nil, nil, nil, nil,
- nil, nil, nil, 232, nil, nil, nil, nil, 232, 232,
- 232, 232, 232, 232, nil, nil, nil, 232, 232, nil,
- nil, nil, 233, 233, 233, 232, 233, nil, 232, nil,
- 233, 233, nil, 232, 232, 233, nil, 233, 233, 233,
- 233, 233, 233, 233, nil, nil, nil, nil, nil, 233,
- 233, 233, 233, 233, 233, 233, nil, nil, 233, nil,
- nil, nil, nil, nil, nil, 233, nil, nil, 233, 233,
- nil, 233, 233, 233, 233, 233, nil, 233, 233, 233,
- nil, 233, 233, nil, 233, 233, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 233, nil, nil,
- 233, nil, nil, 233, nil, nil, 233, nil, nil, nil,
- nil, nil, 233, nil, nil, nil, nil, nil, nil, nil,
- 233, nil, nil, nil, nil, 233, 233, 233, 233, 233,
- 233, nil, nil, nil, 233, 233, nil, nil, nil, 234,
- 234, 234, 233, 234, nil, 233, nil, 234, 234, nil,
- 233, 233, 234, nil, 234, 234, 234, 234, 234, 234,
- 234, nil, nil, nil, nil, nil, 234, 234, 234, 234,
- 234, 234, 234, nil, nil, 234, nil, nil, nil, nil,
- nil, nil, 234, nil, nil, 234, 234, nil, 234, 234,
- 234, 234, 234, nil, 234, 234, 234, nil, 234, 234,
- nil, 234, 234, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 234, nil, nil, 234, nil, nil,
- 234, nil, nil, 234, nil, nil, nil, nil, nil, 234,
- nil, nil, nil, nil, nil, nil, nil, 234, nil, nil,
- nil, nil, 234, 234, 234, 234, 234, 234, nil, nil,
- nil, 234, 234, nil, nil, nil, 235, 235, 235, 234,
- 235, nil, 234, nil, 235, 235, nil, 234, 234, 235,
- nil, 235, 235, 235, 235, 235, 235, 235, nil, nil,
- nil, nil, nil, 235, 235, 235, 235, 235, 235, 235,
- nil, nil, 235, nil, nil, nil, nil, nil, nil, 235,
- nil, nil, 235, 235, nil, 235, 235, 235, 235, 235,
- nil, 235, 235, 235, nil, 235, 235, nil, 235, 235,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 235, nil, nil, 235, nil, nil, 235, nil, nil,
- 235, nil, nil, nil, nil, nil, 235, nil, nil, nil,
- nil, nil, nil, nil, 235, nil, nil, nil, nil, 235,
- 235, 235, 235, 235, 235, nil, nil, nil, 235, 235,
- nil, nil, nil, 236, 236, 236, 235, 236, nil, 235,
- nil, 236, 236, nil, 235, 235, 236, nil, 236, 236,
- 236, 236, 236, 236, 236, nil, nil, nil, nil, nil,
- 236, 236, 236, 236, 236, 236, 236, nil, nil, 236,
- nil, nil, nil, nil, nil, nil, 236, nil, nil, 236,
- 236, nil, 236, 236, 236, 236, 236, nil, 236, 236,
- 236, nil, 236, 236, nil, 236, 236, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 236, nil,
- nil, 236, nil, nil, 236, nil, nil, 236, nil, nil,
- nil, nil, nil, 236, nil, nil, nil, nil, nil, nil,
- nil, 236, nil, nil, nil, nil, 236, 236, 236, 236,
- 236, 236, nil, nil, nil, 236, 236, nil, nil, nil,
- 237, 237, 237, 236, 237, nil, 236, nil, 237, 237,
- nil, 236, 236, 237, nil, 237, 237, 237, 237, 237,
- 237, 237, nil, nil, nil, nil, nil, 237, 237, 237,
- 237, 237, 237, 237, nil, nil, 237, nil, nil, nil,
- nil, nil, nil, 237, nil, nil, 237, 237, nil, 237,
- 237, 237, 237, 237, nil, 237, 237, 237, nil, 237,
- 237, nil, 237, 237, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 237, nil, nil, 237, nil,
- nil, 237, nil, nil, 237, nil, nil, nil, nil, nil,
- 237, nil, nil, nil, nil, nil, nil, nil, 237, nil,
- nil, nil, nil, 237, 237, 237, 237, 237, 237, nil,
- nil, nil, 237, 237, nil, nil, nil, 238, 238, 238,
- 237, 238, nil, 237, nil, 238, 238, nil, 237, 237,
- 238, nil, 238, 238, 238, 238, 238, 238, 238, nil,
- nil, nil, nil, nil, 238, 238, 238, 238, 238, 238,
- 238, nil, nil, 238, nil, nil, nil, nil, nil, nil,
- 238, nil, nil, 238, 238, nil, 238, 238, 238, 238,
- 238, nil, 238, 238, 238, nil, 238, 238, nil, 238,
- 238, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 238, nil, nil, 238, nil, nil, 238, nil,
- nil, 238, nil, nil, nil, nil, nil, 238, nil, nil,
- nil, nil, nil, nil, nil, 238, nil, nil, nil, nil,
- 238, 238, 238, 238, 238, 238, nil, nil, nil, 238,
- 238, nil, nil, nil, 239, 239, 239, 238, 239, nil,
- 238, nil, 239, 239, nil, 238, 238, 239, nil, 239,
- 239, 239, 239, 239, 239, 239, nil, nil, nil, nil,
- nil, 239, 239, 239, 239, 239, 239, 239, nil, nil,
- 239, nil, nil, nil, nil, nil, nil, 239, nil, nil,
- 239, 239, nil, 239, 239, 239, 239, 239, nil, 239,
- 239, 239, nil, 239, 239, nil, 239, 239, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 239,
- nil, nil, 239, nil, nil, 239, nil, nil, 239, nil,
- nil, nil, nil, nil, 239, nil, nil, nil, nil, nil,
- nil, nil, 239, nil, nil, nil, nil, 239, 239, 239,
- 239, 239, 239, nil, nil, nil, 239, 239, nil, nil,
- nil, 240, 240, 240, 239, 240, nil, 239, nil, 240,
- 240, nil, 239, 239, 240, nil, 240, 240, 240, 240,
- 240, 240, 240, nil, nil, nil, nil, nil, 240, 240,
- 240, 240, 240, 240, 240, nil, nil, 240, nil, nil,
- nil, nil, nil, nil, 240, nil, nil, 240, 240, nil,
- 240, 240, 240, 240, 240, nil, 240, 240, 240, nil,
- 240, 240, nil, 240, 240, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 240, nil, nil, 240,
- nil, nil, 240, nil, nil, 240, nil, nil, nil, nil,
- nil, 240, nil, nil, nil, nil, nil, nil, nil, 240,
- nil, nil, nil, nil, 240, 240, 240, 240, 240, 240,
- nil, nil, nil, 240, 240, nil, nil, nil, 241, 241,
- 241, 240, 241, nil, 240, nil, 241, 241, nil, 240,
- 240, 241, nil, 241, 241, 241, 241, 241, 241, 241,
- nil, nil, nil, nil, nil, 241, 241, 241, 241, 241,
- 241, 241, nil, nil, 241, nil, nil, nil, nil, nil,
- nil, 241, nil, nil, 241, 241, nil, 241, 241, 241,
- 241, 241, nil, 241, 241, 241, nil, 241, 241, nil,
- 241, 241, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 241, nil, nil, 241, nil, nil, 241,
- nil, nil, 241, nil, nil, nil, nil, nil, 241, nil,
- nil, nil, nil, nil, nil, nil, 241, nil, nil, nil,
- nil, 241, 241, 241, 241, 241, 241, nil, nil, nil,
- 241, 241, nil, nil, nil, 242, 242, 242, 241, 242,
- nil, 241, nil, 242, 242, nil, 241, 241, 242, nil,
- 242, 242, 242, 242, 242, 242, 242, nil, nil, nil,
- nil, nil, 242, 242, 242, 242, 242, 242, 242, nil,
- nil, 242, nil, nil, nil, nil, nil, nil, 242, nil,
- nil, 242, 242, nil, 242, 242, 242, 242, 242, nil,
- 242, 242, 242, nil, 242, 242, nil, 242, 242, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 242, nil, nil, 242, nil, nil, 242, nil, nil, 242,
- nil, nil, nil, nil, nil, 242, nil, nil, nil, nil,
- nil, nil, nil, 242, nil, nil, nil, nil, 242, 242,
- 242, 242, 242, 242, nil, nil, nil, 242, 242, nil,
- nil, nil, 243, 243, 243, 242, 243, nil, 242, nil,
- 243, 243, nil, 242, 242, 243, nil, 243, 243, 243,
- 243, 243, 243, 243, nil, nil, nil, nil, nil, 243,
- 243, 243, 243, 243, 243, 243, nil, nil, 243, nil,
- nil, nil, nil, nil, nil, 243, nil, nil, 243, 243,
- nil, 243, 243, 243, 243, 243, nil, 243, 243, 243,
- nil, 243, 243, nil, 243, 243, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 243, nil, nil,
- 243, nil, nil, 243, nil, nil, 243, nil, nil, nil,
- nil, nil, 243, nil, nil, nil, nil, nil, nil, nil,
- 243, nil, nil, nil, nil, 243, 243, 243, 243, 243,
- 243, nil, nil, nil, 243, 243, nil, nil, nil, 244,
- 244, 244, 243, 244, nil, 243, nil, 244, 244, nil,
- 243, 243, 244, nil, 244, 244, 244, 244, 244, 244,
- 244, nil, nil, nil, nil, nil, 244, 244, 244, 244,
- 244, 244, 244, nil, nil, 244, nil, nil, nil, nil,
- nil, nil, 244, nil, nil, 244, 244, nil, 244, 244,
- 244, 244, 244, nil, 244, 244, 244, nil, 244, 244,
- nil, 244, 244, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 244, nil, nil, 244, nil, nil,
- 244, nil, nil, 244, nil, nil, nil, nil, nil, 244,
- nil, nil, nil, nil, nil, nil, nil, 244, nil, nil,
- nil, nil, 244, 244, 244, 244, 244, 244, nil, nil,
- nil, 244, 244, nil, nil, nil, 245, 245, 245, 244,
- 245, nil, 244, nil, 245, 245, nil, 244, 244, 245,
- nil, 245, 245, 245, 245, 245, 245, 245, nil, nil,
- nil, nil, nil, 245, 245, 245, 245, 245, 245, 245,
- nil, nil, 245, nil, nil, nil, nil, nil, nil, 245,
- nil, nil, 245, 245, nil, 245, 245, 245, 245, 245,
- nil, 245, 245, 245, nil, 245, 245, nil, 245, 245,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 245, nil, nil, 245, nil, nil, 245, nil, nil,
- 245, nil, nil, nil, nil, nil, 245, nil, nil, nil,
- nil, nil, nil, nil, 245, nil, nil, nil, nil, 245,
- 245, 245, 245, 245, 245, nil, nil, nil, 245, 245,
- nil, nil, nil, 254, 254, 254, 245, 254, nil, 245,
- nil, 254, 254, nil, 245, 245, 254, nil, 254, 254,
- 254, 254, 254, 254, 254, nil, nil, nil, nil, nil,
- 254, 254, 254, 254, 254, 254, 254, nil, nil, 254,
- nil, nil, nil, nil, nil, nil, 254, nil, nil, 254,
- 254, nil, 254, 254, 254, 254, 254, nil, 254, 254,
- 254, nil, 254, 254, nil, 254, 254, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 254, nil,
- nil, 254, nil, nil, 254, nil, nil, 254, nil, nil,
- nil, nil, nil, 254, nil, nil, nil, nil, nil, nil,
- nil, 254, nil, nil, nil, nil, 254, 254, 254, 254,
- 254, 254, nil, nil, nil, 254, 254, nil, nil, nil,
- 256, 256, 256, 254, 256, nil, 254, nil, 256, 256,
- nil, 254, 254, 256, nil, 256, 256, 256, 256, 256,
- 256, 256, nil, nil, nil, nil, nil, 256, 256, 256,
- 256, 256, 256, 256, nil, nil, 256, nil, nil, nil,
- nil, nil, nil, 256, nil, nil, 256, 256, nil, 256,
- 256, 256, 256, 256, nil, 256, 256, 256, nil, 256,
- 256, nil, 256, 256, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 256, nil, nil, 256, nil,
- nil, 256, nil, nil, 256, nil, nil, nil, nil, nil,
- 256, nil, nil, nil, nil, nil, nil, nil, 256, nil,
- nil, nil, nil, 256, 256, 256, 256, 256, 256, nil,
- nil, nil, 256, 256, nil, nil, nil, 261, 261, 261,
- 256, 261, nil, 256, nil, 261, 261, nil, 256, 256,
- 261, nil, 261, 261, 261, 261, 261, 261, 261, nil,
- nil, nil, nil, nil, 261, 261, 261, 261, 261, 261,
- 261, nil, nil, 261, nil, nil, nil, nil, nil, nil,
- 261, nil, nil, 261, 261, nil, 261, 261, 261, 261,
- 261, nil, 261, 261, 261, nil, 261, 261, nil, 261,
- 261, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 261, nil, nil, 261, nil, nil, 261, nil,
- nil, 261, nil, nil, nil, nil, nil, 261, nil, nil,
- nil, nil, nil, nil, nil, 261, nil, nil, nil, nil,
- 261, 261, 261, 261, 261, 261, nil, nil, nil, 261,
- 261, nil, nil, nil, 268, 268, 268, 261, 268, nil,
- 261, nil, 268, 268, nil, 261, 261, 268, nil, 268,
- 268, 268, 268, 268, 268, 268, nil, nil, nil, nil,
- nil, 268, 268, 268, 268, 268, 268, 268, nil, nil,
- 268, nil, nil, nil, nil, nil, nil, 268, nil, nil,
- 268, 268, nil, 268, 268, 268, 268, 268, 268, 268,
- 268, 268, nil, 268, 268, nil, 268, 268, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 268,
- nil, nil, 268, nil, nil, 268, nil, nil, 268, nil,
- 268, nil, 268, nil, 268, nil, nil, nil, nil, nil,
- nil, nil, 268, nil, nil, nil, nil, 268, 268, 268,
- 268, 268, 268, nil, nil, nil, 268, 268, nil, nil,
- nil, 269, 269, 269, 268, 269, nil, 268, nil, 269,
- 269, nil, 268, 268, 269, nil, 269, 269, 269, 269,
- 269, 269, 269, nil, nil, nil, nil, nil, 269, 269,
- 269, 269, 269, 269, 269, nil, nil, 269, nil, nil,
- nil, nil, nil, nil, 269, nil, nil, 269, 269, nil,
- 269, 269, 269, 269, 269, 269, 269, 269, 269, nil,
- 269, 269, nil, 269, 269, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 269, nil, nil, 269,
- nil, nil, 269, nil, nil, 269, nil, 269, nil, 269,
- nil, 269, nil, nil, nil, nil, nil, nil, nil, 269,
- nil, nil, nil, nil, 269, 269, 269, 269, 269, 269,
- nil, nil, nil, 269, 269, nil, nil, nil, 277, 277,
- 277, 269, 277, nil, 269, nil, 277, 277, nil, 269,
- 269, 277, nil, 277, 277, 277, 277, 277, 277, 277,
- nil, nil, nil, nil, nil, 277, 277, 277, 277, 277,
- 277, 277, nil, nil, 277, nil, nil, nil, nil, nil,
- nil, 277, nil, nil, 277, 277, nil, 277, 277, 277,
- 277, 277, 277, 277, 277, 277, nil, 277, 277, nil,
- 277, 277, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 277, nil, nil, 277, nil, 277, 277,
- nil, nil, 277, nil, 277, nil, 277, nil, 277, nil,
- nil, nil, nil, nil, nil, nil, 277, nil, nil, nil,
- nil, 277, 277, 277, 277, 277, 277, nil, nil, nil,
- 277, 277, nil, nil, nil, nil, nil, nil, 277, nil,
- nil, 277, nil, nil, nil, nil, 277, 277, 281, 281,
- 281, 281, 281, nil, nil, nil, 281, 281, nil, nil,
- nil, 281, nil, 281, 281, 281, 281, 281, 281, 281,
- nil, nil, nil, nil, nil, 281, 281, 281, 281, 281,
- 281, 281, nil, nil, 281, nil, nil, nil, nil, nil,
- 281, 281, nil, 281, 281, 281, nil, 281, 281, 281,
- 281, 281, nil, 281, 281, 281, nil, 281, 281, nil,
- 281, 281, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 281, nil, nil, 281, nil, nil, 281,
- nil, nil, 281, nil, 281, nil, nil, nil, 281, nil,
- nil, nil, nil, nil, nil, nil, 281, nil, nil, nil,
- nil, 281, 281, 281, 281, 281, 281, nil, nil, nil,
- 281, 281, nil, nil, nil, 285, 285, 285, 281, 285,
- nil, 281, nil, 285, 285, nil, 281, 281, 285, nil,
- 285, 285, 285, 285, 285, 285, 285, nil, nil, nil,
- nil, nil, 285, 285, 285, 285, 285, 285, 285, nil,
- nil, 285, nil, nil, nil, nil, nil, nil, 285, nil,
- nil, 285, 285, nil, 285, 285, 285, 285, 285, nil,
- 285, 285, 285, nil, 285, 285, 749, nil, 749, 749,
- 749, 749, 749, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 749, nil, nil, nil, nil, nil, nil, nil,
- 285, nil, nil, 285, nil, nil, 285, nil, nil, 285,
- nil, nil, nil, nil, nil, 749, nil, nil, nil, nil,
- nil, nil, nil, 749, 749, 749, 749, nil, 285, 285,
- 285, 285, 285, 285, nil, nil, nil, 285, 285, nil,
- nil, nil, 285, nil, nil, 285, nil, nil, 285, nil,
- nil, nil, nil, 285, 285, 286, 286, 286, 286, 286,
- nil, nil, 749, 286, 286, nil, nil, nil, 286, nil,
- 286, 286, 286, 286, 286, 286, 286, nil, nil, nil,
- nil, nil, 286, 286, 286, 286, 286, 286, 286, nil,
- nil, 286, nil, nil, nil, nil, nil, 286, 286, nil,
- 286, 286, 286, nil, 286, 286, 286, 286, 286, nil,
- 286, 286, 286, nil, 286, 286, nil, 286, 286, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 286, nil, nil, 286, nil, nil, 286, nil, nil, 286,
- nil, 286, nil, nil, nil, 286, nil, nil, nil, nil,
- nil, nil, nil, 286, nil, nil, nil, nil, 286, 286,
- 286, 286, 286, 286, nil, nil, nil, 286, 286, nil,
- nil, nil, 298, 298, 298, 286, 298, nil, 286, nil,
- 298, 298, nil, 286, 286, 298, nil, 298, 298, 298,
- 298, 298, 298, 298, nil, nil, nil, nil, nil, 298,
- 298, 298, 298, 298, 298, 298, nil, nil, 298, nil,
- nil, nil, nil, nil, nil, 298, nil, nil, 298, 298,
- nil, 298, 298, 298, 298, 298, nil, 298, 298, 298,
- nil, 298, 298, 56, nil, 56, 56, 56, nil, 56,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 298, nil, nil,
- 298, nil, nil, 298, nil, nil, 298, nil, nil, nil,
- nil, nil, 56, 56, nil, nil, nil, nil, nil, nil,
- 56, 56, 56, 56, nil, 298, 298, 298, 298, 298,
- 298, nil, nil, nil, 298, 298, nil, nil, nil, 307,
- 307, 307, 298, 307, nil, 298, nil, 307, 307, nil,
- 298, 298, 307, nil, 307, 307, 307, 307, 307, 307,
- 307, nil, nil, nil, nil, nil, 307, 307, 307, 307,
- 307, 307, 307, nil, nil, 307, nil, nil, nil, nil,
- nil, nil, 307, nil, nil, 307, 307, nil, 307, 307,
- 307, 307, 307, nil, 307, 307, 307, nil, 307, 307,
- nil, 307, 307, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 307, nil, nil, 307, 307, nil,
- 307, nil, nil, 307, nil, nil, nil, nil, nil, 307,
- nil, nil, nil, nil, nil, nil, nil, 307, nil, nil,
- nil, nil, 307, 307, 307, 307, 307, 307, nil, nil,
- nil, 307, 307, nil, nil, nil, nil, nil, nil, 307,
- nil, nil, 307, nil, nil, nil, nil, 307, 307, 309,
- 309, 309, 309, 309, nil, nil, nil, 309, 309, nil,
- nil, nil, 309, nil, 309, 309, 309, 309, 309, 309,
- 309, nil, nil, nil, nil, nil, 309, 309, 309, 309,
- 309, 309, 309, nil, nil, 309, nil, nil, nil, nil,
- nil, 309, 309, nil, 309, 309, 309, nil, 309, 309,
- 309, 309, 309, nil, 309, 309, 309, nil, 309, 309,
- nil, 309, 309, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 309, nil, nil, 309, nil, nil,
- 309, nil, nil, 309, nil, 309, nil, nil, nil, 309,
- nil, nil, nil, nil, nil, nil, nil, 309, nil, nil,
- nil, nil, 309, 309, 309, 309, 309, 309, nil, nil,
- nil, 309, 309, nil, nil, nil, 349, 349, 349, 309,
- 349, nil, 309, nil, 349, 349, nil, 309, 309, 349,
- nil, 349, 349, 349, 349, 349, 349, 349, nil, nil,
- nil, nil, nil, 349, 349, 349, 349, 349, 349, 349,
- nil, nil, 349, nil, nil, nil, nil, nil, nil, 349,
- nil, nil, 349, 349, nil, 349, 349, 349, 349, 349,
- nil, 349, 349, 349, nil, 349, 349, nil, 349, 349,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 349, nil, nil, 349, nil, nil, 349, nil, nil,
- 349, nil, nil, nil, nil, nil, 349, nil, nil, nil,
- nil, nil, nil, nil, 349, nil, nil, nil, nil, 349,
- 349, 349, 349, 349, 349, nil, nil, nil, 349, 349,
- nil, nil, nil, 350, 350, 350, 349, 350, nil, 349,
- nil, 350, 350, nil, 349, 349, 350, nil, 350, 350,
- 350, 350, 350, 350, 350, nil, nil, nil, nil, nil,
- 350, 350, 350, 350, 350, 350, 350, nil, nil, 350,
- nil, nil, nil, nil, nil, nil, 350, nil, nil, 350,
- 350, nil, 350, 350, 350, 350, 350, nil, 350, 350,
- 350, nil, 350, 350, nil, 350, 350, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 350, nil,
- nil, 350, nil, nil, 350, nil, nil, 350, nil, nil,
- nil, nil, nil, 350, nil, nil, nil, nil, nil, nil,
- nil, 350, nil, nil, nil, nil, 350, 350, 350, 350,
- 350, 350, nil, nil, nil, 350, 350, nil, nil, nil,
- 369, 369, 369, 350, 369, nil, 350, nil, 369, 369,
- nil, 350, 350, 369, nil, 369, 369, 369, 369, 369,
- 369, 369, nil, nil, nil, nil, nil, 369, 369, 369,
- 369, 369, 369, 369, nil, nil, 369, nil, nil, nil,
- nil, nil, nil, 369, nil, nil, 369, 369, nil, 369,
- 369, 369, 369, 369, nil, 369, 369, 369, nil, 369,
- 369, 322, nil, 322, 322, 322, nil, 322, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 369, nil, nil, 369, nil,
- nil, 369, nil, nil, 369, nil, nil, nil, nil, nil,
- 322, nil, 322, nil, nil, nil, nil, nil, 322, 322,
- 322, 322, nil, 369, 369, 369, 369, 369, 369, nil,
- nil, nil, 369, 369, nil, nil, nil, 381, 381, 381,
- 369, 381, nil, 369, nil, 381, 381, nil, 369, 369,
- 381, nil, 381, 381, 381, 381, 381, 381, 381, nil,
- nil, nil, nil, nil, 381, 381, 381, 381, 381, 381,
- 381, nil, nil, 381, nil, nil, nil, nil, nil, nil,
- 381, nil, nil, 381, 381, nil, 381, 381, 381, 381,
- 381, nil, 381, 381, 381, nil, 381, 381, nil, 381,
- 381, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 381, nil, nil, 381, nil, nil, 381, nil,
- nil, 381, nil, nil, nil, nil, nil, 381, nil, nil,
- nil, nil, nil, nil, nil, 381, nil, nil, nil, nil,
- 381, 381, 381, 381, 381, 381, nil, nil, nil, 381,
- 381, nil, nil, nil, 421, 421, 421, 381, 421, nil,
- 381, nil, 421, 421, nil, 381, 381, 421, nil, 421,
- 421, 421, 421, 421, 421, 421, nil, nil, nil, nil,
- nil, 421, 421, 421, 421, 421, 421, 421, nil, nil,
- 421, nil, nil, nil, nil, nil, nil, 421, nil, nil,
- 421, 421, nil, 421, 421, 421, 421, 421, nil, 421,
- 421, 421, nil, 421, 421, nil, 421, 421, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 421,
- nil, nil, 421, nil, nil, 421, nil, nil, 421, nil,
- nil, nil, nil, nil, 421, nil, nil, nil, nil, nil,
- nil, nil, 421, nil, nil, nil, nil, 421, 421, 421,
- 421, 421, 421, nil, nil, nil, 421, 421, nil, nil,
- nil, 432, 432, 432, 421, 432, nil, 421, nil, 432,
- 432, nil, 421, 421, 432, nil, 432, 432, 432, 432,
- 432, 432, 432, nil, nil, nil, nil, nil, 432, 432,
- 432, 432, 432, 432, 432, nil, nil, 432, nil, nil,
- nil, nil, nil, nil, 432, nil, nil, 432, 432, nil,
- 432, 432, 432, 432, 432, 432, 432, 432, 432, nil,
- 432, 432, nil, 432, 432, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 432, nil, nil, 432,
- 432, nil, 432, nil, nil, 432, nil, 432, nil, 432,
- nil, 432, nil, nil, nil, nil, nil, nil, nil, 432,
- nil, nil, nil, nil, 432, 432, 432, 432, 432, 432,
- nil, nil, nil, 432, 432, nil, nil, nil, 440, 440,
- 440, 432, 440, nil, 432, nil, 440, 440, nil, 432,
- 432, 440, nil, 440, 440, 440, 440, 440, 440, 440,
- nil, nil, nil, nil, nil, 440, 440, 440, 440, 440,
- 440, 440, nil, nil, 440, nil, nil, nil, nil, nil,
- nil, 440, nil, nil, 440, 440, nil, 440, 440, 440,
- 440, 440, 440, 440, 440, 440, nil, 440, 440, nil,
- 440, 440, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 440, nil, nil, 440, 440, nil, 440,
- nil, nil, 440, nil, 440, nil, 440, nil, 440, nil,
- nil, nil, nil, nil, nil, nil, 440, nil, nil, nil,
- nil, 440, 440, 440, 440, 440, 440, nil, nil, nil,
- 440, 440, nil, nil, nil, 441, 441, 441, 440, 441,
- nil, 440, nil, 441, 441, nil, 440, 440, 441, nil,
- 441, 441, 441, 441, 441, 441, 441, nil, nil, nil,
- nil, nil, 441, 441, 441, 441, 441, 441, 441, nil,
- nil, 441, nil, nil, nil, nil, nil, nil, 441, nil,
- nil, 441, 441, nil, 441, 441, 441, 441, 441, 441,
- 441, 441, 441, nil, 441, 441, nil, 441, 441, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 441, nil, nil, 441, 441, nil, 441, nil, nil, 441,
- nil, 441, nil, 441, nil, 441, nil, nil, nil, nil,
- nil, nil, nil, 441, nil, nil, nil, nil, 441, 441,
- 441, 441, 441, 441, nil, nil, nil, 441, 441, nil,
- nil, nil, 442, 442, 442, 441, 442, nil, 441, nil,
- 442, 442, nil, 441, 441, 442, nil, 442, 442, 442,
- 442, 442, 442, 442, nil, nil, nil, nil, nil, 442,
- 442, 442, 442, 442, 442, 442, nil, nil, 442, nil,
- nil, nil, nil, nil, nil, 442, nil, nil, 442, 442,
- nil, 442, 442, 442, 442, 442, 442, 442, 442, 442,
- nil, 442, 442, nil, 442, 442, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 442, nil, nil,
- 442, 442, nil, 442, nil, nil, 442, nil, 442, nil,
- 442, nil, 442, nil, nil, nil, nil, nil, nil, nil,
- 442, nil, nil, nil, nil, 442, 442, 442, 442, 442,
- 442, nil, nil, nil, 442, 442, nil, nil, nil, 451,
- 451, 451, 442, 451, nil, 442, nil, 451, 451, nil,
- 442, 442, 451, nil, 451, 451, 451, 451, 451, 451,
- 451, nil, nil, nil, nil, nil, 451, 451, 451, 451,
- 451, 451, 451, nil, nil, 451, nil, nil, nil, nil,
- nil, nil, 451, nil, nil, 451, 451, nil, 451, 451,
- 451, 451, 451, 451, 451, 451, 451, nil, 451, 451,
- nil, 451, 451, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 451, nil, nil, 451, nil, nil,
- 451, nil, nil, 451, nil, 451, nil, nil, nil, 451,
- nil, nil, nil, nil, nil, nil, nil, 451, nil, nil,
- nil, nil, 451, 451, 451, 451, 451, 451, nil, nil,
- nil, 451, 451, nil, nil, nil, 452, 452, 452, 451,
- 452, nil, 451, nil, 452, 452, nil, 451, 451, 452,
- nil, 452, 452, 452, 452, 452, 452, 452, nil, nil,
- nil, nil, nil, 452, 452, 452, 452, 452, 452, 452,
- nil, nil, 452, nil, nil, nil, nil, nil, nil, 452,
- nil, nil, 452, 452, nil, 452, 452, 452, 452, 452,
- 452, 452, 452, 452, nil, 452, 452, nil, 452, 452,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 452, nil, nil, 452, nil, nil, 452, nil, nil,
- 452, nil, 452, nil, nil, nil, 452, nil, nil, nil,
- nil, nil, nil, nil, 452, nil, nil, nil, nil, 452,
- 452, 452, 452, 452, 452, nil, nil, nil, 452, 452,
- nil, nil, nil, 454, 454, 454, 452, 454, nil, 452,
- nil, 454, 454, nil, 452, 452, 454, nil, 454, 454,
- 454, 454, 454, 454, 454, nil, nil, nil, nil, nil,
- 454, 454, 454, 454, 454, 454, 454, nil, nil, 454,
- nil, nil, nil, nil, nil, nil, 454, nil, nil, 454,
- 454, nil, 454, 454, 454, 454, 454, nil, 454, 454,
- 454, nil, 454, 454, nil, 454, 454, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 454, nil,
- nil, 454, nil, nil, 454, nil, nil, 454, nil, nil,
- nil, nil, nil, 454, nil, nil, nil, nil, nil, nil,
- nil, 454, nil, nil, nil, nil, 454, 454, 454, 454,
- 454, 454, nil, nil, nil, 454, 454, nil, nil, nil,
- 455, 455, 455, 454, 455, nil, 454, nil, 455, 455,
- nil, 454, 454, 455, nil, 455, 455, 455, 455, 455,
- 455, 455, nil, nil, nil, nil, nil, 455, 455, 455,
- 455, 455, 455, 455, nil, nil, 455, nil, nil, nil,
- nil, nil, nil, 455, nil, nil, 455, 455, nil, 455,
- 455, 455, 455, 455, nil, 455, 455, 455, nil, 455,
- 455, nil, 455, 455, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 455, nil, nil, 455, nil,
- nil, 455, nil, nil, 455, nil, nil, nil, nil, nil,
- 455, nil, nil, nil, nil, nil, nil, nil, 455, nil,
- nil, nil, nil, 455, 455, 455, 455, 455, 455, nil,
- nil, nil, 455, 455, nil, nil, nil, 456, 456, 456,
- 455, 456, nil, 455, nil, 456, 456, nil, 455, 455,
- 456, nil, 456, 456, 456, 456, 456, 456, 456, nil,
- nil, nil, nil, nil, 456, 456, 456, 456, 456, 456,
- 456, nil, nil, 456, nil, nil, nil, nil, nil, nil,
- 456, nil, nil, 456, 456, nil, 456, 456, 456, 456,
- 456, nil, 456, 456, 456, nil, 456, 456, nil, 456,
- 456, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 456, nil, nil, 456, nil, nil, 456, nil,
- nil, 456, nil, nil, nil, nil, nil, 456, nil, nil,
- nil, nil, nil, nil, nil, 456, nil, nil, nil, nil,
- 456, 456, 456, 456, 456, 456, nil, nil, nil, 456,
- 456, nil, nil, nil, 487, 487, 487, 456, 487, nil,
- 456, nil, 487, 487, nil, 456, 456, 487, nil, 487,
- 487, 487, 487, 487, 487, 487, nil, nil, nil, nil,
- nil, 487, 487, 487, 487, 487, 487, 487, nil, nil,
- 487, nil, nil, nil, nil, nil, nil, 487, nil, nil,
- 487, 487, nil, 487, 487, 487, 487, 487, 487, 487,
- 487, 487, nil, 487, 487, nil, 487, 487, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 487,
- nil, nil, 487, nil, nil, 487, nil, nil, 487, nil,
- 487, nil, 487, nil, 487, nil, nil, nil, nil, nil,
- nil, nil, 487, nil, nil, nil, nil, 487, 487, 487,
- 487, 487, 487, nil, nil, nil, 487, 487, nil, nil,
- nil, 489, 489, 489, 487, 489, nil, 487, nil, 489,
- 489, nil, 487, 487, 489, nil, 489, 489, 489, 489,
- 489, 489, 489, nil, nil, nil, nil, nil, 489, 489,
- 489, 489, 489, 489, 489, nil, nil, 489, nil, nil,
- nil, nil, nil, nil, 489, nil, nil, 489, 489, nil,
- 489, 489, 489, 489, 489, 489, 489, 489, 489, nil,
- 489, 489, nil, 489, 489, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 489, nil, nil, 489,
- nil, nil, 489, nil, nil, 489, nil, nil, nil, 489,
- nil, 489, nil, nil, nil, nil, nil, nil, nil, 489,
- nil, nil, nil, nil, 489, 489, 489, 489, 489, 489,
- nil, nil, nil, 489, 489, nil, nil, nil, 491, 491,
- 491, 489, 491, nil, 489, nil, 491, 491, nil, 489,
- 489, 491, nil, 491, 491, 491, 491, 491, 491, 491,
- nil, nil, nil, nil, nil, 491, 491, 491, 491, 491,
- 491, 491, nil, nil, 491, nil, nil, nil, nil, nil,
- nil, 491, nil, nil, 491, 491, nil, 491, 491, 491,
- 491, 491, nil, 491, 491, 491, nil, 491, 491, nil,
- 491, 491, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 491, nil, nil, 491, nil, nil, 491,
- nil, nil, 491, nil, nil, nil, nil, nil, 491, nil,
- nil, nil, nil, nil, nil, nil, 491, nil, nil, nil,
- nil, 491, 491, 491, 491, 491, 491, nil, nil, nil,
- 491, 491, nil, nil, nil, 506, 506, 506, 491, 506,
- nil, 491, nil, 506, 506, nil, 491, 491, 506, nil,
- 506, 506, 506, 506, 506, 506, 506, nil, nil, nil,
- nil, nil, 506, 506, 506, 506, 506, 506, 506, nil,
- nil, 506, nil, nil, nil, nil, nil, nil, 506, nil,
- nil, 506, 506, nil, 506, 506, 506, 506, 506, nil,
- 506, 506, 506, nil, 506, 506, nil, 506, 506, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 506, nil, nil, 506, nil, 506, 506, nil, nil, 506,
- nil, nil, nil, 506, nil, 506, nil, nil, nil, nil,
- nil, nil, nil, 506, nil, nil, nil, nil, 506, 506,
- 506, 506, 506, 506, nil, nil, nil, 506, 506, nil,
- nil, nil, nil, nil, nil, 506, nil, nil, 506, nil,
- nil, nil, nil, 506, 506, 512, 512, 512, 512, 512,
- nil, nil, nil, 512, 512, nil, nil, nil, 512, nil,
- 512, 512, 512, 512, 512, 512, 512, nil, nil, nil,
- nil, nil, 512, 512, 512, 512, 512, 512, 512, nil,
- nil, 512, nil, nil, nil, nil, nil, 512, 512, nil,
- 512, 512, 512, nil, 512, 512, 512, 512, 512, nil,
- 512, 512, 512, nil, 512, 512, nil, 512, 512, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 512, nil, nil, 512, nil, nil, 512, nil, nil, 512,
- nil, 512, nil, nil, nil, 512, nil, nil, nil, nil,
- nil, nil, nil, 512, nil, nil, nil, nil, 512, 512,
- 512, 512, 512, 512, nil, nil, nil, 512, 512, nil,
- nil, nil, nil, nil, 512, 512, nil, nil, 512, nil,
- nil, nil, nil, 512, 512, 518, 518, 518, nil, 518,
- nil, nil, nil, 518, 518, nil, nil, nil, 518, nil,
- 518, 518, 518, 518, 518, 518, 518, nil, nil, nil,
- nil, nil, 518, 518, 518, 518, 518, 518, 518, nil,
- nil, 518, nil, nil, nil, nil, nil, nil, 518, nil,
- nil, 518, 518, nil, 518, 518, 518, 518, 518, nil,
- 518, 518, 518, nil, 518, 518, 559, nil, 559, 559,
- 559, nil, 559, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 518, nil, nil, 518, nil, nil, 518, nil, nil, 518,
- nil, nil, nil, nil, nil, 559, nil, nil, nil, nil,
- nil, nil, nil, 559, 559, 559, 559, nil, 518, 518,
- 518, 518, 518, 518, nil, nil, nil, 518, 518, nil,
- nil, nil, 520, 520, 520, 518, 520, nil, 518, nil,
- 520, 520, nil, 518, 518, 520, nil, 520, 520, 520,
- 520, 520, 520, 520, nil, nil, nil, nil, nil, 520,
- 520, 520, 520, 520, 520, 520, nil, nil, 520, nil,
- nil, nil, nil, nil, nil, 520, nil, nil, 520, 520,
- nil, 520, 520, 520, 520, 520, 520, 520, 520, 520,
- nil, 520, 520, nil, 520, 520, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 520, nil, nil,
- 520, nil, nil, 520, nil, nil, 520, nil, 520, nil,
- nil, nil, 520, nil, nil, nil, nil, nil, nil, nil,
- 520, nil, nil, nil, nil, 520, 520, 520, 520, 520,
- 520, nil, nil, nil, 520, 520, nil, nil, nil, 523,
- 523, 523, 520, 523, nil, 520, nil, 523, 523, nil,
- 520, 520, 523, nil, 523, 523, 523, 523, 523, 523,
- 523, nil, nil, nil, nil, nil, 523, 523, 523, 523,
- 523, 523, 523, nil, nil, 523, nil, nil, nil, nil,
- nil, nil, 523, nil, nil, 523, 523, nil, 523, 523,
- 523, 523, 523, 523, 523, 523, 523, nil, 523, 523,
- nil, 523, 523, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 523, nil, nil, 523, nil, nil,
- 523, nil, nil, 523, nil, 523, nil, nil, nil, 523,
- nil, nil, nil, nil, nil, nil, nil, 523, nil, nil,
- nil, nil, 523, 523, 523, 523, 523, 523, nil, nil,
- nil, 523, 523, nil, nil, nil, 531, 531, 531, 523,
- 531, nil, 523, nil, 531, 531, nil, 523, 523, 531,
- nil, 531, 531, 531, 531, 531, 531, 531, nil, nil,
- nil, nil, nil, 531, 531, 531, 531, 531, 531, 531,
- nil, nil, 531, nil, nil, nil, nil, nil, nil, 531,
- nil, nil, 531, 531, nil, 531, 531, 531, 531, 531,
- nil, 531, 531, 531, nil, 531, 531, nil, 531, 531,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 531, nil, nil, 531, nil, nil, 531, nil, nil,
- 531, nil, nil, nil, nil, nil, 531, nil, nil, nil,
- nil, nil, nil, nil, 531, nil, nil, nil, nil, 531,
- 531, 531, 531, 531, 531, nil, nil, nil, 531, 531,
- nil, nil, nil, 532, 532, 532, 531, 532, nil, 531,
- nil, 532, 532, nil, 531, 531, 532, nil, 532, 532,
- 532, 532, 532, 532, 532, nil, nil, nil, nil, nil,
- 532, 532, 532, 532, 532, 532, 532, nil, nil, 532,
- nil, nil, nil, nil, nil, nil, 532, nil, nil, 532,
- 532, nil, 532, 532, 532, 532, 532, nil, 532, 532,
- 532, nil, 532, 532, nil, 532, 532, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 532, nil,
- nil, 532, nil, nil, 532, nil, nil, 532, nil, nil,
- nil, nil, nil, 532, nil, nil, nil, nil, nil, nil,
- nil, 532, nil, nil, nil, nil, 532, 532, 532, 532,
- 532, 532, nil, nil, nil, 532, 532, nil, nil, nil,
- 533, 533, 533, 532, 533, nil, 532, nil, 533, 533,
- nil, 532, 532, 533, nil, 533, 533, 533, 533, 533,
- 533, 533, nil, nil, nil, nil, nil, 533, 533, 533,
- 533, 533, 533, 533, nil, nil, 533, nil, nil, nil,
- nil, nil, nil, 533, nil, nil, 533, 533, nil, 533,
- 533, 533, 533, 533, nil, 533, 533, 533, nil, 533,
- 533, nil, 533, 533, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 533, nil, nil, 533, nil,
- nil, 533, nil, nil, 533, nil, nil, nil, nil, nil,
- 533, nil, nil, nil, nil, nil, nil, nil, 533, nil,
- nil, nil, nil, 533, 533, 533, 533, 533, 533, nil,
- nil, nil, 533, 533, nil, nil, nil, 537, 537, 537,
- 533, 537, nil, 533, nil, 537, 537, nil, 533, 533,
- 537, nil, 537, 537, 537, 537, 537, 537, 537, nil,
- nil, nil, nil, nil, 537, 537, 537, 537, 537, 537,
- 537, nil, nil, 537, nil, nil, nil, nil, nil, nil,
- 537, nil, nil, 537, 537, nil, 537, 537, 537, 537,
- 537, nil, 537, 537, 537, nil, 537, 537, nil, 537,
- 537, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 537, nil, nil, 537, nil, nil, 537, nil,
- nil, 537, nil, nil, nil, nil, nil, 537, nil, nil,
- nil, nil, nil, nil, nil, 537, nil, nil, nil, nil,
- 537, 537, 537, 537, 537, 537, nil, nil, nil, 537,
- 537, nil, nil, nil, 543, 543, 543, 537, 543, nil,
- 537, nil, 543, 543, nil, 537, 537, 543, nil, 543,
- 543, 543, 543, 543, 543, 543, nil, nil, nil, nil,
- nil, 543, 543, 543, 543, 543, 543, 543, nil, nil,
- 543, nil, nil, nil, nil, nil, nil, 543, nil, nil,
- 543, 543, nil, 543, 543, 543, 543, 543, 543, 543,
- 543, 543, nil, 543, 543, nil, 543, 543, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 543,
- nil, nil, 543, nil, nil, 543, nil, nil, 543, nil,
- 543, nil, nil, nil, 543, nil, nil, nil, nil, nil,
- nil, nil, 543, nil, nil, nil, nil, 543, 543, 543,
- 543, 543, 543, nil, nil, nil, 543, 543, nil, nil,
- nil, 546, 546, 546, 543, 546, nil, 543, nil, 546,
- 546, nil, 543, 543, 546, nil, 546, 546, 546, 546,
- 546, 546, 546, nil, nil, nil, nil, nil, 546, 546,
- 546, 546, 546, 546, 546, nil, nil, 546, nil, nil,
- nil, nil, nil, nil, 546, nil, nil, 546, 546, nil,
- 546, 546, 546, 546, 546, 546, 546, 546, 546, nil,
- 546, 546, nil, 546, 546, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 546, nil, nil, 546,
- nil, nil, 546, nil, nil, 546, nil, nil, nil, nil,
- nil, 546, nil, nil, nil, nil, nil, nil, nil, 546,
- nil, nil, nil, nil, 546, 546, 546, 546, 546, 546,
- nil, nil, nil, 546, 546, nil, nil, nil, nil, nil,
- nil, 546, nil, nil, 546, nil, nil, nil, nil, 546,
- 546, 551, 551, 551, 551, 551, nil, nil, nil, 551,
- 551, nil, nil, nil, 551, nil, 551, 551, 551, 551,
- 551, 551, 551, nil, nil, nil, nil, nil, 551, 551,
- 551, 551, 551, 551, 551, nil, nil, 551, nil, nil,
- nil, nil, nil, 551, 551, nil, 551, 551, 551, nil,
- 551, 551, 551, 551, 551, nil, 551, 551, 551, nil,
- 551, 551, nil, 551, 551, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 551, nil, nil, 551,
- nil, nil, 551, nil, nil, 551, nil, 551, nil, nil,
- nil, 551, nil, nil, nil, nil, nil, nil, nil, 551,
- nil, nil, nil, nil, 551, 551, 551, 551, 551, 551,
- nil, nil, nil, 551, 551, nil, nil, nil, nil, nil,
- nil, 551, nil, nil, 551, nil, nil, nil, nil, 551,
- 551, 552, 552, 552, 552, 552, nil, nil, nil, 552,
- 552, nil, nil, nil, 552, nil, 552, 552, 552, 552,
- 552, 552, 552, nil, nil, nil, nil, nil, 552, 552,
- 552, 552, 552, 552, 552, nil, nil, 552, nil, nil,
- nil, nil, nil, 552, 552, nil, 552, 552, 552, nil,
- 552, 552, 552, 552, 552, nil, 552, 552, 552, nil,
- 552, 552, nil, 552, 552, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 552, nil, nil, 552,
- nil, nil, 552, nil, nil, 552, nil, 552, nil, nil,
- nil, 552, nil, nil, nil, nil, nil, nil, nil, 552,
- nil, nil, nil, nil, 552, 552, 552, 552, 552, 552,
- nil, nil, nil, 552, 552, nil, nil, nil, 558, 558,
- 558, 552, 558, nil, 552, nil, 558, 558, nil, 552,
- 552, 558, nil, 558, 558, 558, 558, 558, 558, 558,
- nil, nil, nil, nil, nil, 558, 558, 558, 558, 558,
- 558, 558, nil, nil, 558, nil, nil, nil, nil, nil,
- nil, 558, nil, nil, 558, 558, nil, 558, 558, 558,
- 558, 558, nil, 558, 558, 558, nil, 558, 558, 856,
- nil, 856, 856, 856, 856, 856, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 856, nil, nil, nil, nil,
- nil, nil, nil, 558, nil, nil, 558, nil, nil, 558,
- nil, nil, 558, nil, nil, nil, nil, nil, 856, nil,
- nil, nil, nil, nil, nil, nil, 856, 856, 856, 856,
- nil, 558, 558, 558, 558, 558, 558, nil, nil, nil,
- 558, 558, nil, nil, nil, nil, nil, nil, 558, nil,
- nil, 558, nil, nil, nil, nil, 558, 558, 572, 572,
- 572, 572, 572, nil, nil, 856, 572, 572, nil, nil,
- nil, 572, nil, 572, 572, 572, 572, 572, 572, 572,
- nil, nil, nil, nil, nil, 572, 572, 572, 572, 572,
- 572, 572, nil, nil, 572, nil, nil, nil, nil, nil,
- 572, 572, nil, 572, 572, 572, nil, 572, 572, 572,
- 572, 572, nil, 572, 572, 572, nil, 572, 572, nil,
- 572, 572, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 572, nil, nil, 572, nil, nil, 572,
- nil, nil, 572, nil, 572, nil, nil, nil, 572, nil,
- nil, nil, nil, nil, nil, nil, 572, nil, nil, nil,
- nil, 572, 572, 572, 572, 572, 572, nil, nil, nil,
- 572, 572, nil, nil, nil, nil, nil, nil, 572, nil,
- nil, 572, nil, nil, nil, nil, 572, 572, 576, 576,
- 576, 576, 576, nil, nil, nil, 576, 576, nil, nil,
- nil, 576, nil, 576, 576, 576, 576, 576, 576, 576,
- nil, nil, nil, nil, nil, 576, 576, 576, 576, 576,
- 576, 576, nil, nil, 576, nil, nil, nil, nil, nil,
- 576, 576, nil, 576, 576, 576, nil, 576, 576, 576,
- 576, 576, nil, 576, 576, 576, nil, 576, 576, nil,
- 576, 576, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 576, nil, nil, 576, nil, nil, 576,
- nil, nil, 576, nil, 576, nil, nil, nil, 576, nil,
- nil, nil, nil, nil, nil, nil, 576, nil, nil, nil,
- nil, 576, 576, 576, 576, 576, 576, nil, nil, nil,
- 576, 576, nil, nil, nil, nil, nil, nil, 576, nil,
- nil, 576, nil, nil, nil, nil, 576, 576, 581, 581,
- 581, 581, 581, nil, nil, nil, 581, 581, nil, nil,
- nil, 581, nil, 581, 581, 581, 581, 581, 581, 581,
- nil, nil, nil, nil, nil, 581, 581, 581, 581, 581,
- 581, 581, nil, nil, 581, nil, nil, nil, nil, nil,
- 581, 581, nil, 581, 581, 581, nil, 581, 581, 581,
- 581, 581, nil, 581, 581, 581, nil, 581, 581, nil,
- 581, 581, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 581, nil, nil, 581, nil, nil, 581,
- nil, nil, 581, nil, 581, nil, nil, nil, 581, nil,
- nil, nil, nil, nil, nil, nil, 581, nil, nil, nil,
- nil, 581, 581, 581, 581, 581, 581, nil, nil, nil,
- 581, 581, nil, nil, nil, 583, 583, 583, 581, 583,
- nil, 581, nil, 583, 583, nil, 581, 581, 583, nil,
- 583, 583, 583, 583, 583, 583, 583, nil, nil, nil,
- nil, nil, 583, 583, 583, 583, 583, 583, 583, nil,
- nil, 583, nil, nil, nil, nil, nil, nil, 583, nil,
- nil, 583, 583, nil, 583, 583, 583, 583, 583, 583,
- 583, 583, 583, nil, 583, 583, nil, 583, 583, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 583, nil, nil, 583, nil, nil, 583, nil, nil, 583,
- nil, 583, nil, nil, nil, 583, nil, nil, nil, nil,
- nil, nil, nil, 583, nil, nil, nil, nil, 583, 583,
- 583, 583, 583, 583, nil, nil, nil, 583, 583, nil,
- nil, nil, 586, 586, 586, 583, 586, nil, 583, nil,
- 586, 586, nil, 583, 583, 586, nil, 586, 586, 586,
- 586, 586, 586, 586, nil, nil, nil, nil, nil, 586,
- 586, 586, 586, 586, 586, 586, nil, nil, 586, nil,
- nil, nil, nil, nil, nil, 586, nil, nil, 586, 586,
- nil, 586, 586, 586, 586, 586, 586, 586, 586, 586,
- nil, 586, 586, nil, 586, 586, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 586, nil, nil,
- 586, nil, nil, 586, nil, nil, 586, nil, 586, nil,
- nil, nil, 586, nil, nil, nil, nil, nil, nil, nil,
- 586, nil, nil, nil, nil, 586, 586, 586, 586, 586,
- 586, nil, nil, nil, 586, 586, nil, nil, nil, 592,
- 592, 592, 586, 592, nil, 586, nil, 592, 592, nil,
- 586, 586, 592, nil, 592, 592, 592, 592, 592, 592,
- 592, nil, nil, nil, nil, nil, 592, 592, 592, 592,
- 592, 592, 592, nil, nil, 592, nil, nil, nil, nil,
- nil, nil, 592, nil, nil, 592, 592, nil, 592, 592,
- 592, 592, 592, 592, 592, 592, 592, nil, 592, 592,
- nil, 592, 592, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 592, nil, nil, 592, nil, nil,
- 592, nil, nil, 592, nil, 592, nil, nil, nil, 592,
- nil, nil, nil, nil, nil, nil, nil, 592, nil, nil,
- nil, nil, 592, 592, 592, 592, 592, 592, nil, nil,
- nil, 592, 592, nil, nil, nil, 596, 596, 596, 592,
- 596, nil, 592, nil, 596, 596, nil, 592, 592, 596,
- nil, 596, 596, 596, 596, 596, 596, 596, nil, nil,
- nil, nil, nil, 596, 596, 596, 596, 596, 596, 596,
- nil, nil, 596, nil, nil, nil, nil, nil, nil, 596,
- nil, nil, 596, 596, nil, 596, 596, 596, 596, 596,
- nil, 596, 596, 596, nil, 596, 596, nil, 596, 596,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 596, nil, nil, 596, nil, nil, 596, nil, nil,
- 596, nil, nil, nil, nil, nil, 596, nil, nil, nil,
- nil, nil, nil, nil, 596, nil, nil, nil, nil, 596,
- 596, 596, 596, 596, 596, nil, nil, nil, 596, 596,
- nil, nil, nil, 598, 598, 598, 596, 598, nil, 596,
- nil, 598, 598, nil, 596, 596, 598, nil, 598, 598,
- 598, 598, 598, 598, 598, nil, nil, nil, nil, nil,
- 598, 598, 598, 598, 598, 598, 598, nil, nil, 598,
- nil, nil, nil, nil, nil, nil, 598, nil, nil, 598,
- 598, nil, 598, 598, 598, 598, 598, nil, 598, 598,
- 598, nil, 598, 598, nil, 598, 598, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 598, nil,
- nil, 598, nil, nil, 598, nil, nil, 598, nil, nil,
- nil, nil, nil, 598, nil, nil, nil, nil, nil, nil,
- nil, 598, nil, nil, nil, nil, 598, 598, 598, 598,
- 598, 598, nil, nil, nil, 598, 598, nil, nil, nil,
- 625, 625, 625, 598, 625, nil, 598, nil, 625, 625,
- nil, 598, 598, 625, nil, 625, 625, 625, 625, 625,
- 625, 625, nil, nil, nil, nil, nil, 625, 625, 625,
- 625, 625, 625, 625, nil, nil, 625, nil, nil, nil,
- nil, nil, nil, 625, nil, nil, 625, 625, nil, 625,
- 625, 625, 625, 625, nil, 625, 625, 625, nil, 625,
- 625, nil, 625, 625, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 625, nil, nil, 625, nil,
- nil, 625, nil, nil, 625, nil, nil, nil, nil, nil,
- 625, nil, nil, nil, nil, nil, nil, nil, 625, nil,
- nil, nil, nil, 625, 625, 625, 625, 625, 625, nil,
- nil, nil, 625, 625, nil, nil, nil, 627, 627, 627,
- 625, 627, nil, 625, nil, 627, 627, nil, 625, 625,
- 627, nil, 627, 627, 627, 627, 627, 627, 627, nil,
- nil, nil, nil, nil, 627, 627, 627, 627, 627, 627,
- 627, nil, nil, 627, nil, nil, nil, nil, nil, nil,
- 627, nil, nil, 627, 627, nil, 627, 627, 627, 627,
- 627, nil, 627, 627, 627, nil, 627, 627, nil, 627,
- 627, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 627, nil, nil, 627, nil, nil, 627, nil,
- nil, 627, nil, 627, nil, nil, nil, 627, nil, nil,
- nil, nil, nil, nil, nil, 627, nil, nil, nil, nil,
- 627, 627, 627, 627, 627, 627, nil, nil, nil, 627,
- 627, nil, nil, nil, 630, 630, 630, 627, 630, nil,
- 627, nil, 630, 630, nil, 627, 627, 630, nil, 630,
- 630, 630, 630, 630, 630, 630, nil, nil, nil, nil,
- nil, 630, 630, 630, 630, 630, 630, 630, nil, nil,
- 630, nil, nil, nil, nil, nil, nil, 630, nil, nil,
- 630, 630, nil, 630, 630, 630, 630, 630, nil, 630,
- 630, 630, nil, 630, 630, nil, 630, 630, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 630,
- nil, nil, 630, nil, nil, 630, nil, nil, 630, nil,
- nil, nil, nil, nil, 630, nil, nil, nil, nil, nil,
- nil, nil, 630, nil, nil, nil, nil, 630, 630, 630,
- 630, 630, 630, nil, nil, nil, 630, 630, nil, nil,
- nil, 631, 631, 631, 630, 631, nil, 630, nil, 631,
- 631, nil, 630, 630, 631, nil, 631, 631, 631, 631,
- 631, 631, 631, nil, nil, nil, nil, nil, 631, 631,
- 631, 631, 631, 631, 631, nil, nil, 631, nil, nil,
- nil, nil, nil, nil, 631, nil, nil, 631, 631, nil,
- 631, 631, 631, 631, 631, nil, 631, 631, 631, nil,
- 631, 631, nil, 631, 631, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 631, nil, nil, 631,
- nil, nil, 631, nil, nil, 631, nil, nil, nil, nil,
- nil, 631, nil, nil, nil, nil, nil, nil, nil, 631,
- nil, nil, nil, nil, 631, 631, 631, 631, 631, 631,
- nil, nil, nil, 631, 631, nil, nil, nil, 636, 636,
- 636, 631, 636, nil, 631, nil, 636, 636, nil, 631,
- 631, 636, nil, 636, 636, 636, 636, 636, 636, 636,
- nil, nil, nil, nil, nil, 636, 636, 636, 636, 636,
- 636, 636, nil, nil, 636, nil, nil, nil, nil, nil,
- nil, 636, nil, nil, 636, 636, nil, 636, 636, 636,
- 636, 636, nil, 636, 636, 636, nil, 636, 636, nil,
- 636, 636, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 636, nil, nil, 636, nil, nil, 636,
- nil, nil, 636, nil, nil, nil, nil, nil, 636, nil,
- nil, nil, nil, nil, nil, nil, 636, nil, nil, nil,
- nil, 636, 636, 636, 636, 636, 636, nil, nil, nil,
- 636, 636, nil, nil, nil, 639, 639, 639, 636, 639,
- nil, 636, nil, 639, 639, nil, 636, 636, 639, nil,
- 639, 639, 639, 639, 639, 639, 639, nil, nil, nil,
- nil, nil, 639, 639, 639, 639, 639, 639, 639, nil,
- nil, 639, nil, nil, nil, nil, nil, nil, 639, nil,
- nil, 639, 639, nil, 639, 639, 639, 639, 639, nil,
- 639, 639, 639, nil, 639, 639, nil, 639, 639, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 639, nil, nil, 639, nil, nil, 639, nil, nil, 639,
- nil, nil, nil, nil, nil, 639, nil, nil, nil, nil,
- nil, nil, nil, 639, nil, nil, nil, nil, 639, 639,
- 639, 639, 639, 639, nil, nil, nil, 639, 639, nil,
- nil, nil, 650, 650, 650, 639, 650, nil, 639, nil,
- 650, 650, nil, 639, 639, 650, nil, 650, 650, 650,
- 650, 650, 650, 650, nil, nil, nil, nil, nil, 650,
- 650, 650, 650, 650, 650, 650, nil, nil, 650, nil,
- nil, nil, nil, nil, nil, 650, nil, nil, 650, 650,
- nil, 650, 650, 650, 650, 650, nil, 650, 650, 650,
- nil, 650, 650, nil, 650, 650, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 650, nil, nil,
- 650, nil, nil, 650, nil, nil, 650, nil, nil, nil,
- nil, nil, 650, nil, nil, nil, nil, nil, nil, nil,
- 650, nil, nil, nil, nil, 650, 650, 650, 650, 650,
- 650, nil, nil, nil, 650, 650, nil, nil, nil, nil,
- nil, nil, 650, nil, nil, 650, nil, nil, nil, nil,
- 650, 650, 654, 654, 654, 654, 654, nil, nil, nil,
- 654, 654, nil, nil, nil, 654, nil, 654, 654, 654,
- 654, 654, 654, 654, nil, nil, nil, nil, nil, 654,
- 654, 654, 654, 654, 654, 654, nil, nil, 654, nil,
- nil, nil, nil, nil, 654, 654, nil, 654, 654, 654,
- nil, 654, 654, 654, 654, 654, nil, 654, 654, 654,
- nil, 654, 654, nil, 654, 654, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 654, nil, nil,
- 654, nil, nil, 654, nil, nil, 654, nil, 654, nil,
- nil, nil, 654, nil, nil, nil, nil, nil, nil, nil,
- 654, nil, nil, nil, nil, 654, 654, 654, 654, 654,
- 654, nil, nil, nil, 654, 654, nil, nil, nil, 658,
- 658, 658, 654, 658, nil, 654, nil, 658, 658, nil,
- 654, 654, 658, nil, 658, 658, 658, 658, 658, 658,
- 658, nil, nil, nil, nil, nil, 658, 658, 658, 658,
- 658, 658, 658, nil, nil, 658, nil, nil, nil, nil,
- nil, nil, 658, nil, nil, 658, 658, nil, 658, 658,
- 658, 658, 658, nil, 658, 658, 658, nil, 658, 658,
- nil, 658, 658, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 658, nil, nil, 658, nil, nil,
- 658, nil, nil, 658, nil, nil, nil, nil, nil, 658,
- nil, nil, nil, nil, nil, nil, nil, 658, nil, nil,
- nil, nil, 658, 658, 658, 658, 658, 658, nil, nil,
- nil, 658, 658, nil, nil, nil, nil, nil, nil, 658,
- nil, nil, 658, nil, nil, nil, nil, 658, 658, 667,
- 667, 667, 667, 667, nil, nil, nil, 667, 667, nil,
- nil, nil, 667, nil, 667, 667, 667, 667, 667, 667,
- 667, nil, nil, nil, nil, nil, 667, 667, 667, 667,
- 667, 667, 667, nil, nil, 667, nil, nil, nil, nil,
- nil, 667, 667, nil, 667, 667, 667, nil, 667, 667,
- 667, 667, 667, nil, 667, 667, 667, nil, 667, 667,
- nil, 667, 667, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 667, nil, nil, 667, nil, nil,
- 667, nil, nil, 667, nil, 667, nil, nil, nil, 667,
- nil, nil, nil, nil, nil, nil, nil, 667, nil, nil,
- nil, nil, 667, 667, 667, 667, 667, 667, nil, nil,
- nil, 667, 667, nil, nil, nil, 670, 670, 670, 667,
- 670, nil, 667, nil, 670, 670, nil, 667, 667, 670,
- nil, 670, 670, 670, 670, 670, 670, 670, nil, nil,
- nil, nil, nil, 670, 670, 670, 670, 670, 670, 670,
- nil, nil, 670, nil, nil, nil, nil, nil, nil, 670,
- nil, nil, 670, 670, nil, 670, 670, 670, 670, 670,
- 670, 670, 670, 670, nil, 670, 670, nil, 670, 670,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 670, nil, nil, 670, nil, nil, 670, nil, nil,
- 670, nil, 670, nil, 670, nil, 670, nil, nil, nil,
- nil, nil, nil, nil, 670, nil, nil, nil, nil, 670,
- 670, 670, 670, 670, 670, nil, nil, nil, 670, 670,
- nil, nil, nil, 671, 671, 671, 670, 671, nil, 670,
- nil, 671, 671, nil, 670, 670, 671, nil, 671, 671,
- 671, 671, 671, 671, 671, nil, nil, nil, nil, nil,
- 671, 671, 671, 671, 671, 671, 671, nil, nil, 671,
- nil, nil, nil, nil, nil, nil, 671, nil, nil, 671,
- 671, nil, 671, 671, 671, 671, 671, 671, 671, 671,
- 671, nil, 671, 671, nil, 671, 671, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 671, nil,
- nil, 671, nil, nil, 671, nil, nil, 671, nil, nil,
- nil, 671, nil, 671, nil, nil, nil, nil, nil, nil,
- nil, 671, nil, nil, nil, nil, 671, 671, 671, 671,
- 671, 671, nil, nil, nil, 671, 671, nil, nil, nil,
- nil, nil, nil, 671, nil, nil, 671, nil, nil, nil,
- nil, 671, 671, 677, 677, 677, 677, 677, nil, nil,
- nil, 677, 677, nil, nil, nil, 677, nil, 677, 677,
- 677, 677, 677, 677, 677, nil, nil, nil, nil, nil,
- 677, 677, 677, 677, 677, 677, 677, nil, nil, 677,
- nil, nil, nil, nil, nil, 677, 677, nil, 677, 677,
- 677, nil, 677, 677, 677, 677, 677, nil, 677, 677,
- 677, nil, 677, 677, nil, 677, 677, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 677, nil,
- nil, 677, nil, nil, 677, nil, nil, 677, nil, 677,
- nil, nil, nil, 677, nil, nil, nil, nil, nil, nil,
- nil, 677, nil, nil, nil, nil, 677, 677, 677, 677,
- 677, 677, nil, nil, nil, 677, 677, nil, nil, nil,
- nil, nil, nil, 677, nil, nil, 677, nil, nil, nil,
- nil, 677, 677, 678, 678, 678, 678, 678, nil, nil,
- nil, 678, 678, nil, nil, nil, 678, nil, 678, 678,
- 678, 678, 678, 678, 678, nil, nil, nil, nil, nil,
- 678, 678, 678, 678, 678, 678, 678, nil, nil, 678,
- nil, nil, nil, nil, nil, 678, 678, nil, 678, 678,
- 678, nil, 678, 678, 678, 678, 678, nil, 678, 678,
- 678, nil, 678, 678, nil, 678, 678, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 678, nil,
- nil, 678, nil, nil, 678, nil, nil, 678, nil, 678,
- nil, nil, nil, 678, nil, nil, nil, nil, nil, nil,
- nil, 678, nil, nil, nil, nil, 678, 678, 678, 678,
- 678, 678, nil, nil, nil, 678, 678, nil, nil, nil,
- 682, 682, 682, 678, 682, nil, 678, nil, 682, 682,
- nil, 678, 678, 682, nil, 682, 682, 682, 682, 682,
- 682, 682, nil, nil, nil, nil, nil, 682, 682, 682,
- 682, 682, 682, 682, nil, nil, 682, nil, nil, nil,
- nil, nil, nil, 682, nil, nil, 682, 682, nil, 682,
- 682, 682, 682, 682, nil, 682, 682, 682, nil, 682,
- 682, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 682, nil, nil, 682, nil,
- nil, 682, nil, nil, 682, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 682, 682, 682, 682, 682, 682, nil,
- nil, nil, 682, 682, nil, nil, nil, 694, 694, 694,
- 682, 694, nil, 682, nil, 694, 694, nil, 682, 682,
- 694, nil, 694, 694, 694, 694, 694, 694, 694, nil,
- nil, nil, nil, nil, 694, 694, 694, 694, 694, 694,
- 694, nil, nil, 694, nil, nil, nil, nil, nil, nil,
- 694, nil, nil, 694, 694, nil, 694, 694, 694, 694,
- 694, nil, 694, 694, 694, nil, 694, 694, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 694, nil, nil, 694, nil, nil, 694, nil,
- nil, 694, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 694, 694, 694, 694, 694, 694, nil, nil, nil, 694,
- 694, nil, nil, nil, 700, 700, 700, 694, 700, nil,
- 694, nil, 700, 700, nil, 694, 694, 700, nil, 700,
- 700, 700, 700, 700, 700, 700, nil, nil, nil, nil,
- nil, 700, 700, 700, 700, 700, 700, 700, nil, nil,
- 700, nil, nil, nil, nil, nil, nil, 700, nil, nil,
- 700, 700, nil, 700, 700, 700, 700, 700, nil, 700,
- 700, 700, nil, 700, 700, nil, 700, 700, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 700,
- nil, nil, 700, nil, nil, 700, nil, nil, 700, nil,
- 700, nil, nil, nil, 700, nil, nil, nil, nil, nil,
- nil, nil, 700, nil, nil, nil, nil, 700, 700, 700,
- 700, 700, 700, nil, nil, nil, 700, 700, nil, nil,
- nil, 731, 731, 731, 700, 731, nil, 700, nil, 731,
- 731, nil, 700, 700, 731, nil, 731, 731, 731, 731,
- 731, 731, 731, nil, nil, nil, nil, nil, 731, 731,
- 731, 731, 731, 731, 731, nil, nil, 731, nil, nil,
- nil, nil, nil, nil, 731, nil, nil, 731, 731, nil,
- 731, 731, 731, 731, 731, nil, 731, 731, 731, nil,
- 731, 731, nil, 731, 731, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 731, nil, nil, 731,
- nil, nil, 731, nil, nil, 731, nil, 731, nil, nil,
- nil, 731, nil, nil, nil, nil, nil, nil, nil, 731,
- nil, nil, nil, nil, 731, 731, 731, 731, 731, 731,
- nil, nil, nil, 731, 731, nil, nil, nil, 738, 738,
- 738, 731, 738, nil, 731, nil, 738, 738, nil, 731,
- 731, 738, nil, 738, 738, 738, 738, 738, 738, 738,
- nil, nil, nil, nil, nil, 738, 738, 738, 738, 738,
- 738, 738, nil, nil, 738, nil, nil, nil, nil, nil,
- nil, 738, nil, nil, 738, 738, nil, 738, 738, 738,
- 738, 738, nil, 738, 738, 738, nil, 738, 738, nil,
- 738, 738, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 738, nil, nil, 738, nil, nil, 738,
- nil, nil, 738, nil, nil, nil, nil, nil, 738, nil,
- nil, nil, nil, nil, nil, nil, 738, nil, nil, nil,
- nil, 738, 738, 738, 738, 738, 738, nil, nil, nil,
- 738, 738, nil, nil, nil, nil, nil, nil, 738, nil,
- nil, 738, nil, nil, nil, nil, 738, 738, 743, 743,
- 743, 743, 743, nil, nil, nil, 743, 743, nil, nil,
- nil, 743, nil, 743, 743, 743, 743, 743, 743, 743,
- nil, nil, nil, nil, nil, 743, 743, 743, 743, 743,
- 743, 743, nil, nil, 743, nil, nil, nil, nil, nil,
- 743, 743, nil, 743, 743, 743, nil, 743, 743, 743,
- 743, 743, nil, 743, 743, 743, nil, 743, 743, nil,
- 743, 743, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 743, nil, nil, 743, nil, nil, 743,
- nil, nil, 743, nil, 743, nil, nil, nil, 743, nil,
- nil, nil, nil, nil, nil, nil, 743, nil, nil, nil,
- nil, 743, 743, 743, 743, 743, 743, nil, nil, nil,
- 743, 743, nil, nil, nil, nil, nil, nil, 743, nil,
- nil, 743, nil, nil, nil, nil, 743, 743, 747, 747,
- 747, 747, 747, nil, nil, nil, 747, 747, nil, nil,
- nil, 747, nil, 747, 747, 747, 747, 747, 747, 747,
- nil, nil, nil, nil, nil, 747, 747, 747, 747, 747,
- 747, 747, nil, nil, 747, nil, nil, nil, nil, nil,
- 747, 747, nil, 747, 747, 747, nil, 747, 747, 747,
- 747, 747, nil, 747, 747, 747, nil, 747, 747, nil,
- 747, 747, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 747, nil, nil, 747, nil, nil, 747,
- nil, nil, 747, nil, 747, nil, nil, nil, 747, nil,
- nil, nil, nil, nil, nil, nil, 747, nil, nil, nil,
- nil, 747, 747, 747, 747, 747, 747, nil, nil, nil,
- 747, 747, nil, nil, nil, nil, nil, nil, 747, nil,
- nil, 747, nil, nil, nil, nil, 747, 747, 748, 748,
- 748, 748, 748, nil, nil, nil, 748, 748, nil, nil,
- nil, 748, nil, 748, 748, 748, 748, 748, 748, 748,
- nil, nil, nil, nil, nil, 748, 748, 748, 748, 748,
- 748, 748, nil, nil, 748, nil, nil, nil, nil, nil,
- 748, 748, nil, 748, 748, 748, nil, 748, 748, 748,
- 748, 748, nil, 748, 748, 748, nil, 748, 748, nil,
- 748, 748, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 748, nil, nil, 748, nil, nil, 748,
- nil, nil, 748, nil, 748, nil, nil, nil, 748, nil,
- nil, nil, nil, nil, nil, nil, 748, nil, nil, nil,
- nil, 748, 748, 748, 748, 748, 748, nil, nil, nil,
- 748, 748, nil, nil, nil, 755, 755, 755, 748, 755,
- nil, 748, nil, 755, 755, nil, 748, 748, 755, nil,
- 755, 755, 755, 755, 755, 755, 755, nil, nil, nil,
- nil, nil, 755, 755, 755, 755, 755, 755, 755, nil,
- nil, 755, nil, nil, nil, nil, nil, nil, 755, nil,
- nil, 755, 755, nil, 755, 755, 755, 755, 755, nil,
- 755, 755, 755, nil, 755, 755, nil, 755, 755, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 755, nil, nil, 755, nil, nil, 755, nil, nil, 755,
- nil, nil, nil, nil, nil, 755, nil, nil, nil, nil,
- nil, nil, nil, 755, nil, nil, nil, nil, 755, 755,
- 755, 755, 755, 755, nil, nil, nil, 755, 755, nil,
- nil, nil, nil, nil, nil, 755, nil, nil, 755, nil,
- nil, nil, nil, 755, 755, 769, 769, 769, 769, 769,
- nil, nil, nil, 769, 769, nil, nil, nil, 769, nil,
- 769, 769, 769, 769, 769, 769, 769, nil, nil, nil,
- nil, nil, 769, 769, 769, 769, 769, 769, 769, nil,
- nil, 769, nil, nil, nil, nil, nil, 769, 769, nil,
- 769, 769, 769, nil, 769, 769, 769, 769, 769, nil,
- 769, 769, 769, nil, 769, 769, nil, 769, 769, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 769, nil, nil, 769, nil, nil, 769, nil, nil, 769,
- nil, 769, nil, nil, nil, 769, nil, nil, nil, nil,
- nil, nil, nil, 769, nil, nil, nil, nil, 769, 769,
- 769, 769, 769, 769, nil, nil, nil, 769, 769, nil,
- nil, nil, 775, 775, 775, 769, 775, nil, 769, nil,
- 775, 775, nil, 769, 769, 775, nil, 775, 775, 775,
- 775, 775, 775, 775, nil, nil, nil, nil, nil, 775,
- 775, 775, 775, 775, 775, 775, nil, nil, 775, nil,
- nil, nil, nil, nil, nil, 775, nil, nil, 775, 775,
- nil, 775, 775, 775, 775, 775, nil, 775, 775, 775,
- nil, 775, 775, nil, 775, 775, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 775, nil, nil,
- 775, nil, nil, 775, nil, nil, 775, nil, nil, nil,
- nil, nil, 775, nil, nil, nil, nil, nil, nil, nil,
- 775, nil, nil, nil, nil, 775, 775, 775, 775, 775,
- 775, nil, nil, nil, 775, 775, nil, nil, nil, 776,
- 776, 776, 775, 776, nil, 775, nil, 776, 776, nil,
- 775, 775, 776, nil, 776, 776, 776, 776, 776, 776,
- 776, nil, nil, nil, nil, nil, 776, 776, 776, 776,
- 776, 776, 776, nil, nil, 776, nil, nil, nil, nil,
- nil, nil, 776, nil, nil, 776, 776, nil, 776, 776,
- 776, 776, 776, nil, 776, 776, 776, nil, 776, 776,
- nil, 776, 776, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 776, nil, nil, 776, nil, nil,
- 776, nil, nil, 776, nil, nil, nil, nil, nil, 776,
- nil, nil, nil, nil, nil, nil, nil, 776, nil, nil,
- nil, nil, 776, 776, 776, 776, 776, 776, nil, nil,
- nil, 776, 776, nil, nil, nil, 777, 777, 777, 776,
- 777, nil, 776, nil, 777, 777, nil, 776, 776, 777,
- nil, 777, 777, 777, 777, 777, 777, 777, nil, nil,
- nil, nil, nil, 777, 777, 777, 777, 777, 777, 777,
- nil, nil, 777, nil, nil, nil, nil, nil, nil, 777,
- nil, nil, 777, 777, nil, 777, 777, 777, 777, 777,
- nil, 777, 777, 777, nil, 777, 777, nil, 777, 777,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 777, nil, nil, 777, nil, nil, 777, nil, nil,
- 777, nil, nil, nil, nil, nil, 777, nil, nil, nil,
- nil, nil, nil, nil, 777, nil, nil, nil, nil, 777,
- 777, 777, 777, 777, 777, nil, nil, nil, 777, 777,
- nil, nil, nil, 788, 788, 788, 777, 788, nil, 777,
- nil, 788, 788, nil, 777, 777, 788, nil, 788, 788,
- 788, 788, 788, 788, 788, nil, nil, nil, nil, nil,
- 788, 788, 788, 788, 788, 788, 788, nil, nil, 788,
- nil, nil, nil, nil, nil, nil, 788, nil, nil, 788,
- 788, nil, 788, 788, 788, 788, 788, nil, 788, 788,
- 788, nil, 788, 788, nil, 788, 788, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 788, nil,
- nil, 788, nil, nil, 788, nil, nil, 788, nil, nil,
- nil, nil, nil, 788, nil, nil, nil, nil, nil, nil,
- nil, 788, nil, nil, nil, nil, 788, 788, 788, 788,
- 788, 788, nil, nil, nil, 788, 788, nil, nil, nil,
- 789, 789, 789, 788, 789, nil, 788, nil, 789, 789,
- nil, 788, 788, 789, nil, 789, 789, 789, 789, 789,
- 789, 789, nil, nil, nil, nil, nil, 789, 789, 789,
- 789, 789, 789, 789, nil, nil, 789, nil, nil, nil,
- nil, nil, nil, 789, nil, nil, 789, 789, nil, 789,
- 789, 789, 789, 789, nil, 789, 789, 789, nil, 789,
- 789, nil, 789, 789, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 789, nil, nil, 789, nil,
- nil, 789, nil, nil, 789, nil, nil, nil, nil, nil,
- 789, nil, nil, nil, nil, nil, nil, nil, 789, nil,
- nil, nil, nil, 789, 789, 789, 789, 789, 789, nil,
- nil, nil, 789, 789, nil, nil, nil, 790, 790, 790,
- 789, 790, nil, 789, nil, 790, 790, nil, 789, 789,
- 790, nil, 790, 790, 790, 790, 790, 790, 790, nil,
- nil, nil, nil, nil, 790, 790, 790, 790, 790, 790,
- 790, nil, nil, 790, nil, nil, nil, nil, nil, nil,
- 790, nil, nil, 790, 790, nil, 790, 790, 790, 790,
- 790, nil, 790, 790, 790, nil, 790, 790, nil, 790,
- 790, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 790, nil, nil, 790, nil, nil, 790, nil,
- nil, 790, nil, nil, nil, nil, nil, 790, nil, nil,
- nil, nil, nil, nil, nil, 790, nil, nil, nil, nil,
- 790, 790, 790, 790, 790, 790, nil, nil, nil, 790,
- 790, nil, nil, nil, 802, 802, 802, 790, 802, nil,
- 790, nil, 802, 802, nil, 790, 790, 802, nil, 802,
- 802, 802, 802, 802, 802, 802, nil, nil, nil, nil,
- nil, 802, 802, 802, 802, 802, 802, 802, nil, nil,
- 802, nil, nil, nil, nil, nil, nil, 802, nil, nil,
- 802, 802, nil, 802, 802, 802, 802, 802, nil, 802,
- 802, 802, nil, 802, 802, nil, 802, 802, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 802,
- nil, nil, 802, nil, nil, 802, nil, nil, 802, nil,
- 802, nil, nil, nil, 802, nil, nil, nil, nil, nil,
- nil, nil, 802, nil, nil, nil, nil, 802, 802, 802,
- 802, 802, 802, nil, nil, nil, 802, 802, nil, nil,
- nil, nil, nil, nil, 802, nil, nil, 802, nil, nil,
- nil, nil, 802, 802, 813, 813, 813, 813, 813, nil,
- nil, nil, 813, 813, nil, nil, nil, 813, nil, 813,
- 813, 813, 813, 813, 813, 813, nil, nil, nil, nil,
- nil, 813, 813, 813, 813, 813, 813, 813, nil, nil,
- 813, nil, nil, nil, nil, nil, 813, 813, nil, 813,
- 813, 813, nil, 813, 813, 813, 813, 813, nil, 813,
- 813, 813, nil, 813, 813, nil, 813, 813, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 813,
- nil, nil, 813, nil, nil, 813, nil, nil, 813, nil,
- 813, nil, nil, nil, 813, nil, nil, nil, nil, nil,
- nil, nil, 813, nil, nil, nil, nil, 813, 813, 813,
- 813, 813, 813, nil, nil, nil, 813, 813, nil, nil,
- nil, 832, 832, 832, 813, 832, nil, 813, nil, 832,
- 832, nil, 813, 813, 832, nil, 832, 832, 832, 832,
- 832, 832, 832, nil, nil, nil, nil, nil, 832, 832,
- 832, 832, 832, 832, 832, nil, nil, 832, nil, nil,
- nil, nil, nil, nil, 832, nil, nil, 832, 832, nil,
- 832, 832, 832, 832, 832, nil, 832, 832, 832, nil,
- 832, 832, nil, 832, 832, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 832, nil, nil, 832,
- nil, nil, 832, nil, nil, 832, nil, nil, nil, nil,
- nil, 832, nil, nil, nil, nil, nil, nil, nil, 832,
- nil, nil, nil, nil, 832, 832, 832, 832, 832, 832,
- nil, nil, nil, 832, 832, nil, nil, nil, nil, nil,
- nil, 832, nil, nil, 832, nil, nil, nil, nil, 832,
- 832, 834, 834, 834, 834, 834, nil, nil, nil, 834,
- 834, nil, nil, nil, 834, nil, 834, 834, 834, 834,
- 834, 834, 834, nil, nil, nil, nil, nil, 834, 834,
- 834, 834, 834, 834, 834, nil, nil, 834, nil, nil,
- nil, nil, nil, 834, 834, nil, 834, 834, 834, nil,
- 834, 834, 834, 834, 834, nil, 834, 834, 834, nil,
- 834, 834, nil, 834, 834, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 834, nil, nil, 834,
- nil, nil, 834, nil, nil, 834, nil, 834, nil, nil,
- nil, 834, nil, nil, nil, nil, nil, nil, nil, 834,
- nil, nil, nil, nil, 834, 834, 834, 834, 834, 834,
- nil, nil, nil, 834, 834, nil, nil, nil, nil, nil,
- nil, 834, nil, nil, 834, nil, nil, nil, nil, 834,
- 834, 835, 835, 835, 835, 835, nil, nil, nil, 835,
- 835, nil, nil, nil, 835, nil, 835, 835, 835, 835,
- 835, 835, 835, nil, nil, nil, nil, nil, 835, 835,
- 835, 835, 835, 835, 835, nil, nil, 835, nil, nil,
- nil, nil, nil, 835, 835, nil, 835, 835, 835, nil,
- 835, 835, 835, 835, 835, nil, 835, 835, 835, nil,
- 835, 835, nil, 835, 835, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 835, nil, nil, 835,
- nil, nil, 835, nil, nil, 835, nil, 835, nil, nil,
- nil, 835, nil, nil, nil, nil, nil, nil, nil, 835,
- nil, nil, nil, nil, 835, 835, 835, 835, 835, 835,
- nil, nil, nil, 835, 835, nil, nil, nil, 862, 862,
- 862, 835, 862, nil, 835, nil, 862, 862, nil, 835,
- 835, 862, nil, 862, 862, 862, 862, 862, 862, 862,
- nil, nil, nil, nil, nil, 862, 862, 862, 862, 862,
- 862, 862, nil, nil, 862, nil, nil, nil, nil, nil,
- nil, 862, nil, nil, 862, 862, nil, 862, 862, 862,
- 862, 862, nil, 862, 862, 862, nil, 862, 862, nil,
- 862, 862, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 862, nil, nil, 862, nil, nil, 862,
- nil, nil, 862, nil, nil, nil, nil, nil, 862, nil,
- nil, nil, nil, nil, nil, nil, 862, nil, nil, nil,
- nil, 862, 862, 862, 862, 862, 862, nil, nil, nil,
- 862, 862, nil, nil, nil, 876, 876, 876, 862, 876,
- nil, 862, nil, 876, 876, nil, 862, 862, 876, nil,
- 876, 876, 876, 876, 876, 876, 876, nil, nil, nil,
- nil, nil, 876, 876, 876, 876, 876, 876, 876, nil,
- nil, 876, nil, nil, nil, nil, nil, nil, 876, nil,
- nil, 876, 876, nil, 876, 876, 876, 876, 876, nil,
- 876, 876, 876, nil, 876, 876, nil, 876, 876, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 876, nil, nil, 876, nil, nil, 876, nil, nil, 876,
- nil, nil, nil, nil, nil, 876, nil, nil, nil, nil,
- nil, nil, nil, 876, nil, nil, nil, nil, 876, 876,
- 876, 876, 876, 876, nil, nil, nil, 876, 876, nil,
- nil, nil, 877, 877, 877, 876, 877, nil, 876, nil,
- 877, 877, nil, 876, 876, 877, nil, 877, 877, 877,
- 877, 877, 877, 877, nil, nil, nil, nil, nil, 877,
- 877, 877, 877, 877, 877, 877, nil, nil, 877, nil,
- nil, nil, nil, nil, nil, 877, nil, nil, 877, 877,
- nil, 877, 877, 877, 877, 877, nil, 877, 877, 877,
- nil, 877, 877, nil, 877, 877, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 877, nil, nil,
- 877, nil, nil, 877, nil, nil, 877, nil, nil, nil,
- nil, nil, 877, nil, nil, nil, nil, nil, nil, nil,
- 877, nil, nil, nil, nil, 877, 877, 877, 877, 877,
- 877, nil, nil, nil, 877, 877, nil, nil, nil, 881,
- 881, 881, 877, 881, nil, 877, nil, 881, 881, nil,
- 877, 877, 881, nil, 881, 881, 881, 881, 881, 881,
- 881, nil, nil, nil, nil, nil, 881, 881, 881, 881,
- 881, 881, 881, nil, nil, 881, nil, nil, nil, nil,
- nil, nil, 881, nil, nil, 881, 881, nil, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, nil, 881, 881,
- nil, 881, 881, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 881, nil, nil, 881, nil, nil,
- 881, nil, nil, 881, nil, nil, nil, 881, nil, 881,
- nil, nil, nil, nil, nil, nil, nil, 881, nil, nil,
- nil, nil, 881, 881, 881, 881, 881, 881, nil, nil,
- nil, 881, 881, nil, nil, nil, nil, nil, nil, 881,
- nil, nil, 881, nil, nil, nil, nil, 881, 881, 886,
- 886, 886, 886, 886, nil, nil, nil, 886, 886, nil,
- nil, nil, 886, nil, 886, 886, 886, 886, 886, 886,
- 886, nil, nil, nil, nil, nil, 886, 886, 886, 886,
- 886, 886, 886, nil, nil, 886, nil, nil, nil, nil,
- nil, 886, 886, nil, 886, 886, 886, nil, 886, 886,
- 886, 886, 886, nil, 886, 886, 886, nil, 886, 886,
- nil, 886, 886, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 886, nil, nil, 886, nil, nil,
- 886, nil, nil, 886, nil, 886, nil, nil, nil, 886,
- nil, nil, nil, nil, nil, nil, nil, 886, nil, nil,
- nil, nil, 886, 886, 886, 886, 886, 886, nil, nil,
- nil, 886, 886, nil, nil, nil, 890, 890, 890, 886,
- 890, nil, 886, nil, 890, 890, nil, 886, 886, 890,
- nil, 890, 890, 890, 890, 890, 890, 890, nil, nil,
- nil, nil, nil, 890, 890, 890, 890, 890, 890, 890,
- nil, nil, 890, nil, nil, nil, nil, nil, nil, 890,
- nil, nil, 890, 890, nil, 890, 890, 890, 890, 890,
- nil, 890, 890, 890, nil, 890, 890, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 890, nil, nil, 890, nil, nil, 890, nil, nil,
- 890, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 890,
- 890, 890, 890, 890, 890, nil, nil, nil, 890, 890,
- nil, nil, nil, 900, 900, 900, 890, 900, nil, 890,
- nil, 900, 900, nil, 890, 890, 900, nil, 900, 900,
- 900, 900, 900, 900, 900, nil, nil, nil, nil, nil,
- 900, 900, 900, 900, 900, 900, 900, nil, nil, 900,
- nil, nil, nil, nil, nil, nil, 900, nil, nil, 900,
- 900, nil, 900, 900, 900, 900, 900, nil, 900, 900,
- 900, nil, 900, 900, nil, 900, 900, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 900, nil,
- nil, 900, nil, nil, 900, nil, nil, 900, nil, 900,
- nil, nil, nil, 900, nil, nil, nil, nil, nil, nil,
- nil, 900, nil, nil, nil, nil, 900, 900, 900, 900,
- 900, 900, nil, nil, nil, 900, 900, nil, nil, nil,
- nil, nil, nil, 900, nil, nil, 900, nil, nil, nil,
- nil, 900, 900, 901, 901, 901, 901, 901, nil, nil,
- nil, 901, 901, nil, nil, nil, 901, nil, 901, 901,
- 901, 901, 901, 901, 901, nil, nil, nil, nil, nil,
- 901, 901, 901, 901, 901, 901, 901, nil, nil, 901,
- nil, nil, nil, nil, nil, 901, 901, nil, 901, 901,
- 901, nil, 901, 901, 901, 901, 901, nil, 901, 901,
- 901, nil, 901, 901, nil, 901, 901, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 901, nil,
- nil, 901, nil, nil, 901, nil, nil, 901, nil, 901,
- nil, nil, nil, 901, nil, nil, nil, nil, nil, nil,
- nil, 901, nil, nil, nil, nil, 901, 901, 901, 901,
- 901, 901, nil, nil, nil, 901, 901, nil, nil, nil,
- nil, nil, nil, 901, nil, nil, 901, nil, nil, nil,
- nil, 901, 901, 904, 904, 904, 904, 904, nil, nil,
- nil, 904, 904, nil, nil, nil, 904, nil, 904, 904,
- 904, 904, 904, 904, 904, nil, nil, nil, nil, nil,
- 904, 904, 904, 904, 904, 904, 904, nil, nil, 904,
- nil, nil, nil, nil, nil, 904, 904, nil, 904, 904,
- 904, nil, 904, 904, 904, 904, 904, nil, 904, 904,
- 904, nil, 904, 904, nil, 904, 904, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 904, nil,
- nil, 904, nil, nil, 904, nil, nil, 904, nil, 904,
- nil, nil, nil, 904, nil, nil, nil, nil, nil, nil,
- nil, 904, nil, nil, nil, nil, 904, 904, 904, 904,
- 904, 904, nil, nil, nil, 904, 904, nil, nil, nil,
- 921, 921, 921, 904, 921, nil, 904, nil, 921, 921,
- nil, 904, 904, 921, nil, 921, 921, 921, 921, 921,
- 921, 921, nil, nil, nil, nil, nil, 921, 921, 921,
- 921, 921, 921, 921, nil, nil, 921, nil, nil, nil,
- nil, nil, nil, 921, nil, nil, 921, 921, nil, 921,
- 921, 921, 921, 921, nil, 921, 921, 921, nil, 921,
- 921, nil, 921, 921, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 921, nil, nil, 921, nil,
- nil, 921, nil, nil, 921, nil, 921, nil, 921, nil,
- 921, nil, nil, nil, nil, nil, nil, nil, 921, nil,
- nil, nil, nil, 921, 921, 921, 921, 921, 921, nil,
- nil, nil, 921, 921, nil, nil, nil, nil, nil, nil,
- 921, nil, nil, 921, nil, nil, nil, nil, 921, 921,
- 923, 923, 923, 923, 923, nil, nil, nil, 923, 923,
- nil, nil, nil, 923, nil, 923, 923, 923, 923, 923,
- 923, 923, nil, nil, nil, nil, nil, 923, 923, 923,
- 923, 923, 923, 923, nil, nil, 923, nil, nil, nil,
- nil, nil, 923, 923, nil, 923, 923, 923, nil, 923,
- 923, 923, 923, 923, nil, 923, 923, 923, nil, 923,
- 923, nil, 923, 923, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 923, nil, nil, 923, nil,
- nil, 923, nil, nil, 923, nil, 923, nil, nil, nil,
- 923, nil, nil, nil, nil, nil, nil, nil, 923, nil,
- nil, nil, nil, 923, 923, 923, 923, 923, 923, nil,
- nil, nil, 923, 923, nil, nil, nil, nil, nil, nil,
- 923, nil, nil, 923, nil, nil, nil, nil, 923, 923,
- 930, 930, 930, 930, 930, nil, nil, nil, 930, 930,
- nil, nil, nil, 930, nil, 930, 930, 930, 930, 930,
- 930, 930, nil, nil, nil, nil, nil, 930, 930, 930,
- 930, 930, 930, 930, nil, nil, 930, nil, nil, nil,
- nil, nil, 930, 930, nil, 930, 930, 930, nil, 930,
- 930, 930, 930, 930, nil, 930, 930, 930, nil, 930,
- 930, nil, 930, 930, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 930, nil, nil, 930, nil,
- nil, 930, nil, nil, 930, nil, 930, nil, nil, nil,
- 930, nil, nil, nil, nil, nil, nil, nil, 930, nil,
- nil, nil, nil, 930, 930, 930, 930, 930, 930, nil,
- nil, nil, 930, 930, nil, nil, nil, nil, nil, nil,
- 930, nil, nil, 930, nil, nil, nil, nil, 930, 930,
- 935, 935, 935, 935, 935, nil, nil, nil, 935, 935,
- nil, nil, nil, 935, nil, 935, 935, 935, 935, 935,
- 935, 935, nil, nil, nil, nil, nil, 935, 935, 935,
- 935, 935, 935, 935, nil, nil, 935, nil, nil, nil,
- nil, nil, 935, 935, nil, 935, 935, 935, nil, 935,
- 935, 935, 935, 935, nil, 935, 935, 935, nil, 935,
- 935, nil, 935, 935, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 935, nil, nil, 935, nil,
- nil, 935, nil, nil, 935, nil, 935, nil, nil, nil,
- 935, nil, nil, nil, nil, nil, nil, nil, 935, nil,
- nil, nil, nil, 935, 935, 935, 935, 935, 935, nil,
- nil, nil, 935, 935, nil, nil, nil, nil, nil, nil,
- 935, nil, nil, 935, nil, nil, nil, nil, 935, 935,
- 943, 943, 943, 943, 943, nil, nil, nil, 943, 943,
- nil, nil, nil, 943, nil, 943, 943, 943, 943, 943,
- 943, 943, nil, nil, nil, nil, nil, 943, 943, 943,
- 943, 943, 943, 943, nil, nil, 943, nil, nil, nil,
- nil, nil, 943, 943, nil, 943, 943, 943, nil, 943,
- 943, 943, 943, 943, nil, 943, 943, 943, nil, 943,
- 943, nil, 943, 943, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 943, nil, nil, 943, nil,
- nil, 943, nil, nil, 943, nil, 943, nil, nil, nil,
- 943, nil, nil, nil, nil, nil, nil, nil, 943, nil,
- nil, nil, nil, 943, 943, 943, 943, 943, 943, nil,
- nil, nil, 943, 943, nil, nil, nil, 945, 945, 945,
- 943, 945, nil, 943, nil, 945, 945, nil, 943, 943,
- 945, nil, 945, 945, 945, 945, 945, 945, 945, nil,
- nil, nil, nil, nil, 945, 945, 945, 945, 945, 945,
- 945, nil, nil, 945, nil, nil, nil, nil, nil, nil,
- 945, nil, nil, 945, 945, nil, 945, 945, 945, 945,
- 945, 945, 945, 945, 945, nil, 945, 945, nil, 945,
- 945, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 945, nil, nil, 945, nil, nil, 945, nil,
- nil, 945, nil, 945, nil, nil, nil, 945, nil, nil,
- nil, nil, nil, nil, nil, 945, nil, nil, nil, 436,
- 945, 945, 945, 945, 945, 945, 436, 436, 436, 945,
- 945, nil, 436, 436, nil, 436, nil, 945, nil, nil,
- 945, nil, nil, nil, 436, 945, 945, nil, nil, nil,
- nil, nil, nil, nil, nil, 436, 436, nil, 436, 436,
- 436, 436, 436, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 436, 436, 436, 436,
- 436, 436, 436, 436, 436, 436, 436, 436, 436, 436,
- 436, 438, nil, 436, 436, 436, nil, 436, 438, 438,
- 438, 436, nil, nil, 438, 438, nil, 438, 436, nil,
- 436, nil, 436, 436, 436, 436, 436, 436, 436, nil,
- 436, 436, 436, nil, nil, nil, nil, 438, 438, nil,
- 438, 438, 438, 438, 438, 436, 436, nil, 436, nil,
- 436, nil, nil, 436, nil, 436, nil, 436, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 438, 438,
- 438, 438, 438, 438, 438, 438, 438, 438, 438, 438,
- 438, 438, 438, nil, nil, 438, 438, 438, nil, 438,
- nil, nil, nil, 438, nil, nil, nil, nil, nil, nil,
- 438, nil, 438, nil, 438, 438, 438, 438, 438, 438,
- 438, nil, 438, nil, 438, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 438, 438, nil,
- 438, nil, 438, 644, nil, 438, nil, 438, nil, 438,
- 644, 644, 644, nil, nil, 644, 644, 644, nil, 644,
- nil, nil, nil, nil, nil, nil, nil, nil, 644, 644,
- 644, nil, nil, nil, nil, nil, nil, nil, nil, 644,
- 644, nil, 644, 644, 644, 644, 644, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 644, 644, 644, 644, 644, 644, 644, 644, 644, 644,
- 644, 644, 644, 644, 644, nil, nil, 644, 644, 644,
- nil, 644, 644, nil, nil, 644, nil, nil, 644, nil,
- 644, nil, 644, nil, 644, nil, 644, 644, 644, 644,
- 644, 644, 644, nil, 644, 644, 644, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 644,
- 644, 644, 644, nil, 644, 645, nil, 644, nil, 644,
- nil, 644, 645, 645, 645, nil, nil, 645, 645, 645,
- nil, 645, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 645, 645, nil, nil, nil, nil, nil, nil, nil,
- nil, 645, 645, nil, 645, 645, 645, 645, 645, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 645, 645, 645, 645, 645, 645, 645, 645,
- 645, 645, 645, 645, 645, 645, 645, nil, nil, 645,
- 645, 645, nil, 645, 645, nil, nil, 645, nil, nil,
- 645, nil, 645, nil, 645, nil, 645, nil, 645, 645,
- 645, 645, 645, 645, 645, nil, 645, nil, 645, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 645, 645, 645, 645, nil, 645, 28, nil, 645,
- nil, 645, nil, 645, 28, 28, 28, nil, nil, 28,
- 28, 28, nil, 28, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 28, 28, nil, nil, nil, nil, nil,
- nil, nil, nil, 28, 28, nil, 28, 28, 28, 28,
- 28, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28, 28, nil,
- nil, 28, 28, 28, nil, nil, 28, nil, 28, 28,
- nil, nil, 28, nil, 28, nil, 28, nil, 28, nil,
- 28, 28, 28, 28, 28, 28, 28, nil, 28, nil,
- 28, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 28, 28, 28, 28, 50, 28, nil,
- nil, 28, nil, 28, 50, 50, 50, nil, nil, 50,
- 50, 50, nil, 50, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 50, 50, nil, nil, nil, nil,
- nil, nil, nil, 50, 50, nil, 50, 50, 50, 50,
- 50, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 50, 50, 50, 50, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, nil,
- nil, 50, 50, 50, nil, nil, 50, nil, nil, 50,
- nil, nil, 50, nil, 50, nil, 50, nil, 50, nil,
- 50, 50, 50, 50, 50, 50, 50, nil, 50, nil,
- 50, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 50, 50, 50, 50, 494, 50, nil,
- 50, 50, nil, 50, 494, 494, 494, nil, nil, 494,
- 494, 494, nil, 494, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 494, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 494, 494, nil, 494, 494, 494, 494,
- 494, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 495, nil, nil, nil, nil, nil,
- nil, 495, 495, 495, nil, nil, 495, 495, 495, nil,
- 495, nil, nil, nil, nil, 494, 494, nil, nil, nil,
- 495, nil, nil, 494, nil, nil, nil, nil, 494, 494,
- 495, 495, nil, 495, 495, 495, 495, 495, nil, nil,
- nil, nil, 918, nil, 918, 918, 918, 918, 918, nil,
- 494, nil, nil, nil, nil, nil, nil, nil, 918, nil,
- nil, nil, 496, 494, nil, 494, nil, nil, 494, 496,
- 496, 496, 495, 495, 496, 496, 496, nil, 496, nil,
- 495, 918, 918, nil, nil, 495, 495, nil, 496, 918,
- 918, 918, 918, nil, nil, nil, nil, nil, 496, 496,
- nil, 496, 496, 496, 496, 496, nil, 495, nil, nil,
- nil, nil, nil, 202, 202, nil, nil, 202, nil, nil,
- 495, nil, 495, nil, nil, 495, 202, 202, 918, 202,
- 202, 202, 202, 202, 202, 202, nil, nil, 202, 202,
- 496, 496, nil, nil, 202, 202, 202, 202, 496, nil,
- nil, nil, nil, 496, 496, nil, nil, nil, nil, nil,
- 202, 202, nil, 202, 202, 202, 202, 202, 202, 202,
- 202, 202, 202, 202, nil, 496, 202, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 496, nil,
- 496, nil, nil, 496, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, nil, nil,
- nil, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, nil, 7, 7, 7, nil, 7, nil, nil,
- nil, nil, nil, nil, nil, nil, 7, 7, nil, 7,
- 7, 7, 7, 7, 7, 7, nil, nil, 7, 7,
- nil, nil, nil, nil, 7, 7, 7, 7, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 7, 7, nil, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, nil, nil, 7, 7, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 7, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, nil, nil, nil, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, nil, 8, 8, nil,
- nil, 8, nil, nil, nil, nil, nil, nil, nil, nil,
- 8, 8, nil, 8, 8, 8, 8, 8, 8, 8,
- nil, nil, 8, 8, nil, nil, nil, nil, 8, 8,
- 8, 8, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 8, 8, nil, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, nil, nil,
- 8, 8, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 8, 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, nil, nil, nil, 411,
- 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411, 411, 411,
- nil, 411, 411, nil, nil, 411, nil, nil, nil, nil,
- nil, nil, nil, nil, 411, 411, nil, 411, 411, 411,
- 411, 411, 411, 411, nil, nil, 411, 411, nil, nil,
- nil, nil, 411, 411, 411, 411, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 411, 411,
- nil, 411, 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, nil, nil, 411, 411, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 411, 415, 415, 415, 415,
- 415, 415, 415, 415, 415, 415, 415, 415, 415, 415,
- 415, 415, 415, 415, 415, 415, 415, 415, 415, 415,
- nil, nil, nil, 415, 415, 415, 415, 415, 415, 415,
- 415, 415, 415, 415, 415, 415, 415, 415, 415, 415,
- 415, 415, 415, 415, nil, 415, 415, nil, nil, 415,
- nil, nil, nil, nil, nil, nil, nil, nil, 415, 415,
- nil, 415, 415, 415, 415, 415, 415, 415, nil, nil,
- 415, 415, nil, nil, nil, nil, 415, 415, 415, 415,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 415, 415, nil, 415, 415, 415, 415, 415,
- 415, 415, 415, 415, 415, 415, nil, nil, 415, 415,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 415,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, nil, nil, nil, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, nil, 65,
- 65, 65, 65, 65, nil, 65, nil, nil, nil, nil,
- nil, nil, 65, 65, nil, 65, 65, 65, 65, 65,
- 65, 65, nil, nil, 65, 65, nil, nil, nil, nil,
- 65, 65, 65, 65, nil, nil, nil, nil, nil, 65,
- nil, nil, nil, nil, nil, nil, 65, 65, nil, 65,
- 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
- nil, nil, 65, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, nil, nil, nil,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, nil, 79, 79, 79, 79, 79, nil, 79, nil,
- nil, nil, nil, nil, nil, 79, 79, nil, 79, 79,
- 79, 79, 79, 79, 79, nil, nil, 79, 79, nil,
- nil, nil, nil, 79, 79, 79, 79, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 79,
- 79, nil, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, nil, nil, 79, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
- nil, nil, nil, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, nil, 192, 192, 192, 192, 192,
- nil, 192, nil, nil, nil, nil, nil, nil, 192, 192,
- nil, 192, 192, 192, 192, 192, 192, 192, nil, nil,
- 192, 192, nil, nil, nil, nil, 192, 192, 192, 192,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 192, 192, nil, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, nil, nil, 192, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, nil, nil, nil, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, nil, 766, 766,
- nil, nil, 766, nil, nil, nil, nil, nil, nil, nil,
- nil, 766, 766, nil, 766, 766, 766, 766, 766, 766,
- 766, nil, nil, 766, 766, nil, nil, nil, nil, 766,
- 766, 766, 766, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 766, 766, nil, 766, 766,
- 766, 766, 766, 766, 766, 766, 766, 766, 766, 201,
- 201, 766, nil, 201, nil, nil, nil, nil, nil, nil,
- nil, nil, 201, 201, nil, 201, 201, 201, 201, 201,
- 201, 201, nil, nil, 201, 201, nil, nil, nil, nil,
- 201, 201, 201, 201, nil, nil, nil, nil, nil, 201,
- nil, nil, nil, nil, nil, nil, 201, 201, nil, 201,
- 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
- 203, 203, 201, nil, 203, nil, nil, nil, nil, nil,
- nil, nil, nil, 203, 203, nil, 203, 203, 203, 203,
- 203, 203, 203, nil, nil, 203, 203, nil, nil, nil,
- nil, 203, 203, 203, 203, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 203, 203, nil,
- 203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 264, 264, 203, nil, 264, nil, nil, nil, nil,
- nil, nil, nil, nil, 264, 264, nil, 264, 264, 264,
- 264, 264, 264, 264, nil, nil, 264, 264, nil, nil,
- nil, nil, 264, 264, 264, 264, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 264, 264,
- nil, 264, 264, 264, 264, 264, 264, 264, 264, 264,
- 264, 264, 265, 265, 264, nil, 265, nil, nil, nil,
- nil, nil, nil, nil, nil, 265, 265, nil, 265, 265,
- 265, 265, 265, 265, 265, nil, nil, 265, 265, nil,
- nil, nil, nil, 265, 265, 265, 265, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 265,
- 265, nil, 265, 265, 265, 265, 265, 265, 265, 265,
- 265, 265, 265, 266, 266, 265, nil, 266, nil, nil,
- nil, nil, nil, nil, nil, nil, 266, 266, nil, 266,
- 266, 266, 266, 266, 266, 266, nil, nil, 266, 266,
- nil, nil, nil, nil, 266, 266, 266, 266, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 266, 266, nil, 266, 266, 266, 266, 266, 266, 266,
- 266, 266, 266, 266, 449, 449, 266, nil, 449, nil,
- nil, nil, nil, nil, nil, nil, nil, 449, 449, nil,
- 449, 449, 449, 449, 449, 449, 449, nil, nil, 449,
- 449, nil, nil, nil, nil, 449, 449, 449, 449, nil,
- nil, nil, nil, nil, 449, nil, nil, nil, nil, nil,
- nil, 449, 449, nil, 449, 449, 449, 449, 449, 449,
- 449, 449, 449, 449, 449, 450, 450, 449, nil, 450,
- nil, nil, nil, nil, nil, nil, nil, nil, 450, 450,
- nil, 450, 450, 450, 450, 450, 450, 450, nil, nil,
- 450, 450, nil, nil, nil, nil, 450, 450, 450, 450,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 450, 450, nil, 450, 450, 450, 450, 450,
- 450, 450, 450, 450, 450, 450, 521, 521, 450, nil,
- 521, nil, nil, nil, nil, nil, nil, nil, nil, 521,
- 521, nil, 521, 521, 521, 521, 521, 521, 521, nil,
- nil, 521, 521, nil, nil, nil, nil, 521, 521, 521,
- 521, nil, nil, nil, nil, nil, 521, nil, nil, nil,
- nil, nil, nil, 521, 521, nil, 521, 521, 521, 521,
- 521, 521, 521, 521, 521, 521, 521, 522, 522, 521,
- nil, 522, nil, nil, nil, nil, nil, nil, nil, nil,
- 522, 522, nil, 522, 522, 522, 522, 522, 522, 522,
- nil, nil, 522, 522, nil, nil, nil, nil, 522, 522,
- 522, 522, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 522, 522, nil, 522, 522, 522,
- 522, 522, 522, 522, 522, 522, 522, 522, 524, 524,
- 522, nil, 524, nil, nil, nil, nil, nil, nil, nil,
- nil, 524, 524, nil, 524, 524, 524, 524, 524, 524,
- 524, nil, nil, 524, 524, nil, nil, nil, nil, 524,
- 524, 524, 524, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 524, 524, nil, 524, 524,
- 524, 524, 524, 524, 524, 524, 524, 524, 524, 534,
- 534, 524, nil, 534, nil, nil, nil, nil, nil, nil,
- nil, nil, 534, 534, nil, 534, 534, 534, 534, 534,
- 534, 534, nil, nil, 534, 534, nil, nil, nil, nil,
- 534, 534, 534, 534, nil, nil, nil, nil, nil, 534,
- nil, nil, nil, nil, nil, nil, 534, 534, nil, 534,
- 534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
- 535, 535, 534, nil, 535, nil, nil, nil, nil, nil,
- nil, nil, nil, 535, 535, nil, 535, 535, 535, 535,
- 535, 535, 535, nil, nil, 535, 535, nil, nil, nil,
- nil, 535, 535, 535, 535, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 535, 535, nil,
- 535, 535, 535, 535, 535, 535, 535, 535, 535, 535,
- 535, 584, 584, 535, nil, 584, nil, nil, nil, nil,
- nil, nil, nil, nil, 584, 584, nil, 584, 584, 584,
- 584, 584, 584, 584, nil, nil, 584, 584, nil, nil,
- nil, nil, 584, 584, 584, 584, nil, nil, nil, nil,
- nil, 584, nil, nil, nil, nil, nil, nil, 584, 584,
- nil, 584, 584, 584, 584, 584, 584, 584, 584, 584,
- 584, 584, 585, 585, 584, nil, 585, nil, nil, nil,
- nil, nil, nil, nil, nil, 585, 585, nil, 585, 585,
- 585, 585, 585, 585, 585, nil, nil, 585, 585, nil,
- nil, nil, nil, 585, 585, 585, 585, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 585,
- 585, nil, 585, 585, 585, 585, 585, 585, 585, 585,
- 585, 585, 585, 591, 591, 585, nil, 591, nil, nil,
- nil, nil, nil, nil, nil, nil, 591, 591, nil, 591,
- 591, 591, 591, 591, 591, 591, nil, nil, 591, 591,
- nil, nil, nil, nil, 591, 591, 591, 591, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 591, 591, nil, 591, 591, 591, 591, 591, 591, 591,
- 591, 591, 591, 591, 593, 593, 591, nil, 593, nil,
- nil, nil, nil, nil, nil, nil, nil, 593, 593, nil,
- 593, 593, 593, 593, 593, 593, 593, nil, nil, 593,
- 593, nil, nil, nil, nil, 593, 593, 593, 593, nil,
- nil, nil, nil, nil, 593, nil, nil, nil, nil, nil,
- nil, 593, 593, nil, 593, 593, 593, 593, 593, 593,
- 593, 593, 593, 593, 593, 822, 822, 593, nil, 822,
- nil, nil, nil, nil, nil, nil, nil, nil, 822, 822,
- nil, 822, 822, 822, 822, 822, 822, 822, nil, nil,
- 822, 822, nil, nil, nil, nil, 822, 822, 822, 822,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 822, 822, nil, 822, 822, 822, 822, 822,
- 822, 822, 822, 822, 822, 822, 946, 946, 822, nil,
- 946, nil, nil, nil, nil, nil, nil, nil, nil, 946,
- 946, nil, 946, 946, 946, 946, 946, 946, 946, nil,
- nil, 946, 946, nil, nil, nil, nil, 946, 946, 946,
- 946, nil, nil, nil, nil, nil, 946, nil, nil, nil,
- nil, nil, nil, 946, 946, nil, 946, 946, 946, 946,
- 946, 946, 946, 946, 946, 946, 946, 947, 947, 946,
- nil, 947, nil, nil, nil, nil, nil, nil, nil, nil,
- 947, 947, nil, 947, 947, 947, 947, 947, 947, 947,
- nil, nil, 947, 947, nil, nil, nil, nil, 947, 947,
- 947, 947, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 947, 947, nil, 947, 947, 947,
- 947, 947, 947, 947, 947, 947, 947, 947, nil, nil,
- 947 ]
-
-racc_action_pointer = [
- -2, 34, nil, 234, nil, 618, -19, 22922, 23046, -5,
- -1, 15, 117, 414, 291, 243, nil, 125, 252, 900,
- 186, nil, 379, 506, 633, 381, 13, 760, 22407, nil,
- 900, 1027, 1154, nil, 108, 541, 237, 261, 1294, 1421,
- 1548, 176, 467, nil, nil, nil, nil, nil, nil, nil,
- 22537, nil, 1675, 1802, 1929, 29, 9932, 2056, 2183, nil,
- nil, 2310, 2450, 2577, nil, 23418, nil, nil, nil, nil,
- nil, -102, nil, nil, nil, nil, nil, 178, 220, 23531,
- nil, nil, nil, 429, 2704, nil, nil, 2831, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 359, nil, 2971,
- nil, nil, nil, 3111, 3238, 3365, 3492, 3632, 3772, nil,
- 663, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 23644, 234, nil, 3912, 4039, 4166, 4293, 4420,
- 4547, 23818, 22792, 23879, 4674, 4801, 4928, nil, 541, -49,
- 319, 61, 240, 328, 5068, 5195, nil, nil, 5322, 363,
- 5449, 5576, 5703, 5830, 5957, 6084, 6211, 6338, 6465, 6592,
- 6719, 6846, 6973, 7100, 7227, 7354, 7481, 7608, 7735, 7862,
- 7989, 8116, 8243, 8370, 8497, 8624, nil, nil, nil, 1294,
- nil, 329, 339, nil, 8751, 389, 8878, nil, nil, nil,
- nil, 9005, nil, nil, 23940, 24001, 24062, 383, 9132, 9259,
- nil, nil, nil, nil, nil, nil, nil, 9386, 249, 745,
- 390, 9526, 409, 438, 405, 9653, 9793, 73, 594, 497,
- 196, 465, 440, 207, nil, 478, 471, nil, 9920, nil,
- 586, 505, 531, 633, nil, 533, nil, 10047, nil, 10187,
- 35, nil, 502, -103, 135, 537, 521, 262, 556, nil,
- nil, -22, 10580, nil, nil, nil, 520, 545, nil, 564,
- 567, nil, nil, nil, nil, nil, nil, nil, 3097, nil,
- nil, nil, 648, nil, nil, 674, 806, -7, 36, 10314,
- 10441, 324, 63, 596, -17, 668, 690, 37, 731, nil,
- nil, 506, 704, nil, 721, nil, 65, nil, nil, 10568,
- -12, 122, 360, 384, 385, 436, 509, 590, nil, 795,
- nil, 10695, nil, 173, nil, 326, nil, -23, 649, 362,
- nil, 653, -50, nil, 365, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 683, 23170, nil, nil, nil, 23294, 688, nil, nil, 760,
- nil, 10822, 681, nil, 691, nil, nil, 1421, 728, 731,
- 668, 761, 10949, nil, nil, nil, 21929, 757, 22011, nil,
- 11076, 11203, 11330, nil, nil, nil, 1548, nil, nil, 24123,
- 24184, 11457, 11584, 180, 11711, 11838, 11965, 115, nil, 3238,
- 3365, 232, 879, 785, 787, 821, 824, 2457, 2584, 5068,
- 3492, 3632, 3772, 3912, 4039, 4166, 4293, 4420, 4547, 4674,
- 1133, 1232, 4801, 4928, 633, -34, nil, 12092, nil, 12219,
- nil, 12346, nil, nil, 22667, 22724, 22792, -17, nil, 771,
- nil, nil, 785, 787, nil, nil, 12473, 59, 203, 832,
- nil, nil, 12613, 833, 797, nil, nil, 799, 12753, 845,
- 12880, 24245, 24306, 13007, 24367, 223, 848, nil, nil, 821,
- nil, 13134, 13261, 13388, 24428, 24489, 1675, 13515, 949, 951,
- 871, nil, nil, 13642, nil, nil, 13769, nil, nil, nil,
- nil, 13909, 14049, 874, nil, 1000, nil, nil, 14176, 12765,
- nil, 772, nil, nil, 894, nil, 3126, nil, 859, 1198,
- nil, nil, 14316, 977, nil, nil, 14456, 212, 227, 975,
- 983, 14596, nil, 14723, 24550, 24611, 14850, 40, nil, 760,
- nil, 24672, 14977, 24733, nil, nil, 15104, 387, 15231, nil,
- 1166, nil, nil, nil, 45, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, -35, nil, nil, nil, 864,
- nil, nil, nil, nil, nil, 15358, 866, 15485, 798, 203,
- 15612, 15739, 900, nil, nil, nil, 15866, 903, nil, 15993,
- 915, nil, 268, 307, 22143, 22275, 927, 928, 506, nil,
- 16120, nil, 1040, nil, 16260, 897, nil, 939, 16387, nil,
- nil, nil, nil, nil, nil, nil, nil, 16527, nil, 942,
- 16654, 16781, 2310, 907, nil, nil, 947, 16921, 17061, nil,
- 1154, -27, 17188, 914, nil, 957, 228, 235, 962, 313,
- 327, 963, 960, 972, 17315, 1802, 997, 1001, 240, 1056,
- 17442, nil, nil, 376, 960, 1068, nil, nil, 945, nil,
- 958, 935, 1035, 963, 967, nil, nil, 1010, 3135, nil,
- 869, nil, 1096, nil, nil, nil, nil, nil, 1102, nil,
- 1103, 17569, 1020, 46, 52, 59, 102, 1021, 17696, 1027,
- nil, 1028, 1026, 17836, 416, nil, -25, 17976, 18116, 9665,
- 463, nil, nil, 1075, nil, 18243, nil, 998, 999, nil,
- 1000, 1002, 1004, nil, 996, nil, 23757, 1043, 1050, 18383,
- nil, nil, nil, 1929, 1007, 18510, 18637, 18764, nil, 2056,
- nil, 2183, nil, nil, 2446, nil, 2573, nil, 18891, 19018,
- 19145, 315, 319, 2704, nil, 1041, 1144, nil, nil, 1041,
- nil, 1026, 19272, nil, 1053, 1161, 1072, 323, nil, nil,
- nil, 1196, nil, 19412, 1081, 1125, nil, nil, nil, nil,
- nil, nil, 24794, nil, 1127, nil, nil, nil, nil, 1407,
- 1215, nil, 19539, 1220, 19679, 19819, nil, nil, 66, 56,
- 988, 295, nil, 1221, nil, nil, 1222, 1225, 1109, nil,
- nil, nil, -32, nil, nil, 807, 14188, nil, 842, nil,
- 406, nil, 19946, nil, nil, nil, nil, nil, nil, nil,
- 1127, 1113, nil, 2831, nil, 2971, 20073, 20200, nil, nil,
- nil, 20327, 1114, nil, nil, nil, 20467, nil, nil, 72,
- 20594, nil, 1154, 1125, nil, nil, 78, nil, 1249, 1250,
- 20721, 20861, nil, nil, 21001, nil, nil, 1168, nil, 1132,
- nil, nil, 1133, 1134, 1139, 1137, nil, nil, 22721, nil,
- nil, 21128, nil, 21268, 91, 1112, 1221, 97, nil, nil,
- 21408, nil, nil, nil, 460, 21548, 1268, nil, nil, 1081,
- nil, nil, nil, 21688, 1273, 21815, 24855, 24916, 98, 899,
- nil, nil, nil, 1272, nil, 1153, 1275, nil, 1190, 108,
- 120, 198, 202, nil, nil, nil, nil, 218 ]
-
-racc_action_default = [
- -3, -555, -1, -543, -4, -6, -555, -555, -555, -555,
- -555, -555, -555, -555, -277, -37, -38, -555, -555, -43,
- -45, -46, -289, -327, -328, -50, -255, -382, -255, -65,
- -10, -69, -76, -78, -555, -457, -555, -555, -555, -555,
- -555, -545, -232, -270, -271, -272, -273, -274, -275, -276,
- -533, -279, -555, -554, -525, -297, -554, -555, -555, -302,
- -305, -543, -555, -555, -319, -555, -329, -330, -400, -401,
- -402, -403, -404, -554, -407, -554, -554, -554, -554, -554,
- -434, -440, -441, -555, -446, -447, -448, -449, -450, -451,
- -452, -453, -454, -455, -456, -459, -460, -555, -2, -544,
- -550, -551, -552, -555, -555, -555, -555, -555, -3, -13,
- -555, -105, -106, -107, -108, -109, -110, -111, -114, -115,
- -116, -117, -118, -119, -120, -121, -122, -123, -124, -125,
- -126, -127, -128, -129, -130, -131, -132, -133, -134, -135,
- -136, -137, -138, -139, -140, -141, -142, -143, -144, -145,
- -146, -147, -148, -149, -150, -151, -152, -153, -154, -155,
- -156, -157, -158, -159, -160, -161, -162, -163, -164, -165,
- -166, -167, -168, -169, -170, -171, -172, -173, -174, -175,
- -176, -177, -178, -179, -180, -181, -182, -183, -184, -185,
- -186, -187, -555, -18, -112, -10, -555, -555, -555, -554,
- -554, -555, -555, -555, -555, -555, -555, -41, -555, -457,
- -555, -277, -555, -555, -10, -555, -42, -224, -555, -555,
- -555, -555, -555, -555, -555, -555, -555, -555, -555, -555,
- -555, -555, -555, -555, -555, -555, -555, -555, -555, -555,
- -555, -555, -555, -555, -555, -555, -369, -371, -47, -233,
- -248, -262, -262, -252, -555, -263, -555, -289, -327, -328,
- -527, -555, -48, -49, -555, -555, -555, -55, -554, -555,
- -296, -375, -383, -385, -63, -381, -64, -555, -543, -11,
- -65, -10, -555, -555, -70, -73, -10, -457, -555, -555,
- -277, -292, -545, -555, -331, -382, -555, -75, -555, -80,
- -284, -442, -443, -555, -209, -210, -225, -555, -546, -10,
- -545, -234, -545, -547, -547, -555, -555, -547, -555, -298,
- -299, -555, -555, -342, -343, -350, -554, -491, -357, -554,
- -554, -368, -490, -492, -493, -494, -495, -496, -555, -509,
- -514, -515, -517, -518, -519, -555, -44, -555, -555, -555,
- -555, -543, -555, -544, -457, -555, -555, -277, -555, -498,
- -499, -101, -555, -103, -555, -277, -555, -316, -457, -555,
- -105, -106, -143, -144, -160, -165, -172, -175, -322, -555,
- -523, -555, -405, -555, -420, -555, -422, -555, -555, -555,
- -412, -555, -555, -418, -555, -433, -435, -436, -437, -438,
- -444, -445, 968, -5, -553, -19, -20, -21, -22, -23,
- -555, -555, -15, -16, -17, -555, -555, -25, -34, -188,
- -263, -555, -555, -26, -35, -36, -27, -190, -555, -555,
- -534, -535, -554, -378, -536, -537, -534, -255, -535, -380,
- -539, -540, -554, -534, -535, -33, -198, -39, -40, -555,
- -555, -554, -554, -284, -555, -555, -555, -555, -295, -199,
- -200, -201, -202, -203, -204, -205, -206, -211, -212, -213,
- -214, -215, -216, -217, -218, -219, -220, -221, -222, -223,
- -226, -227, -228, -229, -555, -554, -249, -555, -250, -555,
- -260, -555, -264, -530, -255, -255, -255, -554, -56, -545,
- -243, -244, -262, -262, -256, -257, -555, -554, -554, -555,
- -291, -9, -544, -555, -66, -282, -81, -71, -555, -555,
- -554, -555, -555, -554, -555, -284, -555, -442, -443, -77,
- -82, -555, -555, -555, -555, -555, -230, -555, -392, -555,
- -555, -235, -236, -549, -548, -238, -549, -287, -288, -526,
- -339, -10, -10, -555, -341, -555, -359, -366, -555, -363,
- -364, -555, -367, -491, -555, -500, -555, -502, -504, -508,
- -516, -520, -10, -332, -333, -334, -10, -555, -555, -555,
- -555, -10, -387, -554, -555, -555, -554, -284, -311, -101,
- -102, -555, -554, -555, -314, -461, -555, -555, -555, -320,
- -489, -324, -541, -542, -545, -406, -421, -424, -425, -427,
- -408, -423, -409, -410, -411, -555, -414, -416, -417, -555,
- -439, -7, -14, -113, -24, -555, -269, -555, -285, -286,
- -555, -555, -59, -241, -242, -376, -555, -61, -379, -555,
- -57, -377, -534, -535, -534, -535, -555, -555, -188, -294,
- -555, -353, -555, -355, -10, -262, -261, -265, -555, -528,
- -529, -51, -372, -52, -373, -53, -374, -10, -239, -555,
- -245, -247, -43, -555, -254, -258, -555, -10, -10, -290,
- -12, -66, -555, -74, -79, -555, -534, -535, -554, -538,
- -283, -555, -555, -554, -555, -197, -207, -208, -555, -554,
- -554, -280, -281, -547, -555, -555, -340, -351, -555, -358,
- -554, -352, -555, -554, -554, -510, -497, -555, -555, -507,
- -554, -335, -554, -303, -336, -337, -338, -306, -555, -309,
- -555, -555, -555, -534, -535, -538, -283, -555, -555, -101,
- -104, -538, -555, -10, -555, -463, -555, -10, -10, -489,
- -555, -466, -467, -469, -470, -472, -473, -522, -522, -478,
- -480, -480, -480, -488, -491, -512, -555, -555, -555, -10,
- -413, -415, -419, -189, -267, -555, -555, -555, -30, -193,
- -31, -194, -60, -32, -195, -62, -196, -58, -555, -555,
- -555, -286, -285, -231, -354, -555, -555, -251, -266, -555,
- -240, -262, -555, -259, -555, -555, -72, -285, -286, -83,
- -293, -554, -348, -10, -393, -554, -394, -395, -237, -344,
- -345, -365, -555, -284, -555, -361, -362, -501, -503, -506,
- -555, -346, -555, -555, -10, -10, -308, -310, -555, -285,
- -93, -555, -285, -555, -462, -317, -555, -555, -545, -465,
- -468, -471, -555, -476, -477, -555, -555, -484, -555, -486,
- -555, -487, -555, -325, -524, -426, -429, -430, -431, -432,
- -555, -268, -28, -191, -29, -192, -555, -555, -356, -370,
- -54, -246, -262, -384, -386, -8, -10, -399, -349, -555,
- -555, -397, -283, -554, -505, -300, -555, -301, -555, -555,
- -555, -10, -312, -315, -10, -321, -323, -555, -474, -522,
- -521, -479, -480, -480, -480, -555, -513, -511, -489, -428,
- -253, -555, -398, -10, -457, -555, -555, -277, -396, -360,
- -10, -304, -307, -265, -554, -10, -555, -464, -475, -555,
- -482, -483, -485, -10, -392, -554, -555, -555, -284, -554,
- -388, -389, -390, -555, -318, -480, -555, -391, -555, -534,
- -535, -538, -283, -347, -313, -481, -326, -285 ]
-
-racc_goto_table = [
- 13, 315, 307, 699, 323, 378, 498, 114, 114, 539,
- 250, 250, 250, 432, 437, 442, 5, 208, 208, 396,
- 284, 488, 208, 208, 208, 659, 331, 102, 294, 294,
- 13, 288, 288, 572, 576, 529, 10, 98, 12, 557,
- 748, 312, 560, 562, 251, 251, 251, 366, 565, 109,
- 194, 580, 208, 208, 117, 117, 216, 208, 208, 294,
- 294, 208, 355, 364, 99, 114, 10, 715, 12, 418,
- 425, 760, 707, 267, 274, 276, 494, 495, 496, 114,
- 542, 545, 659, 2, 549, 102, 280, 297, 252, 252,
- 252, 606, 763, 723, 727, 352, 759, 616, 359, 13,
- 1, 916, 590, 208, 208, 208, 208, 13, 13, 347,
- 348, 403, 282, 351, 641, 5, 564, 710, 385, 387,
- 317, 714, 394, 409, 5, 885, 830, 248, 262, 263,
- 193, 360, 396, 411, 499, 10, 668, 12, 676, 504,
- 207, 654, 811, 10, 10, 12, 12, 428, 429, 853,
- 854, 380, 316, 667, 319, 405, 406, 407, 408, 320,
- 358, 594, 762, 677, 678, 833, 662, 664, 666, 379,
- 601, 309, 349, 834, 350, 310, 835, 738, 935, 743,
- 346, 346, 916, 598, 346, 904, 369, 312, 312, 747,
- 600, 410, 114, 766, 918, 13, 208, 208, 208, 208,
- 208, 321, 441, 550, 208, 208, 208, 659, 713, 247,
- 485, 656, 507, 656, 13, 208, 508, 950, 422, 422,
- 760, 731, 815, 889, 382, 383, 346, 346, 346, 346,
- 674, 10, 389, 12, 417, 423, 426, 615, 392, 865,
- 768, 763, 445, 769, 848, 759, 909, 908, 912, 828,
- 10, nil, 12, 526, nil, 683, 250, 250, nil, nil,
- nil, 432, 437, nil, nil, 250, nil, nil, 208, 208,
- 553, 540, 488, 541, nil, nil, 565, 208, 728, 719,
- nil, 13, 294, nil, nil, 288, 13, 530, nil, nil,
- 502, 251, 331, nil, nil, 294, nil, nil, 288, 251,
- nil, 938, 102, nil, nil, nil, nil, nil, nil, 13,
- nil, 762, 511, nil, nil, nil, nil, 10, nil, 12,
- nil, nil, 10, 771, 12, nil, 271, 275, 447, 448,
- 14, 740, nil, 688, 503, 252, 693, 280, 457, 512,
- 517, 707, 280, 252, 717, 10, 688, 12, 910, 208,
- 208, 910, 759, 599, 759, 963, 759, 902, 943, nil,
- 14, 290, 290, 513, 715, 641, 294, nil, 519, 364,
- nil, 782, nil, 501, 505, 102, 785, 951, nil, 787,
- nil, 208, 509, nil, nil, 579, 893, nil, nil, 760,
- 595, nil, 357, 365, 656, 656, 688, nil, nil, 646,
- 647, 577, 578, nil, nil, 688, nil, nil, nil, 957,
- 763, 114, nil, nil, 759, 114, nil, 659, 913, 806,
- 914, nil, nil, 821, 797, nil, 825, 826, 565, 14,
- nil, nil, nil, nil, nil, 759, nil, 14, 14, 312,
- 312, nil, nil, 843, nil, nil, nil, 846, 847, nil,
- 441, 208, 208, 622, nil, nil, nil, 623, 117, nil,
- 669, nil, 117, nil, nil, nil, nil, nil, 685, nil,
- 818, 692, 346, 346, nil, nil, nil, nil, nil, 632,
- 762, nil, nil, nil, 637, nil, nil, nil, nil, 640,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 955, nil, nil, 604, nil, 208, 530, 312, nil,
- nil, 312, 13, nil, nil, 294, nil, nil, 288, nil,
- 208, nil, 441, 208, 901, 14, nil, nil, 680, nil,
- nil, 732, nil, nil, 737, 441, nil, 208, nil, 894,
- 742, 661, 663, 665, 14, nil, nil, nil, 10, nil,
- 12, 13, 13, 655, nil, 294, nil, nil, 711, nil,
- nil, nil, nil, nil, nil, 767, nil, nil, nil, nil,
- 797, 312, 13, 816, 312, 923, 13, 857, 859, 861,
- 312, 13, 930, 208, nil, 441, 208, 10, 10, 12,
- 12, 441, 208, 271, 35, 275, 208, nil, 208, nil,
- 795, 724, 724, nil, 936, 656, 929, nil, 10, 703,
- 12, 14, 10, nil, 12, 290, 14, 10, nil, 12,
- nil, 745, 331, nil, 35, 287, 287, nil, 290, 310,
- 208, 208, nil, 952, nil, nil, 208, nil, nil, 14,
- nil, nil, nil, 956, nil, 656, nil, nil, 744, nil,
- nil, 920, nil, nil, 13, nil, 354, 368, nil, 368,
- 698, nil, 283, nil, nil, nil, nil, 13, 778, 780,
- nil, 530, nil, nil, 783, nil, nil, 13, 13, 294,
- nil, nil, 288, 809, nil, nil, nil, nil, nil, nil,
- 10, 294, 12, 35, 288, nil, nil, nil, nil, 365,
- nil, 35, 35, 10, nil, 12, 863, nil, nil, nil,
- nil, nil, nil, 10, 10, 12, 12, nil, nil, 346,
- nil, 746, 422, nil, nil, nil, nil, nil, nil, 940,
- 941, 942, 634, nil, nil, nil, 801, 638, 208, nil,
- nil, nil, 634, 13, nil, nil, nil, 13, 13, nil,
- nil, nil, nil, 838, nil, nil, nil, nil, 688, nil,
- nil, nil, nil, nil, nil, nil, 114, nil, 844, 13,
- 845, nil, 965, nil, 849, nil, 208, 208, nil, 10,
- nil, 12, nil, 10, 10, 12, 12, nil, nil, 35,
- 841, nil, nil, nil, 634, 634, 634, nil, nil, nil,
- nil, nil, nil, nil, nil, 10, nil, 12, 35, 907,
- nil, nil, nil, 13, 872, 874, nil, nil, nil, nil,
- nil, nil, 441, nil, 882, nil, nil, 416, nil, nil,
- nil, nil, 208, 318, 13, 13, nil, nil, nil, nil,
- nil, nil, 14, nil, nil, nil, 283, nil, 290, 10,
- nil, 12, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 346, nil, nil, nil, 724, nil, nil, nil, nil,
- 10, 10, 12, 12, nil, 35, nil, nil, nil, 287,
- 35, 14, 14, nil, 896, nil, 13, 294, 365, nil,
- 925, nil, 287, 958, nil, nil, nil, nil, nil, nil,
- nil, 13, 14, 35, 13, nil, 14, nil, nil, nil,
- nil, 14, nil, 283, nil, nil, nil, nil, 283, nil,
- nil, nil, 10, 13, 12, nil, 928, nil, nil, nil,
- 13, nil, nil, 312, nil, 13, nil, 10, nil, 12,
- 10, nil, 12, 13, nil, 208, nil, 441, nil, nil,
- nil, nil, nil, nil, nil, 346, nil, nil, nil, 10,
- nil, 12, nil, 368, nil, nil, 10, nil, 12, nil,
- nil, 10, nil, 12, nil, 420, 424, nil, nil, 10,
- nil, 12, nil, nil, 14, nil, nil, nil, 634, nil,
- nil, 638, nil, 634, nil, nil, nil, 14, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 14, 14, nil,
- nil, nil, 290, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 290, nil, nil, nil, nil, nil,
- nil, nil, nil, 490, nil, 492, nil, nil, nil, nil,
- 493, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 324, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 14, nil, nil, nil, 14, 14, 384,
- nil, 386, 386, 390, 393, 386, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 869, 14,
- nil, nil, nil, nil, nil, nil, 35, nil, nil, nil,
- nil, nil, 287, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 14, nil, 35, 35, nil, nil, nil,
- nil, nil, 368, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 14, 14, 35, 217, nil, nil,
- 35, 249, 249, 249, nil, 35, nil, nil, nil, nil,
- nil, nil, nil, 704, 705, nil, nil, 304, 305, 306,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 626, nil, 249, 249, 720, nil, nil, nil, 722, nil,
- nil, nil, nil, 730, nil, nil, 14, nil, nil, nil,
- 927, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 14, nil, nil, 14, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 35, nil,
- nil, nil, nil, 14, nil, nil, nil, nil, nil, nil,
- 14, 35, nil, nil, nil, 14, 657, nil, 318, nil,
- 660, 35, 35, 14, 500, nil, 287, nil, nil, nil,
- nil, nil, nil, nil, nil, 673, 796, nil, 287, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 799,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 804,
- 805, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 657, nil, nil, 318, nil, nil, nil, nil,
- nil, nil, 556, nil, nil, 556, 556, 35, nil, nil,
- nil, 35, 35, nil, nil, 419, 249, 427, 249, 249,
- nil, nil, nil, 446, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 35, nil, nil, nil, 217, nil, 459,
- 460, 461, 462, 463, 464, 465, 466, 467, 468, 469,
- 470, 471, 472, 473, 474, 475, 476, 477, 478, 479,
- 480, 481, 482, 483, 484, nil, nil, nil, nil, nil,
- nil, 870, nil, 249, nil, 249, 774, 35, nil, nil,
- 249, nil, nil, nil, nil, nil, nil, 249, 249, nil,
- nil, nil, nil, nil, nil, nil, 249, nil, 35, 35,
- nil, nil, nil, nil, nil, nil, nil, 798, 633, nil,
- nil, nil, nil, nil, nil, 888, nil, nil, 633, 657,
- 318, nil, nil, nil, nil, nil, 536, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 898, 899, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 814,
- 35, nil, nil, nil, 924, nil, nil, nil, nil, nil,
- nil, 651, nil, nil, nil, 35, nil, nil, 35, nil,
- 633, 633, 633, 651, nil, nil, nil, nil, nil, nil,
- 420, nil, nil, 651, 651, nil, nil, 35, 922, nil,
- nil, nil, nil, nil, 35, nil, nil, nil, nil, 35,
- nil, nil, nil, 934, 851, nil, nil, 35, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 871, 944, nil, nil, nil, nil,
- nil, nil, 949, nil, nil, nil, nil, 953, nil, nil,
- 249, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 420, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 249, 249, nil, 446, 648, 427, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 249, nil, 249, nil,
- 249, 917, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 672, nil, nil, nil, nil,
- 318, nil, nil, nil, nil, nil, nil, nil, nil, 249,
- nil, nil, 249, nil, nil, nil, nil, nil, nil, 933,
- 695, 696, 697, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 249, nil, 633, 249, nil, nil, nil, 633,
- 933, nil, nil, nil, nil, 812, 817, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 556, nil, nil, 556,
- 556, nil, nil, nil, nil, nil, 812, nil, 812, nil,
- nil, nil, 249, nil, nil, 249, nil, nil, nil, nil,
- nil, 249, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 773, nil, 249, nil, nil, 779,
- 781, nil, nil, 293, 293, 784, nil, nil, 786, nil,
- 293, 293, 293, nil, nil, nil, nil, nil, nil, 793,
- nil, nil, nil, nil, nil, nil, 293, 249, nil, nil,
- nil, nil, nil, nil, 293, 293, nil, 887, nil, 249,
- 249, 891, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 249,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 249, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 556,
- nil, nil, nil, nil, 249, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 249, 873, 875, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 779, 781, 784,
- 812, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 249, nil, nil, nil, 812, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 293, nil, 293, 293, 293, 293, 293, 293, 293, 293,
- 293, 293, 293, 293, 293, 293, 293, 293, 293, 293,
- 293, 293, 293, 293, 293, 293, 293, 293, nil, nil,
- nil, nil, nil, nil, nil, nil, 293, nil, 293, nil,
- nil, 249, nil, 293, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 875, 873, nil, nil, nil,
- 249, nil, nil, nil, nil, nil, nil, 293, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 249,
- 293, nil, nil, nil, nil, nil, nil, nil, nil, 293,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 249, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 249, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 293, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 293, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 293, 293, 293, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 293,
- nil, 293, nil, 293, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 293, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 293, 293, 293, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 293, nil, nil, 293, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 293, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 293, nil, 293,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 293, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 293, nil, nil, nil, nil, nil, nil, nil,
- 293, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 293, 293, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 293, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 293, nil, nil, nil,
- nil, nil, 293, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 293, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 293, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 293, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 293, 293, 293, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 293, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 293, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 293, 293,
- nil, nil, nil, 293, nil, nil, nil, nil, nil, nil,
- nil, nil, 293, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 293, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 293 ]
-
-racc_goto_check = [
- 21, 22, 51, 10, 104, 47, 35, 48, 48, 8,
- 29, 29, 29, 33, 33, 33, 7, 21, 21, 47,
- 41, 61, 21, 21, 21, 154, 107, 83, 52, 52,
- 21, 21, 21, 77, 77, 43, 17, 4, 20, 109,
- 84, 29, 109, 109, 54, 54, 54, 46, 145, 14,
- 14, 80, 21, 21, 50, 50, 18, 21, 21, 52,
- 52, 21, 21, 21, 6, 48, 17, 147, 20, 24,
- 24, 110, 106, 34, 34, 34, 33, 33, 33, 48,
- 55, 55, 154, 2, 55, 83, 38, 42, 56, 56,
- 56, 129, 141, 79, 79, 4, 108, 129, 17, 21,
- 1, 151, 45, 21, 21, 21, 21, 21, 21, 16,
- 16, 5, 39, 16, 60, 7, 148, 111, 126, 126,
- 56, 111, 126, 7, 7, 12, 78, 31, 31, 31,
- 15, 19, 47, 27, 58, 17, 59, 20, 63, 64,
- 26, 36, 11, 17, 17, 20, 20, 22, 22, 142,
- 142, 72, 73, 36, 74, 16, 16, 16, 16, 76,
- 81, 82, 111, 36, 36, 11, 60, 60, 60, 85,
- 86, 87, 88, 89, 90, 26, 91, 92, 93, 94,
- 26, 26, 151, 95, 26, 96, 97, 29, 29, 98,
- 99, 2, 48, 100, 101, 21, 21, 21, 21, 21,
- 21, 102, 48, 103, 21, 21, 21, 154, 105, 112,
- 113, 62, 115, 62, 21, 21, 116, 117, 54, 54,
- 110, 118, 119, 120, 124, 125, 26, 26, 26, 26,
- 62, 17, 127, 20, 18, 18, 18, 128, 130, 131,
- 132, 141, 18, 133, 135, 108, 137, 139, 144, 149,
- 17, nil, 20, 51, nil, 43, 29, 29, nil, nil,
- nil, 33, 33, nil, nil, 29, nil, nil, 21, 21,
- 104, 51, 61, 51, nil, nil, 145, 21, 80, 145,
- nil, 21, 52, nil, nil, 21, 21, 41, nil, nil,
- 54, 54, 107, nil, nil, 52, nil, nil, 21, 54,
- nil, 142, 83, nil, nil, nil, nil, nil, nil, 21,
- nil, 111, 4, nil, nil, nil, nil, 17, nil, 20,
- nil, nil, 17, 129, 20, nil, 57, 57, 26, 26,
- 23, 45, nil, 33, 56, 56, 33, 38, 26, 6,
- 42, 106, 38, 56, 148, 17, 33, 20, 108, 21,
- 21, 108, 108, 46, 108, 78, 108, 79, 84, nil,
- 23, 23, 23, 39, 147, 60, 52, nil, 39, 21,
- nil, 35, nil, 31, 31, 83, 35, 11, nil, 35,
- nil, 21, 31, nil, nil, 4, 111, nil, nil, 110,
- 83, nil, 23, 23, 62, 62, 33, nil, nil, 22,
- 22, 16, 16, nil, nil, 33, nil, nil, nil, 10,
- 141, 48, nil, nil, 108, 48, nil, 154, 111, 43,
- 111, nil, nil, 109, 61, nil, 109, 109, 145, 23,
- nil, nil, nil, nil, nil, 108, nil, 23, 23, 29,
- 29, nil, nil, 8, nil, nil, nil, 8, 8, nil,
- 48, 21, 21, 14, nil, nil, nil, 14, 50, nil,
- 51, nil, 50, nil, nil, nil, nil, nil, 22, nil,
- 55, 22, 26, 26, nil, nil, nil, nil, nil, 34,
- 111, nil, nil, nil, 34, nil, nil, nil, nil, 34,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 111, nil, nil, 26, nil, 21, 41, 29, nil,
- nil, 29, 21, nil, nil, 52, nil, nil, 21, nil,
- 21, nil, 48, 21, 77, 23, nil, nil, 7, nil,
- nil, 22, nil, nil, 22, 48, nil, 21, nil, 145,
- 22, 34, 34, 34, 23, nil, nil, nil, 17, nil,
- 20, 21, 21, 56, nil, 52, nil, nil, 21, nil,
- nil, nil, nil, nil, nil, 51, nil, nil, nil, nil,
- 61, 29, 21, 24, 29, 77, 21, 143, 143, 143,
- 29, 21, 77, 21, nil, 48, 21, 17, 17, 20,
- 20, 48, 21, 57, 44, 57, 21, nil, 21, nil,
- 104, 83, 83, nil, 8, 62, 109, nil, 17, 56,
- 20, 23, 17, nil, 20, 23, 23, 17, nil, 20,
- nil, 83, 107, nil, 44, 44, 44, nil, 23, 26,
- 21, 21, nil, 80, nil, nil, 21, nil, nil, 23,
- nil, nil, nil, 8, nil, 62, nil, nil, 16, nil,
- nil, 61, nil, nil, 21, nil, 44, 44, nil, 44,
- 26, nil, 9, nil, nil, nil, nil, 21, 18, 18,
- nil, 41, nil, nil, 18, nil, nil, 21, 21, 52,
- nil, nil, 21, 41, nil, nil, nil, nil, nil, nil,
- 17, 52, 20, 44, 21, nil, nil, nil, nil, 23,
- nil, 44, 44, 17, nil, 20, 47, nil, nil, nil,
- nil, nil, nil, 17, 17, 20, 20, nil, nil, 26,
- nil, 26, 54, nil, nil, nil, nil, nil, nil, 143,
- 143, 143, 57, nil, nil, nil, 56, 57, 21, nil,
- nil, nil, 57, 21, nil, nil, nil, 21, 21, nil,
- nil, nil, nil, 54, nil, nil, nil, nil, 33, nil,
- nil, nil, nil, nil, nil, nil, 48, nil, 83, 21,
- 83, nil, 143, nil, 83, nil, 21, 21, nil, 17,
- nil, 20, nil, 17, 17, 20, 20, nil, nil, 44,
- 16, nil, nil, nil, 57, 57, 57, nil, nil, nil,
- nil, nil, nil, nil, nil, 17, nil, 20, 44, 51,
- nil, nil, nil, 21, 18, 18, nil, nil, nil, nil,
- nil, nil, 48, nil, 54, nil, nil, 9, nil, nil,
- nil, nil, 21, 25, 21, 21, nil, nil, nil, nil,
- nil, nil, 23, nil, nil, nil, 9, nil, 23, 17,
- nil, 20, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 26, nil, nil, nil, 83, nil, nil, nil, nil,
- 17, 17, 20, 20, nil, 44, nil, nil, nil, 44,
- 44, 23, 23, nil, 16, nil, 21, 52, 23, nil,
- 21, nil, 44, 22, nil, nil, nil, nil, nil, nil,
- nil, 21, 23, 44, 21, nil, 23, nil, nil, nil,
- nil, 23, nil, 9, nil, nil, nil, nil, 9, nil,
- nil, nil, 17, 21, 20, nil, 17, nil, nil, nil,
- 21, nil, nil, 29, nil, 21, nil, 17, nil, 20,
- 17, nil, 20, 21, nil, 21, nil, 48, nil, nil,
- nil, nil, nil, nil, nil, 26, nil, nil, nil, 17,
- nil, 20, nil, 44, nil, nil, 17, nil, 20, nil,
- nil, 17, nil, 20, nil, 25, 25, nil, nil, 17,
- nil, 20, nil, nil, 23, nil, nil, nil, 57, nil,
- nil, 57, nil, 57, nil, nil, nil, 23, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 23, 23, nil,
- nil, nil, 23, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 23, nil, nil, nil, nil, nil,
- nil, nil, nil, 25, nil, 25, nil, nil, nil, nil,
- 25, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 53, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 23, nil, nil, nil, 23, 23, 53,
- nil, 53, 53, 53, 53, 53, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 23, 23,
- nil, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 23, nil, 44, 44, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 23, 23, 44, 28, nil, nil,
- 44, 28, 28, 28, nil, 44, nil, nil, nil, nil,
- nil, nil, nil, 9, 9, nil, nil, 28, 28, 28,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 25, nil, 28, 28, 9, nil, nil, nil, 9, nil,
- nil, nil, nil, 9, nil, nil, 23, nil, nil, nil,
- 23, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 23, nil, nil, 23, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, 23, nil, nil, nil, nil, nil, nil,
- 23, 44, nil, nil, nil, 23, 25, nil, 25, nil,
- 25, 44, 44, 23, 53, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 25, 9, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 9,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 9,
- 9, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 25, nil, nil, 25, nil, nil, nil, nil,
- nil, nil, 53, nil, nil, 53, 53, 44, nil, nil,
- nil, 44, 44, nil, nil, 28, 28, 28, 28, 28,
- nil, nil, nil, 28, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 44, nil, nil, nil, 28, nil, 28,
- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, nil, nil, nil, nil, nil,
- nil, 9, nil, 28, nil, 28, 25, 44, nil, nil,
- 28, nil, nil, nil, nil, nil, nil, 28, 28, nil,
- nil, nil, nil, nil, nil, nil, 28, nil, 44, 44,
- nil, nil, nil, nil, nil, nil, nil, 25, 53, nil,
- nil, nil, nil, nil, nil, 9, nil, nil, 53, 25,
- 25, nil, nil, nil, nil, nil, 28, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 9, 9, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 25,
- 44, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, 53, nil, nil, nil, 44, nil, nil, 44, nil,
- 53, 53, 53, 53, nil, nil, nil, nil, nil, nil,
- 25, nil, nil, 53, 53, nil, nil, 44, 9, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, 44,
- nil, nil, nil, 9, 25, nil, nil, 44, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 25, 9, nil, nil, nil, nil,
- nil, nil, 9, nil, nil, nil, nil, 9, nil, nil,
- 28, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 25, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 28, 28, nil, 28, 28, 28, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 28, nil, 28, nil,
- 28, 25, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 28, nil, nil, nil, nil,
- 25, nil, nil, nil, nil, nil, nil, nil, nil, 28,
- nil, nil, 28, nil, nil, nil, nil, nil, nil, 25,
- 28, 28, 28, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 28, nil, 53, 28, nil, nil, nil, 53,
- 25, nil, nil, nil, nil, 53, 53, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 53, nil, nil, 53,
- 53, nil, nil, nil, nil, nil, 53, nil, 53, nil,
- nil, nil, 28, nil, nil, 28, nil, nil, nil, nil,
- nil, 28, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 28, nil, 28, nil, nil, 28,
- 28, nil, nil, 37, 37, 28, nil, nil, 28, nil,
- 37, 37, 37, nil, nil, nil, nil, nil, nil, 28,
- nil, nil, nil, nil, nil, nil, 37, 28, nil, nil,
- nil, nil, nil, nil, 37, 37, nil, 53, nil, 28,
- 28, 53, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 28,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 28, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 53,
- nil, nil, nil, nil, 28, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 28, 28, 28, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 28, 28, 28,
- 53, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 28, nil, nil, nil, 53, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 37, nil, 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
- 37, 37, 37, 37, 37, 37, 37, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, 37, nil, 37, nil,
- nil, 28, nil, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 28, 28, nil, nil, nil,
- 28, nil, nil, nil, nil, nil, nil, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 28,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 28, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 28, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 37, 37, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 37,
- nil, 37, nil, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 37, 37, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 37, nil, nil, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 37, nil, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 37, nil, nil, nil, nil, nil, nil, nil,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 37, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 37, nil, nil, nil,
- nil, nil, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 37, 37, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 37, 37,
- nil, nil, nil, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 37 ]
-
-racc_goto_pointer = [
- nil, 100, 83, nil, 34, 12, 61, 16, -300, 632,
- -535, -557, -686, nil, 42, 122, 52, 36, 38, 69,
- 38, 0, -52, 330, -127, 779, 123, 24, 1149, -12,
- nil, 105, nil, -188, 47, -261, -344, 1752, 56, 82,
- nil, -11, 55, -263, 594, -260, -16, -60, 0, nil,
- 47, -39, -3, 1006, 22, -233, 66, 300, -134, -363,
- -328, -231, -276, -368, -130, nil, nil, nil, nil, nil,
- nil, nil, 86, 98, 99, nil, 103, -314, -594, -484,
- -301, 98, -205, 24, -560, 104, -209, 120, 113, -550,
- 114, -551, -411, -724, -415, -184, -660, 122, -410, -188,
- -408, -669, 145, -118, -52, -351, -483, -30, -504, -287,
- -529, -438, 189, -36, nil, -60, -57, -717, -361, -478,
- -592, nil, nil, nil, 153, 152, 43, 155, -152, -292,
- 160, -529, -368, -366, nil, -505, nil, -606, nil, -605,
- nil, -508, -608, -183, -608, -290, nil, -492, -222, -469,
- nil, -757, nil, nil, -464 ]
-
-racc_goto_default = [
- nil, nil, nil, 3, nil, 4, 353, 279, nil, 538,
- nil, 831, nil, 278, nil, nil, nil, 212, 16, 11,
- 213, 303, nil, 211, nil, 255, 15, nil, 19, 20,
- 21, nil, 25, 691, nil, nil, nil, 26, 29, nil,
- 31, 34, 33, nil, 209, 363, nil, 116, 435, 115,
- 69, nil, 42, 311, 313, nil, 314, 433, nil, nil,
- 635, 486, 253, nil, nil, 269, 43, 44, 45, 46,
- 47, 48, 49, nil, 270, 55, nil, nil, nil, nil,
- nil, nil, nil, 573, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 326, 325, 709, 328, nil,
- 329, 330, nil, nil, 439, nil, nil, nil, nil, nil,
- nil, 68, 70, 71, 72, nil, nil, nil, nil, 611,
- nil, nil, nil, nil, 395, 750, 753, 758, 755, 756,
- 757, 911, nil, nil, 761, 337, 332, 339, nil, 567,
- 568, 765, 342, 345, 260 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 143, :_reduce_none,
- 2, 144, :_reduce_2,
- 0, 145, :_reduce_3,
- 1, 145, :_reduce_4,
- 3, 145, :_reduce_5,
- 1, 147, :_reduce_none,
- 4, 147, :_reduce_7,
- 4, 150, :_reduce_8,
- 2, 151, :_reduce_9,
- 0, 155, :_reduce_10,
- 1, 155, :_reduce_11,
- 3, 155, :_reduce_12,
- 0, 169, :_reduce_13,
- 4, 149, :_reduce_14,
- 3, 149, :_reduce_15,
- 3, 149, :_reduce_none,
- 3, 149, :_reduce_17,
- 2, 149, :_reduce_18,
- 3, 149, :_reduce_19,
- 3, 149, :_reduce_20,
- 3, 149, :_reduce_21,
- 3, 149, :_reduce_22,
- 3, 149, :_reduce_23,
- 4, 149, :_reduce_none,
- 3, 149, :_reduce_25,
- 3, 149, :_reduce_26,
- 3, 149, :_reduce_27,
- 6, 149, :_reduce_none,
- 6, 149, :_reduce_none,
- 5, 149, :_reduce_30,
- 5, 149, :_reduce_none,
- 5, 149, :_reduce_none,
- 3, 149, :_reduce_none,
- 3, 149, :_reduce_34,
- 3, 149, :_reduce_35,
- 3, 149, :_reduce_36,
- 1, 149, :_reduce_none,
- 1, 168, :_reduce_none,
- 3, 168, :_reduce_39,
- 3, 168, :_reduce_40,
- 2, 168, :_reduce_41,
- 2, 168, :_reduce_42,
- 1, 168, :_reduce_none,
- 1, 158, :_reduce_none,
- 1, 160, :_reduce_none,
- 1, 160, :_reduce_none,
- 2, 160, :_reduce_47,
- 2, 160, :_reduce_48,
- 2, 160, :_reduce_49,
- 1, 172, :_reduce_none,
- 4, 172, :_reduce_none,
- 4, 172, :_reduce_none,
- 4, 172, :_reduce_none,
- 4, 177, :_reduce_none,
- 2, 171, :_reduce_55,
- 3, 171, :_reduce_none,
- 4, 171, :_reduce_57,
- 5, 171, :_reduce_none,
- 4, 171, :_reduce_59,
- 5, 171, :_reduce_none,
- 4, 171, :_reduce_61,
- 5, 171, :_reduce_none,
- 2, 171, :_reduce_63,
- 2, 171, :_reduce_64,
- 1, 161, :_reduce_65,
- 3, 161, :_reduce_66,
- 1, 181, :_reduce_67,
- 3, 181, :_reduce_68,
- 1, 180, :_reduce_69,
- 2, 180, :_reduce_70,
- 3, 180, :_reduce_71,
- 5, 180, :_reduce_none,
- 2, 180, :_reduce_73,
- 4, 180, :_reduce_none,
- 2, 180, :_reduce_75,
- 1, 180, :_reduce_76,
- 3, 180, :_reduce_none,
- 1, 183, :_reduce_78,
- 3, 183, :_reduce_79,
- 2, 182, :_reduce_80,
- 3, 182, :_reduce_81,
- 1, 185, :_reduce_none,
- 3, 185, :_reduce_none,
- 1, 184, :_reduce_84,
- 4, 184, :_reduce_85,
- 3, 184, :_reduce_86,
- 3, 184, :_reduce_none,
- 3, 184, :_reduce_none,
- 3, 184, :_reduce_none,
- 2, 184, :_reduce_none,
- 1, 184, :_reduce_none,
- 1, 159, :_reduce_92,
- 4, 159, :_reduce_93,
- 4, 159, :_reduce_94,
- 3, 159, :_reduce_95,
- 3, 159, :_reduce_96,
- 3, 159, :_reduce_97,
- 3, 159, :_reduce_98,
- 2, 159, :_reduce_99,
- 1, 159, :_reduce_none,
- 1, 187, :_reduce_none,
- 2, 188, :_reduce_102,
- 1, 188, :_reduce_103,
- 3, 188, :_reduce_104,
- 1, 189, :_reduce_none,
- 1, 189, :_reduce_none,
- 1, 189, :_reduce_none,
- 1, 189, :_reduce_108,
- 1, 189, :_reduce_109,
- 1, 156, :_reduce_110,
- 1, 156, :_reduce_none,
- 1, 157, :_reduce_112,
- 3, 157, :_reduce_113,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 190, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 1, 191, :_reduce_none,
- 3, 170, :_reduce_188,
- 5, 170, :_reduce_189,
- 3, 170, :_reduce_190,
- 6, 170, :_reduce_191,
- 6, 170, :_reduce_192,
- 5, 170, :_reduce_193,
- 5, 170, :_reduce_none,
- 5, 170, :_reduce_none,
- 5, 170, :_reduce_none,
- 4, 170, :_reduce_none,
- 3, 170, :_reduce_none,
- 3, 170, :_reduce_199,
- 3, 170, :_reduce_200,
- 3, 170, :_reduce_201,
- 3, 170, :_reduce_202,
- 3, 170, :_reduce_203,
- 3, 170, :_reduce_204,
- 3, 170, :_reduce_205,
- 3, 170, :_reduce_206,
- 4, 170, :_reduce_207,
- 4, 170, :_reduce_208,
- 2, 170, :_reduce_209,
- 2, 170, :_reduce_210,
- 3, 170, :_reduce_211,
- 3, 170, :_reduce_212,
- 3, 170, :_reduce_213,
- 3, 170, :_reduce_214,
- 3, 170, :_reduce_215,
- 3, 170, :_reduce_216,
- 3, 170, :_reduce_217,
- 3, 170, :_reduce_218,
- 3, 170, :_reduce_219,
- 3, 170, :_reduce_220,
- 3, 170, :_reduce_221,
- 3, 170, :_reduce_222,
- 3, 170, :_reduce_223,
- 2, 170, :_reduce_224,
- 2, 170, :_reduce_225,
- 3, 170, :_reduce_226,
- 3, 170, :_reduce_227,
- 3, 170, :_reduce_228,
- 3, 170, :_reduce_229,
- 3, 170, :_reduce_230,
- 5, 170, :_reduce_231,
- 1, 170, :_reduce_none,
- 1, 167, :_reduce_none,
- 1, 164, :_reduce_234,
- 2, 164, :_reduce_235,
- 2, 164, :_reduce_236,
- 4, 164, :_reduce_237,
- 2, 164, :_reduce_238,
- 3, 199, :_reduce_239,
- 2, 201, :_reduce_none,
- 1, 202, :_reduce_241,
- 1, 202, :_reduce_none,
- 1, 200, :_reduce_243,
- 1, 200, :_reduce_none,
- 2, 200, :_reduce_245,
- 4, 200, :_reduce_246,
- 2, 200, :_reduce_247,
- 1, 173, :_reduce_248,
- 2, 173, :_reduce_249,
- 2, 173, :_reduce_250,
- 4, 173, :_reduce_251,
- 1, 173, :_reduce_252,
- 4, 205, :_reduce_none,
- 1, 205, :_reduce_none,
- 0, 207, :_reduce_255,
- 2, 176, :_reduce_256,
- 1, 206, :_reduce_none,
- 2, 206, :_reduce_258,
- 3, 206, :_reduce_259,
- 2, 204, :_reduce_260,
- 2, 203, :_reduce_261,
- 0, 203, :_reduce_262,
- 1, 196, :_reduce_263,
- 2, 196, :_reduce_264,
- 3, 196, :_reduce_265,
- 4, 196, :_reduce_266,
- 3, 166, :_reduce_267,
- 4, 166, :_reduce_268,
- 2, 166, :_reduce_269,
- 1, 194, :_reduce_none,
- 1, 194, :_reduce_none,
- 1, 194, :_reduce_none,
- 1, 194, :_reduce_none,
- 1, 194, :_reduce_none,
- 1, 194, :_reduce_none,
- 1, 194, :_reduce_none,
- 1, 194, :_reduce_none,
- 1, 194, :_reduce_none,
- 0, 229, :_reduce_279,
- 4, 194, :_reduce_280,
- 4, 194, :_reduce_281,
- 3, 194, :_reduce_282,
- 3, 194, :_reduce_283,
- 2, 194, :_reduce_284,
- 4, 194, :_reduce_285,
- 4, 194, :_reduce_286,
- 3, 194, :_reduce_287,
- 3, 194, :_reduce_288,
- 1, 194, :_reduce_289,
- 4, 194, :_reduce_290,
- 3, 194, :_reduce_291,
- 1, 194, :_reduce_292,
- 5, 194, :_reduce_293,
- 4, 194, :_reduce_294,
- 3, 194, :_reduce_295,
- 2, 194, :_reduce_296,
- 1, 194, :_reduce_none,
- 2, 194, :_reduce_298,
- 2, 194, :_reduce_299,
- 6, 194, :_reduce_300,
- 6, 194, :_reduce_301,
- 0, 230, :_reduce_302,
- 0, 231, :_reduce_303,
- 7, 194, :_reduce_304,
- 0, 232, :_reduce_305,
- 0, 233, :_reduce_306,
- 7, 194, :_reduce_307,
- 5, 194, :_reduce_308,
- 4, 194, :_reduce_309,
- 5, 194, :_reduce_310,
- 0, 234, :_reduce_311,
- 0, 235, :_reduce_312,
- 9, 194, :_reduce_313,
- 0, 236, :_reduce_314,
- 6, 194, :_reduce_315,
- 0, 237, :_reduce_316,
- 0, 238, :_reduce_317,
- 8, 194, :_reduce_318,
- 0, 239, :_reduce_319,
- 0, 240, :_reduce_320,
- 6, 194, :_reduce_321,
- 0, 241, :_reduce_322,
- 6, 194, :_reduce_323,
- 0, 242, :_reduce_324,
- 0, 243, :_reduce_325,
- 9, 194, :_reduce_326,
- 1, 194, :_reduce_327,
- 1, 194, :_reduce_328,
- 1, 194, :_reduce_329,
- 1, 194, :_reduce_none,
- 1, 163, :_reduce_none,
- 1, 219, :_reduce_none,
- 1, 219, :_reduce_none,
- 1, 219, :_reduce_none,
- 2, 219, :_reduce_none,
- 1, 221, :_reduce_none,
- 1, 221, :_reduce_none,
- 1, 221, :_reduce_none,
- 2, 218, :_reduce_339,
- 3, 244, :_reduce_340,
- 2, 244, :_reduce_341,
- 1, 244, :_reduce_none,
- 1, 244, :_reduce_none,
- 3, 245, :_reduce_344,
- 3, 245, :_reduce_345,
- 1, 220, :_reduce_346,
- 5, 220, :_reduce_347,
- 1, 153, :_reduce_none,
- 2, 153, :_reduce_349,
- 1, 247, :_reduce_350,
- 3, 247, :_reduce_351,
- 3, 248, :_reduce_352,
- 1, 178, :_reduce_none,
- 2, 178, :_reduce_354,
- 1, 178, :_reduce_355,
- 3, 178, :_reduce_356,
- 1, 249, :_reduce_357,
- 2, 251, :_reduce_358,
- 1, 251, :_reduce_359,
- 6, 246, :_reduce_360,
- 4, 246, :_reduce_361,
- 4, 246, :_reduce_362,
- 2, 246, :_reduce_363,
- 2, 246, :_reduce_364,
- 4, 246, :_reduce_365,
- 2, 246, :_reduce_366,
- 2, 246, :_reduce_367,
- 1, 246, :_reduce_368,
- 0, 255, :_reduce_369,
- 5, 254, :_reduce_370,
- 2, 174, :_reduce_371,
- 4, 174, :_reduce_none,
- 4, 174, :_reduce_none,
- 4, 174, :_reduce_none,
- 2, 217, :_reduce_375,
- 4, 217, :_reduce_376,
- 4, 217, :_reduce_377,
- 3, 217, :_reduce_378,
- 4, 217, :_reduce_379,
- 3, 217, :_reduce_380,
- 2, 217, :_reduce_381,
- 1, 217, :_reduce_382,
- 0, 257, :_reduce_383,
- 5, 216, :_reduce_384,
- 0, 258, :_reduce_385,
- 5, 216, :_reduce_386,
- 0, 260, :_reduce_387,
- 6, 222, :_reduce_388,
- 1, 259, :_reduce_389,
- 1, 259, :_reduce_none,
- 6, 152, :_reduce_391,
- 0, 152, :_reduce_392,
- 1, 261, :_reduce_393,
- 1, 261, :_reduce_none,
- 1, 261, :_reduce_none,
- 2, 262, :_reduce_396,
- 1, 262, :_reduce_397,
- 2, 154, :_reduce_398,
- 1, 154, :_reduce_none,
- 1, 208, :_reduce_none,
- 1, 208, :_reduce_none,
- 1, 208, :_reduce_none,
- 1, 209, :_reduce_403,
- 1, 265, :_reduce_none,
- 2, 265, :_reduce_405,
- 3, 266, :_reduce_406,
- 1, 266, :_reduce_407,
- 3, 210, :_reduce_408,
- 3, 211, :_reduce_409,
- 3, 212, :_reduce_410,
- 3, 212, :_reduce_411,
- 1, 269, :_reduce_412,
- 3, 269, :_reduce_413,
- 1, 270, :_reduce_414,
- 2, 270, :_reduce_415,
- 3, 213, :_reduce_416,
- 3, 213, :_reduce_417,
- 1, 272, :_reduce_418,
- 3, 272, :_reduce_419,
- 1, 267, :_reduce_420,
- 2, 267, :_reduce_421,
- 1, 268, :_reduce_422,
- 2, 268, :_reduce_423,
- 1, 271, :_reduce_424,
- 0, 274, :_reduce_425,
- 3, 271, :_reduce_426,
- 0, 275, :_reduce_427,
- 4, 271, :_reduce_428,
- 1, 273, :_reduce_429,
- 1, 273, :_reduce_430,
- 1, 273, :_reduce_431,
- 1, 273, :_reduce_none,
- 2, 192, :_reduce_433,
- 1, 192, :_reduce_434,
- 1, 276, :_reduce_none,
- 1, 276, :_reduce_none,
- 1, 276, :_reduce_none,
- 1, 276, :_reduce_none,
- 3, 264, :_reduce_439,
- 1, 263, :_reduce_440,
- 1, 263, :_reduce_441,
- 2, 263, :_reduce_442,
- 2, 263, :_reduce_443,
- 2, 263, :_reduce_444,
- 2, 263, :_reduce_445,
- 1, 186, :_reduce_446,
- 1, 186, :_reduce_447,
- 1, 186, :_reduce_448,
- 1, 186, :_reduce_449,
- 1, 186, :_reduce_450,
- 1, 186, :_reduce_451,
- 1, 186, :_reduce_452,
- 1, 186, :_reduce_453,
- 1, 186, :_reduce_454,
- 1, 186, :_reduce_455,
- 1, 186, :_reduce_456,
- 1, 214, :_reduce_457,
- 1, 162, :_reduce_458,
- 1, 165, :_reduce_459,
- 1, 165, :_reduce_none,
- 1, 224, :_reduce_461,
- 3, 224, :_reduce_462,
- 2, 224, :_reduce_463,
- 4, 226, :_reduce_464,
- 2, 226, :_reduce_465,
- 1, 278, :_reduce_none,
- 1, 278, :_reduce_none,
- 2, 279, :_reduce_468,
- 1, 279, :_reduce_469,
- 1, 280, :_reduce_470,
- 2, 281, :_reduce_471,
- 1, 281, :_reduce_472,
- 1, 282, :_reduce_473,
- 3, 282, :_reduce_474,
- 4, 283, :_reduce_475,
- 2, 283, :_reduce_476,
- 2, 283, :_reduce_477,
- 1, 283, :_reduce_478,
- 2, 285, :_reduce_479,
- 0, 285, :_reduce_480,
- 6, 277, :_reduce_481,
- 4, 277, :_reduce_482,
- 4, 277, :_reduce_483,
- 2, 277, :_reduce_484,
- 4, 277, :_reduce_485,
- 2, 277, :_reduce_486,
- 2, 277, :_reduce_487,
- 1, 277, :_reduce_488,
- 0, 277, :_reduce_489,
- 1, 287, :_reduce_none,
- 1, 287, :_reduce_491,
- 1, 288, :_reduce_492,
- 1, 288, :_reduce_493,
- 1, 288, :_reduce_494,
- 1, 288, :_reduce_495,
- 1, 289, :_reduce_496,
- 3, 289, :_reduce_497,
- 1, 223, :_reduce_none,
- 1, 223, :_reduce_none,
- 1, 291, :_reduce_500,
- 3, 291, :_reduce_none,
- 1, 292, :_reduce_502,
- 3, 292, :_reduce_503,
- 1, 290, :_reduce_none,
- 4, 290, :_reduce_none,
- 3, 290, :_reduce_none,
- 2, 290, :_reduce_none,
- 1, 290, :_reduce_none,
- 1, 252, :_reduce_509,
- 3, 252, :_reduce_510,
- 3, 293, :_reduce_511,
- 1, 286, :_reduce_512,
- 3, 286, :_reduce_513,
- 1, 294, :_reduce_none,
- 1, 294, :_reduce_none,
- 2, 253, :_reduce_516,
- 1, 253, :_reduce_517,
- 1, 295, :_reduce_none,
- 1, 295, :_reduce_none,
- 2, 250, :_reduce_520,
- 2, 284, :_reduce_521,
- 0, 284, :_reduce_522,
- 1, 227, :_reduce_523,
- 4, 227, :_reduce_524,
- 0, 215, :_reduce_525,
- 2, 215, :_reduce_526,
- 1, 198, :_reduce_527,
- 3, 198, :_reduce_528,
- 3, 296, :_reduce_529,
- 2, 296, :_reduce_530,
- 1, 179, :_reduce_none,
- 1, 179, :_reduce_none,
- 1, 179, :_reduce_none,
- 1, 175, :_reduce_none,
- 1, 175, :_reduce_none,
- 1, 175, :_reduce_none,
- 1, 175, :_reduce_none,
- 1, 256, :_reduce_none,
- 1, 256, :_reduce_none,
- 1, 256, :_reduce_none,
- 1, 228, :_reduce_none,
- 1, 228, :_reduce_none,
- 0, 146, :_reduce_none,
- 1, 146, :_reduce_none,
- 0, 193, :_reduce_none,
- 1, 193, :_reduce_none,
- 0, 197, :_reduce_none,
- 1, 197, :_reduce_none,
- 1, 197, :_reduce_none,
- 1, 225, :_reduce_none,
- 1, 225, :_reduce_none,
- 1, 148, :_reduce_none,
- 2, 148, :_reduce_none,
- 0, 195, :_reduce_554 ]
-
-racc_reduce_n = 555
-
-racc_shift_n = 968
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :kCLASS => 2,
- :kMODULE => 3,
- :kDEF => 4,
- :kUNDEF => 5,
- :kBEGIN => 6,
- :kRESCUE => 7,
- :kENSURE => 8,
- :kEND => 9,
- :kIF => 10,
- :kUNLESS => 11,
- :kTHEN => 12,
- :kELSIF => 13,
- :kELSE => 14,
- :kCASE => 15,
- :kWHEN => 16,
- :kWHILE => 17,
- :kUNTIL => 18,
- :kFOR => 19,
- :kBREAK => 20,
- :kNEXT => 21,
- :kREDO => 22,
- :kRETRY => 23,
- :kIN => 24,
- :kDO => 25,
- :kDO_COND => 26,
- :kDO_BLOCK => 27,
- :kDO_LAMBDA => 28,
- :kRETURN => 29,
- :kYIELD => 30,
- :kSUPER => 31,
- :kSELF => 32,
- :kNIL => 33,
- :kTRUE => 34,
- :kFALSE => 35,
- :kAND => 36,
- :kOR => 37,
- :kNOT => 38,
- :kIF_MOD => 39,
- :kUNLESS_MOD => 40,
- :kWHILE_MOD => 41,
- :kUNTIL_MOD => 42,
- :kRESCUE_MOD => 43,
- :kALIAS => 44,
- :kDEFINED => 45,
- :klBEGIN => 46,
- :klEND => 47,
- :k__LINE__ => 48,
- :k__FILE__ => 49,
- :k__ENCODING__ => 50,
- :tIDENTIFIER => 51,
- :tFID => 52,
- :tGVAR => 53,
- :tIVAR => 54,
- :tCONSTANT => 55,
- :tLABEL => 56,
- :tCVAR => 57,
- :tNTH_REF => 58,
- :tBACK_REF => 59,
- :tSTRING_CONTENT => 60,
- :tINTEGER => 61,
- :tFLOAT => 62,
- :tREGEXP_END => 63,
- :tUPLUS => 64,
- :tUMINUS => 65,
- :tUMINUS_NUM => 66,
- :tPOW => 67,
- :tCMP => 68,
- :tEQ => 69,
- :tEQQ => 70,
- :tNEQ => 71,
- :tGEQ => 72,
- :tLEQ => 73,
- :tANDOP => 74,
- :tOROP => 75,
- :tMATCH => 76,
- :tNMATCH => 77,
- :tJSDOT => 78,
- :tDOT => 79,
- :tDOT2 => 80,
- :tDOT3 => 81,
- :tAREF => 82,
- :tASET => 83,
- :tLSHFT => 84,
- :tRSHFT => 85,
- :tCOLON2 => 86,
- :tCOLON3 => 87,
- :tOP_ASGN => 88,
- :tASSOC => 89,
- :tLPAREN => 90,
- :tLPAREN2 => 91,
- :tRPAREN => 92,
- :tLPAREN_ARG => 93,
- :ARRAY_BEG => 94,
- :tRBRACK => 95,
- :tLBRACE => 96,
- :tLBRACE_ARG => 97,
- :tSTAR => 98,
- :tSTAR2 => 99,
- :tAMPER => 100,
- :tAMPER2 => 101,
- :tTILDE => 102,
- :tPERCENT => 103,
- :tDIVIDE => 104,
- :tPLUS => 105,
- :tMINUS => 106,
- :tLT => 107,
- :tGT => 108,
- :tPIPE => 109,
- :tBANG => 110,
- :tCARET => 111,
- :tLCURLY => 112,
- :tRCURLY => 113,
- :tBACK_REF2 => 114,
- :tSYMBEG => 115,
- :tSTRING_BEG => 116,
- :tXSTRING_BEG => 117,
- :tREGEXP_BEG => 118,
- :tWORDS_BEG => 119,
- :tAWORDS_BEG => 120,
- :tSTRING_DBEG => 121,
- :tSTRING_DVAR => 122,
- :tSTRING_END => 123,
- :tSTRING => 124,
- :tSYMBOL => 125,
- :tNL => 126,
- :tEH => 127,
- :tCOLON => 128,
- :tCOMMA => 129,
- :tSPACE => 130,
- :tSEMI => 131,
- :tLAMBDA => 132,
- :tLAMBEG => 133,
- :tLBRACK2 => 134,
- :tLBRACK => 135,
- :tJSLBRACK => 136,
- :tDSTAR => 137,
- :tEQL => 138,
- :tLOWEST => 139,
- "-@NUM" => 140,
- "+@NUM" => 141 }
-
-racc_nt_base = 142
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "kCLASS",
- "kMODULE",
- "kDEF",
- "kUNDEF",
- "kBEGIN",
- "kRESCUE",
- "kENSURE",
- "kEND",
- "kIF",
- "kUNLESS",
- "kTHEN",
- "kELSIF",
- "kELSE",
- "kCASE",
- "kWHEN",
- "kWHILE",
- "kUNTIL",
- "kFOR",
- "kBREAK",
- "kNEXT",
- "kREDO",
- "kRETRY",
- "kIN",
- "kDO",
- "kDO_COND",
- "kDO_BLOCK",
- "kDO_LAMBDA",
- "kRETURN",
- "kYIELD",
- "kSUPER",
- "kSELF",
- "kNIL",
- "kTRUE",
- "kFALSE",
- "kAND",
- "kOR",
- "kNOT",
- "kIF_MOD",
- "kUNLESS_MOD",
- "kWHILE_MOD",
- "kUNTIL_MOD",
- "kRESCUE_MOD",
- "kALIAS",
- "kDEFINED",
- "klBEGIN",
- "klEND",
- "k__LINE__",
- "k__FILE__",
- "k__ENCODING__",
- "tIDENTIFIER",
- "tFID",
- "tGVAR",
- "tIVAR",
- "tCONSTANT",
- "tLABEL",
- "tCVAR",
- "tNTH_REF",
- "tBACK_REF",
- "tSTRING_CONTENT",
- "tINTEGER",
- "tFLOAT",
- "tREGEXP_END",
- "tUPLUS",
- "tUMINUS",
- "tUMINUS_NUM",
- "tPOW",
- "tCMP",
- "tEQ",
- "tEQQ",
- "tNEQ",
- "tGEQ",
- "tLEQ",
- "tANDOP",
- "tOROP",
- "tMATCH",
- "tNMATCH",
- "tJSDOT",
- "tDOT",
- "tDOT2",
- "tDOT3",
- "tAREF",
- "tASET",
- "tLSHFT",
- "tRSHFT",
- "tCOLON2",
- "tCOLON3",
- "tOP_ASGN",
- "tASSOC",
- "tLPAREN",
- "tLPAREN2",
- "tRPAREN",
- "tLPAREN_ARG",
- "ARRAY_BEG",
- "tRBRACK",
- "tLBRACE",
- "tLBRACE_ARG",
- "tSTAR",
- "tSTAR2",
- "tAMPER",
- "tAMPER2",
- "tTILDE",
- "tPERCENT",
- "tDIVIDE",
- "tPLUS",
- "tMINUS",
- "tLT",
- "tGT",
- "tPIPE",
- "tBANG",
- "tCARET",
- "tLCURLY",
- "tRCURLY",
- "tBACK_REF2",
- "tSYMBEG",
- "tSTRING_BEG",
- "tXSTRING_BEG",
- "tREGEXP_BEG",
- "tWORDS_BEG",
- "tAWORDS_BEG",
- "tSTRING_DBEG",
- "tSTRING_DVAR",
- "tSTRING_END",
- "tSTRING",
- "tSYMBOL",
- "tNL",
- "tEH",
- "tCOLON",
- "tCOMMA",
- "tSPACE",
- "tSEMI",
- "tLAMBDA",
- "tLAMBEG",
- "tLBRACK2",
- "tLBRACK",
- "tJSLBRACK",
- "tDSTAR",
- "tEQL",
- "tLOWEST",
- "\"-@NUM\"",
- "\"+@NUM\"",
- "$start",
- "program",
- "top_compstmt",
- "top_stmts",
- "opt_terms",
- "top_stmt",
- "terms",
- "stmt",
- "bodystmt",
- "compstmt",
- "opt_rescue",
- "opt_else",
- "opt_ensure",
- "stmts",
- "fitem",
- "undef_list",
- "expr_value",
- "lhs",
- "command_call",
- "mlhs",
- "var_lhs",
- "primary_value",
- "aref_args",
- "backref",
- "mrhs",
- "arg_value",
- "expr",
- "@1",
- "arg",
- "command",
- "block_command",
- "call_args",
- "block_call",
- "operation2",
- "command_args",
- "cmd_brace_block",
- "opt_block_var",
- "operation",
- "mlhs_basic",
- "mlhs_entry",
- "mlhs_head",
- "mlhs_item",
- "mlhs_node",
- "mlhs_post",
- "variable",
- "cname",
- "cpath",
- "fname",
- "op",
- "reswords",
- "symbol",
- "opt_nl",
- "primary",
- "none",
- "args",
- "trailer",
- "assocs",
- "paren_args",
- "opt_call_args",
- "rparen",
- "opt_paren_args",
- "opt_block_arg",
- "block_arg",
- "call_args2",
- "open_args",
- "@2",
- "literal",
- "strings",
- "xstring",
- "regexp",
- "words",
- "awords",
- "var_ref",
- "assoc_list",
- "brace_block",
- "method_call",
- "lambda",
- "then",
- "if_tail",
- "do",
- "case_body",
- "for_var",
- "superclass",
- "term",
- "f_arglist",
- "singleton",
- "dot_or_colon",
- "@3",
- "@4",
- "@5",
- "@6",
- "@7",
- "@8",
- "@9",
- "@10",
- "@11",
- "@12",
- "@13",
- "@14",
- "@15",
- "@16",
- "@17",
- "f_larglist",
- "lambda_body",
- "block_param",
- "f_block_optarg",
- "f_block_opt",
- "block_args_tail",
- "f_block_arg",
- "opt_block_args_tail",
- "f_arg",
- "f_rest_arg",
- "do_block",
- "@18",
- "operation3",
- "@19",
- "@20",
- "cases",
- "@21",
- "exc_list",
- "exc_var",
- "numeric",
- "dsym",
- "string",
- "string1",
- "string_contents",
- "xstring_contents",
- "word_list",
- "word",
- "string_content",
- "qword_list",
- "string_dvar",
- "@22",
- "@23",
- "sym",
- "f_args",
- "kwrest_mark",
- "f_kwrest",
- "f_label",
- "f_kw",
- "f_kwarg",
- "args_tail",
- "opt_f_block_arg",
- "opt_args_tail",
- "f_optarg",
- "f_norm_arg",
- "f_bad_arg",
- "f_arg_item",
- "f_margs",
- "f_marg",
- "f_marg_list",
- "f_opt",
- "restarg_mark",
- "blkarg_mark",
- "assoc" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-# reduce 1 omitted
-
-module_eval(<<'.,.,', 'opal.y', 70)
- def _reduce_2(val, _values, result)
- result = new_compstmt val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 75)
- def _reduce_3(val, _values, result)
- result = new_block
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 79)
- def _reduce_4(val, _values, result)
- result = new_block val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 83)
- def _reduce_5(val, _values, result)
- val[0] << val[2]
- result = val[0]
-
- result
- end
-.,.,
-
-# reduce 6 omitted
-
-module_eval(<<'.,.,', 'opal.y', 90)
- def _reduce_7(val, _values, result)
- result = val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 95)
- def _reduce_8(val, _values, result)
- result = new_body(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 100)
- def _reduce_9(val, _values, result)
- result = new_compstmt val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 105)
- def _reduce_10(val, _values, result)
- result = new_block
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 109)
- def _reduce_11(val, _values, result)
- result = new_block val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 113)
- def _reduce_12(val, _values, result)
- val[0] << val[2]
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 119)
- def _reduce_13(val, _values, result)
- lexer.lex_state = :expr_fname
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 123)
- def _reduce_14(val, _values, result)
- result = new_alias(val[0], val[1], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 127)
- def _reduce_15(val, _values, result)
- result = s(:valias, value(val[1]).to_sym, value(val[2]).to_sym)
-
- result
- end
-.,.,
-
-# reduce 16 omitted
-
-module_eval(<<'.,.,', 'opal.y', 132)
- def _reduce_17(val, _values, result)
- result = s(:valias, value(val[1]).to_sym, value(val[2]).to_sym)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 136)
- def _reduce_18(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 140)
- def _reduce_19(val, _values, result)
- result = new_if(val[1], val[2], val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 144)
- def _reduce_20(val, _values, result)
- result = new_if(val[1], val[2], nil, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 148)
- def _reduce_21(val, _values, result)
- result = new_while(val[1], val[2], val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 152)
- def _reduce_22(val, _values, result)
- result = new_until(val[1], val[2], val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 156)
- def _reduce_23(val, _values, result)
- result = new_rescue_mod(val[1], val[0], val[2])
-
- result
- end
-.,.,
-
-# reduce 24 omitted
-
-module_eval(<<'.,.,', 'opal.y', 161)
- def _reduce_25(val, _values, result)
- result = new_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 165)
- def _reduce_26(val, _values, result)
- result = s(:masgn, val[0], s(:to_ary, val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 169)
- def _reduce_27(val, _values, result)
- result = new_op_asgn val[1], val[0], val[2]
-
- result
- end
-.,.,
-
-# reduce 28 omitted
-
-# reduce 29 omitted
-
-module_eval(<<'.,.,', 'opal.y', 175)
- def _reduce_30(val, _values, result)
- result = s(:op_asgn2, val[0], op_to_setter(val[2]), value(val[3]).to_sym, val[4])
-
- result
- end
-.,.,
-
-# reduce 31 omitted
-
-# reduce 32 omitted
-
-# reduce 33 omitted
-
-module_eval(<<'.,.,', 'opal.y', 182)
- def _reduce_34(val, _values, result)
- result = new_assign val[0], val[1], s(:svalue, val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 186)
- def _reduce_35(val, _values, result)
- result = s(:masgn, val[0], s(:to_ary, val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 190)
- def _reduce_36(val, _values, result)
- result = s(:masgn, val[0], val[2])
-
- result
- end
-.,.,
-
-# reduce 37 omitted
-
-# reduce 38 omitted
-
-module_eval(<<'.,.,', 'opal.y', 197)
- def _reduce_39(val, _values, result)
- result = s(:and, val[0], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 201)
- def _reduce_40(val, _values, result)
- result = s(:or, val[0], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 205)
- def _reduce_41(val, _values, result)
- result = new_unary_call(['!', []], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 209)
- def _reduce_42(val, _values, result)
- result = new_unary_call(val[0], val[1])
-
- result
- end
-.,.,
-
-# reduce 43 omitted
-
-# reduce 44 omitted
-
-# reduce 45 omitted
-
-# reduce 46 omitted
-
-module_eval(<<'.,.,', 'opal.y', 219)
- def _reduce_47(val, _values, result)
- result = new_return(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 223)
- def _reduce_48(val, _values, result)
- result = new_break(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 227)
- def _reduce_49(val, _values, result)
- result = new_next(val[0], val[1])
-
- result
- end
-.,.,
-
-# reduce 50 omitted
-
-# reduce 51 omitted
-
-# reduce 52 omitted
-
-# reduce 53 omitted
-
-# reduce 54 omitted
-
-module_eval(<<'.,.,', 'opal.y', 239)
- def _reduce_55(val, _values, result)
- result = new_call(nil, val[0], val[1])
-
- result
- end
-.,.,
-
-# reduce 56 omitted
-
-module_eval(<<'.,.,', 'opal.y', 244)
- def _reduce_57(val, _values, result)
- result = new_js_call(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-# reduce 58 omitted
-
-module_eval(<<'.,.,', 'opal.y', 249)
- def _reduce_59(val, _values, result)
- result = new_call(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-# reduce 60 omitted
-
-module_eval(<<'.,.,', 'opal.y', 254)
- def _reduce_61(val, _values, result)
- result = new_call(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-# reduce 62 omitted
-
-module_eval(<<'.,.,', 'opal.y', 259)
- def _reduce_63(val, _values, result)
- result = new_super(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 263)
- def _reduce_64(val, _values, result)
- result = new_yield val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 268)
- def _reduce_65(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 272)
- def _reduce_66(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 277)
- def _reduce_67(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 281)
- def _reduce_68(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 286)
- def _reduce_69(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 290)
- def _reduce_70(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 294)
- def _reduce_71(val, _values, result)
- result = val[0] << s(:splat, val[2])
-
- result
- end
-.,.,
-
-# reduce 72 omitted
-
-module_eval(<<'.,.,', 'opal.y', 299)
- def _reduce_73(val, _values, result)
- result = val[0] << s(:splat)
-
- result
- end
-.,.,
-
-# reduce 74 omitted
-
-module_eval(<<'.,.,', 'opal.y', 304)
- def _reduce_75(val, _values, result)
- result = s(:array, s(:splat, val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 308)
- def _reduce_76(val, _values, result)
- result = s(:array, s(:splat))
-
- result
- end
-.,.,
-
-# reduce 77 omitted
-
-module_eval(<<'.,.,', 'opal.y', 314)
- def _reduce_78(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 318)
- def _reduce_79(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 323)
- def _reduce_80(val, _values, result)
- result = s(:array, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 327)
- def _reduce_81(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-# reduce 82 omitted
-
-# reduce 83 omitted
-
-module_eval(<<'.,.,', 'opal.y', 335)
- def _reduce_84(val, _values, result)
- result = new_assignable val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 339)
- def _reduce_85(val, _values, result)
- args = val[2] ? val[2] : []
- result = s(:attrasgn, val[0], :[]=, s(:arglist, *args))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 344)
- def _reduce_86(val, _values, result)
- result = new_call val[0], val[2], []
-
- result
- end
-.,.,
-
-# reduce 87 omitted
-
-# reduce 88 omitted
-
-# reduce 89 omitted
-
-# reduce 90 omitted
-
-# reduce 91 omitted
-
-module_eval(<<'.,.,', 'opal.y', 354)
- def _reduce_92(val, _values, result)
- result = new_assignable val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 358)
- def _reduce_93(val, _values, result)
- result = new_js_attrasgn(val[0], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 362)
- def _reduce_94(val, _values, result)
- result = new_attrasgn(val[0], :[]=, val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 366)
- def _reduce_95(val, _values, result)
- result = new_attrasgn(val[0], op_to_setter(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 370)
- def _reduce_96(val, _values, result)
- result = new_attrasgn(val[0], op_to_setter(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 374)
- def _reduce_97(val, _values, result)
- result = new_attrasgn(val[0], op_to_setter(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 378)
- def _reduce_98(val, _values, result)
- result = new_colon2(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 382)
- def _reduce_99(val, _values, result)
- result = new_colon3(val[0], val[1])
-
- result
- end
-.,.,
-
-# reduce 100 omitted
-
-# reduce 101 omitted
-
-module_eval(<<'.,.,', 'opal.y', 390)
- def _reduce_102(val, _values, result)
- result = new_colon3(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 394)
- def _reduce_103(val, _values, result)
- result = new_const(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 398)
- def _reduce_104(val, _values, result)
- result = new_colon2(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-# reduce 105 omitted
-
-# reduce 106 omitted
-
-# reduce 107 omitted
-
-module_eval(<<'.,.,', 'opal.y', 406)
- def _reduce_108(val, _values, result)
- lexer.lex_state = :expr_end
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 411)
- def _reduce_109(val, _values, result)
- lexer.lex_state = :expr_end
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 417)
- def _reduce_110(val, _values, result)
- result = new_sym(val[0])
-
- result
- end
-.,.,
-
-# reduce 111 omitted
-
-module_eval(<<'.,.,', 'opal.y', 423)
- def _reduce_112(val, _values, result)
- result = s(:undef, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 427)
- def _reduce_113(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-# reduce 114 omitted
-
-# reduce 115 omitted
-
-# reduce 116 omitted
-
-# reduce 117 omitted
-
-# reduce 118 omitted
-
-# reduce 119 omitted
-
-# reduce 120 omitted
-
-# reduce 121 omitted
-
-# reduce 122 omitted
-
-# reduce 123 omitted
-
-# reduce 124 omitted
-
-# reduce 125 omitted
-
-# reduce 126 omitted
-
-# reduce 127 omitted
-
-# reduce 128 omitted
-
-# reduce 129 omitted
-
-# reduce 130 omitted
-
-# reduce 131 omitted
-
-# reduce 132 omitted
-
-# reduce 133 omitted
-
-# reduce 134 omitted
-
-# reduce 135 omitted
-
-# reduce 136 omitted
-
-# reduce 137 omitted
-
-# reduce 138 omitted
-
-# reduce 139 omitted
-
-# reduce 140 omitted
-
-# reduce 141 omitted
-
-# reduce 142 omitted
-
-# reduce 143 omitted
-
-# reduce 144 omitted
-
-# reduce 145 omitted
-
-# reduce 146 omitted
-
-# reduce 147 omitted
-
-# reduce 148 omitted
-
-# reduce 149 omitted
-
-# reduce 150 omitted
-
-# reduce 151 omitted
-
-# reduce 152 omitted
-
-# reduce 153 omitted
-
-# reduce 154 omitted
-
-# reduce 155 omitted
-
-# reduce 156 omitted
-
-# reduce 157 omitted
-
-# reduce 158 omitted
-
-# reduce 159 omitted
-
-# reduce 160 omitted
-
-# reduce 161 omitted
-
-# reduce 162 omitted
-
-# reduce 163 omitted
-
-# reduce 164 omitted
-
-# reduce 165 omitted
-
-# reduce 166 omitted
-
-# reduce 167 omitted
-
-# reduce 168 omitted
-
-# reduce 169 omitted
-
-# reduce 170 omitted
-
-# reduce 171 omitted
-
-# reduce 172 omitted
-
-# reduce 173 omitted
-
-# reduce 174 omitted
-
-# reduce 175 omitted
-
-# reduce 176 omitted
-
-# reduce 177 omitted
-
-# reduce 178 omitted
-
-# reduce 179 omitted
-
-# reduce 180 omitted
-
-# reduce 181 omitted
-
-# reduce 182 omitted
-
-# reduce 183 omitted
-
-# reduce 184 omitted
-
-# reduce 185 omitted
-
-# reduce 186 omitted
-
-# reduce 187 omitted
-
-module_eval(<<'.,.,', 'opal.y', 447)
- def _reduce_188(val, _values, result)
- result = new_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 451)
- def _reduce_189(val, _values, result)
- result = new_assign val[0], val[1], s(:rescue_mod, val[2], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 455)
- def _reduce_190(val, _values, result)
- result = new_op_asgn val[1], val[0], val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 459)
- def _reduce_191(val, _values, result)
- result = new_op_asgn1(val[0], val[2], val[4], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 463)
- def _reduce_192(val, _values, result)
- raise ".JS[...] #{val[4]} is not supported"
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 467)
- def _reduce_193(val, _values, result)
- result = s(:op_asgn2, val[0], op_to_setter(val[2]), value(val[3]).to_sym, val[4])
-
- result
- end
-.,.,
-
-# reduce 194 omitted
-
-# reduce 195 omitted
-
-# reduce 196 omitted
-
-# reduce 197 omitted
-
-# reduce 198 omitted
-
-module_eval(<<'.,.,', 'opal.y', 476)
- def _reduce_199(val, _values, result)
- result = new_irange(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 480)
- def _reduce_200(val, _values, result)
- result = new_erange(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 484)
- def _reduce_201(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 488)
- def _reduce_202(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 492)
- def _reduce_203(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 496)
- def _reduce_204(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 500)
- def _reduce_205(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 504)
- def _reduce_206(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 508)
- def _reduce_207(val, _values, result)
- result = new_call new_binary_call(new_int(val[1]), val[2], val[3]), [:"-@", []], []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 512)
- def _reduce_208(val, _values, result)
- result = new_call new_binary_call(new_float(val[1]), val[2], val[3]), [:"-@", []], []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 516)
- def _reduce_209(val, _values, result)
- result = new_call val[1], [:"+@", []], []
- if [:int, :float].include? val[1].type
- result = val[1]
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 523)
- def _reduce_210(val, _values, result)
- result = new_call val[1], [:"-@", []], []
- if val[1].type == :int
- val[1][1] = -val[1][1]
- result = val[1]
- elsif val[1].type == :float
- val[1][1] = -val[1][1].to_f
- result = val[1]
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 534)
- def _reduce_211(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 538)
- def _reduce_212(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 542)
- def _reduce_213(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 546)
- def _reduce_214(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 550)
- def _reduce_215(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 554)
- def _reduce_216(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 558)
- def _reduce_217(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 562)
- def _reduce_218(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 566)
- def _reduce_219(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 570)
- def _reduce_220(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 574)
- def _reduce_221(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 578)
- def _reduce_222(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 582)
- def _reduce_223(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 586)
- def _reduce_224(val, _values, result)
- result = new_unary_call(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 590)
- def _reduce_225(val, _values, result)
- result = new_unary_call(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 594)
- def _reduce_226(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 598)
- def _reduce_227(val, _values, result)
- result = new_binary_call(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 602)
- def _reduce_228(val, _values, result)
- result = new_and(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 606)
- def _reduce_229(val, _values, result)
- result = new_or(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 610)
- def _reduce_230(val, _values, result)
- result = s(:defined, val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 614)
- def _reduce_231(val, _values, result)
- result = new_if(val[1], val[0], val[2], val[4])
-
- result
- end
-.,.,
-
-# reduce 232 omitted
-
-# reduce 233 omitted
-
-module_eval(<<'.,.,', 'opal.y', 622)
- def _reduce_234(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 626)
- def _reduce_235(val, _values, result)
- result = [val[0]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 630)
- def _reduce_236(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 634)
- def _reduce_237(val, _values, result)
- val[0] << s(:hash, *val[2])
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 639)
- def _reduce_238(val, _values, result)
- result = [s(:hash, *val[0])]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 644)
- def _reduce_239(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-# reduce 240 omitted
-
-module_eval(<<'.,.,', 'opal.y', 651)
- def _reduce_241(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-# reduce 242 omitted
-
-module_eval(<<'.,.,', 'opal.y', 657)
- def _reduce_243(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-# reduce 244 omitted
-
-module_eval(<<'.,.,', 'opal.y', 662)
- def _reduce_245(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 666)
- def _reduce_246(val, _values, result)
- result = val[0]
- result << new_hash(nil, val[2], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 671)
- def _reduce_247(val, _values, result)
- result = [new_hash(nil, val[0], nil)]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 676)
- def _reduce_248(val, _values, result)
- result = [val[0]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 680)
- def _reduce_249(val, _values, result)
- result = val[0]
- add_block_pass val[0], val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 685)
- def _reduce_250(val, _values, result)
- result = [new_hash(nil, val[0], nil)]
- add_block_pass result, val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 690)
- def _reduce_251(val, _values, result)
- result = val[0]
- result << new_hash(nil, val[2], nil)
- result << val[3] if val[3]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 696)
- def _reduce_252(val, _values, result)
- result = []
- add_block_pass result, val[0]
-
- result
- end
-.,.,
-
-# reduce 253 omitted
-
-# reduce 254 omitted
-
-module_eval(<<'.,.,', 'opal.y', 704)
- def _reduce_255(val, _values, result)
- lexer.cmdarg_push 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 708)
- def _reduce_256(val, _values, result)
- lexer.cmdarg_pop
- result = val[1]
-
- result
- end
-.,.,
-
-# reduce 257 omitted
-
-module_eval(<<'.,.,', 'opal.y', 715)
- def _reduce_258(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 719)
- def _reduce_259(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 724)
- def _reduce_260(val, _values, result)
- result = new_block_pass(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 729)
- def _reduce_261(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 733)
- def _reduce_262(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 738)
- def _reduce_263(val, _values, result)
- result = [val[0]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 742)
- def _reduce_264(val, _values, result)
- result = [new_splat(val[0], val[1])]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 746)
- def _reduce_265(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 750)
- def _reduce_266(val, _values, result)
- result = val[0] << new_splat(val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 755)
- def _reduce_267(val, _values, result)
- val[0] << val[2]
- result = s(:array, *val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 760)
- def _reduce_268(val, _values, result)
- val[0] << s(:splat, val[3])
- result = s(:array, *val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 765)
- def _reduce_269(val, _values, result)
- result = s(:splat, val[1])
-
- result
- end
-.,.,
-
-# reduce 270 omitted
-
-# reduce 271 omitted
-
-# reduce 272 omitted
-
-# reduce 273 omitted
-
-# reduce 274 omitted
-
-# reduce 275 omitted
-
-# reduce 276 omitted
-
-# reduce 277 omitted
-
-# reduce 278 omitted
-
-module_eval(<<'.,.,', 'opal.y', 779)
- def _reduce_279(val, _values, result)
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 783)
- def _reduce_280(val, _values, result)
- result = s(:begin, val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 787)
- def _reduce_281(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 791)
- def _reduce_282(val, _values, result)
- result = new_paren(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 795)
- def _reduce_283(val, _values, result)
- result = new_colon2(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 799)
- def _reduce_284(val, _values, result)
- result = new_colon3(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 803)
- def _reduce_285(val, _values, result)
- result = new_call val[0], [:[], []], val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 807)
- def _reduce_286(val, _values, result)
- result = new_js_call val[0], [:[], []], val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 811)
- def _reduce_287(val, _values, result)
- result = new_array(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 815)
- def _reduce_288(val, _values, result)
- result = new_hash(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 819)
- def _reduce_289(val, _values, result)
- result = new_return(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 823)
- def _reduce_290(val, _values, result)
- result = new_yield val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 827)
- def _reduce_291(val, _values, result)
- result = s(:yield)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 831)
- def _reduce_292(val, _values, result)
- result = s(:yield)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 835)
- def _reduce_293(val, _values, result)
- result = s(:defined, val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 839)
- def _reduce_294(val, _values, result)
- result = new_unary_call(['!', []], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 843)
- def _reduce_295(val, _values, result)
- result = new_unary_call(['!', []], new_nil(val[0]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 847)
- def _reduce_296(val, _values, result)
- result = new_call(nil, val[0], [])
- result << val[1]
-
- result
- end
-.,.,
-
-# reduce 297 omitted
-
-module_eval(<<'.,.,', 'opal.y', 853)
- def _reduce_298(val, _values, result)
- val[0] << val[1]
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 858)
- def _reduce_299(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 862)
- def _reduce_300(val, _values, result)
- result = new_if(val[0], val[1], val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 866)
- def _reduce_301(val, _values, result)
- result = new_if(val[0], val[1], val[4], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 870)
- def _reduce_302(val, _values, result)
- lexer.cond_push 1
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 875)
- def _reduce_303(val, _values, result)
- lexer.cond_pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 879)
- def _reduce_304(val, _values, result)
- result = s(:while, val[2], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 883)
- def _reduce_305(val, _values, result)
- lexer.cond_push 1
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 888)
- def _reduce_306(val, _values, result)
- lexer.cond_pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 892)
- def _reduce_307(val, _values, result)
- result = s(:until, val[2], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 896)
- def _reduce_308(val, _values, result)
- result = s(:case, val[1], *val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 900)
- def _reduce_309(val, _values, result)
- result = s(:case, nil, *val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 904)
- def _reduce_310(val, _values, result)
- result = s(:case, nil, val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 908)
- def _reduce_311(val, _values, result)
- lexer.cond_push 1
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 913)
- def _reduce_312(val, _values, result)
- lexer.cond_pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 917)
- def _reduce_313(val, _values, result)
- result = s(:for, val[4], val[1], val[7])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 921)
- def _reduce_314(val, _values, result)
- # ...
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 925)
- def _reduce_315(val, _values, result)
- result = new_class val[0], val[1], val[2], val[4], val[5]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 929)
- def _reduce_316(val, _values, result)
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 933)
- def _reduce_317(val, _values, result)
- # ...
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 937)
- def _reduce_318(val, _values, result)
- result = new_sclass(val[0], val[3], val[6], val[7])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 941)
- def _reduce_319(val, _values, result)
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 945)
- def _reduce_320(val, _values, result)
- # ...
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 949)
- def _reduce_321(val, _values, result)
- result = new_module(val[0], val[2], val[4], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 953)
- def _reduce_322(val, _values, result)
- push_scope
- lexer.lex_state = :expr_endfn
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 958)
- def _reduce_323(val, _values, result)
- result = new_def(val[0], nil, val[1], val[3], val[4], val[5])
- pop_scope
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 963)
- def _reduce_324(val, _values, result)
- lexer.lex_state = :expr_fname
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 967)
- def _reduce_325(val, _values, result)
- push_scope
- lexer.lex_state = :expr_endfn
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 972)
- def _reduce_326(val, _values, result)
- result = new_def(val[0], val[1], val[4], val[6], val[7], val[8])
- pop_scope
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 977)
- def _reduce_327(val, _values, result)
- result = new_break(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 981)
- def _reduce_328(val, _values, result)
- result = s(:next)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 985)
- def _reduce_329(val, _values, result)
- result = s(:redo)
-
- result
- end
-.,.,
-
-# reduce 330 omitted
-
-# reduce 331 omitted
-
-# reduce 332 omitted
-
-# reduce 333 omitted
-
-# reduce 334 omitted
-
-# reduce 335 omitted
-
-# reduce 336 omitted
-
-# reduce 337 omitted
-
-# reduce 338 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1002)
- def _reduce_339(val, _values, result)
- result = new_call nil, [:lambda, []], []
- result << new_iter(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1008)
- def _reduce_340(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1012)
- def _reduce_341(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-# reduce 342 omitted
-
-# reduce 343 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1019)
- def _reduce_344(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1023)
- def _reduce_345(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1028)
- def _reduce_346(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1032)
- def _reduce_347(val, _values, result)
- result = new_if(val[0], val[1], val[3], val[4])
-
- result
- end
-.,.,
-
-# reduce 348 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1038)
- def _reduce_349(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1043)
- def _reduce_350(val, _values, result)
- result = s(:block, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1047)
- def _reduce_351(val, _values, result)
- val[0] << val[2]
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1053)
- def _reduce_352(val, _values, result)
- result = new_assign(new_assignable(new_ident(
- val[0])), val[1], val[2])
-
- result
- end
-.,.,
-
-# reduce 353 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1060)
- def _reduce_354(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1064)
- def _reduce_355(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1068)
- def _reduce_356(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1073)
- def _reduce_357(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1078)
- def _reduce_358(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1082)
- def _reduce_359(val, _values, result)
- nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1087)
- def _reduce_360(val, _values, result)
- result = new_block_args(val[0], val[2], val[4], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1091)
- def _reduce_361(val, _values, result)
- result = new_block_args(val[0], val[2], nil, val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1095)
- def _reduce_362(val, _values, result)
- result = new_block_args(val[0], nil, val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1099)
- def _reduce_363(val, _values, result)
- result = new_block_args(val[0], nil, nil, nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1103)
- def _reduce_364(val, _values, result)
- result = new_block_args(val[0], nil, nil, val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1107)
- def _reduce_365(val, _values, result)
- result = new_block_args(nil, val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1111)
- def _reduce_366(val, _values, result)
- result = new_block_args(nil, val[0], nil, val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1115)
- def _reduce_367(val, _values, result)
- result = new_block_args(nil, nil, val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1119)
- def _reduce_368(val, _values, result)
- result = new_block_args(nil, nil, nil, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1124)
- def _reduce_369(val, _values, result)
- push_scope :block
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1129)
- def _reduce_370(val, _values, result)
- result = new_iter val[2], val[3]
- pop_scope
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1135)
- def _reduce_371(val, _values, result)
- val[0] << val[1]
- result = val[0]
-
- result
- end
-.,.,
-
-# reduce 372 omitted
-
-# reduce 373 omitted
-
-# reduce 374 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1144)
- def _reduce_375(val, _values, result)
- result = new_call(nil, val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1148)
- def _reduce_376(val, _values, result)
- result = new_call(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1152)
- def _reduce_377(val, _values, result)
- result = new_js_call(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1156)
- def _reduce_378(val, _values, result)
- result = new_call(val[0], [:call, []], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1160)
- def _reduce_379(val, _values, result)
- result = new_call(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1164)
- def _reduce_380(val, _values, result)
- result = new_call(val[0], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1168)
- def _reduce_381(val, _values, result)
- result = new_super(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1172)
- def _reduce_382(val, _values, result)
- result = new_super(val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1177)
- def _reduce_383(val, _values, result)
- push_scope :block
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1182)
- def _reduce_384(val, _values, result)
- result = new_iter val[2], val[3]
- pop_scope
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1187)
- def _reduce_385(val, _values, result)
- push_scope :block
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1192)
- def _reduce_386(val, _values, result)
- result = new_iter val[2], val[3]
- pop_scope
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1198)
- def _reduce_387(val, _values, result)
- result = lexer.line
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1202)
- def _reduce_388(val, _values, result)
- part = s(:when, s(:array, *val[2]), val[4])
- result = [part]
- result.push(*val[5]) if val[5]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1209)
- def _reduce_389(val, _values, result)
- result = [val[0]]
-
- result
- end
-.,.,
-
-# reduce 390 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1215)
- def _reduce_391(val, _values, result)
- exc = val[1] || s(:array)
- exc << new_assign(val[2], val[2], s(:gvar, '$!'.intern)) if val[2]
- result = [s(:resbody, exc, val[4])]
- result.push val[5].first if val[5]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1222)
- def _reduce_392(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1227)
- def _reduce_393(val, _values, result)
- result = s(:array, val[0])
-
- result
- end
-.,.,
-
-# reduce 394 omitted
-
-# reduce 395 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1234)
- def _reduce_396(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1238)
- def _reduce_397(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1243)
- def _reduce_398(val, _values, result)
- result = val[1].nil? ? s(:nil) : val[1]
-
- result
- end
-.,.,
-
-# reduce 399 omitted
-
-# reduce 400 omitted
-
-# reduce 401 omitted
-
-# reduce 402 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1253)
- def _reduce_403(val, _values, result)
- result = new_str val[0]
-
- result
- end
-.,.,
-
-# reduce 404 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1259)
- def _reduce_405(val, _values, result)
- result = str_append val[0], val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1264)
- def _reduce_406(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1268)
- def _reduce_407(val, _values, result)
- result = s(:str, value(val[0]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1273)
- def _reduce_408(val, _values, result)
- result = new_xstr(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1278)
- def _reduce_409(val, _values, result)
- result = new_regexp val[1], val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1283)
- def _reduce_410(val, _values, result)
- result = s(:array)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1287)
- def _reduce_411(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1292)
- def _reduce_412(val, _values, result)
- result = s(:array)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1296)
- def _reduce_413(val, _values, result)
- part = val[1]
- part = s(:dstr, "", val[1]) if part.type == :evstr
- result = val[0] << part
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1303)
- def _reduce_414(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1307)
- def _reduce_415(val, _values, result)
- result = val[0].concat([val[1]])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1312)
- def _reduce_416(val, _values, result)
- result = s(:array)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1316)
- def _reduce_417(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1321)
- def _reduce_418(val, _values, result)
- result = s(:array)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1325)
- def _reduce_419(val, _values, result)
- result = val[0] << s(:str, value(val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1330)
- def _reduce_420(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1334)
- def _reduce_421(val, _values, result)
- result = str_append val[0], val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1339)
- def _reduce_422(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1343)
- def _reduce_423(val, _values, result)
- result = str_append val[0], val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1348)
- def _reduce_424(val, _values, result)
- result = new_str_content(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1352)
- def _reduce_425(val, _values, result)
- result = lexer.strterm
- lexer.strterm = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1357)
- def _reduce_426(val, _values, result)
- lexer.strterm = val[1]
- result = new_evstr(val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1362)
- def _reduce_427(val, _values, result)
- lexer.cond_push 0
- lexer.cmdarg_push 0
- result = lexer.strterm
- lexer.strterm = nil
- lexer.lex_state = :expr_beg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1370)
- def _reduce_428(val, _values, result)
- lexer.strterm = val[1]
- lexer.cond_lexpop
- lexer.cmdarg_lexpop
- result = new_evstr(val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1378)
- def _reduce_429(val, _values, result)
- result = new_gvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1382)
- def _reduce_430(val, _values, result)
- result = new_ivar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1386)
- def _reduce_431(val, _values, result)
- result = new_cvar(val[0])
-
- result
- end
-.,.,
-
-# reduce 432 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1393)
- def _reduce_433(val, _values, result)
- result = new_sym(val[1])
- lexer.lex_state = :expr_end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1398)
- def _reduce_434(val, _values, result)
- result = new_sym(val[0])
-
- result
- end
-.,.,
-
-# reduce 435 omitted
-
-# reduce 436 omitted
-
-# reduce 437 omitted
-
-# reduce 438 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1408)
- def _reduce_439(val, _values, result)
- result = new_dsym val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1413)
- def _reduce_440(val, _values, result)
- result = new_int(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1417)
- def _reduce_441(val, _values, result)
- result = new_float(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1421)
- def _reduce_442(val, _values, result)
- result = negate_num(new_int(val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1425)
- def _reduce_443(val, _values, result)
- result = negate_num(new_float(val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1429)
- def _reduce_444(val, _values, result)
- result = new_int(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1433)
- def _reduce_445(val, _values, result)
- result = new_float(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1438)
- def _reduce_446(val, _values, result)
- result = new_ident(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1442)
- def _reduce_447(val, _values, result)
- result = new_ivar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1446)
- def _reduce_448(val, _values, result)
- result = new_gvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1450)
- def _reduce_449(val, _values, result)
- result = new_const(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1454)
- def _reduce_450(val, _values, result)
- result = new_cvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1458)
- def _reduce_451(val, _values, result)
- result = new_nil(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1462)
- def _reduce_452(val, _values, result)
- result = new_self(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1466)
- def _reduce_453(val, _values, result)
- result = new_true(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1470)
- def _reduce_454(val, _values, result)
- result = new_false(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1474)
- def _reduce_455(val, _values, result)
- result = new___FILE__(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1478)
- def _reduce_456(val, _values, result)
- result = new___LINE__(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1483)
- def _reduce_457(val, _values, result)
- result = new_var_ref(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1488)
- def _reduce_458(val, _values, result)
- result = new_assignable val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1493)
- def _reduce_459(val, _values, result)
- result = s(:nth_ref, value(val[0]))
-
- result
- end
-.,.,
-
-# reduce 460 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1499)
- def _reduce_461(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1503)
- def _reduce_462(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1507)
- def _reduce_463(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1512)
- def _reduce_464(val, _values, result)
- result = val[1]
- lexer.lex_state = :expr_beg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1517)
- def _reduce_465(val, _values, result)
- result = val[0]
- lexer.lex_state = :expr_beg
-
- result
- end
-.,.,
-
-# reduce 466 omitted
-
-# reduce 467 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1526)
- def _reduce_468(val, _values, result)
- result = new_kwrestarg(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1530)
- def _reduce_469(val, _values, result)
- result = new_kwrestarg()
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1535)
- def _reduce_470(val, _values, result)
- result = new_sym(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1540)
- def _reduce_471(val, _values, result)
- result = new_kwoptarg(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1544)
- def _reduce_472(val, _values, result)
- result = new_kwarg(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1549)
- def _reduce_473(val, _values, result)
- result = [val[0]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1553)
- def _reduce_474(val, _values, result)
- result = val[0]
- result << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1559)
- def _reduce_475(val, _values, result)
- result = new_args_tail(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1563)
- def _reduce_476(val, _values, result)
- result = new_args_tail(val[0], nil, val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1567)
- def _reduce_477(val, _values, result)
- result = new_args_tail(nil, val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1571)
- def _reduce_478(val, _values, result)
- result = new_args_tail(nil, nil, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1576)
- def _reduce_479(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1580)
- def _reduce_480(val, _values, result)
- result = new_args_tail(nil, nil, nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1585)
- def _reduce_481(val, _values, result)
- result = new_args(val[0], val[2], val[4], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1589)
- def _reduce_482(val, _values, result)
- result = new_args(val[0], val[2], nil, val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1593)
- def _reduce_483(val, _values, result)
- result = new_args(val[0], nil, val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1597)
- def _reduce_484(val, _values, result)
- result = new_args(val[0], nil, nil, val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1601)
- def _reduce_485(val, _values, result)
- result = new_args(nil, val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1605)
- def _reduce_486(val, _values, result)
- result = new_args(nil, val[0], nil, val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1609)
- def _reduce_487(val, _values, result)
- result = new_args(nil, nil, val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1613)
- def _reduce_488(val, _values, result)
- result = new_args(nil, nil, nil, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1617)
- def _reduce_489(val, _values, result)
- result = new_args(nil, nil, nil, nil)
-
- result
- end
-.,.,
-
-# reduce 490 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1623)
- def _reduce_491(val, _values, result)
- result = value(val[0]).to_sym
- scope.add_local result
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1629)
- def _reduce_492(val, _values, result)
- raise 'formal argument cannot be a constant'
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1633)
- def _reduce_493(val, _values, result)
- raise 'formal argument cannot be an instance variable'
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1637)
- def _reduce_494(val, _values, result)
- raise 'formal argument cannot be a class variable'
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1641)
- def _reduce_495(val, _values, result)
- raise 'formal argument cannot be a global variable'
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1646)
- def _reduce_496(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1650)
- def _reduce_497(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-# reduce 498 omitted
-
-# reduce 499 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1658)
- def _reduce_500(val, _values, result)
- result = s(:lasgn, val[0])
-
- result
- end
-.,.,
-
-# reduce 501 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1664)
- def _reduce_502(val, _values, result)
- result = s(:array, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1668)
- def _reduce_503(val, _values, result)
- val[0] << val[2]
- result = val[0]
-
- result
- end
-.,.,
-
-# reduce 504 omitted
-
-# reduce 505 omitted
-
-# reduce 506 omitted
-
-# reduce 507 omitted
-
-# reduce 508 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1680)
- def _reduce_509(val, _values, result)
- result = [val[0]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1684)
- def _reduce_510(val, _values, result)
- val[0] << val[2]
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1690)
- def _reduce_511(val, _values, result)
- result = new_assign(new_assignable(new_ident(val[0])), val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1695)
- def _reduce_512(val, _values, result)
- result = s(:block, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1699)
- def _reduce_513(val, _values, result)
- result = val[0]
- val[0] << val[2]
-
- result
- end
-.,.,
-
-# reduce 514 omitted
-
-# reduce 515 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1708)
- def _reduce_516(val, _values, result)
- result = "*#{value(val[1])}".to_sym
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1712)
- def _reduce_517(val, _values, result)
- result = :"*"
-
- result
- end
-.,.,
-
-# reduce 518 omitted
-
-# reduce 519 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1720)
- def _reduce_520(val, _values, result)
- result = "&#{value(val[1])}".to_sym
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1725)
- def _reduce_521(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1729)
- def _reduce_522(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1734)
- def _reduce_523(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1738)
- def _reduce_524(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1743)
- def _reduce_525(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1747)
- def _reduce_526(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1752)
- def _reduce_527(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1756)
- def _reduce_528(val, _values, result)
- result = val[0].push(*val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1761)
- def _reduce_529(val, _values, result)
- result = [val[0], val[2]]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'opal.y', 1765)
- def _reduce_530(val, _values, result)
- result = [new_sym(val[0]), val[1]]
-
- result
- end
-.,.,
-
-# reduce 531 omitted
-
-# reduce 532 omitted
-
-# reduce 533 omitted
-
-# reduce 534 omitted
-
-# reduce 535 omitted
-
-# reduce 536 omitted
-
-# reduce 537 omitted
-
-# reduce 538 omitted
-
-# reduce 539 omitted
-
-# reduce 540 omitted
-
-# reduce 541 omitted
-
-# reduce 542 omitted
-
-# reduce 543 omitted
-
-# reduce 544 omitted
-
-# reduce 545 omitted
-
-# reduce 546 omitted
-
-# reduce 547 omitted
-
-# reduce 548 omitted
-
-# reduce 549 omitted
-
-# reduce 550 omitted
-
-# reduce 551 omitted
-
-# reduce 552 omitted
-
-# reduce 553 omitted
-
-module_eval(<<'.,.,', 'opal.y', 1802)
- def _reduce_554(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module Opal
diff --git a/test/racc/regress/php_serialization b/test/racc/regress/php_serialization
deleted file mode 100644
index e412db1cc8..0000000000
--- a/test/racc/regress/php_serialization
+++ /dev/null
@@ -1,336 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-require 'php_serialization/tokenizer'
-
-module PhpSerialization
- class Unserializer < Racc::Parser
-
-module_eval(<<'...end php_serialization.y/module_eval...', 'php_serialization.y', 84)
- def initialize(tokenizer_klass = Tokenizer)
- @tokenizer_klass = tokenizer_klass
- end
-
- def run(string)
- @tokenizer = @tokenizer_klass.new(string)
- yyparse(@tokenizer, :each)
- return @object
- ensure
- @tokenizer = nil
- end
-
- def next_token
- @tokenizer.next_token
- end
-...end php_serialization.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 9, 10, 16, 17, 11, 12, 13, 18, 14, 9,
- 10, 15, 19, 11, 12, 13, 20, 14, 21, 46,
- 15, 9, 10, 22, 23, 11, 12, 13, 24, 14,
- 9, 10, 15, 25, 11, 12, 13, 26, 14, 27,
- 51, 15, 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41, 43, 47, 49 ]
-
-racc_action_check = [
- 0, 0, 1, 2, 0, 0, 0, 3, 0, 42,
- 42, 0, 4, 42, 42, 42, 5, 42, 6, 42,
- 42, 45, 45, 10, 11, 45, 45, 45, 12, 45,
- 50, 50, 45, 13, 50, 50, 50, 14, 50, 15,
- 50, 50, 16, 22, 23, 24, 25, 26, 27, 32,
- 33, 34, 35, 36, 37, 39, 41, 43, 47 ]
-
-racc_action_pointer = [
- -3, 2, 1, 5, 10, 14, 16, nil, nil, nil,
- 18, 19, 23, 28, 32, 34, 42, nil, nil, nil,
- nil, nil, 37, 38, 39, 40, 41, 42, nil, nil,
- nil, nil, 44, 45, 46, 42, 43, 42, nil, 50,
- nil, 50, 6, 52, nil, 18, nil, 46, nil, nil,
- 27, nil ]
-
-racc_action_default = [
- -18, -18, -18, -18, -18, -18, -18, -6, -7, -8,
- -18, -18, -18, -18, -18, -18, -18, -1, -2, -3,
- -4, -5, -18, -18, -18, -18, -18, -18, 52, -9,
- -10, -11, -18, -18, -18, -18, -18, -18, -12, -18,
- -15, -18, -18, -18, -14, -18, -17, -18, -16, -15,
- -18, -13 ]
-
-racc_goto_table = [
- 1, 42, nil, nil, nil, nil, nil, nil, nil, nil,
- 50, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 48 ]
-
-racc_goto_check = [
- 1, 9, nil, nil, nil, nil, nil, nil, nil, nil,
- 9, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 1 ]
-
-racc_goto_pointer = [
- nil, 0, nil, nil, nil, nil, nil, nil, nil, -39,
- nil ]
-
-racc_goto_default = [
- nil, 45, 2, 3, 4, 5, 6, 7, 8, nil,
- 44 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 2, 16, :_reduce_1,
- 2, 16, :_reduce_2,
- 2, 16, :_reduce_3,
- 2, 16, :_reduce_4,
- 2, 16, :_reduce_5,
- 1, 16, :_reduce_6,
- 1, 16, :_reduce_7,
- 1, 17, :_reduce_8,
- 3, 18, :_reduce_9,
- 3, 19, :_reduce_10,
- 3, 20, :_reduce_11,
- 5, 21, :_reduce_12,
- 11, 23, :_reduce_13,
- 2, 24, :_reduce_14,
- 0, 24, :_reduce_15,
- 2, 25, :_reduce_16,
- 7, 22, :_reduce_17 ]
-
-racc_reduce_n = 18
-
-racc_shift_n = 52
-
-racc_token_table = {
- false => 0,
- :error => 1,
- ";" => 2,
- "N" => 3,
- "b" => 4,
- ":" => 5,
- :NUMBER => 6,
- "i" => 7,
- "d" => 8,
- "s" => 9,
- :STRING => 10,
- "O" => 11,
- "{" => 12,
- "}" => 13,
- "a" => 14 }
-
-racc_nt_base = 15
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "\";\"",
- "\"N\"",
- "\"b\"",
- "\":\"",
- "NUMBER",
- "\"i\"",
- "\"d\"",
- "\"s\"",
- "STRING",
- "\"O\"",
- "\"{\"",
- "\"}\"",
- "\"a\"",
- "$start",
- "data",
- "null",
- "bool",
- "integer",
- "double",
- "string",
- "assoc_array",
- "object",
- "attribute_list",
- "attribute" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'php_serialization.y', 6)
- def _reduce_1(val, _values, result)
- @object = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 7)
- def _reduce_2(val, _values, result)
- @object = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 8)
- def _reduce_3(val, _values, result)
- @object = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 9)
- def _reduce_4(val, _values, result)
- @object = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 10)
- def _reduce_5(val, _values, result)
- @object = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 11)
- def _reduce_6(val, _values, result)
- @object = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 12)
- def _reduce_7(val, _values, result)
- @object = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 15)
- def _reduce_8(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 18)
- def _reduce_9(val, _values, result)
- result = Integer(val[2]) > 0
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 21)
- def _reduce_10(val, _values, result)
- result = Integer(val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 24)
- def _reduce_11(val, _values, result)
- result = Float(val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 27)
- def _reduce_12(val, _values, result)
- result = val[4]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 32)
- def _reduce_13(val, _values, result)
- if eval("defined?(#{val[4]})")
- result = Object.const_get(val[4]).new
-
- val[9].each do |(attr_name, value)|
- # Protected and private attributes will have a \0..\0 prefix
- attr_name = attr_name.gsub(/\A\\0[^\\]+\\0/, '')
- result.instance_variable_set("@#{attr_name}", value)
- end
- else
- klass_name = val[4].gsub(/^Struct::/, '')
- attr_names, values = [], []
-
- val[9].each do |(attr_name, value)|
- # Protected and private attributes will have a \0..\0 prefix
- attr_names << attr_name.gsub(/\A\\0[^\\]+\\0/, '')
- values << value
- end
-
- result = Struct.new(klass_name, *attr_names).new(*values)
- result.instance_variable_set("@_php_class", klass_name)
- end
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 56)
- def _reduce_14(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 57)
- def _reduce_15(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 60)
- def _reduce_16(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'php_serialization.y', 65)
- def _reduce_17(val, _values, result)
- # Checks if the keys are a sequence of integers
- idx = -1
- arr = val[5].all? { |(k,v)| k == (idx += 1) }
-
- if arr
- result = val[5].map { |(k,v)| v }
- else
- result = Hash[val[5]]
- end
-
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Unserializer
-end # module PhpSerialization
diff --git a/test/racc/regress/riml b/test/racc/regress/riml
deleted file mode 100644
index 5882a431cf..0000000000
--- a/test/racc/regress/riml
+++ /dev/null
@@ -1,4037 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.2
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
- require File.expand_path("../lexer", __FILE__)
- require File.expand_path("../nodes", __FILE__)
- require File.expand_path("../errors", __FILE__)
- require File.expand_path("../ast_rewriter", __FILE__)
-module Riml
- class Parser < Racc::Parser
-
-module_eval(<<'...end riml.y/module_eval...', 'riml.y', 592)
- # This code will be put as-is in the parser class
-
- attr_accessor :ast_rewriter
- attr_writer :options
-
- # The Parser and AST_Rewriter share this same hash of options
- def options
- @options ||= {}
- end
-
- def self.ast_cache
- @ast_cache
- end
- @ast_cache = {}
-
- # parses tokens or code into output nodes
- def parse(object, ast_rewriter = Riml::AST_Rewriter.new, filename = nil, included = false)
- if (ast = self.class.ast_cache[filename])
- else
- if tokens?(object)
- @tokens = object
- elsif code?(object)
- @lexer = Riml::Lexer.new(object, filename, true)
- end
-
- begin
- ast = do_parse
- rescue Racc::ParseError => e
- raise unless @lexer
- if (invalid_token = @lexer.prev_token_is_keyword?)
- warning = "#{invalid_token.inspect} is a keyword, and cannot " \
- "be used as a variable name"
- end
- error_msg = e.message
- error_msg << "\nWARNING: #{warning}" if warning
- error = Riml::ParseError.new(error_msg, @lexer.filename, @lexer.lineno)
- raise error
- end
- self.class.ast_cache[filename] = ast if filename
- end
- @ast_rewriter ||= ast_rewriter
- return ast unless @ast_rewriter
- @ast_rewriter.ast = ast.dup
- @ast_rewriter.options ||= options
- @ast_rewriter.rewrite(filename, included)
- @ast_rewriter.ast
- end
-
- # get the next token from either the list of tokens provided, or
- # the lexer getting the next token
- def next_token
- return @tokens.shift unless @lexer
- token = @lexer.next_token
- if token && @lexer.parser_info
- @current_parser_info = token.pop
- end
- token
- end
-
- private
-
- def tokens?(object)
- Array === object
- end
-
- def code?(object)
- String === object
- end
-
- def make_node(racc_val)
- node = yield racc_val
- node.parser_info = @current_parser_info
- node
- end
-...end riml.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 135, 265, 60, 139, 136, 211, 417, 418, 48, 47,
- 411, 211, 448, 274, 146, 56, 199, 89, 272, 60,
- 273, 270, 409, 271, 37, 46, 48, 47, 37, 49,
- 44, 45, 392, 412, 37, 449, 384, 60, 50, 70,
- 316, 61, 386, 385, 317, 62, 63, 129, 130, 132,
- 127, 128, 131, 115, 116, 117, 121, 122, 123, 118,
- 119, 120, 124, 125, 126, 102, 104, 103, 109, 111,
- 110, 112, 114, 113, 106, 108, 107, 133, 134, 101,
- 100, 137, 171, 80, 38, 173, 37, 81, 38, 82,
- 85, 83, 84, 87, 38, 105, 86, 37, 75, 76,
- 153, 152, 57, 56, 88, 89, 77, 37, 90, 58,
- 59, 78, 37, 46, 48, 47, 91, 49, 44, 45,
- 64, 72, 73, -116, 161, 60, 50, 70, 79, 61,
- 272, 37, 92, 62, 63, 271, 48, 47, -178, -178,
- -178, -178, 211, 147, 211, 211, 38, 60, -43, -43,
- 153, 152, 329, 409, 99, 409, 409, 38, 331, 153,
- 152, -42, -42, 161, 60, 50, 70, 38, 139, 313,
- 29, 313, 38, 52, 80, 54, 164, 277, 81, 277,
- 82, 85, 83, 84, 87, 279, 279, 86, 149, 75,
- 76, 38, 182, 57, 56, 88, 89, 77, 149, 90,
- 58, 59, 78, 37, 46, 48, 47, 91, 49, 44,
- 45, 64, 72, 73, -116, 164, 60, 50, 70, 79,
- 61, 164, 60, 164, 62, 63, -204, 277, 149, 164,
- 279, 164, -203, 305, 149, 366, 141, 164, 164, -44,
- -44, 129, 130, 132, -85, -85, -85, -85, 142, -48,
- -48, -116, 258, 60, 50, 70, -99, -98, 60, 50,
- 70, 29, 149, 38, 52, 80, 54, 371, 149, 81,
- 52, 82, 85, 83, 84, 87, 149, 139, 86, 164,
- 75, 76, 164, 139, 57, 56, 88, 89, 77, 105,
- 90, 58, 59, 78, 37, 46, 48, 47, 91, 49,
- 44, 45, 64, 72, 73, -99, -98, 60, 50, 70,
- 79, 61, -46, -46, 370, 62, 63, -175, -175, -175,
- -175, 139, 129, 130, 132, -47, -47, -45, -45, 433,
- 195, 432, 129, 130, 132, 127, 128, 131, 115, 116,
- 117, 121, 122, 123, 118, 119, 120, 124, 125, 126,
- 164, 354, 29, 211, 38, 52, 80, 54, 153, 152,
- 81, 60, 82, 85, 83, 84, 87, 149, 60, 86,
- 105, 75, 76, 417, 437, 57, 56, 88, 89, 77,
- 105, 90, 58, 59, 78, 215, 46, 48, 47, 91,
- 49, 44, 45, 64, 72, 73, -116, 216, 60, 50,
- 70, 79, 61, 139, 218, 319, 62, 63, -175, -175,
- -175, -175, -178, -178, -178, -178, 211, 147, 48, 47,
- 211, 49, 48, 47, 262, 49, -176, -176, -176, -176,
- 263, 320, 191, 192, 193, 194, 267, 129, 130, 132,
- 127, 128, 131, 29, 269, 269, 52, 269, 54, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, 102, 104, 103,
- 109, 111, 110, 112, 114, 113, 106, 108, 107, 133,
- 134, 101, 100, 137, 323, 105, 258, 276, 294, 295,
- 149, 139, 302, 305, 306, 105, 139, 105, 312, 326,
- 327, 328, 333, 105, 105, 105, 342, 346, 357, 361,
- 320, 258, 362, 363, 60, 129, 130, 132, 127, 128,
- 131, 129, 130, 132, 127, 128, 131, 368, 129, 130,
- 132, 127, 128, 131, 115, 116, 117, 121, 122, 123,
- 118, 119, 120, 124, 125, 126, 102, 104, 103, 109,
- 111, 110, 112, 114, 113, 106, 108, 107, 133, 134,
- 101, 100, 137, 105, 80, 129, 130, 132, 81, 105,
- 82, 85, 83, 84, 87, 374, 105, 86, 377, 75,
- 76, 379, 380, 57, 56, 88, 89, 77, 393, 90,
- 58, 59, 78, 37, 46, 48, 47, 91, 49, 44,
- 45, 64, 72, 73, -116, 302, 60, 50, 70, 79,
- 61, 394, 397, 105, 62, 63, 269, 258, 129, 130,
- 132, 127, 128, 131, 115, 116, 117, 121, 122, 123,
- 118, 119, 120, 124, 125, 126, 102, 104, 103, 109,
- 111, 110, 112, 114, 113, 106, 108, 107, 133, 134,
- 101, 29, 400, 38, 52, 80, 54, 401, 402, 81,
- -245, 82, 85, 83, 84, 87, 105, 403, 86, 406,
- 75, 76, 60, 211, 57, 56, 88, 89, 77, 211,
- 90, 58, 59, 78, 37, 46, 48, 47, 91, 49,
- 44, 45, 64, 72, 73, 427, 60, 60, 50, 70,
- 79, 61, 430, 431, 434, 62, 63, 435, 438, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, 102, 104, 103,
- 109, 111, 110, 112, 114, 113, 106, 108, 107, 133,
- 134, 440, 29, 441, 38, 52, 80, 54, 442, 443,
- 81, 211, 82, 85, 83, 84, 87, 105, 445, 86,
- 446, 75, 76, 371, 371, 57, 56, 88, 89, 77,
- 211, 90, 58, 59, 78, 37, 46, 48, 47, 91,
- 49, 44, 45, 64, 72, 73, 458, 435, 60, 50,
- 70, 79, 61, 462, 463, 371, 62, 63, 465, 468,
- 129, 130, 132, 127, 128, 131, 115, 116, 117, 121,
- 122, 123, 118, 119, 120, 124, 125, 126, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 129,
- 130, 132, nil, 29, nil, 38, 52, 80, 54, nil,
- nil, 81, nil, 82, 85, 83, 84, 87, 105, nil,
- 86, nil, 75, 76, nil, nil, 57, 56, 88, 89,
- 77, nil, 90, 58, 59, 78, 37, 46, 48, 47,
- 91, 49, 44, 45, 64, 72, 73, 105, nil, 60,
- 50, 70, 79, 61, nil, nil, nil, 62, 63, nil,
- nil, 129, 130, 132, 127, 128, 131, 115, 116, 117,
- 121, 122, 123, 118, 119, 120, 124, 125, 126, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 129, 130, 132, nil, 29, nil, 38, 52, 80, 54,
- nil, nil, 81, nil, 82, 85, 83, 84, 87, 105,
- nil, 86, nil, 75, 76, nil, nil, 57, 56, 88,
- 89, 77, nil, 90, 58, 59, 78, 37, 46, 48,
- 47, 91, 49, 44, 45, 64, 72, 73, 105, nil,
- 60, 50, 70, 79, 61, nil, nil, nil, 62, 63,
- 414, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 29, nil, 38, 52, nil,
- 54, nil, 129, 130, 132, 127, 128, 131, 115, 116,
- 117, 121, 122, 123, 118, 119, 120, 124, 125, 126,
- 102, 104, 103, 109, 111, 110, 112, 114, 113, 106,
- 108, 107, 133, 134, 101, 100, 137, 419, nil, nil,
- nil, nil, nil, nil, nil, nil, 146, 56, nil, 89,
- 105, nil, 90, nil, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, 102, 104, 103,
- 109, 111, 110, 112, 114, 113, 106, 108, 107, 133,
- 134, 101, 100, 137, 29, nil, nil, 52, nil, 54,
- nil, 261, 146, 56, nil, 89, nil, 105, 90, nil,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, nil, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, 180, 146, 56, nil, 89,
- nil, nil, 90, nil, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, -116, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, nil,
- 29, nil, nil, 52, nil, 54, nil, 261, nil, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, nil, 180, 146,
- 56, nil, 89, nil, 176, 90, nil, 52, nil, 54,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- nil, nil, 60, 50, 70, nil, 61, 105, nil, nil,
- 62, 63, 180, 146, 56, nil, 89, nil, nil, 90,
- nil, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, nil, 29, -119, nil,
- 52, nil, 54, nil, nil, 129, 130, 132, 127, 128,
- 131, 115, 116, 117, 121, 122, 123, 118, 119, 120,
- 124, 125, 126, nil, nil, nil, 180, 146, 56, nil,
- 89, 29, -119, 90, 52, nil, 54, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, 105, 61, nil, nil, nil, 62, 63,
- 180, 146, 56, nil, 89, nil, nil, 90, nil, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, nil, 29, -119, nil, 52, nil,
- 54, nil, nil, 129, 130, 132, 127, 128, 131, 115,
- 116, 117, 121, 122, 123, 118, 119, 120, 124, 125,
- 126, nil, nil, nil, 180, 146, 56, nil, 89, 29,
- -119, 90, 52, nil, 54, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, 105, 61, nil, nil, nil, 62, 63, 180, 146,
- 56, nil, 89, nil, nil, 90, nil, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- nil, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, nil, 29, -121, nil, 52, nil, 54, nil,
- nil, 129, 130, 132, 127, 128, 131, 115, 116, 117,
- 121, 122, 123, 118, 119, 120, 124, 125, 126, nil,
- nil, nil, nil, 146, 56, nil, 89, 29, -119, 90,
- 52, nil, 54, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, 105,
- 61, nil, nil, nil, 62, 63, 180, 146, 56, nil,
- 89, nil, nil, 90, nil, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- nil, 29, nil, nil, 52, nil, 54, 350, nil, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, nil, nil, nil,
- 180, 146, 56, nil, 89, 29, -119, 90, 52, nil,
- 54, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, 105, 61, nil,
- nil, nil, 62, 63, 365, 146, 56, nil, 89, nil,
- nil, 90, nil, nil, nil, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, nil, 29,
- -119, nil, 52, nil, 54, nil, 129, 130, 132, 127,
- 128, 131, 115, 116, 117, 121, 122, 123, 118, 119,
- 120, 124, 125, 126, nil, nil, nil, 180, 146, 56,
- nil, 89, nil, 29, 90, nil, 52, nil, 54, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, 105, 61, nil, nil, nil, 62,
- 63, 180, 146, 56, nil, 89, nil, nil, 90, nil,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, nil, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, nil, 29, -119, nil, 52,
- nil, 54, nil, nil, 129, 130, 132, 127, 128, 131,
- 115, 116, 117, 121, 122, 123, 118, 119, 120, 124,
- 125, 126, nil, nil, nil, nil, 146, 56, nil, 89,
- 29, -119, 90, 52, nil, 54, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, 105, 61, nil, nil, nil, 62, 63, 146,
- 56, nil, 89, nil, nil, 90, nil, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- -116, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, 146, 56, 29, 89, nil, 52, 90, 54,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, -116, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, 146, 56, 29, 89, nil,
- 52, 90, 54, nil, nil, 167, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, 146, 56,
- 29, 89, nil, 52, 90, 54, nil, nil, nil, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, nil, 61, nil, nil, nil, 62,
- 63, 146, 56, 165, 89, nil, 52, 90, 54, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, 146, 56, 29, 89, nil, 52,
- 90, 54, nil, nil, nil, 46, 48, 47, nil, 49,
- 44, 45, 64, nil, nil, nil, nil, 60, 50, 70,
- nil, 61, nil, nil, nil, 62, 63, 146, 56, 29,
- 89, nil, 52, 90, 54, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, -116, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- 146, 56, 29, 89, nil, 52, 90, 54, nil, nil,
- nil, 46, 48, 47, nil, 49, 44, 45, 64, nil,
- nil, nil, nil, 60, 50, 70, nil, 61, nil, nil,
- nil, 62, 63, 146, 56, 29, 89, nil, 52, 90,
- 54, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, 146, 56, 29, 89,
- nil, 52, 90, 54, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, 146,
- 56, 29, 89, nil, 52, 90, 54, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- nil, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, 146, 56, 29, 89, nil, 52, 90, 54,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, nil, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, 146, 56, 29, 89, nil,
- 52, 90, 54, nil, nil, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, 146, 56,
- 29, 89, nil, 52, 90, 54, nil, nil, nil, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, nil, 61, nil, nil, nil, 62,
- 63, 146, 56, 29, 89, nil, 52, 90, 54, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, 146, 56, 29, 89, nil, 52,
- 90, 54, nil, nil, nil, 46, 48, 47, nil, 49,
- 44, 45, 64, nil, nil, nil, nil, 60, 50, 70,
- nil, 61, nil, nil, nil, 62, 63, 146, 56, 29,
- 89, nil, 52, 90, 54, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- 146, 56, 29, 89, nil, 52, 90, 54, nil, nil,
- nil, 46, 48, 47, nil, 49, 44, 45, 64, nil,
- nil, nil, nil, 60, 50, 70, nil, 61, nil, nil,
- nil, 62, 63, 146, 56, 29, 89, nil, 52, 90,
- 54, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, 146, 56, 29, 89,
- nil, 52, 90, 54, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, 146,
- 56, 29, 89, nil, 52, 90, 54, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- nil, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, 146, 56, 29, 89, nil, 52, 90, 54,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, nil, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, 146, 56, 29, 89, nil,
- 52, 90, 54, nil, nil, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, 146, 56,
- 29, 89, nil, 52, 90, 54, nil, nil, nil, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, nil, 61, nil, nil, nil, 62,
- 63, 146, 56, 29, 89, nil, 52, 90, 54, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, 146, 56, 29, 89, nil, 52,
- 90, 54, nil, nil, nil, 46, 48, 47, nil, 49,
- 44, 45, 64, nil, nil, nil, nil, 60, 50, 70,
- nil, 61, nil, nil, nil, 62, 63, 146, 56, 29,
- 89, nil, 52, 90, 54, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- 146, 56, 29, 89, nil, 52, 90, 54, nil, nil,
- nil, 46, 48, 47, nil, 49, 44, 45, 64, nil,
- nil, nil, nil, 60, 50, 70, nil, 61, nil, nil,
- nil, 62, 63, 146, 56, 29, 89, nil, 52, 90,
- 54, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, 146, 56, 29, 89,
- nil, 52, 90, 54, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, 146,
- 56, 29, 89, nil, 52, 90, 54, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- nil, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, 146, 56, 29, 89, nil, 52, 90, 54,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, nil, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, 146, 56, 29, 89, nil,
- 52, 90, 54, nil, nil, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, 146, 56,
- 29, 89, nil, 52, 90, 54, nil, nil, nil, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, nil, 61, nil, nil, nil, 62,
- 63, 146, 56, 29, 89, nil, 52, 90, 54, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, 146, 56, 29, 89, nil, 52,
- 90, 54, nil, nil, nil, 46, 48, 47, nil, 49,
- 44, 45, 64, nil, nil, nil, nil, 60, 50, 70,
- nil, 61, nil, nil, nil, 62, 63, 146, 56, 29,
- 89, nil, 52, 90, 54, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- 146, 56, 29, 89, nil, 52, 90, 54, nil, nil,
- nil, 46, 48, 47, nil, 49, 44, 45, 64, nil,
- nil, nil, nil, 60, 50, 70, nil, 61, nil, nil,
- nil, 62, 63, 146, 56, 29, 89, nil, 52, 90,
- 54, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, 146, 56, 29, 89,
- nil, 52, 90, 54, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, 146,
- 56, 29, 89, nil, 52, 90, 54, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- nil, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, 146, 56, 29, 89, nil, 52, 90, 54,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, nil, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, 146, 56, 29, 89, nil,
- 52, 90, 54, nil, nil, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, 146, 56,
- 29, 89, nil, 52, 90, 54, nil, nil, nil, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, nil, 61, nil, nil, nil, 62,
- 63, 146, 56, 29, 89, nil, 52, 90, 54, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, 146, 56, 29, 89, nil, 52,
- 90, 54, nil, nil, nil, 46, 48, 47, nil, 49,
- 44, 45, 64, nil, nil, nil, nil, 60, 50, 70,
- nil, 61, nil, nil, nil, 62, 63, 146, 56, 29,
- 89, nil, 52, 90, 54, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- 146, 56, 29, 89, nil, 52, 90, 54, nil, nil,
- nil, 46, 48, 47, nil, 49, 44, 45, 64, nil,
- nil, nil, nil, 60, 50, 70, nil, 61, nil, nil,
- nil, 62, 63, 146, 56, 29, 89, nil, 52, 90,
- 54, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, 146, 56, 29, 89,
- nil, 52, 90, 54, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, 146,
- 56, 29, 89, nil, 52, 90, 54, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- -116, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, 146, 56, 29, 89, nil, 52, 90, 288,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, nil, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, 146, 56, 29, 89, nil,
- 52, 90, 54, nil, nil, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, 146, 56,
- 29, 89, nil, 52, 90, 54, nil, nil, nil, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, nil, 61, nil, nil, nil, 62,
- 63, 146, 56, 29, 89, nil, 52, 90, 54, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, 146, 56, 29, 89, nil, 52,
- 90, 54, nil, nil, nil, 46, 48, 47, nil, 49,
- 44, 45, 64, nil, nil, nil, nil, 60, 50, 70,
- nil, 61, nil, nil, nil, 62, 63, 146, 56, 29,
- 89, nil, 52, 90, 54, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- 146, 56, 29, 89, nil, 52, 90, 54, nil, nil,
- nil, 46, 48, 47, nil, 49, 44, 45, 64, nil,
- nil, -116, nil, 60, 50, 70, nil, 61, nil, nil,
- nil, 62, 63, 146, 56, 29, 89, nil, 52, 90,
- 54, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, 146, 56, 29, 89,
- nil, 52, 90, 54, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, 146,
- 56, 29, 89, nil, 52, 90, 54, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- nil, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, nil, nil, 29, nil, nil, 52, 348, 54,
- 129, 130, 132, 127, 128, 131, 115, 116, 117, 121,
- 122, 123, 118, 119, 120, 124, 125, 126, nil, nil,
- nil, nil, 146, 56, nil, 89, nil, 29, 90, nil,
- 52, nil, 54, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, -116, nil, 60, 50, 70, 105, 61,
- nil, nil, nil, 62, 63, 146, 56, nil, 89, nil,
- nil, 90, nil, nil, nil, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, nil, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, 146, 56,
- 29, 89, nil, 52, 90, 288, nil, nil, nil, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, nil, 61, nil, nil, nil, 62,
- 63, 146, 56, 29, 89, nil, 52, 90, 54, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, 146, 56, 29, 89, nil, 52,
- 90, 54, nil, nil, nil, 46, 48, 47, nil, 49,
- 44, 45, 64, nil, nil, nil, nil, 60, 50, 70,
- nil, 61, nil, nil, nil, 62, 63, 146, 56, 29,
- 89, nil, 52, 90, 54, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- 146, 56, 29, 89, nil, 52, 90, 54, nil, nil,
- nil, 46, 48, 47, nil, 49, 44, 45, 64, nil,
- nil, nil, nil, 60, 50, 70, nil, 61, nil, nil,
- nil, 62, 63, 146, 56, 29, 89, nil, 52, 90,
- 54, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, 146, 56, 29, 89,
- nil, 52, 90, 54, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, 146,
- 56, 29, 89, nil, 52, 90, 54, nil, nil, nil,
- 46, 48, 47, nil, 49, 44, 45, 64, nil, nil,
- nil, nil, 60, 50, 70, nil, 61, nil, nil, nil,
- 62, 63, 146, 56, 29, 89, nil, 52, 90, 54,
- nil, nil, nil, 46, 48, 47, nil, 49, 44, 45,
- 64, nil, nil, nil, nil, 60, 50, 70, nil, 61,
- nil, nil, nil, 62, 63, 146, 56, 29, 89, nil,
- 52, 90, 54, nil, nil, nil, 46, 48, 47, nil,
- 49, 44, 45, 64, nil, nil, -116, nil, 60, 50,
- 70, nil, 61, nil, nil, nil, 62, 63, 146, 56,
- 29, 89, nil, 52, 90, 54, nil, nil, nil, 46,
- 48, 47, nil, 49, 44, 45, 64, nil, nil, nil,
- nil, 60, 50, 70, nil, 61, nil, nil, nil, 62,
- 63, 146, 56, 29, 89, nil, 52, 90, 54, nil,
- nil, nil, 46, 48, 47, nil, 49, 44, 45, 64,
- nil, nil, nil, nil, 60, 50, 70, nil, 61, nil,
- nil, nil, 62, 63, 146, 56, 29, 89, nil, 52,
- 90, 54, nil, nil, nil, 46, 48, 47, nil, 49,
- 44, 45, 64, nil, nil, nil, nil, 60, 50, 70,
- nil, 61, nil, nil, nil, 62, 63, 146, 56, 29,
- 89, nil, 52, 90, 54, nil, nil, nil, 46, 48,
- 47, nil, 49, 44, 45, 64, nil, nil, nil, nil,
- 60, 50, 70, nil, 61, nil, nil, nil, 62, 63,
- 146, 56, 29, 89, nil, 52, nil, 54, nil, nil,
- nil, 46, 48, 47, nil, 49, 44, 45, nil, nil,
- nil, nil, nil, 60, 50, 70, nil, 61, nil, nil,
- nil, 62, 63, 146, 56, 29, 89, nil, 52, nil,
- 54, nil, nil, nil, 46, 48, 47, nil, 49, 44,
- 45, 64, nil, nil, nil, nil, 60, 50, 70, nil,
- 61, nil, nil, nil, 62, 63, 146, 56, 188, 89,
- nil, 52, nil, nil, nil, nil, nil, 46, 48, 47,
- nil, 49, 44, 45, 64, nil, nil, nil, nil, 60,
- 50, 70, nil, 61, nil, nil, nil, 62, 63, nil,
- nil, 188, nil, nil, 52, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 211, nil, nil, nil, nil, nil, 129, 130, 132, 127,
- 128, 131, nil, nil, 188, nil, nil, 52, 129, 130,
- 132, 127, 128, 131, 115, 116, 117, 121, 122, 123,
- 118, 119, 120, 124, 125, 126, 102, 104, 103, 109,
- 111, 110, 112, 114, 113, 106, 108, 107, 133, 134,
- 101, 100, 137, 211, 105, nil, nil, nil, nil, 129,
- 130, 132, 127, 128, 131, nil, 105, nil, nil, nil,
- nil, 129, 130, 132, 127, 128, 131, 115, 116, 117,
- 121, 122, 123, 118, 119, 120, 124, 125, 126, 102,
- 104, 103, 109, 111, 110, 112, 114, 113, 106, 108,
- 107, 133, 134, 101, 100, 137, 211, 105, nil, nil,
- nil, nil, 129, 130, 132, 127, 128, 131, nil, 105,
- nil, nil, nil, nil, 129, 130, 132, 127, 128, 131,
- 115, 116, 117, 121, 122, 123, 118, 119, 120, 124,
- 125, 126, 102, 104, 103, 109, 111, 110, 112, 114,
- 113, 106, 108, 107, 133, 134, 101, 100, 137, 211,
- 105, nil, nil, nil, nil, 129, 130, 132, 127, 128,
- 131, nil, 105, nil, nil, nil, nil, 129, 130, 132,
- 127, 128, 131, 115, 116, 117, 121, 122, 123, 118,
- 119, 120, 124, 125, 126, 102, 104, 103, 109, 111,
- 110, 112, 114, 113, 106, 108, 107, 133, 134, 101,
- 100, 137, 211, 105, nil, nil, nil, nil, 129, 130,
- 132, 127, 128, 131, nil, 105, nil, nil, nil, nil,
- 129, 130, 132, 127, 128, 131, 115, 116, 117, 121,
- 122, 123, 118, 119, 120, 124, 125, 126, 102, 104,
- 103, 109, 111, 110, 112, 114, 113, 106, 108, 107,
- 133, 134, 101, 100, 137, 455, 105, nil, nil, nil,
- nil, 129, 130, 132, 127, 128, 131, nil, 105, nil,
- nil, nil, nil, 129, 130, 132, 127, 128, 131, 115,
- 116, 117, 121, 122, 123, 118, 119, 120, 124, 125,
- 126, 102, 104, 103, 109, 111, 110, 112, 114, 113,
- 106, 108, 107, 133, 134, 101, 100, 137, 460, 105,
- nil, nil, nil, 129, 130, 132, 127, 128, 131, nil,
- nil, 105, nil, nil, nil, nil, 129, 130, 132, 127,
- 128, 131, 115, 116, 117, 121, 122, 123, 118, 119,
- 120, 124, 125, 126, 102, 104, 103, 109, 111, 110,
- 112, 114, 113, 106, 108, 107, 133, 134, 101, 100,
- 137, 105, 129, 130, 132, 127, 128, 131, nil, nil,
- nil, nil, nil, nil, 105, 129, 130, 132, 127, 128,
- 131, 115, 116, 117, 121, 122, 123, 118, 119, 120,
- 124, 125, 126, 102, 104, 103, 109, 111, 110, 112,
- 114, 113, 106, 108, 107, 133, 134, 101, 100, 137,
- 105, nil, nil, nil, nil, nil, 266, 129, 130, 132,
- 127, 128, 131, 105, 129, 130, 132, 127, 128, 131,
- 115, 116, 117, 121, 122, 123, 118, 119, 120, 124,
- 125, 126, 102, 104, 103, 109, 111, 110, 112, 114,
- 113, 106, 108, 107, 133, 134, 101, 100, 137, nil,
- nil, nil, nil, nil, nil, 105, nil, nil, nil, nil,
- nil, nil, 105, 129, 130, 132, 127, 128, 131, 115,
- 116, 117, 121, 122, 123, 118, 119, 120, 124, 125,
- 126, 102, 104, 103, 109, 111, 110, 112, 114, 113,
- 106, 108, 107, 133, 134, 101, 100, 137, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 275, 105, 129, 130, 132, 127, 128, 131, 115, 116,
- 117, 121, 122, 123, 118, 119, 120, 124, 125, 126,
- 102, 104, 103, 109, 111, 110, 112, 114, 113, 106,
- 108, 107, 133, 134, 101, 100, 137, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 105, 129, 130, 132, 127, 128, 131, 115, 116, 117,
- 121, 122, 123, 118, 119, 120, 124, 125, 126, 102,
- 104, 103, 109, 111, 110, 112, 114, 113, 106, 108,
- 107, 133, 134, 101, 100, 137, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 105,
- 129, 130, 132, 127, 128, 131, 115, 116, 117, 121,
- 122, 123, 118, 119, 120, 124, 125, 126, 102, 104,
- 103, 109, 111, 110, 112, 114, 113, 106, 108, 107,
- 133, 134, 101, 100, 137, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 105, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, 102, 104, 103,
- 109, 111, 110, 112, 114, 113, 106, 108, 107, 133,
- 134, 101, 100, 137, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 105, 129, 130,
- 132, 127, 128, 131, 115, 116, 117, 121, 122, 123,
- 118, 119, 120, 124, 125, 126, 129, 130, 132, 127,
- 128, 131, 115, 116, 117, 121, 122, 123, 118, 119,
- 120, 124, 125, 126, 102, 104, 103, 109, 111, 110,
- 112, 114, 113, 106, 108, 107, 105, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 105, 129, 130, 132, 127, 128,
- 131, 115, 116, 117, 121, 122, 123, 118, 119, 120,
- 124, 125, 126, 102, 104, 103, 109, 111, 110, 112,
- 114, 113, 106, 108, 107, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 105, 129, 130, 132, 127, 128, 131,
- 115, 116, 117, 121, 122, 123, 118, 119, 120, 124,
- 125, 126, 102, 104, 103, 109, 111, 110, 112, 114,
- 113, 106, 108, 107, 133, 134, 101, 100, 137, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 105, 129, 130, 132, 127, 128, 131, 115,
- 116, 117, 121, 122, 123, 118, 119, 120, 124, 125,
- 126, 102, 104, 103, 109, 111, 110, 112, 114, 113,
- 106, 108, 107, 133, 134, 101, 100, 137, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 105, 129, 130, 132, 127, 128, 131, 115, 116,
- 117, 121, 122, 123, 118, 119, 120, 124, 125, 126,
- 102, 104, 103, 109, 111, 110, 112, 114, 113, 106,
- 108, 107, 133, 134, 101, 100, 137, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 337,
- 105, 129, 130, 132, 127, 128, 131, 115, 116, 117,
- 121, 122, 123, 118, 119, 120, 124, 125, 126, 102,
- 104, 103, 109, 111, 110, 112, 114, 113, 106, 108,
- 107, 133, 134, 101, 100, 137, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 340, nil, nil, 341, 105,
- 129, 130, 132, 127, 128, 131, 115, 116, 117, 121,
- 122, 123, 118, 119, 120, 124, 125, 126, 102, 104,
- 103, 109, 111, 110, 112, 114, 113, 106, 108, 107,
- 133, 134, 101, 100, 137, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 105, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, 102, 104, 103,
- 109, 111, 110, 112, 114, 113, 106, 108, 107, 133,
- 134, 101, 100, 137, nil, nil, nil, nil, nil, nil,
- 266, nil, nil, nil, nil, nil, nil, 105, 129, 130,
- 132, 127, 128, 131, 115, 116, 117, 121, 122, 123,
- 118, 119, 120, 124, 125, 126, 102, 104, 103, 109,
- 111, 110, 112, 114, 113, 106, 108, 107, 133, 134,
- 101, 100, 137, nil, nil, nil, nil, nil, nil, 360,
- nil, nil, nil, nil, nil, nil, 105, 129, 130, 132,
- 127, 128, 131, 115, 116, 117, 121, 122, 123, 118,
- 119, 120, 124, 125, 126, 102, 104, 103, 109, 111,
- 110, 112, 114, 113, 106, 108, 107, 133, 134, 101,
- 100, 137, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 105, 129, 130, 132, 127,
- 128, 131, 115, 116, 117, 121, 122, 123, 118, 119,
- 120, 124, 125, 126, 102, 104, 103, 109, 111, 110,
- 112, 114, 113, 106, 108, 107, 133, 134, 101, 100,
- 137, nil, nil, nil, nil, nil, nil, 360, nil, nil,
- nil, nil, nil, nil, 105, 129, 130, 132, 127, 128,
- 131, 115, 116, 117, 121, 122, 123, 118, 119, 120,
- 124, 125, 126, 102, 104, 103, 109, 111, 110, 112,
- 114, 113, 106, 108, 107, 133, 134, 101, 100, 137,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 105, 129, 130, 132, 127, 128, 131,
- 115, 116, 117, 121, 122, 123, 118, 119, 120, 124,
- 125, 126, 102, 104, 103, 109, 111, 110, 112, 114,
- 113, 106, 108, 107, 133, 134, 101, 100, 137, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 105, 129, 130, 132, 127, 128, 131, 115,
- 116, 117, 121, 122, 123, 118, 119, 120, 124, 125,
- 126, 102, 104, 103, 109, 111, 110, 112, 114, 113,
- 106, 108, 107, 133, 134, 101, 100, 137, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 105, 129, 130, 132, 127, 128, 131, 115, 116,
- 117, 121, 122, 123, 118, 119, 120, 124, 125, 126,
- 102, 104, 103, 109, 111, 110, 112, 114, 113, 106,
- 108, 107, 133, 134, 101, 100, 137, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 105, 129, 130, 132, 127, 128, 131, 115, 116, 117,
- 121, 122, 123, 118, 119, 120, 124, 125, 126, 102,
- 104, 103, 109, 111, 110, 112, 114, 113, 106, 108,
- 107, 133, 134, 101, 100, 137, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 396, nil, nil, 341, 105,
- 129, 130, 132, 127, 128, 131, 115, 116, 117, 121,
- 122, 123, 118, 119, 120, 124, 125, 126, 102, 104,
- 103, 109, 111, 110, 112, 114, 113, 106, 108, 107,
- 133, 134, 101, 100, 137, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 105, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, 102, 104, 103,
- 109, 111, 110, 112, 114, 113, 106, 108, 107, 133,
- 134, 101, 100, 137, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 399, nil, nil, nil, 105, 129, 130,
- 132, 127, 128, 131, 115, 116, 117, 121, 122, 123,
- 118, 119, 120, 124, 125, 126, 102, 104, 103, 109,
- 111, 110, 112, 114, 113, 106, 108, 107, 133, 134,
- 101, 100, 137, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 105, 129, 130, 132,
- 127, 128, 131, 115, 116, 117, 121, 122, 123, 118,
- 119, 120, 124, 125, 126, 102, 104, 103, 109, 111,
- 110, 112, 114, 113, 106, 108, 107, 133, 134, 101,
- 100, 137, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 105, 129, 130, 132, 127,
- 128, 131, 115, 116, 117, 121, 122, 123, 118, 119,
- 120, 124, 125, 126, 102, 104, 103, 109, 111, 110,
- 112, 114, 113, 106, 108, 107, 133, 134, 101, 100,
- 137, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 105, 129, 130, 132, 127, 128,
- 131, 115, 116, 117, 121, 122, 123, 118, 119, 120,
- 124, 125, 126, 102, 104, 103, 109, 111, 110, 112,
- 114, 113, 106, 108, 107, 133, 134, 101, 100, 137,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 105, 129, 130, 132, 127, 128, 131,
- 115, 116, 117, 121, 122, 123, 118, 119, 120, 124,
- 125, 126, 102, 104, 103, 109, 111, 110, 112, 114,
- 113, 106, 108, 107, 133, 134, 101, 100, 137, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 105, 129, 130, 132, 127, 128, 131, 115,
- 116, 117, 121, 122, 123, 118, 119, 120, 124, 125,
- 126, 102, 104, 103, 109, 111, 110, 112, 114, 113,
- 106, 108, 107, 133, 134, 101, 100, 137, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 105, 129, 130, 132, 127, 128, 131, 115, 116,
- 117, 121, 122, 123, 118, 119, 120, 124, 125, 126,
- 102, 104, 103, 109, 111, 110, 112, 114, 113, 106,
- 108, 107, 133, 134, 101, 100, 137, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 105, 129, 130, 132, 127, 128, 131, 115, 116, 117,
- 121, 122, 123, 118, 119, 120, 124, 125, 126, 102,
- 104, 103, 109, 111, 110, 112, 114, 113, 106, 108,
- 107, 133, 134, 101, 100, 137, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 105,
- 129, 130, 132, 127, 128, 131, 115, 116, 117, 121,
- 122, 123, 118, 119, 120, 124, 125, 126, 102, 104,
- 103, 109, 111, 110, 112, 114, 113, 106, 108, 107,
- 133, 134, 101, 100, 137, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 105, 129,
- 130, 132, 127, 128, 131, 115, 116, 117, 121, 122,
- 123, 118, 119, 120, 124, 125, 126, 102, 104, 103,
- 109, 111, 110, 112, 114, 113, 106, 108, 107, 133,
- 134, 101, 100, 137, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 105 ]
-
-racc_action_check = [
- 22, 143, 74, 143, 22, 333, 376, 376, 182, 182,
- 370, 369, 433, 157, 57, 57, 74, 57, 155, 182,
- 157, 155, 369, 155, 3, 57, 57, 57, 93, 57,
- 57, 57, 333, 370, 376, 433, 330, 57, 57, 57,
- 202, 57, 330, 330, 202, 57, 57, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 57, 0, 3, 57, 332, 0, 93, 0,
- 0, 0, 0, 0, 376, 22, 0, 454, 0, 0,
- 287, 287, 0, 0, 0, 0, 0, 461, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 55, 0, 0, 0, 0, 0,
- 298, 466, 1, 0, 0, 298, 59, 59, 283, 283,
- 283, 283, 447, 283, 451, 464, 332, 59, 283, 283,
- 40, 40, 210, 447, 19, 451, 464, 454, 210, 181,
- 181, 287, 287, 175, 72, 72, 72, 461, 23, 200,
- 0, 213, 0, 0, 2, 0, 55, 277, 2, 161,
- 2, 2, 2, 2, 2, 162, 278, 2, 284, 2,
- 2, 466, 59, 2, 2, 2, 2, 2, 286, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 175, 2, 2, 2, 2,
- 2, 200, 86, 213, 2, 2, 161, 313, 266, 277,
- 314, 161, 162, 304, 360, 304, 24, 162, 278, 284,
- 284, 186, 186, 186, 138, 138, 138, 138, 27, 286,
- 286, 8, 138, 8, 8, 8, 403, 430, 73, 73,
- 73, 2, 32, 2, 2, 94, 2, 315, 35, 94,
- 86, 94, 94, 94, 94, 94, 285, 266, 94, 313,
- 94, 94, 314, 360, 94, 94, 94, 94, 94, 186,
- 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
- 94, 94, 94, 94, 94, 403, 430, 94, 94, 94,
- 94, 94, 281, 281, 315, 94, 94, 285, 285, 285,
- 285, 43, 187, 187, 187, 282, 282, 285, 285, 410,
- 70, 410, 222, 222, 222, 222, 222, 222, 222, 222,
- 222, 222, 222, 222, 222, 222, 222, 222, 222, 222,
- 290, 290, 94, 87, 94, 94, 95, 94, 387, 387,
- 95, 88, 95, 95, 95, 95, 95, 33, 89, 95,
- 187, 95, 95, 416, 416, 95, 95, 95, 95, 95,
- 222, 95, 95, 95, 95, 90, 95, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 92, 95, 95,
- 95, 95, 95, 96, 97, 203, 95, 95, 33, 33,
- 33, 33, 31, 31, 31, 31, 331, 31, 331, 331,
- 386, 331, 386, 386, 140, 386, 42, 42, 42, 42,
- 141, 203, 66, 66, 66, 66, 146, 235, 235, 235,
- 235, 235, 235, 95, 148, 150, 95, 151, 95, 203,
- 203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 203, 203, 203, 203, 203, 203,
- 203, 203, 203, 203, 204, 235, 154, 160, 166, 169,
- 170, 174, 178, 183, 184, 185, 189, 203, 199, 207,
- 208, 209, 212, 249, 250, 252, 260, 268, 293, 297,
- 204, 299, 300, 301, 305, 236, 236, 236, 236, 236,
- 236, 237, 237, 237, 237, 237, 237, 312, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 236, 211, 247, 247, 247, 211, 237,
- 211, 211, 211, 211, 211, 318, 204, 211, 322, 211,
- 211, 324, 325, 211, 211, 211, 211, 211, 334, 211,
- 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
- 211, 211, 211, 211, 211, 335, 211, 211, 211, 211,
- 211, 336, 339, 247, 211, 211, 344, 345, 220, 220,
- 220, 220, 220, 220, 220, 220, 220, 220, 220, 220,
- 220, 220, 220, 220, 220, 220, 220, 220, 220, 220,
- 220, 220, 220, 220, 220, 220, 220, 220, 220, 220,
- 220, 211, 353, 211, 211, 320, 211, 355, 356, 320,
- 320, 320, 320, 320, 320, 320, 220, 359, 320, 367,
- 320, 320, 368, 385, 320, 320, 320, 320, 320, 389,
- 320, 320, 320, 320, 320, 320, 320, 320, 320, 320,
- 320, 320, 320, 320, 320, 391, 392, 320, 320, 320,
- 320, 320, 404, 408, 411, 320, 320, 412, 417, 221,
- 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
- 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
- 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
- 221, 420, 320, 421, 320, 320, 438, 320, 422, 423,
- 438, 425, 438, 438, 438, 438, 438, 221, 428, 438,
- 429, 438, 438, 432, 434, 438, 438, 438, 438, 438,
- 445, 438, 438, 438, 438, 438, 438, 438, 438, 438,
- 438, 438, 438, 438, 438, 438, 448, 449, 438, 438,
- 438, 438, 438, 456, 457, 458, 438, 438, 459, 467,
- 223, 223, 223, 223, 223, 223, 223, 223, 223, 223,
- 223, 223, 223, 223, 223, 223, 223, 223, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 248,
- 248, 248, nil, 438, nil, 438, 438, 455, 438, nil,
- nil, 455, nil, 455, 455, 455, 455, 455, 223, nil,
- 455, nil, 455, 455, nil, nil, 455, 455, 455, 455,
- 455, nil, 455, 455, 455, 455, 455, 455, 455, 455,
- 455, 455, 455, 455, 455, 455, 455, 248, nil, 455,
- 455, 455, 455, 455, nil, nil, nil, 455, 455, nil,
- nil, 224, 224, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, 224, 224, 224, 224, 224, 224, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 251, 251, 251, nil, 455, nil, 455, 455, 460, 455,
- nil, nil, 460, nil, 460, 460, 460, 460, 460, 224,
- nil, 460, nil, 460, 460, nil, nil, 460, 460, 460,
- 460, 460, nil, 460, 460, 460, 460, 460, 460, 460,
- 460, 460, 460, 460, 460, 460, 460, 460, 251, nil,
- 460, 460, 460, 460, 460, nil, nil, nil, 460, 460,
- 375, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 460, nil, 460, 460, nil,
- 460, nil, 375, 375, 375, 375, 375, 375, 375, 375,
- 375, 375, 375, 375, 375, 375, 375, 375, 375, 375,
- 375, 375, 375, 375, 375, 375, 375, 375, 375, 375,
- 375, 375, 375, 375, 375, 375, 375, 378, nil, nil,
- nil, nil, nil, nil, nil, nil, 139, 139, nil, 139,
- 375, nil, 139, nil, nil, nil, nil, 139, 139, 139,
- nil, 139, 139, 139, 139, nil, nil, nil, nil, 139,
- 139, 139, nil, 139, nil, nil, nil, 139, 139, 378,
- 378, 378, 378, 378, 378, 378, 378, 378, 378, 378,
- 378, 378, 378, 378, 378, 378, 378, 378, 378, 378,
- 378, 378, 378, 378, 378, 378, 378, 378, 378, 378,
- 378, 378, 378, 378, 139, nil, nil, 139, nil, 139,
- nil, 139, 258, 258, nil, 258, nil, 378, 258, nil,
- nil, nil, nil, 258, 258, 258, nil, 258, 258, 258,
- 258, nil, nil, nil, nil, 258, 258, 258, nil, 258,
- nil, nil, nil, 258, 258, 58, 58, 58, nil, 58,
- nil, nil, 58, nil, nil, nil, nil, 58, 58, 58,
- nil, 58, 58, 58, 58, nil, nil, 58, nil, 58,
- 58, 58, nil, 58, nil, nil, nil, 58, 58, nil,
- 258, nil, nil, 258, nil, 258, nil, 258, nil, 226,
- 226, 226, 226, 226, 226, 226, 226, 226, 226, 226,
- 226, 226, 226, 226, 226, 226, 226, nil, 147, 147,
- 147, nil, 147, nil, 58, 147, nil, 58, nil, 58,
- 147, 147, 147, nil, 147, 147, 147, 147, nil, nil,
- nil, nil, 147, 147, 147, nil, 147, 226, nil, nil,
- 147, 147, 165, 165, 165, nil, 165, nil, nil, 165,
- nil, nil, nil, nil, 165, 165, 165, nil, 165, 165,
- 165, 165, nil, nil, nil, nil, 165, 165, 165, nil,
- 165, nil, nil, nil, 165, 165, nil, 147, 147, nil,
- 147, nil, 147, nil, nil, 227, 227, 227, 227, 227,
- 227, 227, 227, 227, 227, 227, 227, 227, 227, 227,
- 227, 227, 227, nil, nil, nil, 171, 171, 171, nil,
- 171, 165, 165, 171, 165, nil, 165, nil, 171, 171,
- 171, nil, 171, 171, 171, 171, nil, nil, nil, nil,
- 171, 171, 171, 227, 171, nil, nil, nil, 171, 171,
- 176, 176, 176, nil, 176, nil, nil, 176, nil, nil,
- nil, nil, 176, 176, 176, nil, 176, 176, 176, 176,
- nil, nil, nil, nil, 176, 176, 176, nil, 176, nil,
- nil, nil, 176, 176, nil, 171, 171, nil, 171, nil,
- 171, nil, nil, 228, 228, 228, 228, 228, 228, 228,
- 228, 228, 228, 228, 228, 228, 228, 228, 228, 228,
- 228, nil, nil, nil, 215, 215, 215, nil, 215, 176,
- 176, 215, 176, nil, 176, nil, 215, 215, 215, nil,
- 215, 215, 215, 215, nil, nil, nil, nil, 215, 215,
- 215, 228, 215, nil, nil, nil, 215, 215, 267, 267,
- 267, nil, 267, nil, nil, 267, nil, nil, nil, nil,
- 267, 267, 267, nil, 267, 267, 267, 267, nil, nil,
- nil, nil, 267, 267, 267, nil, 267, nil, nil, nil,
- 267, 267, nil, 215, 215, nil, 215, nil, 215, nil,
- nil, 229, 229, 229, 229, 229, 229, 229, 229, 229,
- 229, 229, 229, 229, 229, 229, 229, 229, 229, nil,
- nil, nil, nil, 274, 274, nil, 274, 267, 267, 274,
- 267, nil, 267, nil, 274, 274, 274, nil, 274, 274,
- 274, 274, nil, nil, nil, nil, 274, 274, 274, 229,
- 274, nil, nil, nil, 274, 274, 276, 276, 276, nil,
- 276, nil, nil, 276, nil, nil, nil, nil, 276, 276,
- 276, nil, 276, 276, 276, 276, nil, nil, nil, nil,
- 276, 276, 276, nil, 276, nil, nil, nil, 276, 276,
- nil, 274, nil, nil, 274, nil, 274, 274, nil, 230,
- 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
- 230, 230, 230, 230, 230, 230, 230, nil, nil, nil,
- 295, 295, 295, nil, 295, 276, 276, 295, 276, nil,
- 276, nil, 295, 295, 295, nil, 295, 295, 295, 295,
- nil, nil, nil, nil, 295, 295, 295, 230, 295, nil,
- nil, nil, 295, 295, 302, 302, 302, nil, 302, nil,
- nil, 302, nil, nil, nil, nil, 302, 302, 302, nil,
- 302, 302, 302, 302, nil, nil, nil, nil, 302, 302,
- 302, nil, 302, nil, nil, nil, 302, 302, nil, 295,
- 295, nil, 295, nil, 295, nil, 231, 231, 231, 231,
- 231, 231, 231, 231, 231, 231, 231, 231, 231, 231,
- 231, 231, 231, 231, nil, nil, nil, 362, 362, 362,
- nil, 362, nil, 302, 362, nil, 302, nil, 302, 362,
- 362, 362, nil, 362, 362, 362, 362, nil, nil, nil,
- nil, 362, 362, 362, 231, 362, nil, nil, nil, 362,
- 362, 393, 393, 393, nil, 393, nil, nil, 393, nil,
- nil, nil, nil, 393, 393, 393, nil, 393, 393, 393,
- 393, nil, nil, nil, nil, 393, 393, 393, nil, 393,
- nil, nil, nil, 393, 393, nil, 362, 362, nil, 362,
- nil, 362, nil, nil, 232, 232, 232, 232, 232, 232,
- 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
- 232, 232, nil, nil, nil, nil, 29, 29, nil, 29,
- 393, 393, 29, 393, nil, 393, nil, 29, 29, 29,
- nil, 29, 29, 29, 29, nil, nil, nil, nil, 29,
- 29, 29, 232, 29, nil, nil, nil, 29, 29, 52,
- 52, nil, 52, nil, nil, 52, nil, nil, nil, nil,
- 52, 52, 52, nil, 52, 52, 52, 52, nil, nil,
- 52, nil, 52, 52, 52, nil, 52, nil, nil, nil,
- 52, 52, 54, 54, 29, 54, nil, 29, 54, 29,
- nil, nil, nil, 54, 54, 54, nil, 54, 54, 54,
- 54, nil, nil, 54, nil, 54, 54, 54, nil, 54,
- nil, nil, nil, 54, 54, 56, 56, 52, 56, nil,
- 52, 56, 52, nil, nil, 56, 56, 56, 56, nil,
- 56, 56, 56, 56, nil, nil, nil, nil, 56, 56,
- 56, nil, 56, nil, nil, nil, 56, 56, 61, 61,
- 54, 61, nil, 54, 61, 54, nil, nil, nil, 61,
- 61, 61, nil, 61, 61, 61, 61, nil, nil, nil,
- nil, 61, 61, 61, nil, 61, nil, nil, nil, 61,
- 61, 62, 62, 56, 62, nil, 56, 62, 56, nil,
- nil, nil, 62, 62, 62, nil, 62, 62, 62, 62,
- nil, nil, nil, nil, 62, 62, 62, nil, 62, nil,
- nil, nil, 62, 62, 63, 63, 61, 63, nil, 61,
- 63, 61, nil, nil, nil, 63, 63, 63, nil, 63,
- 63, 63, 63, nil, nil, nil, nil, 63, 63, 63,
- nil, 63, nil, nil, nil, 63, 63, 78, 78, 62,
- 78, nil, 62, 78, 62, nil, nil, nil, 78, 78,
- 78, nil, 78, 78, 78, 78, nil, nil, 78, nil,
- 78, 78, 78, nil, 78, nil, nil, nil, 78, 78,
- 80, 80, 63, 80, nil, 63, 80, 63, nil, nil,
- nil, 80, 80, 80, nil, 80, 80, 80, 80, nil,
- nil, nil, nil, 80, 80, 80, nil, 80, nil, nil,
- nil, 80, 80, 81, 81, 78, 81, nil, 78, 81,
- 78, nil, nil, nil, 81, 81, 81, nil, 81, 81,
- 81, 81, nil, nil, nil, nil, 81, 81, 81, nil,
- 81, nil, nil, nil, 81, 81, 82, 82, 80, 82,
- nil, 80, 82, 80, nil, nil, nil, 82, 82, 82,
- nil, 82, 82, 82, 82, nil, nil, nil, nil, 82,
- 82, 82, nil, 82, nil, nil, nil, 82, 82, 85,
- 85, 81, 85, nil, 81, 85, 81, nil, nil, nil,
- 85, 85, 85, nil, 85, 85, 85, 85, nil, nil,
- nil, nil, 85, 85, 85, nil, 85, nil, nil, nil,
- 85, 85, 100, 100, 82, 100, nil, 82, 100, 82,
- nil, nil, nil, 100, 100, 100, nil, 100, 100, 100,
- 100, nil, nil, nil, nil, 100, 100, 100, nil, 100,
- nil, nil, nil, 100, 100, 101, 101, 85, 101, nil,
- 85, 101, 85, nil, nil, nil, 101, 101, 101, nil,
- 101, 101, 101, 101, nil, nil, nil, nil, 101, 101,
- 101, nil, 101, nil, nil, nil, 101, 101, 102, 102,
- 100, 102, nil, 100, 102, 100, nil, nil, nil, 102,
- 102, 102, nil, 102, 102, 102, 102, nil, nil, nil,
- nil, 102, 102, 102, nil, 102, nil, nil, nil, 102,
- 102, 103, 103, 101, 103, nil, 101, 103, 101, nil,
- nil, nil, 103, 103, 103, nil, 103, 103, 103, 103,
- nil, nil, nil, nil, 103, 103, 103, nil, 103, nil,
- nil, nil, 103, 103, 104, 104, 102, 104, nil, 102,
- 104, 102, nil, nil, nil, 104, 104, 104, nil, 104,
- 104, 104, 104, nil, nil, nil, nil, 104, 104, 104,
- nil, 104, nil, nil, nil, 104, 104, 105, 105, 103,
- 105, nil, 103, 105, 103, nil, nil, nil, 105, 105,
- 105, nil, 105, 105, 105, 105, nil, nil, nil, nil,
- 105, 105, 105, nil, 105, nil, nil, nil, 105, 105,
- 106, 106, 104, 106, nil, 104, 106, 104, nil, nil,
- nil, 106, 106, 106, nil, 106, 106, 106, 106, nil,
- nil, nil, nil, 106, 106, 106, nil, 106, nil, nil,
- nil, 106, 106, 107, 107, 105, 107, nil, 105, 107,
- 105, nil, nil, nil, 107, 107, 107, nil, 107, 107,
- 107, 107, nil, nil, nil, nil, 107, 107, 107, nil,
- 107, nil, nil, nil, 107, 107, 108, 108, 106, 108,
- nil, 106, 108, 106, nil, nil, nil, 108, 108, 108,
- nil, 108, 108, 108, 108, nil, nil, nil, nil, 108,
- 108, 108, nil, 108, nil, nil, nil, 108, 108, 109,
- 109, 107, 109, nil, 107, 109, 107, nil, nil, nil,
- 109, 109, 109, nil, 109, 109, 109, 109, nil, nil,
- nil, nil, 109, 109, 109, nil, 109, nil, nil, nil,
- 109, 109, 110, 110, 108, 110, nil, 108, 110, 108,
- nil, nil, nil, 110, 110, 110, nil, 110, 110, 110,
- 110, nil, nil, nil, nil, 110, 110, 110, nil, 110,
- nil, nil, nil, 110, 110, 111, 111, 109, 111, nil,
- 109, 111, 109, nil, nil, nil, 111, 111, 111, nil,
- 111, 111, 111, 111, nil, nil, nil, nil, 111, 111,
- 111, nil, 111, nil, nil, nil, 111, 111, 112, 112,
- 110, 112, nil, 110, 112, 110, nil, nil, nil, 112,
- 112, 112, nil, 112, 112, 112, 112, nil, nil, nil,
- nil, 112, 112, 112, nil, 112, nil, nil, nil, 112,
- 112, 113, 113, 111, 113, nil, 111, 113, 111, nil,
- nil, nil, 113, 113, 113, nil, 113, 113, 113, 113,
- nil, nil, nil, nil, 113, 113, 113, nil, 113, nil,
- nil, nil, 113, 113, 114, 114, 112, 114, nil, 112,
- 114, 112, nil, nil, nil, 114, 114, 114, nil, 114,
- 114, 114, 114, nil, nil, nil, nil, 114, 114, 114,
- nil, 114, nil, nil, nil, 114, 114, 115, 115, 113,
- 115, nil, 113, 115, 113, nil, nil, nil, 115, 115,
- 115, nil, 115, 115, 115, 115, nil, nil, nil, nil,
- 115, 115, 115, nil, 115, nil, nil, nil, 115, 115,
- 116, 116, 114, 116, nil, 114, 116, 114, nil, nil,
- nil, 116, 116, 116, nil, 116, 116, 116, 116, nil,
- nil, nil, nil, 116, 116, 116, nil, 116, nil, nil,
- nil, 116, 116, 117, 117, 115, 117, nil, 115, 117,
- 115, nil, nil, nil, 117, 117, 117, nil, 117, 117,
- 117, 117, nil, nil, nil, nil, 117, 117, 117, nil,
- 117, nil, nil, nil, 117, 117, 118, 118, 116, 118,
- nil, 116, 118, 116, nil, nil, nil, 118, 118, 118,
- nil, 118, 118, 118, 118, nil, nil, nil, nil, 118,
- 118, 118, nil, 118, nil, nil, nil, 118, 118, 119,
- 119, 117, 119, nil, 117, 119, 117, nil, nil, nil,
- 119, 119, 119, nil, 119, 119, 119, 119, nil, nil,
- nil, nil, 119, 119, 119, nil, 119, nil, nil, nil,
- 119, 119, 120, 120, 118, 120, nil, 118, 120, 118,
- nil, nil, nil, 120, 120, 120, nil, 120, 120, 120,
- 120, nil, nil, nil, nil, 120, 120, 120, nil, 120,
- nil, nil, nil, 120, 120, 121, 121, 119, 121, nil,
- 119, 121, 119, nil, nil, nil, 121, 121, 121, nil,
- 121, 121, 121, 121, nil, nil, nil, nil, 121, 121,
- 121, nil, 121, nil, nil, nil, 121, 121, 122, 122,
- 120, 122, nil, 120, 122, 120, nil, nil, nil, 122,
- 122, 122, nil, 122, 122, 122, 122, nil, nil, nil,
- nil, 122, 122, 122, nil, 122, nil, nil, nil, 122,
- 122, 123, 123, 121, 123, nil, 121, 123, 121, nil,
- nil, nil, 123, 123, 123, nil, 123, 123, 123, 123,
- nil, nil, nil, nil, 123, 123, 123, nil, 123, nil,
- nil, nil, 123, 123, 124, 124, 122, 124, nil, 122,
- 124, 122, nil, nil, nil, 124, 124, 124, nil, 124,
- 124, 124, 124, nil, nil, nil, nil, 124, 124, 124,
- nil, 124, nil, nil, nil, 124, 124, 125, 125, 123,
- 125, nil, 123, 125, 123, nil, nil, nil, 125, 125,
- 125, nil, 125, 125, 125, 125, nil, nil, nil, nil,
- 125, 125, 125, nil, 125, nil, nil, nil, 125, 125,
- 126, 126, 124, 126, nil, 124, 126, 124, nil, nil,
- nil, 126, 126, 126, nil, 126, 126, 126, 126, nil,
- nil, nil, nil, 126, 126, 126, nil, 126, nil, nil,
- nil, 126, 126, 127, 127, 125, 127, nil, 125, 127,
- 125, nil, nil, nil, 127, 127, 127, nil, 127, 127,
- 127, 127, nil, nil, nil, nil, 127, 127, 127, nil,
- 127, nil, nil, nil, 127, 127, 128, 128, 126, 128,
- nil, 126, 128, 126, nil, nil, nil, 128, 128, 128,
- nil, 128, 128, 128, 128, nil, nil, nil, nil, 128,
- 128, 128, nil, 128, nil, nil, nil, 128, 128, 129,
- 129, 127, 129, nil, 127, 129, 127, nil, nil, nil,
- 129, 129, 129, nil, 129, 129, 129, 129, nil, nil,
- nil, nil, 129, 129, 129, nil, 129, nil, nil, nil,
- 129, 129, 130, 130, 128, 130, nil, 128, 130, 128,
- nil, nil, nil, 130, 130, 130, nil, 130, 130, 130,
- 130, nil, nil, nil, nil, 130, 130, 130, nil, 130,
- nil, nil, nil, 130, 130, 131, 131, 129, 131, nil,
- 129, 131, 129, nil, nil, nil, 131, 131, 131, nil,
- 131, 131, 131, 131, nil, nil, nil, nil, 131, 131,
- 131, nil, 131, nil, nil, nil, 131, 131, 132, 132,
- 130, 132, nil, 130, 132, 130, nil, nil, nil, 132,
- 132, 132, nil, 132, 132, 132, 132, nil, nil, nil,
- nil, 132, 132, 132, nil, 132, nil, nil, nil, 132,
- 132, 133, 133, 131, 133, nil, 131, 133, 131, nil,
- nil, nil, 133, 133, 133, nil, 133, 133, 133, 133,
- nil, nil, nil, nil, 133, 133, 133, nil, 133, nil,
- nil, nil, 133, 133, 134, 134, 132, 134, nil, 132,
- 134, 132, nil, nil, nil, 134, 134, 134, nil, 134,
- 134, 134, 134, nil, nil, nil, nil, 134, 134, 134,
- nil, 134, nil, nil, nil, 134, 134, 135, 135, 133,
- 135, nil, 133, 135, 133, nil, nil, nil, 135, 135,
- 135, nil, 135, 135, 135, 135, nil, nil, nil, nil,
- 135, 135, 135, nil, 135, nil, nil, nil, 135, 135,
- 136, 136, 134, 136, nil, 134, 136, 134, nil, nil,
- nil, 136, 136, 136, nil, 136, 136, 136, 136, nil,
- nil, nil, nil, 136, 136, 136, nil, 136, nil, nil,
- nil, 136, 136, 137, 137, 135, 137, nil, 135, 137,
- 135, nil, nil, nil, 137, 137, 137, nil, 137, 137,
- 137, 137, nil, nil, nil, nil, 137, 137, 137, nil,
- 137, nil, nil, nil, 137, 137, 164, 164, 136, 164,
- nil, 136, 164, 136, nil, nil, nil, 164, 164, 164,
- nil, 164, 164, 164, 164, nil, nil, nil, nil, 164,
- 164, 164, nil, 164, nil, nil, nil, 164, 164, 173,
- 173, 137, 173, nil, 137, 173, 137, nil, nil, nil,
- 173, 173, 173, nil, 173, 173, 173, 173, nil, nil,
- 173, nil, 173, 173, 173, nil, 173, nil, nil, nil,
- 173, 173, 180, 180, 164, 180, nil, 164, 180, 164,
- nil, nil, nil, 180, 180, 180, nil, 180, 180, 180,
- 180, nil, nil, nil, nil, 180, 180, 180, nil, 180,
- nil, nil, nil, 180, 180, 188, 188, 173, 188, nil,
- 173, 188, 173, nil, nil, nil, 188, 188, 188, nil,
- 188, 188, 188, 188, nil, nil, nil, nil, 188, 188,
- 188, nil, 188, nil, nil, nil, 188, 188, 191, 191,
- 180, 191, nil, 180, 191, 180, nil, nil, nil, 191,
- 191, 191, nil, 191, 191, 191, 191, nil, nil, nil,
- nil, 191, 191, 191, nil, 191, nil, nil, nil, 191,
- 191, 192, 192, 188, 192, nil, 188, 192, 188, nil,
- nil, nil, 192, 192, 192, nil, 192, 192, 192, 192,
- nil, nil, nil, nil, 192, 192, 192, nil, 192, nil,
- nil, nil, 192, 192, 193, 193, 191, 193, nil, 191,
- 193, 191, nil, nil, nil, 193, 193, 193, nil, 193,
- 193, 193, 193, nil, nil, nil, nil, 193, 193, 193,
- nil, 193, nil, nil, nil, 193, 193, 194, 194, 192,
- 194, nil, 192, 194, 192, nil, nil, nil, 194, 194,
- 194, nil, 194, 194, 194, 194, nil, nil, nil, nil,
- 194, 194, 194, nil, 194, nil, nil, nil, 194, 194,
- 261, 261, 193, 261, nil, 193, 261, 193, nil, nil,
- nil, 261, 261, 261, nil, 261, 261, 261, 261, nil,
- nil, 261, nil, 261, 261, 261, nil, 261, nil, nil,
- nil, 261, 261, 270, 270, 194, 270, nil, 194, 270,
- 194, nil, nil, nil, 270, 270, 270, nil, 270, 270,
- 270, 270, nil, nil, nil, nil, 270, 270, 270, nil,
- 270, nil, nil, nil, 270, 270, 272, 272, 261, 272,
- nil, 261, 272, 261, nil, nil, nil, 272, 272, 272,
- nil, 272, 272, 272, 272, nil, nil, nil, nil, 272,
- 272, 272, nil, 272, nil, nil, nil, 272, 272, 275,
- 275, 270, 275, nil, 270, 275, 270, nil, nil, nil,
- 275, 275, 275, nil, 275, 275, 275, 275, nil, nil,
- nil, nil, 275, 275, 275, nil, 275, nil, nil, nil,
- 275, 275, nil, nil, 272, nil, nil, 272, 272, 272,
- 233, 233, 233, 233, 233, 233, 233, 233, 233, 233,
- 233, 233, 233, 233, 233, 233, 233, 233, nil, nil,
- nil, nil, 288, 288, nil, 288, nil, 275, 288, nil,
- 275, nil, 275, 288, 288, 288, nil, 288, 288, 288,
- 288, nil, nil, 288, nil, 288, 288, 288, 233, 288,
- nil, nil, nil, 288, 288, 291, 291, nil, 291, nil,
- nil, 291, nil, nil, nil, nil, 291, 291, 291, nil,
- 291, 291, 291, 291, nil, nil, nil, nil, 291, 291,
- 291, nil, 291, nil, nil, nil, 291, 291, 294, 294,
- 288, 294, nil, 288, 294, 288, nil, nil, nil, 294,
- 294, 294, nil, 294, 294, 294, 294, nil, nil, nil,
- nil, 294, 294, 294, nil, 294, nil, nil, nil, 294,
- 294, 316, 316, 291, 316, nil, 291, 316, 291, nil,
- nil, nil, 316, 316, 316, nil, 316, 316, 316, 316,
- nil, nil, nil, nil, 316, 316, 316, nil, 316, nil,
- nil, nil, 316, 316, 317, 317, 294, 317, nil, 294,
- 317, 294, nil, nil, nil, 317, 317, 317, nil, 317,
- 317, 317, 317, nil, nil, nil, nil, 317, 317, 317,
- nil, 317, nil, nil, nil, 317, 317, 319, 319, 316,
- 319, nil, 316, 319, 316, nil, nil, nil, 319, 319,
- 319, nil, 319, 319, 319, 319, nil, nil, nil, nil,
- 319, 319, 319, nil, 319, nil, nil, nil, 319, 319,
- 323, 323, 317, 323, nil, 317, 323, 317, nil, nil,
- nil, 323, 323, 323, nil, 323, 323, 323, 323, nil,
- nil, nil, nil, 323, 323, 323, nil, 323, nil, nil,
- nil, 323, 323, 326, 326, 319, 326, nil, 319, 326,
- 319, nil, nil, nil, 326, 326, 326, nil, 326, 326,
- 326, 326, nil, nil, nil, nil, 326, 326, 326, nil,
- 326, nil, nil, nil, 326, 326, 327, 327, 323, 327,
- nil, 323, 327, 323, nil, nil, nil, 327, 327, 327,
- nil, 327, 327, 327, 327, nil, nil, nil, nil, 327,
- 327, 327, nil, 327, nil, nil, nil, 327, 327, 328,
- 328, 326, 328, nil, 326, 328, 326, nil, nil, nil,
- 328, 328, 328, nil, 328, 328, 328, 328, nil, nil,
- nil, nil, 328, 328, 328, nil, 328, nil, nil, nil,
- 328, 328, 337, 337, 327, 337, nil, 327, 337, 327,
- nil, nil, nil, 337, 337, 337, nil, 337, 337, 337,
- 337, nil, nil, nil, nil, 337, 337, 337, nil, 337,
- nil, nil, nil, 337, 337, 341, 341, 328, 341, nil,
- 328, 341, 328, nil, nil, nil, 341, 341, 341, nil,
- 341, 341, 341, 341, nil, nil, 341, nil, 341, 341,
- 341, nil, 341, nil, nil, nil, 341, 341, 365, 365,
- 337, 365, nil, 337, 365, 337, nil, nil, nil, 365,
- 365, 365, nil, 365, 365, 365, 365, nil, nil, nil,
- nil, 365, 365, 365, nil, 365, nil, nil, nil, 365,
- 365, 418, 418, 341, 418, nil, 341, 418, 341, nil,
- nil, nil, 418, 418, 418, nil, 418, 418, 418, 418,
- nil, nil, nil, nil, 418, 418, 418, nil, 418, nil,
- nil, nil, 418, 418, 435, 435, 365, 435, nil, 365,
- 435, 365, nil, nil, nil, 435, 435, 435, nil, 435,
- 435, 435, 435, nil, nil, nil, nil, 435, 435, 435,
- nil, 435, nil, nil, nil, 435, 435, 437, 437, 418,
- 437, nil, 418, 437, 418, nil, nil, nil, 437, 437,
- 437, nil, 437, 437, 437, 437, nil, nil, nil, nil,
- 437, 437, 437, nil, 437, nil, nil, nil, 437, 437,
- 64, 64, 435, 64, nil, 435, nil, 435, nil, nil,
- nil, 64, 64, 64, nil, 64, 64, 64, nil, nil,
- nil, nil, nil, 64, 64, 64, nil, 64, nil, nil,
- nil, 64, 64, 99, 99, 437, 99, nil, 437, nil,
- 437, nil, nil, nil, 99, 99, 99, nil, 99, 99,
- 99, 99, nil, nil, nil, nil, 99, 99, 99, nil,
- 99, nil, nil, nil, 99, 99, 142, 142, 64, 142,
- nil, 64, nil, nil, nil, nil, nil, 142, 142, 142,
- nil, 142, 142, 142, 142, nil, nil, nil, nil, 142,
- 142, 142, nil, 142, nil, nil, nil, 142, 142, nil,
- nil, 99, nil, nil, 99, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 205, nil, nil, nil, nil, nil, 238, 238, 238, 238,
- 238, 238, nil, nil, 142, nil, nil, 142, 205, 205,
- 205, 205, 205, 205, 205, 205, 205, 205, 205, 205,
- 205, 205, 205, 205, 205, 205, 205, 205, 205, 205,
- 205, 205, 205, 205, 205, 205, 205, 205, 205, 205,
- 205, 205, 205, 206, 238, nil, nil, nil, nil, 239,
- 239, 239, 239, 239, 239, nil, 205, nil, nil, nil,
- nil, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 381, 239, nil, nil,
- nil, nil, 240, 240, 240, 240, 240, 240, nil, 206,
- nil, nil, nil, nil, 381, 381, 381, 381, 381, 381,
- 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
- 381, 381, 381, 381, 381, 381, 381, 381, 381, 381,
- 381, 381, 381, 381, 381, 381, 381, 381, 381, 382,
- 240, nil, nil, nil, nil, 241, 241, 241, 241, 241,
- 241, nil, 381, nil, nil, nil, nil, 382, 382, 382,
- 382, 382, 382, 382, 382, 382, 382, 382, 382, 382,
- 382, 382, 382, 382, 382, 382, 382, 382, 382, 382,
- 382, 382, 382, 382, 382, 382, 382, 382, 382, 382,
- 382, 382, 383, 241, nil, nil, nil, nil, 242, 242,
- 242, 242, 242, 242, nil, 382, nil, nil, nil, nil,
- 383, 383, 383, 383, 383, 383, 383, 383, 383, 383,
- 383, 383, 383, 383, 383, 383, 383, 383, 383, 383,
- 383, 383, 383, 383, 383, 383, 383, 383, 383, 383,
- 383, 383, 383, 383, 383, 439, 242, nil, nil, nil,
- nil, 243, 243, 243, 243, 243, 243, nil, 383, nil,
- nil, nil, nil, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 439, 439,
- 439, 439, 439, 439, 439, 439, 439, 439, 453, 243,
- nil, nil, nil, 244, 244, 244, 244, 244, 244, nil,
- nil, 439, nil, nil, nil, nil, 453, 453, 453, 453,
- 453, 453, 453, 453, 453, 453, 453, 453, 453, 453,
- 453, 453, 453, 453, 453, 453, 453, 453, 453, 453,
- 453, 453, 453, 453, 453, 453, 453, 453, 453, 453,
- 453, 244, 245, 245, 245, 245, 245, 245, nil, nil,
- nil, nil, nil, nil, 453, 145, 145, 145, 145, 145,
- 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
- 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
- 145, 145, 145, 145, 145, 145, 145, 145, 145, 145,
- 245, nil, nil, nil, nil, nil, 145, 246, 246, 246,
- 246, 246, 246, 145, 156, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 156, nil,
- nil, nil, nil, nil, nil, 246, nil, nil, nil, nil,
- nil, nil, 156, 159, 159, 159, 159, 159, 159, 159,
- 159, 159, 159, 159, 159, 159, 159, 159, 159, 159,
- 159, 159, 159, 159, 159, 159, 159, 159, 159, 159,
- 159, 159, 159, 159, 159, 159, 159, 159, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 159, 159, 168, 168, 168, 168, 168, 168, 168, 168,
- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
- 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
- 168, 168, 168, 168, 168, 168, 168, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 168, 179, 179, 179, 179, 179, 179, 179, 179, 179,
- 179, 179, 179, 179, 179, 179, 179, 179, 179, 179,
- 179, 179, 179, 179, 179, 179, 179, 179, 179, 179,
- 179, 179, 179, 179, 179, 179, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 179,
- 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
- 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
- 201, 201, 201, 201, 201, 201, 201, 201, 201, 201,
- 201, 201, 201, 201, 201, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 201, 225,
- 225, 225, 225, 225, 225, 225, 225, 225, 225, 225,
- 225, 225, 225, 225, 225, 225, 225, 225, 225, 225,
- 225, 225, 225, 225, 225, 225, 225, 225, 225, 225,
- 225, 225, 225, 225, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 225, 234, 234,
- 234, 234, 234, 234, 234, 234, 234, 234, 234, 234,
- 234, 234, 234, 234, 234, 234, 253, 253, 253, 253,
- 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
- 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
- 253, 253, 253, 253, 253, 253, 234, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 253, 254, 254, 254, 254, 254,
- 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
- 254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
- 254, 254, 254, 254, 254, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 254, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 255, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 256, 257, 257, 257, 257, 257, 257, 257, 257,
- 257, 257, 257, 257, 257, 257, 257, 257, 257, 257,
- 257, 257, 257, 257, 257, 257, 257, 257, 257, 257,
- 257, 257, 257, 257, 257, 257, 257, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 257,
- 257, 259, 259, 259, 259, 259, 259, 259, 259, 259,
- 259, 259, 259, 259, 259, 259, 259, 259, 259, 259,
- 259, 259, 259, 259, 259, 259, 259, 259, 259, 259,
- 259, 259, 259, 259, 259, 259, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 259, nil, nil, 259, 259,
- 289, 289, 289, 289, 289, 289, 289, 289, 289, 289,
- 289, 289, 289, 289, 289, 289, 289, 289, 289, 289,
- 289, 289, 289, 289, 289, 289, 289, 289, 289, 289,
- 289, 289, 289, 289, 289, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 289, 292,
- 292, 292, 292, 292, 292, 292, 292, 292, 292, 292,
- 292, 292, 292, 292, 292, 292, 292, 292, 292, 292,
- 292, 292, 292, 292, 292, 292, 292, 292, 292, 292,
- 292, 292, 292, 292, nil, nil, nil, nil, nil, nil,
- 292, nil, nil, nil, nil, nil, nil, 292, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- 296, 296, 296, nil, nil, nil, nil, nil, nil, 296,
- nil, nil, nil, nil, nil, nil, 296, 303, 303, 303,
- 303, 303, 303, 303, 303, 303, 303, 303, 303, 303,
- 303, 303, 303, 303, 303, 303, 303, 303, 303, 303,
- 303, 303, 303, 303, 303, 303, 303, 303, 303, 303,
- 303, 303, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 303, 307, 307, 307, 307,
- 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
- 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
- 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
- 307, nil, nil, nil, nil, nil, nil, 307, nil, nil,
- nil, nil, nil, nil, 307, 308, 308, 308, 308, 308,
- 308, 308, 308, 308, 308, 308, 308, 308, 308, 308,
- 308, 308, 308, 308, 308, 308, 308, 308, 308, 308,
- 308, 308, 308, 308, 308, 308, 308, 308, 308, 308,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 308, 309, 309, 309, 309, 309, 309,
- 309, 309, 309, 309, 309, 309, 309, 309, 309, 309,
- 309, 309, 309, 309, 309, 309, 309, 309, 309, 309,
- 309, 309, 309, 309, 309, 309, 309, 309, 309, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 309, 310, 310, 310, 310, 310, 310, 310,
- 310, 310, 310, 310, 310, 310, 310, 310, 310, 310,
- 310, 310, 310, 310, 310, 310, 310, 310, 310, 310,
- 310, 310, 310, 310, 310, 310, 310, 310, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 310, 311, 311, 311, 311, 311, 311, 311, 311,
- 311, 311, 311, 311, 311, 311, 311, 311, 311, 311,
- 311, 311, 311, 311, 311, 311, 311, 311, 311, 311,
- 311, 311, 311, 311, 311, 311, 311, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 311, 338, 338, 338, 338, 338, 338, 338, 338, 338,
- 338, 338, 338, 338, 338, 338, 338, 338, 338, 338,
- 338, 338, 338, 338, 338, 338, 338, 338, 338, 338,
- 338, 338, 338, 338, 338, 338, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 338, nil, nil, 338, 338,
- 343, 343, 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 343, 347,
- 347, 347, 347, 347, 347, 347, 347, 347, 347, 347,
- 347, 347, 347, 347, 347, 347, 347, 347, 347, 347,
- 347, 347, 347, 347, 347, 347, 347, 347, 347, 347,
- 347, 347, 347, 347, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 347, nil, nil, nil, 347, 349, 349,
- 349, 349, 349, 349, 349, 349, 349, 349, 349, 349,
- 349, 349, 349, 349, 349, 349, 349, 349, 349, 349,
- 349, 349, 349, 349, 349, 349, 349, 349, 349, 349,
- 349, 349, 349, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 349, 352, 352, 352,
- 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
- 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
- 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
- 352, 352, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 352, 358, 358, 358, 358,
- 358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
- 358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
- 358, 358, 358, 358, 358, 358, 358, 358, 358, 358,
- 358, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 358, 364, 364, 364, 364, 364,
- 364, 364, 364, 364, 364, 364, 364, 364, 364, 364,
- 364, 364, 364, 364, 364, 364, 364, 364, 364, 364,
- 364, 364, 364, 364, 364, 364, 364, 364, 364, 364,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 364, 372, 372, 372, 372, 372, 372,
- 372, 372, 372, 372, 372, 372, 372, 372, 372, 372,
- 372, 372, 372, 372, 372, 372, 372, 372, 372, 372,
- 372, 372, 372, 372, 372, 372, 372, 372, 372, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 372, 373, 373, 373, 373, 373, 373, 373,
- 373, 373, 373, 373, 373, 373, 373, 373, 373, 373,
- 373, 373, 373, 373, 373, 373, 373, 373, 373, 373,
- 373, 373, 373, 373, 373, 373, 373, 373, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 373, 395, 395, 395, 395, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, 395, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 395, 398, 398, 398, 398, 398, 398, 398, 398, 398,
- 398, 398, 398, 398, 398, 398, 398, 398, 398, 398,
- 398, 398, 398, 398, 398, 398, 398, 398, 398, 398,
- 398, 398, 398, 398, 398, 398, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 398,
- 405, 405, 405, 405, 405, 405, 405, 405, 405, 405,
- 405, 405, 405, 405, 405, 405, 405, 405, 405, 405,
- 405, 405, 405, 405, 405, 405, 405, 405, 405, 405,
- 405, 405, 405, 405, 405, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 405, 452,
- 452, 452, 452, 452, 452, 452, 452, 452, 452, 452,
- 452, 452, 452, 452, 452, 452, 452, 452, 452, 452,
- 452, 452, 452, 452, 452, 452, 452, 452, 452, 452,
- 452, 452, 452, 452, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 452 ]
-
-racc_action_pointer = [
- 81, 132, 172, -7, nil, nil, nil, nil, 209, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 66,
- nil, nil, -2, 76, 182, nil, nil, 160, nil, 1805,
- nil, 328, 219, 324, nil, 225, nil, nil, nil, nil,
- 117, nil, 342, 229, nil, nil, nil, nil, nil, nil,
- nil, nil, 1838, nil, 1871, 82, 1904, -7, 1155, 103,
- nil, 1937, 1970, 2003, 4409, nil, 348, nil, nil, nil,
- 288, nil, 120, 214, -42, nil, nil, nil, 2036, nil,
- 2069, 2102, 2135, nil, nil, 2168, 178, 322, 317, 324,
- 296, nil, 397, -3, 263, 354, 311, 362, nil, 4442,
- 2201, 2234, 2267, 2300, 2333, 2366, 2399, 2432, 2465, 2498,
- 2531, 2564, 2597, 2630, 2663, 2696, 2729, 2762, 2795, 2828,
- 2861, 2894, 2927, 2960, 2993, 3026, 3059, 3092, 3125, 3158,
- 3191, 3224, 3257, 3290, 3323, 3356, 3389, 3422, 160, 1045,
- 381, 388, 4475, -89, nil, 4886, 347, 1218, 401, nil,
- 402, 404, nil, nil, 394, -70, 4935, -75, nil, 4984,
- 398, 137, 143, nil, 3455, 1252, 400, nil, 5033, 400,
- 447, 1316, nil, 3488, 399, 121, 1350, nil, 404, 5082,
- 3521, 126, -25, 405, 452, 398, 192, 273, 3554, 404,
- nil, 3587, 3620, 3653, 3686, nil, nil, nil, nil, 456,
- 127, 5131, 38, 400, 479, 4519, 4572, 483, 484, 485,
- 145, 562, 460, 129, nil, 1414, nil, nil, nil, nil,
- 569, 660, 283, 751, 842, 5180, 1170, 1266, 1364, 1462,
- 1560, 1657, 1755, 3831, 5229, 388, 466, 472, 4507, 4560,
- 4613, 4666, 4719, 4772, 4824, 4873, 4928, 516, 780, 406,
- 407, 871, 408, 5247, 5296, 5345, 5394, 5443, 1121, 5492,
- 413, 3719, nil, nil, nil, nil, 185, 1448, 417, nil,
- 3752, nil, 3785, nil, 1512, 3818, 1546, 135, 144, nil,
- nil, 218, 231, 54, 145, 233, 155, 67, 3881, 5541,
- 256, 3914, 5590, 418, 3947, 1610, 5639, 419, 42, 419,
- 423, 423, 1644, 5688, 145, 470, nil, 5737, 5786, 5835,
- 5884, 5933, 472, 185, 188, 225, 3980, 4013, 568, 4046,
- 653, nil, 571, 4079, 574, 575, 4112, 4145, 4178, nil,
- 29, 385, 55, -26, 499, 517, 521, 4211, 5982, 519,
- nil, 4244, nil, 6031, 573, 525, nil, 6080, nil, 6129,
- nil, nil, 6178, 562, nil, 562, 563, nil, 6227, 577,
- 191, nil, 1707, nil, 6276, 4277, nil, 627, 628, -20,
- -9, nil, 6325, 6374, nil, 973, 3, nil, 1050, nil,
- nil, 4625, 4678, 4731, nil, 642, 389, 325, nil, 648,
- nil, 688, 652, 1741, nil, 6423, nil, nil, 6472, nil,
- nil, nil, nil, 213, 612, 6521, nil, nil, 696, nil,
- 241, 614, 623, nil, nil, nil, 370, 677, 4310, nil,
- 734, 736, 741, 742, nil, 720, nil, nil, 716, 670,
- 214, nil, 721, -7, 722, 4343, nil, 4376, 744, 4784,
- nil, nil, nil, nil, nil, 739, nil, 111, 696, 703,
- nil, 113, 6570, 4837, 66, 835, 786, 787, 753, 791,
- 926, 76, nil, nil, 114, nil, 100, 792, nil ]
-
-racc_action_default = [
- -1, -259, -2, -3, -4, -8, -9, -10, -11, -12,
- -13, -14, -15, -16, -17, -18, -19, -20, -21, -22,
- -23, -24, -25, -26, -27, -29, -30, -31, -32, -116,
- -34, -35, -36, -37, -38, -39, -40, -49, -50, -51,
- -52, -53, -54, -55, -56, -57, -58, -59, -60, -63,
- -64, -65, -69, -72, -75, -259, -116, -116, -119, -116,
- -115, -116, -116, -116, -116, -168, -259, -177, -179, -180,
- -259, -184, -116, -116, -116, -200, -201, -202, -217, -219,
- -116, -116, -116, -228, -229, -116, -116, -259, -116, -116,
- -257, -258, -259, -7, -116, -6, -259, -259, -188, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -116, -116,
- -116, -116, -116, -116, -116, -116, -116, -116, -83, -116,
- -28, -259, -116, -26, -31, -259, -259, -116, -80, -94,
- -79, -81, -61, -62, -182, -259, -70, -259, -76, -259,
- -259, -183, -185, -189, -116, -116, -101, -102, -127, -35,
- -37, -116, -54, -69, -259, -259, -116, -107, -120, -123,
- -116, -111, -116, -109, -259, -164, -165, -166, -116, -259,
- -167, -116, -116, -116, -116, -181, -186, -187, -117, -259,
- -259, -218, -214, -259, -259, -259, -259, -259, -259, -259,
- -237, -245, -259, -259, -255, -116, 469, -5, -183, -170,
- -129, -130, -131, -132, -133, -134, -135, -136, -137, -138,
- -139, -140, -141, -142, -143, -144, -145, -146, -147, -148,
- -149, -150, -151, -152, -153, -154, -155, -156, -157, -158,
- -159, -160, -161, -162, -163, -222, -225, -259, -116, -259,
- -259, -93, -97, -96, -169, -41, -33, -116, -259, -95,
- -116, -67, -116, -73, -116, -116, -116, -259, -190, -191,
- -192, -29, -30, -35, -36, -37, -39, -52, -75, -259,
- -259, -116, -123, -259, -116, -116, -123, -259, -259, -83,
- -259, -259, -116, -124, -259, -116, -110, -259, -171, -172,
- -173, -174, -259, -204, -203, -207, -116, -116, -259, -116,
- -116, -246, -259, -116, -259, -259, -116, -116, -116, -234,
- -259, -259, -244, -259, -105, -122, -259, -116, -259, -259,
- -86, -91, -87, -92, -82, -84, -99, -259, -68, -71,
- -74, -77, -78, -259, -193, -259, -259, -100, -128, -259,
- -259, -103, -116, -106, -125, -116, -108, -259, -116, -259,
- -208, -205, -215, -216, -220, -259, -244, -223, -259, -227,
- -230, -259, -259, -259, -235, -259, -259, -243, -238, -259,
- -242, -259, -116, -116, -256, -226, -88, -89, -90, -66,
- -98, -194, -195, -114, -259, -126, -112, -118, -259, -206,
- -259, -259, -209, -210, -221, -247, -248, -259, -116, -224,
- -259, -259, -259, -259, -240, -259, -239, -253, -259, -259,
- -113, -196, -207, -259, -207, -116, -249, -116, -116, -259,
- -231, -232, -233, -236, -241, -259, -104, -259, -259, -211,
- -212, -259, -213, -259, -250, -116, -259, -259, -207, -259,
- -116, -251, -254, -197, -259, -198, -252, -259, -199 ]
-
-racc_goto_table = [
- 2, 154, 3, 95, 27, 169, 27, 96, 210, 98,
- 390, 170, 148, 281, 155, 151, 183, 369, 413, 260,
- 389, 415, 172, 318, 322, 1, 282, 217, 140, 356,
- 284, 286, 209, 351, 166, 214, 97, 200, 335, 336,
- 190, 207, 410, 202, 177, 330, 416, nil, nil, nil,
- nil, 208, nil, nil, 154, nil, nil, nil, nil, nil,
- nil, 436, nil, nil, nil, 390, nil, nil, nil, nil,
- nil, 96, 96, 196, 197, 425, nil, nil, nil, nil,
- nil, 450, nil, nil, nil, 175, nil, 184, nil, nil,
- nil, nil, 160, 95, nil, nil, 145, nil, 27, 27,
- 97, 97, 198, 219, nil, nil, 181, nil, nil, nil,
- nil, nil, 283, nil, 97, nil, 212, 213, 285, 156,
- nil, 159, nil, 168, nil, 179, 324, 325, 185, 186,
- 187, 162, 299, 268, 447, 298, 451, 281, 339, 304,
- 281, 280, nil, 291, nil, 201, 264, 203, 204, 205,
- 282, 293, 206, 282, 284, 286, nil, 284, 286, nil,
- 464, nil, 301, nil, nil, nil, nil, 220, 221, 222,
- 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
- 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
- 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
- 253, 254, 255, 256, 257, nil, 259, nil, nil, nil,
- 184, 287, 300, 332, 179, 27, nil, nil, nil, nil,
- nil, nil, nil, nil, 345, nil, nil, nil, nil, 181,
- nil, 289, 292, nil, nil, nil, 283, 315, 296, 283,
- 156, nil, 285, 292, nil, 285, 344, 303, nil, nil,
- 334, 162, 388, nil, 391, 307, nil, 280, 308, 309,
- 310, 311, 353, nil, 148, nil, 151, 291, nil, 355,
- nil, nil, nil, nil, nil, nil, 314, nil, nil, nil,
- nil, 359, 179, nil, nil, nil, nil, nil, nil, 314,
- 408, nil, nil, 280, nil, nil, nil, nil, nil, nil,
- nil, nil, 420, 421, 422, nil, 423, 424, nil, nil,
- 426, nil, nil, nil, nil, nil, nil, nil, 345, nil,
- nil, nil, 376, nil, 27, 338, nil, nil, 343, nil,
- nil, nil, 95, 367, 179, 287, 143, 347, 287, 349,
- 344, 159, 352, 179, nil, nil, 444, nil, 404, nil,
- nil, nil, nil, nil, nil, 159, nil, nil, 289, nil,
- nil, 358, 179, nil, 174, nil, 456, nil, 457, 364,
- nil, 189, 459, nil, nil, nil, 95, nil, 387, 429,
- nil, nil, nil, 372, 373, 467, 375, nil, nil, nil,
- 378, nil, nil, 381, 382, 383, 407, nil, nil, nil,
- nil, nil, nil, nil, 395, nil, 189, nil, 398, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 428, nil, nil, nil, nil, nil, nil, nil, nil, 179,
- nil, nil, 405, 387, nil, nil, nil, nil, nil, nil,
- 454, nil, 27, nil, nil, nil, nil, nil, nil, 189,
- nil, nil, nil, nil, 95, nil, nil, 461, nil, 27,
- 179, 95, 466, nil, 27, nil, 95, nil, nil, nil,
- nil, nil, 143, nil, nil, nil, nil, nil, 143, nil,
- nil, nil, nil, 143, nil, 439, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 143, nil, nil, nil, nil,
- nil, nil, 452, nil, 453 ]
-
-racc_goto_check = [
- 2, 50, 3, 2, 28, 31, 28, 42, 70, 64,
- 40, 33, 49, 26, 45, 49, 58, 69, 72, 52,
- 76, 77, 41, 74, 74, 1, 27, 4, 25, 37,
- 32, 35, 44, 48, 56, 57, 53, 59, 60, 61,
- 62, 65, 71, 73, 55, 75, 78, nil, nil, nil,
- nil, 41, nil, nil, 50, nil, nil, nil, nil, nil,
- nil, 77, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, 42, 42, 64, 64, 76, nil, nil, nil, nil,
- nil, 72, nil, nil, nil, 53, nil, 53, nil, nil,
- nil, nil, 54, 2, nil, nil, 22, nil, 28, 28,
- 53, 53, 53, 28, nil, nil, 38, nil, nil, nil,
- nil, nil, 31, nil, 53, nil, 53, 53, 33, 22,
- nil, 22, nil, 22, nil, 22, 70, 70, 22, 22,
- 22, 66, 50, 55, 69, 45, 69, 26, 52, 58,
- 26, 67, nil, 67, nil, 22, 28, 22, 22, 22,
- 27, 55, 22, 27, 32, 35, nil, 32, 35, nil,
- 69, nil, 55, nil, nil, nil, nil, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, nil, 22, nil, nil, nil,
- 53, 38, 54, 3, 22, 28, nil, nil, nil, nil,
- nil, nil, nil, nil, 50, nil, nil, nil, nil, 38,
- nil, 22, 22, nil, nil, nil, 31, 54, 22, 31,
- 22, nil, 33, 22, nil, 33, 49, 22, nil, nil,
- 54, 66, 70, nil, 70, 22, nil, 67, 22, 22,
- 22, 22, 55, nil, 49, nil, 49, 67, nil, 67,
- nil, nil, nil, nil, nil, nil, 66, nil, nil, nil,
- nil, 55, 22, nil, nil, nil, nil, nil, nil, 66,
- 70, nil, nil, 67, nil, nil, nil, nil, nil, nil,
- nil, nil, 70, 70, 70, nil, 70, 70, nil, nil,
- 70, nil, nil, nil, nil, nil, nil, nil, 50, nil,
- nil, nil, 3, nil, 28, 22, nil, nil, 22, nil,
- nil, nil, 2, 53, 22, 38, 23, 22, 38, 22,
- 49, 22, 22, 22, nil, nil, 70, nil, 55, nil,
- nil, nil, nil, nil, nil, 22, nil, nil, 22, nil,
- nil, 22, 22, nil, 23, nil, 70, nil, 70, 22,
- nil, 23, 70, nil, nil, nil, 2, nil, 38, 55,
- nil, nil, nil, 22, 22, 70, 22, nil, nil, nil,
- 22, nil, nil, 22, 22, 22, 53, nil, nil, nil,
- nil, nil, nil, nil, 22, nil, 23, nil, 22, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 53, nil, nil, nil, nil, nil, nil, nil, nil, 22,
- nil, nil, 22, 38, nil, nil, nil, nil, nil, nil,
- 3, nil, 28, nil, nil, nil, nil, nil, nil, 23,
- nil, nil, nil, nil, 2, nil, nil, 3, nil, 28,
- 22, 2, 3, nil, 28, nil, 2, nil, nil, nil,
- nil, nil, 23, nil, nil, nil, nil, nil, 23, nil,
- nil, nil, nil, 23, nil, 22, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 23, nil, nil, nil, nil,
- nil, nil, 22, nil, 22 ]
-
-racc_goto_pointer = [
- nil, 25, 0, 2, -68, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 67, 307, nil, 4, -151, -138, 4, nil,
- nil, -52, -134, -46, nil, -133, nil, -262, 47, nil,
- -321, -35, -1, nil, -54, -38, nil, nil, -241, -20,
- -42, nil, -120, 28, 37, -14, -22, -54, -43, -37,
- -177, -176, -24, nil, 1, -45, 76, -21, nil, -298,
- -79, -328, -352, -35, -180, -165, -311, -355, -330 ]
-
-racc_goto_default = [
- nil, nil, 94, 93, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, nil, 25, 26, 144, 28,
- 30, 31, 32, 33, 34, 35, 36, 290, 40, 39,
- 41, 42, 43, 51, 67, nil, 53, 157, 158, 150,
- 138, 68, nil, 55, nil, 297, nil, nil, nil, nil,
- 178, nil, 65, 66, 71, 69, 278, 163, 74, nil,
- 321, nil, nil, nil, nil, nil, nil, nil, nil ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 0, 99, :_reduce_1,
- 1, 99, :_reduce_2,
- 1, 99, :_reduce_3,
- 1, 101, :_reduce_4,
- 3, 101, :_reduce_5,
- 2, 101, :_reduce_6,
- 2, 101, :_reduce_7,
- 1, 102, :_reduce_8,
- 1, 102, :_reduce_9,
- 1, 102, :_reduce_10,
- 1, 102, :_reduce_11,
- 1, 102, :_reduce_12,
- 1, 102, :_reduce_13,
- 1, 102, :_reduce_14,
- 1, 102, :_reduce_15,
- 1, 102, :_reduce_16,
- 1, 102, :_reduce_17,
- 1, 102, :_reduce_18,
- 1, 102, :_reduce_19,
- 1, 102, :_reduce_20,
- 1, 102, :_reduce_21,
- 1, 102, :_reduce_22,
- 1, 102, :_reduce_23,
- 1, 102, :_reduce_24,
- 1, 102, :_reduce_25,
- 1, 120, :_reduce_26,
- 1, 120, :_reduce_27,
- 2, 120, :_reduce_28,
- 1, 120, :_reduce_29,
- 1, 120, :_reduce_30,
- 1, 120, :_reduce_31,
- 1, 120, :_reduce_32,
- 3, 120, :_reduce_33,
- 1, 121, :_reduce_34,
- 1, 121, :_reduce_35,
- 1, 121, :_reduce_36,
- 1, 121, :_reduce_37,
- 1, 121, :_reduce_38,
- 1, 121, :_reduce_39,
- 1, 121, :_reduce_40,
- 3, 121, :_reduce_41,
- 1, 135, :_reduce_42,
- 1, 135, :_reduce_43,
- 1, 135, :_reduce_44,
- 1, 135, :_reduce_45,
- 1, 135, :_reduce_46,
- 1, 135, :_reduce_47,
- 1, 135, :_reduce_48,
- 1, 100, :_reduce_49,
- 1, 100, :_reduce_50,
- 1, 132, :_reduce_51,
- 1, 132, :_reduce_52,
- 1, 132, :_reduce_53,
- 1, 132, :_reduce_54,
- 1, 132, :_reduce_55,
- 1, 132, :_reduce_56,
- 1, 132, :_reduce_57,
- 1, 137, :_reduce_58,
- 1, 136, :_reduce_59,
- 1, 136, :_reduce_60,
- 2, 136, :_reduce_61,
- 2, 136, :_reduce_62,
- 1, 138, :_reduce_63,
- 1, 140, :_reduce_64,
- 1, 139, :_reduce_65,
- 5, 142, :_reduce_66,
- 3, 141, :_reduce_67,
- 4, 141, :_reduce_68,
- 0, 143, :_reduce_69,
- 1, 143, :_reduce_70,
- 3, 143, :_reduce_71,
- 1, 122, :_reduce_72,
- 3, 144, :_reduce_73,
- 4, 144, :_reduce_74,
- 0, 145, :_reduce_75,
- 1, 145, :_reduce_76,
- 3, 145, :_reduce_77,
- 3, 146, :_reduce_78,
- 2, 129, :_reduce_79,
- 2, 129, :_reduce_80,
- 2, 129, :_reduce_81,
- 4, 129, :_reduce_82,
- 2, 130, :_reduce_83,
- 4, 130, :_reduce_84,
- 2, 149, :_reduce_85,
- 3, 148, :_reduce_86,
- 3, 148, :_reduce_87,
- 4, 148, :_reduce_88,
- 4, 148, :_reduce_89,
- 3, 150, :_reduce_90,
- 2, 150, :_reduce_91,
- 2, 150, :_reduce_92,
- 1, 150, :_reduce_93,
- 1, 147, :_reduce_94,
- 2, 147, :_reduce_95,
- 2, 123, :_reduce_96,
- 2, 123, :_reduce_97,
- 5, 133, :_reduce_98,
- 4, 133, :_reduce_99,
- 4, 133, :_reduce_100,
- 2, 133, :_reduce_101,
- 2, 133, :_reduce_102,
- 4, 133, :_reduce_103,
- 5, 155, :_reduce_104,
- 2, 155, :_reduce_105,
- 4, 115, :_reduce_106,
- 2, 115, :_reduce_107,
- 4, 116, :_reduce_108,
- 2, 116, :_reduce_109,
- 2, 156, :_reduce_110,
- 1, 156, :_reduce_111,
- 4, 156, :_reduce_112,
- 6, 103, :_reduce_113,
- 5, 103, :_reduce_114,
- 1, 151, :_reduce_115,
- 0, 151, :_reduce_116,
- 1, 157, :_reduce_117,
- 4, 157, :_reduce_118,
- 0, 153, :_reduce_119,
- 1, 153, :_reduce_120,
- 0, 159, :_reduce_121,
- 1, 159, :_reduce_122,
- 1, 158, :_reduce_123,
- 2, 158, :_reduce_124,
- 3, 158, :_reduce_125,
- 4, 158, :_reduce_126,
- 1, 154, :_reduce_127,
- 3, 154, :_reduce_128,
- 3, 124, :_reduce_129,
- 3, 124, :_reduce_130,
- 3, 124, :_reduce_131,
- 3, 124, :_reduce_132,
- 3, 124, :_reduce_133,
- 3, 124, :_reduce_134,
- 3, 124, :_reduce_135,
- 3, 124, :_reduce_136,
- 3, 124, :_reduce_137,
- 3, 124, :_reduce_138,
- 3, 124, :_reduce_139,
- 3, 124, :_reduce_140,
- 3, 124, :_reduce_141,
- 3, 124, :_reduce_142,
- 3, 124, :_reduce_143,
- 3, 124, :_reduce_144,
- 3, 124, :_reduce_145,
- 3, 124, :_reduce_146,
- 3, 124, :_reduce_147,
- 3, 124, :_reduce_148,
- 3, 124, :_reduce_149,
- 3, 124, :_reduce_150,
- 3, 124, :_reduce_151,
- 3, 124, :_reduce_152,
- 3, 124, :_reduce_153,
- 3, 124, :_reduce_154,
- 3, 124, :_reduce_155,
- 3, 124, :_reduce_156,
- 3, 124, :_reduce_157,
- 3, 124, :_reduce_158,
- 3, 124, :_reduce_159,
- 3, 124, :_reduce_160,
- 3, 124, :_reduce_161,
- 3, 124, :_reduce_162,
- 3, 124, :_reduce_163,
- 2, 128, :_reduce_164,
- 2, 128, :_reduce_165,
- 2, 128, :_reduce_166,
- 2, 126, :_reduce_167,
- 1, 126, :_reduce_168,
- 3, 117, :_reduce_169,
- 3, 117, :_reduce_170,
- 3, 160, :_reduce_171,
- 3, 160, :_reduce_172,
- 3, 160, :_reduce_173,
- 3, 160, :_reduce_174,
- 1, 161, :_reduce_175,
- 1, 161, :_reduce_176,
- 1, 161, :_reduce_177,
- 1, 161, :_reduce_178,
- 1, 161, :_reduce_179,
- 1, 162, :_reduce_180,
- 2, 162, :_reduce_181,
- 2, 162, :_reduce_182,
- 2, 163, :_reduce_183,
- 1, 131, :_reduce_184,
- 2, 131, :_reduce_185,
- 2, 106, :_reduce_186,
- 2, 106, :_reduce_187,
- 2, 106, :_reduce_188,
- 1, 164, :_reduce_189,
- 2, 164, :_reduce_190,
- 2, 164, :_reduce_191,
- 2, 164, :_reduce_192,
- 3, 165, :_reduce_193,
- 4, 165, :_reduce_194,
- 4, 165, :_reduce_195,
- 6, 104, :_reduce_196,
- 9, 104, :_reduce_197,
- 9, 104, :_reduce_198,
- 11, 104, :_reduce_199,
- 1, 166, :_reduce_200,
- 1, 166, :_reduce_201,
- 1, 166, :_reduce_202,
- 1, 152, :_reduce_203,
- 1, 152, :_reduce_204,
- 1, 167, :_reduce_205,
- 2, 167, :_reduce_206,
- 0, 167, :_reduce_207,
- 0, 169, :_reduce_208,
- 1, 169, :_reduce_209,
- 1, 169, :_reduce_210,
- 3, 169, :_reduce_211,
- 3, 169, :_reduce_212,
- 3, 170, :_reduce_213,
- 2, 105, :_reduce_214,
- 4, 105, :_reduce_215,
- 4, 105, :_reduce_216,
- 0, 171, :_reduce_217,
- 1, 171, :_reduce_218,
- 1, 114, :_reduce_219,
- 4, 118, :_reduce_220,
- 5, 118, :_reduce_221,
- 3, 118, :_reduce_222,
- 4, 119, :_reduce_223,
- 5, 119, :_reduce_224,
- 3, 119, :_reduce_225,
- 5, 125, :_reduce_226,
- 4, 109, :_reduce_227,
- 1, 113, :_reduce_228,
- 1, 113, :_reduce_229,
- 4, 110, :_reduce_230,
- 6, 108, :_reduce_231,
- 6, 108, :_reduce_232,
- 6, 108, :_reduce_233,
- 3, 111, :_reduce_234,
- 4, 111, :_reduce_235,
- 6, 111, :_reduce_236,
- 0, 173, :_reduce_237,
- 2, 173, :_reduce_238,
- 3, 173, :_reduce_239,
- 3, 173, :_reduce_240,
- 4, 173, :_reduce_241,
- 1, 174, :_reduce_242,
- 1, 174, :_reduce_243,
- 2, 168, :_reduce_244,
- 1, 168, :_reduce_245,
- 1, 172, :_reduce_246,
- 3, 172, :_reduce_247,
- 3, 172, :_reduce_248,
- 4, 172, :_reduce_249,
- 3, 175, :_reduce_250,
- 4, 176, :_reduce_251,
- 5, 176, :_reduce_252,
- 5, 112, :_reduce_253,
- 8, 112, :_reduce_254,
- 2, 134, :_reduce_255,
- 4, 127, :_reduce_256,
- 1, 127, :_reduce_257,
- 1, 107, :_reduce_258 ]
-
-racc_reduce_n = 259
-
-racc_shift_n = 469
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :IF => 2,
- :ELSE => 3,
- :ELSEIF => 4,
- :THEN => 5,
- :UNLESS => 6,
- :END => 7,
- :WHILE => 8,
- :UNTIL => 9,
- :BREAK => 10,
- :CONTINUE => 11,
- :TRY => 12,
- :CATCH => 13,
- :FINALLY => 14,
- :FOR => 15,
- :IN => 16,
- :DEF => 17,
- :DEF_BANG => 18,
- :SPLAT_PARAM => 19,
- :SPLAT_ARG => 20,
- :CALL => 21,
- :BUILTIN_COMMAND => 22,
- :CLASS => 23,
- :NEW => 24,
- :DEFM => 25,
- :DEFM_BANG => 26,
- :SUPER => 27,
- :RIML_FILE_COMMAND => 28,
- :RIML_CLASS_COMMAND => 29,
- :RETURN => 30,
- :NEWLINE => 31,
- :NUMBER => 32,
- :STRING_D => 33,
- :STRING_S => 34,
- :EX_LITERAL => 35,
- :REGEXP => 36,
- :TRUE => 37,
- :FALSE => 38,
- :LET => 39,
- :UNLET => 40,
- :UNLET_BANG => 41,
- :IDENTIFIER => 42,
- :DICT_VAL => 43,
- :SCOPE_MODIFIER => 44,
- :SCOPE_MODIFIER_LITERAL => 45,
- :SPECIAL_VAR_PREFIX => 46,
- :FINISH => 47,
- "!" => 48,
- "*" => 49,
- "/" => 50,
- "%" => 51,
- "+" => 52,
- "-" => 53,
- "." => 54,
- ">" => 55,
- ">#" => 56,
- ">?" => 57,
- "<" => 58,
- "<#" => 59,
- "<?" => 60,
- ">=" => 61,
- ">=#" => 62,
- ">=?" => 63,
- "<=" => 64,
- "<=#" => 65,
- "<=?" => 66,
- "==" => 67,
- "==?" => 68,
- "==#" => 69,
- "=~" => 70,
- "=~?" => 71,
- "=~#" => 72,
- "!~" => 73,
- "!~?" => 74,
- "!~#" => 75,
- "!=" => 76,
- "!=?" => 77,
- "!=#" => 78,
- :IS => 79,
- :ISNOT => 80,
- "&&" => 81,
- "||" => 82,
- "?" => 83,
- "=" => 84,
- "+=" => 85,
- "-=" => 86,
- ".=" => 87,
- "," => 88,
- "(" => 89,
- ")" => 90,
- ";" => 91,
- "[" => 92,
- "]" => 93,
- "{" => 94,
- "}" => 95,
- ":" => 96,
- "===" => 97 }
-
-racc_nt_base = 98
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "IF",
- "ELSE",
- "ELSEIF",
- "THEN",
- "UNLESS",
- "END",
- "WHILE",
- "UNTIL",
- "BREAK",
- "CONTINUE",
- "TRY",
- "CATCH",
- "FINALLY",
- "FOR",
- "IN",
- "DEF",
- "DEF_BANG",
- "SPLAT_PARAM",
- "SPLAT_ARG",
- "CALL",
- "BUILTIN_COMMAND",
- "CLASS",
- "NEW",
- "DEFM",
- "DEFM_BANG",
- "SUPER",
- "RIML_FILE_COMMAND",
- "RIML_CLASS_COMMAND",
- "RETURN",
- "NEWLINE",
- "NUMBER",
- "STRING_D",
- "STRING_S",
- "EX_LITERAL",
- "REGEXP",
- "TRUE",
- "FALSE",
- "LET",
- "UNLET",
- "UNLET_BANG",
- "IDENTIFIER",
- "DICT_VAL",
- "SCOPE_MODIFIER",
- "SCOPE_MODIFIER_LITERAL",
- "SPECIAL_VAR_PREFIX",
- "FINISH",
- "\"!\"",
- "\"*\"",
- "\"/\"",
- "\"%\"",
- "\"+\"",
- "\"-\"",
- "\".\"",
- "\">\"",
- "\">#\"",
- "\">?\"",
- "\"<\"",
- "\"<#\"",
- "\"<?\"",
- "\">=\"",
- "\">=#\"",
- "\">=?\"",
- "\"<=\"",
- "\"<=#\"",
- "\"<=?\"",
- "\"==\"",
- "\"==?\"",
- "\"==#\"",
- "\"=~\"",
- "\"=~?\"",
- "\"=~#\"",
- "\"!~\"",
- "\"!~?\"",
- "\"!~#\"",
- "\"!=\"",
- "\"!=?\"",
- "\"!=#\"",
- "IS",
- "ISNOT",
- "\"&&\"",
- "\"||\"",
- "\"?\"",
- "\"=\"",
- "\"+=\"",
- "\"-=\"",
- "\".=\"",
- "\",\"",
- "\"(\"",
- "\")\"",
- "\";\"",
- "\"[\"",
- "\"]\"",
- "\"{\"",
- "\"}\"",
- "\":\"",
- "\"===\"",
- "$start",
- "Root",
- "Terminator",
- "Statements",
- "Statement",
- "ExplicitCall",
- "Def",
- "Return",
- "UnletVariable",
- "ExLiteral",
- "For",
- "While",
- "Until",
- "Try",
- "ClassDefinition",
- "LoopKeyword",
- "EndScript",
- "RimlFileCommand",
- "RimlClassCommand",
- "MultiAssign",
- "If",
- "Unless",
- "Expression",
- "ExpressionWithoutDictLiteral",
- "Dictionary",
- "DictGetWithDotLiteral",
- "BinaryOperator",
- "Ternary",
- "Assign",
- "Super",
- "UnaryOperator",
- "DictGet",
- "ListOrDictGet",
- "AllVariableRetrieval",
- "LiteralWithoutDictLiteral",
- "Call",
- "ObjectInstantiation",
- "PossibleStringValue",
- "String",
- "Number",
- "Regexp",
- "List",
- "ScopeModifierLiteral",
- "ListLiteral",
- "ListUnpack",
- "ListItems",
- "DictionaryLiteral",
- "DictItems",
- "DictItem",
- "DictGetWithDot",
- "ListOrDictGetWithBrackets",
- "ListOrDictGetAssign",
- "SubList",
- "Scope",
- "DefCallIdentifier",
- "ArgList",
- "ArgListWithoutNothing",
- "ObjectInstantiationCall",
- "ClassArgList",
- "SIDAndScope",
- "ArgListWithoutNothingWithSplat",
- "ArgListWithSplat",
- "AssignExpression",
- "AssignLHS",
- "VariableRetrieval",
- "SimpleVariableRetrieval",
- "CurlyBraceName",
- "CurlyBraceVarPart",
- "FunctionType",
- "DefKeywords",
- "Block",
- "ParamList",
- "DefaultParam",
- "Returnable",
- "IfBlock",
- "Catch",
- "Catchable",
- "ElseBlock",
- "ElseifBlock" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'riml.y', 61)
- def _reduce_1(val, _values, result)
- result = make_node(val) { |_| Riml::Nodes.new([]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 62)
- def _reduce_2(val, _values, result)
- result = make_node(val) { |_| Riml::Nodes.new([]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 63)
- def _reduce_3(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 68)
- def _reduce_4(val, _values, result)
- result = make_node(val) { |v| Riml::Nodes.new([ v[0] ]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 69)
- def _reduce_5(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 70)
- def _reduce_6(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 71)
- def _reduce_7(val, _values, result)
- result = make_node(val) { |v| Riml::Nodes.new(v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 76)
- def _reduce_8(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 77)
- def _reduce_9(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 78)
- def _reduce_10(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 79)
- def _reduce_11(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 80)
- def _reduce_12(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 81)
- def _reduce_13(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 82)
- def _reduce_14(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 83)
- def _reduce_15(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 84)
- def _reduce_16(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 85)
- def _reduce_17(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 86)
- def _reduce_18(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 87)
- def _reduce_19(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 88)
- def _reduce_20(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 89)
- def _reduce_21(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 90)
- def _reduce_22(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 91)
- def _reduce_23(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 92)
- def _reduce_24(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 93)
- def _reduce_25(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 97)
- def _reduce_26(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 98)
- def _reduce_27(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 99)
- def _reduce_28(val, _values, result)
- result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 100)
- def _reduce_29(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 101)
- def _reduce_30(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 102)
- def _reduce_31(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 103)
- def _reduce_32(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 104)
- def _reduce_33(val, _values, result)
- result = make_node(val) { |v| Riml::WrapInParensNode.new(v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 108)
- def _reduce_34(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 109)
- def _reduce_35(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 110)
- def _reduce_36(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 111)
- def _reduce_37(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 112)
- def _reduce_38(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 113)
- def _reduce_39(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 114)
- def _reduce_40(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 115)
- def _reduce_41(val, _values, result)
- result = make_node(val) { |v| Riml::WrapInParensNode.new(v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 120)
- def _reduce_42(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 121)
- def _reduce_43(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 122)
- def _reduce_44(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 123)
- def _reduce_45(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 124)
- def _reduce_46(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 125)
- def _reduce_47(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 126)
- def _reduce_48(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 130)
- def _reduce_49(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 131)
- def _reduce_50(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 135)
- def _reduce_51(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 136)
- def _reduce_52(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 137)
- def _reduce_53(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 138)
- def _reduce_54(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 139)
- def _reduce_55(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 140)
- def _reduce_56(val, _values, result)
- result = make_node(val) { |_| Riml::TrueNode.new }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 141)
- def _reduce_57(val, _values, result)
- result = make_node(val) { |_| Riml::FalseNode.new }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 145)
- def _reduce_58(val, _values, result)
- result = make_node(val) { |v| Riml::NumberNode.new(v[0]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 149)
- def _reduce_59(val, _values, result)
- result = make_node(val) { |v| Riml::StringNode.new(v[0], :s) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 150)
- def _reduce_60(val, _values, result)
- result = make_node(val) { |v| Riml::StringNode.new(v[0], :d) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 151)
- def _reduce_61(val, _values, result)
- result = make_node(val) { |v| Riml::StringLiteralConcatNode.new(v[0], Riml::StringNode.new(v[1], :s)) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 152)
- def _reduce_62(val, _values, result)
- result = make_node(val) { |v| Riml::StringLiteralConcatNode.new(v[0], Riml::StringNode.new(v[1], :d)) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 156)
- def _reduce_63(val, _values, result)
- result = make_node(val) { |v| Riml::RegexpNode.new(v[0]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 160)
- def _reduce_64(val, _values, result)
- result = make_node(val) { |v| Riml::ScopeModifierLiteralNode.new(v[0]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 164)
- def _reduce_65(val, _values, result)
- result = make_node(val) { |v| Riml::ListNode.new(v[0]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 168)
- def _reduce_66(val, _values, result)
- result = make_node(val) { |v| Riml::ListUnpackNode.new(v[1] << v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 172)
- def _reduce_67(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 173)
- def _reduce_68(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 177)
- def _reduce_69(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 178)
- def _reduce_70(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 179)
- def _reduce_71(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 183)
- def _reduce_72(val, _values, result)
- result = make_node(val) { |v| Riml::DictionaryNode.new(v[0]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 190)
- def _reduce_73(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 191)
- def _reduce_74(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 196)
- def _reduce_75(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 197)
- def _reduce_76(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 198)
- def _reduce_77(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 203)
- def _reduce_78(val, _values, result)
- result = [val[0], val[2]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 207)
- def _reduce_79(val, _values, result)
- result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 208)
- def _reduce_80(val, _values, result)
- result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 209)
- def _reduce_81(val, _values, result)
- result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 210)
- def _reduce_82(val, _values, result)
- result = make_node(val) { |v| Riml::DictGetDotNode.new(Riml::WrapInParensNode.new(v[1]), v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 214)
- def _reduce_83(val, _values, result)
- result = make_node(val) { |v| Riml::ListOrDictGetNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 215)
- def _reduce_84(val, _values, result)
- result = make_node(val) { |v| Riml::ListOrDictGetNode.new(Riml::WrapInParensNode.new(v[1]), v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 219)
- def _reduce_85(val, _values, result)
- result = make_node(val) { |v| Riml::ListOrDictGetNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 223)
- def _reduce_86(val, _values, result)
- result = [val[1]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 224)
- def _reduce_87(val, _values, result)
- result = [val[1]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 225)
- def _reduce_88(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 226)
- def _reduce_89(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 230)
- def _reduce_90(val, _values, result)
- result = make_node(val) { |v| Riml::SublistNode.new([v[0], Riml::LiteralNode.new(' : '), v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 231)
- def _reduce_91(val, _values, result)
- result = make_node(val) { |v| Riml::SublistNode.new([v[0], Riml::LiteralNode.new(' :')]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 232)
- def _reduce_92(val, _values, result)
- result = make_node(val) { |v| Riml::SublistNode.new([Riml::LiteralNode.new(': '), v[1]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 233)
- def _reduce_93(val, _values, result)
- result = make_node(val) { |_| Riml::SublistNode.new([Riml::LiteralNode.new(':')]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 237)
- def _reduce_94(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 238)
- def _reduce_95(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 242)
- def _reduce_96(val, _values, result)
- result = [val[1]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 243)
- def _reduce_97(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 247)
- def _reduce_98(val, _values, result)
- result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 248)
- def _reduce_99(val, _values, result)
- result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 249)
- def _reduce_100(val, _values, result)
- result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 250)
- def _reduce_101(val, _values, result)
- result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 251)
- def _reduce_102(val, _values, result)
- result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], []) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 252)
- def _reduce_103(val, _values, result)
- result = make_node(val) { |v| Riml::ExplicitCallNode.new(nil, nil, v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 256)
- def _reduce_104(val, _values, result)
- result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 257)
- def _reduce_105(val, _values, result)
- result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], []) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 261)
- def _reduce_106(val, _values, result)
- result = make_node(val) { |v| Riml::RimlFileCommandNode.new(nil, v[0], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 262)
- def _reduce_107(val, _values, result)
- result = make_node(val) { |v| Riml::RimlFileCommandNode.new(nil, v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 266)
- def _reduce_108(val, _values, result)
- result = make_node(val) { |v| Riml::RimlClassCommandNode.new(nil, v[0], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 267)
- def _reduce_109(val, _values, result)
- result = make_node(val) { |v| Riml::RimlClassCommandNode.new(nil, v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 271)
- def _reduce_110(val, _values, result)
- result = ["#{val[0]}#{val[1]}"]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 272)
- def _reduce_111(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 273)
- def _reduce_112(val, _values, result)
- result = val[0].concat ["#{val[2]}#{val[3]}"]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 277)
- def _reduce_113(val, _values, result)
- result = make_node(val) { |v| Riml::ExplicitCallNode.new(v[1], v[2], v[4]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 278)
- def _reduce_114(val, _values, result)
- result = make_node(val) { |v| Riml::ExplicitCallNode.new(nil, v[1], v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 282)
- def _reduce_115(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 283)
- def _reduce_116(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 288)
- def _reduce_117(val, _values, result)
- result = [ nil, val[0] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 289)
- def _reduce_118(val, _values, result)
- result = [ make_node(val) { |v| Riml::SIDNode.new(v[1]) }, val[3] ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 293)
- def _reduce_119(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 294)
- def _reduce_120(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 298)
- def _reduce_121(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 299)
- def _reduce_122(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 303)
- def _reduce_123(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 304)
- def _reduce_124(val, _values, result)
- result = [ make_node(val) { |v| Riml::SplatNode.new(v[1]) } ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 305)
- def _reduce_125(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 306)
- def _reduce_126(val, _values, result)
- result = val[0] << make_node(val) { |v| Riml::SplatNode.new(v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 310)
- def _reduce_127(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 311)
- def _reduce_128(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 315)
- def _reduce_129(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 316)
- def _reduce_130(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 318)
- def _reduce_131(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 319)
- def _reduce_132(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 320)
- def _reduce_133(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 323)
- def _reduce_134(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 325)
- def _reduce_135(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 326)
- def _reduce_136(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 327)
- def _reduce_137(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 329)
- def _reduce_138(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 330)
- def _reduce_139(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 331)
- def _reduce_140(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 333)
- def _reduce_141(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 334)
- def _reduce_142(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 335)
- def _reduce_143(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 337)
- def _reduce_144(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 338)
- def _reduce_145(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 339)
- def _reduce_146(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 341)
- def _reduce_147(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 342)
- def _reduce_148(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 343)
- def _reduce_149(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 345)
- def _reduce_150(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 346)
- def _reduce_151(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 347)
- def _reduce_152(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 349)
- def _reduce_153(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 350)
- def _reduce_154(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 351)
- def _reduce_155(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 353)
- def _reduce_156(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 354)
- def _reduce_157(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 355)
- def _reduce_158(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 356)
- def _reduce_159(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 357)
- def _reduce_160(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 358)
- def _reduce_161(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 360)
- def _reduce_162(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 361)
- def _reduce_163(val, _values, result)
- result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 365)
- def _reduce_164(val, _values, result)
- result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 366)
- def _reduce_165(val, _values, result)
- result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 367)
- def _reduce_166(val, _values, result)
- result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 372)
- def _reduce_167(val, _values, result)
- result = make_node(val) { |v| Riml::AssignNode.new(v[1][0], v[1][1], v[1][2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 373)
- def _reduce_168(val, _values, result)
- result = make_node(val) { |v| Riml::AssignNode.new(v[0][0], v[0][1], v[0][2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 377)
- def _reduce_169(val, _values, result)
- result = make_node(val) { |v| Riml::MultiAssignNode.new([v[0], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 378)
- def _reduce_170(val, _values, result)
- val[0].assigns << val[2]; result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 383)
- def _reduce_171(val, _values, result)
- result = [val[1], val[0], val[2]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 384)
- def _reduce_172(val, _values, result)
- result = [val[1], val[0], val[2]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 385)
- def _reduce_173(val, _values, result)
- result = [val[1], val[0], val[2]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 386)
- def _reduce_174(val, _values, result)
- result = [val[1], val[0], val[2]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 390)
- def _reduce_175(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 391)
- def _reduce_176(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 392)
- def _reduce_177(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 393)
- def _reduce_178(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 394)
- def _reduce_179(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 399)
- def _reduce_180(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 400)
- def _reduce_181(val, _values, result)
- result = make_node(val) { |v| Riml::GetSpecialVariableNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 401)
- def _reduce_182(val, _values, result)
- result = make_node(val) { |v| Riml::GetVariableByScopeAndDictNameNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 405)
- def _reduce_183(val, _values, result)
- result = make_node(val) { |v| Riml::GetVariableNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 409)
- def _reduce_184(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 410)
- def _reduce_185(val, _values, result)
- result = make_node(val) { |v| Riml::GetCurlyBraceNameNode.new(v[0], v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 414)
- def _reduce_186(val, _values, result)
- result = make_node(val) { |v| Riml::UnletVariableNode.new('!', [ v[1] ]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 415)
- def _reduce_187(val, _values, result)
- result = make_node(val) { |v| Riml::UnletVariableNode.new('!', [ v[1] ]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 416)
- def _reduce_188(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 420)
- def _reduce_189(val, _values, result)
- result = make_node(val) { |v| Riml::CurlyBraceVariable.new([ v[0] ]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 421)
- def _reduce_190(val, _values, result)
- result = make_node(val) { |v| Riml::CurlyBraceVariable.new([ Riml::CurlyBracePart.new(v[0]), v[1] ]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 422)
- def _reduce_191(val, _values, result)
- result = val[0] << make_node(val) { |v| Riml::CurlyBracePart.new(v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 423)
- def _reduce_192(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 427)
- def _reduce_193(val, _values, result)
- result = make_node(val) { |v| Riml::CurlyBracePart.new(v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 428)
- def _reduce_194(val, _values, result)
- result = make_node(val) { |v| Riml::CurlyBracePart.new([v[1], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 429)
- def _reduce_195(val, _values, result)
- result = make_node(val) { |v| Riml::CurlyBracePart.new([v[1], v[2]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 435)
- def _reduce_196(val, _values, result)
- result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], [], v[3], v[4]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 436)
- def _reduce_197(val, _values, result)
- result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], v[4], v[6], v[7]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 437)
- def _reduce_198(val, _values, result)
- result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], [v[4]], v[6], v[7]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 438)
- def _reduce_199(val, _values, result)
- result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], v[4] << v[6], v[8], v[9]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 442)
- def _reduce_200(val, _values, result)
- result = "DefNode"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 443)
- def _reduce_201(val, _values, result)
- result = "DefNode"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 444)
- def _reduce_202(val, _values, result)
- result = "DefMethodNode"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 449)
- def _reduce_203(val, _values, result)
- result = make_node(val) { |v| Riml::GetCurlyBraceNameNode.new('', v[0]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 450)
- def _reduce_204(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 455)
- def _reduce_205(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 456)
- def _reduce_206(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 457)
- def _reduce_207(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 461)
- def _reduce_208(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 462)
- def _reduce_209(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 463)
- def _reduce_210(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 464)
- def _reduce_211(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 465)
- def _reduce_212(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 469)
- def _reduce_213(val, _values, result)
- result = make_node(val) { |v| Riml::DefaultParamNode.new(v[0], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 473)
- def _reduce_214(val, _values, result)
- result = make_node(val) { |v| Riml::ReturnNode.new(v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 474)
- def _reduce_215(val, _values, result)
- result = make_node(val) { |v| Riml::IfNode.new(v[3], Nodes.new([ReturnNode.new(v[1])])) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 475)
- def _reduce_216(val, _values, result)
- result = make_node(val) { |v| Riml::UnlessNode.new(v[3], Nodes.new([ReturnNode.new(v[1])])) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 479)
- def _reduce_217(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 480)
- def _reduce_218(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 484)
- def _reduce_219(val, _values, result)
- result = make_node(val) { |_| Riml::FinishNode.new }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 489)
- def _reduce_220(val, _values, result)
- result = make_node(val) { |v| Riml::IfNode.new(v[1], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 490)
- def _reduce_221(val, _values, result)
- result = make_node(val) { |v| Riml::IfNode.new(v[1], Riml::Nodes.new([v[3]])) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 491)
- def _reduce_222(val, _values, result)
- result = make_node(val) { |v| Riml::IfNode.new(v[2], Riml::Nodes.new([v[0]])) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 495)
- def _reduce_223(val, _values, result)
- result = make_node(val) { |v| Riml::UnlessNode.new(v[1], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 496)
- def _reduce_224(val, _values, result)
- result = make_node(val) { |v| Riml::UnlessNode.new(v[1], Riml::Nodes.new([v[3]])) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 497)
- def _reduce_225(val, _values, result)
- result = make_node(val) { |v| Riml::UnlessNode.new(v[2], Riml::Nodes.new([v[0]])) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 501)
- def _reduce_226(val, _values, result)
- result = make_node(val) { |v| Riml::TernaryOperatorNode.new([v[0], v[2], v[4]]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 505)
- def _reduce_227(val, _values, result)
- result = make_node(val) { |v| Riml::WhileNode.new(v[1], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 509)
- def _reduce_228(val, _values, result)
- result = make_node(val) { |_| Riml::BreakNode.new }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 510)
- def _reduce_229(val, _values, result)
- result = make_node(val) { |_| Riml::ContinueNode.new }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 514)
- def _reduce_230(val, _values, result)
- result = make_node(val) { |v| Riml::UntilNode.new(v[1], v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 518)
- def _reduce_231(val, _values, result)
- result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 519)
- def _reduce_232(val, _values, result)
- result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 520)
- def _reduce_233(val, _values, result)
- result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 524)
- def _reduce_234(val, _values, result)
- result = make_node(val) { |v| Riml::TryNode.new(v[1], nil, nil) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 525)
- def _reduce_235(val, _values, result)
- result = make_node(val) { |v| Riml::TryNode.new(v[1], v[2], nil) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 526)
- def _reduce_236(val, _values, result)
- result = make_node(val) { |v| Riml::TryNode.new(v[1], v[2], v[4]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 530)
- def _reduce_237(val, _values, result)
- result = nil
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 531)
- def _reduce_238(val, _values, result)
- result = [ make_node(val) { |v| Riml::CatchNode.new(nil, v[1]) } ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 532)
- def _reduce_239(val, _values, result)
- result = [ make_node(val) { |v| Riml::CatchNode.new(v[1], v[2]) } ]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 533)
- def _reduce_240(val, _values, result)
- result = val[0] << make_node(val) { |v| Riml::CatchNode.new(nil, v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 534)
- def _reduce_241(val, _values, result)
- result = val[0] << make_node(val) { |v| Riml::CatchNode.new(v[2], v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 538)
- def _reduce_242(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 539)
- def _reduce_243(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 546)
- def _reduce_244(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 547)
- def _reduce_245(val, _values, result)
- result = make_node(val) { |_| Riml::Nodes.new([]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 551)
- def _reduce_246(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 552)
- def _reduce_247(val, _values, result)
- result = val[1] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 553)
- def _reduce_248(val, _values, result)
- result = val[1] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 554)
- def _reduce_249(val, _values, result)
- result = val[1] << val[2] << val[3]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 558)
- def _reduce_250(val, _values, result)
- result = make_node(val) { |v| Riml::ElseNode.new(v[2]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 562)
- def _reduce_251(val, _values, result)
- result = make_node(val) { |v| Riml::Nodes.new([Riml::ElseifNode.new(v[1], v[3])]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 563)
- def _reduce_252(val, _values, result)
- result = val[0] << make_node(val) { |v| Riml::ElseifNode.new(v[2], v[4]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 567)
- def _reduce_253(val, _values, result)
- result = make_node(val) { |v| Riml::ClassDefinitionNode.new(v[1], v[2], nil, v[3]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 568)
- def _reduce_254(val, _values, result)
- result = make_node(val) { |v| Riml::ClassDefinitionNode.new(v[1], v[2], (v[4] || ClassDefinitionNode::DEFAULT_SCOPE_MODIFIER) + v[5], v[6]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 572)
- def _reduce_255(val, _values, result)
- result = make_node(val) { |v| Riml::ObjectInstantiationNode.new(v[1]) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 576)
- def _reduce_256(val, _values, result)
- result = make_node(val) { |v| Riml::SuperNode.new(v[2], true) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 577)
- def _reduce_257(val, _values, result)
- result = make_node(val) { |_| Riml::SuperNode.new([], false) }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'riml.y', 581)
- def _reduce_258(val, _values, result)
- result = make_node(val) { |v| Riml::ExLiteralNode.new(v[0]) }
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module Riml
diff --git a/test/racc/regress/ruby18 b/test/racc/regress/ruby18
deleted file mode 100644
index 9e9c55d564..0000000000
--- a/test/racc/regress/ruby18
+++ /dev/null
@@ -1,9945 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.2
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-
-require 'parser'
-
-module Parser
- class Ruby18 < Racc::Parser
-
-module_eval(<<'...end ruby18.y/module_eval...', 'ruby18.y', 1936)
-
- def version
- 18
- end
-
- def default_encoding
- Encoding::BINARY if defined? Encoding
- end
-...end ruby18.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- -480, 195, 196, 195, 196, 489, 814, -480, -480, -480,
- 511, 578, 578, -480, -480, -80, -480, -429, 579, 579,
- 489, 72, 531, -87, 558, -480, 99, 489, -86, 73,
- 95, 98, 395, 195, 196, -480, -480, -82, -480, -480,
- -480, -480, -480, 489, 489, 558, 495, -84, 496, -83,
- -81, 463, 659, 658, 662, 661, 186, 99, 557, 558,
- 291, 291, 98, -80, -480, -480, -480, -480, -480, -480,
- -480, -480, -480, -480, -480, -480, -480, -480, -87, 557,
- -480, -480, -480, 259, 546, 530, 722, -74, -480, -61,
- 99, -480, 291, 557, 621, 98, -480, -86, -480, -85,
- -480, -480, -480, -480, -480, -480, -480, -277, -480, -480,
- -480, 187, -476, 510, -277, -277, -277, 99, -72, 488,
- -277, -277, 98, -277, -480, -480, -79, -75, -69, -480,
- -83, -78, 99, 99, 488, 621, -76, 98, 98, 99,
- -74, 488, -277, -277, 98, -277, -277, -277, -277, -277,
- -76, -74, -75, -73, 431, 99, 99, 488, 488, 621,
- 98, 98, -477, 259, 502, 195, 196, 258, 503, -74,
- 690, -277, -277, -277, -277, -277, -277, -277, -277, -277,
- -277, -277, -277, -277, -277, 558, 259, -277, -277, -277,
- -74, 549, 99, -74, 620, -277, 713, 98, -277, 691,
- -76, 188, -77, -277, 521, -277, 521, -277, -277, -277,
- -277, -277, -277, -277, -272, -277, -82, -277, -76, 557,
- 189, -272, -272, -272, 99, 254, -272, -272, -272, 98,
- -272, -277, -277, 99, -77, 620, -277, -85, 98, -76,
- -272, -272, -76, 477, 190, -84, 476, 258, 254, -272,
- -272, 768, -272, -272, -272, -272, -272, 99, 194, 620,
- 477, 234, 98, 479, 521, 523, 522, 523, 522, 519,
- 258, 477, 358, 282, 482, 673, 360, 359, -272, -272,
- -272, -272, -272, -272, -272, -272, -272, -272, -272, -272,
- -272, -272, 521, 192, -272, -272, -272, -81, 283, -272,
- 193, -79, -272, 521, -87, -272, -272, 291, -272, 191,
- -272, 349, -272, 215, -272, -272, -272, -272, -272, -272,
- -272, -226, -272, 361, -272, 523, 522, 524, -226, -226,
- -226, 814, 394, -226, -226, -226, 521, -226, -272, -272,
- -272, -272, 396, -272, -473, 212, 606, -226, 496, 214,
- 213, 210, 211, 523, 522, 526, -226, -226, 397, -226,
- -226, -226, -226, -226, 523, 522, 527, 251, 477, 426,
- -474, 479, -480, -480, 252, -319, -226, 659, 658, 662,
- 661, 428, -319, -226, -226, -226, -417, -476, -226, -226,
- -226, -319, -226, -417, -417, 431, -226, 523, 522, 532,
- -429, -417, -226, -226, 284, 285, -473, 436, 254, -226,
- -417, -226, -226, -60, -226, -226, -226, -226, -226, 463,
- -421, 451, -480, -480, 541, -477, 542, -421, -473, -480,
- -480, -226, -474, 680, -476, -476, -421, -476, -480, -480,
- 452, 215, 453, -72, -476, -226, -80, -226, 215, -476,
- -226, -226, 391, -476, -474, 99, -480, -480, -226, 392,
- 98, 99, -78, 254, -226, -86, 98, -74, 393, -76,
- -82, -476, -84, 212, -428, -477, -73, 214, 213, -81,
- 212, -428, -477, 459, 214, 213, -226, -477, 461, 462,
- -428, -477, 195, 196, -421, -476, -476, -476, 263, -476,
- -226, -421, -226, -476, -476, -226, 291, -480, -476, -477,
- -476, -476, -476, -476, -476, -476, -476, 195, 196, 734,
- 606, -476, -476, -476, -476, -476, -476, -476, -427, 215,
- 254, -426, -425, 662, 661, -427, 464, -476, -426, -425,
- -476, -476, -476, -476, -476, -476, -476, -476, -476, -476,
- 465, -476, -476, -422, -476, -476, -476, -480, 734, 606,
- -422, 212, 215, -423, -480, 214, 213, 210, 211, -476,
- -423, 457, 471, -480, -424, 472, -476, 692, 458, -476,
- -476, -424, -476, -476, 291, 481, -476, 456, -476, 484,
- -476, -480, -476, 351, 516, -271, 466, 498, 500, 501,
- -476, 517, -271, 467, 499, -476, -476, -476, -476, -476,
- -476, -271, 393, 497, -476, -476, -477, -477, -477, 535,
- -477, 536, 538, -83, -477, -477, -259, 540, 254, -477,
- 215, -477, -477, -477, -477, -477, -477, -477, 215, 215,
- 215, 568, -477, -477, -477, -477, -477, -477, -477, 667,
- 668, 575, 669, 93, 94, 291, 580, 234, -477, 590,
- 591, -477, -477, -477, -477, -477, -477, -477, -477, -477,
- -477, -69, -477, -477, 592, -477, -477, -477, 215, 219,
- 224, 225, 226, 221, 223, 231, 232, 227, 228, 507,
- -497, -497, -278, 469, 229, 230, 505, -477, 549, -278,
- -477, -477, 606, -477, -477, 506, 291, -477, -278, -477,
- 212, -477, 218, -477, 214, 213, 210, 211, 222, 220,
- 216, -477, 217, 616, 496, 624, -477, -477, -477, -477,
- -477, -477, 672, -278, 675, -477, -477, 62, 63, 64,
- -278, 51, 436, 436, -85, 56, 57, 693, 704, -278,
- 60, 431, 58, 59, 61, 23, 24, 65, 66, 431,
- 243, 707, 708, 22, 28, 27, 88, 87, 89, 90,
- 715, 717, 17, 721, 254, 254, 215, 537, 215, 41,
- 724, -259, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, 728, 80, 81, 730, 38, 39, 37, 215,
- 219, 224, 225, 226, 221, 223, 231, 232, 227, 228,
- -277, 208, 209, -279, 606, 229, 230, -277, 200, 738,
- -279, 204, -477, 739, 52, 53, -277, 740, 54, -279,
- 743, 212, 745, 218, 40, 214, 213, 210, 211, 222,
- 220, 216, 18, 217, 749, 753, 755, 79, 72, 74,
- 75, 76, 77, 758, 759, 760, 73, 78, 761, 99,
- 233, 763, -215, -277, 98, 62, 63, 64, 7, 51,
- -277, -260, 769, 56, 57, -477, 777, 778, 60, -277,
- 58, 59, 61, 23, 24, 65, 66, 568, 568, 254,
- 254, 22, 28, 27, 88, 87, 89, 90, 234, 568,
- 17, 101, 102, 103, 104, 105, 6, 41, 8, 9,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- 790, 80, 81, 791, 38, 39, 37, 215, 219, 224,
- 225, 226, 221, 223, 231, 232, 227, 228, -428, -497,
- -497, 823, 792, 229, 230, -428, 36, 797, 824, 30,
- 799, 805, 52, 53, -428, 807, 54, 822, 32, 212,
- 291, 218, 40, 214, 213, 210, 211, 222, 220, 216,
- 18, 217, 818, 825, 826, 79, 72, 74, 75, 76,
- 77, 827, -271, 829, 73, 78, 62, 63, 64, -271,
- 51, 830, 351, -278, 56, 57, 832, 835, -271, 60,
- -278, 58, 59, 61, 246, 247, 65, 66, 839, -278,
- 840, 846, 245, 275, 279, 88, 87, 89, 90, 101,
- 102, 103, 104, 105, 847, 848, 758, 758, 276, 759,
- 861, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, 568, 80, 81, 215, 568, 655, 280, 653, 652,
- 651, 654, -277, 471, 874, -279, 875, 876, 880, -277,
- 229, 230, -279, 883, -477, 758, 885, 772, -277, 886,
- 204, -279, 568, 52, 53, 568, 212, 54, 218, 568,
- 214, 213, 210, 211, 645, nil, 216, nil, 217, nil,
- nil, nil, 659, 658, 662, 661, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, nil, 62, 63,
- 64, 775, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, 101, 102, 103, 104, 105, nil, nil, 537, nil,
- 276, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, nil, nil, 280,
- 215, 219, 224, 225, 226, 221, 223, 231, 232, 227,
- 228, nil, 208, 209, nil, nil, 229, 230, nil, 772,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, 212, nil, 218, nil, 214, 213, 210, 211,
- 222, 220, 216, nil, 217, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, nil,
- nil, 233, nil, 855, 5, 62, 63, 64, 7, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- 17, nil, nil, nil, nil, nil, 6, 41, 8, 9,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 36, nil, nil, 30,
- nil, nil, 52, 53, nil, nil, 54, nil, 32, nil,
- nil, nil, 40, 655, nil, 653, 652, 651, 654, nil,
- 18, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 5, 62, 63, 64,
- 7, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, 659,
- 658, 662, 661, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, 6, 41,
- 8, 9, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 36, nil,
- nil, 265, nil, nil, 52, 53, nil, nil, 54, nil,
- 32, nil, nil, nil, 40, 655, nil, 653, 652, 651,
- 654, nil, 18, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 5, 62,
- 63, 64, 7, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, 659, 658, 662, 661, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- 6, 41, 8, 9, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, nil, nil, 30, nil, nil, 52, 53, nil, nil,
- 54, nil, 32, nil, nil, nil, 40, 655, nil, 653,
- 652, 651, 654, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 5, 62, 63, 64, 7, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, 645, 58, 59, 61, 23,
- 24, 65, 66, 659, 658, 662, 661, 22, 28, 27,
- 88, 87, 89, 90, nil, nil, 17, nil, nil, nil,
- nil, nil, 6, 41, 8, 9, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, 215, -497, -497, -497, -497, 221, 223,
- nil, nil, -497, -497, nil, nil, nil, nil, nil, 229,
- 230, nil, 36, nil, nil, 30, nil, nil, 52, 53,
- nil, nil, 54, nil, 32, 212, nil, 218, 40, 214,
- 213, 210, 211, 222, 220, 216, 18, 217, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 5, 62, 63, 64, 7, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 23, 24, 65, 66, nil, nil, nil, nil, 22,
- 28, 27, 88, 87, 89, 90, nil, nil, 17, nil,
- nil, nil, nil, nil, 6, 41, 8, 9, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, 215, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 229, 230, nil, 36, nil, nil, 30, nil, nil,
- 52, 53, nil, nil, 54, nil, 32, 212, nil, 218,
- 40, 214, 213, 210, 211, nil, nil, 216, 18, 217,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 5, 62, 63, 64, 7, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- 17, nil, nil, nil, nil, nil, 6, 41, 8, 9,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, 215, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 229, 230, nil, 36, nil, nil, 30,
- nil, nil, 52, 53, nil, nil, 54, nil, 32, 212,
- nil, 218, 40, 214, 213, 210, 211, nil, nil, 216,
- 18, 217, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 5, 62, 63, 64,
- 7, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, 6, 41,
- 8, 9, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, 215,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 229, 230, nil, 36, nil,
- nil, 265, nil, nil, 52, 53, nil, nil, 54, nil,
- 32, 212, nil, 218, 40, 214, 213, 210, 211, nil,
- nil, 216, 18, 217, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 5, 62,
- 63, 64, 7, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- 6, 41, 8, 9, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, 215, -497, -497, -497, -497, 221, 223, nil, nil,
- -497, -497, nil, nil, nil, nil, nil, 229, 230, nil,
- 36, nil, nil, 265, nil, nil, 52, 53, nil, nil,
- 54, nil, 32, 212, nil, 218, 40, 214, 213, 210,
- 211, 222, 220, 216, 18, 217, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 5, 62, 63, 64, 7, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 23,
- 24, 65, 66, nil, nil, nil, nil, 22, 28, 27,
- 88, 87, 89, 90, nil, nil, 17, nil, nil, nil,
- nil, nil, 6, 41, 8, 9, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, 215, -497, -497, -497, -497, 221, 223,
- nil, nil, -497, -497, nil, nil, nil, nil, nil, 229,
- 230, nil, 36, nil, nil, 30, nil, nil, 52, 53,
- nil, nil, 54, nil, 32, 212, nil, 218, 40, 214,
- 213, 210, 211, 222, 220, 216, 18, 217, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 5, 62, 63, 64, 7, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 23, 24, 65, 66, nil, nil, nil, nil, 22,
- 28, 27, 88, 87, 89, 90, nil, nil, 17, nil,
- nil, nil, nil, nil, 6, 41, 8, 9, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, 215, -497, -497, -497, -497,
- 221, 223, nil, nil, -497, -497, nil, nil, nil, nil,
- nil, 229, 230, nil, 36, nil, nil, 30, nil, nil,
- 52, 53, nil, nil, 54, nil, 32, 212, nil, 218,
- 40, 214, 213, 210, 211, 222, 220, 216, 18, 217,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 5, 62, 63, 64, 7, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- 17, nil, nil, nil, nil, nil, 6, 41, 8, 9,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, 215, -497, -497,
- -497, -497, 221, 223, nil, nil, -497, -497, nil, nil,
- nil, nil, nil, 229, 230, nil, 36, nil, nil, 30,
- nil, nil, 52, 53, nil, nil, 54, nil, 32, 212,
- nil, 218, 40, 214, 213, 210, 211, 222, 220, 216,
- 18, 217, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 5, 62, 63, 64,
- 7, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, 6, 41,
- 8, 9, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, 215,
- -497, -497, -497, -497, 221, 223, nil, nil, -497, -497,
- nil, nil, nil, nil, nil, 229, 230, nil, 36, nil,
- nil, 30, nil, nil, 52, 53, nil, nil, 54, nil,
- 32, 212, nil, 218, 40, 214, 213, 210, 211, 222,
- 220, 216, 18, 217, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 5, 62,
- 63, 64, 7, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- 6, 41, 8, 9, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, 215, 219, 224, 225, 226, 221, 223, nil, nil,
- 227, 228, nil, nil, nil, nil, nil, 229, 230, nil,
- 36, nil, nil, 30, nil, nil, 52, 53, nil, nil,
- 54, nil, 32, 212, nil, 218, 40, 214, 213, 210,
- 211, 222, 220, 216, 18, 217, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 5, 62, 63, 64, 7, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 23,
- 24, 65, 66, nil, nil, nil, nil, 22, 28, 27,
- 88, 87, 89, 90, nil, nil, 17, nil, nil, nil,
- nil, nil, 6, 41, 8, 9, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, 215, 219, 224, 225, 226, 221, 223,
- 231, nil, 227, 228, nil, nil, nil, nil, nil, 229,
- 230, nil, 36, nil, nil, 30, nil, nil, 52, 53,
- nil, nil, 54, nil, 32, 212, nil, 218, 40, 214,
- 213, 210, 211, 222, 220, 216, 18, 217, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 5, 62, 63, 64, 7, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 23, 24, 65, 66, nil, nil, nil, nil, 22,
- 28, 27, 88, 87, 89, 90, nil, nil, 17, nil,
- nil, nil, nil, nil, 6, 41, 8, 9, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, 215, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 229, 230, nil, 36, nil, nil, 30, nil, nil,
- 52, 53, nil, nil, 54, nil, 32, 212, nil, 218,
- 40, 214, 213, 210, 211, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 5, 62, 63, 64, 7, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- 17, nil, nil, nil, nil, nil, 6, 41, 8, 9,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, 215, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 229, 230, nil, 36, nil, nil, 30,
- nil, nil, 52, 53, nil, nil, 54, nil, 32, 212,
- nil, 218, 40, 214, 213, 210, 211, nil, nil, nil,
- 18, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 5, 62, 63, 64,
- 7, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, 6, 41,
- 8, 9, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, 215,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 229, 230, nil, 36, nil,
- nil, 30, nil, nil, 52, 53, nil, nil, 54, nil,
- 32, 212, nil, nil, 40, 214, 213, 210, 211, nil,
- nil, nil, 18, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 5, 62,
- 63, 64, 7, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- 6, 41, 8, 9, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, nil, nil, 30, nil, nil, 52, 53, nil, nil,
- 54, nil, 32, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 5, 62, 63, 64, 7, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 23,
- 24, 65, 66, nil, nil, nil, nil, 22, 28, 27,
- 88, 87, 89, 90, nil, nil, 17, nil, nil, nil,
- nil, nil, 6, 41, 8, 9, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 36, nil, nil, 30, nil, nil, 52, 53,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 5, 62, 63, 64, 7, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 23, 24, 65, 66, nil, nil, nil, nil, 22,
- 28, 27, 88, 87, 89, 90, nil, nil, 17, nil,
- nil, nil, nil, nil, 6, 41, 8, 9, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 36, nil, nil, 30, nil, nil,
- 52, 53, nil, nil, 54, nil, 32, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 5, 62, 63, 64, 7, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- 17, nil, nil, nil, nil, nil, 6, 41, 8, 9,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 36, nil, nil, 30,
- nil, nil, 52, 53, nil, nil, 54, nil, 32, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 18, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 5, 62, 63, 64,
- 7, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, 6, 41,
- 8, 9, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 36, nil,
- nil, 30, nil, nil, 52, 53, nil, nil, 54, nil,
- 32, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 18, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 5, 62,
- 63, 64, 7, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- 6, 41, 8, 9, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, nil, nil, 30, nil, nil, 52, 53, nil, nil,
- 54, nil, 32, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 5, 62, 63, 64, 7, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 23,
- 24, 65, 66, nil, nil, nil, nil, 22, 28, 27,
- 88, 87, 89, 90, nil, nil, 17, nil, nil, nil,
- nil, nil, 6, 41, 8, 9, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 36, nil, nil, 30, nil, nil, 52, 53,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 5, 62, 63, 64, 7, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 23, 24, 65, 66, nil, nil, nil, nil, 22,
- 28, 27, 88, 87, 89, 90, nil, nil, 17, nil,
- nil, nil, nil, nil, 6, 41, 8, 9, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 36, nil, nil, 30, nil, nil,
- 52, 53, nil, nil, 54, nil, 32, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 5, 62, 63, 64, 7, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- 17, nil, nil, nil, nil, nil, 6, 41, 8, 9,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 36, nil, nil, 30,
- nil, nil, 52, 53, nil, nil, 54, nil, 32, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 18, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 5, 62, 63, 64,
- 7, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, 6, 41,
- 8, 9, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 36, nil,
- nil, 30, nil, nil, 52, 53, nil, nil, 54, nil,
- 32, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 18, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 5, 62,
- 63, 64, 7, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- 6, 41, 8, 9, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 36, nil, nil, 30, nil, nil, 52, 53, nil, nil,
- 54, nil, 32, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 5, 62, 63, 64, 7, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 23,
- 24, 65, 66, nil, nil, nil, nil, 22, 28, 27,
- 88, 87, 89, 90, nil, nil, 17, nil, nil, nil,
- nil, nil, 6, 41, 8, 9, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 36, nil, nil, 30, nil, nil, 52, 53,
- nil, nil, 54, nil, 32, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, 7, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 23, 24, 65, 66, nil, nil, nil, nil, 22, 28,
- 27, 88, 87, 89, 90, nil, nil, 17, nil, nil,
- nil, nil, nil, 6, 41, 8, 9, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 36, nil, nil, 30, nil, nil, 52,
- 53, nil, nil, 54, nil, 32, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 18, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 153, 164, 154, 177, 150, 170, 160,
- 159, 180, 181, 175, 158, 157, 152, 178, 182, 183,
- 162, 151, 165, 169, 171, 163, 156, nil, nil, 172,
- 179, 174, 173, 166, 176, 161, 149, 168, 167, nil,
- nil, nil, nil, nil, 148, 155, 146, 147, 144, 145,
- 109, 111, 108, nil, 110, nil, nil, nil, nil, nil,
- nil, nil, 139, 140, nil, 137, 121, 122, 123, nil,
- 126, 128, nil, nil, 124, nil, nil, nil, nil, 141,
- 142, 129, 130, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 134, 133, nil, 120,
- 138, 136, 135, 131, 132, 127, 125, 118, nil, 119,
- nil, nil, 143, 79, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 78, 153, 164, 154, 177, 150, 170,
- 160, 159, 180, 181, 175, 158, 157, 152, 178, 182,
- 183, 162, 151, 165, 169, 171, 163, 156, nil, nil,
- 172, 179, 174, 173, 166, 176, 161, 149, 168, 167,
- nil, nil, nil, nil, nil, 148, 155, 146, 147, 144,
- 145, 109, 111, nil, nil, 110, nil, nil, nil, nil,
- nil, nil, nil, 139, 140, nil, 137, 121, 122, 123,
- nil, 126, 128, nil, nil, 124, nil, nil, nil, nil,
- 141, 142, 129, 130, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 134, 133, nil,
- 120, 138, 136, 135, 131, 132, 127, 125, 118, nil,
- 119, nil, nil, 143, 79, nil, nil, 62, 63, 64,
- nil, 51, nil, nil, 78, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 18, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 23, 24, 65, 66,
- nil, nil, nil, nil, 22, 28, 27, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 28, 27, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, 241, nil, 243, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 28, 27, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, 241, nil, 243, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 28, 27,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, 241, nil, 243, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, -249, -249, -249, nil, -249, nil, nil, nil,
- -249, -249, nil, nil, nil, -249, nil, -249, -249, -249,
- -249, -249, -249, -249, nil, nil, nil, nil, -249, -249,
- -249, -249, -249, -249, -249, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, -249, nil, nil, -249, -249, -249,
- -249, -249, -249, -249, -249, -249, -249, nil, -249, -249,
- nil, -249, -249, -249, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -249, nil, nil, -249, 254, nil, -249,
- -249, nil, nil, -249, nil, -249, nil, -249, nil, -249,
- nil, nil, nil, nil, nil, nil, nil, -249, nil, nil,
- nil, nil, -249, -249, -249, -249, -249, -249, nil, nil,
- nil, -249, -249, -249, -249, -249, nil, -249, nil, nil,
- nil, -249, -249, nil, nil, nil, -249, nil, -249, -249,
- -249, -249, -249, -249, -249, nil, nil, nil, nil, -249,
- -249, -249, -249, -249, -249, -249, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, -249, nil, nil, -249, -249,
- -249, -249, -249, -249, -249, -249, -249, -249, nil, -249,
- -249, nil, -249, -249, -249, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, -249, nil, nil, -249, 263, nil,
- -249, -249, nil, nil, -249, nil, -249, nil, -249, nil,
- -249, nil, nil, nil, nil, nil, nil, nil, -249, nil,
- nil, nil, nil, -249, -249, -249, -249, -249, -249, nil,
- nil, nil, -249, -249, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 276, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, nil, nil, 280, nil, 215, 219, 224,
- 225, 226, 221, 223, 231, 232, 227, 228, nil, 208,
- 209, nil, nil, 229, 230, 273, nil, nil, 270, nil,
- nil, 52, 53, nil, nil, 54, nil, 269, nil, 212,
- nil, 218, nil, 214, 213, 210, 211, 222, 220, 216,
- nil, 217, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, 233, 51,
- 568, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 276, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, nil, nil, 280, nil, 215, 219,
- 224, 225, 226, 221, 223, 231, 232, 227, 228, nil,
- 208, 209, nil, nil, 229, 230, 273, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- 212, nil, 218, nil, 214, 213, 210, 211, 222, 220,
- 216, nil, 217, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, 233,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 275, 279, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 28, 27, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, 299, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 23, 24, 65, 66, nil, nil, nil, nil, 22, 28,
- 27, 88, 87, 89, 90, nil, nil, 17, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 18, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 23, 24, 65, 66, nil, nil, nil, nil, 22,
- 28, 27, 88, 87, 89, 90, nil, nil, 17, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 276, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, nil, nil, 280, nil, 215, 219, 224,
- 225, 226, 221, 223, 231, 232, 227, 228, nil, 208,
- 209, nil, nil, 229, 230, 315, nil, nil, 30, nil,
- nil, 52, 53, nil, nil, 54, nil, 32, nil, 212,
- nil, 218, nil, 214, 213, 210, 211, 222, 220, 216,
- nil, 217, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, 233, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 276, nil, nil,
- 92, 91, 320, 50, 84, 83, 321, 85, 93, 94,
- nil, 80, 81, nil, nil, nil, 280, nil, 215, 219,
- 224, 225, 226, 221, 223, 231, 232, 227, 228, nil,
- 208, 209, nil, 327, 229, 230, 322, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- 212, nil, 218, nil, 214, 213, 210, 211, 222, 220,
- 216, nil, 217, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, 233,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 276, nil,
- nil, 92, 91, 320, 50, 84, 83, 321, 85, 93,
- 94, nil, 80, 81, nil, nil, nil, 280, nil, 215,
- 219, 224, 225, 226, 221, 223, 231, 232, 227, 228,
- nil, 208, 209, nil, nil, 229, 230, 322, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, 212, nil, 218, nil, 214, 213, 210, 211, 222,
- 220, 216, nil, 217, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, -473, -473, -473,
- 233, -473, nil, nil, nil, -473, -473, nil, nil, nil,
- -473, nil, -473, -473, -473, -473, -473, -473, -473, nil,
- -473, nil, nil, -473, -473, -473, -473, -473, -473, -473,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, -473,
- nil, nil, -473, -473, -473, -473, -473, -473, -473, -473,
- -473, -473, nil, -473, -473, nil, -473, -473, -473, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, -473, nil,
- nil, -473, -473, nil, -473, -473, nil, nil, -473, nil,
- -473, nil, -473, nil, -473, nil, nil, nil, nil, nil,
- nil, nil, -473, nil, -473, nil, nil, -473, -473, -473,
- -473, -473, -473, nil, nil, nil, -473, -473, -474, -474,
- -474, nil, -474, nil, nil, nil, -474, -474, nil, nil,
- nil, -474, nil, -474, -474, -474, -474, -474, -474, -474,
- nil, -474, nil, nil, -474, -474, -474, -474, -474, -474,
- -474, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- -474, nil, nil, -474, -474, -474, -474, -474, -474, -474,
- -474, -474, -474, nil, -474, -474, nil, -474, -474, -474,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, -474,
- nil, nil, -474, -474, nil, -474, -474, nil, nil, -474,
- nil, -474, nil, -474, nil, -474, nil, nil, nil, nil,
- nil, nil, nil, -474, nil, -474, nil, nil, -474, -474,
- -474, -474, -474, -474, nil, nil, nil, -474, -474, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 23, 24,
- 65, 66, nil, nil, nil, nil, 22, 28, 27, 88,
- 87, 89, 90, nil, nil, 17, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 18, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 23,
- 24, 65, 66, nil, nil, nil, nil, 22, 28, 27,
- 88, 87, 89, 90, nil, nil, 17, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 18, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 23, 24, 65, 66, nil, nil, nil, nil, 22, 28,
- 27, 88, 87, 89, 90, nil, nil, 17, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 18, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, 7, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 23, 24, 65, 66, nil, nil, nil, nil, 22,
- 28, 27, 88, 87, 89, 90, nil, nil, 17, nil,
- nil, nil, nil, nil, 6, 41, 8, 9, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 36, nil, nil, 30, nil, nil,
- 52, 53, nil, nil, 54, nil, 32, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 18, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 23, 24, 65, 66, nil, nil, nil, nil,
- 22, 28, 27, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, 369, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, 369, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 207, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 23, 24, 65, 66, nil, nil,
- nil, nil, 22, 28, 27, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 28, 27, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- 299, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 23, 24, 65, 66,
- nil, nil, nil, nil, 22, 28, 27, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 23, 24,
- 65, 66, nil, nil, nil, nil, 22, 28, 27, 88,
- 87, 89, 90, nil, nil, 17, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 18, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 207, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 275, 279, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 275, 279, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 275, 279, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 207, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 275, 279, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 275, 279, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 275, 279, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 207, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 275, 279, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 275, 279, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 28, 27, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, 241, nil, 243, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 28, 27,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 445, 53,
- nil, nil, 54, nil, 241, nil, 243, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 28,
- 27, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, 449, 52,
- 53, nil, nil, 54, nil, 241, nil, 243, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 276, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, nil, nil, 280, nil, 215, 219, 224, 225,
- 226, 221, 223, 231, 232, 227, 228, nil, 208, 209,
- nil, nil, 229, 230, 273, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, 212, nil,
- 218, nil, 214, 213, 210, 211, 222, 220, 216, nil,
- 217, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, 233, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, 469,
- nil, 52, 53, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 207, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 23, 24, 65, 66, nil, nil,
- nil, nil, 22, 28, 27, 88, 87, 89, 90, nil,
- nil, 17, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 18, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 18, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 23, 24, 65, 66,
- nil, nil, nil, nil, 22, 28, 27, 88, 87, 89,
- 90, nil, nil, 17, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 18, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 153, 164, 154, 177, 150, 170, 160, 159, 180, 181,
- 175, 158, 157, 152, 178, 182, 183, 162, 151, 165,
- 169, 171, 163, 156, nil, nil, 172, 179, 174, 173,
- 166, 176, 161, 149, 168, 167, nil, nil, nil, nil,
- nil, 148, 155, 146, 147, 144, 145, 109, 111, nil,
- nil, 110, nil, nil, nil, nil, nil, nil, nil, 139,
- 140, nil, 137, 121, 122, 123, nil, 126, 128, nil,
- nil, 124, nil, nil, nil, nil, 141, 142, 129, 130,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 134, 133, nil, 120, 138, 136, 135,
- 131, 132, 127, 125, 118, nil, 119, nil, nil, 143,
- 79, nil, nil, 62, 63, 64, nil, 51, nil, nil,
- 78, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, -249, -249, -249, nil, -249, nil,
- nil, nil, -249, -249, nil, nil, nil, -249, nil, -249,
- -249, -249, -249, -249, -249, -249, nil, nil, nil, nil,
- -249, -249, -249, -249, -249, -249, -249, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, -249, nil, nil, -249,
- -249, -249, -249, -249, -249, -249, -249, -249, -249, nil,
- -249, -249, nil, -249, -249, -249, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, -249, nil, nil, -249, 254,
- nil, -249, -249, nil, nil, -249, nil, -249, nil, -249,
- nil, -249, nil, nil, nil, nil, nil, nil, nil, -249,
- nil, nil, nil, nil, -249, -249, -249, -249, -249, -249,
- nil, nil, nil, -249, -249, -478, -478, -478, nil, -478,
- nil, nil, nil, -478, -478, nil, nil, nil, -478, nil,
- -478, -478, -478, -478, -478, -478, -478, nil, nil, nil,
- nil, -478, -478, -478, -478, -478, -478, -478, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, -478, nil, nil,
- -478, -478, -478, -478, -478, -478, -478, -478, -478, -478,
- nil, -478, -478, nil, -478, -478, -478, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, -478, nil, nil, -478,
- -478, nil, -478, -478, nil, nil, -478, nil, -478, nil,
- -478, nil, -478, nil, nil, nil, nil, nil, nil, nil,
- -478, nil, nil, nil, nil, -478, -478, -478, -478, -478,
- -478, nil, nil, nil, -478, -478, -479, -479, -479, nil,
- -479, nil, nil, nil, -479, -479, nil, nil, nil, -479,
- nil, -479, -479, -479, -479, -479, -479, -479, nil, nil,
- nil, nil, -479, -479, -479, -479, -479, -479, -479, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, -479, nil,
- nil, -479, -479, -479, -479, -479, -479, -479, -479, -479,
- -479, nil, -479, -479, nil, -479, -479, -479, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, -479, nil, nil,
- -479, -479, nil, -479, -479, nil, nil, -479, nil, -479,
- nil, -479, nil, -479, nil, nil, nil, nil, nil, nil,
- nil, -479, nil, nil, nil, nil, -479, -479, -479, -479,
- -479, -479, nil, nil, nil, -479, -479, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 28, 27, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- 299, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 275, 279, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 275, 279, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, 560, nil, 243, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, 564, nil, 243, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 23, 24, 65, 66, nil, nil, nil, nil,
- 22, 28, 27, 88, 87, 89, 90, nil, nil, 17,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, 584, nil, 243,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 18,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 28, 27, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, 299, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 207, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 275, 279, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 23, 24, 65,
- 66, nil, nil, nil, nil, 22, 28, 27, 88, 87,
- 89, 90, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 18, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 275, 279, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, 369, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, 612, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, 628, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 28, 27, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, 299, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 207, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 28, 27, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, 299,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, 17, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 18, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 153, 164,
- 154, 177, 150, 170, 160, 159, 180, 181, 175, 158,
- 157, 152, 178, 182, 183, 162, 151, 165, 169, 171,
- 163, 156, nil, nil, 172, 179, 174, 173, 166, 176,
- 161, 149, 168, 167, nil, nil, nil, nil, nil, 148,
- 155, 146, 147, 144, 145, 109, 111, nil, nil, 110,
- nil, nil, nil, nil, nil, nil, nil, 139, 140, nil,
- 137, 121, 122, 123, nil, 126, 128, nil, nil, 124,
- nil, nil, nil, nil, 141, 142, 129, 130, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 134, 133, nil, 120, 138, 136, 135, 131, 132,
- 127, 125, 118, nil, 119, nil, nil, 143, 79, nil,
- nil, 62, 63, 64, nil, 51, nil, nil, 78, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, 679, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 23, 24, 65, 66, nil, nil, nil, nil, 22,
- 28, 27, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 23, 24, 65, 66, nil, nil, nil, nil,
- 22, 28, 27, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 207, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 275, 279, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 276, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, nil, nil, 280,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 273,
- nil, nil, 270, nil, nil, 52, 53, nil, nil, 54,
- nil, 697, nil, 698, nil, nil, nil, nil, nil, nil,
- nil, nil, 699, nil, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 275, 279, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 275, 279, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 28, 27,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, 560, nil, 243, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 23, 24, 65, 66, nil, nil, nil,
- nil, 22, 28, 27, 88, 87, 89, 90, nil, nil,
- 17, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, 38, 39, 37, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 200, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- nil, nil, 40, nil, nil, nil, nil, nil, nil, nil,
- 18, nil, nil, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, nil,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 23, 24, 65, 66, nil,
- nil, nil, nil, 22, 28, 27, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 275, 279, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 275, 279, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, 38,
- 39, 37, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 200, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, nil, nil, nil, nil, 40, nil, nil,
- nil, nil, nil, nil, nil, 207, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 276, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- nil, nil, 280, nil, 215, 219, 224, 225, 226, 221,
- 223, 231, 232, 227, 228, nil, 208, 209, nil, nil,
- 229, 230, 772, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, 212, nil, 218, nil,
- 214, 213, 210, 211, 222, 220, 216, nil, 217, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, 233, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, 780, nil, 243, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, 786, nil, 243, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, 788, nil, 243,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 276, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, nil, nil, 280, nil, 215, 219,
- 224, 225, 226, 221, 223, 231, 232, 227, 228, nil,
- 208, 209, nil, nil, 229, 230, 772, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- 212, nil, 218, nil, 214, 213, 210, 211, 222, 220,
- 216, nil, 217, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, 233,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 23, 24, 65, 66, nil, nil,
- nil, nil, 22, 28, 27, 88, 87, 89, 90, nil,
- nil, 17, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 18, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 275, 279, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, 38, 39, 37, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 200, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- 802, nil, nil, nil, 40, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, nil, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 275, 279, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, nil, nil, nil, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 275, 279, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 276, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, nil,
- nil, 280, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 273, nil, nil, 270, nil, nil, 52, 53, nil,
- nil, 54, nil, 821, nil, 820, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, nil, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, 38, 39, 37, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 200, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, nil, nil,
- 40, nil, nil, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, nil, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, nil, nil, nil,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 276, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, nil, nil, 280, nil, 215, 219,
- 224, 225, 226, 221, 223, 231, 232, 227, 228, nil,
- 208, 209, nil, nil, 229, 230, 772, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- 212, nil, 218, nil, 214, 213, 210, 211, 222, 220,
- 216, nil, 217, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, 233,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 28, 27, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, 299,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 62, 63, 64,
- nil, 51, nil, nil, nil, 56, 57, nil, nil, nil,
- 60, nil, 58, 59, 61, 246, 247, 65, 66, nil,
- nil, nil, nil, 245, 275, 279, 88, 87, 89, 90,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 276,
- nil, nil, 92, 91, 82, 50, 84, 83, 86, 85,
- 93, 94, nil, 80, 81, nil, nil, nil, 280, nil,
- 215, 219, 224, 225, 226, 221, 223, 231, 232, 227,
- 228, nil, 208, 209, nil, nil, 229, 230, 772, nil,
- nil, 204, nil, nil, 52, 53, nil, nil, 54, nil,
- nil, nil, 212, nil, 218, nil, 214, 213, 210, 211,
- 222, 220, 216, nil, 217, nil, nil, 79, 72, 74,
- 75, 76, 77, nil, nil, nil, 73, 78, 62, 63,
- 64, 233, 51, nil, nil, nil, 56, 57, nil, nil,
- nil, 60, nil, 58, 59, 61, 246, 247, 65, 66,
- nil, nil, nil, nil, 245, 275, 279, 88, 87, 89,
- 90, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 41, nil, nil, 92, 91, 82, 50, 84, 83, 86,
- 85, 93, 94, nil, 80, 81, nil, 38, 39, 37,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 200,
- nil, nil, 204, nil, nil, 52, 53, nil, nil, 54,
- nil, 864, nil, 243, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, nil, nil, 79, 72,
- 74, 75, 76, 77, nil, nil, nil, 73, 78, 62,
- 63, 64, nil, 51, nil, nil, nil, 56, 57, nil,
- nil, nil, 60, nil, 58, 59, 61, 246, 247, 65,
- 66, nil, nil, nil, nil, 245, 275, 279, 88, 87,
- 89, 90, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, nil, nil, 92, 91, 82, 50, 84, 83,
- 86, 85, 93, 94, nil, 80, 81, nil, 38, 39,
- 37, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 200, nil, nil, 204, nil, nil, 52, 53, nil, nil,
- 54, nil, 867, nil, 243, nil, 40, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, nil, nil, 79,
- 72, 74, 75, 76, 77, nil, nil, nil, 73, 78,
- 62, 63, 64, nil, 51, nil, nil, nil, 56, 57,
- nil, nil, nil, 60, nil, 58, 59, 61, 246, 247,
- 65, 66, nil, nil, nil, nil, 245, 275, 279, 88,
- 87, 89, 90, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 276, nil, nil, 92, 91, 82, 50, 84,
- 83, 86, 85, 93, 94, nil, 80, 81, nil, nil,
- nil, 280, nil, 215, 219, 224, 225, 226, 221, 223,
- 231, 232, 227, 228, nil, 208, 209, nil, nil, 229,
- 230, 772, nil, nil, 204, nil, nil, 52, 53, nil,
- nil, 54, nil, nil, nil, 212, nil, 218, nil, 214,
- 213, 210, 211, 222, 220, 216, nil, 217, nil, nil,
- 79, 72, 74, 75, 76, 77, nil, nil, nil, 73,
- 78, 62, 63, 64, 233, 51, nil, nil, nil, 56,
- 57, nil, nil, nil, 60, nil, 58, 59, 61, 246,
- 247, 65, 66, nil, nil, nil, nil, 245, 275, 279,
- 88, 87, 89, 90, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, 92, 91, 82, 50,
- 84, 83, 86, 85, 93, 94, nil, 80, 81, nil,
- 38, 39, 37, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 200, nil, nil, 204, nil, nil, 52, 53,
- nil, nil, 54, nil, nil, nil, nil, nil, 40, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 79, 72, 74, 75, 76, 77, nil, nil, nil,
- 73, 78, 62, 63, 64, nil, 51, nil, nil, nil,
- 56, 57, nil, nil, nil, 60, nil, 58, 59, 61,
- 246, 247, 65, 66, nil, nil, nil, nil, 245, 275,
- 279, 88, 87, 89, 90, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 92, 91, 82,
- 50, 84, 83, 86, 85, 93, 94, nil, 80, 81,
- nil, 38, 39, 37, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 200, nil, nil, 204, nil, nil, 52,
- 53, nil, nil, 54, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, 207, nil, nil,
- nil, nil, 79, 72, 74, 75, 76, 77, nil, nil,
- nil, 73, 78, 62, 63, 64, nil, 51, nil, nil,
- nil, 56, 57, nil, nil, nil, 60, nil, 58, 59,
- 61, 246, 247, 65, 66, nil, nil, nil, nil, 245,
- 275, 279, 88, 87, 89, 90, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 276, nil, nil, 92, 91,
- 82, 50, 84, 83, 86, 85, 93, 94, nil, 80,
- 81, nil, nil, nil, 280, nil, 215, 219, 224, 225,
- 226, 221, 223, 231, 232, 227, 228, nil, 208, 209,
- nil, nil, 229, 230, 772, nil, nil, 204, nil, nil,
- 52, 53, nil, nil, 54, nil, nil, nil, 212, nil,
- 218, nil, 214, 213, 210, 211, 222, 220, 216, nil,
- 217, nil, nil, 79, 72, 74, 75, 76, 77, nil,
- nil, nil, 73, 78, 62, 63, 64, 233, 51, nil,
- nil, nil, 56, 57, nil, nil, nil, 60, nil, 58,
- 59, 61, 246, 247, 65, 66, nil, nil, nil, nil,
- 245, 275, 279, 88, 87, 89, 90, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, 92,
- 91, 82, 50, 84, 83, 86, 85, 93, 94, nil,
- 80, 81, nil, 38, 39, 37, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 200, nil, nil, 204, nil,
- nil, 52, 53, nil, nil, 54, nil, 889, nil, 243,
- nil, 40, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 79, 72, 74, 75, 76, 77,
- nil, nil, nil, 73, 78, 62, 63, 64, nil, 51,
- nil, nil, nil, 56, 57, nil, nil, nil, 60, nil,
- 58, 59, 61, 246, 247, 65, 66, nil, nil, nil,
- nil, 245, 275, 279, 88, 87, 89, 90, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 276, nil, nil,
- 92, 91, 82, 50, 84, 83, 86, 85, 93, 94,
- nil, 80, 81, nil, nil, nil, 280, nil, 215, 219,
- 224, 225, 226, 221, 223, 231, 232, 227, 228, nil,
- 208, 209, nil, nil, 229, 230, 772, nil, nil, 204,
- nil, nil, 52, 53, nil, nil, 54, nil, nil, nil,
- 212, nil, 218, nil, 214, 213, 210, 211, 222, 220,
- 216, nil, 217, nil, nil, 79, 72, 74, 75, 76,
- 77, nil, nil, nil, 73, 78, 62, 63, 64, 233,
- 51, nil, nil, nil, 56, 57, nil, nil, nil, 60,
- nil, 58, 59, 61, 246, 247, 65, 66, nil, nil,
- nil, nil, 245, 275, 279, 88, 87, 89, 90, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 41, nil,
- nil, 92, 91, 82, 50, 84, 83, 86, 85, 93,
- 94, nil, 80, 81, nil, 38, 39, 37, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 200, nil, nil,
- 204, nil, nil, 52, 53, nil, nil, 54, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, nil, nil,
- nil, 207, nil, nil, nil, nil, 79, 72, 74, 75,
- 76, 77, nil, nil, nil, 73, 78, 153, 164, 154,
- 177, 150, 170, 160, 159, 180, 181, 175, 158, 157,
- 152, 178, 182, 183, 162, 151, 165, 169, 171, 163,
- 156, nil, nil, 172, 179, 174, 336, 335, 337, 334,
- 149, 168, 167, nil, nil, nil, nil, nil, 148, 155,
- 146, 147, 332, 333, 330, 111, 84, 83, 331, 85,
- nil, nil, nil, nil, nil, nil, 139, 140, nil, 137,
- 121, 122, 123, nil, 126, 128, nil, nil, 124, nil,
- nil, nil, nil, 141, 142, 129, 130, nil, nil, nil,
- nil, nil, 341, nil, nil, nil, nil, nil, nil, nil,
- 134, 133, nil, 120, 138, 136, 135, 131, 132, 127,
- 125, 118, nil, 119, nil, nil, 143, 153, 164, 154,
- 177, 150, 170, 160, 159, 180, 181, 175, 158, 157,
- 152, 178, 182, 183, 162, 151, 165, 169, 171, 163,
- 156, nil, nil, 172, 179, 174, 173, 166, 176, 161,
- 149, 168, 167, nil, nil, nil, nil, nil, 148, 155,
- 146, 147, 144, 145, 109, 111, nil, nil, 110, nil,
- nil, nil, nil, nil, nil, nil, 139, 140, nil, 137,
- 121, 122, 123, nil, 126, 128, nil, nil, 124, nil,
- nil, nil, nil, 141, 142, 129, 130, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 134, 133, nil, 120, 138, 136, 135, 131, 132, 127,
- 125, 118, nil, 119, nil, nil, 143, 215, 219, 224,
- 225, 226, 221, 223, 231, 232, 227, 228, nil, 208,
- 209, nil, nil, 229, 230, nil, nil, nil, -215, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 212,
- nil, 218, nil, 214, 213, 210, 211, 222, 220, 216,
- nil, 217, nil, nil, nil, nil, nil, nil, nil, 376,
- 379, nil, nil, 377, nil, nil, nil, nil, 233, nil,
- -215, 139, 140, nil, 137, 121, 122, 123, nil, 126,
- 128, nil, nil, 124, nil, nil, nil, nil, 141, 142,
- 129, 130, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 134, 133, nil, 120, 138,
- 136, 135, 131, 132, 127, 125, 118, nil, 119, 381,
- 385, 143, nil, 383, nil, nil, nil, nil, nil, nil,
- nil, 139, 140, nil, 137, 121, 122, 123, nil, 126,
- 128, nil, nil, 124, nil, nil, nil, nil, 141, 142,
- 129, 130, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 134, 133, nil, 120, 138,
- 136, 135, 131, 132, 127, 125, 118, nil, 119, 433,
- 379, 143, nil, 434, nil, nil, nil, nil, nil, nil,
- nil, 139, 140, nil, 137, 121, 122, 123, nil, 126,
- 128, nil, nil, 124, nil, nil, nil, nil, 141, 142,
- 129, 130, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 134, 133, nil, 120, 138,
- 136, 135, 131, 132, 127, 125, 118, nil, 119, 433,
- 379, 143, nil, 434, nil, nil, nil, nil, nil, nil,
- nil, 139, 140, nil, 137, 121, 122, 123, nil, 126,
- 128, nil, nil, 124, nil, nil, nil, nil, 141, 142,
- 129, 130, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 134, 133, nil, 120, 138,
- 136, 135, 131, 132, 127, 125, 118, nil, 119, 550,
- 379, 143, nil, 551, nil, nil, nil, nil, nil, nil,
- nil, 139, 140, nil, 137, 121, 122, 123, nil, 126,
- 128, nil, nil, 124, nil, nil, nil, nil, 141, 142,
- 129, 130, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 134, 133, nil, 120, 138,
- 136, 135, 131, 132, 127, 125, 118, nil, 119, 552,
- 385, 143, nil, 553, nil, nil, nil, nil, nil, nil,
- nil, 139, 140, nil, 137, 121, 122, 123, nil, 126,
- 128, nil, nil, 124, nil, nil, nil, nil, 141, 142,
- 129, 130, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 134, 133, nil, 120, 138,
- 136, 135, 131, 132, 127, 125, 118, nil, 119, nil,
- nil, 143, 215, 219, 224, 225, 226, 221, 223, 231,
- 232, 227, 228, nil, 208, 209, nil, nil, 229, 230,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 212, nil, 218, nil, 214, 213,
- 210, 211, 222, 220, 216, nil, 217, nil, nil, nil,
- nil, nil, nil, 594, 379, nil, nil, 595, nil, nil,
- nil, nil, nil, 233, 556, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 597, 385, 143, nil, 598, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 550, 379, 143, nil, 551, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 552, 385, 143, nil, 553, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 630, 379, 143, nil, 631, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 632, 385, 143, nil, 633, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 635, 385, 143, nil, 636, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 433, 379, 143, nil, 434, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 433, 379, 143, nil, 434, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 433, 379, 143, nil, 434, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 857, 379, 143, nil, 858, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, 859, 385, 143, nil, 860, nil, nil,
- nil, nil, nil, nil, nil, 139, 140, nil, 137, 121,
- 122, 123, nil, 126, 128, nil, nil, 124, nil, nil,
- nil, nil, 141, 142, 129, 130, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 134,
- 133, nil, 120, 138, 136, 135, 131, 132, 127, 125,
- 118, nil, 119, nil, nil, 143, 215, 219, 224, 225,
- 226, 221, 223, 231, 232, 227, 228, nil, 208, 209,
- nil, nil, 229, 230, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 212, nil,
- 218, nil, 214, 213, 210, 211, 222, 220, 216, nil,
- 217, nil, 215, 219, 224, 225, 226, 221, 223, 231,
- 232, 227, 228, nil, 208, 209, 291, 233, 229, 230,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 212, nil, 218, nil, 214, 213,
- 210, 211, 222, 220, 216, nil, 217, nil, 215, 219,
- 224, 225, 226, 221, 223, 231, 232, 227, 228, nil,
- 208, 209, 291, 233, 229, 230, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 212, nil, 218, nil, 214, 213, 210, 211, 222, 220,
- 216, nil, 217, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 233 ]
-
-racc_action_check = [
- 381, 512, 512, 518, 518, 306, 755, 381, 381, 381,
- 326, 440, 711, 381, 381, 313, 381, 199, 440, 711,
- 307, 70, 347, 316, 424, 381, 3, 627, 500, 70,
- 1, 3, 201, 603, 603, 381, 381, 630, 381, 381,
- 381, 381, 381, 727, 798, 446, 311, 631, 311, 632,
- 743, 394, 755, 755, 755, 755, 8, 310, 424, 447,
- 440, 711, 310, 199, 381, 381, 381, 381, 381, 381,
- 381, 381, 381, 381, 381, 381, 381, 381, 201, 446,
- 381, 381, 381, 55, 381, 347, 603, 594, 381, 591,
- 512, 381, 518, 447, 491, 512, 381, 394, 381, 633,
- 381, 381, 381, 381, 381, 381, 381, 383, 381, 381,
- 381, 9, 632, 326, 383, 383, 383, 306, 313, 306,
- 383, 383, 306, 383, 381, 381, 316, 381, 591, 381,
- 381, 500, 307, 326, 307, 492, 595, 307, 326, 627,
- 630, 627, 383, 383, 627, 383, 383, 383, 383, 383,
- 631, 594, 632, 743, 582, 727, 798, 727, 798, 744,
- 727, 798, 633, 26, 322, 15, 15, 55, 322, 594,
- 550, 383, 383, 383, 383, 383, 383, 383, 383, 383,
- 383, 383, 383, 383, 383, 574, 277, 383, 383, 383,
- 594, 383, 491, 594, 491, 383, 582, 491, 383, 551,
- 595, 10, 633, 383, 528, 383, 343, 383, 383, 383,
- 383, 383, 383, 383, 50, 383, 550, 383, 595, 574,
- 11, 50, 50, 50, 511, 26, 50, 50, 50, 511,
- 50, 383, 383, 492, 383, 492, 383, 383, 492, 595,
- 50, 50, 595, 297, 12, 551, 297, 26, 277, 50,
- 50, 693, 50, 50, 50, 50, 50, 744, 14, 744,
- 298, 20, 744, 298, 344, 528, 528, 343, 343, 343,
- 277, 301, 108, 34, 301, 528, 108, 108, 50, 50,
- 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
- 50, 50, 345, 13, 50, 50, 50, 693, 36, 50,
- 13, 14, 50, 346, 14, 50, 50, 41, 50, 13,
- 50, 95, 50, 419, 50, 50, 50, 50, 50, 50,
- 50, 432, 50, 184, 50, 344, 344, 344, 432, 432,
- 432, 848, 200, 432, 432, 432, 348, 432, 50, 50,
- 50, 50, 202, 50, 320, 419, 803, 432, 803, 419,
- 419, 419, 419, 345, 345, 345, 432, 432, 203, 432,
- 432, 432, 432, 432, 346, 346, 346, 25, 303, 239,
- 321, 303, 597, 635, 25, 42, 435, 848, 848, 848,
- 848, 240, 42, 435, 435, 435, 330, 857, 435, 435,
- 435, 42, 435, 330, 320, 244, 432, 348, 348, 348,
- 35, 320, 435, 432, 37, 37, 320, 253, 432, 432,
- 320, 435, 435, 264, 435, 435, 435, 435, 435, 283,
- 321, 266, 597, 635, 376, 858, 377, 321, 320, 597,
- 635, 432, 321, 540, 597, 635, 321, 857, 597, 635,
- 267, 400, 268, 35, 857, 432, 35, 432, 401, 857,
- 432, 435, 198, 857, 321, 640, 597, 635, 435, 198,
- 640, 646, 283, 435, 435, 283, 646, 376, 198, 377,
- 376, 857, 377, 400, 271, 858, 540, 400, 400, 540,
- 401, 271, 858, 273, 401, 401, 435, 858, 280, 280,
- 271, 858, 294, 294, 331, 552, 552, 552, 275, 552,
- 435, 331, 435, 552, 552, 435, 276, 859, 552, 858,
- 552, 552, 552, 552, 552, 552, 552, 305, 305, 615,
- 615, 552, 552, 552, 552, 552, 552, 552, 332, 420,
- 279, 333, 334, 758, 758, 332, 284, 552, 333, 334,
- 552, 552, 552, 552, 552, 552, 552, 552, 552, 552,
- 285, 552, 552, 335, 552, 552, 552, 859, 870, 870,
- 335, 420, 288, 336, 859, 420, 420, 420, 420, 859,
- 336, 272, 292, 859, 337, 293, 552, 552, 272, 552,
- 552, 337, 552, 552, 296, 300, 552, 272, 552, 302,
- 552, 859, 552, 312, 339, 274, 286, 314, 315, 317,
- 552, 339, 274, 286, 314, 552, 552, 552, 552, 552,
- 552, 274, 286, 314, 552, 552, 553, 553, 553, 362,
- 553, 363, 368, 552, 553, 553, 371, 375, 382, 553,
- 402, 553, 553, 553, 553, 553, 553, 553, 403, 404,
- 405, 429, 553, 553, 553, 553, 553, 553, 553, 522,
- 522, 438, 522, 522, 522, 439, 441, 442, 553, 448,
- 450, 553, 553, 553, 553, 553, 553, 553, 553, 553,
- 553, 451, 553, 553, 455, 553, 553, 553, 398, 398,
- 398, 398, 398, 398, 398, 398, 398, 398, 398, 324,
- 398, 398, 459, 460, 398, 398, 324, 553, 553, 459,
- 553, 553, 470, 553, 553, 324, 473, 553, 459, 553,
- 398, 553, 398, 553, 398, 398, 398, 398, 398, 398,
- 398, 553, 398, 487, 493, 494, 553, 553, 553, 553,
- 553, 553, 526, 503, 531, 553, 553, 60, 60, 60,
- 503, 60, 543, 547, 553, 60, 60, 554, 561, 503,
- 60, 563, 60, 60, 60, 60, 60, 60, 60, 566,
- 568, 576, 577, 60, 60, 60, 60, 60, 60, 60,
- 583, 586, 60, 593, 596, 599, 601, 366, 602, 60,
- 604, 607, 60, 60, 60, 60, 60, 60, 60, 60,
- 60, 60, 608, 60, 60, 611, 60, 60, 60, 366,
- 366, 366, 366, 366, 366, 366, 366, 366, 366, 366,
- 598, 366, 366, 721, 617, 366, 366, 598, 60, 623,
- 721, 60, 598, 625, 60, 60, 598, 626, 60, 721,
- 629, 366, 638, 366, 60, 366, 366, 366, 366, 366,
- 366, 366, 60, 366, 643, 647, 648, 60, 60, 60,
- 60, 60, 60, 649, 655, 660, 60, 60, 663, 60,
- 366, 665, 366, 636, 60, 97, 97, 97, 97, 97,
- 636, 678, 696, 97, 97, 636, 700, 701, 97, 636,
- 97, 97, 97, 97, 97, 97, 97, 702, 705, 709,
- 710, 97, 97, 97, 97, 97, 97, 97, 712, 716,
- 97, 4, 4, 4, 4, 4, 97, 97, 97, 97,
- 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
- 718, 97, 97, 719, 97, 97, 97, 399, 399, 399,
- 399, 399, 399, 399, 399, 399, 399, 399, 770, 399,
- 399, 771, 720, 399, 399, 770, 97, 732, 771, 97,
- 735, 746, 97, 97, 770, 750, 97, 771, 97, 399,
- 751, 399, 97, 399, 399, 399, 399, 399, 399, 399,
- 97, 399, 764, 772, 774, 97, 97, 97, 97, 97,
- 97, 775, 773, 782, 97, 97, 697, 697, 697, 773,
- 697, 783, 97, 825, 697, 697, 784, 787, 773, 697,
- 825, 697, 697, 697, 697, 697, 697, 697, 800, 825,
- 801, 806, 697, 697, 697, 697, 697, 697, 697, 106,
- 106, 106, 106, 106, 808, 809, 810, 813, 697, 814,
- 826, 697, 697, 697, 697, 697, 697, 697, 697, 697,
- 697, 833, 697, 697, 410, 836, 514, 697, 514, 514,
- 514, 514, 860, 837, 854, 876, 855, 856, 865, 860,
- 410, 410, 876, 871, 860, 872, 873, 697, 860, 874,
- 697, 876, 878, 697, 697, 881, 410, 697, 410, 892,
- 410, 410, 410, 410, 514, nil, 410, nil, 410, nil,
- nil, nil, 514, 514, 514, 514, 697, 697, 697, 697,
- 697, 697, nil, nil, nil, 697, 697, nil, 821, 821,
- 821, 697, 821, nil, nil, nil, 821, 821, nil, nil,
- nil, 821, nil, 821, 821, 821, 821, 821, 821, 821,
- nil, nil, nil, nil, 821, 821, 821, 821, 821, 821,
- 821, 350, 350, 350, 350, 350, nil, nil, 555, nil,
- 821, nil, nil, 821, 821, 821, 821, 821, 821, 821,
- 821, 821, 821, nil, 821, 821, nil, nil, nil, 821,
- 555, 555, 555, 555, 555, 555, 555, 555, 555, 555,
- 555, nil, 555, 555, nil, nil, 555, 555, nil, 821,
- nil, nil, 821, nil, nil, 821, 821, nil, nil, 821,
- nil, nil, 555, nil, 555, nil, 555, 555, 555, 555,
- 555, 555, 555, nil, 555, nil, nil, nil, 821, 821,
- 821, 821, 821, 821, nil, nil, nil, 821, 821, nil,
- nil, 555, nil, 821, 0, 0, 0, 0, 0, 0,
- nil, nil, nil, 0, 0, nil, nil, nil, 0, nil,
- 0, 0, 0, 0, 0, 0, 0, nil, nil, nil,
- nil, 0, 0, 0, 0, 0, 0, 0, nil, nil,
- 0, nil, nil, nil, nil, nil, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- nil, 0, 0, nil, 0, 0, 0, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 0, nil, nil, 0,
- nil, nil, 0, 0, nil, nil, 0, nil, 0, nil,
- nil, nil, 0, 645, nil, 645, 645, 645, 645, nil,
- 0, nil, nil, nil, nil, 0, 0, 0, 0, 0,
- 0, nil, nil, nil, 0, 0, 30, 30, 30, 30,
- 30, 30, nil, nil, nil, 30, 30, nil, nil, nil,
- 30, nil, 30, 30, 30, 30, 30, 30, 30, 645,
- 645, 645, 645, 30, 30, 30, 30, 30, 30, 30,
- nil, nil, 30, nil, nil, nil, nil, nil, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, nil, 30, 30, nil, 30, 30, 30, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 30, nil,
- nil, 30, nil, nil, 30, 30, nil, nil, 30, nil,
- 30, nil, nil, nil, 30, 753, nil, 753, 753, 753,
- 753, nil, 30, nil, nil, nil, nil, 30, 30, 30,
- 30, 30, 30, nil, nil, nil, 30, 30, 51, 51,
- 51, 51, 51, 51, nil, nil, nil, 51, 51, nil,
- nil, nil, 51, nil, 51, 51, 51, 51, 51, 51,
- 51, 753, 753, 753, 753, 51, 51, 51, 51, 51,
- 51, 51, nil, nil, 51, nil, nil, nil, nil, nil,
- 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, nil, 51, 51, nil, 51, 51,
- 51, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 51, nil, nil, 51, nil, nil, 51, 51, nil, nil,
- 51, nil, 51, nil, nil, nil, 51, 817, nil, 817,
- 817, 817, 817, nil, 51, nil, nil, nil, nil, 51,
- 51, 51, 51, 51, 51, nil, nil, nil, 51, 51,
- 186, 186, 186, 186, 186, 186, nil, nil, nil, 186,
- 186, nil, nil, nil, 186, 817, 186, 186, 186, 186,
- 186, 186, 186, 817, 817, 817, 817, 186, 186, 186,
- 186, 186, 186, 186, nil, nil, 186, nil, nil, nil,
- nil, nil, 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 186, 186, 186, 186, 186, nil, 186, 186, nil,
- 186, 186, 186, 409, 409, 409, 409, 409, 409, 409,
- nil, nil, 409, 409, nil, nil, nil, nil, nil, 409,
- 409, nil, 186, nil, nil, 186, nil, nil, 186, 186,
- nil, nil, 186, nil, 186, 409, nil, 409, 186, 409,
- 409, 409, 409, 409, 409, 409, 186, 409, nil, nil,
- nil, 186, 186, 186, 186, 186, 186, nil, nil, nil,
- 186, 186, 187, 187, 187, 187, 187, 187, nil, nil,
- nil, 187, 187, nil, nil, nil, 187, nil, 187, 187,
- 187, 187, 187, 187, 187, nil, nil, nil, nil, 187,
- 187, 187, 187, 187, 187, 187, nil, nil, 187, nil,
- nil, nil, nil, nil, 187, 187, 187, 187, 187, 187,
- 187, 187, 187, 187, 187, 187, 187, 187, nil, 187,
- 187, nil, 187, 187, 187, 411, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 411, 411, nil, 187, nil, nil, 187, nil, nil,
- 187, 187, nil, nil, 187, nil, 187, 411, nil, 411,
- 187, 411, 411, 411, 411, nil, nil, 411, 187, 411,
- nil, nil, nil, 187, 187, 187, 187, 187, 187, nil,
- nil, nil, 187, 187, 204, 204, 204, 204, 204, 204,
- nil, nil, nil, 204, 204, nil, nil, nil, 204, nil,
- 204, 204, 204, 204, 204, 204, 204, nil, nil, nil,
- nil, 204, 204, 204, 204, 204, 204, 204, nil, nil,
- 204, nil, nil, nil, nil, nil, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204, 204, 204,
- nil, 204, 204, nil, 204, 204, 204, 412, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 412, 412, nil, 204, nil, nil, 204,
- nil, nil, 204, 204, nil, nil, 204, nil, 204, 412,
- nil, 412, 204, 412, 412, 412, 412, nil, nil, 412,
- 204, 412, nil, nil, nil, 204, 204, 204, 204, 204,
- 204, nil, nil, nil, 204, 204, 265, 265, 265, 265,
- 265, 265, nil, nil, nil, 265, 265, nil, nil, nil,
- 265, nil, 265, 265, 265, 265, 265, 265, 265, nil,
- nil, nil, nil, 265, 265, 265, 265, 265, 265, 265,
- nil, nil, 265, nil, nil, nil, nil, nil, 265, 265,
- 265, 265, 265, 265, 265, 265, 265, 265, 265, 265,
- 265, 265, nil, 265, 265, nil, 265, 265, 265, 413,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 413, 413, nil, 265, nil,
- nil, 265, nil, nil, 265, 265, nil, nil, 265, nil,
- 265, 413, nil, 413, 265, 413, 413, 413, 413, nil,
- nil, 413, 265, 413, nil, nil, nil, 265, 265, 265,
- 265, 265, 265, nil, nil, nil, 265, 265, 270, 270,
- 270, 270, 270, 270, nil, nil, nil, 270, 270, nil,
- nil, nil, 270, nil, 270, 270, 270, 270, 270, 270,
- 270, nil, nil, nil, nil, 270, 270, 270, 270, 270,
- 270, 270, nil, nil, 270, nil, nil, nil, nil, nil,
- 270, 270, 270, 270, 270, 270, 270, 270, 270, 270,
- 270, 270, 270, 270, nil, 270, 270, nil, 270, 270,
- 270, 414, 414, 414, 414, 414, 414, 414, nil, nil,
- 414, 414, nil, nil, nil, nil, nil, 414, 414, nil,
- 270, nil, nil, 270, nil, nil, 270, 270, nil, nil,
- 270, nil, 270, 414, nil, 414, 270, 414, 414, 414,
- 414, 414, 414, 414, 270, 414, nil, nil, nil, 270,
- 270, 270, 270, 270, 270, nil, nil, nil, 270, 270,
- 486, 486, 486, 486, 486, 486, nil, nil, nil, 486,
- 486, nil, nil, nil, 486, nil, 486, 486, 486, 486,
- 486, 486, 486, nil, nil, nil, nil, 486, 486, 486,
- 486, 486, 486, 486, nil, nil, 486, nil, nil, nil,
- nil, nil, 486, 486, 486, 486, 486, 486, 486, 486,
- 486, 486, 486, 486, 486, 486, nil, 486, 486, nil,
- 486, 486, 486, 415, 415, 415, 415, 415, 415, 415,
- nil, nil, 415, 415, nil, nil, nil, nil, nil, 415,
- 415, nil, 486, nil, nil, 486, nil, nil, 486, 486,
- nil, nil, 486, nil, 486, 415, nil, 415, 486, 415,
- 415, 415, 415, 415, 415, 415, 486, 415, nil, nil,
- nil, 486, 486, 486, 486, 486, 486, nil, nil, nil,
- 486, 486, 490, 490, 490, 490, 490, 490, nil, nil,
- nil, 490, 490, nil, nil, nil, 490, nil, 490, 490,
- 490, 490, 490, 490, 490, nil, nil, nil, nil, 490,
- 490, 490, 490, 490, 490, 490, nil, nil, 490, nil,
- nil, nil, nil, nil, 490, 490, 490, 490, 490, 490,
- 490, 490, 490, 490, 490, 490, 490, 490, nil, 490,
- 490, nil, 490, 490, 490, 416, 416, 416, 416, 416,
- 416, 416, nil, nil, 416, 416, nil, nil, nil, nil,
- nil, 416, 416, nil, 490, nil, nil, 490, nil, nil,
- 490, 490, nil, nil, 490, nil, 490, 416, nil, 416,
- 490, 416, 416, 416, 416, 416, 416, 416, 490, 416,
- nil, nil, nil, 490, 490, 490, 490, 490, 490, nil,
- nil, nil, 490, 490, 495, 495, 495, 495, 495, 495,
- nil, nil, nil, 495, 495, nil, nil, nil, 495, nil,
- 495, 495, 495, 495, 495, 495, 495, nil, nil, nil,
- nil, 495, 495, 495, 495, 495, 495, 495, nil, nil,
- 495, nil, nil, nil, nil, nil, 495, 495, 495, 495,
- 495, 495, 495, 495, 495, 495, 495, 495, 495, 495,
- nil, 495, 495, nil, 495, 495, 495, 417, 417, 417,
- 417, 417, 417, 417, nil, nil, 417, 417, nil, nil,
- nil, nil, nil, 417, 417, nil, 495, nil, nil, 495,
- nil, nil, 495, 495, nil, nil, 495, nil, 495, 417,
- nil, 417, 495, 417, 417, 417, 417, 417, 417, 417,
- 495, 417, nil, nil, nil, 495, 495, 495, 495, 495,
- 495, nil, nil, nil, 495, 495, 513, 513, 513, 513,
- 513, 513, nil, nil, nil, 513, 513, nil, nil, nil,
- 513, nil, 513, 513, 513, 513, 513, 513, 513, nil,
- nil, nil, nil, 513, 513, 513, 513, 513, 513, 513,
- nil, nil, 513, nil, nil, nil, nil, nil, 513, 513,
- 513, 513, 513, 513, 513, 513, 513, 513, 513, 513,
- 513, 513, nil, 513, 513, nil, 513, 513, 513, 418,
- 418, 418, 418, 418, 418, 418, nil, nil, 418, 418,
- nil, nil, nil, nil, nil, 418, 418, nil, 513, nil,
- nil, 513, nil, nil, 513, 513, nil, nil, 513, nil,
- 513, 418, nil, 418, 513, 418, 418, 418, 418, 418,
- 418, 418, 513, 418, nil, nil, nil, 513, 513, 513,
- 513, 513, 513, nil, nil, nil, 513, 513, 559, 559,
- 559, 559, 559, 559, nil, nil, nil, 559, 559, nil,
- nil, nil, 559, nil, 559, 559, 559, 559, 559, 559,
- 559, nil, nil, nil, nil, 559, 559, 559, 559, 559,
- 559, 559, nil, nil, 559, nil, nil, nil, nil, nil,
- 559, 559, 559, 559, 559, 559, 559, 559, 559, 559,
- 559, 559, 559, 559, nil, 559, 559, nil, 559, 559,
- 559, 421, 421, 421, 421, 421, 421, 421, nil, nil,
- 421, 421, nil, nil, nil, nil, nil, 421, 421, nil,
- 559, nil, nil, 559, nil, nil, 559, 559, nil, nil,
- 559, nil, 559, 421, nil, 421, 559, 421, 421, 421,
- 421, 421, 421, 421, 559, 421, nil, nil, nil, 559,
- 559, 559, 559, 559, 559, nil, nil, nil, 559, 559,
- 588, 588, 588, 588, 588, 588, nil, nil, nil, 588,
- 588, nil, nil, nil, 588, nil, 588, 588, 588, 588,
- 588, 588, 588, nil, nil, nil, nil, 588, 588, 588,
- 588, 588, 588, 588, nil, nil, 588, nil, nil, nil,
- nil, nil, 588, 588, 588, 588, 588, 588, 588, 588,
- 588, 588, 588, 588, 588, 588, nil, 588, 588, nil,
- 588, 588, 588, 422, 422, 422, 422, 422, 422, 422,
- 422, nil, 422, 422, nil, nil, nil, nil, nil, 422,
- 422, nil, 588, nil, nil, 588, nil, nil, 588, 588,
- nil, nil, 588, nil, 588, 422, nil, 422, 588, 422,
- 422, 422, 422, 422, 422, 422, 588, 422, nil, nil,
- nil, 588, 588, 588, 588, 588, 588, nil, nil, nil,
- 588, 588, 589, 589, 589, 589, 589, 589, nil, nil,
- nil, 589, 589, nil, nil, nil, 589, nil, 589, 589,
- 589, 589, 589, 589, 589, nil, nil, nil, nil, 589,
- 589, 589, 589, 589, 589, 589, nil, nil, 589, nil,
- nil, nil, nil, nil, 589, 589, 589, 589, 589, 589,
- 589, 589, 589, 589, 589, 589, 589, 589, nil, 589,
- 589, nil, 589, 589, 589, 406, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 406, 406, nil, 589, nil, nil, 589, nil, nil,
- 589, 589, nil, nil, 589, nil, 589, 406, nil, 406,
- 589, 406, 406, 406, 406, nil, nil, nil, 589, nil,
- nil, nil, nil, 589, 589, 589, 589, 589, 589, nil,
- nil, nil, 589, 589, 606, 606, 606, 606, 606, 606,
- nil, nil, nil, 606, 606, nil, nil, nil, 606, nil,
- 606, 606, 606, 606, 606, 606, 606, nil, nil, nil,
- nil, 606, 606, 606, 606, 606, 606, 606, nil, nil,
- 606, nil, nil, nil, nil, nil, 606, 606, 606, 606,
- 606, 606, 606, 606, 606, 606, 606, 606, 606, 606,
- nil, 606, 606, nil, 606, 606, 606, 407, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 407, 407, nil, 606, nil, nil, 606,
- nil, nil, 606, 606, nil, nil, 606, nil, 606, 407,
- nil, 407, 606, 407, 407, 407, 407, nil, nil, nil,
- 606, nil, nil, nil, nil, 606, 606, 606, 606, 606,
- 606, nil, nil, nil, 606, 606, 639, 639, 639, 639,
- 639, 639, nil, nil, nil, 639, 639, nil, nil, nil,
- 639, nil, 639, 639, 639, 639, 639, 639, 639, nil,
- nil, nil, nil, 639, 639, 639, 639, 639, 639, 639,
- nil, nil, 639, nil, nil, nil, nil, nil, 639, 639,
- 639, 639, 639, 639, 639, 639, 639, 639, 639, 639,
- 639, 639, nil, 639, 639, nil, 639, 639, 639, 408,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 408, 408, nil, 639, nil,
- nil, 639, nil, nil, 639, 639, nil, nil, 639, nil,
- 639, 408, nil, nil, 639, 408, 408, 408, 408, nil,
- nil, nil, 639, nil, nil, nil, nil, 639, 639, 639,
- 639, 639, 639, nil, nil, nil, 639, 639, 644, 644,
- 644, 644, 644, 644, nil, nil, nil, 644, 644, nil,
- nil, nil, 644, nil, 644, 644, 644, 644, 644, 644,
- 644, nil, nil, nil, nil, 644, 644, 644, 644, 644,
- 644, 644, nil, nil, 644, nil, nil, nil, nil, nil,
- 644, 644, 644, 644, 644, 644, 644, 644, 644, 644,
- 644, 644, 644, 644, nil, 644, 644, nil, 644, 644,
- 644, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 644, nil, nil, 644, nil, nil, 644, 644, nil, nil,
- 644, nil, 644, nil, nil, nil, 644, nil, nil, nil,
- nil, nil, nil, nil, 644, nil, nil, nil, nil, 644,
- 644, 644, 644, 644, 644, nil, nil, nil, 644, 644,
- 671, 671, 671, 671, 671, 671, nil, nil, nil, 671,
- 671, nil, nil, nil, 671, nil, 671, 671, 671, 671,
- 671, 671, 671, nil, nil, nil, nil, 671, 671, 671,
- 671, 671, 671, 671, nil, nil, 671, nil, nil, nil,
- nil, nil, 671, 671, 671, 671, 671, 671, 671, 671,
- 671, 671, 671, 671, 671, 671, nil, 671, 671, nil,
- 671, 671, 671, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 671, nil, nil, 671, nil, nil, 671, 671,
- nil, nil, 671, nil, 671, nil, nil, nil, 671, nil,
- nil, nil, nil, nil, nil, nil, 671, nil, nil, nil,
- nil, 671, 671, 671, 671, 671, 671, nil, nil, nil,
- 671, 671, 706, 706, 706, 706, 706, 706, nil, nil,
- nil, 706, 706, nil, nil, nil, 706, nil, 706, 706,
- 706, 706, 706, 706, 706, nil, nil, nil, nil, 706,
- 706, 706, 706, 706, 706, 706, nil, nil, 706, nil,
- nil, nil, nil, nil, 706, 706, 706, 706, 706, 706,
- 706, 706, 706, 706, 706, 706, 706, 706, nil, 706,
- 706, nil, 706, 706, 706, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 706, nil, nil, 706, nil, nil,
- 706, 706, nil, nil, 706, nil, 706, nil, nil, nil,
- 706, nil, nil, nil, nil, nil, nil, nil, 706, nil,
- nil, nil, nil, 706, 706, 706, 706, 706, 706, nil,
- nil, nil, 706, 706, 724, 724, 724, 724, 724, 724,
- nil, nil, nil, 724, 724, nil, nil, nil, 724, nil,
- 724, 724, 724, 724, 724, 724, 724, nil, nil, nil,
- nil, 724, 724, 724, 724, 724, 724, 724, nil, nil,
- 724, nil, nil, nil, nil, nil, 724, 724, 724, 724,
- 724, 724, 724, 724, 724, 724, 724, 724, 724, 724,
- nil, 724, 724, nil, 724, 724, 724, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 724, nil, nil, 724,
- nil, nil, 724, 724, nil, nil, 724, nil, 724, nil,
- nil, nil, 724, nil, nil, nil, nil, nil, nil, nil,
- 724, nil, nil, nil, nil, 724, 724, 724, 724, 724,
- 724, nil, nil, nil, 724, 724, 736, 736, 736, 736,
- 736, 736, nil, nil, nil, 736, 736, nil, nil, nil,
- 736, nil, 736, 736, 736, 736, 736, 736, 736, nil,
- nil, nil, nil, 736, 736, 736, 736, 736, 736, 736,
- nil, nil, 736, nil, nil, nil, nil, nil, 736, 736,
- 736, 736, 736, 736, 736, 736, 736, 736, 736, 736,
- 736, 736, nil, 736, 736, nil, 736, 736, 736, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 736, nil,
- nil, 736, nil, nil, 736, 736, nil, nil, 736, nil,
- 736, nil, nil, nil, 736, nil, nil, nil, nil, nil,
- nil, nil, 736, nil, nil, nil, nil, 736, 736, 736,
- 736, 736, 736, nil, nil, nil, 736, 736, 737, 737,
- 737, 737, 737, 737, nil, nil, nil, 737, 737, nil,
- nil, nil, 737, nil, 737, 737, 737, 737, 737, 737,
- 737, nil, nil, nil, nil, 737, 737, 737, 737, 737,
- 737, 737, nil, nil, 737, nil, nil, nil, nil, nil,
- 737, 737, 737, 737, 737, 737, 737, 737, 737, 737,
- 737, 737, 737, 737, nil, 737, 737, nil, 737, 737,
- 737, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 737, nil, nil, 737, nil, nil, 737, 737, nil, nil,
- 737, nil, 737, nil, nil, nil, 737, nil, nil, nil,
- nil, nil, nil, nil, 737, nil, nil, nil, nil, 737,
- 737, 737, 737, 737, 737, nil, nil, nil, 737, 737,
- 741, 741, 741, 741, 741, 741, nil, nil, nil, 741,
- 741, nil, nil, nil, 741, nil, 741, 741, 741, 741,
- 741, 741, 741, nil, nil, nil, nil, 741, 741, 741,
- 741, 741, 741, 741, nil, nil, 741, nil, nil, nil,
- nil, nil, 741, 741, 741, 741, 741, 741, 741, 741,
- 741, 741, 741, 741, 741, 741, nil, 741, 741, nil,
- 741, 741, 741, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 741, nil, nil, 741, nil, nil, 741, 741,
- nil, nil, 741, nil, 741, nil, nil, nil, 741, nil,
- nil, nil, nil, nil, nil, nil, 741, nil, nil, nil,
- nil, 741, 741, 741, 741, 741, 741, nil, nil, nil,
- 741, 741, 748, 748, 748, 748, 748, 748, nil, nil,
- nil, 748, 748, nil, nil, nil, 748, nil, 748, 748,
- 748, 748, 748, 748, 748, nil, nil, nil, nil, 748,
- 748, 748, 748, 748, 748, 748, nil, nil, 748, nil,
- nil, nil, nil, nil, 748, 748, 748, 748, 748, 748,
- 748, 748, 748, 748, 748, 748, 748, 748, nil, 748,
- 748, nil, 748, 748, 748, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 748, nil, nil, 748, nil, nil,
- 748, 748, nil, nil, 748, nil, 748, nil, nil, nil,
- 748, nil, nil, nil, nil, nil, nil, nil, 748, nil,
- nil, nil, nil, 748, 748, 748, 748, 748, 748, nil,
- nil, nil, 748, 748, 794, 794, 794, 794, 794, 794,
- nil, nil, nil, 794, 794, nil, nil, nil, 794, nil,
- 794, 794, 794, 794, 794, 794, 794, nil, nil, nil,
- nil, 794, 794, 794, 794, 794, 794, 794, nil, nil,
- 794, nil, nil, nil, nil, nil, 794, 794, 794, 794,
- 794, 794, 794, 794, 794, 794, 794, 794, 794, 794,
- nil, 794, 794, nil, 794, 794, 794, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 794, nil, nil, 794,
- nil, nil, 794, 794, nil, nil, 794, nil, 794, nil,
- nil, nil, 794, nil, nil, nil, nil, nil, nil, nil,
- 794, nil, nil, nil, nil, 794, 794, 794, 794, 794,
- 794, nil, nil, nil, 794, 794, 838, 838, 838, 838,
- 838, 838, nil, nil, nil, 838, 838, nil, nil, nil,
- 838, nil, 838, 838, 838, 838, 838, 838, 838, nil,
- nil, nil, nil, 838, 838, 838, 838, 838, 838, 838,
- nil, nil, 838, nil, nil, nil, nil, nil, 838, 838,
- 838, 838, 838, 838, 838, 838, 838, 838, 838, 838,
- 838, 838, nil, 838, 838, nil, 838, 838, 838, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 838, nil,
- nil, 838, nil, nil, 838, 838, nil, nil, 838, nil,
- 838, nil, nil, nil, 838, nil, nil, nil, nil, nil,
- nil, nil, 838, nil, nil, nil, nil, 838, 838, 838,
- 838, 838, 838, nil, nil, nil, 838, 838, 845, 845,
- 845, 845, 845, 845, nil, nil, nil, 845, 845, nil,
- nil, nil, 845, nil, 845, 845, 845, 845, 845, 845,
- 845, nil, nil, nil, nil, 845, 845, 845, 845, 845,
- 845, 845, nil, nil, 845, nil, nil, nil, nil, nil,
- 845, 845, 845, 845, 845, 845, 845, 845, 845, 845,
- 845, 845, 845, 845, nil, 845, 845, nil, 845, 845,
- 845, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 845, nil, nil, 845, nil, nil, 845, 845, nil, nil,
- 845, nil, 845, nil, nil, nil, 845, nil, nil, nil,
- nil, nil, nil, nil, 845, nil, nil, nil, nil, 845,
- 845, 845, 845, 845, 845, nil, nil, nil, 845, 845,
- 852, 852, 852, 852, 852, 852, nil, nil, nil, 852,
- 852, nil, nil, nil, 852, nil, 852, 852, 852, 852,
- 852, 852, 852, nil, nil, nil, nil, 852, 852, 852,
- 852, 852, 852, 852, nil, nil, 852, nil, nil, nil,
- nil, nil, 852, 852, 852, 852, 852, 852, 852, 852,
- 852, 852, 852, 852, 852, 852, nil, 852, 852, nil,
- 852, 852, 852, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 852, nil, nil, 852, nil, nil, 852, 852,
- nil, nil, 852, nil, 852, nil, nil, nil, 852, nil,
- nil, nil, nil, nil, nil, nil, 852, nil, nil, nil,
- nil, 852, 852, 852, 852, 852, 852, nil, nil, nil,
- 852, 852, 5, 5, 5, 5, 5, nil, nil, nil,
- 5, 5, nil, nil, nil, 5, nil, 5, 5, 5,
- 5, 5, 5, 5, nil, nil, nil, nil, 5, 5,
- 5, 5, 5, 5, 5, nil, nil, 5, nil, nil,
- nil, nil, nil, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, nil, 5, 5,
- nil, 5, 5, 5, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 5, nil, nil, 5, nil, nil, 5,
- 5, nil, nil, 5, nil, 5, nil, nil, nil, 5,
- nil, nil, nil, nil, nil, nil, nil, 5, nil, nil,
- nil, nil, 5, 5, 5, 5, 5, 5, nil, nil,
- nil, 5, 5, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, nil, nil, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, nil,
- nil, nil, nil, nil, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, nil, 6, nil, nil, nil, nil, nil,
- nil, nil, 6, 6, nil, 6, 6, 6, 6, nil,
- 6, 6, nil, nil, 6, nil, nil, nil, nil, 6,
- 6, 6, 6, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 6, 6, nil, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, nil, 6,
- nil, nil, 6, 6, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 6, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, nil, nil,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- nil, nil, nil, nil, nil, 7, 7, 7, 7, 7,
- 7, 7, 7, nil, nil, 7, nil, nil, nil, nil,
- nil, nil, nil, 7, 7, nil, 7, 7, 7, 7,
- nil, 7, 7, nil, nil, 7, nil, nil, nil, nil,
- 7, 7, 7, 7, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 7, 7, nil,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, nil,
- 7, nil, nil, 7, 7, nil, nil, 17, 17, 17,
- nil, 17, nil, nil, 7, 17, 17, nil, nil, nil,
- 17, nil, 17, 17, 17, 17, 17, 17, 17, nil,
- nil, nil, nil, 17, 17, 17, 17, 17, 17, 17,
- nil, nil, 17, nil, nil, nil, nil, nil, nil, 17,
- nil, nil, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 17, nil, 17, 17, nil, 17, 17, 17, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 17, nil,
- nil, 17, nil, nil, 17, 17, nil, nil, 17, nil,
- nil, nil, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, nil, 17, nil, nil, nil, nil, 17, 17, 17,
- 17, 17, 17, nil, nil, nil, 17, 17, 18, 18,
- 18, nil, 18, nil, nil, nil, 18, 18, nil, nil,
- nil, 18, nil, 18, 18, 18, 18, 18, 18, 18,
- nil, nil, nil, nil, 18, 18, 18, 18, 18, 18,
- 18, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 18, nil, nil, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, nil, 18, 18, nil, 18, 18, 18,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 18,
- nil, nil, 18, nil, nil, 18, 18, nil, nil, 18,
- nil, nil, nil, nil, nil, 18, nil, nil, nil, nil,
- nil, nil, nil, 18, nil, nil, nil, nil, 18, 18,
- 18, 18, 18, 18, nil, nil, nil, 18, 18, 22,
- 22, 22, nil, 22, nil, nil, nil, 22, 22, nil,
- nil, nil, 22, nil, 22, 22, 22, 22, 22, 22,
- 22, nil, nil, nil, nil, 22, 22, 22, 22, 22,
- 22, 22, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 22, nil, nil, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, nil, 22, 22, nil, 22, 22,
- 22, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 22, nil, nil, 22, nil, nil, 22, 22, nil, nil,
- 22, nil, 22, nil, 22, nil, 22, nil, nil, nil,
- nil, nil, nil, nil, 22, nil, nil, nil, nil, 22,
- 22, 22, 22, 22, 22, nil, nil, nil, 22, 22,
- 23, 23, 23, nil, 23, nil, nil, nil, 23, 23,
- nil, nil, nil, 23, nil, 23, 23, 23, 23, 23,
- 23, 23, nil, nil, nil, nil, 23, 23, 23, 23,
- 23, 23, 23, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 23, nil, nil, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, nil, 23, 23, nil, 23,
- 23, 23, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 23, nil, nil, 23, nil, nil, 23, 23, nil,
- nil, 23, nil, 23, nil, 23, nil, 23, nil, nil,
- nil, nil, nil, nil, nil, 23, nil, nil, nil, nil,
- 23, 23, 23, 23, 23, 23, nil, nil, nil, 23,
- 23, 24, 24, 24, nil, 24, nil, nil, nil, 24,
- 24, nil, nil, nil, 24, nil, 24, 24, 24, 24,
- 24, 24, 24, nil, nil, nil, nil, 24, 24, 24,
- 24, 24, 24, 24, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 24, nil, nil, 24, 24, 24, 24,
- 24, 24, 24, 24, 24, 24, nil, 24, 24, nil,
- 24, 24, 24, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 24, nil, nil, 24, nil, nil, 24, 24,
- nil, nil, 24, nil, 24, nil, 24, nil, 24, nil,
- nil, nil, nil, nil, nil, nil, 24, nil, nil, nil,
- nil, 24, 24, 24, 24, 24, 24, nil, nil, nil,
- 24, 24, 27, 27, 27, nil, 27, nil, nil, nil,
- 27, 27, nil, nil, nil, 27, nil, 27, 27, 27,
- 27, 27, 27, 27, nil, nil, nil, nil, 27, 27,
- 27, 27, 27, 27, 27, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 27, nil, nil, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, nil, 27, 27,
- nil, 27, 27, 27, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 27, nil, nil, 27, 27, nil, 27,
- 27, nil, nil, 27, nil, 27, nil, 27, nil, 27,
- nil, nil, nil, nil, nil, nil, nil, 27, nil, nil,
- nil, nil, 27, 27, 27, 27, 27, 27, nil, nil,
- nil, 27, 27, 28, 28, 28, nil, 28, nil, nil,
- nil, 28, 28, nil, nil, nil, 28, nil, 28, 28,
- 28, 28, 28, 28, 28, nil, nil, nil, nil, 28,
- 28, 28, 28, 28, 28, 28, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 28, nil, nil, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28, nil, 28,
- 28, nil, 28, 28, 28, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 28, nil, nil, 28, 28, nil,
- 28, 28, nil, nil, 28, nil, 28, nil, 28, nil,
- 28, nil, nil, nil, nil, nil, nil, nil, 28, nil,
- nil, nil, nil, 28, 28, 28, 28, 28, 28, nil,
- nil, nil, 28, 28, 31, 31, 31, nil, 31, nil,
- nil, nil, 31, 31, nil, nil, nil, 31, nil, 31,
- 31, 31, 31, 31, 31, 31, nil, nil, nil, nil,
- 31, 31, 31, 31, 31, 31, 31, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 31, nil, nil, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, 31, nil,
- 31, 31, nil, nil, nil, 31, nil, 828, 828, 828,
- 828, 828, 828, 828, 828, 828, 828, 828, nil, 828,
- 828, nil, nil, 828, 828, 31, nil, nil, 31, nil,
- nil, 31, 31, nil, nil, 31, nil, 31, nil, 828,
- nil, 828, nil, 828, 828, 828, 828, 828, 828, 828,
- nil, 828, nil, nil, 31, 31, 31, 31, 31, 31,
- nil, nil, nil, 31, 31, 32, 32, 32, 828, 32,
- 828, nil, nil, 32, 32, nil, nil, nil, 32, nil,
- 32, 32, 32, 32, 32, 32, 32, nil, nil, nil,
- nil, 32, 32, 32, 32, 32, 32, 32, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 32, nil, nil,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- nil, 32, 32, nil, nil, nil, 32, nil, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, nil,
- 19, 19, nil, nil, 19, 19, 32, nil, nil, 32,
- nil, nil, 32, 32, nil, nil, 32, nil, nil, nil,
- 19, nil, 19, nil, 19, 19, 19, 19, 19, 19,
- 19, nil, 19, nil, nil, 32, 32, 32, 32, 32,
- 32, nil, nil, nil, 32, 32, 38, 38, 38, 19,
- 38, nil, nil, nil, 38, 38, nil, nil, nil, 38,
- nil, 38, 38, 38, 38, 38, 38, 38, nil, nil,
- nil, nil, 38, 38, 38, 38, 38, 38, 38, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 38, nil,
- nil, 38, 38, 38, 38, 38, 38, 38, 38, 38,
- 38, nil, 38, 38, nil, 38, 38, 38, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 38, nil, nil,
- 38, nil, nil, 38, 38, nil, nil, 38, nil, nil,
- nil, nil, nil, 38, nil, nil, nil, nil, nil, nil,
- nil, 38, nil, nil, nil, nil, 38, 38, 38, 38,
- 38, 38, nil, nil, nil, 38, 38, 39, 39, 39,
- nil, 39, nil, nil, nil, 39, 39, nil, nil, nil,
- 39, nil, 39, 39, 39, 39, 39, 39, 39, nil,
- nil, nil, nil, 39, 39, 39, 39, 39, 39, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 39,
- nil, nil, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, nil, 39, 39, nil, 39, 39, 39, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 39, nil,
- nil, 39, nil, nil, 39, 39, nil, nil, 39, nil,
- nil, nil, nil, nil, 39, nil, nil, nil, nil, nil,
- nil, nil, 39, nil, nil, nil, nil, 39, 39, 39,
- 39, 39, 39, nil, nil, nil, 39, 39, 40, 40,
- 40, nil, 40, nil, nil, nil, 40, 40, nil, nil,
- nil, 40, nil, 40, 40, 40, 40, 40, 40, 40,
- nil, nil, nil, nil, 40, 40, 40, 40, 40, 40,
- 40, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 40, nil, nil, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, nil, 40, 40, nil, 40, 40, 40,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 40,
- nil, nil, 40, nil, nil, 40, 40, nil, nil, 40,
- nil, nil, nil, nil, nil, 40, nil, nil, nil, nil,
- nil, nil, nil, 40, nil, nil, nil, nil, 40, 40,
- 40, 40, 40, 40, nil, nil, nil, 40, 40, 52,
- 52, 52, nil, 52, nil, nil, nil, 52, 52, nil,
- nil, nil, 52, nil, 52, 52, 52, 52, 52, 52,
- 52, nil, nil, nil, nil, 52, 52, 52, 52, 52,
- 52, 52, nil, nil, 52, nil, nil, nil, nil, nil,
- nil, 52, nil, nil, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, nil, 52, 52, nil, 52, 52,
- 52, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 52, nil, nil, 52, nil, nil, 52, 52, nil, nil,
- 52, nil, nil, nil, nil, nil, 52, nil, nil, nil,
- nil, nil, nil, nil, 52, nil, nil, nil, nil, 52,
- 52, 52, 52, 52, 52, nil, nil, nil, 52, 52,
- 53, 53, 53, nil, 53, nil, nil, nil, 53, 53,
- nil, nil, nil, 53, nil, 53, 53, 53, 53, 53,
- 53, 53, nil, nil, nil, nil, 53, 53, 53, 53,
- 53, 53, 53, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 53, nil, nil, 53, 53, 53, 53, 53,
- 53, 53, 53, 53, 53, nil, 53, 53, nil, 53,
- 53, 53, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 53, nil, nil, 53, nil, nil, 53, 53, nil,
- nil, 53, nil, 53, nil, nil, nil, 53, nil, nil,
- nil, nil, nil, nil, nil, 53, nil, nil, nil, nil,
- 53, 53, 53, 53, 53, 53, nil, nil, nil, 53,
- 53, 54, 54, 54, nil, 54, nil, nil, nil, 54,
- 54, nil, nil, nil, 54, nil, 54, 54, 54, 54,
- 54, 54, 54, nil, nil, nil, nil, 54, 54, 54,
- 54, 54, 54, 54, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 54, nil, nil, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, nil, 54, 54, nil,
- 54, 54, 54, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 54, nil, nil, 54, nil, nil, 54, 54,
- nil, nil, 54, nil, nil, nil, nil, nil, 54, nil,
- nil, nil, nil, nil, nil, nil, 54, nil, nil, nil,
- nil, 54, 54, 54, 54, 54, 54, nil, nil, nil,
- 54, 54, 56, 56, 56, nil, 56, nil, nil, nil,
- 56, 56, nil, nil, nil, 56, nil, 56, 56, 56,
- 56, 56, 56, 56, nil, nil, nil, nil, 56, 56,
- 56, 56, 56, 56, 56, nil, nil, 56, nil, nil,
- nil, nil, nil, nil, 56, nil, nil, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, nil, 56, 56,
- nil, 56, 56, 56, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 56, nil, nil, 56, nil, nil, 56,
- 56, nil, nil, 56, nil, nil, nil, nil, nil, 56,
- nil, nil, nil, nil, nil, nil, nil, 56, nil, nil,
- nil, nil, 56, 56, 56, 56, 56, 56, nil, nil,
- nil, 56, 56, 57, 57, 57, nil, 57, nil, nil,
- nil, 57, 57, nil, nil, nil, 57, nil, 57, 57,
- 57, 57, 57, 57, 57, nil, nil, nil, nil, 57,
- 57, 57, 57, 57, 57, 57, nil, nil, 57, nil,
- nil, nil, nil, nil, nil, 57, nil, nil, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, nil, 57,
- 57, nil, 57, 57, 57, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 57, nil, nil, 57, nil, nil,
- 57, 57, nil, nil, 57, nil, nil, nil, nil, nil,
- 57, nil, nil, nil, nil, nil, nil, nil, 57, nil,
- nil, nil, nil, 57, 57, 57, 57, 57, 57, nil,
- nil, nil, 57, 57, 61, 61, 61, nil, 61, nil,
- nil, nil, 61, 61, nil, nil, nil, 61, nil, 61,
- 61, 61, 61, 61, 61, 61, nil, nil, nil, nil,
- 61, 61, 61, 61, 61, 61, 61, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 61, nil, nil, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, nil,
- 61, 61, nil, nil, nil, 61, nil, 237, 237, 237,
- 237, 237, 237, 237, 237, 237, 237, 237, nil, 237,
- 237, nil, nil, 237, 237, 61, nil, nil, 61, nil,
- nil, 61, 61, nil, nil, 61, nil, 61, nil, 237,
- nil, 237, nil, 237, 237, 237, 237, 237, 237, 237,
- nil, 237, nil, nil, 61, 61, 61, 61, 61, 61,
- nil, nil, nil, 61, 61, 62, 62, 62, 237, 62,
- nil, nil, nil, 62, 62, nil, nil, nil, 62, nil,
- 62, 62, 62, 62, 62, 62, 62, nil, nil, nil,
- nil, 62, 62, 62, 62, 62, 62, 62, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 62, nil, nil,
- 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
- nil, 62, 62, nil, nil, nil, 62, nil, 374, 374,
- 374, 374, 374, 374, 374, 374, 374, 374, 374, nil,
- 374, 374, nil, 62, 374, 374, 62, nil, nil, 62,
- nil, nil, 62, 62, nil, nil, 62, nil, nil, nil,
- 374, nil, 374, nil, 374, 374, 374, 374, 374, 374,
- 374, nil, 374, nil, nil, 62, 62, 62, 62, 62,
- 62, nil, nil, nil, 62, 62, 63, 63, 63, 374,
- 63, nil, nil, nil, 63, 63, nil, nil, nil, 63,
- nil, 63, 63, 63, 63, 63, 63, 63, nil, nil,
- nil, nil, 63, 63, 63, 63, 63, 63, 63, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 63, nil,
- nil, 63, 63, 63, 63, 63, 63, 63, 63, 63,
- 63, nil, 63, 63, nil, nil, nil, 63, nil, 388,
- 388, 388, 388, 388, 388, 388, 388, 388, 388, 388,
- nil, 388, 388, nil, nil, 388, 388, 63, nil, nil,
- 63, nil, nil, 63, 63, nil, nil, 63, nil, nil,
- nil, 388, nil, 388, nil, 388, 388, 388, 388, 388,
- 388, 388, nil, 388, nil, nil, 63, 63, 63, 63,
- 63, 63, nil, nil, nil, 63, 63, 82, 82, 82,
- 388, 82, nil, nil, nil, 82, 82, nil, nil, nil,
- 82, nil, 82, 82, 82, 82, 82, 82, 82, nil,
- 82, nil, nil, 82, 82, 82, 82, 82, 82, 82,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 82,
- nil, nil, 82, 82, 82, 82, 82, 82, 82, 82,
- 82, 82, nil, 82, 82, nil, 82, 82, 82, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 82, nil,
- nil, 82, 82, nil, 82, 82, nil, nil, 82, nil,
- 82, nil, 82, nil, 82, nil, nil, nil, nil, nil,
- nil, nil, 82, nil, 82, nil, nil, 82, 82, 82,
- 82, 82, 82, nil, nil, nil, 82, 82, 86, 86,
- 86, nil, 86, nil, nil, nil, 86, 86, nil, nil,
- nil, 86, nil, 86, 86, 86, 86, 86, 86, 86,
- nil, 86, nil, nil, 86, 86, 86, 86, 86, 86,
- 86, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 86, nil, nil, 86, 86, 86, 86, 86, 86, 86,
- 86, 86, 86, nil, 86, 86, nil, 86, 86, 86,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 86,
- nil, nil, 86, 86, nil, 86, 86, nil, nil, 86,
- nil, 86, nil, 86, nil, 86, nil, nil, nil, nil,
- nil, nil, nil, 86, nil, 86, nil, nil, 86, 86,
- 86, 86, 86, 86, nil, nil, nil, 86, 86, 101,
- 101, 101, nil, 101, nil, nil, nil, 101, 101, nil,
- nil, nil, 101, nil, 101, 101, 101, 101, 101, 101,
- 101, nil, nil, nil, nil, 101, 101, 101, 101, 101,
- 101, 101, nil, nil, 101, nil, nil, nil, nil, nil,
- nil, 101, nil, nil, 101, 101, 101, 101, 101, 101,
- 101, 101, 101, 101, nil, 101, 101, nil, 101, 101,
- 101, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 101, nil, nil, 101, nil, nil, 101, 101, nil, nil,
- 101, nil, nil, nil, nil, nil, 101, nil, nil, nil,
- nil, nil, nil, nil, 101, nil, nil, nil, nil, 101,
- 101, 101, 101, 101, 101, nil, nil, nil, 101, 101,
- 102, 102, 102, nil, 102, nil, nil, nil, 102, 102,
- nil, nil, nil, 102, nil, 102, 102, 102, 102, 102,
- 102, 102, nil, nil, nil, nil, 102, 102, 102, 102,
- 102, 102, 102, nil, nil, 102, nil, nil, nil, nil,
- nil, nil, 102, nil, nil, 102, 102, 102, 102, 102,
- 102, 102, 102, 102, 102, nil, 102, 102, nil, 102,
- 102, 102, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 102, nil, nil, 102, nil, nil, 102, 102, nil,
- nil, 102, nil, nil, nil, nil, nil, 102, nil, nil,
- nil, nil, nil, nil, nil, 102, nil, nil, nil, nil,
- 102, 102, 102, 102, 102, 102, nil, nil, nil, 102,
- 102, 103, 103, 103, nil, 103, nil, nil, nil, 103,
- 103, nil, nil, nil, 103, nil, 103, 103, 103, 103,
- 103, 103, 103, nil, nil, nil, nil, 103, 103, 103,
- 103, 103, 103, 103, nil, nil, 103, nil, nil, nil,
- nil, nil, nil, 103, nil, nil, 103, 103, 103, 103,
- 103, 103, 103, 103, 103, 103, nil, 103, 103, nil,
- 103, 103, 103, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 103, nil, nil, 103, nil, nil, 103, 103,
- nil, nil, 103, nil, nil, nil, nil, nil, 103, nil,
- nil, nil, nil, nil, nil, nil, 103, nil, nil, nil,
- nil, 103, 103, 103, 103, 103, 103, nil, nil, nil,
- 103, 103, 104, 104, 104, nil, 104, nil, nil, nil,
- 104, 104, nil, nil, nil, 104, nil, 104, 104, 104,
- 104, 104, 104, 104, nil, nil, nil, nil, 104, 104,
- 104, 104, 104, 104, 104, nil, nil, 104, nil, nil,
- nil, nil, nil, nil, 104, nil, nil, 104, 104, 104,
- 104, 104, 104, 104, 104, 104, 104, nil, 104, 104,
- nil, 104, 104, 104, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 104, nil, nil, 104, nil, nil, 104,
- 104, nil, nil, 104, nil, nil, nil, nil, nil, 104,
- nil, nil, nil, nil, nil, nil, nil, 104, nil, nil,
- nil, nil, 104, 104, 104, 104, 104, 104, nil, nil,
- nil, 104, 104, 105, 105, 105, 105, 105, nil, nil,
- nil, 105, 105, nil, nil, nil, 105, nil, 105, 105,
- 105, 105, 105, 105, 105, nil, nil, nil, nil, 105,
- 105, 105, 105, 105, 105, 105, nil, nil, 105, nil,
- nil, nil, nil, nil, 105, 105, 105, 105, 105, 105,
- 105, 105, 105, 105, 105, 105, 105, 105, nil, 105,
- 105, nil, 105, 105, 105, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 105, nil, nil, 105, nil, nil,
- 105, 105, nil, nil, 105, nil, 105, nil, nil, nil,
- 105, nil, nil, nil, nil, nil, nil, nil, 105, nil,
- nil, nil, nil, 105, 105, 105, 105, 105, 105, nil,
- nil, nil, 105, 105, 188, 188, 188, nil, 188, nil,
- nil, nil, 188, 188, nil, nil, nil, 188, nil, 188,
- 188, 188, 188, 188, 188, 188, nil, nil, nil, nil,
- 188, 188, 188, 188, 188, 188, 188, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 188, nil, nil, 188,
- 188, 188, 188, 188, 188, 188, 188, 188, 188, nil,
- 188, 188, nil, 188, 188, 188, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 188, nil, nil, 188, nil,
- nil, 188, 188, nil, nil, 188, nil, 188, nil, nil,
- nil, 188, nil, nil, nil, nil, nil, nil, nil, 188,
- nil, nil, nil, nil, 188, 188, 188, 188, 188, 188,
- nil, nil, nil, 188, 188, 189, 189, 189, nil, 189,
- nil, nil, nil, 189, 189, nil, nil, nil, 189, nil,
- 189, 189, 189, 189, 189, 189, 189, nil, nil, nil,
- nil, 189, 189, 189, 189, 189, 189, 189, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 189, nil, nil,
- 189, 189, 189, 189, 189, 189, 189, 189, 189, 189,
- nil, 189, 189, nil, 189, 189, 189, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 189, nil, nil, 189,
- nil, nil, 189, 189, nil, nil, 189, nil, 189, nil,
- nil, nil, 189, nil, nil, nil, nil, nil, nil, nil,
- 189, nil, nil, nil, nil, 189, 189, 189, 189, 189,
- 189, nil, nil, nil, 189, 189, 190, 190, 190, nil,
- 190, nil, nil, nil, 190, 190, nil, nil, nil, 190,
- nil, 190, 190, 190, 190, 190, 190, 190, nil, nil,
- nil, nil, 190, 190, 190, 190, 190, 190, 190, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 190, nil,
- nil, 190, 190, 190, 190, 190, 190, 190, 190, 190,
- 190, nil, 190, 190, nil, 190, 190, 190, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 190, nil, nil,
- 190, nil, nil, 190, 190, nil, nil, 190, nil, nil,
- nil, nil, nil, 190, nil, nil, nil, nil, nil, nil,
- nil, 190, nil, nil, nil, nil, 190, 190, 190, 190,
- 190, 190, nil, nil, nil, 190, 190, 191, 191, 191,
- nil, 191, nil, nil, nil, 191, 191, nil, nil, nil,
- 191, nil, 191, 191, 191, 191, 191, 191, 191, nil,
- nil, nil, nil, 191, 191, 191, 191, 191, 191, 191,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 191,
- nil, nil, 191, 191, 191, 191, 191, 191, 191, 191,
- 191, 191, nil, 191, 191, nil, 191, 191, 191, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 191, nil,
- nil, 191, nil, nil, 191, 191, nil, nil, 191, nil,
- 191, nil, nil, nil, 191, nil, nil, nil, nil, nil,
- nil, nil, 191, nil, nil, nil, nil, 191, 191, 191,
- 191, 191, 191, nil, nil, nil, 191, 191, 194, 194,
- 194, nil, 194, nil, nil, nil, 194, 194, nil, nil,
- nil, 194, nil, 194, 194, 194, 194, 194, 194, 194,
- nil, nil, nil, nil, 194, 194, 194, 194, 194, 194,
- 194, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 194, nil, nil, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, nil, 194, 194, nil, 194, 194, 194,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 194,
- nil, nil, 194, nil, nil, 194, 194, nil, nil, 194,
- nil, nil, nil, nil, nil, 194, nil, nil, nil, nil,
- nil, nil, nil, 194, nil, nil, nil, nil, 194, 194,
- 194, 194, 194, 194, nil, nil, nil, 194, 194, 195,
- 195, 195, nil, 195, nil, nil, nil, 195, 195, nil,
- nil, nil, 195, nil, 195, 195, 195, 195, 195, 195,
- 195, nil, nil, nil, nil, 195, 195, 195, 195, 195,
- 195, 195, nil, nil, 195, nil, nil, nil, nil, nil,
- nil, 195, nil, nil, 195, 195, 195, 195, 195, 195,
- 195, 195, 195, 195, nil, 195, 195, nil, 195, 195,
- 195, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 195, nil, nil, 195, nil, nil, 195, 195, nil, nil,
- 195, nil, nil, nil, nil, nil, 195, nil, nil, nil,
- nil, nil, nil, nil, 195, nil, nil, nil, nil, 195,
- 195, 195, 195, 195, 195, nil, nil, nil, 195, 195,
- 196, 196, 196, nil, 196, nil, nil, nil, 196, 196,
- nil, nil, nil, 196, nil, 196, 196, 196, 196, 196,
- 196, 196, nil, nil, nil, nil, 196, 196, 196, 196,
- 196, 196, 196, nil, nil, 196, nil, nil, nil, nil,
- nil, nil, 196, nil, nil, 196, 196, 196, 196, 196,
- 196, 196, 196, 196, 196, nil, 196, 196, nil, 196,
- 196, 196, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 196, nil, nil, 196, nil, nil, 196, 196, nil,
- nil, 196, nil, nil, nil, nil, nil, 196, nil, nil,
- nil, nil, nil, nil, nil, 196, nil, nil, nil, nil,
- 196, 196, 196, 196, 196, 196, nil, nil, nil, 196,
- 196, 207, 207, 207, nil, 207, nil, nil, nil, 207,
- 207, nil, nil, nil, 207, nil, 207, 207, 207, 207,
- 207, 207, 207, nil, nil, nil, nil, 207, 207, 207,
- 207, 207, 207, 207, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, 207, 207, 207, 207,
- 207, 207, 207, 207, 207, 207, nil, 207, 207, nil,
- 207, 207, 207, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 207, nil, nil, 207, nil, nil, 207, 207,
- nil, nil, 207, nil, nil, nil, nil, nil, 207, nil,
- nil, nil, nil, nil, nil, nil, 207, nil, nil, nil,
- nil, 207, 207, 207, 207, 207, 207, nil, nil, nil,
- 207, 207, 208, 208, 208, nil, 208, nil, nil, nil,
- 208, 208, nil, nil, nil, 208, nil, 208, 208, 208,
- 208, 208, 208, 208, nil, nil, nil, nil, 208, 208,
- 208, 208, 208, 208, 208, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 208, nil, nil, 208, 208, 208,
- 208, 208, 208, 208, 208, 208, 208, nil, 208, 208,
- nil, 208, 208, 208, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 208, nil, nil, 208, nil, nil, 208,
- 208, nil, nil, 208, nil, nil, nil, nil, nil, 208,
- nil, nil, nil, nil, nil, nil, nil, 208, nil, nil,
- nil, nil, 208, 208, 208, 208, 208, 208, nil, nil,
- nil, 208, 208, 209, 209, 209, nil, 209, nil, nil,
- nil, 209, 209, nil, nil, nil, 209, nil, 209, 209,
- 209, 209, 209, 209, 209, nil, nil, nil, nil, 209,
- 209, 209, 209, 209, 209, 209, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 209, nil, nil, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, nil, 209,
- 209, nil, 209, 209, 209, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 209, nil, nil, 209, nil, nil,
- 209, 209, nil, nil, 209, nil, nil, nil, nil, nil,
- 209, nil, nil, nil, nil, nil, nil, nil, 209, nil,
- nil, nil, nil, 209, 209, 209, 209, 209, 209, nil,
- nil, nil, 209, 209, 210, 210, 210, nil, 210, nil,
- nil, nil, 210, 210, nil, nil, nil, 210, nil, 210,
- 210, 210, 210, 210, 210, 210, nil, nil, nil, nil,
- 210, 210, 210, 210, 210, 210, 210, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 210, nil, nil, 210,
- 210, 210, 210, 210, 210, 210, 210, 210, 210, nil,
- 210, 210, nil, 210, 210, 210, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, nil, nil, 210, nil,
- nil, 210, 210, nil, nil, 210, nil, nil, nil, nil,
- nil, 210, nil, nil, nil, nil, nil, nil, nil, 210,
- nil, nil, nil, nil, 210, 210, 210, 210, 210, 210,
- nil, nil, nil, 210, 210, 211, 211, 211, nil, 211,
- nil, nil, nil, 211, 211, nil, nil, nil, 211, nil,
- 211, 211, 211, 211, 211, 211, 211, nil, nil, nil,
- nil, 211, 211, 211, 211, 211, 211, 211, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 211, nil, nil,
- 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
- nil, 211, 211, nil, 211, 211, 211, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 211, nil, nil, 211,
- nil, nil, 211, 211, nil, nil, 211, nil, nil, nil,
- nil, nil, 211, nil, nil, nil, nil, nil, nil, nil,
- 211, nil, nil, nil, nil, 211, 211, 211, 211, 211,
- 211, nil, nil, nil, 211, 211, 212, 212, 212, nil,
- 212, nil, nil, nil, 212, 212, nil, nil, nil, 212,
- nil, 212, 212, 212, 212, 212, 212, 212, nil, nil,
- nil, nil, 212, 212, 212, 212, 212, 212, 212, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 212, nil,
- nil, 212, 212, 212, 212, 212, 212, 212, 212, 212,
- 212, nil, 212, 212, nil, 212, 212, 212, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 212, nil, nil,
- 212, nil, nil, 212, 212, nil, nil, 212, nil, nil,
- nil, nil, nil, 212, nil, nil, nil, nil, nil, nil,
- nil, 212, nil, nil, nil, nil, 212, 212, 212, 212,
- 212, 212, nil, nil, nil, 212, 212, 213, 213, 213,
- nil, 213, nil, nil, nil, 213, 213, nil, nil, nil,
- 213, nil, 213, 213, 213, 213, 213, 213, 213, nil,
- nil, nil, nil, 213, 213, 213, 213, 213, 213, 213,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 213,
- nil, nil, 213, 213, 213, 213, 213, 213, 213, 213,
- 213, 213, nil, 213, 213, nil, 213, 213, 213, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 213, nil,
- nil, 213, nil, nil, 213, 213, nil, nil, 213, nil,
- nil, nil, nil, nil, 213, nil, nil, nil, nil, nil,
- nil, nil, 213, nil, nil, nil, nil, 213, 213, 213,
- 213, 213, 213, nil, nil, nil, 213, 213, 214, 214,
- 214, nil, 214, nil, nil, nil, 214, 214, nil, nil,
- nil, 214, nil, 214, 214, 214, 214, 214, 214, 214,
- nil, nil, nil, nil, 214, 214, 214, 214, 214, 214,
- 214, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 214, nil, nil, 214, 214, 214, 214, 214, 214, 214,
- 214, 214, 214, nil, 214, 214, nil, 214, 214, 214,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 214,
- nil, nil, 214, nil, nil, 214, 214, nil, nil, 214,
- nil, nil, nil, nil, nil, 214, nil, nil, nil, nil,
- nil, nil, nil, 214, nil, nil, nil, nil, 214, 214,
- 214, 214, 214, 214, nil, nil, nil, 214, 214, 215,
- 215, 215, nil, 215, nil, nil, nil, 215, 215, nil,
- nil, nil, 215, nil, 215, 215, 215, 215, 215, 215,
- 215, nil, nil, nil, nil, 215, 215, 215, 215, 215,
- 215, 215, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 215, nil, nil, 215, 215, 215, 215, 215, 215,
- 215, 215, 215, 215, nil, 215, 215, nil, 215, 215,
- 215, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 215, nil, nil, 215, nil, nil, 215, 215, nil, nil,
- 215, nil, nil, nil, nil, nil, 215, nil, nil, nil,
- nil, nil, nil, nil, 215, nil, nil, nil, nil, 215,
- 215, 215, 215, 215, 215, nil, nil, nil, 215, 215,
- 216, 216, 216, nil, 216, nil, nil, nil, 216, 216,
- nil, nil, nil, 216, nil, 216, 216, 216, 216, 216,
- 216, 216, nil, nil, nil, nil, 216, 216, 216, 216,
- 216, 216, 216, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 216, nil, nil, 216, 216, 216, 216, 216,
- 216, 216, 216, 216, 216, nil, 216, 216, nil, 216,
- 216, 216, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 216, nil, nil, 216, nil, nil, 216, 216, nil,
- nil, 216, nil, nil, nil, nil, nil, 216, nil, nil,
- nil, nil, nil, nil, nil, 216, nil, nil, nil, nil,
- 216, 216, 216, 216, 216, 216, nil, nil, nil, 216,
- 216, 217, 217, 217, nil, 217, nil, nil, nil, 217,
- 217, nil, nil, nil, 217, nil, 217, 217, 217, 217,
- 217, 217, 217, nil, nil, nil, nil, 217, 217, 217,
- 217, 217, 217, 217, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 217, nil, nil, 217, 217, 217, 217,
- 217, 217, 217, 217, 217, 217, nil, 217, 217, nil,
- 217, 217, 217, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 217, nil, nil, 217, nil, nil, 217, 217,
- nil, nil, 217, nil, nil, nil, nil, nil, 217, nil,
- nil, nil, nil, nil, nil, nil, 217, nil, nil, nil,
- nil, 217, 217, 217, 217, 217, 217, nil, nil, nil,
- 217, 217, 218, 218, 218, nil, 218, nil, nil, nil,
- 218, 218, nil, nil, nil, 218, nil, 218, 218, 218,
- 218, 218, 218, 218, nil, nil, nil, nil, 218, 218,
- 218, 218, 218, 218, 218, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 218, nil, nil, 218, 218, 218,
- 218, 218, 218, 218, 218, 218, 218, nil, 218, 218,
- nil, 218, 218, 218, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 218, nil, nil, 218, nil, nil, 218,
- 218, nil, nil, 218, nil, nil, nil, nil, nil, 218,
- nil, nil, nil, nil, nil, nil, nil, 218, nil, nil,
- nil, nil, 218, 218, 218, 218, 218, 218, nil, nil,
- nil, 218, 218, 219, 219, 219, nil, 219, nil, nil,
- nil, 219, 219, nil, nil, nil, 219, nil, 219, 219,
- 219, 219, 219, 219, 219, nil, nil, nil, nil, 219,
- 219, 219, 219, 219, 219, 219, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 219, nil, nil, 219, 219,
- 219, 219, 219, 219, 219, 219, 219, 219, nil, 219,
- 219, nil, 219, 219, 219, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 219, nil, nil, 219, nil, nil,
- 219, 219, nil, nil, 219, nil, nil, nil, nil, nil,
- 219, nil, nil, nil, nil, nil, nil, nil, 219, nil,
- nil, nil, nil, 219, 219, 219, 219, 219, 219, nil,
- nil, nil, 219, 219, 220, 220, 220, nil, 220, nil,
- nil, nil, 220, 220, nil, nil, nil, 220, nil, 220,
- 220, 220, 220, 220, 220, 220, nil, nil, nil, nil,
- 220, 220, 220, 220, 220, 220, 220, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 220, nil, nil, 220,
- 220, 220, 220, 220, 220, 220, 220, 220, 220, nil,
- 220, 220, nil, 220, 220, 220, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 220, nil, nil, 220, nil,
- nil, 220, 220, nil, nil, 220, nil, nil, nil, nil,
- nil, 220, nil, nil, nil, nil, nil, nil, nil, 220,
- nil, nil, nil, nil, 220, 220, 220, 220, 220, 220,
- nil, nil, nil, 220, 220, 221, 221, 221, nil, 221,
- nil, nil, nil, 221, 221, nil, nil, nil, 221, nil,
- 221, 221, 221, 221, 221, 221, 221, nil, nil, nil,
- nil, 221, 221, 221, 221, 221, 221, 221, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 221, nil, nil,
- 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
- nil, 221, 221, nil, 221, 221, 221, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 221, nil, nil, 221,
- nil, nil, 221, 221, nil, nil, 221, nil, nil, nil,
- nil, nil, 221, nil, nil, nil, nil, nil, nil, nil,
- 221, nil, nil, nil, nil, 221, 221, 221, 221, 221,
- 221, nil, nil, nil, 221, 221, 222, 222, 222, nil,
- 222, nil, nil, nil, 222, 222, nil, nil, nil, 222,
- nil, 222, 222, 222, 222, 222, 222, 222, nil, nil,
- nil, nil, 222, 222, 222, 222, 222, 222, 222, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 222, nil,
- nil, 222, 222, 222, 222, 222, 222, 222, 222, 222,
- 222, nil, 222, 222, nil, 222, 222, 222, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 222, nil, nil,
- 222, nil, nil, 222, 222, nil, nil, 222, nil, nil,
- nil, nil, nil, 222, nil, nil, nil, nil, nil, nil,
- nil, 222, nil, nil, nil, nil, 222, 222, 222, 222,
- 222, 222, nil, nil, nil, 222, 222, 223, 223, 223,
- nil, 223, nil, nil, nil, 223, 223, nil, nil, nil,
- 223, nil, 223, 223, 223, 223, 223, 223, 223, nil,
- nil, nil, nil, 223, 223, 223, 223, 223, 223, 223,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 223,
- nil, nil, 223, 223, 223, 223, 223, 223, 223, 223,
- 223, 223, nil, 223, 223, nil, 223, 223, 223, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 223, nil, nil, 223, 223, nil, nil, 223, nil,
- nil, nil, nil, nil, 223, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, nil, nil, 223, 223, 223,
- 223, 223, 223, nil, nil, nil, 223, 223, 224, 224,
- 224, nil, 224, nil, nil, nil, 224, 224, nil, nil,
- nil, 224, nil, 224, 224, 224, 224, 224, 224, 224,
- nil, nil, nil, nil, 224, 224, 224, 224, 224, 224,
- 224, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 224, nil, nil, 224, 224, 224, 224, 224, 224, 224,
- 224, 224, 224, nil, 224, 224, nil, 224, 224, 224,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 224,
- nil, nil, 224, nil, nil, 224, 224, nil, nil, 224,
- nil, nil, nil, nil, nil, 224, nil, nil, nil, nil,
- nil, nil, nil, 224, nil, nil, nil, nil, 224, 224,
- 224, 224, 224, 224, nil, nil, nil, 224, 224, 225,
- 225, 225, nil, 225, nil, nil, nil, 225, 225, nil,
- nil, nil, 225, nil, 225, 225, 225, 225, 225, 225,
- 225, nil, nil, nil, nil, 225, 225, 225, 225, 225,
- 225, 225, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 225, nil, nil, 225, 225, 225, 225, 225, 225,
- 225, 225, 225, 225, nil, 225, 225, nil, 225, 225,
- 225, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 225, nil, nil, 225, nil, nil, 225, 225, nil, nil,
- 225, nil, nil, nil, nil, nil, 225, nil, nil, nil,
- nil, nil, nil, nil, 225, nil, nil, nil, nil, 225,
- 225, 225, 225, 225, 225, nil, nil, nil, 225, 225,
- 226, 226, 226, nil, 226, nil, nil, nil, 226, 226,
- nil, nil, nil, 226, nil, 226, 226, 226, 226, 226,
- 226, 226, nil, nil, nil, nil, 226, 226, 226, 226,
- 226, 226, 226, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 226, nil, nil, 226, 226, 226, 226, 226,
- 226, 226, 226, 226, 226, nil, 226, 226, nil, 226,
- 226, 226, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 226, nil, nil, 226, nil, nil, 226, 226, nil,
- nil, 226, nil, nil, nil, nil, nil, 226, nil, nil,
- nil, nil, nil, nil, nil, 226, nil, nil, nil, nil,
- 226, 226, 226, 226, 226, 226, nil, nil, nil, 226,
- 226, 227, 227, 227, nil, 227, nil, nil, nil, 227,
- 227, nil, nil, nil, 227, nil, 227, 227, 227, 227,
- 227, 227, 227, nil, nil, nil, nil, 227, 227, 227,
- 227, 227, 227, 227, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 227, nil, nil, 227, 227, 227, 227,
- 227, 227, 227, 227, 227, 227, nil, 227, 227, nil,
- 227, 227, 227, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 227, nil, nil, 227, nil, nil, 227, 227,
- nil, nil, 227, nil, nil, nil, nil, nil, 227, nil,
- nil, nil, nil, nil, nil, nil, 227, nil, nil, nil,
- nil, 227, 227, 227, 227, 227, 227, nil, nil, nil,
- 227, 227, 228, 228, 228, nil, 228, nil, nil, nil,
- 228, 228, nil, nil, nil, 228, nil, 228, 228, 228,
- 228, 228, 228, 228, nil, nil, nil, nil, 228, 228,
- 228, 228, 228, 228, 228, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 228, nil, nil, 228, 228, 228,
- 228, 228, 228, 228, 228, 228, 228, nil, 228, 228,
- nil, 228, 228, 228, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, 228, nil, nil, 228,
- 228, nil, nil, 228, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 228, 228, 228, 228, 228, 228, nil, nil,
- nil, 228, 228, 229, 229, 229, nil, 229, nil, nil,
- nil, 229, 229, nil, nil, nil, 229, nil, 229, 229,
- 229, 229, 229, 229, 229, nil, nil, nil, nil, 229,
- 229, 229, 229, 229, 229, 229, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 229, nil, nil, 229, 229,
- 229, 229, 229, 229, 229, 229, 229, 229, nil, 229,
- 229, nil, 229, 229, 229, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 229, nil, nil, 229, nil, nil,
- 229, 229, nil, nil, 229, nil, nil, nil, nil, nil,
- 229, nil, nil, nil, nil, nil, nil, nil, 229, nil,
- nil, nil, nil, 229, 229, 229, 229, 229, 229, nil,
- nil, nil, 229, 229, 230, 230, 230, nil, 230, nil,
- nil, nil, 230, 230, nil, nil, nil, 230, nil, 230,
- 230, 230, 230, 230, 230, 230, nil, nil, nil, nil,
- 230, 230, 230, 230, 230, 230, 230, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 230, nil, nil, 230,
- 230, 230, 230, 230, 230, 230, 230, 230, 230, nil,
- 230, 230, nil, 230, 230, 230, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 230, nil, nil, 230, nil,
- nil, 230, 230, nil, nil, 230, nil, nil, nil, nil,
- nil, 230, nil, nil, nil, nil, nil, nil, nil, 230,
- nil, nil, nil, nil, 230, 230, 230, 230, 230, 230,
- nil, nil, nil, 230, 230, 231, 231, 231, nil, 231,
- nil, nil, nil, 231, 231, nil, nil, nil, 231, nil,
- 231, 231, 231, 231, 231, 231, 231, nil, nil, nil,
- nil, 231, 231, 231, 231, 231, 231, 231, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 231, nil, nil,
- 231, 231, 231, 231, 231, 231, 231, 231, 231, 231,
- nil, 231, 231, nil, 231, 231, 231, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 231, nil, nil, 231,
- nil, nil, 231, 231, nil, nil, 231, nil, nil, nil,
- nil, nil, 231, nil, nil, nil, nil, nil, nil, nil,
- 231, nil, nil, nil, nil, 231, 231, 231, 231, 231,
- 231, nil, nil, nil, 231, 231, 232, 232, 232, nil,
- 232, nil, nil, nil, 232, 232, nil, nil, nil, 232,
- nil, 232, 232, 232, 232, 232, 232, 232, nil, nil,
- nil, nil, 232, 232, 232, 232, 232, 232, 232, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 232, nil,
- nil, 232, 232, 232, 232, 232, 232, 232, 232, 232,
- 232, nil, 232, 232, nil, 232, 232, 232, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 232, nil, nil,
- 232, nil, nil, 232, 232, nil, nil, 232, nil, nil,
- nil, nil, nil, 232, nil, nil, nil, nil, nil, nil,
- nil, 232, nil, nil, nil, nil, 232, 232, 232, 232,
- 232, 232, nil, nil, nil, 232, 232, 233, 233, 233,
- nil, 233, nil, nil, nil, 233, 233, nil, nil, nil,
- 233, nil, 233, 233, 233, 233, 233, 233, 233, nil,
- nil, nil, nil, 233, 233, 233, 233, 233, 233, 233,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 233,
- nil, nil, 233, 233, 233, 233, 233, 233, 233, 233,
- 233, 233, nil, 233, 233, nil, 233, 233, 233, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 233, nil,
- nil, 233, nil, nil, 233, 233, nil, nil, 233, nil,
- nil, nil, nil, nil, 233, nil, nil, nil, nil, nil,
- nil, nil, 233, nil, nil, nil, nil, 233, 233, 233,
- 233, 233, 233, nil, nil, nil, 233, 233, 241, 241,
- 241, nil, 241, nil, nil, nil, 241, 241, nil, nil,
- nil, 241, nil, 241, 241, 241, 241, 241, 241, 241,
- nil, nil, nil, nil, 241, 241, 241, 241, 241, 241,
- 241, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 241, nil, nil, 241, 241, 241, 241, 241, 241, 241,
- 241, 241, 241, nil, 241, 241, nil, 241, 241, 241,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 241,
- nil, nil, 241, nil, nil, 241, 241, nil, nil, 241,
- nil, nil, nil, nil, nil, 241, nil, nil, nil, nil,
- nil, nil, nil, 241, nil, nil, nil, nil, 241, 241,
- 241, 241, 241, 241, nil, nil, nil, 241, 241, 243,
- 243, 243, nil, 243, nil, nil, nil, 243, 243, nil,
- nil, nil, 243, nil, 243, 243, 243, 243, 243, 243,
- 243, nil, nil, nil, nil, 243, 243, 243, 243, 243,
- 243, 243, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 243, nil, nil, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, nil, 243, 243, nil, 243, 243,
- 243, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 243, nil, nil, 243, nil, nil, 243, 243, nil, nil,
- 243, nil, nil, nil, nil, nil, 243, nil, nil, nil,
- nil, nil, nil, nil, 243, nil, nil, nil, nil, 243,
- 243, 243, 243, 243, 243, nil, nil, nil, 243, 243,
- 254, 254, 254, nil, 254, nil, nil, nil, 254, 254,
- nil, nil, nil, 254, nil, 254, 254, 254, 254, 254,
- 254, 254, nil, nil, nil, nil, 254, 254, 254, 254,
- 254, 254, 254, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 254, nil, nil, 254, 254, 254, 254, 254,
- 254, 254, 254, 254, 254, nil, 254, 254, nil, 254,
- 254, 254, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 254, nil, nil, 254, nil, nil, 254, 254, nil,
- nil, 254, nil, 254, nil, 254, nil, 254, nil, nil,
- nil, nil, nil, nil, nil, 254, nil, nil, nil, nil,
- 254, 254, 254, 254, 254, 254, nil, nil, nil, 254,
- 254, 255, 255, 255, nil, 255, nil, nil, nil, 255,
- 255, nil, nil, nil, 255, nil, 255, 255, 255, 255,
- 255, 255, 255, nil, nil, nil, nil, 255, 255, 255,
- 255, 255, 255, 255, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 255, nil, nil, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, nil, 255, 255, nil,
- 255, 255, 255, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 255, nil, nil, 255, nil, nil, 255, 255,
- nil, nil, 255, nil, 255, nil, 255, nil, 255, nil,
- nil, nil, nil, nil, nil, nil, 255, nil, nil, nil,
- nil, 255, 255, 255, 255, 255, 255, nil, nil, nil,
- 255, 255, 263, 263, 263, nil, 263, nil, nil, nil,
- 263, 263, nil, nil, nil, 263, nil, 263, 263, 263,
- 263, 263, 263, 263, nil, nil, nil, nil, 263, 263,
- 263, 263, 263, 263, 263, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 263, nil, nil, 263, 263, 263,
- 263, 263, 263, 263, 263, 263, 263, nil, 263, 263,
- nil, 263, 263, 263, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 263, nil, nil, 263, nil, 263, 263,
- 263, nil, nil, 263, nil, 263, nil, 263, nil, 263,
- nil, nil, nil, nil, nil, nil, nil, 263, nil, nil,
- nil, nil, 263, 263, 263, 263, 263, 263, nil, nil,
- nil, 263, 263, 269, 269, 269, nil, 269, nil, nil,
- nil, 269, 269, nil, nil, nil, 269, nil, 269, 269,
- 269, 269, 269, 269, 269, nil, nil, nil, nil, 269,
- 269, 269, 269, 269, 269, 269, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 269, nil, nil, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269, nil, 269,
- 269, nil, nil, nil, 269, nil, 468, 468, 468, 468,
- 468, 468, 468, 468, 468, 468, 468, nil, 468, 468,
- nil, nil, 468, 468, 269, nil, nil, 269, nil, nil,
- 269, 269, nil, nil, 269, nil, nil, nil, 468, nil,
- 468, nil, 468, 468, 468, 468, 468, 468, 468, nil,
- 468, nil, nil, 269, 269, 269, 269, 269, 269, nil,
- nil, nil, 269, 269, 290, 290, 290, 468, 290, nil,
- nil, nil, 290, 290, nil, nil, nil, 290, nil, 290,
- 290, 290, 290, 290, 290, 290, nil, nil, nil, nil,
- 290, 290, 290, 290, 290, 290, 290, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 290, nil, nil, 290,
- 290, 290, 290, 290, 290, 290, 290, 290, 290, nil,
- 290, 290, nil, 290, 290, 290, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 290, nil, nil, 290, 290,
- nil, 290, 290, nil, nil, 290, nil, nil, nil, nil,
- nil, 290, nil, nil, nil, nil, nil, nil, nil, 290,
- nil, nil, nil, nil, 290, 290, 290, 290, 290, 290,
- nil, nil, nil, 290, 290, 299, 299, 299, nil, 299,
- nil, nil, nil, 299, 299, nil, nil, nil, 299, nil,
- 299, 299, 299, 299, 299, 299, 299, nil, nil, nil,
- nil, 299, 299, 299, 299, 299, 299, 299, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 299, nil, nil,
- 299, 299, 299, 299, 299, 299, 299, 299, 299, 299,
- nil, 299, 299, nil, 299, 299, 299, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 299, nil, nil, 299,
- nil, nil, 299, 299, nil, nil, 299, nil, nil, nil,
- nil, nil, 299, nil, nil, nil, nil, nil, nil, nil,
- 299, nil, nil, nil, nil, 299, 299, 299, 299, 299,
- 299, nil, nil, nil, 299, 299, 308, 308, 308, nil,
- 308, nil, nil, nil, 308, 308, nil, nil, nil, 308,
- nil, 308, 308, 308, 308, 308, 308, 308, nil, nil,
- nil, nil, 308, 308, 308, 308, 308, 308, 308, nil,
- nil, 308, nil, nil, nil, nil, nil, nil, 308, nil,
- nil, 308, 308, 308, 308, 308, 308, 308, 308, 308,
- 308, nil, 308, 308, nil, 308, 308, 308, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 308, nil, nil,
- 308, nil, nil, 308, 308, nil, nil, 308, nil, nil,
- nil, nil, nil, 308, nil, nil, nil, nil, nil, nil,
- nil, 308, nil, nil, nil, nil, 308, 308, 308, 308,
- 308, 308, nil, nil, nil, 308, 308, 309, 309, 309,
- nil, 309, nil, nil, nil, 309, 309, nil, nil, nil,
- 309, nil, 309, 309, 309, 309, 309, 309, 309, nil,
- nil, nil, nil, 309, 309, 309, 309, 309, 309, 309,
- nil, nil, 309, nil, nil, nil, nil, nil, nil, 309,
- nil, nil, 309, 309, 309, 309, 309, 309, 309, 309,
- 309, 309, nil, 309, 309, nil, 309, 309, 309, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 309, nil,
- nil, 309, nil, nil, 309, 309, nil, nil, 309, nil,
- nil, nil, nil, nil, 309, nil, nil, nil, nil, nil,
- nil, nil, 309, nil, nil, nil, nil, 309, 309, 309,
- 309, 309, 309, nil, nil, nil, 309, 309, 327, 327,
- 327, nil, 327, nil, nil, nil, 327, 327, nil, nil,
- nil, 327, nil, 327, 327, 327, 327, 327, 327, 327,
- nil, nil, nil, nil, 327, 327, 327, 327, 327, 327,
- 327, nil, nil, 327, nil, nil, nil, nil, nil, nil,
- 327, nil, nil, 327, 327, 327, 327, 327, 327, 327,
- 327, 327, 327, nil, 327, 327, nil, 327, 327, 327,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 327,
- nil, nil, 327, nil, nil, 327, 327, nil, nil, 327,
- nil, nil, nil, nil, nil, 327, nil, nil, nil, nil,
- nil, nil, nil, 327, nil, nil, nil, nil, 327, 327,
- 327, 327, 327, 327, nil, nil, nil, 327, 327, 341,
- 341, 341, nil, 341, nil, nil, nil, 341, 341, nil,
- nil, nil, 341, nil, 341, 341, 341, 341, 341, 341,
- 341, nil, nil, nil, nil, 341, 341, 341, 341, 341,
- 341, 341, nil, nil, 341, nil, nil, nil, nil, nil,
- nil, 341, nil, nil, 341, 341, 341, 341, 341, 341,
- 341, 341, 341, 341, nil, 341, 341, nil, 341, 341,
- 341, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 341, nil, nil, 341, nil, nil, 341, 341, nil, nil,
- 341, nil, nil, nil, nil, nil, 341, nil, nil, nil,
- nil, nil, nil, nil, 341, nil, nil, nil, nil, 341,
- 341, 341, 341, 341, 341, nil, nil, nil, 341, 341,
- 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
- 357, 357, 357, 357, 357, 357, 357, 357, 357, 357,
- 357, 357, 357, 357, nil, nil, 357, 357, 357, 357,
- 357, 357, 357, 357, 357, 357, nil, nil, nil, nil,
- nil, 357, 357, 357, 357, 357, 357, 357, 357, nil,
- nil, 357, nil, nil, nil, nil, nil, nil, nil, 357,
- 357, nil, 357, 357, 357, 357, nil, 357, 357, nil,
- nil, 357, nil, nil, nil, nil, 357, 357, 357, 357,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 357, 357, nil, 357, 357, 357, 357,
- 357, 357, 357, 357, 357, nil, 357, nil, nil, 357,
- 357, nil, nil, 369, 369, 369, nil, 369, nil, nil,
- 357, 369, 369, nil, nil, nil, 369, nil, 369, 369,
- 369, 369, 369, 369, 369, nil, nil, nil, nil, 369,
- 369, 369, 369, 369, 369, 369, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 369, nil, nil, 369, 369,
- 369, 369, 369, 369, 369, 369, 369, 369, nil, 369,
- 369, nil, 369, 369, 369, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 369, nil, nil, 369, nil, nil,
- 369, 369, nil, nil, 369, nil, nil, nil, nil, nil,
- 369, nil, nil, nil, nil, nil, nil, nil, 369, nil,
- nil, nil, nil, 369, 369, 369, 369, 369, 369, nil,
- nil, nil, 369, 369, 378, 378, 378, nil, 378, nil,
- nil, nil, 378, 378, nil, nil, nil, 378, nil, 378,
- 378, 378, 378, 378, 378, 378, nil, nil, nil, nil,
- 378, 378, 378, 378, 378, 378, 378, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 378, nil, nil, 378,
- 378, 378, 378, 378, 378, 378, 378, 378, 378, nil,
- 378, 378, nil, 378, 378, 378, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 378, nil, nil, 378, 378,
- nil, 378, 378, nil, nil, 378, nil, 378, nil, 378,
- nil, 378, nil, nil, nil, nil, nil, nil, nil, 378,
- nil, nil, nil, nil, 378, 378, 378, 378, 378, 378,
- nil, nil, nil, 378, 378, 385, 385, 385, nil, 385,
- nil, nil, nil, 385, 385, nil, nil, nil, 385, nil,
- 385, 385, 385, 385, 385, 385, 385, nil, nil, nil,
- nil, 385, 385, 385, 385, 385, 385, 385, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 385, nil, nil,
- 385, 385, 385, 385, 385, 385, 385, 385, 385, 385,
- nil, 385, 385, nil, 385, 385, 385, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 385, nil, nil, 385,
- 385, nil, 385, 385, nil, nil, 385, nil, 385, nil,
- 385, nil, 385, nil, nil, nil, nil, nil, nil, nil,
- 385, nil, nil, nil, nil, 385, 385, 385, 385, 385,
- 385, nil, nil, nil, 385, 385, 386, 386, 386, nil,
- 386, nil, nil, nil, 386, 386, nil, nil, nil, 386,
- nil, 386, 386, 386, 386, 386, 386, 386, nil, nil,
- nil, nil, 386, 386, 386, 386, 386, 386, 386, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 386, nil,
- nil, 386, 386, 386, 386, 386, 386, 386, 386, 386,
- 386, nil, 386, 386, nil, 386, 386, 386, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 386, nil, nil,
- 386, 386, nil, 386, 386, nil, nil, 386, nil, 386,
- nil, 386, nil, 386, nil, nil, nil, nil, nil, nil,
- nil, 386, nil, nil, nil, nil, 386, 386, 386, 386,
- 386, 386, nil, nil, nil, 386, 386, 393, 393, 393,
- nil, 393, nil, nil, nil, 393, 393, nil, nil, nil,
- 393, nil, 393, 393, 393, 393, 393, 393, 393, nil,
- nil, nil, nil, 393, 393, 393, 393, 393, 393, 393,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 393,
- nil, nil, 393, 393, 393, 393, 393, 393, 393, 393,
- 393, 393, nil, 393, 393, nil, 393, 393, 393, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 393, nil,
- nil, 393, nil, nil, 393, 393, nil, nil, 393, nil,
- 393, nil, nil, nil, 393, nil, nil, nil, nil, nil,
- nil, nil, 393, nil, nil, nil, nil, 393, 393, 393,
- 393, 393, 393, nil, nil, nil, 393, 393, 395, 395,
- 395, nil, 395, nil, nil, nil, 395, 395, nil, nil,
- nil, 395, nil, 395, 395, 395, 395, 395, 395, 395,
- nil, nil, nil, nil, 395, 395, 395, 395, 395, 395,
- 395, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 395, nil, nil, 395, 395, 395, 395, 395, 395, 395,
- 395, 395, 395, nil, 395, 395, nil, 395, 395, 395,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 395,
- nil, nil, 395, nil, nil, 395, 395, nil, nil, 395,
- nil, nil, nil, nil, nil, 395, nil, nil, nil, nil,
- nil, nil, nil, 395, nil, nil, nil, nil, 395, 395,
- 395, 395, 395, 395, nil, nil, nil, 395, 395, 396,
- 396, 396, nil, 396, nil, nil, nil, 396, 396, nil,
- nil, nil, 396, nil, 396, 396, 396, 396, 396, 396,
- 396, nil, nil, nil, nil, 396, 396, 396, 396, 396,
- 396, 396, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 396, nil, nil, 396, 396, 396, 396, 396, 396,
- 396, 396, 396, 396, nil, 396, 396, nil, 396, 396,
- 396, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 396, nil, nil, 396, nil, nil, 396, 396, nil, nil,
- 396, nil, nil, nil, nil, nil, 396, nil, nil, nil,
- nil, nil, nil, nil, 396, nil, nil, nil, nil, 396,
- 396, 396, 396, 396, 396, nil, nil, nil, 396, 396,
- 397, 397, 397, nil, 397, nil, nil, nil, 397, 397,
- nil, nil, nil, 397, nil, 397, 397, 397, 397, 397,
- 397, 397, nil, nil, nil, nil, 397, 397, 397, 397,
- 397, 397, 397, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 397, nil, nil, 397, 397, 397, 397, 397,
- 397, 397, 397, 397, 397, nil, 397, 397, nil, 397,
- 397, 397, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 397, nil, nil, 397, nil, nil, 397, 397, nil,
- nil, 397, nil, nil, nil, nil, nil, 397, nil, nil,
- nil, nil, nil, nil, nil, 397, nil, nil, nil, nil,
- 397, 397, 397, 397, 397, 397, nil, nil, nil, 397,
- 397, 426, 426, 426, nil, 426, nil, nil, nil, 426,
- 426, nil, nil, nil, 426, nil, 426, 426, 426, 426,
- 426, 426, 426, nil, nil, nil, nil, 426, 426, 426,
- 426, 426, 426, 426, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 426, nil, nil, 426, 426, 426, 426,
- 426, 426, 426, 426, 426, 426, nil, 426, 426, nil,
- 426, 426, 426, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 426, nil, nil, 426, nil, nil, 426, 426,
- nil, nil, 426, nil, 426, nil, 426, nil, 426, nil,
- nil, nil, nil, nil, nil, nil, 426, nil, nil, nil,
- nil, 426, 426, 426, 426, 426, 426, nil, nil, nil,
- 426, 426, 428, 428, 428, nil, 428, nil, nil, nil,
- 428, 428, nil, nil, nil, 428, nil, 428, 428, 428,
- 428, 428, 428, 428, nil, nil, nil, nil, 428, 428,
- 428, 428, 428, 428, 428, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 428, nil, nil, 428, 428, 428,
- 428, 428, 428, 428, 428, 428, 428, nil, 428, 428,
- nil, 428, 428, 428, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 428, nil, nil, 428, nil, nil, 428,
- 428, nil, nil, 428, nil, 428, nil, 428, nil, 428,
- nil, nil, nil, nil, nil, nil, nil, 428, nil, nil,
- nil, nil, 428, 428, 428, 428, 428, 428, nil, nil,
- nil, 428, 428, 431, 431, 431, nil, 431, nil, nil,
- nil, 431, 431, nil, nil, nil, 431, nil, 431, 431,
- 431, 431, 431, 431, 431, nil, nil, nil, nil, 431,
- 431, 431, 431, 431, 431, 431, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 431, nil, nil, 431, 431,
- 431, 431, 431, 431, 431, 431, 431, 431, nil, 431,
- 431, nil, 431, 431, 431, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 431, nil, nil, 431, nil, nil,
- 431, 431, nil, nil, 431, nil, nil, nil, nil, nil,
- 431, nil, nil, nil, nil, nil, nil, nil, 431, nil,
- nil, nil, nil, 431, 431, 431, 431, 431, 431, nil,
- nil, nil, 431, 431, 445, 445, 445, nil, 445, nil,
- nil, nil, 445, 445, nil, nil, nil, 445, nil, 445,
- 445, 445, 445, 445, 445, 445, nil, nil, nil, nil,
- 445, 445, 445, 445, 445, 445, 445, nil, nil, 445,
- nil, nil, nil, nil, nil, nil, 445, nil, nil, 445,
- 445, 445, 445, 445, 445, 445, 445, 445, 445, nil,
- 445, 445, nil, 445, 445, 445, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 445, nil, nil, 445, nil,
- nil, 445, 445, nil, nil, 445, nil, 445, nil, 445,
- nil, 445, nil, nil, nil, nil, nil, nil, nil, 445,
- nil, nil, nil, nil, 445, 445, 445, 445, 445, 445,
- nil, nil, nil, 445, 445, 456, 456, 456, nil, 456,
- nil, nil, nil, 456, 456, nil, nil, nil, 456, nil,
- 456, 456, 456, 456, 456, 456, 456, nil, nil, nil,
- nil, 456, 456, 456, 456, 456, 456, 456, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 456, nil, nil,
- 456, 456, 456, 456, 456, 456, 456, 456, 456, 456,
- nil, 456, 456, nil, 456, 456, 456, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 456, nil, nil, 456,
- nil, nil, 456, 456, nil, nil, 456, nil, 456, nil,
- nil, nil, 456, nil, nil, nil, nil, nil, nil, nil,
- 456, nil, nil, nil, nil, 456, 456, 456, 456, 456,
- 456, nil, nil, nil, 456, 456, 463, 463, 463, nil,
- 463, nil, nil, nil, 463, 463, nil, nil, nil, 463,
- nil, 463, 463, 463, 463, 463, 463, 463, nil, nil,
- nil, nil, 463, 463, 463, 463, 463, 463, 463, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 463, nil,
- nil, 463, 463, 463, 463, 463, 463, 463, 463, 463,
- 463, nil, 463, 463, nil, 463, 463, 463, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 463, nil, nil,
- 463, nil, nil, 463, 463, nil, nil, 463, nil, nil,
- nil, nil, nil, 463, nil, nil, nil, nil, nil, nil,
- nil, 463, nil, nil, nil, nil, 463, 463, 463, 463,
- 463, 463, nil, nil, nil, 463, 463, 464, 464, 464,
- nil, 464, nil, nil, nil, 464, 464, nil, nil, nil,
- 464, nil, 464, 464, 464, 464, 464, 464, 464, nil,
- nil, nil, nil, 464, 464, 464, 464, 464, 464, 464,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 464,
- nil, nil, 464, 464, 464, 464, 464, 464, 464, 464,
- 464, 464, nil, 464, 464, nil, 464, 464, 464, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 464, nil,
- nil, 464, nil, nil, 464, 464, nil, nil, 464, nil,
- nil, nil, nil, nil, 464, nil, nil, nil, nil, nil,
- nil, nil, 464, nil, nil, nil, nil, 464, 464, 464,
- 464, 464, 464, nil, nil, nil, 464, 464, 465, 465,
- 465, nil, 465, nil, nil, nil, 465, 465, nil, nil,
- nil, 465, nil, 465, 465, 465, 465, 465, 465, 465,
- nil, nil, nil, nil, 465, 465, 465, 465, 465, 465,
- 465, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 465, nil, nil, 465, 465, 465, 465, 465, 465, 465,
- 465, 465, 465, nil, 465, 465, nil, 465, 465, 465,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 465,
- nil, nil, 465, nil, nil, 465, 465, nil, nil, 465,
- nil, nil, nil, nil, nil, 465, nil, nil, nil, nil,
- nil, nil, nil, 465, nil, nil, nil, nil, 465, 465,
- 465, 465, 465, 465, nil, nil, nil, 465, 465, 469,
- 469, 469, nil, 469, nil, nil, nil, 469, 469, nil,
- nil, nil, 469, nil, 469, 469, 469, 469, 469, 469,
- 469, nil, nil, nil, nil, 469, 469, 469, 469, 469,
- 469, 469, nil, nil, 469, nil, nil, nil, nil, nil,
- nil, 469, nil, nil, 469, 469, 469, 469, 469, 469,
- 469, 469, 469, 469, nil, 469, 469, nil, 469, 469,
- 469, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 469, nil, nil, 469, nil, nil, 469, 469, nil, nil,
- 469, nil, nil, nil, nil, nil, 469, nil, nil, nil,
- nil, nil, nil, nil, 469, nil, nil, nil, nil, 469,
- 469, 469, 469, 469, 469, nil, nil, nil, 469, 469,
- 471, 471, 471, nil, 471, nil, nil, nil, 471, 471,
- nil, nil, nil, 471, nil, 471, 471, 471, 471, 471,
- 471, 471, nil, nil, nil, nil, 471, 471, 471, 471,
- 471, 471, 471, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 471, nil, nil, 471, 471, 471, 471, 471,
- 471, 471, 471, 471, 471, nil, 471, 471, nil, 471,
- 471, 471, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 471, nil, nil, 471, nil, nil, 471, 471, nil,
- nil, 471, nil, 471, nil, nil, nil, 471, nil, nil,
- nil, nil, nil, nil, nil, 471, nil, nil, nil, nil,
- 471, 471, 471, 471, 471, 471, nil, nil, nil, 471,
- 471, 476, 476, 476, nil, 476, nil, nil, nil, 476,
- 476, nil, nil, nil, 476, nil, 476, 476, 476, 476,
- 476, 476, 476, nil, nil, nil, nil, 476, 476, 476,
- 476, 476, 476, 476, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 476, nil, nil, 476, 476, 476, 476,
- 476, 476, 476, 476, 476, 476, nil, 476, 476, nil,
- 476, 476, 476, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 476, nil, nil, 476, nil, nil, 476, 476,
- nil, nil, 476, nil, 476, nil, nil, nil, 476, nil,
- nil, nil, nil, nil, nil, nil, 476, nil, nil, nil,
- nil, 476, 476, 476, 476, 476, 476, nil, nil, nil,
- 476, 476, 479, 479, 479, nil, 479, nil, nil, nil,
- 479, 479, nil, nil, nil, 479, nil, 479, 479, 479,
- 479, 479, 479, 479, nil, nil, nil, nil, 479, 479,
- 479, 479, 479, 479, 479, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 479, nil, nil, 479, 479, 479,
- 479, 479, 479, 479, 479, 479, 479, nil, 479, 479,
- nil, 479, 479, 479, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 479, nil, nil, 479, nil, nil, 479,
- 479, nil, nil, 479, nil, nil, nil, nil, nil, 479,
- nil, nil, nil, nil, nil, nil, nil, 479, nil, nil,
- nil, nil, 479, 479, 479, 479, 479, 479, nil, nil,
- nil, 479, 479, 482, 482, 482, nil, 482, nil, nil,
- nil, 482, 482, nil, nil, nil, 482, nil, 482, 482,
- 482, 482, 482, 482, 482, nil, nil, nil, nil, 482,
- 482, 482, 482, 482, 482, 482, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 482, nil, nil, 482, 482,
- 482, 482, 482, 482, 482, 482, 482, 482, nil, 482,
- 482, nil, 482, 482, 482, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 482, nil, nil, 482, nil, nil,
- 482, 482, nil, nil, 482, nil, nil, nil, nil, nil,
- 482, nil, nil, nil, nil, nil, nil, nil, 482, nil,
- nil, nil, nil, 482, 482, 482, 482, 482, 482, nil,
- nil, nil, 482, 482, 496, 496, 496, nil, 496, nil,
- nil, nil, 496, 496, nil, nil, nil, 496, nil, 496,
- 496, 496, 496, 496, 496, 496, nil, nil, nil, nil,
- 496, 496, 496, 496, 496, 496, 496, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 496, nil, nil, 496,
- 496, 496, 496, 496, 496, 496, 496, 496, 496, nil,
- 496, 496, nil, 496, 496, 496, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 496, nil, nil, 496, nil,
- nil, 496, 496, nil, nil, 496, nil, 496, nil, nil,
- nil, 496, nil, nil, nil, nil, nil, nil, nil, 496,
- nil, nil, nil, nil, 496, 496, 496, 496, 496, 496,
- nil, nil, nil, 496, 496, 497, 497, 497, nil, 497,
- nil, nil, nil, 497, 497, nil, nil, nil, 497, nil,
- 497, 497, 497, 497, 497, 497, 497, nil, nil, nil,
- nil, 497, 497, 497, 497, 497, 497, 497, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 497, nil, nil,
- 497, 497, 497, 497, 497, 497, 497, 497, 497, 497,
- nil, 497, 497, nil, 497, 497, 497, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 497, nil, nil, 497,
- nil, nil, 497, 497, nil, nil, 497, nil, 497, nil,
- nil, nil, 497, nil, nil, nil, nil, nil, nil, nil,
- 497, nil, nil, nil, nil, 497, 497, 497, 497, 497,
- 497, nil, nil, nil, 497, 497, 506, 506, 506, nil,
- 506, nil, nil, nil, 506, 506, nil, nil, nil, 506,
- nil, 506, 506, 506, 506, 506, 506, 506, nil, nil,
- nil, nil, 506, 506, 506, 506, 506, 506, 506, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 506, nil,
- nil, 506, 506, 506, 506, 506, 506, 506, 506, 506,
- 506, nil, 506, 506, nil, 506, 506, 506, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 506, nil, nil,
- 506, nil, nil, 506, 506, nil, nil, 506, nil, 506,
- nil, nil, nil, 506, nil, nil, nil, nil, nil, nil,
- nil, 506, nil, nil, nil, nil, 506, 506, 506, 506,
- 506, 506, nil, nil, nil, 506, 506, 510, 510, 510,
- nil, 510, nil, nil, nil, 510, 510, nil, nil, nil,
- 510, nil, 510, 510, 510, 510, 510, 510, 510, nil,
- nil, nil, nil, 510, 510, 510, 510, 510, 510, 510,
- nil, nil, 510, nil, nil, nil, nil, nil, nil, 510,
- nil, nil, 510, 510, 510, 510, 510, 510, 510, 510,
- 510, 510, nil, 510, 510, nil, 510, 510, 510, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 510, nil,
- nil, 510, nil, nil, 510, 510, nil, nil, 510, nil,
- nil, nil, nil, nil, 510, nil, nil, nil, nil, nil,
- nil, nil, 510, nil, nil, nil, nil, 510, 510, 510,
- 510, 510, 510, nil, nil, nil, 510, 510, 534, 534,
- 534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
- 534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
- 534, 534, nil, nil, 534, 534, 534, 534, 534, 534,
- 534, 534, 534, 534, nil, nil, nil, nil, nil, 534,
- 534, 534, 534, 534, 534, 534, 534, nil, nil, 534,
- nil, nil, nil, nil, nil, nil, nil, 534, 534, nil,
- 534, 534, 534, 534, nil, 534, 534, nil, nil, 534,
- nil, nil, nil, nil, 534, 534, 534, 534, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 534, 534, nil, 534, 534, 534, 534, 534, 534,
- 534, 534, 534, nil, 534, nil, nil, 534, 534, nil,
- nil, 537, 537, 537, nil, 537, nil, nil, 534, 537,
- 537, nil, nil, nil, 537, nil, 537, 537, 537, 537,
- 537, 537, 537, nil, nil, nil, nil, 537, 537, 537,
- 537, 537, 537, 537, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 537, nil, nil, 537, 537, 537, 537,
- 537, 537, 537, 537, 537, 537, nil, 537, 537, nil,
- 537, 537, 537, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 537, nil, nil, 537, nil, nil, 537, 537,
- nil, nil, 537, nil, nil, nil, nil, nil, 537, nil,
- nil, nil, nil, nil, nil, nil, 537, nil, nil, nil,
- nil, 537, 537, 537, 537, 537, 537, nil, nil, nil,
- 537, 537, 538, 538, 538, nil, 538, nil, nil, nil,
- 538, 538, nil, nil, nil, 538, nil, 538, 538, 538,
- 538, 538, 538, 538, nil, nil, nil, nil, 538, 538,
- 538, 538, 538, 538, 538, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 538, nil, nil, 538, 538, 538,
- 538, 538, 538, 538, 538, 538, 538, nil, 538, 538,
- nil, 538, 538, 538, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 538, nil, nil, 538, nil, nil, 538,
- 538, nil, nil, 538, nil, 538, nil, nil, nil, 538,
- nil, nil, nil, nil, nil, nil, nil, 538, nil, nil,
- nil, nil, 538, 538, 538, 538, 538, 538, nil, nil,
- nil, 538, 538, 541, 541, 541, nil, 541, nil, nil,
- nil, 541, 541, nil, nil, nil, 541, nil, 541, 541,
- 541, 541, 541, 541, 541, nil, nil, nil, nil, 541,
- 541, 541, 541, 541, 541, 541, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 541, nil, nil, 541, 541,
- 541, 541, 541, 541, 541, 541, 541, 541, nil, 541,
- 541, nil, 541, 541, 541, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 541, nil, nil, 541, nil, nil,
- 541, 541, nil, nil, 541, nil, nil, nil, nil, nil,
- 541, nil, nil, nil, nil, nil, nil, nil, 541, nil,
- nil, nil, nil, 541, 541, 541, 541, 541, 541, nil,
- nil, nil, 541, 541, 542, 542, 542, nil, 542, nil,
- nil, nil, 542, 542, nil, nil, nil, 542, nil, 542,
- 542, 542, 542, 542, 542, 542, nil, nil, nil, nil,
- 542, 542, 542, 542, 542, 542, 542, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 542, nil, nil, 542,
- 542, 542, 542, 542, 542, 542, 542, 542, 542, nil,
- 542, 542, nil, 542, 542, 542, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 542, nil, nil, 542, nil,
- nil, 542, 542, nil, nil, 542, nil, nil, nil, nil,
- nil, 542, nil, nil, nil, nil, nil, nil, nil, 542,
- nil, nil, nil, nil, 542, 542, 542, 542, 542, 542,
- nil, nil, nil, 542, 542, 546, 546, 546, nil, 546,
- nil, nil, nil, 546, 546, nil, nil, nil, 546, nil,
- 546, 546, 546, 546, 546, 546, 546, nil, nil, nil,
- nil, 546, 546, 546, 546, 546, 546, 546, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 546, nil, nil,
- 546, 546, 546, 546, 546, 546, 546, 546, 546, 546,
- nil, 546, 546, nil, 546, 546, 546, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 546, nil, nil, 546,
- nil, nil, 546, 546, nil, nil, 546, nil, nil, nil,
- nil, nil, 546, nil, nil, nil, nil, nil, nil, nil,
- 546, nil, nil, nil, nil, 546, 546, 546, 546, 546,
- 546, nil, nil, nil, 546, 546, 549, 549, 549, nil,
- 549, nil, nil, nil, 549, 549, nil, nil, nil, 549,
- nil, 549, 549, 549, 549, 549, 549, 549, nil, nil,
- nil, nil, 549, 549, 549, 549, 549, 549, 549, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 549, nil,
- nil, 549, 549, 549, 549, 549, 549, 549, 549, 549,
- 549, nil, 549, 549, nil, 549, 549, 549, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 549, nil, nil,
- 549, nil, nil, 549, 549, nil, nil, 549, nil, nil,
- nil, nil, nil, 549, nil, nil, nil, nil, nil, nil,
- nil, 549, nil, nil, nil, nil, 549, 549, 549, 549,
- 549, 549, nil, nil, nil, 549, 549, 556, 556, 556,
- nil, 556, nil, nil, nil, 556, 556, nil, nil, nil,
- 556, nil, 556, 556, 556, 556, 556, 556, 556, nil,
- nil, nil, nil, 556, 556, 556, 556, 556, 556, 556,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 556,
- nil, nil, 556, 556, 556, 556, 556, 556, 556, 556,
- 556, 556, nil, 556, 556, nil, 556, 556, 556, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 556, nil,
- nil, 556, nil, nil, 556, 556, nil, nil, 556, nil,
- nil, nil, nil, nil, 556, nil, nil, nil, nil, nil,
- nil, nil, 556, nil, nil, nil, nil, 556, 556, 556,
- 556, 556, 556, nil, nil, nil, 556, 556, 557, 557,
- 557, nil, 557, nil, nil, nil, 557, 557, nil, nil,
- nil, 557, nil, 557, 557, 557, 557, 557, 557, 557,
- nil, nil, nil, nil, 557, 557, 557, 557, 557, 557,
- 557, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 557, nil, nil, 557, 557, 557, 557, 557, 557, 557,
- 557, 557, 557, nil, 557, 557, nil, nil, nil, 557,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 557,
- nil, nil, 557, nil, nil, 557, 557, nil, nil, 557,
- nil, 557, nil, 557, nil, nil, nil, nil, nil, nil,
- nil, nil, 557, nil, nil, nil, nil, nil, 557, 557,
- 557, 557, 557, 557, nil, nil, nil, 557, 557, 560,
- 560, 560, nil, 560, nil, nil, nil, 560, 560, nil,
- nil, nil, 560, nil, 560, 560, 560, 560, 560, 560,
- 560, nil, nil, nil, nil, 560, 560, 560, 560, 560,
- 560, 560, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 560, nil, nil, 560, 560, 560, 560, 560, 560,
- 560, 560, 560, 560, nil, 560, 560, nil, 560, 560,
- 560, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 560, nil, nil, 560, nil, nil, 560, 560, nil, nil,
- 560, nil, nil, nil, nil, nil, 560, nil, nil, nil,
- nil, nil, nil, nil, 560, nil, nil, nil, nil, 560,
- 560, 560, 560, 560, 560, nil, nil, nil, 560, 560,
- 564, 564, 564, nil, 564, nil, nil, nil, 564, 564,
- nil, nil, nil, 564, nil, 564, 564, 564, 564, 564,
- 564, 564, nil, nil, nil, nil, 564, 564, 564, 564,
- 564, 564, 564, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 564, nil, nil, 564, 564, 564, 564, 564,
- 564, 564, 564, 564, 564, nil, 564, 564, nil, 564,
- 564, 564, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 564, nil, nil, 564, nil, nil, 564, 564, nil,
- nil, 564, nil, nil, nil, nil, nil, 564, nil, nil,
- nil, nil, nil, nil, nil, 564, nil, nil, nil, nil,
- 564, 564, 564, 564, 564, 564, nil, nil, nil, 564,
- 564, 580, 580, 580, nil, 580, nil, nil, nil, 580,
- 580, nil, nil, nil, 580, nil, 580, 580, 580, 580,
- 580, 580, 580, nil, nil, nil, nil, 580, 580, 580,
- 580, 580, 580, 580, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 580, nil, nil, 580, 580, 580, 580,
- 580, 580, 580, 580, 580, 580, nil, 580, 580, nil,
- 580, 580, 580, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 580, nil, nil, 580, nil, nil, 580, 580,
- nil, nil, 580, nil, 580, nil, 580, nil, 580, nil,
- nil, nil, nil, nil, nil, nil, 580, nil, nil, nil,
- nil, 580, 580, 580, 580, 580, 580, nil, nil, nil,
- 580, 580, 584, 584, 584, nil, 584, nil, nil, nil,
- 584, 584, nil, nil, nil, 584, nil, 584, 584, 584,
- 584, 584, 584, 584, nil, nil, nil, nil, 584, 584,
- 584, 584, 584, 584, 584, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 584, nil, nil, 584, 584, 584,
- 584, 584, 584, 584, 584, 584, 584, nil, 584, 584,
- nil, 584, 584, 584, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 584, nil, nil, 584, nil, nil, 584,
- 584, nil, nil, 584, nil, nil, nil, nil, nil, 584,
- nil, nil, nil, nil, nil, nil, nil, 584, nil, nil,
- nil, nil, 584, 584, 584, 584, 584, 584, nil, nil,
- nil, 584, 584, 612, 612, 612, nil, 612, nil, nil,
- nil, 612, 612, nil, nil, nil, 612, nil, 612, 612,
- 612, 612, 612, 612, 612, nil, nil, nil, nil, 612,
- 612, 612, 612, 612, 612, 612, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 612, nil, nil, 612, 612,
- 612, 612, 612, 612, 612, 612, 612, 612, nil, 612,
- 612, nil, 612, 612, 612, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 612, nil, nil, 612, nil, nil,
- 612, 612, nil, nil, 612, nil, nil, nil, nil, nil,
- 612, nil, nil, nil, nil, nil, nil, nil, 612, nil,
- nil, nil, nil, 612, 612, 612, 612, 612, 612, nil,
- nil, nil, 612, 612, 628, 628, 628, nil, 628, nil,
- nil, nil, 628, 628, nil, nil, nil, 628, nil, 628,
- 628, 628, 628, 628, 628, 628, nil, nil, nil, nil,
- 628, 628, 628, 628, 628, 628, 628, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 628, nil, nil, 628,
- 628, 628, 628, 628, 628, 628, 628, 628, 628, nil,
- 628, 628, nil, 628, 628, 628, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 628, nil, nil, 628, nil,
- nil, 628, 628, nil, nil, 628, nil, nil, nil, nil,
- nil, 628, nil, nil, nil, nil, nil, nil, nil, 628,
- nil, nil, nil, nil, 628, 628, 628, 628, 628, 628,
- nil, nil, nil, 628, 628, 634, 634, 634, nil, 634,
- nil, nil, nil, 634, 634, nil, nil, nil, 634, nil,
- 634, 634, 634, 634, 634, 634, 634, nil, nil, nil,
- nil, 634, 634, 634, 634, 634, 634, 634, nil, nil,
- 634, nil, nil, nil, nil, nil, nil, 634, nil, nil,
- 634, 634, 634, 634, 634, 634, 634, 634, 634, 634,
- nil, 634, 634, nil, 634, 634, 634, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 634, nil, nil, 634,
- nil, nil, 634, 634, nil, nil, 634, nil, nil, nil,
- nil, nil, 634, nil, nil, nil, nil, nil, nil, nil,
- 634, nil, nil, nil, nil, 634, 634, 634, 634, 634,
- 634, nil, nil, nil, 634, 634, 679, 679, 679, nil,
- 679, nil, nil, nil, 679, 679, nil, nil, nil, 679,
- nil, 679, 679, 679, 679, 679, 679, 679, nil, nil,
- nil, nil, 679, 679, 679, 679, 679, 679, 679, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 679, nil,
- nil, 679, 679, 679, 679, 679, 679, 679, 679, 679,
- 679, nil, 679, 679, nil, 679, 679, 679, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 679, nil, nil,
- 679, nil, nil, 679, 679, nil, nil, 679, nil, nil,
- nil, nil, nil, 679, nil, nil, nil, nil, nil, nil,
- nil, 679, nil, nil, nil, nil, 679, 679, 679, 679,
- 679, 679, nil, nil, nil, 679, 679, 680, 680, 680,
- nil, 680, nil, nil, nil, 680, 680, nil, nil, nil,
- 680, nil, 680, 680, 680, 680, 680, 680, 680, nil,
- nil, nil, nil, 680, 680, 680, 680, 680, 680, 680,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 680,
- nil, nil, 680, 680, 680, 680, 680, 680, 680, 680,
- 680, 680, nil, 680, 680, nil, 680, 680, 680, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 680, nil,
- nil, 680, nil, nil, 680, 680, nil, nil, 680, nil,
- nil, nil, nil, nil, 680, nil, nil, nil, nil, nil,
- nil, nil, 680, nil, nil, nil, nil, 680, 680, 680,
- 680, 680, 680, nil, nil, nil, 680, 680, 690, 690,
- 690, nil, 690, nil, nil, nil, 690, 690, nil, nil,
- nil, 690, nil, 690, 690, 690, 690, 690, 690, 690,
- nil, nil, nil, nil, 690, 690, 690, 690, 690, 690,
- 690, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 690, nil, nil, 690, 690, 690, 690, 690, 690, 690,
- 690, 690, 690, nil, 690, 690, nil, 690, 690, 690,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 690,
- nil, nil, 690, nil, nil, 690, 690, nil, nil, 690,
- nil, nil, nil, nil, nil, 690, nil, nil, nil, nil,
- nil, nil, nil, 690, nil, nil, nil, nil, 690, 690,
- 690, 690, 690, 690, nil, nil, nil, 690, 690, 691,
- 691, 691, nil, 691, nil, nil, nil, 691, 691, nil,
- nil, nil, 691, nil, 691, 691, 691, 691, 691, 691,
- 691, nil, nil, nil, nil, 691, 691, 691, 691, 691,
- 691, 691, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 691, nil, nil, 691, 691, 691, 691, 691, 691,
- 691, 691, 691, 691, nil, 691, 691, nil, 691, 691,
- 691, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 691, nil, nil, 691, nil, nil, 691, 691, nil, nil,
- 691, nil, nil, nil, nil, nil, 691, nil, nil, nil,
- nil, nil, nil, nil, 691, nil, nil, nil, nil, 691,
- 691, 691, 691, 691, 691, nil, nil, nil, 691, 691,
- 692, 692, 692, nil, 692, nil, nil, nil, 692, 692,
- nil, nil, nil, 692, nil, 692, 692, 692, 692, 692,
- 692, 692, nil, nil, nil, nil, 692, 692, 692, 692,
- 692, 692, 692, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 692, nil, nil, 692, 692, 692, 692, 692,
- 692, 692, 692, 692, 692, nil, 692, 692, nil, 692,
- 692, 692, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 692, nil, nil, 692, nil, nil, 692, 692, nil,
- nil, 692, nil, nil, nil, nil, nil, 692, nil, nil,
- nil, nil, nil, nil, nil, 692, nil, nil, nil, nil,
- 692, 692, 692, 692, 692, 692, nil, nil, nil, 692,
- 692, 698, 698, 698, nil, 698, nil, nil, nil, 698,
- 698, nil, nil, nil, 698, nil, 698, 698, 698, 698,
- 698, 698, 698, nil, nil, nil, nil, 698, 698, 698,
- 698, 698, 698, 698, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 698, nil, nil, 698, 698, 698, 698,
- 698, 698, 698, 698, 698, 698, nil, 698, 698, nil,
- nil, nil, 698, nil, 600, 600, 600, 600, 600, 600,
- 600, 600, 600, 600, 600, nil, 600, 600, nil, nil,
- 600, 600, 698, nil, nil, 698, nil, nil, 698, 698,
- nil, nil, 698, nil, nil, nil, 600, nil, 600, nil,
- 600, 600, 600, 600, 600, 600, 600, nil, 600, nil,
- nil, 698, 698, 698, 698, 698, 698, nil, nil, nil,
- 698, 698, 704, 704, 704, 600, 704, nil, nil, nil,
- 704, 704, nil, nil, nil, 704, nil, 704, 704, 704,
- 704, 704, 704, 704, nil, nil, nil, nil, 704, 704,
- 704, 704, 704, 704, 704, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 704, nil, nil, 704, 704, 704,
- 704, 704, 704, 704, 704, 704, 704, nil, 704, 704,
- nil, 704, 704, 704, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 704, nil, nil, 704, nil, nil, 704,
- 704, nil, nil, 704, nil, 704, nil, 704, nil, 704,
- nil, nil, nil, nil, nil, nil, nil, 704, nil, nil,
- nil, nil, 704, 704, 704, 704, 704, 704, nil, nil,
- nil, 704, 704, 713, 713, 713, nil, 713, nil, nil,
- nil, 713, 713, nil, nil, nil, 713, nil, 713, 713,
- 713, 713, 713, 713, 713, nil, nil, nil, nil, 713,
- 713, 713, 713, 713, 713, 713, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 713, nil, nil, 713, 713,
- 713, 713, 713, 713, 713, 713, 713, 713, nil, 713,
- 713, nil, 713, 713, 713, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 713, nil, nil, 713, nil, nil,
- 713, 713, nil, nil, 713, nil, 713, nil, 713, nil,
- 713, nil, nil, nil, nil, nil, nil, nil, 713, nil,
- nil, nil, nil, 713, 713, 713, 713, 713, 713, nil,
- nil, nil, 713, 713, 715, 715, 715, nil, 715, nil,
- nil, nil, 715, 715, nil, nil, nil, 715, nil, 715,
- 715, 715, 715, 715, 715, 715, nil, nil, nil, nil,
- 715, 715, 715, 715, 715, 715, 715, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 715, nil, nil, 715,
- 715, 715, 715, 715, 715, 715, 715, 715, 715, nil,
- 715, 715, nil, 715, 715, 715, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 715, nil, nil, 715, nil,
- nil, 715, 715, nil, nil, 715, nil, 715, nil, 715,
- nil, 715, nil, nil, nil, nil, nil, nil, nil, 715,
- nil, nil, nil, nil, 715, 715, 715, 715, 715, 715,
- nil, nil, nil, 715, 715, 728, 728, 728, nil, 728,
- nil, nil, nil, 728, 728, nil, nil, nil, 728, nil,
- 728, 728, 728, 728, 728, 728, 728, nil, nil, nil,
- nil, 728, 728, 728, 728, 728, 728, 728, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 728, nil, nil,
- 728, 728, 728, 728, 728, 728, 728, 728, 728, 728,
- nil, 728, 728, nil, nil, nil, 728, nil, 677, 677,
- 677, 677, 677, 677, 677, 677, 677, 677, 677, nil,
- 677, 677, nil, nil, 677, 677, 728, nil, nil, 728,
- nil, nil, 728, 728, nil, nil, 728, nil, nil, nil,
- 677, nil, 677, nil, 677, 677, 677, 677, 677, 677,
- 677, nil, 677, nil, nil, 728, 728, 728, 728, 728,
- 728, nil, nil, nil, 728, 728, 734, 734, 734, 677,
- 734, nil, nil, nil, 734, 734, nil, nil, nil, 734,
- nil, 734, 734, 734, 734, 734, 734, 734, nil, nil,
- nil, nil, 734, 734, 734, 734, 734, 734, 734, nil,
- nil, 734, nil, nil, nil, nil, nil, nil, 734, nil,
- nil, 734, 734, 734, 734, 734, 734, 734, 734, 734,
- 734, nil, 734, 734, nil, 734, 734, 734, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 734, nil, nil,
- 734, nil, nil, 734, 734, nil, nil, 734, nil, nil,
- nil, nil, nil, 734, nil, nil, nil, nil, nil, nil,
- nil, 734, nil, nil, nil, nil, 734, 734, 734, 734,
- 734, 734, nil, nil, nil, 734, 734, 740, 740, 740,
- nil, 740, nil, nil, nil, 740, 740, nil, nil, nil,
- 740, nil, 740, 740, 740, 740, 740, 740, 740, nil,
- nil, nil, nil, 740, 740, 740, 740, 740, 740, 740,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 740,
- nil, nil, 740, 740, 740, 740, 740, 740, 740, 740,
- 740, 740, nil, 740, 740, nil, 740, 740, 740, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 740, nil,
- nil, 740, nil, nil, 740, 740, nil, nil, 740, nil,
- 740, nil, nil, nil, 740, nil, nil, nil, nil, nil,
- nil, nil, 740, nil, nil, nil, nil, 740, 740, 740,
- 740, 740, 740, nil, nil, nil, 740, 740, 759, 759,
- 759, nil, 759, nil, nil, nil, 759, 759, nil, nil,
- nil, 759, nil, 759, 759, 759, 759, 759, 759, 759,
- nil, nil, nil, nil, 759, 759, 759, 759, 759, 759,
- 759, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 759, nil, nil, 759, 759, 759, 759, 759, 759, 759,
- 759, 759, 759, nil, 759, 759, nil, 759, 759, 759,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 759,
- nil, nil, 759, nil, nil, 759, 759, nil, nil, 759,
- nil, nil, nil, nil, nil, 759, nil, nil, nil, nil,
- nil, nil, nil, 759, nil, nil, nil, nil, 759, 759,
- 759, 759, 759, 759, nil, nil, nil, 759, 759, 768,
- 768, 768, nil, 768, nil, nil, nil, 768, 768, nil,
- nil, nil, 768, nil, 768, 768, 768, 768, 768, 768,
- 768, nil, nil, nil, nil, 768, 768, 768, 768, 768,
- 768, 768, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 768, nil, nil, 768, 768, 768, 768, 768, 768,
- 768, 768, 768, 768, nil, 768, 768, nil, 768, 768,
- 768, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 768, nil, nil, 768, nil, nil, 768, 768, nil, nil,
- 768, nil, nil, nil, nil, nil, 768, nil, nil, nil,
- nil, nil, nil, nil, 768, nil, nil, nil, nil, 768,
- 768, 768, 768, 768, 768, nil, nil, nil, 768, 768,
- 769, 769, 769, nil, 769, nil, nil, nil, 769, 769,
- nil, nil, nil, 769, nil, 769, 769, 769, 769, 769,
- 769, 769, nil, nil, nil, nil, 769, 769, 769, 769,
- 769, 769, 769, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 769, nil, nil, 769, 769, 769, 769, 769,
- 769, 769, 769, 769, 769, nil, 769, 769, nil, nil,
- nil, 769, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 769, nil, nil, 769, nil, nil, 769, 769, nil,
- nil, 769, nil, 769, nil, 769, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 769, 769, 769, 769, 769, 769, nil, nil, nil, 769,
- 769, 780, 780, 780, nil, 780, nil, nil, nil, 780,
- 780, nil, nil, nil, 780, nil, 780, 780, 780, 780,
- 780, 780, 780, nil, nil, nil, nil, 780, 780, 780,
- 780, 780, 780, 780, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 780, nil, nil, 780, 780, 780, 780,
- 780, 780, 780, 780, 780, 780, nil, 780, 780, nil,
- 780, 780, 780, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 780, nil, nil, 780, nil, nil, 780, 780,
- nil, nil, 780, nil, nil, nil, nil, nil, 780, nil,
- nil, nil, nil, nil, nil, nil, 780, nil, nil, nil,
- nil, 780, 780, 780, 780, 780, 780, nil, nil, nil,
- 780, 780, 786, 786, 786, nil, 786, nil, nil, nil,
- 786, 786, nil, nil, nil, 786, nil, 786, 786, 786,
- 786, 786, 786, 786, nil, nil, nil, nil, 786, 786,
- 786, 786, 786, 786, 786, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 786, nil, nil, 786, 786, 786,
- 786, 786, 786, 786, 786, 786, 786, nil, 786, 786,
- nil, 786, 786, 786, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 786, nil, nil, 786, nil, nil, 786,
- 786, nil, nil, 786, nil, nil, nil, nil, nil, 786,
- nil, nil, nil, nil, nil, nil, nil, 786, nil, nil,
- nil, nil, 786, 786, 786, 786, 786, 786, nil, nil,
- nil, 786, 786, 788, 788, 788, nil, 788, nil, nil,
- nil, 788, 788, nil, nil, nil, 788, nil, 788, 788,
- 788, 788, 788, 788, 788, nil, nil, nil, nil, 788,
- 788, 788, 788, 788, 788, 788, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 788, nil, nil, 788, 788,
- 788, 788, 788, 788, 788, 788, 788, 788, nil, 788,
- 788, nil, 788, 788, 788, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 788, nil, nil, 788, nil, nil,
- 788, 788, nil, nil, 788, nil, nil, nil, nil, nil,
- 788, nil, nil, nil, nil, nil, nil, nil, 788, nil,
- nil, nil, nil, 788, 788, 788, 788, 788, 788, nil,
- nil, nil, 788, 788, 802, 802, 802, nil, 802, nil,
- nil, nil, 802, 802, nil, nil, nil, 802, nil, 802,
- 802, 802, 802, 802, 802, 802, nil, nil, nil, nil,
- 802, 802, 802, 802, 802, 802, 802, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 802, nil, nil, 802,
- 802, 802, 802, 802, 802, 802, 802, 802, 802, nil,
- 802, 802, nil, 802, 802, 802, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 802, nil, nil, 802, nil,
- nil, 802, 802, nil, nil, 802, nil, nil, nil, nil,
- nil, 802, nil, nil, nil, nil, nil, nil, nil, 802,
- nil, nil, nil, nil, 802, 802, 802, 802, 802, 802,
- nil, nil, nil, 802, 802, 820, 820, 820, nil, 820,
- nil, nil, nil, 820, 820, nil, nil, nil, 820, nil,
- 820, 820, 820, 820, 820, 820, 820, nil, nil, nil,
- nil, 820, 820, 820, 820, 820, 820, 820, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 820, nil, nil,
- 820, 820, 820, 820, 820, 820, 820, 820, 820, 820,
- nil, 820, 820, nil, nil, nil, 820, nil, 682, 682,
- 682, 682, 682, 682, 682, 682, 682, 682, 682, nil,
- 682, 682, nil, nil, 682, 682, 820, nil, nil, 820,
- nil, nil, 820, 820, nil, nil, 820, nil, nil, nil,
- 682, nil, 682, nil, 682, 682, 682, 682, 682, 682,
- 682, nil, 682, nil, nil, 820, 820, 820, 820, 820,
- 820, nil, nil, nil, 820, 820, 822, 822, 822, 682,
- 822, nil, nil, nil, 822, 822, nil, nil, nil, 822,
- nil, 822, 822, 822, 822, 822, 822, 822, nil, nil,
- nil, nil, 822, 822, 822, 822, 822, 822, 822, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 822, nil,
- nil, 822, 822, 822, 822, 822, 822, 822, 822, 822,
- 822, nil, 822, 822, nil, 822, 822, 822, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 822, nil, nil,
- 822, nil, nil, 822, 822, nil, nil, 822, nil, 822,
- nil, nil, nil, 822, nil, nil, nil, nil, nil, nil,
- nil, 822, nil, nil, nil, nil, 822, 822, 822, 822,
- 822, 822, nil, nil, nil, 822, 822, 827, 827, 827,
- nil, 827, nil, nil, nil, 827, 827, nil, nil, nil,
- 827, nil, 827, 827, 827, 827, 827, 827, 827, nil,
- nil, nil, nil, 827, 827, 827, 827, 827, 827, 827,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 827,
- nil, nil, 827, 827, 827, 827, 827, 827, 827, 827,
- 827, 827, nil, 827, 827, nil, nil, nil, 827, nil,
- 684, 684, 684, 684, 684, 684, 684, 684, 684, 684,
- 684, nil, 684, 684, nil, nil, 684, 684, 827, nil,
- nil, 827, nil, nil, 827, 827, nil, nil, 827, nil,
- nil, nil, 684, nil, 684, nil, 684, 684, 684, 684,
- 684, 684, 684, nil, 684, nil, nil, 827, 827, 827,
- 827, 827, 827, nil, nil, nil, 827, 827, 832, 832,
- 832, 684, 832, nil, nil, nil, 832, 832, nil, nil,
- nil, 832, nil, 832, 832, 832, 832, 832, 832, 832,
- nil, nil, nil, nil, 832, 832, 832, 832, 832, 832,
- 832, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 832, nil, nil, 832, 832, 832, 832, 832, 832, 832,
- 832, 832, 832, nil, 832, 832, nil, 832, 832, 832,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 832,
- nil, nil, 832, nil, nil, 832, 832, nil, nil, 832,
- nil, 832, nil, 832, nil, 832, nil, nil, nil, nil,
- nil, nil, nil, 832, nil, nil, nil, nil, 832, 832,
- 832, 832, 832, 832, nil, nil, nil, 832, 832, 835,
- 835, 835, nil, 835, nil, nil, nil, 835, 835, nil,
- nil, nil, 835, nil, 835, 835, 835, 835, 835, 835,
- 835, nil, nil, nil, nil, 835, 835, 835, 835, 835,
- 835, 835, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 835, nil, nil, 835, 835, 835, 835, 835, 835,
- 835, 835, 835, 835, nil, 835, 835, nil, 835, 835,
- 835, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 835, nil, nil, 835, nil, nil, 835, 835, nil, nil,
- 835, nil, 835, nil, 835, nil, 835, nil, nil, nil,
- nil, nil, nil, nil, 835, nil, nil, nil, nil, 835,
- 835, 835, 835, 835, 835, nil, nil, nil, 835, 835,
- 861, 861, 861, nil, 861, nil, nil, nil, 861, 861,
- nil, nil, nil, 861, nil, 861, 861, 861, 861, 861,
- 861, 861, nil, nil, nil, nil, 861, 861, 861, 861,
- 861, 861, 861, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 861, nil, nil, 861, 861, 861, 861, 861,
- 861, 861, 861, 861, 861, nil, 861, 861, nil, nil,
- nil, 861, nil, 687, 687, 687, 687, 687, 687, 687,
- 687, 687, 687, 687, nil, 687, 687, nil, nil, 687,
- 687, 861, nil, nil, 861, nil, nil, 861, 861, nil,
- nil, 861, nil, nil, nil, 687, nil, 687, nil, 687,
- 687, 687, 687, 687, 687, 687, nil, 687, nil, nil,
- 861, 861, 861, 861, 861, 861, nil, nil, nil, 861,
- 861, 864, 864, 864, 687, 864, nil, nil, nil, 864,
- 864, nil, nil, nil, 864, nil, 864, 864, 864, 864,
- 864, 864, 864, nil, nil, nil, nil, 864, 864, 864,
- 864, 864, 864, 864, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 864, nil, nil, 864, 864, 864, 864,
- 864, 864, 864, 864, 864, 864, nil, 864, 864, nil,
- 864, 864, 864, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 864, nil, nil, 864, nil, nil, 864, 864,
- nil, nil, 864, nil, nil, nil, nil, nil, 864, nil,
- nil, nil, nil, nil, nil, nil, 864, nil, nil, nil,
- nil, 864, 864, 864, 864, 864, 864, nil, nil, nil,
- 864, 864, 867, 867, 867, nil, 867, nil, nil, nil,
- 867, 867, nil, nil, nil, 867, nil, 867, 867, 867,
- 867, 867, 867, 867, nil, nil, nil, nil, 867, 867,
- 867, 867, 867, 867, 867, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 867, nil, nil, 867, 867, 867,
- 867, 867, 867, 867, 867, 867, 867, nil, 867, 867,
- nil, 867, 867, 867, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 867, nil, nil, 867, nil, nil, 867,
- 867, nil, nil, 867, nil, nil, nil, nil, nil, 867,
- nil, nil, nil, nil, nil, nil, nil, 867, nil, nil,
- nil, nil, 867, 867, 867, 867, 867, 867, nil, nil,
- nil, 867, 867, 875, 875, 875, nil, 875, nil, nil,
- nil, 875, 875, nil, nil, nil, 875, nil, 875, 875,
- 875, 875, 875, 875, 875, nil, nil, nil, nil, 875,
- 875, 875, 875, 875, 875, 875, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 875, nil, nil, 875, 875,
- 875, 875, 875, 875, 875, 875, 875, 875, nil, 875,
- 875, nil, nil, nil, 875, nil, 689, 689, 689, 689,
- 689, 689, 689, 689, 689, 689, 689, nil, 689, 689,
- nil, nil, 689, 689, 875, nil, nil, 875, nil, nil,
- 875, 875, nil, nil, 875, nil, nil, nil, 689, nil,
- 689, nil, 689, 689, 689, 689, 689, 689, 689, nil,
- 689, nil, nil, 875, 875, 875, 875, 875, 875, nil,
- nil, nil, 875, 875, 880, 880, 880, 689, 880, nil,
- nil, nil, 880, 880, nil, nil, nil, 880, nil, 880,
- 880, 880, 880, 880, 880, 880, nil, nil, nil, nil,
- 880, 880, 880, 880, 880, 880, 880, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 880, nil, nil, 880,
- 880, 880, 880, 880, 880, 880, 880, 880, 880, nil,
- 880, 880, nil, 880, 880, 880, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 880, nil, nil, 880, nil,
- nil, 880, 880, nil, nil, 880, nil, 880, nil, 880,
- nil, 880, nil, nil, nil, nil, nil, nil, nil, 880,
- nil, nil, nil, nil, 880, 880, 880, 880, 880, 880,
- nil, nil, nil, 880, 880, 886, 886, 886, nil, 886,
- nil, nil, nil, 886, 886, nil, nil, nil, 886, nil,
- 886, 886, 886, 886, 886, 886, 886, nil, nil, nil,
- nil, 886, 886, 886, 886, 886, 886, 886, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 886, nil, nil,
- 886, 886, 886, 886, 886, 886, 886, 886, 886, 886,
- nil, 886, 886, nil, nil, nil, 886, nil, 694, 694,
- 694, 694, 694, 694, 694, 694, 694, 694, 694, nil,
- 694, 694, nil, nil, 694, 694, 886, nil, nil, 886,
- nil, nil, 886, 886, nil, nil, 886, nil, nil, nil,
- 694, nil, 694, nil, 694, 694, 694, 694, 694, 694,
- 694, nil, 694, nil, nil, 886, 886, 886, 886, 886,
- 886, nil, nil, nil, 886, 886, 889, 889, 889, 694,
- 889, nil, nil, nil, 889, 889, nil, nil, nil, 889,
- nil, 889, 889, 889, 889, 889, 889, 889, nil, nil,
- nil, nil, 889, 889, 889, 889, 889, 889, 889, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 889, nil,
- nil, 889, 889, 889, 889, 889, 889, 889, 889, 889,
- 889, nil, 889, 889, nil, 889, 889, 889, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 889, nil, nil,
- 889, nil, nil, 889, 889, nil, nil, 889, nil, nil,
- nil, nil, nil, 889, nil, nil, nil, nil, nil, nil,
- nil, 889, nil, nil, nil, nil, 889, 889, 889, 889,
- 889, 889, nil, nil, nil, 889, 889, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, nil, nil, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, nil, nil, nil, nil, nil, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- nil, nil, nil, nil, nil, nil, 64, 64, nil, 64,
- 64, 64, 64, nil, 64, 64, nil, nil, 64, nil,
- nil, nil, nil, 64, 64, 64, 64, nil, nil, nil,
- nil, nil, 64, nil, nil, nil, nil, nil, nil, nil,
- 64, 64, nil, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, nil, 64, nil, nil, 64, 664, 664, 664,
- 664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
- 664, 664, 664, 664, 664, 664, 664, 664, 664, 664,
- 664, nil, nil, 664, 664, 664, 664, 664, 664, 664,
- 664, 664, 664, nil, nil, nil, nil, nil, 664, 664,
- 664, 664, 664, 664, 664, 664, nil, nil, 664, nil,
- nil, nil, nil, nil, nil, nil, 664, 664, nil, 664,
- 664, 664, 664, nil, 664, 664, nil, nil, 664, nil,
- nil, nil, nil, 664, 664, 664, 664, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 664, 664, nil, 664, 664, 664, 664, 664, 664, 664,
- 664, 664, nil, 664, nil, nil, 664, 581, 581, 581,
- 581, 581, 581, 581, 581, 581, 581, 581, nil, 581,
- 581, nil, nil, 581, 581, nil, nil, nil, 581, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 581,
- nil, 581, nil, 581, 581, 581, 581, 581, 581, 581,
- nil, 581, nil, nil, nil, nil, nil, nil, nil, 192,
- 192, nil, nil, 192, nil, nil, nil, nil, 581, nil,
- 581, 192, 192, nil, 192, 192, 192, 192, nil, 192,
- 192, nil, nil, 192, nil, nil, nil, nil, 192, 192,
- 192, 192, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 192, 192, nil, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, nil, 192, 193,
- 193, 192, nil, 193, nil, nil, nil, nil, nil, nil,
- nil, 193, 193, nil, 193, 193, 193, 193, nil, 193,
- 193, nil, nil, 193, nil, nil, nil, nil, 193, 193,
- 193, 193, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 193, 193, nil, 193, 193,
- 193, 193, 193, 193, 193, 193, 193, nil, 193, 251,
- 251, 193, nil, 251, nil, nil, nil, nil, nil, nil,
- nil, 251, 251, nil, 251, 251, 251, 251, nil, 251,
- 251, nil, nil, 251, nil, nil, nil, nil, 251, 251,
- 251, 251, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 251, 251, nil, 251, 251,
- 251, 251, 251, 251, 251, 251, 251, nil, 251, 252,
- 252, 251, nil, 252, nil, nil, nil, nil, nil, nil,
- nil, 252, 252, nil, 252, 252, 252, 252, nil, 252,
- 252, nil, nil, 252, nil, nil, nil, nil, 252, 252,
- 252, 252, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 252, 252, nil, 252, 252,
- 252, 252, 252, 252, 252, 252, 252, nil, 252, 391,
- 391, 252, nil, 391, nil, nil, nil, nil, nil, nil,
- nil, 391, 391, nil, 391, 391, 391, 391, nil, 391,
- 391, nil, nil, 391, nil, nil, nil, nil, 391, 391,
- 391, 391, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 391, 391, nil, 391, 391,
- 391, 391, 391, 391, 391, 391, 391, nil, 391, 392,
- 392, 391, nil, 392, nil, nil, nil, nil, nil, nil,
- nil, 392, 392, nil, 392, 392, 392, 392, nil, 392,
- 392, nil, nil, 392, nil, nil, nil, nil, 392, 392,
- 392, 392, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 392, 392, nil, 392, 392,
- 392, 392, 392, 392, 392, 392, 392, nil, 392, nil,
- nil, 392, 423, 423, 423, 423, 423, 423, 423, 423,
- 423, 423, 423, nil, 423, 423, nil, nil, 423, 423,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 423, nil, 423, nil, 423, 423,
- 423, 423, 423, 423, 423, nil, 423, nil, nil, nil,
- nil, nil, nil, 457, 457, nil, nil, 457, nil, nil,
- nil, nil, nil, 423, 423, 457, 457, nil, 457, 457,
- 457, 457, nil, 457, 457, nil, nil, 457, nil, nil,
- nil, nil, 457, 457, 457, 457, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 457,
- 457, nil, 457, 457, 457, 457, 457, 457, 457, 457,
- 457, nil, 457, 458, 458, 457, nil, 458, nil, nil,
- nil, nil, nil, nil, nil, 458, 458, nil, 458, 458,
- 458, 458, nil, 458, 458, nil, nil, 458, nil, nil,
- nil, nil, 458, 458, 458, 458, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 458,
- 458, nil, 458, 458, 458, 458, 458, 458, 458, 458,
- 458, nil, 458, 466, 466, 458, nil, 466, nil, nil,
- nil, nil, nil, nil, nil, 466, 466, nil, 466, 466,
- 466, 466, nil, 466, 466, nil, nil, 466, nil, nil,
- nil, nil, 466, 466, 466, 466, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 466,
- 466, nil, 466, 466, 466, 466, 466, 466, 466, 466,
- 466, nil, 466, 467, 467, 466, nil, 467, nil, nil,
- nil, nil, nil, nil, nil, 467, 467, nil, 467, 467,
- 467, 467, nil, 467, 467, nil, nil, 467, nil, nil,
- nil, nil, 467, 467, 467, 467, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 467,
- 467, nil, 467, 467, 467, 467, 467, 467, 467, 467,
- 467, nil, 467, 498, 498, 467, nil, 498, nil, nil,
- nil, nil, nil, nil, nil, 498, 498, nil, 498, 498,
- 498, 498, nil, 498, 498, nil, nil, 498, nil, nil,
- nil, nil, 498, 498, 498, 498, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 498,
- 498, nil, 498, 498, 498, 498, 498, 498, 498, 498,
- 498, nil, 498, 499, 499, 498, nil, 499, nil, nil,
- nil, nil, nil, nil, nil, 499, 499, nil, 499, 499,
- 499, 499, nil, 499, 499, nil, nil, 499, nil, nil,
- nil, nil, 499, 499, 499, 499, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 499,
- 499, nil, 499, 499, 499, 499, 499, 499, 499, 499,
- 499, nil, 499, 505, 505, 499, nil, 505, nil, nil,
- nil, nil, nil, nil, nil, 505, 505, nil, 505, 505,
- 505, 505, nil, 505, 505, nil, nil, 505, nil, nil,
- nil, nil, 505, 505, 505, 505, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 505,
- 505, nil, 505, 505, 505, 505, 505, 505, 505, 505,
- 505, nil, 505, 507, 507, 505, nil, 507, nil, nil,
- nil, nil, nil, nil, nil, 507, 507, nil, 507, 507,
- 507, 507, nil, 507, 507, nil, nil, 507, nil, nil,
- nil, nil, 507, 507, 507, 507, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 507,
- 507, nil, 507, 507, 507, 507, 507, 507, 507, 507,
- 507, nil, 507, 578, 578, 507, nil, 578, nil, nil,
- nil, nil, nil, nil, nil, 578, 578, nil, 578, 578,
- 578, 578, nil, 578, 578, nil, nil, 578, nil, nil,
- nil, nil, 578, 578, 578, 578, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 578,
- 578, nil, 578, 578, 578, 578, 578, 578, 578, 578,
- 578, nil, 578, 579, 579, 578, nil, 579, nil, nil,
- nil, nil, nil, nil, nil, 579, 579, nil, 579, 579,
- 579, 579, nil, 579, 579, nil, nil, 579, nil, nil,
- nil, nil, 579, 579, 579, 579, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 579,
- 579, nil, 579, 579, 579, 579, 579, 579, 579, 579,
- 579, nil, 579, 823, 823, 579, nil, 823, nil, nil,
- nil, nil, nil, nil, nil, 823, 823, nil, 823, 823,
- 823, 823, nil, 823, 823, nil, nil, 823, nil, nil,
- nil, nil, 823, 823, 823, 823, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 823,
- 823, nil, 823, 823, 823, 823, 823, 823, 823, 823,
- 823, nil, 823, 824, 824, 823, nil, 824, nil, nil,
- nil, nil, nil, nil, nil, 824, 824, nil, 824, 824,
- 824, 824, nil, 824, 824, nil, nil, 824, nil, nil,
- nil, nil, 824, 824, 824, 824, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 824,
- 824, nil, 824, 824, 824, 824, 824, 824, 824, 824,
- 824, nil, 824, nil, nil, 824, 480, 480, 480, 480,
- 480, 480, 480, 480, 480, 480, 480, nil, 480, 480,
- nil, nil, 480, 480, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 480, nil,
- 480, nil, 480, 480, 480, 480, 480, 480, 480, nil,
- 480, nil, 731, 731, 731, 731, 731, 731, 731, 731,
- 731, 731, 731, nil, 731, 731, 480, 480, 731, 731,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 731, nil, 731, nil, 731, 731,
- 731, 731, 731, 731, 731, nil, 731, nil, 767, 767,
- 767, 767, 767, 767, 767, 767, 767, 767, 767, nil,
- 767, 767, 731, 731, 767, 767, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 767, nil, 767, nil, 767, 767, 767, 767, 767, 767,
- 767, nil, 767, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 767 ]
-
-racc_action_pointer = [
- 1233, 30, nil, -98, 863, 4770, 4891, 5012, -53, 2,
- 71, 90, 160, 218, 174, 130, nil, 5125, 5246, 6094,
- 234, nil, 5367, 5488, 5609, 292, 138, 5730, 5851, nil,
- 1355, 5972, 6093, nil, 146, 316, 245, 346, 6214, 6335,
- 6456, 183, 300, nil, nil, nil, nil, nil, nil, nil,
- 214, 1477, 6577, 6698, 6819, 58, 6940, 7061, nil, nil,
- 735, 7182, 7303, 7424, 22775, nil, nil, nil, nil, nil,
- -92, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 7545, nil, nil, nil, 7666, nil, nil, nil,
- nil, nil, nil, nil, nil, 311, nil, 863, nil, nil,
- nil, 7787, 7908, 8029, 8150, 8271, 981, nil, 221, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 196, nil, 1599, 1721, 8392, 8513,
- 8634, 8755, 23000, 23060, 8876, 8997, 9118, nil, 377, -67,
- 279, -52, 212, 274, 1843, nil, nil, 9239, 9360, 9481,
- 9602, 9723, 9844, 9965, 10086, 10207, 10328, 10449, 10570, 10691,
- 10812, 10933, 11054, 11175, 11296, 11417, 11538, 11659, 11780, 11901,
- 12022, 12143, 12264, 12385, nil, nil, nil, 7183, nil, 242,
- 254, 12506, nil, 12627, 310, nil, nil, nil, nil, nil,
- nil, 23120, 23180, 313, 12748, 12869, nil, nil, nil, nil,
- nil, nil, nil, 12990, 325, 1965, 333, 352, 315, 13111,
- 2087, 399, 496, 430, 520, 411, 382, 161, nil, 443,
- 430, nil, nil, 335, 472, 486, 521, nil, 498, nil,
- 13232, nil, 565, 566, 457, nil, 460, 119, 136, 13353,
- 493, 147, 479, 244, nil, 482, -7, 8, 13474, 13595,
- -67, 32, 464, -9, 522, 545, -1, 575, nil, nil,
- 319, 345, 115, nil, 614, nil, 9, 13716, nil, nil,
- 311, 419, 453, 456, 457, 478, 488, 499, nil, 519,
- nil, 13837, nil, 149, 207, 235, 246, -35, 279, nil,
- 1103, nil, nil, nil, nil, nil, nil, 13958, nil, nil,
- nil, nil, 509, 511, nil, nil, 735, nil, 495, 14071,
- nil, 499, nil, nil, 7304, 535, 340, 342, 14192, nil,
- nil, 0, 541, 107, nil, 14313, 14434, nil, 7425, nil,
- nil, 23240, 23300, 14555, -33, 14676, 14797, 14918, 614, 863,
- 377, 384, 566, 574, 575, 576, 2941, 3063, 3185, 1599,
- 980, 1721, 1843, 1965, 2087, 2209, 2331, 2453, 2575, 249,
- 465, 2697, 2819, 23348, -48, nil, 15039, nil, 15160, 514,
- nil, 15281, 321, nil, nil, 376, nil, nil, 563, 531,
- -64, 529, 630, nil, nil, 15402, -27, -13, 571, nil,
- 572, 544, nil, nil, nil, 586, 15523, 23414, 23474, 617,
- 606, nil, nil, 15644, 15765, 15886, 23534, 23594, 13112, 16007,
- 688, 16128, nil, 582, nil, nil, 16249, nil, nil, 16370,
- 24122, nil, 16491, nil, nil, nil, 2209, 711, nil, nil,
- 2331, 68, 109, 708, 716, 2453, 16612, 16733, 23654, 23714,
- 4, nil, nil, 658, nil, 23774, 16854, 23834, nil, nil,
- 16975, 100, -34, 2575, 997, nil, nil, nil, -32, nil,
- nil, nil, 598, nil, nil, nil, 609, nil, 147, nil,
- nil, 606, nil, nil, 17096, nil, nil, 17209, 17330, nil,
- 349, 17451, 17572, 648, nil, nil, 17693, 649, nil, 17814,
- 86, 115, 493, 614, 655, 1106, 17935, 18056, nil, 2697,
- 18177, 621, nil, 666, 18298, nil, 674, nil, 663, nil,
- nil, nil, nil, nil, 113, nil, 673, 674, 23894, 23954,
- 18419, 22933, 69, 643, 18540, nil, 683, nil, 2819, 2941,
- nil, 1, nil, 681, 63, 112, 687, 347, 735, 688,
- 19630, 712, 714, -2, 772, nil, 3063, 654, 707, nil,
- nil, 707, 18661, nil, nil, 506, nil, 800, nil, nil,
- nil, nil, nil, 810, nil, 814, 700, 15, 18782, 738,
- 13, 23, 25, 75, 18903, 348, 788, nil, 740, 3185,
- 331, nil, nil, 835, 3307, 1284, 337, 718, 719, 726,
- nil, nil, nil, nil, nil, 724, nil, nil, nil, nil,
- 806, nil, nil, 809, 22885, 773, nil, nil, nil, nil,
- nil, 3429, nil, nil, nil, nil, nil, 20114, 744, 19024,
- 19145, nil, 21324, nil, 21566, nil, nil, 21929, nil, 22292,
- 19266, 19387, 19508, 167, 22534, nil, 745, 984, 19629, nil,
- 770, 868, 760, nil, 19750, 761, 3551, nil, nil, 802,
- 803, -63, 871, 19871, nil, 19992, 772, nil, 832, 813,
- 933, 738, nil, nil, 3673, nil, nil, 31, 20113, nil,
- nil, 24168, 938, nil, 20234, 941, 3795, 3917, nil, nil,
- 20355, 4039, nil, 26, 133, nil, 942, nil, 4161, nil,
- 946, 836, nil, 1406, nil, -43, nil, nil, 436, 20476,
- nil, nil, nil, nil, 862, nil, nil, 24214, 20597, 20718,
- 863, 866, 920, 907, 847, 884, nil, nil, nil, nil,
- 20839, nil, 873, 903, 869, nil, 20960, 870, 21081, nil,
- nil, nil, nil, nil, 4283, nil, nil, nil, 32, nil,
- 999, 1001, 21202, 332, nil, nil, 1002, nil, 936, 898,
- 899, nil, nil, 900, 899, nil, nil, 1528, nil, nil,
- 21323, 1106, 21444, 24014, 24074, 918, 933, 21565, 5973, nil,
- nil, nil, 21686, 914, nil, 21807, 918, 1046, 4405, nil,
- nil, nil, nil, nil, nil, 4527, nil, nil, 282, nil,
- nil, nil, 4649, nil, 927, 959, 965, 362, 400, 482,
- 977, 21928, nil, nil, 22049, 931, nil, 22170, nil, nil,
- 545, 1054, 938, 1057, 972, 22291, 980, nil, 945, nil,
- 22412, 948, nil, nil, nil, nil, 22533, nil, nil, 22654,
- nil, nil, 952, nil ]
-
-racc_action_default = [
- -4, -497, -1, -485, -5, -497, -497, -497, -497, -497,
- -497, -497, -497, -497, -271, -32, -33, -497, -497, -38,
- -40, -41, -282, -315, -316, -45, -249, -361, -285, -58,
- -4, -62, -67, -68, -497, -428, -497, -497, -497, -497,
- -497, -487, -214, -264, -265, -266, -267, -268, -269, -270,
- -475, -4, -497, -496, -467, -288, -497, -497, -292, -295,
- -485, -497, -497, -497, -497, -317, -318, -381, -382, -383,
- -384, -385, -399, -388, -401, -401, -392, -397, -411, -401,
- -413, -414, -417, -418, -419, -420, -421, -422, -423, -424,
- -425, -426, -427, -430, -431, -497, -3, -486, -492, -493,
- -494, -497, -497, -497, -497, -497, -6, -8, -497, -93,
- -94, -95, -96, -97, -98, -99, -100, -101, -105, -106,
- -107, -108, -109, -110, -111, -112, -113, -114, -115, -116,
- -117, -118, -119, -120, -121, -122, -123, -124, -125, -126,
- -127, -128, -129, -130, -131, -132, -133, -134, -135, -136,
- -137, -138, -139, -140, -141, -142, -143, -144, -145, -146,
- -147, -148, -149, -150, -151, -152, -153, -154, -155, -156,
- -157, -158, -159, -160, -161, -162, -163, -164, -165, -166,
- -167, -168, -169, -170, -13, -102, -4, -4, -497, -497,
- -497, -496, -497, -497, -497, -497, -497, -36, -497, -428,
- -497, -271, -497, -497, -4, -37, -206, -497, -497, -497,
- -497, -497, -497, -497, -497, -497, -497, -497, -497, -497,
- -497, -497, -497, -497, -497, -497, -497, -497, -497, -497,
- -497, -497, -497, -497, -351, -353, -42, -215, -228, -258,
- -258, -497, -236, -497, -259, -282, -315, -316, -470, -43,
- -44, -497, -497, -50, -496, -497, -287, -356, -362, -364,
- -56, -360, -57, -497, -58, -4, -497, -497, -63, -65,
- -4, -72, -497, -497, -79, -285, -487, -497, -319, -361,
- -497, -66, -70, -278, -415, -416, -497, -191, -192, -207,
- -497, -488, -373, -497, -274, -216, -487, -489, -489, -497,
- -497, -489, -497, -489, -289, -39, -497, -497, -497, -497,
- -485, -497, -486, -428, -497, -497, -271, -497, -331, -332,
- -88, -89, -497, -91, -497, -271, -497, -497, -428, -308,
- -93, -94, -131, -132, -148, -153, -160, -163, -310, -497,
- -465, -497, -386, -497, -497, -497, -497, -497, -497, 894,
- -7, -495, -14, -15, -16, -17, -18, -497, -10, -11,
- -12, -103, -497, -497, -21, -29, -171, -259, -497, -497,
- -22, -30, -31, -23, -173, -497, -476, -477, -226, -478,
- -479, -476, -249, -477, -359, -481, -482, -28, -180, -34,
- -35, -497, -497, -496, -278, -497, -497, -497, -181, -182,
- -183, -184, -185, -186, -187, -188, -193, -194, -195, -196,
- -197, -198, -199, -200, -201, -202, -203, -204, -205, -208,
- -209, -210, -211, -497, -347, -229, -497, -231, -497, -258,
- -256, -497, -249, -476, -477, -249, -48, -51, -497, -487,
- -487, -258, -228, -250, -251, -252, -347, -347, -497, -284,
- -497, -59, -276, -71, -64, -497, -496, -497, -497, -78,
- -497, -415, -416, -497, -497, -497, -497, -497, -212, -497,
- -496, -496, -273, -487, -217, -218, -491, -490, -220, -491,
- -487, -280, -491, -469, -281, -468, -4, -320, -321, -322,
- -4, -497, -497, -497, -497, -4, -497, -496, -497, -497,
- -278, -301, -88, -89, -90, -497, -496, -497, -304, -432,
- -497, -497, -497, -4, -445, -312, -483, -484, -487, -387,
- -400, -403, -497, -405, -389, -402, -497, -391, -497, -394,
- -396, -497, -412, -9, -497, -19, -20, -497, -497, -263,
- -279, -497, -497, -52, -227, -357, -497, -54, -358, -497,
- -476, -477, -480, -277, -497, -171, -497, -497, -349, -4,
- -497, -258, -257, -260, -497, -471, -497, -235, -497, -472,
- -46, -354, -47, -355, -347, -222, -497, -497, -497, -497,
- -497, -38, -497, -258, -497, -248, -497, -254, -4, -4,
- -283, -59, -69, -497, -476, -477, -226, -75, -77, -497,
- -179, -189, -190, -497, -496, -329, -4, -374, -496, -375,
- -376, -497, -497, -260, -221, -496, -323, -496, -293, -324,
- -325, -326, -296, -497, -299, -497, -367, -497, -497, -497,
- -476, -477, -480, -277, -497, -88, -89, -92, -497, -4,
- -497, -434, -306, -497, -4, -445, -497, -464, -464, -464,
- -444, -446, -447, -448, -449, -450, -451, -454, -456, -457,
- -459, -460, -461, -497, -497, -497, -404, -407, -408, -409,
- -410, -4, -390, -393, -395, -398, -104, -172, -261, -497,
- -497, -25, -175, -26, -176, -53, -27, -177, -55, -178,
- -497, -497, -497, -279, -213, -333, -335, -345, -497, -348,
- -497, -497, -258, -233, -497, -258, -4, -223, -224, -226,
- -226, -487, -497, -497, -241, -497, -258, -253, -497, -497,
- -497, -73, -286, -2, -4, -380, -330, -497, -497, -378,
- -275, -487, -497, -327, -497, -497, -4, -4, -298, -300,
- -497, -4, -369, -279, -497, -279, -497, -433, -4, -309,
- -497, -487, -436, -497, -440, -497, -442, -443, -497, -497,
- -458, -462, -313, -466, -497, -262, -24, -174, -497, -336,
- -80, -497, -497, -87, -344, -497, -346, -350, -352, -230,
- -497, -232, -497, -497, -258, -238, -497, -258, -497, -247,
- -255, -363, -365, -379, -4, -377, -219, -290, -497, -291,
- -497, -497, -497, -496, -302, -305, -497, -311, -497, -464,
- -464, -452, -463, -464, -497, -455, -453, -445, -406, -334,
- -497, -341, -496, -497, -497, -86, -497, -497, -258, -49,
- -225, -237, -497, -258, -243, -497, -258, -373, -4, -294,
- -297, -368, -366, -370, -371, -4, -307, -435, -497, -438,
- -439, -441, -4, -337, -340, -497, -497, -82, -84, -83,
- -85, -497, -343, -234, -497, -258, -239, -497, -242, -372,
- -496, -497, -464, -497, -497, -497, -81, -342, -258, -244,
- -497, -258, -328, -303, -437, -314, -497, -339, -240, -497,
- -245, -338, -258, -246 ]
-
-racc_goto_table = [
- 10, 205, 240, 240, 240, 10, 268, 438, 112, 112,
- 100, 300, 338, 470, 293, 644, 242, 242, 242, 440,
- 107, 185, 238, 238, 238, 115, 115, 117, 117, 494,
- 10, 486, 490, 650, 303, 437, 239, 239, 239, 253,
- 260, 262, 604, 290, 365, 372, 732, 618, 622, 96,
- 565, 10, 815, 296, 257, 261, 281, 571, 504, 520,
- 573, 318, 529, 236, 249, 250, 112, 100, 301, 559,
- 810, 264, 813, 266, 106, 475, 478, 344, 345, 483,
- 1, 485, 348, 723, 754, 756, 757, 326, 329, 306,
- 307, 588, 589, 310, 97, 13, 184, 10, 319, 357,
- 13, 565, 574, 534, 587, 10, 311, 443, 586, 718,
- 340, 302, 198, 198, 304, 317, 508, 198, 198, 198,
- 339, 515, 473, 308, 736, 13, 272, 272, 309, 737,
- 634, 278, 278, 845, 352, 353, 354, 355, 639, 748,
- 513, 197, 514, 664, 817, 815, 13, 198, 198, 375,
- 696, 198, 198, 700, 424, 198, 314, 324, 324, 446,
- 447, 278, 278, 278, 650, 872, 350, 627, 842, 608,
- 727, 364, 370, 373, 356, 342, 294, 387, 343, 346,
- 305, 305, 528, 347, 305, 666, 10, 10, 671, 735,
- 751, 296, 13, 809, 811, 386, 198, 198, 198, 198,
- 13, 2, 368, 368, 10, nil, nil, nil, nil, nil,
- nil, 623, nil, nil, nil, nil, nil, nil, nil, 706,
- nil, nil, nil, 605, 610, 305, 305, 305, 305, nil,
- nil, 267, nil, nil, 240, 240, nil, nil, nil, nil,
- nil, 637, nil, 240, 674, nil, 849, 850, 242, 242,
- 851, nil, nil, nil, 442, 238, nil, 242, nil, nil,
- nil, nil, nil, 238, nil, 10, nil, nil, 441, 239,
- 10, nil, nil, nil, nil, nil, nil, 239, 460, nil,
- nil, 13, 13, 198, 198, 198, 198, nil, nil, 198,
- 198, 198, 14, 454, nil, 439, 444, 14, 474, 13,
- 804, 882, nil, 427, 448, 257, 264, 261, 450, 884,
- nil, 264, nil, 455, nil, nil, nil, 100, 852, 389,
- 390, nil, 14, 274, 274, 685, 565, 609, nil, 688,
- nil, nil, nil, 509, 571, 573, 650, 565, nil, nil,
- nil, 491, 492, 14, nil, 711, nil, nil, nil, 198,
- 198, 554, 741, 316, 325, 325, 493, 725, 198, 112,
- 13, 729, nil, nil, 272, 13, nil, nil, 605, 278,
- 605, 533, nil, nil, nil, 843, 115, nil, 117, nil,
- nil, nil, nil, nil, nil, nil, nil, 362, 363, 14,
- nil, 543, nil, 296, 386, 547, nil, 14, nil, nil,
- nil, nil, nil, 198, 198, 267, 561, nil, nil, nil,
- 548, nil, nil, nil, 593, nil, nil, nil, nil, nil,
- nil, nil, 198, nil, nil, 583, nil, nil, nil, nil,
- nil, nil, 305, 305, nil, nil, 198, nil, nil, 585,
- nil, 576, 577, nil, nil, 570, nil, nil, 572, nil,
- nil, 512, 794, nil, nil, 629, 296, 565, nil, nil,
- 386, nil, nil, nil, 638, 518, 267, nil, nil, 386,
- nil, 267, nil, nil, nil, 611, 643, nil, 14, 14,
- nil, nil, 614, nil, nil, 368, 10, nil, 198, nil,
- 10, nil, 567, nil, nil, 10, 14, 296, 619, 619,
- nil, 386, 565, nil, nil, nil, 296, 386, nil, nil,
- 626, nil, nil, 10, nil, nil, nil, nil, 641, 642,
- 665, 844, nil, 838, 681, 683, nil, nil, nil, 686,
- nil, nil, 695, nil, nil, nil, 112, nil, nil, nil,
- 198, nil, nil, 640, nil, nil, nil, nil, 676, nil,
- nil, 198, nil, 115, nil, 117, 605, 14, 869, 10,
- 561, 274, 14, nil, 198, nil, nil, nil, nil, 294,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 712, 13, nil, nil, nil, 13, nil, nil, 10, 10,
- 13, nil, 198, 603, nil, nil, 378, 382, 35, nil,
- nil, 198, 746, 35, nil, 198, 10, 750, 13, nil,
- nil, nil, 762, 12, nil, nil, nil, nil, 12, nil,
- nil, nil, nil, 605, 703, nil, nil, 548, 35, 271,
- 271, nil, nil, nil, 305, nil, 198, 198, nil, 10,
- nil, 198, nil, 12, 10, nil, 714, 747, nil, 35,
- nil, nil, 272, 752, 13, 432, 435, 278, nil, 313,
- 328, 328, 328, 766, 12, nil, 112, 744, nil, nil,
- nil, 10, nil, nil, nil, 198, nil, nil, nil, nil,
- nil, nil, nil, 13, 13, nil, nil, 615, nil, nil,
- nil, 617, nil, 787, nil, 35, 625, 774, 776, nil,
- nil, 13, nil, 35, nil, nil, 10, 785, nil, nil,
- 12, 806, nil, 783, nil, nil, nil, nil, 12, nil,
- nil, nil, nil, nil, 10, nil, nil, 784, 795, 198,
- nil, nil, nil, 796, 13, nil, 10, 10, nil, 13,
- nil, 10, nil, nil, 819, nil, nil, nil, 10, nil,
- nil, 619, nil, 808, nil, nil, nil, nil, 305, nil,
- 701, nil, nil, nil, nil, 779, 13, 798, 781, nil,
- nil, nil, nil, nil, nil, 198, nil, nil, 14, 789,
- 856, nil, 14, nil, 35, 35, nil, 14, nil, 719,
- 720, nil, 771, 771, 10, 378, 382, 278, 278, 12,
- 12, 13, 35, nil, nil, 14, nil, 726, nil, nil,
- nil, nil, 865, nil, 670, 873, nil, 12, nil, 13,
- 853, 854, 296, 771, nil, nil, 386, 862, 278, 198,
- nil, 13, 13, nil, nil, nil, 13, nil, 10, nil,
- nil, nil, nil, 13, nil, 10, nil, 831, nil, 274,
- 834, 14, 10, nil, nil, nil, nil, nil, 305, nil,
- nil, 877, 599, 35, 272, nil, nil, 271, 35, 278,
- nil, 599, 764, nil, nil, 887, nil, nil, 12, nil,
- 14, 14, nil, 12, nil, nil, 891, nil, nil, 13,
- nil, 863, nil, nil, nil, nil, 866, nil, 14, 868,
- nil, nil, nil, 599, nil, nil, nil, 782, nil, 599,
- nil, nil, nil, nil, nil, 771, 771, 198, nil, nil,
- 278, 278, 771, nil, nil, 793, nil, 278, 879, nil,
- nil, 14, nil, 13, nil, nil, 14, 800, 801, nil,
- 13, 888, 803, nil, 890, nil, nil, 13, nil, nil,
- nil, nil, nil, nil, nil, 893, 771, nil, nil, nil,
- nil, 278, nil, 14, nil, nil, nil, nil, nil, nil,
- 771, nil, nil, nil, nil, 278, nil, nil, nil, nil,
- nil, 771, 709, 710, nil, nil, 278, nil, nil, 773,
- 773, nil, nil, nil, nil, 837, nil, nil, 14, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 14, nil, nil, nil,
- 773, nil, nil, nil, nil, nil, nil, nil, 14, 14,
- nil, nil, nil, 14, nil, nil, nil, nil, nil, 870,
- 14, nil, nil, nil, nil, nil, 871, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 274, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 35, nil, 14, nil, 35, nil,
- nil, nil, nil, 35, nil, nil, nil, nil, nil, 12,
- nil, nil, nil, 12, nil, nil, nil, nil, 12, nil,
- nil, 35, 773, 773, nil, nil, nil, nil, nil, 773,
- nil, nil, nil, nil, nil, nil, 12, nil, nil, nil,
- 14, nil, nil, nil, nil, nil, nil, 14, nil, nil,
- nil, nil, nil, nil, 14, nil, nil, nil, nil, nil,
- nil, nil, nil, 773, nil, 271, nil, 35, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 773, nil, nil,
- nil, nil, 12, nil, nil, nil, nil, nil, 773, nil,
- nil, nil, nil, nil, nil, nil, 35, 35, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 12, 12, nil, 35, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 12,
- nil, nil, nil, nil, nil, nil, nil, nil, 599, nil,
- nil, nil, nil, nil, nil, nil, nil, 35, nil, nil,
- nil, nil, 35, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 12, nil, nil, nil, nil, 12, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 35,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 12, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 770, 770, nil, nil, nil,
- nil, nil, nil, nil, 35, nil, nil, 206, nil, nil,
- nil, 237, 237, 237, nil, nil, nil, nil, nil, 12,
- nil, nil, 35, nil, nil, nil, 770, 287, 288, 289,
- nil, nil, nil, nil, 35, 35, nil, 12, nil, 35,
- nil, nil, 237, 237, nil, nil, 35, nil, nil, 12,
- 12, nil, nil, nil, 12, nil, nil, nil, nil, 367,
- 371, 12, nil, nil, nil, nil, nil, 271, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 35, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 12, nil, nil,
- nil, nil, 429, nil, 430, nil, nil, nil, 770, 770,
- nil, nil, nil, nil, nil, 770, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 35, nil, nil, nil,
- nil, nil, nil, 35, nil, nil, nil, nil, nil, nil,
- 35, 12, nil, nil, nil, nil, nil, nil, 12, 770,
- nil, nil, nil, nil, nil, 12, nil, nil, nil, nil,
- nil, nil, nil, 770, nil, nil, nil, 366, 237, 374,
- 237, nil, nil, 388, 770, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 206, 398, 399, 400,
- 401, 402, 403, 404, 405, 406, 407, 408, 409, 410,
- 411, 412, 413, 414, 415, 416, 417, 418, 419, 420,
- 421, 422, 423, nil, nil, nil, nil, nil, nil, nil,
- 237, nil, 237, nil, nil, nil, nil, nil, nil, nil,
- 539, nil, nil, 237, 237, nil, nil, nil, nil, nil,
- nil, nil, 237, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 468,
- nil, nil, nil, nil, nil, nil, nil, nil, 480, nil,
- nil, nil, nil, nil, nil, nil, nil, 563, nil, 566,
- nil, nil, 569, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 582, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 607, nil, nil, nil, nil, 613, nil, nil,
- 566, nil, nil, 613, nil, nil, nil, nil, 237, nil,
- nil, nil, nil, nil, nil, nil, nil, 367, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 237, nil, 388, 555, 374, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 678,
- nil, nil, nil, nil, nil, 237, nil, 237, nil, nil,
- 237, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 702, nil, nil, 581, 705, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 237, nil, nil, nil, nil,
- nil, 563, 600, 601, 602, 716, nil, 26, nil, nil,
- 237, nil, 26, nil, nil, 237, nil, nil, 237, nil,
- nil, 237, nil, nil, 26, 26, nil, nil, nil, 26,
- 26, 26, nil, nil, nil, 237, 237, 26, nil, nil,
- nil, nil, nil, nil, nil, 237, nil, nil, nil, 742,
- nil, nil, nil, nil, nil, nil, nil, nil, 26, 26,
- 26, nil, nil, 26, 26, nil, nil, 26, nil, nil,
- nil, nil, nil, nil, nil, nil, 677, 237, nil, nil,
- 682, 684, nil, nil, nil, 687, nil, nil, 689, nil,
- nil, nil, nil, nil, nil, 694, nil, nil, nil, 237,
- 765, nil, nil, 237, 26, nil, nil, nil, 26, 26,
- 26, 26, 26, nil, nil, nil, nil, nil, nil, 237,
- nil, nil, nil, 237, nil, 566, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 566, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 731, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 613, nil, nil, nil, nil, nil, 237, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 816, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 26, 26, 26, 26, 26, 26, nil,
- nil, 26, 26, 26, nil, nil, nil, 833, nil, 836,
- nil, 26, nil, nil, nil, nil, nil, nil, 237, 767,
- nil, nil, nil, 841, nil, nil, nil, nil, nil, 682,
- 684, 687, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 237, nil, nil, nil, nil, nil, nil,
- nil, nil, 237, 563, 237, nil, 566, nil, nil, nil,
- nil, 26, 26, nil, nil, nil, nil, nil, nil, nil,
- 26, nil, 26, nil, nil, nil, nil, 26, nil, 237,
- nil, nil, nil, nil, nil, 878, nil, nil, 881, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 237, nil,
- nil, 566, nil, nil, nil, nil, nil, 767, nil, nil,
- 892, nil, nil, nil, nil, 26, 26, nil, nil, 828,
- nil, nil, nil, nil, nil, 237, nil, 237, nil, nil,
- nil, nil, nil, nil, 26, nil, nil, nil, nil, nil,
- nil, 237, nil, nil, nil, nil, nil, nil, 26, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 237, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 237, nil, nil, 237, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 26, nil, nil, 237, nil, nil, 237, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 237,
- nil, nil, nil, nil, nil, nil, nil, nil, 237, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 26, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 26, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 26, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 26, nil, nil, nil, 26, nil, nil,
- nil, nil, 26, nil, 26, nil, nil, nil, nil, nil,
- nil, nil, nil, 26, nil, nil, nil, 26, nil, nil,
- 26, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 26, 26,
- nil, nil, nil, 26, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 26, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 26, nil, nil,
- nil, nil, nil, nil, nil, 26, 26, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 26, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 26, nil, nil, nil, nil, 26, nil, nil, nil,
- nil, 26, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 26, nil,
- nil, nil, nil, nil, nil, nil, nil, 26, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 26, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 26, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 26, nil, 26, 26, nil, nil, nil, 26, nil,
- nil, nil, nil, nil, nil, 26, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 26, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 26,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 26, nil, nil, nil, nil,
- nil, nil, 26, nil, nil, nil, nil, nil, nil, 26 ]
-
-racc_goto_check = [
- 14, 15, 56, 56, 56, 14, 39, 53, 45, 45,
- 82, 19, 44, 4, 3, 83, 60, 60, 60, 29,
- 11, 11, 26, 26, 26, 48, 48, 49, 49, 79,
- 14, 76, 76, 126, 56, 32, 54, 54, 54, 31,
- 31, 31, 5, 51, 21, 21, 77, 78, 78, 8,
- 131, 14, 128, 26, 57, 57, 40, 58, 42, 117,
- 58, 14, 117, 28, 28, 28, 45, 82, 54, 33,
- 124, 36, 124, 37, 9, 55, 55, 114, 114, 55,
- 1, 55, 114, 6, 125, 125, 125, 43, 43, 13,
- 13, 33, 33, 13, 10, 18, 12, 14, 16, 24,
- 18, 131, 34, 50, 61, 14, 8, 62, 64, 65,
- 72, 73, 18, 18, 74, 80, 81, 18, 18, 18,
- 84, 85, 86, 87, 88, 18, 18, 18, 89, 90,
- 91, 52, 52, 92, 13, 13, 13, 13, 93, 94,
- 95, 23, 96, 97, 98, 128, 18, 18, 18, 19,
- 99, 18, 18, 100, 102, 18, 18, 18, 18, 104,
- 105, 52, 52, 52, 126, 124, 9, 106, 107, 108,
- 109, 15, 15, 15, 9, 112, 23, 15, 113, 115,
- 23, 23, 116, 118, 23, 119, 14, 14, 120, 5,
- 121, 26, 18, 123, 127, 45, 18, 18, 18, 18,
- 18, 2, 54, 54, 14, nil, nil, nil, nil, nil,
- nil, 79, nil, nil, nil, nil, nil, nil, nil, 33,
- nil, nil, nil, 53, 53, 23, 23, 23, 23, nil,
- nil, 2, nil, nil, 56, 56, nil, nil, nil, nil,
- nil, 42, nil, 56, 117, nil, 125, 125, 60, 60,
- 125, nil, nil, nil, 26, 26, nil, 60, nil, nil,
- nil, nil, nil, 26, nil, 14, nil, nil, 54, 54,
- 14, nil, nil, nil, nil, nil, nil, 54, 51, nil,
- nil, 18, 18, 18, 18, 18, 18, nil, nil, 18,
- 18, 18, 20, 40, nil, 28, 28, 20, 51, 18,
- 78, 77, nil, 59, 28, 57, 36, 57, 37, 125,
- nil, 36, nil, 37, nil, nil, nil, 82, 83, 23,
- 23, nil, 20, 20, 20, 32, 131, 21, nil, 32,
- nil, nil, nil, 82, 58, 58, 126, 131, nil, nil,
- nil, 13, 13, 20, nil, 29, nil, nil, nil, 18,
- 18, 19, 76, 20, 20, 20, 8, 53, 18, 45,
- 18, 53, nil, nil, 18, 18, nil, nil, 53, 52,
- 53, 11, nil, nil, nil, 5, 48, nil, 49, nil,
- nil, nil, nil, nil, nil, nil, nil, 2, 2, 20,
- nil, 31, nil, 26, 45, 31, nil, 20, nil, nil,
- nil, nil, nil, 18, 18, 2, 56, nil, nil, nil,
- 57, nil, nil, nil, 19, nil, nil, nil, nil, nil,
- nil, nil, 18, nil, nil, 56, nil, nil, nil, nil,
- nil, nil, 23, 23, nil, nil, 18, nil, nil, 60,
- nil, 51, 51, nil, nil, 31, nil, nil, 31, nil,
- nil, 23, 76, nil, nil, 19, 26, 131, nil, nil,
- 45, nil, nil, nil, 19, 23, 2, nil, nil, 45,
- nil, 2, nil, nil, nil, 51, 3, nil, 20, 20,
- nil, nil, 51, nil, nil, 54, 14, nil, 18, nil,
- 14, nil, 59, nil, nil, 14, 20, 26, 82, 82,
- nil, 45, 131, nil, nil, nil, 26, 45, nil, nil,
- 54, nil, nil, 14, nil, nil, nil, nil, 82, 82,
- 51, 79, nil, 76, 15, 15, nil, nil, nil, 15,
- nil, nil, 39, nil, nil, nil, 45, nil, nil, nil,
- 18, nil, nil, 13, nil, nil, nil, nil, 11, nil,
- nil, 18, nil, 48, nil, 49, 53, 20, 4, 14,
- 56, 20, 20, nil, 18, nil, nil, nil, nil, 23,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 26, 18, nil, nil, nil, 18, nil, nil, 14, 14,
- 18, nil, 18, 23, nil, nil, 30, 30, 41, nil,
- nil, 18, 3, 41, nil, 18, 14, 3, 18, nil,
- nil, nil, 44, 17, nil, nil, nil, nil, 17, nil,
- nil, nil, nil, 53, 59, nil, nil, 57, 41, 41,
- 41, nil, nil, nil, 23, nil, 18, 18, nil, 14,
- nil, 18, nil, 17, 14, nil, 59, 82, nil, 41,
- nil, nil, 18, 82, 18, 30, 30, 52, nil, 41,
- 41, 41, 41, 15, 17, nil, 45, 13, nil, nil,
- nil, 14, nil, nil, nil, 18, nil, nil, nil, nil,
- nil, nil, nil, 18, 18, nil, nil, 2, nil, nil,
- nil, 2, nil, 56, nil, 41, 2, 14, 14, nil,
- nil, 18, nil, 41, nil, nil, 14, 60, nil, nil,
- 17, 3, nil, 51, nil, nil, nil, nil, 17, nil,
- nil, nil, nil, nil, 14, nil, nil, 54, 14, 18,
- nil, nil, nil, 51, 18, nil, 14, 14, nil, 18,
- nil, 14, nil, nil, 39, nil, nil, nil, 14, nil,
- nil, 82, nil, 51, nil, nil, nil, nil, 23, nil,
- 2, nil, nil, nil, nil, 59, 18, 13, 59, nil,
- nil, nil, nil, nil, nil, 18, nil, nil, 20, 59,
- 19, nil, 20, nil, 41, 41, nil, 20, nil, 2,
- 2, nil, 18, 18, 14, 30, 30, 52, 52, 17,
- 17, 18, 41, nil, nil, 20, nil, 2, nil, nil,
- nil, nil, 56, nil, 20, 3, nil, 17, nil, 18,
- 14, 14, 26, 18, nil, nil, 45, 14, 52, 18,
- nil, 18, 18, nil, nil, nil, 18, nil, 14, nil,
- nil, nil, nil, 18, nil, 14, nil, 59, nil, 20,
- 59, 20, 14, nil, nil, nil, nil, nil, 23, nil,
- nil, 14, 30, 41, 18, nil, nil, 41, 41, 52,
- nil, 30, 2, nil, nil, 14, nil, nil, 17, nil,
- 20, 20, nil, 17, nil, nil, 14, nil, nil, 18,
- nil, 59, nil, nil, nil, nil, 59, nil, 20, 59,
- nil, nil, nil, 30, nil, nil, nil, 2, nil, 30,
- nil, nil, nil, nil, nil, 18, 18, 18, nil, nil,
- 52, 52, 18, nil, nil, 2, nil, 52, 59, nil,
- nil, 20, nil, 18, nil, nil, 20, 2, 2, nil,
- 18, 59, 2, nil, 59, nil, nil, 18, nil, nil,
- nil, nil, nil, nil, nil, 59, 18, nil, nil, nil,
- nil, 52, nil, 20, nil, nil, nil, nil, nil, nil,
- 18, nil, nil, nil, nil, 52, nil, nil, nil, nil,
- nil, 18, 30, 30, nil, nil, 52, nil, nil, 20,
- 20, nil, nil, nil, nil, 2, nil, nil, 20, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 20, nil, nil, nil,
- 20, nil, nil, nil, nil, nil, nil, nil, 20, 20,
- nil, nil, nil, 20, nil, nil, nil, nil, nil, 2,
- 20, nil, nil, nil, nil, nil, 2, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 20, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, 20, nil, 41, nil,
- nil, nil, nil, 41, nil, nil, nil, nil, nil, 17,
- nil, nil, nil, 17, nil, nil, nil, nil, 17, nil,
- nil, 41, 20, 20, nil, nil, nil, nil, nil, 20,
- nil, nil, nil, nil, nil, nil, 17, nil, nil, nil,
- 20, nil, nil, nil, nil, nil, nil, 20, nil, nil,
- nil, nil, nil, nil, 20, nil, nil, nil, nil, nil,
- nil, nil, nil, 20, nil, 41, nil, 41, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 20, nil, nil,
- nil, nil, 17, nil, nil, nil, nil, nil, 20, nil,
- nil, nil, nil, nil, nil, nil, 41, 41, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 17, 17, nil, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 17,
- nil, nil, nil, nil, nil, nil, nil, nil, 30, nil,
- nil, nil, nil, nil, nil, nil, nil, 41, nil, nil,
- nil, nil, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 17, nil, nil, nil, nil, 17, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 41,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 17, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 41, 41, nil, nil, nil,
- nil, nil, nil, nil, 41, nil, nil, 25, nil, nil,
- nil, 25, 25, 25, nil, nil, nil, nil, nil, 17,
- nil, nil, 41, nil, nil, nil, 41, 25, 25, 25,
- nil, nil, nil, nil, 41, 41, nil, 17, nil, 41,
- nil, nil, 25, 25, nil, nil, 41, nil, nil, 17,
- 17, nil, nil, nil, 17, nil, nil, nil, nil, 22,
- 22, 17, nil, nil, nil, nil, nil, 41, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 17, nil, nil,
- nil, nil, 22, nil, 22, nil, nil, nil, 41, 41,
- nil, nil, nil, nil, nil, 41, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 41, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, nil, nil, nil, nil,
- 41, 17, nil, nil, nil, nil, nil, nil, 17, 41,
- nil, nil, nil, nil, nil, 17, nil, nil, nil, nil,
- nil, nil, nil, 41, nil, nil, nil, 25, 25, 25,
- 25, nil, nil, 25, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, nil, nil, nil, nil, nil, nil, nil,
- 25, nil, 25, nil, nil, nil, nil, nil, nil, nil,
- 22, nil, nil, 25, 25, nil, nil, nil, nil, nil,
- nil, nil, 25, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 25,
- nil, nil, nil, nil, nil, nil, nil, nil, 25, nil,
- nil, nil, nil, nil, nil, nil, nil, 22, nil, 22,
- nil, nil, 22, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 22, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 22, nil, nil, nil, nil, 22, nil, nil,
- 22, nil, nil, 22, nil, nil, nil, nil, 25, nil,
- nil, nil, nil, nil, nil, nil, nil, 22, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 25, nil, 25, 25, 25, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 22,
- nil, nil, nil, nil, nil, 25, nil, 25, nil, nil,
- 25, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 22, nil, nil, 25, 22, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 25, nil, nil, nil, nil,
- nil, 22, 25, 25, 25, 22, nil, 35, nil, nil,
- 25, nil, 35, nil, nil, 25, nil, nil, 25, nil,
- nil, 25, nil, nil, 35, 35, nil, nil, nil, 35,
- 35, 35, nil, nil, nil, 25, 25, 35, nil, nil,
- nil, nil, nil, nil, nil, 25, nil, nil, nil, 22,
- nil, nil, nil, nil, nil, nil, nil, nil, 35, 35,
- 35, nil, nil, 35, 35, nil, nil, 35, nil, nil,
- nil, nil, nil, nil, nil, nil, 25, 25, nil, nil,
- 25, 25, nil, nil, nil, 25, nil, nil, 25, nil,
- nil, nil, nil, nil, nil, 25, nil, nil, nil, 25,
- 22, nil, nil, 25, 35, nil, nil, nil, 35, 35,
- 35, 35, 35, nil, nil, nil, nil, nil, nil, 25,
- nil, nil, nil, 25, nil, 22, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 22, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 25, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 22, nil, nil, nil, nil, nil, 25, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 22, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 35, 35, 35, 35, 35, 35, nil,
- nil, 35, 35, 35, nil, nil, nil, 22, nil, 22,
- nil, 35, nil, nil, nil, nil, nil, nil, 25, 25,
- nil, nil, nil, 22, nil, nil, nil, nil, nil, 25,
- 25, 25, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 25, nil, nil, nil, nil, nil, nil,
- nil, nil, 25, 22, 25, nil, 22, nil, nil, nil,
- nil, 35, 35, nil, nil, nil, nil, nil, nil, nil,
- 35, nil, 35, nil, nil, nil, nil, 35, nil, 25,
- nil, nil, nil, nil, nil, 22, nil, nil, 22, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 25, nil,
- nil, 22, nil, nil, nil, nil, nil, 25, nil, nil,
- 22, nil, nil, nil, nil, 35, 35, nil, nil, 25,
- nil, nil, nil, nil, nil, 25, nil, 25, nil, nil,
- nil, nil, nil, nil, 35, nil, nil, nil, nil, nil,
- nil, 25, nil, nil, nil, nil, nil, nil, 35, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 25, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 25, nil, nil, 25, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 35, nil, nil, 25, nil, nil, 25, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 25,
- nil, nil, nil, nil, nil, nil, nil, nil, 25, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 35, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 35, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 35, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 35, nil, nil, nil, 35, nil, nil,
- nil, nil, 35, nil, 35, nil, nil, nil, nil, nil,
- nil, nil, nil, 35, nil, nil, nil, 35, nil, nil,
- 35, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 35, 35,
- nil, nil, nil, 35, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 35, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 35, nil, nil,
- nil, nil, nil, nil, nil, 35, 35, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 35, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 35, nil, nil, nil, nil, 35, nil, nil, nil,
- nil, 35, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 35, nil,
- nil, nil, nil, nil, nil, nil, nil, 35, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 35, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 35, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 35, nil, 35, 35, nil, nil, nil, 35, nil,
- nil, nil, nil, nil, nil, 35, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 35, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 35,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 35, nil, nil, nil, nil,
- nil, nil, 35, nil, nil, nil, nil, nil, nil, 35 ]
-
-racc_goto_pointer = [
- nil, 80, 201, -37, -279, -428, -521, nil, 46, 69,
- 91, 14, 89, 33, 0, -17, 37, 613, 95, -42,
- 292, -144, 1171, 124, -8, 1289, 0, nil, 41, -235,
- 404, 13, -218, -355, -334, 1757, 41, 43, nil, -25,
- 24, 598, -264, 25, -52, 2, nil, nil, 19, 21,
- -258, 2, 100, -247, 14, -222, -20, 28, -375, 63,
- -6, -341, -148, nil, -337, -478, nil, nil, nil, nil,
- nil, nil, 46, 57, 59, nil, -275, -569, -444, -282,
- 54, -210, 7, -499, 56, -218, -172, 65, -494, 69,
- -493, -371, -671, -370, -503, -189, -196, -372, -618, -407,
- -404, nil, -80, nil, -99, -99, -329, -635, -302, -438,
- nil, nil, 105, 106, 3, 103, -164, -284, 106, -337,
- -335, -455, nil, -560, -683, -563, -481, -559, -703, nil,
- nil, -378 ]
-
-racc_goto_default = [
- nil, nil, 292, nil, nil, 733, nil, 3, nil, 4,
- 312, nil, nil, nil, 202, 16, 11, 203, 286, nil,
- 201, nil, 244, 15, nil, 19, 20, 21, nil, 25,
- 596, nil, nil, nil, nil, 277, 29, nil, 31, 34,
- 33, 199, 323, nil, 114, 380, 113, 116, 68, 69,
- nil, nil, 42, 295, 297, nil, 298, 544, 545, 425,
- 562, nil, nil, 255, nil, nil, 43, 44, 45, 46,
- 47, 48, 49, nil, 256, 55, nil, nil, nil, nil,
- nil, nil, 487, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 235, nil, 384, nil, nil, nil, nil, nil, nil,
- 67, 70, 71, nil, nil, nil, nil, 525, nil, nil,
- nil, 646, 647, 648, 649, nil, 812, 656, 657, 660,
- 663, 248 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 133, :_reduce_1,
- 4, 135, :_reduce_2,
- 2, 134, :_reduce_3,
- 0, 139, :_reduce_4,
- 1, 139, :_reduce_5,
- 2, 139, :_reduce_6,
- 3, 139, :_reduce_7,
- 0, 156, :_reduce_8,
- 4, 141, :_reduce_9,
- 3, 141, :_reduce_10,
- 3, 141, :_reduce_11,
- 3, 141, :_reduce_12,
- 2, 141, :_reduce_13,
- 3, 141, :_reduce_14,
- 3, 141, :_reduce_15,
- 3, 141, :_reduce_16,
- 3, 141, :_reduce_17,
- 3, 141, :_reduce_18,
- 4, 141, :_reduce_19,
- 4, 141, :_reduce_20,
- 3, 141, :_reduce_21,
- 3, 141, :_reduce_22,
- 3, 141, :_reduce_23,
- 6, 141, :_reduce_24,
- 5, 141, :_reduce_25,
- 5, 141, :_reduce_26,
- 5, 141, :_reduce_27,
- 3, 141, :_reduce_28,
- 3, 141, :_reduce_29,
- 3, 141, :_reduce_30,
- 3, 141, :_reduce_31,
- 1, 141, :_reduce_none,
- 1, 155, :_reduce_none,
- 3, 155, :_reduce_34,
- 3, 155, :_reduce_35,
- 2, 155, :_reduce_36,
- 2, 155, :_reduce_37,
- 1, 155, :_reduce_none,
- 1, 145, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 2, 147, :_reduce_42,
- 2, 147, :_reduce_43,
- 2, 147, :_reduce_44,
- 1, 159, :_reduce_none,
- 4, 159, :_reduce_46,
- 4, 159, :_reduce_47,
- 0, 166, :_reduce_48,
- 5, 164, :_reduce_49,
- 2, 158, :_reduce_50,
- 3, 158, :_reduce_51,
- 4, 158, :_reduce_52,
- 5, 158, :_reduce_53,
- 4, 158, :_reduce_54,
- 5, 158, :_reduce_55,
- 2, 158, :_reduce_56,
- 2, 158, :_reduce_57,
- 1, 148, :_reduce_58,
- 3, 148, :_reduce_59,
- 1, 169, :_reduce_60,
- 3, 169, :_reduce_61,
- 1, 168, :_reduce_62,
- 2, 168, :_reduce_63,
- 3, 168, :_reduce_64,
- 2, 168, :_reduce_65,
- 2, 168, :_reduce_66,
- 1, 168, :_reduce_67,
- 1, 171, :_reduce_none,
- 3, 171, :_reduce_69,
- 2, 170, :_reduce_70,
- 3, 170, :_reduce_71,
- 1, 172, :_reduce_72,
- 4, 172, :_reduce_73,
- 3, 172, :_reduce_74,
- 3, 172, :_reduce_75,
- 3, 172, :_reduce_76,
- 3, 172, :_reduce_77,
- 2, 172, :_reduce_78,
- 1, 172, :_reduce_79,
- 1, 146, :_reduce_80,
- 4, 146, :_reduce_81,
- 3, 146, :_reduce_82,
- 3, 146, :_reduce_83,
- 3, 146, :_reduce_84,
- 3, 146, :_reduce_85,
- 2, 146, :_reduce_86,
- 1, 146, :_reduce_87,
- 1, 174, :_reduce_88,
- 1, 174, :_reduce_none,
- 2, 175, :_reduce_90,
- 1, 175, :_reduce_91,
- 3, 175, :_reduce_92,
- 1, 176, :_reduce_none,
- 1, 176, :_reduce_none,
- 1, 176, :_reduce_none,
- 1, 176, :_reduce_none,
- 1, 176, :_reduce_none,
- 1, 179, :_reduce_98,
- 1, 179, :_reduce_none,
- 1, 143, :_reduce_none,
- 1, 143, :_reduce_none,
- 1, 144, :_reduce_102,
- 0, 182, :_reduce_103,
- 4, 144, :_reduce_104,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 177, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 1, 178, :_reduce_none,
- 3, 157, :_reduce_171,
- 5, 157, :_reduce_172,
- 3, 157, :_reduce_173,
- 6, 157, :_reduce_174,
- 5, 157, :_reduce_175,
- 5, 157, :_reduce_176,
- 5, 157, :_reduce_177,
- 5, 157, :_reduce_178,
- 4, 157, :_reduce_179,
- 3, 157, :_reduce_180,
- 3, 157, :_reduce_181,
- 3, 157, :_reduce_182,
- 3, 157, :_reduce_183,
- 3, 157, :_reduce_184,
- 3, 157, :_reduce_185,
- 3, 157, :_reduce_186,
- 3, 157, :_reduce_187,
- 3, 157, :_reduce_188,
- 4, 157, :_reduce_189,
- 4, 157, :_reduce_190,
- 2, 157, :_reduce_191,
- 2, 157, :_reduce_192,
- 3, 157, :_reduce_193,
- 3, 157, :_reduce_194,
- 3, 157, :_reduce_195,
- 3, 157, :_reduce_196,
- 3, 157, :_reduce_197,
- 3, 157, :_reduce_198,
- 3, 157, :_reduce_199,
- 3, 157, :_reduce_200,
- 3, 157, :_reduce_201,
- 3, 157, :_reduce_202,
- 3, 157, :_reduce_203,
- 3, 157, :_reduce_204,
- 3, 157, :_reduce_205,
- 2, 157, :_reduce_206,
- 2, 157, :_reduce_207,
- 3, 157, :_reduce_208,
- 3, 157, :_reduce_209,
- 3, 157, :_reduce_210,
- 3, 157, :_reduce_211,
- 3, 157, :_reduce_212,
- 5, 157, :_reduce_213,
- 1, 157, :_reduce_none,
- 1, 154, :_reduce_none,
- 1, 151, :_reduce_none,
- 2, 151, :_reduce_217,
- 2, 151, :_reduce_218,
- 5, 151, :_reduce_219,
- 2, 151, :_reduce_220,
- 3, 151, :_reduce_221,
- 3, 189, :_reduce_222,
- 4, 189, :_reduce_223,
- 4, 189, :_reduce_224,
- 6, 189, :_reduce_225,
- 0, 190, :_reduce_226,
- 1, 190, :_reduce_none,
- 1, 160, :_reduce_228,
- 2, 160, :_reduce_229,
- 5, 160, :_reduce_230,
- 2, 160, :_reduce_231,
- 5, 160, :_reduce_232,
- 4, 160, :_reduce_233,
- 7, 160, :_reduce_234,
- 3, 160, :_reduce_235,
- 1, 160, :_reduce_236,
- 4, 193, :_reduce_237,
- 3, 193, :_reduce_238,
- 5, 193, :_reduce_239,
- 7, 193, :_reduce_240,
- 2, 193, :_reduce_241,
- 5, 193, :_reduce_242,
- 4, 193, :_reduce_243,
- 6, 193, :_reduce_244,
- 7, 193, :_reduce_245,
- 9, 193, :_reduce_246,
- 3, 193, :_reduce_247,
- 1, 193, :_reduce_248,
- 0, 195, :_reduce_249,
- 2, 163, :_reduce_250,
- 1, 194, :_reduce_251,
- 0, 196, :_reduce_252,
- 3, 194, :_reduce_253,
- 0, 197, :_reduce_254,
- 4, 194, :_reduce_255,
- 2, 192, :_reduce_256,
- 2, 191, :_reduce_257,
- 0, 191, :_reduce_258,
- 1, 186, :_reduce_259,
- 3, 186, :_reduce_260,
- 3, 153, :_reduce_261,
- 4, 153, :_reduce_262,
- 2, 153, :_reduce_263,
- 1, 184, :_reduce_none,
- 1, 184, :_reduce_none,
- 1, 184, :_reduce_none,
- 1, 184, :_reduce_none,
- 1, 184, :_reduce_none,
- 1, 184, :_reduce_none,
- 1, 184, :_reduce_none,
- 1, 184, :_reduce_none,
- 1, 184, :_reduce_272,
- 3, 184, :_reduce_273,
- 0, 218, :_reduce_274,
- 5, 184, :_reduce_275,
- 3, 184, :_reduce_276,
- 3, 184, :_reduce_277,
- 2, 184, :_reduce_278,
- 4, 184, :_reduce_279,
- 3, 184, :_reduce_280,
- 3, 184, :_reduce_281,
- 1, 184, :_reduce_282,
- 4, 184, :_reduce_283,
- 3, 184, :_reduce_284,
- 1, 184, :_reduce_285,
- 5, 184, :_reduce_286,
- 2, 184, :_reduce_287,
- 1, 184, :_reduce_none,
- 2, 184, :_reduce_289,
- 6, 184, :_reduce_290,
- 6, 184, :_reduce_291,
- 0, 219, :_reduce_292,
- 0, 220, :_reduce_293,
- 7, 184, :_reduce_294,
- 0, 221, :_reduce_295,
- 0, 222, :_reduce_296,
- 7, 184, :_reduce_297,
- 5, 184, :_reduce_298,
- 4, 184, :_reduce_299,
- 5, 184, :_reduce_300,
- 0, 223, :_reduce_301,
- 0, 224, :_reduce_302,
- 9, 184, :_reduce_303,
- 0, 225, :_reduce_304,
- 6, 184, :_reduce_305,
- 0, 226, :_reduce_306,
- 7, 184, :_reduce_307,
- 0, 227, :_reduce_308,
- 5, 184, :_reduce_309,
- 0, 228, :_reduce_310,
- 6, 184, :_reduce_311,
- 0, 229, :_reduce_312,
- 0, 230, :_reduce_313,
- 9, 184, :_reduce_314,
- 1, 184, :_reduce_315,
- 1, 184, :_reduce_316,
- 1, 184, :_reduce_317,
- 1, 184, :_reduce_318,
- 1, 150, :_reduce_none,
- 1, 208, :_reduce_none,
- 1, 208, :_reduce_none,
- 1, 208, :_reduce_none,
- 2, 208, :_reduce_323,
- 1, 210, :_reduce_none,
- 1, 210, :_reduce_none,
- 1, 210, :_reduce_none,
- 1, 209, :_reduce_none,
- 5, 209, :_reduce_328,
- 1, 137, :_reduce_none,
- 2, 137, :_reduce_330,
- 1, 212, :_reduce_none,
- 1, 212, :_reduce_none,
- 1, 231, :_reduce_333,
- 3, 231, :_reduce_334,
- 1, 232, :_reduce_none,
- 2, 232, :_reduce_none,
- 4, 232, :_reduce_337,
- 7, 232, :_reduce_338,
- 6, 232, :_reduce_339,
- 4, 232, :_reduce_340,
- 3, 232, :_reduce_341,
- 5, 232, :_reduce_342,
- 4, 232, :_reduce_343,
- 2, 232, :_reduce_344,
- 1, 232, :_reduce_345,
- 2, 232, :_reduce_346,
- 0, 165, :_reduce_347,
- 2, 165, :_reduce_348,
- 1, 165, :_reduce_349,
- 3, 165, :_reduce_350,
- 0, 234, :_reduce_351,
- 5, 233, :_reduce_352,
- 2, 161, :_reduce_353,
- 4, 161, :_reduce_354,
- 4, 161, :_reduce_355,
- 2, 207, :_reduce_356,
- 4, 207, :_reduce_357,
- 4, 207, :_reduce_358,
- 3, 207, :_reduce_359,
- 2, 207, :_reduce_360,
- 1, 207, :_reduce_361,
- 0, 236, :_reduce_362,
- 5, 206, :_reduce_363,
- 0, 237, :_reduce_364,
- 5, 206, :_reduce_365,
- 5, 211, :_reduce_366,
- 1, 238, :_reduce_none,
- 4, 238, :_reduce_368,
- 2, 238, :_reduce_369,
- 1, 239, :_reduce_370,
- 1, 239, :_reduce_none,
- 6, 136, :_reduce_372,
- 0, 136, :_reduce_373,
- 1, 240, :_reduce_374,
- 1, 240, :_reduce_none,
- 1, 240, :_reduce_none,
- 2, 241, :_reduce_377,
- 1, 241, :_reduce_none,
- 2, 138, :_reduce_379,
- 1, 138, :_reduce_none,
- 1, 198, :_reduce_none,
- 1, 198, :_reduce_none,
- 1, 198, :_reduce_none,
- 1, 199, :_reduce_384,
- 1, 243, :_reduce_385,
- 2, 243, :_reduce_386,
- 3, 244, :_reduce_387,
- 1, 244, :_reduce_388,
- 3, 200, :_reduce_389,
- 4, 201, :_reduce_390,
- 3, 202, :_reduce_391,
- 0, 247, :_reduce_392,
- 3, 247, :_reduce_393,
- 1, 248, :_reduce_394,
- 2, 248, :_reduce_395,
- 3, 203, :_reduce_396,
- 0, 250, :_reduce_397,
- 3, 250, :_reduce_398,
- 0, 245, :_reduce_399,
- 2, 245, :_reduce_400,
- 0, 246, :_reduce_401,
- 2, 246, :_reduce_402,
- 1, 249, :_reduce_403,
- 2, 249, :_reduce_404,
- 0, 252, :_reduce_405,
- 4, 249, :_reduce_406,
- 1, 251, :_reduce_407,
- 1, 251, :_reduce_408,
- 1, 251, :_reduce_409,
- 1, 251, :_reduce_none,
- 1, 180, :_reduce_411,
- 3, 181, :_reduce_412,
- 1, 242, :_reduce_413,
- 1, 242, :_reduce_414,
- 2, 242, :_reduce_415,
- 2, 242, :_reduce_416,
- 1, 173, :_reduce_417,
- 1, 173, :_reduce_418,
- 1, 173, :_reduce_419,
- 1, 173, :_reduce_420,
- 1, 173, :_reduce_421,
- 1, 173, :_reduce_422,
- 1, 173, :_reduce_423,
- 1, 173, :_reduce_424,
- 1, 173, :_reduce_425,
- 1, 173, :_reduce_426,
- 1, 173, :_reduce_427,
- 1, 204, :_reduce_428,
- 1, 149, :_reduce_429,
- 1, 152, :_reduce_430,
- 1, 152, :_reduce_431,
- 1, 213, :_reduce_432,
- 3, 213, :_reduce_433,
- 2, 213, :_reduce_434,
- 4, 215, :_reduce_435,
- 2, 215, :_reduce_436,
- 6, 253, :_reduce_437,
- 4, 253, :_reduce_438,
- 4, 253, :_reduce_439,
- 2, 253, :_reduce_440,
- 4, 253, :_reduce_441,
- 2, 253, :_reduce_442,
- 2, 253, :_reduce_443,
- 1, 253, :_reduce_444,
- 0, 253, :_reduce_445,
- 1, 259, :_reduce_446,
- 1, 259, :_reduce_447,
- 1, 259, :_reduce_448,
- 1, 259, :_reduce_449,
- 1, 259, :_reduce_450,
- 1, 254, :_reduce_451,
- 3, 254, :_reduce_452,
- 3, 260, :_reduce_453,
- 1, 255, :_reduce_454,
- 3, 255, :_reduce_455,
- 1, 261, :_reduce_none,
- 1, 261, :_reduce_none,
- 2, 256, :_reduce_458,
- 1, 256, :_reduce_459,
- 1, 262, :_reduce_none,
- 1, 262, :_reduce_none,
- 2, 258, :_reduce_462,
- 2, 257, :_reduce_463,
- 0, 257, :_reduce_464,
- 1, 216, :_reduce_none,
- 4, 216, :_reduce_466,
- 0, 205, :_reduce_467,
- 2, 205, :_reduce_468,
- 2, 205, :_reduce_469,
- 1, 188, :_reduce_470,
- 3, 188, :_reduce_471,
- 3, 263, :_reduce_472,
- 1, 167, :_reduce_none,
- 1, 167, :_reduce_none,
- 1, 167, :_reduce_none,
- 1, 162, :_reduce_none,
- 1, 162, :_reduce_none,
- 1, 162, :_reduce_none,
- 1, 162, :_reduce_none,
- 1, 235, :_reduce_none,
- 1, 235, :_reduce_none,
- 1, 235, :_reduce_none,
- 1, 217, :_reduce_none,
- 1, 217, :_reduce_none,
- 0, 140, :_reduce_none,
- 1, 140, :_reduce_none,
- 0, 183, :_reduce_none,
- 1, 183, :_reduce_none,
- 0, 187, :_reduce_none,
- 1, 187, :_reduce_none,
- 1, 187, :_reduce_none,
- 1, 214, :_reduce_492,
- 1, 214, :_reduce_none,
- 1, 142, :_reduce_none,
- 2, 142, :_reduce_none,
- 0, 185, :_reduce_496 ]
-
-racc_reduce_n = 497
-
-racc_shift_n = 894
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :kCLASS => 2,
- :kMODULE => 3,
- :kDEF => 4,
- :kUNDEF => 5,
- :kBEGIN => 6,
- :kRESCUE => 7,
- :kENSURE => 8,
- :kEND => 9,
- :kIF => 10,
- :kUNLESS => 11,
- :kTHEN => 12,
- :kELSIF => 13,
- :kELSE => 14,
- :kCASE => 15,
- :kWHEN => 16,
- :kWHILE => 17,
- :kUNTIL => 18,
- :kFOR => 19,
- :kBREAK => 20,
- :kNEXT => 21,
- :kREDO => 22,
- :kRETRY => 23,
- :kIN => 24,
- :kDO => 25,
- :kDO_COND => 26,
- :kDO_BLOCK => 27,
- :kRETURN => 28,
- :kYIELD => 29,
- :kSUPER => 30,
- :kSELF => 31,
- :kNIL => 32,
- :kTRUE => 33,
- :kFALSE => 34,
- :kAND => 35,
- :kOR => 36,
- :kNOT => 37,
- :kIF_MOD => 38,
- :kUNLESS_MOD => 39,
- :kWHILE_MOD => 40,
- :kUNTIL_MOD => 41,
- :kRESCUE_MOD => 42,
- :kALIAS => 43,
- :kDEFINED => 44,
- :klBEGIN => 45,
- :klEND => 46,
- :k__LINE__ => 47,
- :k__FILE__ => 48,
- :tIDENTIFIER => 49,
- :tFID => 50,
- :tGVAR => 51,
- :tIVAR => 52,
- :tCONSTANT => 53,
- :tCVAR => 54,
- :tNTH_REF => 55,
- :tBACK_REF => 56,
- :tSTRING_CONTENT => 57,
- :tINTEGER => 58,
- :tFLOAT => 59,
- :tREGEXP_END => 60,
- :tUPLUS => 61,
- :tUMINUS => 62,
- :tUMINUS_NUM => 63,
- :tPOW => 64,
- :tCMP => 65,
- :tEQ => 66,
- :tEQQ => 67,
- :tNEQ => 68,
- :tGEQ => 69,
- :tLEQ => 70,
- :tANDOP => 71,
- :tOROP => 72,
- :tMATCH => 73,
- :tNMATCH => 74,
- :tDOT => 75,
- :tDOT2 => 76,
- :tDOT3 => 77,
- :tAREF => 78,
- :tASET => 79,
- :tLSHFT => 80,
- :tRSHFT => 81,
- :tCOLON2 => 82,
- :tCOLON3 => 83,
- :tOP_ASGN => 84,
- :tASSOC => 85,
- :tLPAREN => 86,
- :tLPAREN2 => 87,
- :tRPAREN => 88,
- :tLPAREN_ARG => 89,
- :tLBRACK => 90,
- :tLBRACK2 => 91,
- :tRBRACK => 92,
- :tLBRACE => 93,
- :tLBRACE_ARG => 94,
- :tSTAR => 95,
- :tSTAR2 => 96,
- :tAMPER => 97,
- :tAMPER2 => 98,
- :tTILDE => 99,
- :tPERCENT => 100,
- :tDIVIDE => 101,
- :tPLUS => 102,
- :tMINUS => 103,
- :tLT => 104,
- :tGT => 105,
- :tPIPE => 106,
- :tBANG => 107,
- :tCARET => 108,
- :tLCURLY => 109,
- :tRCURLY => 110,
- :tBACK_REF2 => 111,
- :tSYMBEG => 112,
- :tSTRING_BEG => 113,
- :tXSTRING_BEG => 114,
- :tREGEXP_BEG => 115,
- :tWORDS_BEG => 116,
- :tQWORDS_BEG => 117,
- :tSTRING_DBEG => 118,
- :tSTRING_DVAR => 119,
- :tSTRING_END => 120,
- :tSTRING => 121,
- :tSYMBOL => 122,
- :tREGEXP_OPT => 123,
- :tNL => 124,
- :tEH => 125,
- :tCOLON => 126,
- :tCOMMA => 127,
- :tSPACE => 128,
- :tSEMI => 129,
- :tEQL => 130,
- :tLOWEST => 131 }
-
-racc_nt_base = 132
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "kCLASS",
- "kMODULE",
- "kDEF",
- "kUNDEF",
- "kBEGIN",
- "kRESCUE",
- "kENSURE",
- "kEND",
- "kIF",
- "kUNLESS",
- "kTHEN",
- "kELSIF",
- "kELSE",
- "kCASE",
- "kWHEN",
- "kWHILE",
- "kUNTIL",
- "kFOR",
- "kBREAK",
- "kNEXT",
- "kREDO",
- "kRETRY",
- "kIN",
- "kDO",
- "kDO_COND",
- "kDO_BLOCK",
- "kRETURN",
- "kYIELD",
- "kSUPER",
- "kSELF",
- "kNIL",
- "kTRUE",
- "kFALSE",
- "kAND",
- "kOR",
- "kNOT",
- "kIF_MOD",
- "kUNLESS_MOD",
- "kWHILE_MOD",
- "kUNTIL_MOD",
- "kRESCUE_MOD",
- "kALIAS",
- "kDEFINED",
- "klBEGIN",
- "klEND",
- "k__LINE__",
- "k__FILE__",
- "tIDENTIFIER",
- "tFID",
- "tGVAR",
- "tIVAR",
- "tCONSTANT",
- "tCVAR",
- "tNTH_REF",
- "tBACK_REF",
- "tSTRING_CONTENT",
- "tINTEGER",
- "tFLOAT",
- "tREGEXP_END",
- "tUPLUS",
- "tUMINUS",
- "tUMINUS_NUM",
- "tPOW",
- "tCMP",
- "tEQ",
- "tEQQ",
- "tNEQ",
- "tGEQ",
- "tLEQ",
- "tANDOP",
- "tOROP",
- "tMATCH",
- "tNMATCH",
- "tDOT",
- "tDOT2",
- "tDOT3",
- "tAREF",
- "tASET",
- "tLSHFT",
- "tRSHFT",
- "tCOLON2",
- "tCOLON3",
- "tOP_ASGN",
- "tASSOC",
- "tLPAREN",
- "tLPAREN2",
- "tRPAREN",
- "tLPAREN_ARG",
- "tLBRACK",
- "tLBRACK2",
- "tRBRACK",
- "tLBRACE",
- "tLBRACE_ARG",
- "tSTAR",
- "tSTAR2",
- "tAMPER",
- "tAMPER2",
- "tTILDE",
- "tPERCENT",
- "tDIVIDE",
- "tPLUS",
- "tMINUS",
- "tLT",
- "tGT",
- "tPIPE",
- "tBANG",
- "tCARET",
- "tLCURLY",
- "tRCURLY",
- "tBACK_REF2",
- "tSYMBEG",
- "tSTRING_BEG",
- "tXSTRING_BEG",
- "tREGEXP_BEG",
- "tWORDS_BEG",
- "tQWORDS_BEG",
- "tSTRING_DBEG",
- "tSTRING_DVAR",
- "tSTRING_END",
- "tSTRING",
- "tSYMBOL",
- "tREGEXP_OPT",
- "tNL",
- "tEH",
- "tCOLON",
- "tCOMMA",
- "tSPACE",
- "tSEMI",
- "tEQL",
- "tLOWEST",
- "$start",
- "program",
- "compstmt",
- "bodystmt",
- "opt_rescue",
- "opt_else",
- "opt_ensure",
- "stmts",
- "opt_terms",
- "stmt",
- "terms",
- "fitem",
- "undef_list",
- "expr_value",
- "lhs",
- "command_call",
- "mlhs",
- "var_lhs",
- "primary_value",
- "aref_args",
- "backref",
- "mrhs",
- "arg_value",
- "expr",
- "@1",
- "arg",
- "command",
- "block_command",
- "call_args",
- "block_call",
- "operation2",
- "command_args",
- "cmd_brace_block",
- "opt_block_var",
- "@2",
- "operation",
- "mlhs_basic",
- "mlhs_entry",
- "mlhs_head",
- "mlhs_item",
- "mlhs_node",
- "variable",
- "cname",
- "cpath",
- "fname",
- "op",
- "reswords",
- "fsym",
- "symbol",
- "dsym",
- "@3",
- "opt_nl",
- "primary",
- "none",
- "args",
- "trailer",
- "assocs",
- "paren_args",
- "opt_paren_args",
- "opt_block_arg",
- "block_arg",
- "call_args2",
- "open_args",
- "@4",
- "@5",
- "@6",
- "literal",
- "strings",
- "xstring",
- "regexp",
- "words",
- "qwords",
- "var_ref",
- "assoc_list",
- "brace_block",
- "method_call",
- "then",
- "if_tail",
- "do",
- "case_body",
- "for_var",
- "superclass",
- "term",
- "f_arglist",
- "singleton",
- "dot_or_colon",
- "@7",
- "@8",
- "@9",
- "@10",
- "@11",
- "@12",
- "@13",
- "@14",
- "@15",
- "@16",
- "@17",
- "@18",
- "@19",
- "block_par",
- "block_var",
- "do_block",
- "@20",
- "operation3",
- "@21",
- "@22",
- "when_args",
- "cases",
- "exc_list",
- "exc_var",
- "numeric",
- "string",
- "string1",
- "string_contents",
- "xstring_contents",
- "word_list",
- "word",
- "string_content",
- "qword_list",
- "string_dvar",
- "@23",
- "f_args",
- "f_arg",
- "f_optarg",
- "f_rest_arg",
- "opt_f_block_arg",
- "f_block_arg",
- "f_norm_arg",
- "f_opt",
- "restarg_mark",
- "blkarg_mark",
- "assoc" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 73)
- def _reduce_1(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 78)
- def _reduce_2(val, _values, result)
- rescue_bodies = val[1]
- else_t, else_ = val[2]
- ensure_t, ensure_ = val[3]
-
- if rescue_bodies.empty? && !else_.nil?
- diagnostic :warning, :useless_else, nil, else_t
- end
-
- result = @builder.begin_body(val[0],
- rescue_bodies,
- else_t, else_,
- ensure_t, ensure_)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 94)
- def _reduce_3(val, _values, result)
- result = @builder.compstmt(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 99)
- def _reduce_4(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 103)
- def _reduce_5(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 107)
- def _reduce_6(val, _values, result)
- result = [ val[1] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 111)
- def _reduce_7(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 116)
- def _reduce_8(val, _values, result)
- @lexer.state = :expr_fname
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 120)
- def _reduce_9(val, _values, result)
- result = @builder.alias(val[0], val[1], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 124)
- def _reduce_10(val, _values, result)
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.gvar(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 130)
- def _reduce_11(val, _values, result)
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.back_ref(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 136)
- def _reduce_12(val, _values, result)
- diagnostic :error, :nth_ref_alias, nil, val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 140)
- def _reduce_13(val, _values, result)
- result = @builder.undef_method(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 144)
- def _reduce_14(val, _values, result)
- result = @builder.condition_mod(val[0], nil,
- val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 149)
- def _reduce_15(val, _values, result)
- result = @builder.condition_mod(nil, val[0],
- val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 154)
- def _reduce_16(val, _values, result)
- result = @builder.loop_mod(:while, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 158)
- def _reduce_17(val, _values, result)
- result = @builder.loop_mod(:until, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 162)
- def _reduce_18(val, _values, result)
- rescue_body = @builder.rescue_body(val[1],
- nil, nil, nil,
- nil, val[2])
-
- result = @builder.begin_body(val[0], [ rescue_body ])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 170)
- def _reduce_19(val, _values, result)
- if in_def?
- diagnostic :error, :begin_in_method, nil, val[0]
- end
-
- result = @builder.preexe(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 178)
- def _reduce_20(val, _values, result)
- result = @builder.postexe(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 182)
- def _reduce_21(val, _values, result)
- result = @builder.assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 186)
- def _reduce_22(val, _values, result)
- result = @builder.multi_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 190)
- def _reduce_23(val, _values, result)
- result = @builder.op_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 194)
- def _reduce_24(val, _values, result)
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 201)
- def _reduce_25(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 208)
- def _reduce_26(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 215)
- def _reduce_27(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 222)
- def _reduce_28(val, _values, result)
- @builder.op_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 226)
- def _reduce_29(val, _values, result)
- result = @builder.assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 231)
- def _reduce_30(val, _values, result)
- result = @builder.multi_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 235)
- def _reduce_31(val, _values, result)
- result = @builder.multi_assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
-
- result
- end
-.,.,
-
-# reduce 32 omitted
-
-# reduce 33 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 243)
- def _reduce_34(val, _values, result)
- result = @builder.logical_op(:and, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 247)
- def _reduce_35(val, _values, result)
- result = @builder.logical_op(:or, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 251)
- def _reduce_36(val, _values, result)
- result = @builder.not_op(val[0], nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 255)
- def _reduce_37(val, _values, result)
- result = @builder.not_op(val[0], nil, val[1], nil)
-
- result
- end
-.,.,
-
-# reduce 38 omitted
-
-# reduce 39 omitted
-
-# reduce 40 omitted
-
-# reduce 41 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 265)
- def _reduce_42(val, _values, result)
- result = @builder.keyword_cmd(:return, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 270)
- def _reduce_43(val, _values, result)
- result = @builder.keyword_cmd(:break, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 275)
- def _reduce_44(val, _values, result)
- result = @builder.keyword_cmd(:next, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-# reduce 45 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 282)
- def _reduce_46(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 288)
- def _reduce_47(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 295)
- def _reduce_48(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 299)
- def _reduce_49(val, _values, result)
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 306)
- def _reduce_50(val, _values, result)
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 312)
- def _reduce_51(val, _values, result)
- lparen_t, args, rparen_t = val[1]
- method_call = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
-
- begin_t, block_args, body, end_t = val[2]
- result = @builder.block(method_call,
- begin_t, block_args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 322)
- def _reduce_52(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 329)
- def _reduce_53(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- method_call = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- begin_t, block_args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, block_args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 339)
- def _reduce_54(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 345)
- def _reduce_55(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- method_call = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- begin_t, block_args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, block_args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 355)
- def _reduce_56(val, _values, result)
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 361)
- def _reduce_57(val, _values, result)
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:yield, val[0],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 368)
- def _reduce_58(val, _values, result)
- result = @builder.multi_lhs(nil, val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 372)
- def _reduce_59(val, _values, result)
- result = @builder.begin(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 377)
- def _reduce_60(val, _values, result)
- result = @builder.multi_lhs(nil, val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 381)
- def _reduce_61(val, _values, result)
- result = @builder.multi_lhs(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 386)
- def _reduce_62(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 390)
- def _reduce_63(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 394)
- def _reduce_64(val, _values, result)
- result = val[0] << @builder.splat(val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 398)
- def _reduce_65(val, _values, result)
- result = val[0] << @builder.splat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 402)
- def _reduce_66(val, _values, result)
- result = [ @builder.splat(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 406)
- def _reduce_67(val, _values, result)
- result = [ @builder.splat(val[0]) ]
-
- result
- end
-.,.,
-
-# reduce 68 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 412)
- def _reduce_69(val, _values, result)
- result = @builder.begin(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 417)
- def _reduce_70(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 421)
- def _reduce_71(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 426)
- def _reduce_72(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 430)
- def _reduce_73(val, _values, result)
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 434)
- def _reduce_74(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 438)
- def _reduce_75(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 442)
- def _reduce_76(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 446)
- def _reduce_77(val, _values, result)
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 451)
- def _reduce_78(val, _values, result)
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 456)
- def _reduce_79(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 461)
- def _reduce_80(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 465)
- def _reduce_81(val, _values, result)
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 469)
- def _reduce_82(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 473)
- def _reduce_83(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 477)
- def _reduce_84(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 481)
- def _reduce_85(val, _values, result)
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 486)
- def _reduce_86(val, _values, result)
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 491)
- def _reduce_87(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 496)
- def _reduce_88(val, _values, result)
- diagnostic :error, :module_name_const, nil, val[0]
-
- result
- end
-.,.,
-
-# reduce 89 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 502)
- def _reduce_90(val, _values, result)
- result = @builder.const_global(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 506)
- def _reduce_91(val, _values, result)
- result = @builder.const(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 510)
- def _reduce_92(val, _values, result)
- result = @builder.const_fetch(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-# reduce 93 omitted
-
-# reduce 94 omitted
-
-# reduce 95 omitted
-
-# reduce 96 omitted
-
-# reduce 97 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 519)
- def _reduce_98(val, _values, result)
- result = @builder.symbol(val[0])
-
- result
- end
-.,.,
-
-# reduce 99 omitted
-
-# reduce 100 omitted
-
-# reduce 101 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 528)
- def _reduce_102(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 532)
- def _reduce_103(val, _values, result)
- @lexer.state = :expr_fname
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 536)
- def _reduce_104(val, _values, result)
- result = val[0] << val[3]
-
- result
- end
-.,.,
-
-# reduce 105 omitted
-
-# reduce 106 omitted
-
-# reduce 107 omitted
-
-# reduce 108 omitted
-
-# reduce 109 omitted
-
-# reduce 110 omitted
-
-# reduce 111 omitted
-
-# reduce 112 omitted
-
-# reduce 113 omitted
-
-# reduce 114 omitted
-
-# reduce 115 omitted
-
-# reduce 116 omitted
-
-# reduce 117 omitted
-
-# reduce 118 omitted
-
-# reduce 119 omitted
-
-# reduce 120 omitted
-
-# reduce 121 omitted
-
-# reduce 122 omitted
-
-# reduce 123 omitted
-
-# reduce 124 omitted
-
-# reduce 125 omitted
-
-# reduce 126 omitted
-
-# reduce 127 omitted
-
-# reduce 128 omitted
-
-# reduce 129 omitted
-
-# reduce 130 omitted
-
-# reduce 131 omitted
-
-# reduce 132 omitted
-
-# reduce 133 omitted
-
-# reduce 134 omitted
-
-# reduce 135 omitted
-
-# reduce 136 omitted
-
-# reduce 137 omitted
-
-# reduce 138 omitted
-
-# reduce 139 omitted
-
-# reduce 140 omitted
-
-# reduce 141 omitted
-
-# reduce 142 omitted
-
-# reduce 143 omitted
-
-# reduce 144 omitted
-
-# reduce 145 omitted
-
-# reduce 146 omitted
-
-# reduce 147 omitted
-
-# reduce 148 omitted
-
-# reduce 149 omitted
-
-# reduce 150 omitted
-
-# reduce 151 omitted
-
-# reduce 152 omitted
-
-# reduce 153 omitted
-
-# reduce 154 omitted
-
-# reduce 155 omitted
-
-# reduce 156 omitted
-
-# reduce 157 omitted
-
-# reduce 158 omitted
-
-# reduce 159 omitted
-
-# reduce 160 omitted
-
-# reduce 161 omitted
-
-# reduce 162 omitted
-
-# reduce 163 omitted
-
-# reduce 164 omitted
-
-# reduce 165 omitted
-
-# reduce 166 omitted
-
-# reduce 167 omitted
-
-# reduce 168 omitted
-
-# reduce 169 omitted
-
-# reduce 170 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 555)
- def _reduce_171(val, _values, result)
- result = @builder.assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 559)
- def _reduce_172(val, _values, result)
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.assign(val[0], val[1], rescue_)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 569)
- def _reduce_173(val, _values, result)
- result = @builder.op_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 573)
- def _reduce_174(val, _values, result)
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 580)
- def _reduce_175(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 587)
- def _reduce_176(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 594)
- def _reduce_177(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 601)
- def _reduce_178(val, _values, result)
- diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 605)
- def _reduce_179(val, _values, result)
- diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 609)
- def _reduce_180(val, _values, result)
- result = @builder.op_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 613)
- def _reduce_181(val, _values, result)
- result = @builder.range_inclusive(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 617)
- def _reduce_182(val, _values, result)
- result = @builder.range_exclusive(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 621)
- def _reduce_183(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 625)
- def _reduce_184(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 629)
- def _reduce_185(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 633)
- def _reduce_186(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 637)
- def _reduce_187(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 641)
- def _reduce_188(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 645)
- def _reduce_189(val, _values, result)
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.integer(val[1]),
- val[2], val[3]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 652)
- def _reduce_190(val, _values, result)
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- @builder.float(val[1]),
- val[2], val[3]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 659)
- def _reduce_191(val, _values, result)
- result = @builder.unary_op(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 663)
- def _reduce_192(val, _values, result)
- result = @builder.unary_op(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 667)
- def _reduce_193(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 671)
- def _reduce_194(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 675)
- def _reduce_195(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 679)
- def _reduce_196(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 683)
- def _reduce_197(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 687)
- def _reduce_198(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 691)
- def _reduce_199(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 695)
- def _reduce_200(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 699)
- def _reduce_201(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 703)
- def _reduce_202(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 707)
- def _reduce_203(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 711)
- def _reduce_204(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 715)
- def _reduce_205(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 719)
- def _reduce_206(val, _values, result)
- result = @builder.not_op(val[0], nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 723)
- def _reduce_207(val, _values, result)
- result = @builder.unary_op(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 727)
- def _reduce_208(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 731)
- def _reduce_209(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 735)
- def _reduce_210(val, _values, result)
- result = @builder.logical_op(:and, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 739)
- def _reduce_211(val, _values, result)
- result = @builder.logical_op(:or, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 743)
- def _reduce_212(val, _values, result)
- result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 747)
- def _reduce_213(val, _values, result)
- result = @builder.ternary(val[0], val[1],
- val[2], val[3], val[4])
-
- result
- end
-.,.,
-
-# reduce 214 omitted
-
-# reduce 215 omitted
-
-# reduce 216 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 757)
- def _reduce_217(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 761)
- def _reduce_218(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 765)
- def _reduce_219(val, _values, result)
- result = val[0] << @builder.splat(val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 769)
- def _reduce_220(val, _values, result)
- result = [ @builder.associate(nil, val[0], nil) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 773)
- def _reduce_221(val, _values, result)
- result = [ @builder.splat(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 778)
- def _reduce_222(val, _values, result)
- result = [ val[0], [], val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 782)
- def _reduce_223(val, _values, result)
- result = [ val[0], val[1], val[3] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 786)
- def _reduce_224(val, _values, result)
- result = [ val[0], [ val[1] ], val[3] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 790)
- def _reduce_225(val, _values, result)
- result = [ val[0], val[1] << val[3], val[5] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 795)
- def _reduce_226(val, _values, result)
- result = [ nil, [], nil ]
-
- result
- end
-.,.,
-
-# reduce 227 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 801)
- def _reduce_228(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 805)
- def _reduce_229(val, _values, result)
- result = val[0].concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 809)
- def _reduce_230(val, _values, result)
- result = val[0].concat(
- [ @builder.splat(val[2], val[3]),
- *val[4] ])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 815)
- def _reduce_231(val, _values, result)
- result = [ @builder.associate(nil, val[0], nil),
- *val[1] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 820)
- def _reduce_232(val, _values, result)
- result = [ @builder.associate(nil, val[0], nil),
- @builder.splat(val[2], val[3]),
- *val[4] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 826)
- def _reduce_233(val, _values, result)
- result = val[0].concat(
- [ @builder.associate(nil, val[2], nil),
- *val[3] ])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 832)
- def _reduce_234(val, _values, result)
- result = val[0].concat(
- [ @builder.associate(nil, val[2], nil),
- @builder.splat(val[4], val[5]),
- *val[6] ])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 839)
- def _reduce_235(val, _values, result)
- result = [ @builder.splat(val[0], val[1]),
- *val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 844)
- def _reduce_236(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 849)
- def _reduce_237(val, _values, result)
- result = [ val[0], *val[2].concat(val[3]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 853)
- def _reduce_238(val, _values, result)
- result = [ val[0], val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 857)
- def _reduce_239(val, _values, result)
- result = [ val[0],
- @builder.splat(val[2], val[3]),
- *val[4] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 863)
- def _reduce_240(val, _values, result)
- result = [ val[0],
- *val[2].
- push(@builder.splat(val[4], val[5])).
- concat(val[6]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 870)
- def _reduce_241(val, _values, result)
- result = [ @builder.associate(nil, val[0], nil),
- *val[1] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 875)
- def _reduce_242(val, _values, result)
- result = [ @builder.associate(nil, val[0], nil),
- @builder.splat(val[2], val[3]),
- *val[4] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 881)
- def _reduce_243(val, _values, result)
- result = [ val[0],
- @builder.associate(nil, val[2], nil),
- *val[3] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 887)
- def _reduce_244(val, _values, result)
- result = [ val[0],
- *val[2].
- push(@builder.associate(nil, val[4], nil)).
- concat(val[5]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 894)
- def _reduce_245(val, _values, result)
- result = [ val[0],
- @builder.associate(nil, val[2], nil),
- @builder.splat(val[4], val[5]),
- *val[6] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 901)
- def _reduce_246(val, _values, result)
- result = [ val[0],
- *val[2].
- push(@builder.associate(nil, val[4], nil)).
- push(@builder.splat(val[6], val[7])).
- concat(val[8]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 909)
- def _reduce_247(val, _values, result)
- result = [ @builder.splat(val[0], val[1]),
- *val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 914)
- def _reduce_248(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 918)
- def _reduce_249(val, _values, result)
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 923)
- def _reduce_250(val, _values, result)
- @lexer.cmdarg = val[0]
-
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 930)
- def _reduce_251(val, _values, result)
- result = [ nil, val[0], nil ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 934)
- def _reduce_252(val, _values, result)
- @lexer.state = :expr_endarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 938)
- def _reduce_253(val, _values, result)
- result = [ val[0], [], val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 942)
- def _reduce_254(val, _values, result)
- @lexer.state = :expr_endarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 946)
- def _reduce_255(val, _values, result)
- result = [ val[0], val[1], val[3] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 951)
- def _reduce_256(val, _values, result)
- result = @builder.block_pass(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 956)
- def _reduce_257(val, _values, result)
- result = [ val[1] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 960)
- def _reduce_258(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 965)
- def _reduce_259(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 969)
- def _reduce_260(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 974)
- def _reduce_261(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 978)
- def _reduce_262(val, _values, result)
- result = val[0] << @builder.splat(val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 982)
- def _reduce_263(val, _values, result)
- result = [ @builder.splat(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-# reduce 264 omitted
-
-# reduce 265 omitted
-
-# reduce 266 omitted
-
-# reduce 267 omitted
-
-# reduce 268 omitted
-
-# reduce 269 omitted
-
-# reduce 270 omitted
-
-# reduce 271 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 995)
- def _reduce_272(val, _values, result)
- result = @builder.call_method(nil, nil, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 999)
- def _reduce_273(val, _values, result)
- result = @builder.begin_keyword(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1003)
- def _reduce_274(val, _values, result)
- @lexer.state = :expr_endarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1007)
- def _reduce_275(val, _values, result)
- result = @builder.begin(val[0], val[1], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1011)
- def _reduce_276(val, _values, result)
- result = @builder.begin(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1015)
- def _reduce_277(val, _values, result)
- result = @builder.const_fetch(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1019)
- def _reduce_278(val, _values, result)
- result = @builder.const_global(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1023)
- def _reduce_279(val, _values, result)
- result = @builder.index(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1027)
- def _reduce_280(val, _values, result)
- result = @builder.array(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1031)
- def _reduce_281(val, _values, result)
- result = @builder.associate(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1035)
- def _reduce_282(val, _values, result)
- result = @builder.keyword_cmd(:return, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1039)
- def _reduce_283(val, _values, result)
- result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1043)
- def _reduce_284(val, _values, result)
- result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1047)
- def _reduce_285(val, _values, result)
- result = @builder.keyword_cmd(:yield, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1051)
- def _reduce_286(val, _values, result)
- result = @builder.keyword_cmd(:defined?, val[0],
- val[2], [ val[3] ], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1056)
- def _reduce_287(val, _values, result)
- method_call = @builder.call_method(nil, nil, val[0])
-
- begin_t, args, body, end_t = val[1]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-# reduce 288 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1065)
- def _reduce_289(val, _values, result)
- begin_t, args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1071)
- def _reduce_290(val, _values, result)
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1078)
- def _reduce_291(val, _values, result)
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- else_, else_t,
- val[3], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1085)
- def _reduce_292(val, _values, result)
- @lexer.cond.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1089)
- def _reduce_293(val, _values, result)
- @lexer.cond.pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1093)
- def _reduce_294(val, _values, result)
- result = @builder.loop(:while, val[0], val[2], val[3],
- val[5], val[6])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1098)
- def _reduce_295(val, _values, result)
- @lexer.cond.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1102)
- def _reduce_296(val, _values, result)
- @lexer.cond.pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1106)
- def _reduce_297(val, _values, result)
- result = @builder.loop(:until, val[0], val[2], val[3],
- val[5], val[6])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1111)
- def _reduce_298(val, _values, result)
- when_bodies = val[3][0..-2]
- else_t, else_body = val[3][-1]
-
- result = @builder.case(val[0], val[1],
- when_bodies, else_t, else_body,
- val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1120)
- def _reduce_299(val, _values, result)
- when_bodies = val[2][0..-2]
- else_t, else_body = val[2][-1]
-
- result = @builder.case(val[0], nil,
- when_bodies, else_t, else_body,
- val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1129)
- def _reduce_300(val, _values, result)
- result = @builder.case(val[0], nil,
- [], val[2], val[3],
- val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1135)
- def _reduce_301(val, _values, result)
- @lexer.cond.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1139)
- def _reduce_302(val, _values, result)
- @lexer.cond.pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1143)
- def _reduce_303(val, _values, result)
- result = @builder.for(val[0], val[1],
- val[2], val[4],
- val[5], val[7], val[8])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1149)
- def _reduce_304(val, _values, result)
- @static_env.extend_static
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1153)
- def _reduce_305(val, _values, result)
- if in_def?
- diagnostic :error, :class_in_def, nil, val[0]
- end
-
- lt_t, superclass = val[2]
- result = @builder.def_class(val[0], val[1],
- lt_t, superclass,
- val[4], val[5])
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1166)
- def _reduce_306(val, _values, result)
- result = @def_level
- @def_level = 0
-
- @static_env.extend_static
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1173)
- def _reduce_307(val, _values, result)
- result = @builder.def_sclass(val[0], val[1], val[2],
- val[5], val[6])
-
- @static_env.unextend
-
- @def_level = val[4]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1182)
- def _reduce_308(val, _values, result)
- @static_env.extend_static
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1186)
- def _reduce_309(val, _values, result)
- if in_def?
- diagnostic :error, :module_in_def, nil, val[0]
- end
-
- result = @builder.def_module(val[0], val[1],
- val[3], val[4])
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1197)
- def _reduce_310(val, _values, result)
- @def_level += 1
- @static_env.extend_static
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1202)
- def _reduce_311(val, _values, result)
- result = @builder.def_method(val[0], val[1],
- val[3], val[4], val[5])
-
- @static_env.unextend
- @def_level -= 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1210)
- def _reduce_312(val, _values, result)
- @lexer.state = :expr_fname
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1214)
- def _reduce_313(val, _values, result)
- @def_level += 1
- @static_env.extend_static
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1219)
- def _reduce_314(val, _values, result)
- result = @builder.def_singleton(val[0], val[1], val[2],
- val[4], val[6], val[7], val[8])
-
- @static_env.unextend
- @def_level -= 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1227)
- def _reduce_315(val, _values, result)
- result = @builder.keyword_cmd(:break, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1231)
- def _reduce_316(val, _values, result)
- result = @builder.keyword_cmd(:next, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1235)
- def _reduce_317(val, _values, result)
- result = @builder.keyword_cmd(:redo, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1239)
- def _reduce_318(val, _values, result)
- result = @builder.keyword_cmd(:retry, val[0])
-
- result
- end
-.,.,
-
-# reduce 319 omitted
-
-# reduce 320 omitted
-
-# reduce 321 omitted
-
-# reduce 322 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1249)
- def _reduce_323(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-# reduce 324 omitted
-
-# reduce 325 omitted
-
-# reduce 326 omitted
-
-# reduce 327 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1259)
- def _reduce_328(val, _values, result)
- else_t, else_ = val[4]
- result = [ val[0],
- @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, nil),
- ]
-
- result
- end
-.,.,
-
-# reduce 329 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1270)
- def _reduce_330(val, _values, result)
- result = val
-
- result
- end
-.,.,
-
-# reduce 331 omitted
-
-# reduce 332 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1278)
- def _reduce_333(val, _values, result)
- result = [ @builder.arg_expr(val[0]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1282)
- def _reduce_334(val, _values, result)
- result = val[0] << @builder.arg_expr(val[2])
-
- result
- end
-.,.,
-
-# reduce 335 omitted
-
-# reduce 336 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1289)
- def _reduce_337(val, _values, result)
- result = val[0].
- push(@builder.blockarg_expr(val[2], val[3]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1294)
- def _reduce_338(val, _values, result)
- result = val[0].
- push(@builder.restarg_expr(val[2], val[3])).
- push(@builder.blockarg_expr(val[5], val[6]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1300)
- def _reduce_339(val, _values, result)
- result = val[0].
- push(@builder.restarg_expr(val[2])).
- push(@builder.blockarg_expr(val[4], val[5]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1306)
- def _reduce_340(val, _values, result)
- result = val[0].
- push(@builder.restarg_expr(val[2], val[3]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1311)
- def _reduce_341(val, _values, result)
- result = val[0].
- push(@builder.restarg_expr(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1316)
- def _reduce_342(val, _values, result)
- result = [ @builder.restarg_expr(val[0], val[1]),
- @builder.blockarg_expr(val[3], val[4]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1321)
- def _reduce_343(val, _values, result)
- result = [ @builder.restarg_expr(val[0]),
- @builder.blockarg_expr(val[2], val[3]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1326)
- def _reduce_344(val, _values, result)
- result = [ @builder.restarg_expr(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1330)
- def _reduce_345(val, _values, result)
- result = [ @builder.restarg_expr(val[0]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1334)
- def _reduce_346(val, _values, result)
- result = [ @builder.blockarg_expr(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1340)
- def _reduce_347(val, _values, result)
- result = @builder.args(nil, [], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1344)
- def _reduce_348(val, _values, result)
- result = @builder.args(val[0], [], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1348)
- def _reduce_349(val, _values, result)
- result = @builder.args(val[0], [], val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1352)
- def _reduce_350(val, _values, result)
- result = @builder.args(val[0], val[1], val[2], false)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1357)
- def _reduce_351(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1361)
- def _reduce_352(val, _values, result)
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1368)
- def _reduce_353(val, _values, result)
- begin_t, block_args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, block_args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1374)
- def _reduce_354(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1380)
- def _reduce_355(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1387)
- def _reduce_356(val, _values, result)
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1393)
- def _reduce_357(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1399)
- def _reduce_358(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1405)
- def _reduce_359(val, _values, result)
- result = @builder.call_method(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1409)
- def _reduce_360(val, _values, result)
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1415)
- def _reduce_361(val, _values, result)
- result = @builder.keyword_cmd(:zsuper, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1420)
- def _reduce_362(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1424)
- def _reduce_363(val, _values, result)
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1430)
- def _reduce_364(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1434)
- def _reduce_365(val, _values, result)
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1441)
- def _reduce_366(val, _values, result)
- result = [ @builder.when(val[0], val[1], val[2], val[3]),
- *val[4] ]
-
- result
- end
-.,.,
-
-# reduce 367 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1448)
- def _reduce_368(val, _values, result)
- result = val[0] << @builder.splat(val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1452)
- def _reduce_369(val, _values, result)
- result = [ @builder.splat(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1457)
- def _reduce_370(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-# reduce 371 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1463)
- def _reduce_372(val, _values, result)
- assoc_t, exc_var = val[2]
-
- if val[1]
- exc_list = @builder.array(nil, val[1], nil)
- end
-
- result = [ @builder.rescue_body(val[0],
- exc_list, assoc_t, exc_var,
- val[3], val[4]),
- *val[5] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1476)
- def _reduce_373(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1481)
- def _reduce_374(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-# reduce 375 omitted
-
-# reduce 376 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1488)
- def _reduce_377(val, _values, result)
- result = [ val[0], val[1] ]
-
- result
- end
-.,.,
-
-# reduce 378 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1494)
- def _reduce_379(val, _values, result)
- result = [ val[0], val[1] ]
-
- result
- end
-.,.,
-
-# reduce 380 omitted
-
-# reduce 381 omitted
-
-# reduce 382 omitted
-
-# reduce 383 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1504)
- def _reduce_384(val, _values, result)
- result = @builder.string_compose(nil, val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1509)
- def _reduce_385(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1513)
- def _reduce_386(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1518)
- def _reduce_387(val, _values, result)
- result = @builder.string_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1522)
- def _reduce_388(val, _values, result)
- result = @builder.string(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1527)
- def _reduce_389(val, _values, result)
- result = @builder.xstring_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1532)
- def _reduce_390(val, _values, result)
- opts = @builder.regexp_options(val[3])
- result = @builder.regexp_compose(val[0], val[1], val[2], opts)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1538)
- def _reduce_391(val, _values, result)
- result = @builder.words_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1543)
- def _reduce_392(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1547)
- def _reduce_393(val, _values, result)
- result = val[0] << @builder.word(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1552)
- def _reduce_394(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1556)
- def _reduce_395(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1561)
- def _reduce_396(val, _values, result)
- result = @builder.words_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1566)
- def _reduce_397(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1570)
- def _reduce_398(val, _values, result)
- result = val[0] << @builder.string_internal(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1575)
- def _reduce_399(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1579)
- def _reduce_400(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1584)
- def _reduce_401(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1588)
- def _reduce_402(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1593)
- def _reduce_403(val, _values, result)
- result = @builder.string_internal(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1597)
- def _reduce_404(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1601)
- def _reduce_405(val, _values, result)
- @lexer.cond.push(false)
- @lexer.cmdarg.push(false)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1606)
- def _reduce_406(val, _values, result)
- @lexer.cond.lexpop
- @lexer.cmdarg.lexpop
-
- result = @builder.begin(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1614)
- def _reduce_407(val, _values, result)
- result = @builder.gvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1618)
- def _reduce_408(val, _values, result)
- result = @builder.ivar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1622)
- def _reduce_409(val, _values, result)
- result = @builder.cvar(val[0])
-
- result
- end
-.,.,
-
-# reduce 410 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1629)
- def _reduce_411(val, _values, result)
- result = @builder.symbol(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1634)
- def _reduce_412(val, _values, result)
- result = @builder.symbol_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1639)
- def _reduce_413(val, _values, result)
- result = @builder.integer(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1643)
- def _reduce_414(val, _values, result)
- result = @builder.float(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1647)
- def _reduce_415(val, _values, result)
- result = @builder.negate(val[0],
- @builder.integer(val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1652)
- def _reduce_416(val, _values, result)
- result = @builder.negate(val[0],
- @builder.float(val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1658)
- def _reduce_417(val, _values, result)
- result = @builder.ident(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1662)
- def _reduce_418(val, _values, result)
- result = @builder.ivar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1666)
- def _reduce_419(val, _values, result)
- result = @builder.gvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1670)
- def _reduce_420(val, _values, result)
- result = @builder.cvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1674)
- def _reduce_421(val, _values, result)
- result = @builder.const(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1678)
- def _reduce_422(val, _values, result)
- result = @builder.nil(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1682)
- def _reduce_423(val, _values, result)
- result = @builder.self(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1686)
- def _reduce_424(val, _values, result)
- result = @builder.true(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1690)
- def _reduce_425(val, _values, result)
- result = @builder.false(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1694)
- def _reduce_426(val, _values, result)
- result = @builder.__FILE__(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1698)
- def _reduce_427(val, _values, result)
- result = @builder.__LINE__(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1703)
- def _reduce_428(val, _values, result)
- result = @builder.accessible(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1708)
- def _reduce_429(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1713)
- def _reduce_430(val, _values, result)
- result = @builder.nth_ref(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1717)
- def _reduce_431(val, _values, result)
- result = @builder.back_ref(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1722)
- def _reduce_432(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1726)
- def _reduce_433(val, _values, result)
- result = [ val[0], val[1] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1730)
- def _reduce_434(val, _values, result)
- yyerrok
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1736)
- def _reduce_435(val, _values, result)
- result = @builder.args(val[0], val[1], val[3])
-
- @lexer.state = :expr_beg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1742)
- def _reduce_436(val, _values, result)
- result = @builder.args(nil, val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1747)
- def _reduce_437(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1754)
- def _reduce_438(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1760)
- def _reduce_439(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1766)
- def _reduce_440(val, _values, result)
- result = val[0].
- concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1771)
- def _reduce_441(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1777)
- def _reduce_442(val, _values, result)
- result = val[0].
- concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1782)
- def _reduce_443(val, _values, result)
- result = val[0].
- concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1787)
- def _reduce_444(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1791)
- def _reduce_445(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1796)
- def _reduce_446(val, _values, result)
- diagnostic :error, :argument_const, nil, val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1800)
- def _reduce_447(val, _values, result)
- diagnostic :error, :argument_ivar, nil, val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1804)
- def _reduce_448(val, _values, result)
- diagnostic :error, :argument_gvar, nil, val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1808)
- def _reduce_449(val, _values, result)
- diagnostic :error, :argument_cvar, nil, val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1812)
- def _reduce_450(val, _values, result)
- @static_env.declare val[0][0]
-
- result = @builder.arg(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1819)
- def _reduce_451(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1823)
- def _reduce_452(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1828)
- def _reduce_453(val, _values, result)
- @static_env.declare val[0][0]
-
- result = @builder.optarg(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1835)
- def _reduce_454(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1839)
- def _reduce_455(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-# reduce 456 omitted
-
-# reduce 457 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1846)
- def _reduce_458(val, _values, result)
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1852)
- def _reduce_459(val, _values, result)
- result = [ @builder.restarg(val[0]) ]
-
- result
- end
-.,.,
-
-# reduce 460 omitted
-
-# reduce 461 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1859)
- def _reduce_462(val, _values, result)
- @static_env.declare val[1][0]
-
- result = @builder.blockarg(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1866)
- def _reduce_463(val, _values, result)
- result = [ val[1] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1870)
- def _reduce_464(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-# reduce 465 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1876)
- def _reduce_466(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1881)
- def _reduce_467(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1885)
- def _reduce_468(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1889)
- def _reduce_469(val, _values, result)
- result = @builder.pair_list_18(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1894)
- def _reduce_470(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1898)
- def _reduce_471(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby18.y', 1903)
- def _reduce_472(val, _values, result)
- result = @builder.pair(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-# reduce 473 omitted
-
-# reduce 474 omitted
-
-# reduce 475 omitted
-
-# reduce 476 omitted
-
-# reduce 477 omitted
-
-# reduce 478 omitted
-
-# reduce 479 omitted
-
-# reduce 480 omitted
-
-# reduce 481 omitted
-
-# reduce 482 omitted
-
-# reduce 483 omitted
-
-# reduce 484 omitted
-
-# reduce 485 omitted
-
-# reduce 486 omitted
-
-# reduce 487 omitted
-
-# reduce 488 omitted
-
-# reduce 489 omitted
-
-# reduce 490 omitted
-
-# reduce 491 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1916)
- def _reduce_492(val, _values, result)
- yyerrok
-
- result
- end
-.,.,
-
-# reduce 493 omitted
-
-# reduce 494 omitted
-
-# reduce 495 omitted
-
-module_eval(<<'.,.,', 'ruby18.y', 1925)
- def _reduce_496(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Ruby18
-end # module Parser
diff --git a/test/racc/regress/ruby22 b/test/racc/regress/ruby22
deleted file mode 100644
index 4731071275..0000000000
--- a/test/racc/regress/ruby22
+++ /dev/null
@@ -1,11180 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.2
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-
-
-require 'parser'
-
-Parser.check_for_encoding_support
-
-module Parser
- class Ruby22 < Racc::Parser
-
-module_eval(<<'...end ruby22.y/module_eval...', 'ruby22.y', 2374)
-
- def version
- 22
- end
-
- def default_encoding
- Encoding::UTF_8
- end
-...end ruby22.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- -476, -97, 268, 214, 215, -98, -105, -476, -476, -476,
- -490, 568, -476, -476, -476, 610, -476, 580, 217, 612,
- -288, 581, 214, 215, -476, -491, -476, -476, -476, 647,
- 268, 268, 214, 215, -104, 589, -476, -476, 568, -476,
- -476, -476, -476, -476, 568, 568, 212, 109, 568, 815,
- -100, 121, -100, -83, -102, -99, 214, 215, 268, 218,
- -288, 806, -69, 574, 646, -102, -97, -476, -476, -476,
- -476, -476, -476, -476, -476, -476, -476, -476, -476, -476,
- -476, -98, 609, -476, -476, -476, 611, -476, -476, 715,
- 267, -476, 206, -96, -476, -476, 263, -476, 218, -476,
- 207, -476, -105, -476, -476, -99, -476, -476, -476, -476,
- -476, -88, -476, -479, -476, -89, -96, 218, 267, 267,
- -479, -479, -479, 263, -101, -479, -479, -479, -476, -479,
- 113, -476, -476, -476, -476, 112, -476, -479, -476, -479,
- -479, -479, 588, -476, -95, 715, 267, -101, 715, -479,
- -479, 218, -479, -479, -479, -479, -479, 113, 208, 814,
- -91, -91, 112, 113, 113, 113, 842, 113, 112, 112,
- 112, -100, 112, -102, -99, -93, -100, 213, -102, -99,
- -479, -479, -479, -479, -479, -479, -479, -479, -479, -479,
- -479, -479, -479, -479, 113, 257, -479, -479, -479, 112,
- -479, -479, -574, -93, -479, 316, -103, -479, -479, 317,
- -479, 597, -479, -574, -479, -90, -479, -479, 444, -479,
- -479, -479, -479, -479, -291, -479, 218, -479, -91, 214,
- 215, -291, -291, -291, 647, 260, 527, -291, -291, 526,
- -291, -479, 261, -101, -479, -479, -479, -479, -101, -479,
- 113, -479, -571, 113, 113, 112, -479, -92, 112, 112,
- -291, -291, 386, -291, -291, -291, -291, -291, -91, 646,
- -93, -91, -575, 396, -105, 399, 599, 598, 398, 397,
- -91, 548, 597, 545, 544, 543, 747, 546, 443, 91,
- 92, -291, -291, -291, -291, -291, -291, -291, -291, -291,
- -291, -291, -291, -291, -291, -476, -572, -291, -291, -291,
- -93, 630, -476, -93, -490, -291, -94, -571, -291, 91,
- 92, -476, -93, -291, 113, -291, 515, -291, -291, 112,
- -291, -291, -291, -291, -291, 597, -291, -578, -291, 445,
- -571, -491, -476, 446, -578, -578, -578, 599, 598, -476,
- -578, -578, -291, -578, 647, -291, -291, 749, -94, -479,
- -291, -88, -578, 217, 833, -578, -479, -103, 93, 94,
- -97, -572, 477, -578, -578, -479, -578, -578, -578, -578,
- -578, 548, -104, 545, 544, 543, 515, 546, -89, 646,
- 527, 647, 597, 529, -572, 597, 486, -98, 93, 94,
- 599, 598, 595, -412, -578, -578, -578, -578, -578, -578,
- -578, -578, -578, -578, -578, -578, -578, -578, -578, 625,
- -578, -578, -578, 597, 631, -578, 646, 113, -578, 626,
- -574, -578, 112, -95, -578, 597, -578, 770, -578, -578,
- -578, -578, -104, -578, -578, -578, -578, -578, 488, -578,
- -578, -578, 597, -578, 490, 597, -412, 599, 598, 595,
- 599, 598, 600, -412, 957, -578, -91, 756, -578, -578,
- -578, -92, -412, -578, 662, -100, -93, -578, -578, -578,
- -101, 498, -578, -578, -578, -102, -578, -479, 599, 598,
- 602, -412, -578, -100, -479, -578, -578, -578, -578, -578,
- 599, 598, 604, 771, -574, -68, -578, -578, -578, -578,
- -578, -578, -578, -578, -90, 218, 860, 599, 598, 608,
- 599, 598, 613, -99, 214, 215, -486, -578, 548, -485,
- 545, 544, 543, -486, 546, 501, -485, -578, -578, -578,
- -578, -578, -578, -578, -578, -578, -578, -578, -578, -578,
- -578, 553, 502, -578, -578, -578, -487, 772, -578, -102,
- 509, -578, 556, -487, -578, -578, 701, -578, 272, -578,
- 218, -578, -99, -578, -578, 704, -578, -578, -578, -578,
- -578, 553, -578, -578, -578, 527, -484, 79, 529, 113,
- -481, 263, 556, -484, 112, 564, 563, -481, -578, 80,
- 557, -578, -578, -578, -578, 238, -578, -291, -578, 81,
- -482, 210, 512, -101, -291, -291, -291, -482, 211, -291,
- -291, -291, -334, -291, 440, 564, 563, 209, 516, -334,
- 557, 441, -483, -291, -291, -291, 238, 235, -334, -483,
- 442, 237, 236, -291, -291, 260, -291, -291, -291, -291,
- -291, 548, 261, 545, 544, 543, -488, 546, 548, 218,
- 545, 544, 543, -488, 546, 548, 530, 545, 544, 543,
- 527, 546, -488, 529, -291, -291, -291, -291, -291, -291,
- -291, -291, -291, -291, -291, -291, -291, -291, 238, 701,
- -291, -291, -291, -489, 773, -291, 701, 238, -291, 531,
- -489, -291, -291, 701, -291, 704, -291, 490, -291, -489,
- -291, -291, 904, -291, -291, -291, -291, -291, 113, -291,
- 235, -291, 574, 112, 237, 236, 238, 233, 234, 235,
- 214, 215, 388, 237, 236, -291, 233, 234, -291, -291,
- -291, -291, 113, -291, 113, -291, 578, 112, 579, 112,
- -103, 5, 69, 70, 71, 9, 57, 614, 235, 507,
- 63, 64, 237, 236, 617, 67, 508, 65, 66, 68,
- 30, 31, 72, 73, 218, 506, -263, 981, 619, 29,
- 28, 27, 101, 100, 102, 103, 741, 742, 19, 218,
- 743, 107, 108, 635, 8, 45, 7, 10, 105, 104,
- 106, 95, 56, 97, 96, 98, 623, 99, 107, 108,
- 624, 91, 92, 263, 42, 43, 41, 238, 242, 247,
- 248, 249, 244, 246, 254, 255, 250, 251, -281, 231,
- 232, 517, 634, 252, 253, -281, 40, 637, 518, 33,
- 564, 563, 58, 59, -281, 238, 60, 442, 35, 235,
- 238, 241, 44, 237, 236, 238, 233, 234, 245, 243,
- 239, 20, 240, 837, 806, 238, 89, 79, 82, 83,
- 576, 84, 86, 85, 87, 837, 806, 577, 218, 80,
- 88, 218, 256, 218, -240, -83, 575, 62, 666, 81,
- 93, 94, 290, 69, 70, 71, 9, 57, 218, 520,
- 584, 63, 64, 677, 682, 683, 67, 583, 65, 66,
- 68, 30, 31, 72, 73, 685, 585, 689, 692, 693,
- 29, 28, 27, 101, 100, 102, 103, 695, 697, 19,
- 699, 707, 708, 709, 620, 8, 45, 292, 10, 105,
- 104, 106, 95, 56, 97, 96, 98, 711, 99, 107,
- 108, 574, 91, 92, 718, 42, 43, 41, 238, 242,
- 247, 248, 249, 244, 246, 254, 255, 250, 251, -292,
- 231, 232, -292, 736, 252, 253, -292, 40, 746, -292,
- 294, 750, 751, 58, 59, -292, -264, 60, -292, 35,
- 235, 757, 241, 44, 237, 236, 477, 233, 234, 245,
- 243, 239, 20, 240, 477, 218, 257, 89, 79, 82,
- 83, 584, 84, 86, 85, 87, 488, 490, 939, 799,
- 80, 88, 677, 256, 218, 263, 263, 585, 62, 677,
- 81, 93, 94, 5, 69, 70, 71, 9, 57, 238,
- 806, 584, 63, 64, 218, 218, 831, 67, 939, 65,
- 66, 68, 30, 31, 72, 73, 218, 585, 806, 841,
- 218, 29, 28, 27, 101, 100, 102, 103, 218, 850,
- 19, -265, 859, 861, 862, 635, 8, 45, 7, 10,
- 105, 104, 106, 95, 56, 97, 96, 98, 692, 99,
- 107, 108, 865, 91, 92, 867, 42, 43, 41, 238,
- 242, 247, 248, 249, 244, 246, 254, 255, 250, 251,
- -291, 231, 232, -488, 869, 252, 253, -291, 40, 871,
- -488, 33, -575, 218, 58, 59, -291, 873, 60, -488,
- 35, 235, 874, 241, 44, 237, 236, 877, 233, 234,
- 245, 243, 239, 20, 240, 879, 880, 677, 89, 79,
- 82, 83, -489, 84, 86, 85, 87, 882, -263, -489,
- 886, 80, 88, 888, 256, 891, 692, 893, -489, 62,
- 895, 81, 93, 94, 290, 69, 70, 71, 9, 57,
- 897, 899, 986, 63, 64, 899, 218, 905, 67, 987,
- 65, 66, 68, 30, 31, 72, 73, 907, 985, 909,
- 915, 918, 29, 28, 27, 101, 100, 102, 103, 218,
- 936, 19, 545, 544, 543, 922, 546, 8, 45, 292,
- 10, 105, 104, 106, 95, 56, 97, 96, 98, -266,
- 99, 107, 108, 933, 91, 92, 940, 42, 43, 41,
- 238, 242, 247, 248, 249, 244, 246, 254, 255, 250,
- 251, -291, 231, 232, -281, 941, 252, 253, -291, 40,
- 950, -281, 33, -575, 951, 58, 59, -291, 959, 60,
- -281, 35, 235, 961, 241, 44, 237, 236, 962, 233,
- 234, 245, 243, 239, 20, 240, 967, 736, 692, 89,
- 79, 82, 83, -292, 84, 86, 85, 87, 971, 973,
- -292, 975, 80, 88, 977, 256, 977, 988, 989, -292,
- 62, 899, 81, 93, 94, 290, 69, 70, 71, 9,
- 57, 899, 899, 994, 63, 64, 959, -575, -574, 67,
- 682, 65, 66, 68, 30, 31, 72, 73, 116, 117,
- 118, 119, 120, 29, 28, 27, 101, 100, 102, 103,
- 959, 936, 19, 545, 544, 543, 1013, 546, 8, 45,
- 292, 10, 105, 104, 106, 95, 56, 97, 96, 98,
- 1014, 99, 107, 108, 1015, 91, 92, 977, 42, 43,
- 41, 238, 242, 247, 248, 249, 244, 246, 254, 255,
- 250, 251, -291, 231, 232, 977, 977, 252, 253, -291,
- 40, 218, 899, 33, -575, 959, 58, 59, -291, 977,
- 60, nil, 35, 235, nil, 241, 44, 237, 236, nil,
- 233, 234, 245, 243, 239, 20, 240, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, 256, nil, nil, nil,
- nil, 62, nil, 81, 93, 94, 290, 69, 70, 71,
- 9, 57, nil, nil, nil, 63, 64, nil, nil, nil,
- 67, nil, 65, 66, 68, 30, 31, 72, 73, 116,
- 117, 118, 119, 120, 29, 28, 27, 101, 100, 102,
- 103, nil, nil, 19, 116, 117, 118, 119, 120, 8,
- 45, 292, 10, 105, 104, 106, 95, 56, 97, 96,
- 98, nil, 99, 107, 108, nil, 91, 92, nil, 42,
- 43, 41, 238, 242, 247, 248, 249, 244, 246, 254,
- 255, 250, 251, nil, 231, 232, nil, nil, 252, 253,
- nil, 40, nil, nil, 294, nil, nil, 58, 59, nil,
- nil, 60, nil, 35, 235, nil, 241, 44, 237, 236,
- nil, 233, 234, 245, 243, 239, 20, 240, nil, nil,
- nil, 89, 79, 82, 83, nil, 84, 86, 85, 87,
- nil, nil, nil, nil, 80, 88, nil, 256, nil, nil,
- nil, nil, 62, nil, 81, 93, 94, 290, 69, 70,
- 71, 9, 57, nil, nil, nil, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 19, nil, nil, nil, nil, nil,
- 8, 45, 292, 10, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, 238, 242, 247, 248, 249, 244, 246,
- 254, 255, 250, 251, nil, 231, 232, nil, nil, 252,
- 253, nil, 40, nil, nil, 294, nil, nil, 58, 59,
- nil, nil, 60, nil, 35, 235, nil, 241, 44, 237,
- 236, nil, 233, 234, 245, 243, 239, 20, 240, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, 256, nil,
- nil, nil, nil, 62, nil, 81, 93, 94, 290, 69,
- 70, 71, 9, 57, nil, nil, nil, 63, 64, nil,
- nil, nil, 67, nil, 65, 66, 68, 30, 31, 72,
- 73, nil, nil, nil, nil, nil, 29, 28, 27, 101,
- 100, 102, 103, nil, nil, 19, nil, nil, nil, nil,
- nil, 8, 45, 292, 10, 105, 104, 106, 95, 56,
- 97, 96, 98, nil, 99, 107, 108, nil, 91, 92,
- nil, 42, 43, 41, 238, 242, 247, 248, 249, 244,
- 246, 254, 255, 250, 251, nil, 231, 232, nil, nil,
- 252, 253, nil, 40, nil, nil, 33, nil, nil, 58,
- 59, nil, nil, 60, nil, 35, 235, nil, 241, 44,
- 237, 236, nil, 233, 234, 245, 243, 239, 20, 240,
- nil, nil, nil, 89, 79, 82, 83, nil, 84, 86,
- 85, 87, nil, nil, nil, nil, 80, 88, 218, 256,
- nil, nil, nil, nil, 62, nil, 81, 93, 94, 5,
- 69, 70, 71, 9, 57, nil, nil, nil, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 19, nil, nil, nil,
- nil, nil, 8, 45, 7, 10, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, 238, 242, 247, 248, 249,
- 244, 246, 254, 255, 250, 251, nil, 231, 232, nil,
- nil, 252, 253, nil, 40, nil, nil, 33, nil, nil,
- 58, 59, nil, nil, 60, nil, 35, 235, nil, 241,
- 44, 237, 236, nil, 233, 234, 245, 243, 239, 20,
- 240, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- 256, nil, nil, nil, nil, 62, nil, 81, 93, 94,
- 290, 69, 70, 71, 9, 57, nil, nil, nil, 63,
- 64, nil, nil, nil, 67, nil, 65, 66, 68, 30,
- 31, 72, 73, nil, nil, nil, nil, nil, 29, 28,
- 27, 101, 100, 102, 103, nil, nil, 19, nil, nil,
- nil, nil, nil, 8, 45, 292, 10, 105, 104, 106,
- 95, 56, 97, 96, 98, nil, 99, 107, 108, nil,
- 91, 92, nil, 42, 43, 41, 238, 242, 247, 248,
- 249, 244, 246, 254, 255, 250, 251, nil, 231, 232,
- nil, nil, 252, 253, nil, 40, nil, nil, 33, nil,
- nil, 58, 59, nil, nil, 60, nil, 35, 235, nil,
- 241, 44, 237, 236, nil, 233, 234, 245, 243, 239,
- 20, 240, nil, nil, nil, 89, 79, 82, 83, nil,
- 84, 86, 85, 87, nil, nil, nil, nil, 80, 88,
- nil, 256, nil, nil, nil, nil, 62, nil, 81, 93,
- 94, 290, 69, 70, 71, 9, 57, nil, nil, nil,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, 8, 45, 292, 10, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, 238, 242, 247,
- 248, 249, 244, 246, 254, 255, 250, 251, nil, 231,
- 232, nil, nil, 252, 253, nil, 40, nil, nil, 33,
- nil, nil, 58, 59, nil, nil, 60, nil, 35, 235,
- nil, 241, 44, 237, 236, nil, 233, 234, 245, 243,
- 239, 20, 240, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, 256, nil, nil, nil, nil, 62, nil, 81,
- 93, 94, 290, 69, 70, 71, 9, 57, nil, nil,
- nil, 63, 64, nil, nil, nil, 67, nil, 65, 66,
- 68, 30, 31, 72, 73, nil, nil, nil, nil, nil,
- 29, 28, 27, 101, 100, 102, 103, nil, nil, 19,
- nil, nil, nil, nil, nil, 8, 45, 292, 10, 105,
- 104, 106, 95, 56, 97, 96, 98, nil, 99, 107,
- 108, nil, 91, 92, nil, 42, 43, 41, 238, 242,
- 247, 248, 249, 244, 246, 254, 255, 250, 251, nil,
- 231, 232, nil, nil, 252, 253, nil, 40, nil, nil,
- 33, nil, nil, 58, 59, nil, nil, 60, nil, 35,
- 235, nil, 241, 44, 237, 236, nil, 233, 234, 245,
- 243, 239, 20, 240, nil, nil, nil, 89, 79, 82,
- 83, nil, 84, 86, 85, 87, nil, nil, nil, nil,
- 80, 88, nil, 256, nil, nil, nil, nil, 62, nil,
- 81, 93, 94, 290, 69, 70, 71, 9, 57, nil,
- nil, nil, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 19, nil, nil, nil, nil, nil, 8, 45, 292, 10,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, 238,
- 242, 247, 248, 249, 244, 246, 254, 255, 250, 251,
- nil, 231, 232, nil, nil, 252, 253, nil, 40, nil,
- nil, 33, nil, nil, 58, 59, nil, nil, 60, nil,
- 35, 235, nil, 241, 44, 237, 236, nil, 233, 234,
- 245, 243, 239, 20, 240, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, 256, nil, nil, nil, nil, 62,
- nil, 81, 93, 94, 290, 69, 70, 71, 9, 57,
- nil, nil, nil, 63, 64, nil, nil, nil, 67, nil,
- 65, 66, 68, 30, 31, 72, 73, nil, nil, nil,
- nil, nil, 29, 28, 27, 101, 100, 102, 103, nil,
- nil, 19, nil, nil, nil, nil, nil, 8, 45, 292,
- 10, 105, 104, 106, 95, 56, 97, 96, 98, nil,
- 99, 107, 108, nil, 91, 92, nil, 42, 43, 41,
- 238, 242, 247, 248, 249, 244, 246, 254, 255, 250,
- 251, nil, 231, 232, nil, nil, 252, 253, nil, 40,
- nil, nil, 33, nil, nil, 58, 59, nil, nil, 60,
- nil, 35, 235, nil, 241, 44, 237, 236, nil, 233,
- 234, 245, 243, 239, 20, 240, nil, nil, nil, 89,
- 79, 82, 83, nil, 84, 86, 85, 87, nil, nil,
- nil, nil, 80, 88, nil, 256, nil, nil, nil, nil,
- 62, nil, 81, 93, 94, 290, 69, 70, 71, 9,
- 57, nil, nil, nil, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 19, nil, nil, nil, nil, nil, 8, 45,
- 292, 10, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, 238, 242, 247, 248, 249, 244, 246, 254, 255,
- 250, 251, nil, 231, 232, nil, nil, 252, 253, nil,
- 40, nil, nil, 33, nil, nil, 58, 59, nil, nil,
- 60, nil, 35, 235, nil, 241, 44, 237, 236, nil,
- 233, 234, 245, 243, 239, 20, 240, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, 256, nil, nil, nil,
- nil, 62, nil, 81, 93, 94, 290, 69, 70, 71,
- 9, 57, nil, nil, nil, 63, 64, nil, nil, nil,
- 67, nil, 65, 66, 68, 30, 31, 72, 73, nil,
- nil, nil, nil, nil, 29, 28, 27, 101, 100, 102,
- 103, nil, nil, 19, nil, nil, nil, nil, nil, 8,
- 45, 292, 10, 105, 104, 106, 95, 56, 97, 96,
- 98, nil, 99, 107, 108, nil, 91, 92, nil, 42,
- 43, 41, 238, 242, 247, 248, 249, 244, 246, 254,
- 255, 250, 251, nil, 231, 232, nil, nil, 252, 253,
- nil, 40, nil, nil, 33, nil, nil, 58, 59, nil,
- nil, 60, nil, 35, 235, nil, 241, 44, 237, 236,
- nil, 233, 234, 245, 243, 239, 20, 240, nil, nil,
- nil, 89, 79, 82, 83, nil, 84, 86, 85, 87,
- nil, nil, nil, nil, 80, 88, nil, 256, nil, nil,
- nil, nil, 62, nil, 81, 93, 94, 290, 69, 70,
- 71, 9, 57, nil, nil, nil, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 19, nil, nil, nil, nil, nil,
- 8, 45, 292, 10, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, 238, 242, 247, 248, 249, 244, 246,
- 254, 255, 250, 251, nil, 231, 232, nil, nil, 252,
- 253, nil, 40, nil, nil, 33, nil, nil, 58, 59,
- nil, nil, 60, nil, 35, 235, nil, 241, 44, 237,
- 236, nil, 233, 234, 245, 243, 239, 20, 240, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, 256, nil,
- nil, nil, nil, 62, nil, 81, 93, 94, 290, 69,
- 70, 71, 9, 57, nil, nil, nil, 63, 64, nil,
- nil, nil, 67, nil, 65, 66, 68, 30, 31, 72,
- 73, nil, nil, nil, nil, nil, 29, 28, 27, 101,
- 100, 102, 103, nil, nil, 19, nil, nil, nil, nil,
- nil, 8, 45, 292, 10, 105, 104, 106, 95, 56,
- 97, 96, 98, nil, 99, 107, 108, nil, 91, 92,
- nil, 42, 43, 41, 238, 242, 247, 248, 249, 244,
- 246, 254, 255, 250, 251, nil, -597, -597, nil, nil,
- 252, 253, nil, 40, nil, nil, 33, nil, nil, 58,
- 59, nil, nil, 60, nil, 35, 235, nil, 241, 44,
- 237, 236, nil, 233, 234, 245, 243, 239, 20, 240,
- nil, nil, nil, 89, 79, 82, 83, nil, 84, 86,
- 85, 87, nil, nil, nil, nil, 80, 88, nil, nil,
- nil, nil, nil, nil, 62, nil, 81, 93, 94, 290,
- 69, 70, 71, 9, 57, nil, nil, nil, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 19, nil, nil, nil,
- nil, nil, 8, 45, 292, 10, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, 238, 242, 247, 248, 249,
- 244, 246, 254, 255, 250, 251, nil, -597, -597, nil,
- nil, 252, 253, nil, 40, nil, nil, 33, nil, nil,
- 58, 59, nil, nil, 60, nil, 35, 235, nil, 241,
- 44, 237, 236, nil, 233, 234, 245, 243, 239, 20,
- 240, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, nil, nil, nil, 62, nil, 81, 93, 94,
- 290, 69, 70, 71, 9, 57, nil, nil, nil, 63,
- 64, nil, nil, nil, 67, nil, 65, 66, 68, 30,
- 31, 72, 73, nil, nil, nil, nil, nil, 29, 28,
- 27, 101, 100, 102, 103, nil, 548, 19, 545, 544,
- 543, nil, 546, 8, 45, 292, 10, 105, 104, 106,
- 95, 56, 97, 96, 98, nil, 99, 107, 108, nil,
- 91, 92, nil, 42, 43, 41, 238, -597, -597, -597,
- -597, 244, 246, nil, 701, -597, -597, nil, nil, nil,
- nil, nil, 252, 253, nil, 40, nil, nil, 33, nil,
- nil, 58, 59, nil, nil, 60, nil, 35, 235, nil,
- 241, 44, 237, 236, nil, 233, 234, 245, 243, 239,
- 20, 240, nil, nil, nil, 89, 79, 82, 83, nil,
- 84, 86, 85, 87, nil, nil, nil, nil, 80, 88,
- nil, nil, nil, nil, nil, nil, 62, nil, 81, 93,
- 94, 290, 69, 70, 71, 9, 57, nil, nil, nil,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, 548, 19, 545,
- 544, 543, nil, 546, 8, 45, 292, 10, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, 238, nil, nil,
- 548, nil, 545, 544, 543, 701, 546, nil, nil, nil,
- nil, nil, nil, 252, 253, nil, 40, nil, nil, 33,
- nil, nil, 58, 59, nil, nil, 60, nil, 35, 235,
- nil, 241, 44, 237, 236, nil, 233, 234, 701, nil,
- 239, 20, 240, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, nil, nil, nil, 62, nil, 81,
- 93, 94, 290, 69, 70, 71, 9, 57, nil, nil,
- nil, 63, 64, nil, nil, nil, 67, nil, 65, 66,
- 68, 30, 31, 72, 73, nil, nil, nil, nil, nil,
- 29, 28, 27, 101, 100, 102, 103, nil, 548, 19,
- 545, 544, 543, nil, 546, 8, 45, 292, 10, 105,
- 104, 106, 95, 56, 97, 96, 98, nil, 99, 107,
- 108, nil, 91, 92, nil, 42, 43, 41, 238, nil,
- nil, nil, nil, nil, nil, nil, 701, nil, nil, nil,
- nil, nil, nil, nil, 252, 253, nil, 40, nil, nil,
- 33, nil, nil, 58, 59, nil, nil, 60, nil, 35,
- 235, nil, 241, 44, 237, 236, nil, 233, 234, nil,
- nil, 239, 20, 240, nil, nil, nil, 89, 79, 82,
- 83, nil, 84, 86, 85, 87, nil, nil, nil, nil,
- 80, 88, nil, nil, nil, nil, nil, nil, 62, nil,
- 81, 93, 94, 290, 69, 70, 71, 9, 57, nil,
- nil, nil, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 19, nil, nil, nil, nil, nil, 8, 45, 292, 10,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, 238,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 252, 253, nil, 40, nil,
- nil, 33, nil, nil, 58, 59, nil, nil, 60, nil,
- 35, 235, nil, 241, 44, 237, 236, nil, 233, 234,
- nil, nil, 239, 20, 240, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, nil, nil, nil, 62,
- nil, 81, 93, 94, 290, 69, 70, 71, 9, 57,
- nil, nil, nil, 63, 64, nil, nil, nil, 67, nil,
- 65, 66, 68, 30, 31, 72, 73, nil, nil, nil,
- nil, nil, 29, 28, 27, 101, 100, 102, 103, nil,
- nil, 19, nil, nil, nil, nil, nil, 8, 45, 292,
- 10, 105, 104, 106, 95, 56, 97, 96, 98, nil,
- 99, 107, 108, nil, 91, 92, nil, 42, 43, 41,
- 238, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 252, 253, nil, 40,
- nil, nil, 33, nil, nil, 58, 59, nil, nil, 60,
- nil, 35, 235, nil, 241, 44, 237, 236, nil, 233,
- 234, nil, nil, 239, 20, 240, nil, nil, nil, 89,
- 79, 82, 83, nil, 84, 86, 85, 87, nil, nil,
- nil, nil, 80, 88, nil, nil, nil, nil, nil, nil,
- 62, nil, 81, 93, 94, 290, 69, 70, 71, 9,
- 57, nil, nil, nil, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 19, nil, nil, nil, nil, nil, 8, 45,
- 292, 10, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, 238, -597, -597, -597, -597, 244, 246, nil, nil,
- -597, -597, nil, nil, nil, nil, nil, 252, 253, nil,
- 40, nil, nil, 33, nil, nil, 58, 59, nil, nil,
- 60, nil, 35, 235, nil, 241, 44, 237, 236, nil,
- 233, 234, 245, 243, 239, 20, 240, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, nil, nil,
- nil, 62, nil, 81, 93, 94, 290, 69, 70, 71,
- 9, 57, nil, nil, nil, 63, 64, nil, nil, nil,
- 67, nil, 65, 66, 68, 30, 31, 72, 73, nil,
- nil, nil, nil, nil, 29, 28, 27, 101, 100, 102,
- 103, nil, nil, 19, nil, nil, nil, nil, nil, 8,
- 45, 292, 10, 105, 104, 106, 95, 56, 97, 96,
- 98, nil, 99, 107, 108, nil, 91, 92, nil, 42,
- 43, 41, 238, -597, -597, -597, -597, 244, 246, nil,
- nil, -597, -597, nil, nil, nil, nil, nil, 252, 253,
- nil, 40, nil, nil, 33, nil, nil, 58, 59, nil,
- nil, 60, nil, 35, 235, nil, 241, 44, 237, 236,
- nil, 233, 234, 245, 243, 239, 20, 240, nil, nil,
- nil, 89, 79, 82, 83, nil, 84, 86, 85, 87,
- nil, nil, nil, nil, 80, 88, nil, nil, nil, nil,
- nil, nil, 62, nil, 81, 93, 94, 290, 69, 70,
- 71, 9, 57, nil, nil, nil, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 19, nil, nil, nil, nil, nil,
- 8, 45, 292, 10, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, 238, -597, -597, -597, -597, 244, 246,
- nil, nil, -597, -597, nil, nil, nil, nil, nil, 252,
- 253, nil, 40, nil, nil, 33, nil, nil, 58, 59,
- nil, nil, 60, nil, 35, 235, nil, 241, 44, 237,
- 236, nil, 233, 234, 245, 243, 239, 20, 240, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- nil, nil, nil, 62, nil, 81, 93, 94, 290, 69,
- 70, 71, 9, 57, nil, nil, nil, 63, 64, nil,
- nil, nil, 67, nil, 65, 66, 68, 30, 31, 72,
- 73, nil, nil, nil, nil, nil, 29, 28, 27, 101,
- 100, 102, 103, nil, nil, 19, nil, nil, nil, nil,
- nil, 8, 45, 292, 10, 105, 104, 106, 95, 56,
- 97, 96, 98, nil, 99, 107, 108, nil, 91, 92,
- nil, 42, 43, 41, 238, -597, -597, -597, -597, 244,
- 246, nil, nil, -597, -597, nil, nil, nil, nil, nil,
- 252, 253, nil, 40, nil, nil, 33, nil, nil, 58,
- 59, nil, nil, 60, nil, 35, 235, nil, 241, 44,
- 237, 236, nil, 233, 234, 245, 243, 239, 20, 240,
- nil, nil, nil, 89, 79, 82, 83, nil, 84, 86,
- 85, 87, nil, nil, nil, nil, 80, 88, nil, nil,
- nil, nil, nil, nil, 62, nil, 81, 93, 94, 290,
- 69, 70, 71, 9, 57, nil, nil, nil, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 19, nil, nil, nil,
- nil, nil, 8, 45, 292, 10, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, 238, -597, -597, -597, -597,
- 244, 246, nil, nil, -597, -597, nil, nil, nil, nil,
- nil, 252, 253, nil, 40, nil, nil, 33, nil, nil,
- 58, 59, nil, nil, 60, nil, 35, 235, nil, 241,
- 44, 237, 236, nil, 233, 234, 245, 243, 239, 20,
- 240, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, nil, nil, nil, 62, nil, 81, 93, 94,
- 290, 69, 70, 71, 9, 57, nil, nil, nil, 63,
- 64, nil, nil, nil, 67, nil, 65, 66, 68, 30,
- 31, 72, 73, nil, nil, nil, nil, nil, 29, 28,
- 27, 101, 100, 102, 103, nil, nil, 19, nil, nil,
- nil, nil, nil, 8, 45, 292, 10, 105, 104, 106,
- 95, 56, 97, 96, 98, nil, 99, 107, 108, nil,
- 91, 92, nil, 42, 43, 41, 238, 242, 247, 248,
- 249, 244, 246, nil, nil, 250, 251, nil, nil, nil,
- nil, nil, 252, 253, nil, 40, nil, nil, 33, nil,
- nil, 58, 59, nil, nil, 60, nil, 35, 235, nil,
- 241, 44, 237, 236, nil, 233, 234, 245, 243, 239,
- 20, 240, nil, nil, nil, 89, 79, 82, 83, nil,
- 84, 86, 85, 87, nil, nil, nil, nil, 80, 88,
- nil, nil, nil, nil, nil, nil, 62, nil, 81, 93,
- 94, 290, 69, 70, 71, 9, 57, nil, nil, nil,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, 8, 45, 292, 10, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, 238, 242, 247,
- 248, 249, 244, 246, 254, nil, 250, 251, nil, nil,
- nil, nil, nil, 252, 253, nil, 40, nil, nil, 33,
- nil, nil, 58, 59, nil, nil, 60, nil, 35, 235,
- nil, 241, 44, 237, 236, nil, 233, 234, 245, 243,
- 239, 20, 240, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, nil, nil, nil, 62, nil, 81,
- 93, 94, 69, 70, 71, 9, 57, nil, nil, nil,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, 8, 45, 7, 10, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, 238, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 252, 253, nil, 40, nil, nil, 33,
- nil, nil, 58, 59, nil, nil, 60, nil, 35, 235,
- nil, 241, 44, 237, 236, nil, 233, 234, nil, nil,
- nil, 20, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, 238,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 252, 253, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, 235, nil, 241, 44, 237, 236, nil, 233, 234,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- 284, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, 238, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 252, 253, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, 281, 235, 279, nil, 44, 237, 236, 285,
- 233, 234, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 282, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, 284, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, 281, nil, 279, nil, 44, nil,
- nil, 285, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 282, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, 284, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, 281, nil, 279, nil,
- 44, nil, nil, 285, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 282, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 307, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, nil, nil, 313, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 303, nil, nil, 299,
- nil, nil, 58, 59, nil, nil, 60, nil, 298, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 307, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, nil, nil, 313, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 303, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- 548, nil, 545, 544, 543, 553, 546, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 556, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 315, nil, 551, 62,
- nil, 81, 93, 94, 69, 70, 71, nil, 57, 564,
- 563, nil, 63, 64, 557, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, 284, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, 281, nil, nil, nil,
- 44, nil, nil, 285, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 282, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, 284, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, 285, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 282, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 19, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 20, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 19, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 20, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 19, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 20, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, 113, nil, nil,
- nil, nil, 112, 62, nil, 81, 93, 94, 69, 70,
- 71, nil, 57, nil, nil, nil, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 307, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- nil, nil, 313, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 348, nil, nil, 33, nil, nil, 58, 59,
- nil, nil, 60, nil, 35, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 307, nil, nil, 105, 104, 106, 353,
- 56, 97, 96, 354, nil, 99, 107, 108, nil, 91,
- 92, nil, nil, nil, 313, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 360, nil, nil, 355, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 307, nil, nil, 105, 104,
- 106, 353, 56, 97, 96, 354, nil, 99, 107, 108,
- nil, 91, 92, nil, nil, nil, 313, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 355, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, 548, nil,
- 545, 544, 543, 553, 546, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 556, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, nil, nil, 551, 62, nil, 81,
- 93, 94, 69, 70, 71, 9, 57, 564, 563, nil,
- 63, 64, 557, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, 8, 45, 7, 10, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 40, nil, nil, 33,
- nil, nil, 58, 59, nil, nil, 60, nil, 35, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 20, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, nil, nil, 388, 62, nil, 81,
- 93, 94, 69, 70, 71, nil, 57, nil, nil, nil,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 20, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 19, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 20, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 19, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 20, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 19, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 20, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- nil, nil, nil, 62, nil, 81, 93, 94, 69, 70,
- 71, 9, 57, nil, nil, nil, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 19, nil, nil, nil, nil, nil,
- 8, 45, nil, 10, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 40, nil, nil, 33, nil, nil, 58, 59,
- nil, nil, 60, nil, 35, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 20, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, 404, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, 284, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- 281, nil, 279, nil, 44, nil, nil, 285, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 282,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, 404, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 19, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 20,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 20, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 19, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 20, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 19, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 20, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, 218, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, 284, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, 281, nil, 279, nil,
- 44, nil, nil, 285, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 282, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, 284, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, 281, nil,
- 279, nil, 44, nil, nil, 285, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 282, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, 284, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- 281, nil, 279, nil, 44, nil, nil, 285, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 282,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, 218, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, nil, nil, nil, 62, nil, 81,
- 93, 94, 69, 70, 71, 9, 57, nil, nil, nil,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, 8, 45, nil, 10, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 40, nil, nil, 33,
- nil, nil, 58, 59, nil, nil, 60, nil, 35, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 20, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 307, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, nil, nil, 313, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 303, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- 548, nil, 545, 544, 543, 553, 546, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 556, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 504, nil, 551, 62,
- nil, 81, 93, 94, 69, 70, 71, nil, 57, 564,
- 563, nil, 63, 64, 557, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 307, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, nil, nil, 313, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 303, nil,
- nil, 299, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, 520, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 19, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 20, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 19, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 20,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 20, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 19, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 20, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 19, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 20, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, 284, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, 281, nil, 279, nil,
- 44, nil, nil, 285, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 282, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, 284, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, 659, nil, 279, nil,
- 44, nil, nil, 285, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 282, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, 284, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- 279, nil, 44, nil, nil, 285, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 282, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, nil, nil, nil, 62,
- nil, 81, 93, 94, 69, 70, 71, 9, 57, nil,
- nil, nil, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 19, nil, nil, nil, nil, nil, 8, 45, 292, 10,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 40, nil,
- nil, 33, nil, nil, 58, 59, nil, nil, 60, nil,
- 35, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 20, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, nil, nil, 388, 62,
- nil, 81, 93, 94, 69, 70, 71, nil, 57, nil,
- nil, nil, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 307, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, nil, nil, 313, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 303, nil,
- nil, 299, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- 284, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, 281, nil, 279, nil, 44, nil, nil, 285,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 282, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 307, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- nil, nil, 313, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 303, nil, nil, 299, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 19, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 20, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- 284, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, 659, nil, nil, nil, 44, nil, nil, 285,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 282, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, 284, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, 285, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 282, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, 281, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, 284, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- 281, nil, 279, nil, 44, nil, nil, 285, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 282,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- 284, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, 281, nil, 279, nil, 44, nil, nil, 285,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 282, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, 754, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, 284, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, 659, nil,
- 279, nil, 44, nil, nil, 285, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 282, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, 284, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, 279, nil, 44, nil, nil, 285, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 282,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 30, 31, 72, 73, nil, nil, nil, nil,
- nil, 29, 28, 27, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 307, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, nil, nil, 313, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 303, nil, nil, 299,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 307, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, nil, nil, 313, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 303, nil,
- nil, 299, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, 404, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 30, 31,
- 72, 73, nil, nil, nil, nil, nil, 29, 28, 27,
- 101, 100, 102, 103, nil, nil, 19, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 20,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 19, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 20, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 30, 31, 72, 73, nil, nil,
- nil, nil, nil, 29, 28, 27, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 45,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, 42, 43,
- 41, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 223, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, 44, nil, nil, nil,
- nil, nil, nil, nil, nil, 228, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, nil, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- nil, nil, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 79, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 307,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, nil, nil,
- 313, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 876, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 30, 31, 72, 73,
- nil, nil, nil, nil, nil, 29, 28, 27, 101, 100,
- 102, 103, nil, nil, 19, nil, nil, nil, nil, nil,
- nil, 45, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- 42, 43, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 223, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 20, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, 659, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 309, 310, 72, 73, nil, nil, nil, nil, nil, 305,
- 306, 312, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, 284, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, nil, nil,
- 279, nil, 44, nil, nil, 285, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 282, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, 69, 70, 71, 62, 57, 81,
- 93, 94, 63, 64, nil, nil, nil, 67, nil, 65,
- 66, 68, 309, 310, 72, 73, nil, nil, nil, nil,
- nil, 305, 306, 312, 101, 100, 102, 103, nil, nil,
- 230, nil, nil, nil, nil, nil, nil, 45, nil, nil,
- 105, 104, 106, 95, 56, 97, 96, 98, nil, 99,
- 107, 108, nil, 91, 92, nil, 42, 43, 41, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 223, nil,
- nil, 229, nil, nil, 58, 59, nil, nil, 60, nil,
- nil, nil, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, nil, nil, 228, nil, nil, nil, nil, 89, 79,
- 82, 83, nil, 84, 86, 85, 87, nil, nil, nil,
- nil, 80, 88, nil, nil, nil, 69, 70, 71, 62,
- 57, 81, 93, 94, 63, 64, nil, nil, nil, 67,
- nil, 65, 66, 68, 309, 310, 72, 73, nil, nil,
- nil, nil, nil, 305, 306, 312, 101, 100, 102, 103,
- nil, nil, 230, nil, nil, nil, nil, nil, nil, 307,
- nil, nil, 105, 104, 106, 95, 56, 97, 96, 98,
- nil, 99, 107, 108, nil, 91, 92, nil, nil, nil,
- 313, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 876, nil, nil, 229, nil, nil, 58, 59, nil, nil,
- 60, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 89, 79, 82, 83, nil, 84, 86, 85, 87, nil,
- nil, nil, nil, 80, 88, nil, nil, nil, 69, 70,
- 71, 62, 57, 81, 93, 94, 63, 64, nil, nil,
- nil, 67, nil, 65, 66, 68, 309, 310, 72, 73,
- nil, nil, nil, nil, nil, 305, 306, 312, 101, 100,
- 102, 103, nil, nil, 230, nil, nil, nil, nil, nil,
- nil, 307, nil, nil, 105, 104, 106, 95, 56, 97,
- 96, 98, nil, 99, 107, 108, nil, 91, 92, nil,
- nil, nil, 313, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 947, nil, nil, 229, nil, nil, 58, 59,
- nil, nil, 60, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 89, 79, 82, 83, nil, 84, 86, 85,
- 87, nil, nil, nil, nil, 80, 88, nil, nil, nil,
- 69, 70, 71, 62, 57, 81, 93, 94, 63, 64,
- nil, nil, nil, 67, nil, 65, 66, 68, 309, 310,
- 72, 73, nil, nil, nil, nil, nil, 305, 306, 312,
- 101, 100, 102, 103, nil, nil, 230, nil, nil, nil,
- nil, nil, nil, 45, nil, nil, 105, 104, 106, 95,
- 56, 97, 96, 98, nil, 99, 107, 108, nil, 91,
- 92, nil, 42, 43, 41, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 223, nil, nil, 229, nil, nil,
- 58, 59, nil, nil, 60, nil, nil, nil, nil, nil,
- 44, nil, nil, nil, nil, nil, nil, nil, nil, 228,
- nil, nil, nil, nil, 89, 79, 82, 83, nil, 84,
- 86, 85, 87, nil, nil, nil, nil, 80, 88, nil,
- nil, nil, 69, 70, 71, 62, 57, 81, 93, 94,
- 63, 64, nil, nil, nil, 67, nil, 65, 66, 68,
- 30, 31, 72, 73, nil, nil, nil, nil, nil, 29,
- 28, 27, 101, 100, 102, 103, nil, nil, 230, nil,
- nil, nil, nil, nil, nil, 45, nil, nil, 105, 104,
- 106, 95, 56, 97, 96, 98, 284, 99, 107, 108,
- nil, 91, 92, nil, 42, 43, 41, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 223, nil, nil, 229,
- nil, nil, 58, 59, nil, nil, 60, nil, 281, nil,
- 279, nil, 44, nil, nil, 285, nil, nil, nil, nil,
- nil, 228, nil, nil, nil, nil, 89, 282, 82, 83,
- nil, 84, 86, 85, 87, nil, nil, nil, nil, 80,
- 88, nil, nil, nil, nil, -282, nil, 62, nil, 81,
- 93, 94, -282, -282, -282, nil, nil, -282, -282, -282,
- nil, -282, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, -282, -282, -282, nil, nil, nil, nil, nil, nil,
- nil, -282, -282, nil, -282, -282, -282, -282, -282, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, -282, -282, -282, -282, -282, -282, -282, -282,
- -282, -282, -282, -282, -282, -282, nil, nil, -282, -282,
- -282, nil, nil, -282, nil, nil, -282, nil, nil, -282,
- -282, nil, -282, nil, -282, nil, -282, nil, -282, -282,
- nil, -282, -282, -282, -282, -282, nil, -282, nil, -282,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -282, nil, nil, -282, -282, -282, -282,
- -579, -282, nil, -282, nil, nil, nil, -579, -579, -579,
- nil, nil, -579, -579, -579, nil, -579, nil, nil, nil,
- nil, nil, nil, nil, nil, -579, -579, -579, -579, nil,
- nil, nil, nil, nil, nil, nil, -579, -579, nil, -579,
- -579, -579, -579, -579, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, -579, -579, -579,
- -579, -579, -579, -579, -579, -579, -579, -579, -579, -579,
- -579, nil, nil, -579, -579, -579, nil, nil, -579, nil,
- nil, -579, nil, nil, -579, -579, nil, -579, nil, -579,
- nil, -579, nil, -579, -579, nil, -579, -579, -579, -579,
- -579, nil, -579, -579, -579, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, -579, nil,
- nil, -579, -579, -579, -579, -580, -579, nil, -579, nil,
- nil, nil, -580, -580, -580, nil, nil, -580, -580, -580,
- nil, -580, nil, nil, nil, nil, nil, nil, nil, nil,
- -580, -580, -580, -580, nil, nil, nil, nil, nil, nil,
- nil, -580, -580, nil, -580, -580, -580, -580, -580, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, -580, -580, -580, -580, -580, -580, -580, -580,
- -580, -580, -580, -580, -580, -580, nil, nil, -580, -580,
- -580, nil, nil, -580, nil, nil, -580, nil, nil, -580,
- -580, nil, -580, nil, -580, nil, -580, nil, -580, -580,
- nil, -580, -580, -580, -580, -580, nil, -580, -580, -580,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, -580, nil, nil, -580, -580, -580, -580,
- -411, -580, nil, -580, nil, nil, nil, -411, -411, -411,
- nil, nil, -411, -411, -411, nil, -411, nil, nil, nil,
- nil, nil, nil, nil, nil, -411, -411, -411, nil, nil,
- nil, nil, nil, nil, nil, nil, -411, -411, nil, -411,
- -411, -411, -411, -411, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, -411, -411, -411,
- -411, -411, -411, -411, -411, -411, -411, -411, -411, -411,
- -411, nil, nil, -411, -411, -411, nil, nil, -411, nil,
- 263, -411, nil, nil, -411, -411, nil, -411, nil, -411,
- nil, -411, nil, -411, -411, nil, -411, -411, -411, -411,
- -411, -298, -411, -411, -411, nil, nil, nil, -298, -298,
- -298, nil, nil, -298, -298, -298, nil, -298, -411, nil,
- nil, -411, -411, nil, -411, nil, -411, -298, -298, nil,
- nil, nil, nil, nil, nil, nil, nil, -298, -298, nil,
- -298, -298, -298, -298, -298, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, -298, -298,
- -298, -298, -298, -298, -298, -298, -298, -298, -298, -298,
- -298, -298, nil, nil, -298, -298, -298, nil, nil, -298,
- nil, 272, -298, nil, nil, -298, -298, nil, -298, nil,
- -298, nil, -298, nil, -298, -298, nil, -298, -298, -298,
- -298, -298, nil, -298, -246, -298, nil, nil, nil, nil,
- nil, -246, -246, -246, nil, nil, -246, -246, -246, -298,
- -246, nil, -298, -298, nil, -298, nil, -298, nil, -246,
- -246, -246, nil, nil, nil, nil, nil, nil, nil, nil,
- -246, -246, nil, -246, -246, -246, -246, -246, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, -246, -246, -246, -246, -246, -246, -246, -246, -246,
- -246, -246, -246, -246, -246, nil, nil, -246, -246, -246,
- nil, nil, -246, nil, 263, -246, nil, nil, -246, -246,
- nil, -246, nil, -246, nil, -246, nil, -246, -246, nil,
- -246, -246, -246, -246, -246, nil, -246, -246, -246, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, -246, nil, -246, -246, -246, nil, -246, nil,
- -246, -246, -246, -246, nil, nil, -246, -246, -246, 548,
- -246, 545, 544, 543, 553, 546, nil, nil, nil, -246,
- -246, nil, nil, nil, nil, 556, nil, nil, nil, nil,
- -246, -246, nil, -246, -246, -246, -246, -246, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 551, 548, nil,
- 545, 544, 543, 553, 546, nil, 561, 560, 564, 563,
- nil, nil, nil, 557, 556, 548, nil, 545, 544, 543,
- 553, 546, -246, nil, nil, nil, nil, nil, nil, -246,
- nil, 556, nil, nil, 263, -246, 551, 534, nil, 218,
- nil, nil, nil, nil, nil, 561, 560, 564, 563, nil,
- nil, nil, 557, 551, nil, nil, nil, -246, -246, nil,
- nil, nil, 561, 560, 564, 563, nil, nil, nil, 557,
- nil, nil, -246, nil, nil, -246, nil, nil, nil, nil,
- -246, 173, 184, 174, 197, 170, 190, 180, 179, 200,
- 201, 195, 178, 177, 172, 198, 202, 203, 182, 171,
- 185, 189, 191, 183, 176, nil, nil, nil, 192, 199,
- 194, 193, 186, 196, 181, 169, 188, 187, nil, nil,
- nil, nil, nil, 168, 175, 166, 167, 163, 164, 165,
- 124, 126, 123, nil, 125, nil, nil, nil, nil, nil,
- nil, nil, nil, 157, 158, nil, 154, 136, 137, 138,
- 145, 142, 144, nil, nil, 139, 140, nil, nil, nil,
- 159, 160, 146, 147, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 151, 150, nil,
- 135, 156, 153, 152, 161, 148, 149, 143, 141, 133,
- 155, 134, nil, nil, 162, 89, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 88,
- 173, 184, 174, 197, 170, 190, 180, 179, 200, 201,
- 195, 178, 177, 172, 198, 202, 203, 182, 171, 185,
- 189, 191, 183, 176, nil, nil, nil, 192, 199, 194,
- 193, 186, 196, 181, 169, 188, 187, nil, nil, nil,
- nil, nil, 168, 175, 166, 167, 163, 164, 165, 124,
- 126, nil, nil, 125, nil, nil, nil, nil, nil, nil,
- nil, nil, 157, 158, nil, 154, 136, 137, 138, 145,
- 142, 144, nil, nil, 139, 140, nil, nil, nil, 159,
- 160, 146, 147, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 151, 150, nil, 135,
- 156, 153, 152, 161, 148, 149, 143, 141, 133, 155,
- 134, nil, nil, 162, 89, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 88, 173,
- 184, 174, 197, 170, 190, 180, 179, 200, 201, 195,
- 178, 177, 172, 198, 202, 203, 182, 171, 185, 189,
- 191, 183, 176, nil, nil, nil, 192, 199, 194, 193,
- 186, 196, 181, 169, 188, 187, nil, nil, nil, nil,
- nil, 168, 175, 166, 167, 163, 164, 165, 124, 126,
- nil, nil, 125, nil, nil, nil, nil, nil, nil, nil,
- nil, 157, 158, nil, 154, 136, 137, 138, 145, 142,
- 144, nil, nil, 139, 140, nil, nil, nil, 159, 160,
- 146, 147, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 151, 150, nil, 135, 156,
- 153, 152, 161, 148, 149, 143, 141, 133, 155, 134,
- nil, nil, 162, 89, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 88, 173, 184,
- 174, 197, 170, 190, 180, 179, 200, 201, 195, 178,
- 177, 172, 198, 202, 203, 182, 171, 185, 189, 191,
- 183, 176, nil, nil, nil, 192, 199, 194, 193, 186,
- 196, 181, 169, 188, 187, nil, nil, nil, nil, nil,
- 168, 175, 166, 167, 163, 164, 165, 124, 126, nil,
- nil, 125, nil, nil, nil, nil, nil, nil, nil, nil,
- 157, 158, nil, 154, 136, 137, 138, 145, 142, 144,
- nil, nil, 139, 140, nil, nil, nil, 159, 160, 146,
- 147, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 151, 150, nil, 135, 156, 153,
- 152, 161, 148, 149, 143, 141, 133, 155, 134, nil,
- nil, 162, 89, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 88, 173, 184, 174,
- 197, 170, 190, 180, 179, 200, 201, 195, 178, 177,
- 172, 198, 202, 203, 182, 171, 185, 189, 191, 183,
- 176, nil, nil, nil, 192, 199, 194, 371, 370, 372,
- 369, 169, 188, 187, nil, nil, nil, nil, nil, 168,
- 175, 166, 167, 366, 367, 368, 364, 126, 97, 96,
- 365, nil, 99, nil, nil, nil, nil, nil, nil, 157,
- 158, nil, 154, 136, 137, 138, 145, 142, 144, nil,
- nil, 139, 140, nil, nil, nil, 159, 160, 146, 147,
- nil, nil, nil, nil, nil, 376, nil, nil, nil, nil,
- nil, nil, nil, 151, 150, nil, 135, 156, 153, 152,
- 161, 148, 149, 143, 141, 133, 155, 134, nil, nil,
- 162, 173, 184, 174, 197, 170, 190, 180, 179, 200,
- 201, 195, 178, 177, 172, 198, 202, 203, 182, 171,
- 185, 189, 191, 183, 176, nil, nil, nil, 192, 199,
- 194, 193, 186, 196, 181, 169, 188, 187, nil, nil,
- nil, nil, nil, 168, 175, 166, 167, 163, 164, 165,
- 124, 126, nil, nil, 125, nil, nil, nil, nil, nil,
- nil, nil, nil, 157, 158, nil, 154, 136, 137, 138,
- 145, 142, 144, nil, nil, 139, 140, nil, nil, nil,
- 159, 160, 146, 147, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 151, 150, nil,
- 135, 156, 153, 152, 161, 148, 149, 143, 141, 133,
- 155, 134, 413, 417, 162, nil, 414, nil, nil, nil,
- nil, nil, nil, nil, nil, 157, 158, nil, 154, 136,
- 137, 138, 145, 142, 144, nil, nil, 139, 140, nil,
- nil, nil, 159, 160, 146, 147, nil, nil, nil, nil,
- nil, 263, nil, nil, nil, nil, nil, nil, nil, 151,
- 150, nil, 135, 156, 153, 152, 161, 148, 149, 143,
- 141, 133, 155, 134, 420, 424, 162, nil, 419, nil,
- nil, nil, nil, nil, nil, nil, nil, 157, 158, nil,
- 154, 136, 137, 138, 145, 142, 144, nil, nil, 139,
- 140, nil, nil, nil, 159, 160, 146, 147, nil, nil,
- nil, nil, nil, 263, nil, nil, nil, nil, nil, nil,
- nil, 151, 150, nil, 135, 156, 153, 152, 161, 148,
- 149, 143, 141, 133, 155, 134, 475, 417, 162, nil,
- 476, nil, nil, nil, nil, nil, nil, nil, nil, 157,
- 158, nil, 154, 136, 137, 138, 145, 142, 144, nil,
- nil, 139, 140, nil, nil, nil, 159, 160, 146, 147,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 151, 150, nil, 135, 156, 153, 152,
- 161, 148, 149, 143, 141, 133, 155, 134, 638, 417,
- 162, nil, 639, nil, nil, nil, nil, nil, nil, nil,
- nil, 157, 158, nil, 154, 136, 137, 138, 145, 142,
- 144, nil, nil, 139, 140, nil, nil, nil, 159, 160,
- 146, 147, nil, nil, nil, nil, nil, 263, nil, nil,
- nil, nil, nil, nil, nil, 151, 150, nil, 135, 156,
- 153, 152, 161, 148, 149, 143, 141, 133, 155, 134,
- 640, 424, 162, nil, 641, nil, nil, nil, nil, nil,
- nil, nil, nil, 157, 158, nil, 154, 136, 137, 138,
- 145, 142, 144, nil, nil, 139, 140, nil, nil, nil,
- 159, 160, 146, 147, nil, nil, nil, nil, nil, 263,
- nil, nil, nil, nil, nil, nil, nil, 151, 150, nil,
- 135, 156, 153, 152, 161, 148, 149, 143, 141, 133,
- 155, 134, 670, 417, 162, nil, 671, nil, nil, nil,
- nil, nil, nil, nil, nil, 157, 158, nil, 154, 136,
- 137, 138, 145, 142, 144, nil, nil, 139, 140, nil,
- nil, nil, 159, 160, 146, 147, nil, nil, nil, nil,
- nil, 263, nil, nil, nil, nil, nil, nil, nil, 151,
- 150, nil, 135, 156, 153, 152, 161, 148, 149, 143,
- 141, 133, 155, 134, 673, 424, 162, nil, 674, nil,
- nil, nil, nil, nil, nil, nil, nil, 157, 158, nil,
- 154, 136, 137, 138, 145, 142, 144, nil, nil, 139,
- 140, nil, nil, nil, 159, 160, 146, 147, nil, nil,
- nil, nil, nil, 263, nil, nil, nil, nil, nil, nil,
- nil, 151, 150, nil, 135, 156, 153, 152, 161, 148,
- 149, 143, 141, 133, 155, 134, 638, 417, 162, nil,
- 639, nil, nil, nil, nil, nil, nil, nil, nil, 157,
- 158, nil, 154, 136, 137, 138, 145, 142, 144, nil,
- nil, 139, 140, nil, nil, nil, 159, 160, 146, 147,
- nil, nil, nil, nil, nil, 263, nil, nil, nil, nil,
- nil, nil, nil, 151, 150, nil, 135, 156, 153, 152,
- 161, 148, 149, 143, 141, 133, 155, 134, 640, 424,
- 162, nil, 641, nil, nil, nil, nil, nil, nil, nil,
- nil, 157, 158, nil, 154, 136, 137, 138, 145, 142,
- 144, nil, nil, 139, 140, nil, nil, nil, 159, 160,
- 146, 147, nil, nil, nil, nil, nil, 263, nil, nil,
- nil, nil, nil, nil, nil, 151, 150, nil, 135, 156,
- 153, 152, 161, 148, 149, 143, 141, 133, 155, 134,
- 721, 417, 162, nil, 722, nil, nil, nil, nil, nil,
- nil, nil, nil, 157, 158, nil, 154, 136, 137, 138,
- 145, 142, 144, nil, nil, 139, 140, nil, nil, nil,
- 159, 160, 146, 147, nil, nil, nil, nil, nil, 263,
- nil, nil, nil, nil, nil, nil, nil, 151, 150, nil,
- 135, 156, 153, 152, 161, 148, 149, 143, 141, 133,
- 155, 134, 723, 424, 162, nil, 724, nil, nil, nil,
- nil, nil, nil, nil, nil, 157, 158, nil, 154, 136,
- 137, 138, 145, 142, 144, nil, nil, 139, 140, nil,
- nil, nil, 159, 160, 146, 147, nil, nil, nil, nil,
- nil, 263, nil, nil, nil, nil, nil, nil, nil, 151,
- 150, nil, 135, 156, 153, 152, 161, 148, 149, 143,
- 141, 133, 155, 134, 726, 424, 162, nil, 727, nil,
- nil, nil, nil, nil, nil, nil, nil, 157, 158, nil,
- 154, 136, 137, 138, 145, 142, 144, nil, nil, 139,
- 140, nil, nil, nil, 159, 160, 146, 147, nil, nil,
- nil, nil, nil, 263, nil, nil, nil, nil, nil, nil,
- nil, 151, 150, nil, 135, 156, 153, 152, 161, 148,
- 149, 143, 141, 133, 155, 134, 475, 417, 162, nil,
- 476, nil, nil, nil, nil, nil, nil, nil, nil, 157,
- 158, nil, 154, 136, 137, 138, 145, 142, 144, nil,
- nil, 139, 140, nil, nil, nil, 159, 160, 146, 147,
- nil, nil, nil, nil, nil, 263, nil, nil, nil, nil,
- nil, nil, nil, 151, 150, nil, 135, 156, 153, 152,
- 161, 148, 149, 143, 141, 133, 155, 134, 983, 424,
- 162, nil, 982, nil, nil, nil, nil, nil, nil, nil,
- nil, 157, 158, nil, 154, 136, 137, 138, 145, 142,
- 144, nil, nil, 139, 140, nil, nil, nil, 159, 160,
- 146, 147, nil, nil, nil, nil, nil, 263, nil, nil,
- nil, nil, nil, nil, nil, 151, 150, nil, 135, 156,
- 153, 152, 161, 148, 149, 143, 141, 133, 155, 134,
- 1006, 417, 162, nil, 1007, nil, nil, nil, nil, nil,
- nil, nil, nil, 157, 158, nil, 154, 136, 137, 138,
- 145, 142, 144, nil, nil, 139, 140, nil, nil, nil,
- 159, 160, 146, 147, nil, nil, nil, nil, nil, 263,
- nil, nil, nil, nil, nil, nil, nil, 151, 150, nil,
- 135, 156, 153, 152, 161, 148, 149, 143, 141, 133,
- 155, 134, 1008, 424, 162, nil, 1009, nil, nil, nil,
- nil, nil, nil, nil, nil, 157, 158, nil, 154, 136,
- 137, 138, 145, 142, 144, nil, nil, 139, 140, nil,
- nil, nil, 159, 160, 146, 147, nil, nil, nil, nil,
- nil, 263, nil, nil, nil, nil, nil, nil, nil, 151,
- 150, nil, 135, 156, 153, 152, 161, 148, 149, 143,
- 141, 133, 155, 134, nil, 548, 162, 545, 544, 543,
- 553, 546, nil, 548, nil, 545, 544, 543, 553, 546,
- nil, 556, nil, nil, nil, nil, nil, nil, 548, 556,
- 545, 544, 543, 553, 546, nil, nil, nil, nil, nil,
- nil, nil, nil, 551, 556, nil, nil, nil, nil, nil,
- nil, 551, 561, 560, 564, 563, nil, nil, nil, 557,
- 561, 560, 564, 563, nil, nil, 551, 557, 548, nil,
- 545, 544, 543, 553, 546, 561, 560, 564, 563, nil,
- nil, nil, 557, 548, 556, 545, 544, 543, 553, 546,
- nil, 548, nil, 545, 544, 543, 553, 546, nil, 556,
- nil, nil, nil, nil, nil, nil, 551, 556, 548, nil,
- 545, 544, 543, 553, 546, 561, 560, 564, 563, nil,
- nil, 551, 557, nil, 556, nil, nil, nil, nil, 551,
- 561, 560, 564, 563, nil, nil, nil, 557, 561, 560,
- 564, 563, nil, nil, nil, 557, 551, 548, nil, 545,
- 544, 543, 553, 546, nil, 561, 560, 564, 563, nil,
- nil, nil, 557, 556, 548, nil, 545, 544, 543, 553,
- 546, nil, 548, nil, 545, 544, 543, 553, 546, nil,
- 556, nil, nil, nil, nil, 551, nil, 548, 556, 545,
- 544, 543, 553, 546, nil, nil, 564, 563, nil, nil,
- nil, 557, 551, 556, nil, nil, nil, nil, nil, nil,
- 551, nil, nil, 564, 563, nil, nil, nil, 557, 561,
- 560, 564, 563, nil, nil, 551, 557, 548, nil, 545,
- 544, 543, 553, 546, nil, nil, 564, 563, nil, nil,
- nil, 557, 548, 556, 545, 544, 543, 553, 546, nil,
- 548, nil, 545, 544, 543, 553, 546, 548, 556, 545,
- 544, 543, 553, 546, nil, 551, 556, nil, nil, nil,
- nil, nil, nil, 556, nil, nil, 564, 563, nil, nil,
- 551, 557, nil, nil, nil, nil, nil, nil, 551, nil,
- nil, 564, 563, nil, nil, 551, 557, nil, nil, 564,
- 563, nil, nil, nil, 557, nil, 564, 563, nil, nil,
- nil, 557 ]
-
-racc_action_check = [
- 95, 345, 61, 437, 437, 346, 349, 95, 95, 95,
- 221, 338, 95, 95, 95, 383, 95, 355, 19, 384,
- 58, 355, 594, 594, 95, 222, 95, 95, 95, 473,
- 650, 26, 17, 17, 578, 359, 95, 95, 339, 95,
- 95, 95, 95, 95, 719, 885, 15, 1, 908, 687,
- 721, 7, 1006, 665, 1007, 1020, 680, 680, 308, 19,
- 58, 913, 665, 913, 473, 722, 221, 95, 95, 95,
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
- 95, 222, 383, 95, 95, 95, 384, 95, 95, 570,
- 61, 95, 10, 15, 95, 95, 26, 95, 437, 95,
- 12, 95, 15, 95, 95, 844, 95, 95, 95, 95,
- 95, 345, 95, 98, 95, 346, 349, 594, 650, 26,
- 98, 98, 98, 308, 1008, 98, 98, 98, 95, 98,
- 338, 95, 95, 95, 95, 338, 95, 98, 95, 98,
- 98, 98, 359, 95, 578, 571, 308, 723, 845, 98,
- 98, 680, 98, 98, 98, 98, 98, 339, 13, 687,
- 721, 670, 339, 719, 885, 359, 719, 908, 719, 885,
- 359, 1006, 908, 1007, 1020, 722, 1006, 16, 1007, 1020,
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
- 98, 98, 98, 98, 570, 22, 98, 98, 98, 570,
- 98, 98, 1008, 671, 98, 37, 724, 98, 98, 40,
- 98, 605, 98, 723, 98, 844, 98, 98, 224, 98,
- 98, 98, 98, 98, 419, 98, 45, 98, 670, 590,
- 590, 419, 419, 419, 481, 24, 328, 419, 419, 328,
- 419, 98, 24, 1008, 98, 98, 98, 98, 1008, 98,
- 571, 98, 353, 845, 3, 571, 98, 723, 845, 3,
- 419, 419, 109, 419, 419, 419, 419, 419, 670, 481,
- 671, 670, 724, 123, 224, 204, 605, 605, 123, 123,
- 670, 704, 607, 704, 704, 704, 605, 704, 223, 41,
- 41, 419, 419, 419, 419, 419, 419, 419, 419, 419,
- 419, 419, 419, 419, 419, 353, 354, 419, 419, 419,
- 671, 419, 353, 671, 38, 419, 724, 353, 419, 313,
- 313, 353, 671, 419, 590, 419, 443, 419, 419, 590,
- 419, 419, 419, 419, 419, 378, 419, 420, 419, 225,
- 353, 39, 364, 226, 420, 420, 420, 607, 607, 364,
- 420, 420, 419, 420, 482, 419, 419, 607, 419, 354,
- 419, 38, 420, 230, 704, 673, 354, 419, 41, 41,
- 38, 354, 262, 420, 420, 354, 420, 420, 420, 420,
- 420, 904, 443, 904, 904, 904, 317, 904, 39, 482,
- 329, 651, 492, 329, 354, 379, 276, 39, 313, 313,
- 378, 378, 378, 801, 420, 420, 420, 420, 420, 420,
- 420, 420, 420, 420, 420, 420, 420, 420, 673, 413,
- 420, 420, 420, 380, 420, 673, 651, 288, 420, 414,
- 673, 420, 288, 317, 673, 381, 420, 638, 420, 726,
- 420, 420, 317, 420, 420, 420, 420, 420, 277, 420,
- 420, 420, 382, 673, 280, 385, 801, 492, 492, 492,
- 379, 379, 379, 801, 904, 420, 413, 621, 420, 420,
- 640, 420, 801, 420, 492, 413, 414, 640, 640, 640,
- 420, 292, 640, 640, 640, 414, 640, 365, 380, 380,
- 380, 801, 726, 638, 365, 640, 640, 640, 640, 726,
- 381, 381, 381, 639, 726, 293, 640, 640, 726, 640,
- 640, 640, 640, 640, 621, 295, 774, 382, 382, 382,
- 385, 385, 385, 621, 337, 337, 366, 726, 551, 367,
- 551, 551, 551, 366, 551, 296, 367, 640, 640, 640,
- 640, 640, 640, 640, 640, 640, 640, 640, 640, 640,
- 640, 689, 297, 640, 640, 640, 368, 640, 640, 639,
- 303, 640, 689, 368, 640, 640, 551, 640, 306, 640,
- 307, 640, 774, 640, 640, 551, 640, 640, 640, 640,
- 640, 862, 640, 640, 640, 332, 369, 77, 332, 342,
- 370, 312, 862, 369, 342, 689, 689, 370, 640, 77,
- 689, 640, 640, 640, 640, 449, 640, 641, 640, 77,
- 371, 14, 314, 640, 641, 641, 641, 371, 14, 641,
- 641, 641, 46, 641, 220, 862, 862, 14, 318, 46,
- 862, 220, 372, 641, 641, 641, 321, 449, 46, 372,
- 220, 449, 449, 641, 641, 374, 641, 641, 641, 641,
- 641, 833, 374, 833, 833, 833, 300, 833, 701, 326,
- 701, 701, 701, 300, 701, 831, 330, 831, 831, 831,
- 686, 831, 300, 686, 641, 641, 641, 641, 641, 641,
- 641, 641, 641, 641, 641, 641, 641, 641, 468, 833,
- 641, 641, 641, 301, 641, 641, 701, 469, 641, 331,
- 301, 641, 641, 831, 641, 701, 641, 333, 641, 301,
- 641, 641, 831, 641, 641, 641, 641, 641, 589, 641,
- 468, 641, 343, 589, 468, 468, 450, 468, 468, 469,
- 523, 523, 344, 469, 469, 641, 469, 469, 641, 641,
- 641, 641, 848, 641, 853, 641, 348, 848, 350, 853,
- 641, 0, 0, 0, 0, 0, 0, 394, 450, 302,
- 0, 0, 450, 450, 400, 0, 302, 0, 0, 0,
- 0, 0, 0, 0, 934, 302, 403, 934, 405, 0,
- 0, 0, 0, 0, 0, 0, 598, 598, 0, 409,
- 598, 598, 598, 432, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 411, 0, 0, 0,
- 412, 0, 0, 421, 0, 0, 0, 432, 432, 432,
- 432, 432, 432, 432, 432, 432, 432, 432, 304, 432,
- 432, 319, 429, 432, 432, 304, 0, 439, 319, 0,
- 692, 692, 0, 0, 304, 451, 0, 319, 0, 432,
- 452, 432, 0, 432, 432, 453, 432, 432, 432, 432,
- 432, 0, 432, 710, 710, 454, 0, 0, 0, 0,
- 347, 0, 0, 0, 0, 996, 996, 347, 479, 0,
- 0, 483, 432, 499, 432, 500, 347, 0, 503, 0,
- 0, 0, 33, 33, 33, 33, 33, 33, 505, 510,
- 357, 33, 33, 513, 521, 522, 33, 357, 33, 33,
- 33, 33, 33, 33, 33, 524, 357, 536, 537, 539,
- 33, 33, 33, 33, 33, 33, 33, 540, 541, 33,
- 550, 558, 562, 565, 408, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 567, 33, 33,
- 33, 572, 33, 33, 573, 33, 33, 33, 408, 408,
- 408, 408, 408, 408, 408, 408, 408, 408, 408, 509,
- 408, 408, 581, 592, 408, 408, 509, 33, 602, 581,
- 33, 610, 612, 33, 33, 509, 618, 33, 581, 33,
- 408, 622, 408, 33, 408, 408, 627, 408, 408, 408,
- 408, 408, 33, 408, 632, 642, 649, 33, 33, 33,
- 33, 875, 33, 33, 33, 33, 656, 658, 875, 664,
- 33, 33, 667, 408, 669, 672, 675, 875, 33, 676,
- 33, 33, 33, 121, 121, 121, 121, 121, 121, 679,
- 681, 938, 121, 121, 684, 688, 703, 121, 938, 121,
- 121, 121, 121, 121, 121, 121, 705, 938, 712, 717,
- 720, 121, 121, 121, 121, 121, 121, 121, 729, 734,
- 121, 753, 758, 775, 776, 643, 121, 121, 121, 121,
- 121, 121, 121, 121, 121, 121, 121, 121, 777, 121,
- 121, 121, 779, 121, 121, 780, 121, 121, 121, 643,
- 643, 643, 643, 643, 643, 643, 643, 643, 643, 643,
- 674, 643, 643, 944, 781, 643, 643, 674, 121, 783,
- 944, 121, 674, 784, 121, 121, 674, 785, 121, 944,
- 121, 643, 786, 643, 121, 643, 643, 790, 643, 643,
- 643, 643, 643, 121, 643, 794, 795, 800, 121, 121,
- 121, 121, 945, 121, 121, 121, 121, 804, 807, 945,
- 808, 121, 121, 811, 643, 816, 817, 821, 945, 121,
- 822, 121, 121, 121, 206, 206, 206, 206, 206, 206,
- 824, 825, 946, 206, 206, 827, 830, 832, 206, 946,
- 206, 206, 206, 206, 206, 206, 206, 835, 946, 838,
- 847, 851, 206, 206, 206, 206, 206, 206, 206, 852,
- 873, 206, 873, 873, 873, 855, 873, 206, 206, 206,
- 206, 206, 206, 206, 206, 206, 206, 206, 206, 856,
- 206, 206, 206, 872, 206, 206, 876, 206, 206, 206,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 727, 21, 21, 948, 878, 21, 21, 727, 206,
- 889, 948, 206, 727, 890, 206, 206, 727, 906, 206,
- 948, 206, 21, 910, 21, 206, 21, 21, 911, 21,
- 21, 21, 21, 21, 206, 21, 917, 921, 924, 206,
- 206, 206, 206, 988, 206, 206, 206, 206, 927, 928,
- 988, 929, 206, 206, 930, 21, 932, 947, 952, 988,
- 206, 953, 206, 206, 206, 229, 229, 229, 229, 229,
- 229, 954, 955, 956, 229, 229, 958, 982, 983, 229,
- 984, 229, 229, 229, 229, 229, 229, 229, 6, 6,
- 6, 6, 6, 229, 229, 229, 229, 229, 229, 229,
- 995, 981, 229, 981, 981, 981, 997, 981, 229, 229,
- 229, 229, 229, 229, 229, 229, 229, 229, 229, 229,
- 998, 229, 229, 229, 999, 229, 229, 1000, 229, 229,
- 229, 274, 274, 274, 274, 274, 274, 274, 274, 274,
- 274, 274, 1009, 274, 274, 1001, 1002, 274, 274, 1009,
- 229, 1005, 1010, 229, 1009, 1011, 229, 229, 1009, 1022,
- 229, nil, 229, 274, nil, 274, 229, 274, 274, nil,
- 274, 274, 274, 274, 274, 229, 274, nil, nil, nil,
- 229, 229, 229, 229, nil, 229, 229, 229, 229, nil,
- nil, nil, nil, 229, 229, nil, 274, nil, nil, nil,
- nil, 229, nil, 229, 229, 229, 294, 294, 294, 294,
- 294, 294, nil, nil, nil, 294, 294, nil, nil, nil,
- 294, nil, 294, 294, 294, 294, 294, 294, 294, 291,
- 291, 291, 291, 291, 294, 294, 294, 294, 294, 294,
- 294, nil, nil, 294, 497, 497, 497, 497, 497, 294,
- 294, 294, 294, 294, 294, 294, 294, 294, 294, 294,
- 294, nil, 294, 294, 294, nil, 294, 294, nil, 294,
- 294, 294, 427, 427, 427, 427, 427, 427, 427, 427,
- 427, 427, 427, nil, 427, 427, nil, nil, 427, 427,
- nil, 294, nil, nil, 294, nil, nil, 294, 294, nil,
- nil, 294, nil, 294, 427, nil, 427, 294, 427, 427,
- nil, 427, 427, 427, 427, 427, 294, 427, nil, nil,
- nil, 294, 294, 294, 294, nil, 294, 294, 294, 294,
- nil, nil, nil, nil, 294, 294, nil, 427, nil, nil,
- nil, nil, 294, nil, 294, 294, 294, 299, 299, 299,
- 299, 299, 299, nil, nil, nil, 299, 299, nil, nil,
- nil, 299, nil, 299, 299, 299, 299, 299, 299, 299,
- nil, nil, nil, nil, nil, 299, 299, 299, 299, 299,
- 299, 299, nil, nil, 299, nil, nil, nil, nil, nil,
- 299, 299, 299, 299, 299, 299, 299, 299, 299, 299,
- 299, 299, nil, 299, 299, 299, nil, 299, 299, nil,
- 299, 299, 299, 519, 519, 519, 519, 519, 519, 519,
- 519, 519, 519, 519, nil, 519, 519, nil, nil, 519,
- 519, nil, 299, nil, nil, 299, nil, nil, 299, 299,
- nil, nil, 299, nil, 299, 519, nil, 519, 299, 519,
- 519, nil, 519, 519, 519, 519, 519, 299, 519, nil,
- nil, nil, 299, 299, 299, 299, nil, 299, 299, 299,
- 299, nil, nil, nil, nil, 299, 299, nil, 519, nil,
- nil, nil, nil, 299, nil, 299, 299, 299, 324, 324,
- 324, 324, 324, 324, nil, nil, nil, 324, 324, nil,
- nil, nil, 324, nil, 324, 324, 324, 324, 324, 324,
- 324, nil, nil, nil, nil, nil, 324, 324, 324, 324,
- 324, 324, 324, nil, nil, 324, nil, nil, nil, nil,
- nil, 324, 324, 324, 324, 324, 324, 324, 324, 324,
- 324, 324, 324, nil, 324, 324, 324, nil, 324, 324,
- nil, 324, 324, 324, 644, 644, 644, 644, 644, 644,
- 644, 644, 644, 644, 644, nil, 644, 644, nil, nil,
- 644, 644, nil, 324, nil, nil, 324, nil, nil, 324,
- 324, nil, nil, 324, nil, 324, 644, nil, 644, 324,
- 644, 644, nil, 644, 644, 644, 644, 644, 324, 644,
- nil, nil, nil, 324, 324, 324, 324, nil, 324, 324,
- 324, 324, nil, nil, nil, nil, 324, 324, 644, 644,
- nil, nil, nil, nil, 324, nil, 324, 324, 324, 498,
- 498, 498, 498, 498, 498, nil, nil, nil, 498, 498,
- nil, nil, nil, 498, nil, 498, 498, 498, 498, 498,
- 498, 498, nil, nil, nil, nil, nil, 498, 498, 498,
- 498, 498, 498, 498, nil, nil, 498, nil, nil, nil,
- nil, nil, 498, 498, 498, 498, 498, 498, 498, 498,
- 498, 498, 498, 498, nil, 498, 498, 498, nil, 498,
- 498, nil, 498, 498, 498, 678, 678, 678, 678, 678,
- 678, 678, 678, 678, 678, 678, nil, 678, 678, nil,
- nil, 678, 678, nil, 498, nil, nil, 498, nil, nil,
- 498, 498, nil, nil, 498, nil, 498, 678, nil, 678,
- 498, 678, 678, nil, 678, 678, 678, 678, 678, 498,
- 678, nil, nil, nil, 498, 498, 498, 498, nil, 498,
- 498, 498, 498, nil, nil, nil, nil, 498, 498, nil,
- 678, nil, nil, nil, nil, 498, nil, 498, 498, 498,
- 566, 566, 566, 566, 566, 566, nil, nil, nil, 566,
- 566, nil, nil, nil, 566, nil, 566, 566, 566, 566,
- 566, 566, 566, nil, nil, nil, nil, nil, 566, 566,
- 566, 566, 566, 566, 566, nil, nil, 566, nil, nil,
- nil, nil, nil, 566, 566, 566, 566, 566, 566, 566,
- 566, 566, 566, 566, 566, nil, 566, 566, 566, nil,
- 566, 566, nil, 566, 566, 566, 755, 755, 755, 755,
- 755, 755, 755, 755, 755, 755, 755, nil, 755, 755,
- nil, nil, 755, 755, nil, 566, nil, nil, 566, nil,
- nil, 566, 566, nil, nil, 566, nil, 566, 755, nil,
- 755, 566, 755, 755, nil, 755, 755, 755, 755, 755,
- 566, 755, nil, nil, nil, 566, 566, 566, 566, nil,
- 566, 566, 566, 566, nil, nil, nil, nil, 566, 566,
- nil, 755, nil, nil, nil, nil, 566, nil, 566, 566,
- 566, 569, 569, 569, 569, 569, 569, nil, nil, nil,
- 569, 569, nil, nil, nil, 569, nil, 569, 569, 569,
- 569, 569, 569, 569, nil, nil, nil, nil, nil, 569,
- 569, 569, 569, 569, 569, 569, nil, nil, 569, nil,
- nil, nil, nil, nil, 569, 569, 569, 569, 569, 569,
- 569, 569, 569, 569, 569, 569, nil, 569, 569, 569,
- nil, 569, 569, nil, 569, 569, 569, 760, 760, 760,
- 760, 760, 760, 760, 760, 760, 760, 760, nil, 760,
- 760, nil, nil, 760, 760, nil, 569, nil, nil, 569,
- nil, nil, 569, 569, nil, nil, 569, nil, 569, 760,
- nil, 760, 569, 760, 760, nil, 760, 760, 760, 760,
- 760, 569, 760, nil, nil, nil, 569, 569, 569, 569,
- nil, 569, 569, 569, 569, nil, nil, nil, nil, 569,
- 569, nil, 760, nil, nil, nil, nil, 569, nil, 569,
- 569, 569, 591, 591, 591, 591, 591, 591, nil, nil,
- nil, 591, 591, nil, nil, nil, 591, nil, 591, 591,
- 591, 591, 591, 591, 591, nil, nil, nil, nil, nil,
- 591, 591, 591, 591, 591, 591, 591, nil, nil, 591,
- nil, nil, nil, nil, nil, 591, 591, 591, 591, 591,
- 591, 591, 591, 591, 591, 591, 591, nil, 591, 591,
- 591, nil, 591, 591, nil, 591, 591, 591, 762, 762,
- 762, 762, 762, 762, 762, 762, 762, 762, 762, nil,
- 762, 762, nil, nil, 762, 762, nil, 591, nil, nil,
- 591, nil, nil, 591, 591, nil, nil, 591, nil, 591,
- 762, nil, 762, 591, 762, 762, nil, 762, 762, 762,
- 762, 762, 591, 762, nil, nil, nil, 591, 591, 591,
- 591, nil, 591, 591, 591, 591, nil, nil, nil, nil,
- 591, 591, nil, 762, nil, nil, nil, nil, 591, nil,
- 591, 591, 591, 648, 648, 648, 648, 648, 648, nil,
- nil, nil, 648, 648, nil, nil, nil, 648, nil, 648,
- 648, 648, 648, 648, 648, 648, nil, nil, nil, nil,
- nil, 648, 648, 648, 648, 648, 648, 648, nil, nil,
- 648, nil, nil, nil, nil, nil, 648, 648, 648, 648,
- 648, 648, 648, 648, 648, 648, 648, 648, nil, 648,
- 648, 648, nil, 648, 648, nil, 648, 648, 648, 765,
- 765, 765, 765, 765, 765, 765, 765, 765, 765, 765,
- nil, 765, 765, nil, nil, 765, 765, nil, 648, nil,
- nil, 648, nil, nil, 648, 648, nil, nil, 648, nil,
- 648, 765, nil, 765, 648, 765, 765, nil, 765, 765,
- 765, 765, 765, 648, 765, nil, nil, nil, 648, 648,
- 648, 648, nil, 648, 648, 648, 648, nil, nil, nil,
- nil, 648, 648, nil, 765, nil, nil, nil, nil, 648,
- nil, 648, 648, 648, 653, 653, 653, 653, 653, 653,
- nil, nil, nil, 653, 653, nil, nil, nil, 653, nil,
- 653, 653, 653, 653, 653, 653, 653, nil, nil, nil,
- nil, nil, 653, 653, 653, 653, 653, 653, 653, nil,
- nil, 653, nil, nil, nil, nil, nil, 653, 653, 653,
- 653, 653, 653, 653, 653, 653, 653, 653, 653, nil,
- 653, 653, 653, nil, 653, 653, nil, 653, 653, 653,
- 767, 767, 767, 767, 767, 767, 767, 767, 767, 767,
- 767, nil, 767, 767, nil, nil, 767, 767, nil, 653,
- nil, nil, 653, nil, nil, 653, 653, nil, nil, 653,
- nil, 653, 767, nil, 767, 653, 767, 767, nil, 767,
- 767, 767, 767, 767, 653, 767, nil, nil, nil, 653,
- 653, 653, 653, nil, 653, 653, 653, 653, nil, nil,
- nil, nil, 653, 653, nil, 767, nil, nil, nil, nil,
- 653, nil, 653, 653, 653, 654, 654, 654, 654, 654,
- 654, nil, nil, nil, 654, 654, nil, nil, nil, 654,
- nil, 654, 654, 654, 654, 654, 654, 654, nil, nil,
- nil, nil, nil, 654, 654, 654, 654, 654, 654, 654,
- nil, nil, 654, nil, nil, nil, nil, nil, 654, 654,
- 654, 654, 654, 654, 654, 654, 654, 654, 654, 654,
- nil, 654, 654, 654, nil, 654, 654, nil, 654, 654,
- 654, 769, 769, 769, 769, 769, 769, 769, 769, 769,
- 769, 769, nil, 769, 769, nil, nil, 769, 769, nil,
- 654, nil, nil, 654, nil, nil, 654, 654, nil, nil,
- 654, nil, 654, 769, nil, 769, 654, 769, 769, nil,
- 769, 769, 769, 769, 769, 654, 769, nil, nil, nil,
- 654, 654, 654, 654, nil, 654, 654, 654, 654, nil,
- nil, nil, nil, 654, 654, nil, 769, nil, nil, nil,
- nil, 654, nil, 654, 654, 654, 730, 730, 730, 730,
- 730, 730, nil, nil, nil, 730, 730, nil, nil, nil,
- 730, nil, 730, 730, 730, 730, 730, 730, 730, nil,
- nil, nil, nil, nil, 730, 730, 730, 730, 730, 730,
- 730, nil, nil, 730, nil, nil, nil, nil, nil, 730,
- 730, 730, 730, 730, 730, 730, 730, 730, 730, 730,
- 730, nil, 730, 730, 730, nil, 730, 730, nil, 730,
- 730, 730, 858, 858, 858, 858, 858, 858, 858, 858,
- 858, 858, 858, nil, 858, 858, nil, nil, 858, 858,
- nil, 730, nil, nil, 730, nil, nil, 730, 730, nil,
- nil, 730, nil, 730, 858, nil, 858, 730, 858, 858,
- nil, 858, 858, 858, 858, 858, 730, 858, nil, nil,
- nil, 730, 730, 730, 730, nil, 730, 730, 730, 730,
- nil, nil, nil, nil, 730, 730, nil, 858, nil, nil,
- nil, nil, 730, nil, 730, 730, 730, 735, 735, 735,
- 735, 735, 735, nil, nil, nil, 735, 735, nil, nil,
- nil, 735, nil, 735, 735, 735, 735, 735, 735, 735,
- nil, nil, nil, nil, nil, 735, 735, 735, 735, 735,
- 735, 735, nil, nil, 735, nil, nil, nil, nil, nil,
- 735, 735, 735, 735, 735, 735, 735, 735, 735, 735,
- 735, 735, nil, 735, 735, 735, nil, 735, 735, nil,
- 735, 735, 735, 969, 969, 969, 969, 969, 969, 969,
- 969, 969, 969, 969, nil, 969, 969, nil, nil, 969,
- 969, nil, 735, nil, nil, 735, nil, nil, 735, 735,
- nil, nil, 735, nil, 735, 969, nil, 969, 735, 969,
- 969, nil, 969, 969, 969, 969, 969, 735, 969, nil,
- nil, nil, 735, 735, 735, 735, nil, 735, 735, 735,
- 735, nil, nil, nil, nil, 735, 735, nil, 969, nil,
- nil, nil, nil, 735, nil, 735, 735, 735, 745, 745,
- 745, 745, 745, 745, nil, nil, nil, 745, 745, nil,
- nil, nil, 745, nil, 745, 745, 745, 745, 745, 745,
- 745, nil, nil, nil, nil, nil, 745, 745, 745, 745,
- 745, 745, 745, nil, nil, 745, nil, nil, nil, nil,
- nil, 745, 745, 745, 745, 745, 745, 745, 745, 745,
- 745, 745, 745, nil, 745, 745, 745, nil, 745, 745,
- nil, 745, 745, 745, 447, 447, 447, 447, 447, 447,
- 447, 447, 447, 447, 447, nil, 447, 447, nil, nil,
- 447, 447, nil, 745, nil, nil, 745, nil, nil, 745,
- 745, nil, nil, 745, nil, 745, 447, nil, 447, 745,
- 447, 447, nil, 447, 447, 447, 447, 447, 745, 447,
- nil, nil, nil, 745, 745, 745, 745, nil, 745, 745,
- 745, 745, nil, nil, nil, nil, 745, 745, nil, nil,
- nil, nil, nil, nil, 745, nil, 745, 745, 745, 793,
- 793, 793, 793, 793, 793, nil, nil, nil, 793, 793,
- nil, nil, nil, 793, nil, 793, 793, 793, 793, 793,
- 793, 793, nil, nil, nil, nil, nil, 793, 793, 793,
- 793, 793, 793, 793, nil, nil, 793, nil, nil, nil,
- nil, nil, 793, 793, 793, 793, 793, 793, 793, 793,
- 793, 793, 793, 793, nil, 793, 793, 793, nil, 793,
- 793, nil, 793, 793, 793, 448, 448, 448, 448, 448,
- 448, 448, 448, 448, 448, 448, nil, 448, 448, nil,
- nil, 448, 448, nil, 793, nil, nil, 793, nil, nil,
- 793, 793, nil, nil, 793, nil, 793, 448, nil, 448,
- 793, 448, 448, nil, 448, 448, 448, 448, 448, 793,
- 448, nil, nil, nil, 793, 793, 793, 793, nil, 793,
- 793, 793, 793, nil, nil, nil, nil, 793, 793, nil,
- nil, nil, nil, nil, nil, 793, nil, 793, 793, 793,
- 806, 806, 806, 806, 806, 806, nil, nil, nil, 806,
- 806, nil, nil, nil, 806, nil, 806, 806, 806, 806,
- 806, 806, 806, nil, nil, nil, nil, nil, 806, 806,
- 806, 806, 806, 806, 806, nil, 905, 806, 905, 905,
- 905, nil, 905, 806, 806, 806, 806, 806, 806, 806,
- 806, 806, 806, 806, 806, nil, 806, 806, 806, nil,
- 806, 806, nil, 806, 806, 806, 458, 458, 458, 458,
- 458, 458, 458, nil, 905, 458, 458, nil, nil, nil,
- nil, nil, 458, 458, nil, 806, nil, nil, 806, nil,
- nil, 806, 806, nil, nil, 806, nil, 806, 458, nil,
- 458, 806, 458, 458, nil, 458, 458, 458, 458, 458,
- 806, 458, nil, nil, nil, 806, 806, 806, 806, nil,
- 806, 806, 806, 806, nil, nil, nil, nil, 806, 806,
- nil, nil, nil, nil, nil, nil, 806, nil, 806, 806,
- 806, 814, 814, 814, 814, 814, 814, nil, nil, nil,
- 814, 814, nil, nil, nil, 814, nil, 814, 814, 814,
- 814, 814, 814, 814, nil, nil, nil, nil, nil, 814,
- 814, 814, 814, 814, 814, 814, nil, 957, 814, 957,
- 957, 957, nil, 957, 814, 814, 814, 814, 814, 814,
- 814, 814, 814, 814, 814, 814, nil, 814, 814, 814,
- nil, 814, 814, nil, 814, 814, 814, 459, nil, nil,
- 959, nil, 959, 959, 959, 957, 959, nil, nil, nil,
- nil, nil, nil, 459, 459, nil, 814, nil, nil, 814,
- nil, nil, 814, 814, nil, nil, 814, nil, 814, 459,
- nil, 459, 814, 459, 459, nil, 459, 459, 959, nil,
- 459, 814, 459, nil, nil, nil, 814, 814, 814, 814,
- nil, 814, 814, 814, 814, nil, nil, nil, nil, 814,
- 814, nil, nil, nil, nil, nil, nil, 814, nil, 814,
- 814, 814, 815, 815, 815, 815, 815, 815, nil, nil,
- nil, 815, 815, nil, nil, nil, 815, nil, 815, 815,
- 815, 815, 815, 815, 815, nil, nil, nil, nil, nil,
- 815, 815, 815, 815, 815, 815, 815, nil, 994, 815,
- 994, 994, 994, nil, 994, 815, 815, 815, 815, 815,
- 815, 815, 815, 815, 815, 815, 815, nil, 815, 815,
- 815, nil, 815, 815, nil, 815, 815, 815, 460, nil,
- nil, nil, nil, nil, nil, nil, 994, nil, nil, nil,
- nil, nil, nil, nil, 460, 460, nil, 815, nil, nil,
- 815, nil, nil, 815, 815, nil, nil, 815, nil, 815,
- 460, nil, 460, 815, 460, 460, nil, 460, 460, nil,
- nil, 460, 815, 460, nil, nil, nil, 815, 815, 815,
- 815, nil, 815, 815, 815, 815, nil, nil, nil, nil,
- 815, 815, nil, nil, nil, nil, nil, nil, 815, nil,
- 815, 815, 815, 839, 839, 839, 839, 839, 839, nil,
- nil, nil, 839, 839, nil, nil, nil, 839, nil, 839,
- 839, 839, 839, 839, 839, 839, nil, nil, nil, nil,
- nil, 839, 839, 839, 839, 839, 839, 839, nil, nil,
- 839, nil, nil, nil, nil, nil, 839, 839, 839, 839,
- 839, 839, 839, 839, 839, 839, 839, 839, nil, 839,
- 839, 839, nil, 839, 839, nil, 839, 839, 839, 461,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 461, 461, nil, 839, nil,
- nil, 839, nil, nil, 839, 839, nil, nil, 839, nil,
- 839, 461, nil, 461, 839, 461, 461, nil, 461, 461,
- nil, nil, 461, 839, 461, nil, nil, nil, 839, 839,
- 839, 839, nil, 839, 839, 839, 839, nil, nil, nil,
- nil, 839, 839, nil, nil, nil, nil, nil, nil, 839,
- nil, 839, 839, 839, 840, 840, 840, 840, 840, 840,
- nil, nil, nil, 840, 840, nil, nil, nil, 840, nil,
- 840, 840, 840, 840, 840, 840, 840, nil, nil, nil,
- nil, nil, 840, 840, 840, 840, 840, 840, 840, nil,
- nil, 840, nil, nil, nil, nil, nil, 840, 840, 840,
- 840, 840, 840, 840, 840, 840, 840, 840, 840, nil,
- 840, 840, 840, nil, 840, 840, nil, 840, 840, 840,
- 462, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 462, 462, nil, 840,
- nil, nil, 840, nil, nil, 840, 840, nil, nil, 840,
- nil, 840, 462, nil, 462, 840, 462, 462, nil, 462,
- 462, nil, nil, 462, 840, 462, nil, nil, nil, 840,
- 840, 840, 840, nil, 840, 840, 840, 840, nil, nil,
- nil, nil, 840, 840, nil, nil, nil, nil, nil, nil,
- 840, nil, 840, 840, 840, 843, 843, 843, 843, 843,
- 843, nil, nil, nil, 843, 843, nil, nil, nil, 843,
- nil, 843, 843, 843, 843, 843, 843, 843, nil, nil,
- nil, nil, nil, 843, 843, 843, 843, 843, 843, 843,
- nil, nil, 843, nil, nil, nil, nil, nil, 843, 843,
- 843, 843, 843, 843, 843, 843, 843, 843, 843, 843,
- nil, 843, 843, 843, nil, 843, 843, nil, 843, 843,
- 843, 463, 463, 463, 463, 463, 463, 463, nil, nil,
- 463, 463, nil, nil, nil, nil, nil, 463, 463, nil,
- 843, nil, nil, 843, nil, nil, 843, 843, nil, nil,
- 843, nil, 843, 463, nil, 463, 843, 463, 463, nil,
- 463, 463, 463, 463, 463, 843, 463, nil, nil, nil,
- 843, 843, 843, 843, nil, 843, 843, 843, 843, nil,
- nil, nil, nil, 843, 843, nil, nil, nil, nil, nil,
- nil, 843, nil, 843, 843, 843, 849, 849, 849, 849,
- 849, 849, nil, nil, nil, 849, 849, nil, nil, nil,
- 849, nil, 849, 849, 849, 849, 849, 849, 849, nil,
- nil, nil, nil, nil, 849, 849, 849, 849, 849, 849,
- 849, nil, nil, 849, nil, nil, nil, nil, nil, 849,
- 849, 849, 849, 849, 849, 849, 849, 849, 849, 849,
- 849, nil, 849, 849, 849, nil, 849, 849, nil, 849,
- 849, 849, 464, 464, 464, 464, 464, 464, 464, nil,
- nil, 464, 464, nil, nil, nil, nil, nil, 464, 464,
- nil, 849, nil, nil, 849, nil, nil, 849, 849, nil,
- nil, 849, nil, 849, 464, nil, 464, 849, 464, 464,
- nil, 464, 464, 464, 464, 464, 849, 464, nil, nil,
- nil, 849, 849, 849, 849, nil, 849, 849, 849, 849,
- nil, nil, nil, nil, 849, 849, nil, nil, nil, nil,
- nil, nil, 849, nil, 849, 849, 849, 882, 882, 882,
- 882, 882, 882, nil, nil, nil, 882, 882, nil, nil,
- nil, 882, nil, 882, 882, 882, 882, 882, 882, 882,
- nil, nil, nil, nil, nil, 882, 882, 882, 882, 882,
- 882, 882, nil, nil, 882, nil, nil, nil, nil, nil,
- 882, 882, 882, 882, 882, 882, 882, 882, 882, 882,
- 882, 882, nil, 882, 882, 882, nil, 882, 882, nil,
- 882, 882, 882, 465, 465, 465, 465, 465, 465, 465,
- nil, nil, 465, 465, nil, nil, nil, nil, nil, 465,
- 465, nil, 882, nil, nil, 882, nil, nil, 882, 882,
- nil, nil, 882, nil, 882, 465, nil, 465, 882, 465,
- 465, nil, 465, 465, 465, 465, 465, 882, 465, nil,
- nil, nil, 882, 882, 882, 882, nil, 882, 882, 882,
- 882, nil, nil, nil, nil, 882, 882, nil, nil, nil,
- nil, nil, nil, 882, nil, 882, 882, 882, 943, 943,
- 943, 943, 943, 943, nil, nil, nil, 943, 943, nil,
- nil, nil, 943, nil, 943, 943, 943, 943, 943, 943,
- 943, nil, nil, nil, nil, nil, 943, 943, 943, 943,
- 943, 943, 943, nil, nil, 943, nil, nil, nil, nil,
- nil, 943, 943, 943, 943, 943, 943, 943, 943, 943,
- 943, 943, 943, nil, 943, 943, 943, nil, 943, 943,
- nil, 943, 943, 943, 466, 466, 466, 466, 466, 466,
- 466, nil, nil, 466, 466, nil, nil, nil, nil, nil,
- 466, 466, nil, 943, nil, nil, 943, nil, nil, 943,
- 943, nil, nil, 943, nil, 943, 466, nil, 466, 943,
- 466, 466, nil, 466, 466, 466, 466, 466, 943, 466,
- nil, nil, nil, 943, 943, 943, 943, nil, 943, 943,
- 943, 943, nil, nil, nil, nil, 943, 943, nil, nil,
- nil, nil, nil, nil, 943, nil, 943, 943, 943, 960,
- 960, 960, 960, 960, 960, nil, nil, nil, 960, 960,
- nil, nil, nil, 960, nil, 960, 960, 960, 960, 960,
- 960, 960, nil, nil, nil, nil, nil, 960, 960, 960,
- 960, 960, 960, 960, nil, nil, 960, nil, nil, nil,
- nil, nil, 960, 960, 960, 960, 960, 960, 960, 960,
- 960, 960, 960, 960, nil, 960, 960, 960, nil, 960,
- 960, nil, 960, 960, 960, 467, 467, 467, 467, 467,
- 467, 467, nil, nil, 467, 467, nil, nil, nil, nil,
- nil, 467, 467, nil, 960, nil, nil, 960, nil, nil,
- 960, 960, nil, nil, 960, nil, 960, 467, nil, 467,
- 960, 467, 467, nil, 467, 467, 467, 467, 467, 960,
- 467, nil, nil, nil, 960, 960, 960, 960, nil, 960,
- 960, 960, 960, nil, nil, nil, nil, 960, 960, nil,
- nil, nil, nil, nil, nil, 960, nil, 960, 960, 960,
- 966, 966, 966, 966, 966, 966, nil, nil, nil, 966,
- 966, nil, nil, nil, 966, nil, 966, 966, 966, 966,
- 966, 966, 966, nil, nil, nil, nil, nil, 966, 966,
- 966, 966, 966, 966, 966, nil, nil, 966, nil, nil,
- nil, nil, nil, 966, 966, 966, 966, 966, 966, 966,
- 966, 966, 966, 966, 966, nil, 966, 966, 966, nil,
- 966, 966, nil, 966, 966, 966, 470, 470, 470, 470,
- 470, 470, 470, nil, nil, 470, 470, nil, nil, nil,
- nil, nil, 470, 470, nil, 966, nil, nil, 966, nil,
- nil, 966, 966, nil, nil, 966, nil, 966, 470, nil,
- 470, 966, 470, 470, nil, 470, 470, 470, 470, 470,
- 966, 470, nil, nil, nil, 966, 966, 966, 966, nil,
- 966, 966, 966, 966, nil, nil, nil, nil, 966, 966,
- nil, nil, nil, nil, nil, nil, 966, nil, 966, 966,
- 966, 968, 968, 968, 968, 968, 968, nil, nil, nil,
- 968, 968, nil, nil, nil, 968, nil, 968, 968, 968,
- 968, 968, 968, 968, nil, nil, nil, nil, nil, 968,
- 968, 968, 968, 968, 968, 968, nil, nil, 968, nil,
- nil, nil, nil, nil, 968, 968, 968, 968, 968, 968,
- 968, 968, 968, 968, 968, 968, nil, 968, 968, 968,
- nil, 968, 968, nil, 968, 968, 968, 471, 471, 471,
- 471, 471, 471, 471, 471, nil, 471, 471, nil, nil,
- nil, nil, nil, 471, 471, nil, 968, nil, nil, 968,
- nil, nil, 968, 968, nil, nil, 968, nil, 968, 471,
- nil, 471, 968, 471, 471, nil, 471, 471, 471, 471,
- 471, 968, 471, nil, nil, nil, 968, 968, 968, 968,
- nil, 968, 968, 968, 968, nil, nil, nil, nil, 968,
- 968, nil, nil, nil, nil, nil, nil, 968, nil, 968,
- 968, 968, 5, 5, 5, 5, 5, nil, nil, nil,
- 5, 5, nil, nil, nil, 5, nil, 5, 5, 5,
- 5, 5, 5, 5, nil, nil, nil, nil, nil, 5,
- 5, 5, 5, 5, 5, 5, nil, nil, 5, nil,
- nil, nil, nil, nil, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, nil, 5, 5, 5,
- nil, 5, 5, nil, 5, 5, 5, 455, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 455, 455, nil, 5, nil, nil, 5,
- nil, nil, 5, 5, nil, nil, 5, nil, 5, 455,
- nil, 455, 5, 455, 455, nil, 455, 455, nil, nil,
- nil, 5, nil, nil, nil, nil, 5, 5, 5, 5,
- nil, 5, 5, 5, 5, nil, nil, nil, nil, 5,
- 5, nil, nil, nil, 20, 20, 20, 5, 20, 5,
- 5, 5, 20, 20, nil, nil, nil, 20, nil, 20,
- 20, 20, 20, 20, 20, 20, nil, nil, nil, nil,
- nil, 20, 20, 20, 20, 20, 20, 20, nil, nil,
- 20, nil, nil, nil, nil, nil, nil, 20, nil, nil,
- 20, 20, 20, 20, 20, 20, 20, 20, nil, 20,
- 20, 20, nil, 20, 20, nil, 20, 20, 20, 456,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 456, 456, nil, 20, nil,
- nil, 20, nil, nil, 20, 20, nil, nil, 20, nil,
- nil, 456, nil, 456, 20, 456, 456, nil, 456, 456,
- nil, nil, nil, 20, nil, nil, nil, nil, 20, 20,
- 20, 20, nil, 20, 20, 20, 20, nil, nil, nil,
- nil, 20, 20, nil, nil, nil, 29, 29, 29, 20,
- 29, 20, 20, 20, 29, 29, nil, nil, nil, 29,
- nil, 29, 29, 29, 29, 29, 29, 29, nil, nil,
- nil, nil, nil, 29, 29, 29, 29, 29, 29, 29,
- nil, nil, 29, nil, nil, nil, nil, nil, nil, 29,
- nil, nil, 29, 29, 29, 29, 29, 29, 29, 29,
- 29, 29, 29, 29, nil, 29, 29, nil, 29, 29,
- 29, 457, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 457, 457, nil,
- 29, nil, nil, 29, nil, nil, 29, 29, nil, nil,
- 29, nil, 29, 457, 29, nil, 29, 457, 457, 29,
- 457, 457, nil, nil, nil, 29, nil, nil, nil, nil,
- 29, 29, 29, 29, nil, 29, 29, 29, 29, nil,
- nil, nil, nil, 29, 29, nil, nil, nil, 30, 30,
- 30, 29, 30, 29, 29, 29, 30, 30, nil, nil,
- nil, 30, nil, 30, 30, 30, 30, 30, 30, 30,
- nil, nil, nil, nil, nil, 30, 30, 30, 30, 30,
- 30, 30, nil, nil, 30, nil, nil, nil, nil, nil,
- nil, 30, nil, nil, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, nil, 30, 30, nil,
- 30, 30, 30, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 30, nil, nil, 30, nil, nil, 30, 30,
- nil, nil, 30, nil, 30, nil, 30, nil, 30, nil,
- nil, 30, nil, nil, nil, nil, nil, 30, nil, nil,
- nil, nil, 30, 30, 30, 30, nil, 30, 30, 30,
- 30, nil, nil, nil, nil, 30, 30, nil, nil, nil,
- 31, 31, 31, 30, 31, 30, 30, 30, 31, 31,
- nil, nil, nil, 31, nil, 31, 31, 31, 31, 31,
- 31, 31, nil, nil, nil, nil, nil, 31, 31, 31,
- 31, 31, 31, 31, nil, nil, 31, nil, nil, nil,
- nil, nil, nil, 31, nil, nil, 31, 31, 31, 31,
- 31, 31, 31, 31, 31, 31, 31, 31, nil, 31,
- 31, nil, 31, 31, 31, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 31, nil, nil, 31, nil, nil,
- 31, 31, nil, nil, 31, nil, 31, nil, 31, nil,
- 31, nil, nil, 31, nil, nil, nil, nil, nil, 31,
- nil, nil, nil, nil, 31, 31, 31, 31, nil, 31,
- 31, 31, 31, nil, nil, nil, nil, 31, 31, nil,
- nil, nil, 34, 34, 34, 31, 34, 31, 31, 31,
- 34, 34, nil, nil, nil, 34, nil, 34, 34, 34,
- 34, 34, 34, 34, nil, nil, nil, nil, nil, 34,
- 34, 34, 34, 34, 34, 34, nil, nil, 34, nil,
- nil, nil, nil, nil, nil, 34, nil, nil, 34, 34,
- 34, 34, 34, 34, 34, 34, nil, 34, 34, 34,
- nil, 34, 34, nil, nil, nil, 34, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 34, nil, nil, 34,
- nil, nil, 34, 34, nil, nil, 34, nil, 34, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 34, 34, 34, 34,
- nil, 34, 34, 34, 34, nil, nil, nil, nil, 34,
- 34, nil, nil, nil, 35, 35, 35, 34, 35, 34,
- 34, 34, 35, 35, nil, nil, nil, 35, nil, 35,
- 35, 35, 35, 35, 35, 35, nil, nil, nil, nil,
- nil, 35, 35, 35, 35, 35, 35, 35, nil, nil,
- 35, nil, nil, nil, nil, nil, nil, 35, nil, nil,
- 35, 35, 35, 35, 35, 35, 35, 35, nil, 35,
- 35, 35, nil, 35, 35, nil, nil, nil, 35, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 35, nil,
- nil, 35, nil, nil, 35, 35, nil, nil, 35, nil,
- 697, nil, 697, 697, 697, 697, 697, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 697, nil, 35, 35,
- 35, 35, nil, 35, 35, 35, 35, nil, nil, nil,
- nil, 35, 35, nil, nil, nil, 35, nil, 697, 35,
- nil, 35, 35, 35, 42, 42, 42, nil, 42, 697,
- 697, nil, 42, 42, 697, nil, nil, 42, nil, 42,
- 42, 42, 42, 42, 42, 42, nil, nil, nil, nil,
- nil, 42, 42, 42, 42, 42, 42, 42, nil, nil,
- 42, nil, nil, nil, nil, nil, nil, 42, nil, nil,
- 42, 42, 42, 42, 42, 42, 42, 42, nil, 42,
- 42, 42, nil, 42, 42, nil, 42, 42, 42, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 42, nil,
- nil, 42, nil, nil, 42, 42, nil, nil, 42, nil,
- nil, nil, nil, nil, 42, nil, nil, nil, nil, nil,
- nil, nil, nil, 42, nil, nil, nil, nil, 42, 42,
- 42, 42, nil, 42, 42, 42, 42, nil, nil, nil,
- nil, 42, 42, nil, nil, nil, 43, 43, 43, 42,
- 43, 42, 42, 42, 43, 43, nil, nil, nil, 43,
- nil, 43, 43, 43, 43, 43, 43, 43, nil, nil,
- nil, nil, nil, 43, 43, 43, 43, 43, 43, 43,
- nil, nil, 43, nil, nil, nil, nil, nil, nil, 43,
- nil, nil, 43, 43, 43, 43, 43, 43, 43, 43,
- nil, 43, 43, 43, nil, 43, 43, nil, 43, 43,
- 43, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 43, nil, nil, 43, nil, nil, 43, 43, nil, nil,
- 43, nil, nil, nil, nil, nil, 43, nil, nil, nil,
- nil, nil, nil, nil, nil, 43, nil, nil, nil, nil,
- 43, 43, 43, 43, nil, 43, 43, 43, 43, nil,
- nil, nil, nil, 43, 43, nil, nil, nil, 44, 44,
- 44, 43, 44, 43, 43, 43, 44, 44, nil, nil,
- nil, 44, nil, 44, 44, 44, 44, 44, 44, 44,
- nil, nil, nil, nil, nil, 44, 44, 44, 44, 44,
- 44, 44, nil, nil, 44, nil, nil, nil, nil, nil,
- nil, 44, nil, nil, 44, 44, 44, 44, 44, 44,
- 44, 44, nil, 44, 44, 44, nil, 44, 44, nil,
- 44, 44, 44, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 44, nil, nil, 44, nil, nil, 44, 44,
- nil, nil, 44, nil, nil, nil, nil, nil, 44, nil,
- nil, nil, nil, nil, nil, nil, nil, 44, nil, nil,
- nil, nil, 44, 44, 44, 44, nil, 44, 44, 44,
- 44, nil, nil, nil, nil, 44, 44, nil, nil, nil,
- 59, 59, 59, 44, 59, 44, 44, 44, 59, 59,
- nil, nil, nil, 59, nil, 59, 59, 59, 59, 59,
- 59, 59, nil, nil, nil, nil, nil, 59, 59, 59,
- 59, 59, 59, 59, nil, nil, 59, nil, nil, nil,
- nil, nil, nil, 59, nil, nil, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, nil, 59,
- 59, nil, 59, 59, 59, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 59, nil, nil, 59, nil, nil,
- 59, 59, nil, nil, 59, nil, 59, nil, nil, nil,
- 59, nil, nil, 59, nil, nil, nil, nil, nil, 59,
- nil, nil, nil, nil, 59, 59, 59, 59, nil, 59,
- 59, 59, 59, nil, nil, nil, nil, 59, 59, nil,
- nil, nil, 60, 60, 60, 59, 60, 59, 59, 59,
- 60, 60, nil, nil, nil, 60, nil, 60, 60, 60,
- 60, 60, 60, 60, nil, nil, nil, nil, nil, 60,
- 60, 60, 60, 60, 60, 60, nil, nil, 60, nil,
- nil, nil, nil, nil, nil, 60, nil, nil, 60, 60,
- 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
- nil, 60, 60, nil, 60, 60, 60, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 60, nil, nil, 60,
- nil, nil, 60, 60, nil, nil, 60, nil, nil, nil,
- nil, nil, 60, nil, nil, 60, nil, nil, nil, nil,
- nil, 60, nil, nil, nil, nil, 60, 60, 60, 60,
- nil, 60, 60, 60, 60, nil, nil, nil, nil, 60,
- 60, nil, nil, nil, 63, 63, 63, 60, 63, 60,
- 60, 60, 63, 63, nil, nil, nil, 63, nil, 63,
- 63, 63, 63, 63, 63, 63, nil, nil, nil, nil,
- nil, 63, 63, 63, 63, 63, 63, 63, nil, nil,
- 63, nil, nil, nil, nil, nil, nil, 63, nil, nil,
- 63, 63, 63, 63, 63, 63, 63, 63, nil, 63,
- 63, 63, nil, 63, 63, nil, 63, 63, 63, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 63, nil,
- nil, 63, nil, nil, 63, 63, nil, nil, 63, nil,
- nil, nil, nil, nil, 63, nil, nil, nil, nil, nil,
- nil, nil, nil, 63, nil, nil, nil, nil, 63, 63,
- 63, 63, nil, 63, 63, 63, 63, nil, nil, nil,
- nil, 63, 63, nil, nil, nil, 64, 64, 64, 63,
- 64, 63, 63, 63, 64, 64, nil, nil, nil, 64,
- nil, 64, 64, 64, 64, 64, 64, 64, nil, nil,
- nil, nil, nil, 64, 64, 64, 64, 64, 64, 64,
- nil, nil, 64, nil, nil, nil, nil, nil, nil, 64,
- nil, nil, 64, 64, 64, 64, 64, 64, 64, 64,
- nil, 64, 64, 64, nil, 64, 64, nil, 64, 64,
- 64, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 64, nil, nil, 64, nil, nil, 64, 64, nil, nil,
- 64, nil, nil, nil, nil, nil, 64, nil, nil, nil,
- nil, nil, nil, nil, nil, 64, nil, nil, nil, nil,
- 64, 64, 64, 64, nil, 64, 64, 64, 64, nil,
- nil, nil, nil, 64, 64, nil, nil, nil, 67, 67,
- 67, 64, 67, 64, 64, 64, 67, 67, nil, nil,
- nil, 67, nil, 67, 67, 67, 67, 67, 67, 67,
- nil, nil, nil, nil, nil, 67, 67, 67, 67, 67,
- 67, 67, nil, nil, 67, nil, nil, nil, nil, nil,
- nil, 67, nil, nil, 67, 67, 67, 67, 67, 67,
- 67, 67, nil, 67, 67, 67, nil, 67, 67, nil,
- 67, 67, 67, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 67, nil, nil, 67, nil, nil, 67, 67,
- nil, nil, 67, nil, nil, nil, nil, nil, 67, nil,
- nil, nil, nil, nil, nil, nil, nil, 67, nil, nil,
- nil, nil, 67, 67, 67, 67, nil, 67, 67, 67,
- 67, nil, nil, nil, nil, 67, 67, 67, nil, nil,
- nil, nil, 67, 67, nil, 67, 67, 67, 68, 68,
- 68, nil, 68, nil, nil, nil, 68, 68, nil, nil,
- nil, 68, nil, 68, 68, 68, 68, 68, 68, 68,
- nil, nil, nil, nil, nil, 68, 68, 68, 68, 68,
- 68, 68, nil, nil, 68, nil, nil, nil, nil, nil,
- nil, 68, nil, nil, 68, 68, 68, 68, 68, 68,
- 68, 68, nil, 68, 68, 68, nil, 68, 68, nil,
- nil, nil, 68, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 68, nil, nil, 68, nil, nil, 68, 68,
- nil, nil, 68, nil, 68, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 68, 68, 68, 68, nil, 68, 68, 68,
- 68, nil, nil, nil, nil, 68, 68, nil, nil, nil,
- 69, 69, 69, 68, 69, 68, 68, 68, 69, 69,
- nil, nil, nil, 69, nil, 69, 69, 69, 69, 69,
- 69, 69, nil, nil, nil, nil, nil, 69, 69, 69,
- 69, 69, 69, 69, nil, nil, 69, nil, nil, nil,
- nil, nil, nil, 69, nil, nil, 69, 69, 69, 69,
- 69, 69, 69, 69, nil, 69, 69, 69, nil, 69,
- 69, nil, nil, nil, 69, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 69, nil, nil, 69, nil, nil, 69, nil, nil,
- 69, 69, nil, nil, 69, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 69, 69, 69, 69, nil, 69,
- 69, 69, 69, nil, nil, nil, nil, 69, 69, nil,
- nil, nil, 70, 70, 70, 69, 70, 69, 69, 69,
- 70, 70, nil, nil, nil, 70, nil, 70, 70, 70,
- 70, 70, 70, 70, nil, nil, nil, nil, nil, 70,
- 70, 70, 70, 70, 70, 70, nil, nil, 70, nil,
- nil, nil, nil, nil, nil, 70, nil, nil, 70, 70,
- 70, 70, 70, 70, 70, 70, nil, 70, 70, 70,
- nil, 70, 70, nil, nil, nil, 70, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 70, nil, nil, 70,
- nil, nil, 70, 70, nil, nil, 70, nil, 869, nil,
- 869, 869, 869, 869, 869, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 869, nil, 70, 70, 70, 70,
- nil, 70, 70, 70, 70, nil, nil, nil, nil, 70,
- 70, nil, nil, nil, nil, nil, 869, 70, nil, 70,
- 70, 70, 111, 111, 111, 111, 111, 869, 869, nil,
- 111, 111, 869, nil, nil, 111, nil, 111, 111, 111,
- 111, 111, 111, 111, nil, nil, nil, nil, nil, 111,
- 111, 111, 111, 111, 111, 111, nil, nil, 111, nil,
- nil, nil, nil, nil, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 111, nil, 111, 111, 111,
- nil, 111, 111, nil, 111, 111, 111, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 111, nil, nil, 111,
- nil, nil, 111, 111, nil, nil, 111, nil, 111, nil,
- nil, nil, 111, nil, nil, nil, nil, nil, nil, nil,
- nil, 111, nil, nil, nil, nil, 111, 111, 111, 111,
- nil, 111, 111, 111, 111, nil, nil, nil, nil, 111,
- 111, nil, nil, nil, nil, nil, 111, 111, nil, 111,
- 111, 111, 116, 116, 116, nil, 116, nil, nil, nil,
- 116, 116, nil, nil, nil, 116, nil, 116, 116, 116,
- 116, 116, 116, 116, nil, nil, nil, nil, nil, 116,
- 116, 116, 116, 116, 116, 116, nil, nil, 116, nil,
- nil, nil, nil, nil, nil, 116, nil, nil, 116, 116,
- 116, 116, 116, 116, 116, 116, nil, 116, 116, 116,
- nil, 116, 116, nil, 116, 116, 116, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 116, nil, nil, 116,
- nil, nil, 116, 116, nil, nil, 116, nil, nil, nil,
- nil, nil, 116, nil, nil, nil, nil, nil, nil, nil,
- nil, 116, nil, nil, nil, nil, 116, 116, 116, 116,
- nil, 116, 116, 116, 116, nil, nil, nil, nil, 116,
- 116, nil, nil, nil, 117, 117, 117, 116, 117, 116,
- 116, 116, 117, 117, nil, nil, nil, 117, nil, 117,
- 117, 117, 117, 117, 117, 117, nil, nil, nil, nil,
- nil, 117, 117, 117, 117, 117, 117, 117, nil, nil,
- 117, nil, nil, nil, nil, nil, nil, 117, nil, nil,
- 117, 117, 117, 117, 117, 117, 117, 117, nil, 117,
- 117, 117, nil, 117, 117, nil, 117, 117, 117, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 117, nil,
- nil, 117, nil, nil, 117, 117, nil, nil, 117, nil,
- nil, nil, nil, nil, 117, nil, nil, nil, nil, nil,
- nil, nil, nil, 117, nil, nil, nil, nil, 117, 117,
- 117, 117, nil, 117, 117, 117, 117, nil, nil, nil,
- nil, 117, 117, nil, nil, nil, 118, 118, 118, 117,
- 118, 117, 117, 117, 118, 118, nil, nil, nil, 118,
- nil, 118, 118, 118, 118, 118, 118, 118, nil, nil,
- nil, nil, nil, 118, 118, 118, 118, 118, 118, 118,
- nil, nil, 118, nil, nil, nil, nil, nil, nil, 118,
- nil, nil, 118, 118, 118, 118, 118, 118, 118, 118,
- nil, 118, 118, 118, nil, 118, 118, nil, 118, 118,
- 118, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 118, nil, nil, 118, nil, nil, 118, 118, nil, nil,
- 118, nil, nil, nil, nil, nil, 118, nil, nil, nil,
- nil, nil, nil, nil, nil, 118, nil, nil, nil, nil,
- 118, 118, 118, 118, nil, 118, 118, 118, 118, nil,
- nil, nil, nil, 118, 118, nil, nil, nil, 119, 119,
- 119, 118, 119, 118, 118, 118, 119, 119, nil, nil,
- nil, 119, nil, 119, 119, 119, 119, 119, 119, 119,
- nil, nil, nil, nil, nil, 119, 119, 119, 119, 119,
- 119, 119, nil, nil, 119, nil, nil, nil, nil, nil,
- nil, 119, nil, nil, 119, 119, 119, 119, 119, 119,
- 119, 119, nil, 119, 119, 119, nil, 119, 119, nil,
- 119, 119, 119, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 119, nil, nil, 119, nil, nil, 119, 119,
- nil, nil, 119, nil, nil, nil, nil, nil, 119, nil,
- nil, nil, nil, nil, nil, nil, nil, 119, nil, nil,
- nil, nil, 119, 119, 119, 119, nil, 119, 119, 119,
- 119, nil, nil, nil, nil, 119, 119, nil, nil, nil,
- nil, nil, nil, 119, nil, 119, 119, 119, 120, 120,
- 120, 120, 120, nil, nil, nil, 120, 120, nil, nil,
- nil, 120, nil, 120, 120, 120, 120, 120, 120, 120,
- nil, nil, nil, nil, nil, 120, 120, 120, 120, 120,
- 120, 120, nil, nil, 120, nil, nil, nil, nil, nil,
- 120, 120, nil, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, nil, 120, 120, 120, nil, 120, 120, nil,
- 120, 120, 120, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 120, nil, nil, 120, nil, nil, 120, 120,
- nil, nil, 120, nil, 120, nil, nil, nil, 120, nil,
- nil, nil, nil, nil, nil, nil, nil, 120, nil, nil,
- nil, nil, 120, 120, 120, 120, nil, 120, 120, 120,
- 120, nil, nil, nil, nil, 120, 120, nil, nil, nil,
- 207, 207, 207, 120, 207, 120, 120, 120, 207, 207,
- nil, nil, nil, 207, nil, 207, 207, 207, 207, 207,
- 207, 207, nil, nil, nil, nil, nil, 207, 207, 207,
- 207, 207, 207, 207, nil, nil, 207, nil, nil, nil,
- nil, nil, nil, 207, nil, nil, 207, 207, 207, 207,
- 207, 207, 207, 207, nil, 207, 207, 207, nil, 207,
- 207, nil, 207, 207, 207, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 207, nil, nil, 207, nil, nil,
- 207, 207, nil, nil, 207, nil, 207, nil, nil, nil,
- 207, nil, nil, nil, nil, nil, nil, nil, nil, 207,
- nil, nil, nil, nil, 207, 207, 207, 207, nil, 207,
- 207, 207, 207, nil, nil, nil, nil, 207, 207, nil,
- nil, nil, 208, 208, 208, 207, 208, 207, 207, 207,
- 208, 208, nil, nil, nil, 208, nil, 208, 208, 208,
- 208, 208, 208, 208, nil, nil, nil, nil, nil, 208,
- 208, 208, 208, 208, 208, 208, nil, nil, 208, nil,
- nil, nil, nil, nil, nil, 208, nil, nil, 208, 208,
- 208, 208, 208, 208, 208, 208, nil, 208, 208, 208,
- nil, 208, 208, nil, 208, 208, 208, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 208, nil, nil, 208,
- nil, nil, 208, 208, nil, nil, 208, nil, nil, nil,
- nil, nil, 208, nil, nil, nil, nil, nil, nil, nil,
- nil, 208, nil, nil, nil, nil, 208, 208, 208, 208,
- nil, 208, 208, 208, 208, nil, nil, nil, nil, 208,
- 208, nil, nil, nil, 209, 209, 209, 208, 209, 208,
- 208, 208, 209, 209, nil, nil, nil, 209, nil, 209,
- 209, 209, 209, 209, 209, 209, nil, nil, nil, nil,
- nil, 209, 209, 209, 209, 209, 209, 209, nil, nil,
- 209, nil, nil, nil, nil, nil, nil, 209, nil, nil,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, nil, 209, 209, nil, 209, 209, 209, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 209, nil,
- nil, 209, nil, nil, 209, 209, nil, nil, 209, nil,
- 209, nil, 209, nil, 209, nil, nil, 209, nil, nil,
- nil, nil, nil, 209, nil, nil, nil, nil, 209, 209,
- 209, 209, nil, 209, 209, 209, 209, nil, nil, nil,
- nil, 209, 209, nil, nil, nil, 212, 212, 212, 209,
- 212, 209, 209, 209, 212, 212, nil, nil, nil, 212,
- nil, 212, 212, 212, 212, 212, 212, 212, nil, nil,
- nil, nil, nil, 212, 212, 212, 212, 212, 212, 212,
- nil, nil, 212, nil, nil, nil, nil, nil, nil, 212,
- nil, nil, 212, 212, 212, 212, 212, 212, 212, 212,
- nil, 212, 212, 212, nil, 212, 212, nil, 212, 212,
- 212, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 212, nil, nil, 212, nil, nil, 212, 212, nil, nil,
- 212, nil, nil, nil, nil, nil, 212, nil, nil, nil,
- nil, nil, nil, nil, nil, 212, nil, nil, nil, nil,
- 212, 212, 212, 212, nil, 212, 212, 212, 212, nil,
- nil, nil, nil, 212, 212, nil, nil, nil, 213, 213,
- 213, 212, 213, 212, 212, 212, 213, 213, nil, nil,
- nil, 213, nil, 213, 213, 213, 213, 213, 213, 213,
- nil, nil, nil, nil, nil, 213, 213, 213, 213, 213,
- 213, 213, nil, nil, 213, nil, nil, nil, nil, nil,
- nil, 213, nil, nil, 213, 213, 213, 213, 213, 213,
- 213, 213, nil, 213, 213, 213, nil, 213, 213, nil,
- 213, 213, 213, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 213, nil, nil, 213, nil, nil, 213, 213,
- nil, nil, 213, nil, 213, nil, nil, nil, 213, nil,
- nil, nil, nil, nil, nil, nil, nil, 213, nil, nil,
- nil, nil, 213, 213, 213, 213, nil, 213, 213, 213,
- 213, nil, nil, nil, nil, 213, 213, nil, nil, nil,
- 214, 214, 214, 213, 214, 213, 213, 213, 214, 214,
- nil, nil, nil, 214, nil, 214, 214, 214, 214, 214,
- 214, 214, nil, nil, nil, nil, nil, 214, 214, 214,
- 214, 214, 214, 214, nil, nil, 214, nil, nil, nil,
- nil, nil, nil, 214, nil, nil, 214, 214, 214, 214,
- 214, 214, 214, 214, nil, 214, 214, 214, nil, 214,
- 214, nil, 214, 214, 214, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 214, nil, nil, 214, nil, nil,
- 214, 214, nil, nil, 214, nil, nil, nil, nil, nil,
- 214, nil, nil, nil, nil, nil, nil, nil, nil, 214,
- nil, nil, nil, nil, 214, 214, 214, 214, nil, 214,
- 214, 214, 214, nil, nil, nil, nil, 214, 214, nil,
- nil, nil, 215, 215, 215, 214, 215, 214, 214, 214,
- 215, 215, nil, nil, nil, 215, nil, 215, 215, 215,
- 215, 215, 215, 215, nil, nil, nil, nil, nil, 215,
- 215, 215, 215, 215, 215, 215, nil, nil, 215, nil,
- nil, nil, nil, nil, nil, 215, nil, nil, 215, 215,
- 215, 215, 215, 215, 215, 215, nil, 215, 215, 215,
- nil, 215, 215, nil, 215, 215, 215, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 215, nil, nil, 215,
- nil, nil, 215, 215, nil, nil, 215, nil, nil, nil,
- nil, nil, 215, nil, nil, nil, nil, nil, nil, nil,
- nil, 215, nil, nil, nil, nil, 215, 215, 215, 215,
- nil, 215, 215, 215, 215, nil, nil, nil, nil, 215,
- 215, nil, nil, nil, 216, 216, 216, 215, 216, 215,
- 215, 215, 216, 216, nil, nil, nil, 216, nil, 216,
- 216, 216, 216, 216, 216, 216, nil, nil, nil, nil,
- nil, 216, 216, 216, 216, 216, 216, 216, nil, nil,
- 216, nil, nil, nil, nil, nil, nil, 216, nil, nil,
- 216, 216, 216, 216, 216, 216, 216, 216, nil, 216,
- 216, 216, nil, 216, 216, nil, 216, 216, 216, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 216, nil,
- nil, 216, nil, nil, 216, 216, nil, nil, 216, nil,
- nil, nil, nil, nil, 216, nil, nil, nil, nil, nil,
- nil, nil, nil, 216, nil, nil, nil, nil, 216, 216,
- 216, 216, nil, 216, 216, 216, 216, nil, nil, nil,
- nil, 216, 216, nil, nil, nil, 217, 217, 217, 216,
- 217, 216, 216, 216, 217, 217, nil, nil, nil, 217,
- nil, 217, 217, 217, 217, 217, 217, 217, nil, nil,
- nil, nil, nil, 217, 217, 217, 217, 217, 217, 217,
- nil, nil, 217, nil, nil, nil, nil, nil, nil, 217,
- nil, nil, 217, 217, 217, 217, 217, 217, 217, 217,
- nil, 217, 217, 217, nil, 217, 217, nil, 217, 217,
- 217, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 217, nil, nil, 217, nil, nil, 217, 217, nil, nil,
- 217, nil, nil, nil, nil, nil, 217, nil, nil, nil,
- nil, nil, nil, nil, nil, 217, nil, nil, nil, nil,
- 217, 217, 217, 217, nil, 217, 217, 217, 217, nil,
- nil, nil, nil, 217, 217, 217, nil, nil, 228, 228,
- 228, 217, 228, 217, 217, 217, 228, 228, nil, nil,
- nil, 228, nil, 228, 228, 228, 228, 228, 228, 228,
- nil, nil, nil, nil, nil, 228, 228, 228, 228, 228,
- 228, 228, nil, nil, 228, nil, nil, nil, nil, nil,
- nil, 228, nil, nil, 228, 228, 228, 228, 228, 228,
- 228, 228, nil, 228, 228, 228, nil, 228, 228, nil,
- 228, 228, 228, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 228, nil, nil, 228, nil, nil, 228, 228,
- nil, nil, 228, nil, nil, nil, nil, nil, 228, nil,
- nil, nil, nil, nil, nil, nil, nil, 228, nil, nil,
- nil, nil, 228, 228, 228, 228, nil, 228, 228, 228,
- 228, nil, nil, nil, nil, 228, 228, nil, nil, nil,
- 231, 231, 231, 228, 231, 228, 228, 228, 231, 231,
- nil, nil, nil, 231, nil, 231, 231, 231, 231, 231,
- 231, 231, nil, nil, nil, nil, nil, 231, 231, 231,
- 231, 231, 231, 231, nil, nil, 231, nil, nil, nil,
- nil, nil, nil, 231, nil, nil, 231, 231, 231, 231,
- 231, 231, 231, 231, nil, 231, 231, 231, nil, 231,
- 231, nil, 231, 231, 231, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 231, nil, nil, 231, nil, nil,
- 231, 231, nil, nil, 231, nil, nil, nil, nil, nil,
- 231, nil, nil, nil, nil, nil, nil, nil, nil, 231,
- nil, nil, nil, nil, 231, 231, 231, 231, nil, 231,
- 231, 231, 231, nil, nil, nil, nil, 231, 231, nil,
- nil, nil, 232, 232, 232, 231, 232, 231, 231, 231,
- 232, 232, nil, nil, nil, 232, nil, 232, 232, 232,
- 232, 232, 232, 232, nil, nil, nil, nil, nil, 232,
- 232, 232, 232, 232, 232, 232, nil, nil, 232, nil,
- nil, nil, nil, nil, nil, 232, nil, nil, 232, 232,
- 232, 232, 232, 232, 232, 232, nil, 232, 232, 232,
- nil, 232, 232, nil, 232, 232, 232, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 232, nil, nil, 232,
- nil, nil, 232, 232, nil, nil, 232, nil, nil, nil,
- nil, nil, 232, nil, nil, nil, nil, nil, nil, nil,
- nil, 232, nil, nil, nil, nil, 232, 232, 232, 232,
- nil, 232, 232, 232, 232, nil, nil, nil, nil, 232,
- 232, nil, nil, nil, 233, 233, 233, 232, 233, 232,
- 232, 232, 233, 233, nil, nil, nil, 233, nil, 233,
- 233, 233, 233, 233, 233, 233, nil, nil, nil, nil,
- nil, 233, 233, 233, 233, 233, 233, 233, nil, nil,
- 233, nil, nil, nil, nil, nil, nil, 233, nil, nil,
- 233, 233, 233, 233, 233, 233, 233, 233, nil, 233,
- 233, 233, nil, 233, 233, nil, 233, 233, 233, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 233, nil,
- nil, 233, nil, nil, 233, 233, nil, nil, 233, nil,
- nil, nil, nil, nil, 233, nil, nil, nil, nil, nil,
- nil, nil, nil, 233, nil, nil, nil, nil, 233, 233,
- 233, 233, nil, 233, 233, 233, 233, nil, nil, nil,
- nil, 233, 233, nil, nil, nil, 234, 234, 234, 233,
- 234, 233, 233, 233, 234, 234, nil, nil, nil, 234,
- nil, 234, 234, 234, 234, 234, 234, 234, nil, nil,
- nil, nil, nil, 234, 234, 234, 234, 234, 234, 234,
- nil, nil, 234, nil, nil, nil, nil, nil, nil, 234,
- nil, nil, 234, 234, 234, 234, 234, 234, 234, 234,
- nil, 234, 234, 234, nil, 234, 234, nil, 234, 234,
- 234, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 234, nil, nil, 234, nil, nil, 234, 234, nil, nil,
- 234, nil, nil, nil, nil, nil, 234, nil, nil, nil,
- nil, nil, nil, nil, nil, 234, nil, nil, nil, nil,
- 234, 234, 234, 234, nil, 234, 234, 234, 234, nil,
- nil, nil, nil, 234, 234, nil, nil, nil, 235, 235,
- 235, 234, 235, 234, 234, 234, 235, 235, nil, nil,
- nil, 235, nil, 235, 235, 235, 235, 235, 235, 235,
- nil, nil, nil, nil, nil, 235, 235, 235, 235, 235,
- 235, 235, nil, nil, 235, nil, nil, nil, nil, nil,
- nil, 235, nil, nil, 235, 235, 235, 235, 235, 235,
- 235, 235, nil, 235, 235, 235, nil, 235, 235, nil,
- 235, 235, 235, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 235, nil, nil, 235, nil, nil, 235, 235,
- nil, nil, 235, nil, nil, nil, nil, nil, 235, nil,
- nil, nil, nil, nil, nil, nil, nil, 235, nil, nil,
- nil, nil, 235, 235, 235, 235, nil, 235, 235, 235,
- 235, nil, nil, nil, nil, 235, 235, nil, nil, nil,
- 236, 236, 236, 235, 236, 235, 235, 235, 236, 236,
- nil, nil, nil, 236, nil, 236, 236, 236, 236, 236,
- 236, 236, nil, nil, nil, nil, nil, 236, 236, 236,
- 236, 236, 236, 236, nil, nil, 236, nil, nil, nil,
- nil, nil, nil, 236, nil, nil, 236, 236, 236, 236,
- 236, 236, 236, 236, nil, 236, 236, 236, nil, 236,
- 236, nil, 236, 236, 236, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 236, nil, nil, 236, nil, nil,
- 236, 236, nil, nil, 236, nil, nil, nil, nil, nil,
- 236, nil, nil, nil, nil, nil, nil, nil, nil, 236,
- nil, nil, nil, nil, 236, 236, 236, 236, nil, 236,
- 236, 236, 236, nil, nil, nil, nil, 236, 236, nil,
- nil, nil, 237, 237, 237, 236, 237, 236, 236, 236,
- 237, 237, nil, nil, nil, 237, nil, 237, 237, 237,
- 237, 237, 237, 237, nil, nil, nil, nil, nil, 237,
- 237, 237, 237, 237, 237, 237, nil, nil, 237, nil,
- nil, nil, nil, nil, nil, 237, nil, nil, 237, 237,
- 237, 237, 237, 237, 237, 237, nil, 237, 237, 237,
- nil, 237, 237, nil, 237, 237, 237, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 237, nil, nil, 237,
- nil, nil, 237, 237, nil, nil, 237, nil, nil, nil,
- nil, nil, 237, nil, nil, nil, nil, nil, nil, nil,
- nil, 237, nil, nil, nil, nil, 237, 237, 237, 237,
- nil, 237, 237, 237, 237, nil, nil, nil, nil, 237,
- 237, nil, nil, nil, 238, 238, 238, 237, 238, 237,
- 237, 237, 238, 238, nil, nil, nil, 238, nil, 238,
- 238, 238, 238, 238, 238, 238, nil, nil, nil, nil,
- nil, 238, 238, 238, 238, 238, 238, 238, nil, nil,
- 238, nil, nil, nil, nil, nil, nil, 238, nil, nil,
- 238, 238, 238, 238, 238, 238, 238, 238, nil, 238,
- 238, 238, nil, 238, 238, nil, 238, 238, 238, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 238, nil,
- nil, 238, nil, nil, 238, 238, nil, nil, 238, nil,
- nil, nil, nil, nil, 238, nil, nil, nil, nil, nil,
- nil, nil, nil, 238, nil, nil, nil, nil, 238, 238,
- 238, 238, nil, 238, 238, 238, 238, nil, nil, nil,
- nil, 238, 238, nil, nil, nil, 239, 239, 239, 238,
- 239, 238, 238, 238, 239, 239, nil, nil, nil, 239,
- nil, 239, 239, 239, 239, 239, 239, 239, nil, nil,
- nil, nil, nil, 239, 239, 239, 239, 239, 239, 239,
- nil, nil, 239, nil, nil, nil, nil, nil, nil, 239,
- nil, nil, 239, 239, 239, 239, 239, 239, 239, 239,
- nil, 239, 239, 239, nil, 239, 239, nil, 239, 239,
- 239, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 239, nil, nil, 239, nil, nil, 239, 239, nil, nil,
- 239, nil, nil, nil, nil, nil, 239, nil, nil, nil,
- nil, nil, nil, nil, nil, 239, nil, nil, nil, nil,
- 239, 239, 239, 239, nil, 239, 239, 239, 239, nil,
- nil, nil, nil, 239, 239, nil, nil, nil, 240, 240,
- 240, 239, 240, 239, 239, 239, 240, 240, nil, nil,
- nil, 240, nil, 240, 240, 240, 240, 240, 240, 240,
- nil, nil, nil, nil, nil, 240, 240, 240, 240, 240,
- 240, 240, nil, nil, 240, nil, nil, nil, nil, nil,
- nil, 240, nil, nil, 240, 240, 240, 240, 240, 240,
- 240, 240, nil, 240, 240, 240, nil, 240, 240, nil,
- 240, 240, 240, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 240, nil, nil, 240, nil, nil, 240, 240,
- nil, nil, 240, nil, nil, nil, nil, nil, 240, nil,
- nil, nil, nil, nil, nil, nil, nil, 240, nil, nil,
- nil, nil, 240, 240, 240, 240, nil, 240, 240, 240,
- 240, nil, nil, nil, nil, 240, 240, nil, nil, nil,
- 241, 241, 241, 240, 241, 240, 240, 240, 241, 241,
- nil, nil, nil, 241, nil, 241, 241, 241, 241, 241,
- 241, 241, nil, nil, nil, nil, nil, 241, 241, 241,
- 241, 241, 241, 241, nil, nil, 241, nil, nil, nil,
- nil, nil, nil, 241, nil, nil, 241, 241, 241, 241,
- 241, 241, 241, 241, nil, 241, 241, 241, nil, 241,
- 241, nil, 241, 241, 241, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 241, nil, nil, 241, nil, nil,
- 241, 241, nil, nil, 241, nil, nil, nil, nil, nil,
- 241, nil, nil, nil, nil, nil, nil, nil, nil, 241,
- nil, nil, nil, nil, 241, 241, 241, 241, nil, 241,
- 241, 241, 241, nil, nil, nil, nil, 241, 241, nil,
- nil, nil, 242, 242, 242, 241, 242, 241, 241, 241,
- 242, 242, nil, nil, nil, 242, nil, 242, 242, 242,
- 242, 242, 242, 242, nil, nil, nil, nil, nil, 242,
- 242, 242, 242, 242, 242, 242, nil, nil, 242, nil,
- nil, nil, nil, nil, nil, 242, nil, nil, 242, 242,
- 242, 242, 242, 242, 242, 242, nil, 242, 242, 242,
- nil, 242, 242, nil, 242, 242, 242, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 242, nil, nil, 242,
- nil, nil, 242, 242, nil, nil, 242, nil, nil, nil,
- nil, nil, 242, nil, nil, nil, nil, nil, nil, nil,
- nil, 242, nil, nil, nil, nil, 242, 242, 242, 242,
- nil, 242, 242, 242, 242, nil, nil, nil, nil, 242,
- 242, nil, nil, nil, 243, 243, 243, 242, 243, 242,
- 242, 242, 243, 243, nil, nil, nil, 243, nil, 243,
- 243, 243, 243, 243, 243, 243, nil, nil, nil, nil,
- nil, 243, 243, 243, 243, 243, 243, 243, nil, nil,
- 243, nil, nil, nil, nil, nil, nil, 243, nil, nil,
- 243, 243, 243, 243, 243, 243, 243, 243, nil, 243,
- 243, 243, nil, 243, 243, nil, 243, 243, 243, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 243, nil,
- nil, 243, nil, nil, 243, 243, nil, nil, 243, nil,
- nil, nil, nil, nil, 243, nil, nil, nil, nil, nil,
- nil, nil, nil, 243, nil, nil, nil, nil, 243, 243,
- 243, 243, nil, 243, 243, 243, 243, nil, nil, nil,
- nil, 243, 243, nil, nil, nil, 244, 244, 244, 243,
- 244, 243, 243, 243, 244, 244, nil, nil, nil, 244,
- nil, 244, 244, 244, 244, 244, 244, 244, nil, nil,
- nil, nil, nil, 244, 244, 244, 244, 244, 244, 244,
- nil, nil, 244, nil, nil, nil, nil, nil, nil, 244,
- nil, nil, 244, 244, 244, 244, 244, 244, 244, 244,
- nil, 244, 244, 244, nil, 244, 244, nil, 244, 244,
- 244, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 244, nil, nil, 244, nil, nil, 244, 244, nil, nil,
- 244, nil, nil, nil, nil, nil, 244, nil, nil, nil,
- nil, nil, nil, nil, nil, 244, nil, nil, nil, nil,
- 244, 244, 244, 244, nil, 244, 244, 244, 244, nil,
- nil, nil, nil, 244, 244, nil, nil, nil, 245, 245,
- 245, 244, 245, 244, 244, 244, 245, 245, nil, nil,
- nil, 245, nil, 245, 245, 245, 245, 245, 245, 245,
- nil, nil, nil, nil, nil, 245, 245, 245, 245, 245,
- 245, 245, nil, nil, 245, nil, nil, nil, nil, nil,
- nil, 245, nil, nil, 245, 245, 245, 245, 245, 245,
- 245, 245, nil, 245, 245, 245, nil, 245, 245, nil,
- 245, 245, 245, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 245, nil, nil, 245, nil, nil, 245, 245,
- nil, nil, 245, nil, nil, nil, nil, nil, 245, nil,
- nil, nil, nil, nil, nil, nil, nil, 245, nil, nil,
- nil, nil, 245, 245, 245, 245, nil, 245, 245, 245,
- 245, nil, nil, nil, nil, 245, 245, nil, nil, nil,
- 246, 246, 246, 245, 246, 245, 245, 245, 246, 246,
- nil, nil, nil, 246, nil, 246, 246, 246, 246, 246,
- 246, 246, nil, nil, nil, nil, nil, 246, 246, 246,
- 246, 246, 246, 246, nil, nil, 246, nil, nil, nil,
- nil, nil, nil, 246, nil, nil, 246, 246, 246, 246,
- 246, 246, 246, 246, nil, 246, 246, 246, nil, 246,
- 246, nil, 246, 246, 246, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 246, nil, nil, 246, nil, nil,
- 246, 246, nil, nil, 246, nil, nil, nil, nil, nil,
- 246, nil, nil, nil, nil, nil, nil, nil, nil, 246,
- nil, nil, nil, nil, 246, 246, 246, 246, nil, 246,
- 246, 246, 246, nil, nil, nil, nil, 246, 246, nil,
- nil, nil, 247, 247, 247, 246, 247, 246, 246, 246,
- 247, 247, nil, nil, nil, 247, nil, 247, 247, 247,
- 247, 247, 247, 247, nil, nil, nil, nil, nil, 247,
- 247, 247, 247, 247, 247, 247, nil, nil, 247, nil,
- nil, nil, nil, nil, nil, 247, nil, nil, 247, 247,
- 247, 247, 247, 247, 247, 247, nil, 247, 247, 247,
- nil, 247, 247, nil, 247, 247, 247, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 247, nil, nil, 247,
- nil, nil, 247, 247, nil, nil, 247, nil, nil, nil,
- nil, nil, 247, nil, nil, nil, nil, nil, nil, nil,
- nil, 247, nil, nil, nil, nil, 247, 247, 247, 247,
- nil, 247, 247, 247, 247, nil, nil, nil, nil, 247,
- 247, nil, nil, nil, 248, 248, 248, 247, 248, 247,
- 247, 247, 248, 248, nil, nil, nil, 248, nil, 248,
- 248, 248, 248, 248, 248, 248, nil, nil, nil, nil,
- nil, 248, 248, 248, 248, 248, 248, 248, nil, nil,
- 248, nil, nil, nil, nil, nil, nil, 248, nil, nil,
- 248, 248, 248, 248, 248, 248, 248, 248, nil, 248,
- 248, 248, nil, 248, 248, nil, 248, 248, 248, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 248, nil,
- nil, 248, nil, nil, 248, 248, nil, nil, 248, nil,
- nil, nil, nil, nil, 248, nil, nil, nil, nil, nil,
- nil, nil, nil, 248, nil, nil, nil, nil, 248, 248,
- 248, 248, nil, 248, 248, 248, 248, nil, nil, nil,
- nil, 248, 248, nil, nil, nil, 249, 249, 249, 248,
- 249, 248, 248, 248, 249, 249, nil, nil, nil, 249,
- nil, 249, 249, 249, 249, 249, 249, 249, nil, nil,
- nil, nil, nil, 249, 249, 249, 249, 249, 249, 249,
- nil, nil, 249, nil, nil, nil, nil, nil, nil, 249,
- nil, nil, 249, 249, 249, 249, 249, 249, 249, 249,
- nil, 249, 249, 249, nil, 249, 249, nil, 249, 249,
- 249, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 249, nil, nil, 249, nil, nil, 249, 249, nil, nil,
- 249, nil, nil, nil, nil, nil, 249, nil, nil, nil,
- nil, nil, nil, nil, nil, 249, nil, nil, nil, nil,
- 249, 249, 249, 249, nil, 249, 249, 249, 249, nil,
- nil, nil, nil, 249, 249, nil, nil, nil, 250, 250,
- 250, 249, 250, 249, 249, 249, 250, 250, nil, nil,
- nil, 250, nil, 250, 250, 250, 250, 250, 250, 250,
- nil, nil, nil, nil, nil, 250, 250, 250, 250, 250,
- 250, 250, nil, nil, 250, nil, nil, nil, nil, nil,
- nil, 250, nil, nil, 250, 250, 250, 250, 250, 250,
- 250, 250, nil, 250, 250, 250, nil, 250, 250, nil,
- 250, 250, 250, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 250, nil, nil, 250, nil, nil, 250, 250,
- nil, nil, 250, nil, nil, nil, nil, nil, 250, nil,
- nil, nil, nil, nil, nil, nil, nil, 250, nil, nil,
- nil, nil, 250, 250, 250, 250, nil, 250, 250, 250,
- 250, nil, nil, nil, nil, 250, 250, nil, nil, nil,
- 251, 251, 251, 250, 251, 250, 250, 250, 251, 251,
- nil, nil, nil, 251, nil, 251, 251, 251, 251, 251,
- 251, 251, nil, nil, nil, nil, nil, 251, 251, 251,
- 251, 251, 251, 251, nil, nil, 251, nil, nil, nil,
- nil, nil, nil, 251, nil, nil, 251, 251, 251, 251,
- 251, 251, 251, 251, nil, 251, 251, 251, nil, 251,
- 251, nil, 251, 251, 251, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 251, nil, nil, 251, nil, nil,
- 251, 251, nil, nil, 251, nil, nil, nil, nil, nil,
- 251, nil, nil, nil, nil, nil, nil, nil, nil, 251,
- nil, nil, nil, nil, 251, 251, 251, 251, nil, 251,
- 251, 251, 251, nil, nil, nil, nil, 251, 251, nil,
- nil, nil, 252, 252, 252, 251, 252, 251, 251, 251,
- 252, 252, nil, nil, nil, 252, nil, 252, 252, 252,
- 252, 252, 252, 252, nil, nil, nil, nil, nil, 252,
- 252, 252, 252, 252, 252, 252, nil, nil, 252, nil,
- nil, nil, nil, nil, nil, 252, nil, nil, 252, 252,
- 252, 252, 252, 252, 252, 252, nil, 252, 252, 252,
- nil, 252, 252, nil, 252, 252, 252, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 252, nil, nil, 252,
- nil, nil, 252, 252, nil, nil, 252, nil, nil, nil,
- nil, nil, 252, nil, nil, nil, nil, nil, nil, nil,
- nil, 252, nil, nil, nil, nil, 252, 252, 252, 252,
- nil, 252, 252, 252, 252, nil, nil, nil, nil, 252,
- 252, nil, nil, nil, 253, 253, 253, 252, 253, 252,
- 252, 252, 253, 253, nil, nil, nil, 253, nil, 253,
- 253, 253, 253, 253, 253, 253, nil, nil, nil, nil,
- nil, 253, 253, 253, 253, 253, 253, 253, nil, nil,
- 253, nil, nil, nil, nil, nil, nil, 253, nil, nil,
- 253, 253, 253, 253, 253, 253, 253, 253, nil, 253,
- 253, 253, nil, 253, 253, nil, 253, 253, 253, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 253, nil,
- nil, 253, nil, nil, 253, 253, nil, nil, 253, nil,
- nil, nil, nil, nil, 253, nil, nil, nil, nil, nil,
- nil, nil, nil, 253, nil, nil, nil, nil, 253, 253,
- 253, 253, nil, 253, 253, 253, 253, nil, nil, nil,
- nil, 253, 253, nil, nil, nil, 254, 254, 254, 253,
- 254, 253, 253, 253, 254, 254, nil, nil, nil, 254,
- nil, 254, 254, 254, 254, 254, 254, 254, nil, nil,
- nil, nil, nil, 254, 254, 254, 254, 254, 254, 254,
- nil, nil, 254, nil, nil, nil, nil, nil, nil, 254,
- nil, nil, 254, 254, 254, 254, 254, 254, 254, 254,
- nil, 254, 254, 254, nil, 254, 254, nil, 254, 254,
- 254, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 254, nil, nil, 254, nil, nil, 254, 254, nil, nil,
- 254, nil, nil, nil, nil, nil, 254, nil, nil, nil,
- nil, nil, nil, nil, nil, 254, nil, nil, nil, nil,
- 254, 254, 254, 254, nil, 254, 254, 254, 254, nil,
- nil, nil, nil, 254, 254, nil, nil, nil, 255, 255,
- 255, 254, 255, 254, 254, 254, 255, 255, nil, nil,
- nil, 255, nil, 255, 255, 255, 255, 255, 255, 255,
- nil, nil, nil, nil, nil, 255, 255, 255, 255, 255,
- 255, 255, nil, nil, 255, nil, nil, nil, nil, nil,
- nil, 255, nil, nil, 255, 255, 255, 255, 255, 255,
- 255, 255, nil, 255, 255, 255, nil, 255, 255, nil,
- 255, 255, 255, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 255, nil, nil, 255, nil, nil, 255, 255,
- nil, nil, 255, nil, nil, nil, nil, nil, 255, nil,
- nil, nil, nil, nil, nil, nil, nil, 255, nil, nil,
- nil, nil, 255, 255, 255, 255, nil, 255, 255, 255,
- 255, nil, nil, nil, nil, 255, 255, nil, nil, nil,
- 263, 263, 263, 255, 263, 255, 255, 255, 263, 263,
- nil, nil, nil, 263, nil, 263, 263, 263, 263, 263,
- 263, 263, nil, nil, nil, nil, nil, 263, 263, 263,
- 263, 263, 263, 263, nil, nil, 263, nil, nil, nil,
- nil, nil, nil, 263, nil, nil, 263, 263, 263, 263,
- 263, 263, 263, 263, 263, 263, 263, 263, nil, 263,
- 263, nil, 263, 263, 263, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 263, nil, nil, 263, nil, nil,
- 263, 263, nil, nil, 263, nil, 263, nil, 263, nil,
- 263, nil, nil, 263, nil, nil, nil, nil, nil, 263,
- nil, nil, nil, nil, 263, 263, 263, 263, nil, 263,
- 263, 263, 263, nil, nil, nil, nil, 263, 263, nil,
- nil, nil, 264, 264, 264, 263, 264, 263, 263, 263,
- 264, 264, nil, nil, nil, 264, nil, 264, 264, 264,
- 264, 264, 264, 264, nil, nil, nil, nil, nil, 264,
- 264, 264, 264, 264, 264, 264, nil, nil, 264, nil,
- nil, nil, nil, nil, nil, 264, nil, nil, 264, 264,
- 264, 264, 264, 264, 264, 264, 264, 264, 264, 264,
- nil, 264, 264, nil, 264, 264, 264, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 264, nil, nil, 264,
- nil, nil, 264, 264, nil, nil, 264, nil, 264, nil,
- 264, nil, 264, nil, nil, 264, nil, nil, nil, nil,
- nil, 264, nil, nil, nil, nil, 264, 264, 264, 264,
- nil, 264, 264, 264, 264, nil, nil, nil, nil, 264,
- 264, nil, nil, nil, 272, 272, 272, 264, 272, 264,
- 264, 264, 272, 272, nil, nil, nil, 272, nil, 272,
- 272, 272, 272, 272, 272, 272, nil, nil, nil, nil,
- nil, 272, 272, 272, 272, 272, 272, 272, nil, nil,
- 272, nil, nil, nil, nil, nil, nil, 272, nil, nil,
- 272, 272, 272, 272, 272, 272, 272, 272, 272, 272,
- 272, 272, nil, 272, 272, nil, 272, 272, 272, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 272, nil,
- nil, 272, nil, nil, 272, 272, nil, nil, 272, nil,
- 272, nil, 272, nil, 272, nil, nil, 272, nil, nil,
- nil, nil, nil, 272, nil, nil, nil, nil, 272, 272,
- 272, 272, nil, 272, 272, 272, 272, nil, nil, nil,
- nil, 272, 272, 272, nil, nil, 279, 279, 279, 272,
- 279, 272, 272, 272, 279, 279, nil, nil, nil, 279,
- nil, 279, 279, 279, 279, 279, 279, 279, nil, nil,
- nil, nil, nil, 279, 279, 279, 279, 279, 279, 279,
- nil, nil, 279, nil, nil, nil, nil, nil, nil, 279,
- nil, nil, 279, 279, 279, 279, 279, 279, 279, 279,
- nil, 279, 279, 279, nil, 279, 279, nil, 279, 279,
- 279, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 279, nil, nil, 279, nil, nil, 279, 279, nil, nil,
- 279, nil, nil, nil, nil, nil, 279, nil, nil, nil,
- nil, nil, nil, nil, nil, 279, nil, nil, nil, nil,
- 279, 279, 279, 279, nil, 279, 279, 279, 279, nil,
- nil, nil, nil, 279, 279, nil, nil, nil, 281, 281,
- 281, 279, 281, 279, 279, 279, 281, 281, nil, nil,
- nil, 281, nil, 281, 281, 281, 281, 281, 281, 281,
- nil, nil, nil, nil, nil, 281, 281, 281, 281, 281,
- 281, 281, nil, nil, 281, nil, nil, nil, nil, nil,
- nil, 281, nil, nil, 281, 281, 281, 281, 281, 281,
- 281, 281, nil, 281, 281, 281, nil, 281, 281, nil,
- 281, 281, 281, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 281, nil, nil, 281, nil, nil, 281, 281,
- nil, nil, 281, nil, nil, nil, nil, nil, 281, nil,
- nil, nil, nil, nil, nil, nil, nil, 281, nil, nil,
- nil, nil, 281, 281, 281, 281, nil, 281, 281, 281,
- 281, nil, nil, nil, nil, 281, 281, nil, nil, nil,
- 284, 284, 284, 281, 284, 281, 281, 281, 284, 284,
- nil, nil, nil, 284, nil, 284, 284, 284, 284, 284,
- 284, 284, nil, nil, nil, nil, nil, 284, 284, 284,
- 284, 284, 284, 284, nil, nil, 284, nil, nil, nil,
- nil, nil, nil, 284, nil, nil, 284, 284, 284, 284,
- 284, 284, 284, 284, nil, 284, 284, 284, nil, 284,
- 284, nil, 284, 284, 284, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 284, nil, nil, 284, nil, nil,
- 284, 284, nil, nil, 284, nil, nil, nil, nil, nil,
- 284, nil, nil, nil, nil, nil, nil, nil, nil, 284,
- nil, nil, nil, nil, 284, 284, 284, 284, nil, 284,
- 284, 284, 284, nil, nil, nil, nil, 284, 284, nil,
- nil, nil, 285, 285, 285, 284, 285, 284, 284, 284,
- 285, 285, nil, nil, nil, 285, nil, 285, 285, 285,
- 285, 285, 285, 285, nil, nil, nil, nil, nil, 285,
- 285, 285, 285, 285, 285, 285, nil, nil, 285, nil,
- nil, nil, nil, nil, nil, 285, nil, nil, 285, 285,
- 285, 285, 285, 285, 285, 285, nil, 285, 285, 285,
- nil, 285, 285, nil, 285, 285, 285, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 285, nil, nil, 285,
- nil, nil, 285, 285, nil, nil, 285, nil, nil, nil,
- nil, nil, 285, nil, nil, nil, nil, nil, nil, nil,
- nil, 285, nil, nil, nil, nil, 285, 285, 285, 285,
- nil, 285, 285, 285, 285, nil, nil, nil, nil, 285,
- 285, nil, nil, nil, nil, nil, nil, 285, nil, 285,
- 285, 285, 290, 290, 290, 290, 290, nil, nil, nil,
- 290, 290, nil, nil, nil, 290, nil, 290, 290, 290,
- 290, 290, 290, 290, nil, nil, nil, nil, nil, 290,
- 290, 290, 290, 290, 290, 290, nil, nil, 290, nil,
- nil, nil, nil, nil, 290, 290, nil, 290, 290, 290,
- 290, 290, 290, 290, 290, 290, nil, 290, 290, 290,
- nil, 290, 290, nil, 290, 290, 290, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 290, nil, nil, 290,
- nil, nil, 290, 290, nil, nil, 290, nil, 290, nil,
- nil, nil, 290, nil, nil, nil, nil, nil, nil, nil,
- nil, 290, nil, nil, nil, nil, 290, 290, 290, 290,
- nil, 290, 290, 290, 290, nil, nil, nil, nil, 290,
- 290, nil, nil, nil, 298, 298, 298, 290, 298, 290,
- 290, 290, 298, 298, nil, nil, nil, 298, nil, 298,
- 298, 298, 298, 298, 298, 298, nil, nil, nil, nil,
- nil, 298, 298, 298, 298, 298, 298, 298, nil, nil,
- 298, nil, nil, nil, nil, nil, nil, 298, nil, nil,
- 298, 298, 298, 298, 298, 298, 298, 298, nil, 298,
- 298, 298, nil, 298, 298, nil, nil, nil, 298, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 298, nil,
- nil, 298, nil, nil, 298, 298, nil, nil, 298, nil,
- 895, nil, 895, 895, 895, 895, 895, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 895, nil, 298, 298,
- 298, 298, nil, 298, 298, 298, 298, nil, nil, nil,
- nil, 298, 298, nil, nil, nil, 298, nil, 895, 298,
- nil, 298, 298, 298, 315, 315, 315, nil, 315, 895,
- 895, nil, 315, 315, 895, nil, nil, 315, nil, 315,
- 315, 315, 315, 315, 315, 315, nil, nil, nil, nil,
- nil, 315, 315, 315, 315, 315, 315, 315, nil, nil,
- 315, nil, nil, nil, nil, nil, nil, 315, nil, nil,
- 315, 315, 315, 315, 315, 315, 315, 315, nil, 315,
- 315, 315, nil, 315, 315, nil, nil, nil, 315, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 315, nil,
- nil, 315, nil, nil, 315, 315, nil, nil, 315, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 315, 315,
- 315, 315, nil, 315, 315, 315, 315, nil, nil, nil,
- nil, 315, 315, nil, nil, nil, 323, 323, 323, 315,
- 323, 315, 315, 315, 323, 323, nil, nil, nil, 323,
- nil, 323, 323, 323, 323, 323, 323, 323, nil, nil,
- nil, nil, nil, 323, 323, 323, 323, 323, 323, 323,
- nil, nil, 323, nil, nil, nil, nil, nil, nil, 323,
- nil, nil, 323, 323, 323, 323, 323, 323, 323, 323,
- nil, 323, 323, 323, nil, 323, 323, nil, 323, 323,
- 323, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 323, nil, nil, 323, 323, nil, 323, 323, nil, nil,
- 323, nil, nil, nil, nil, nil, 323, nil, nil, nil,
- nil, nil, nil, nil, nil, 323, nil, nil, nil, nil,
- 323, 323, 323, 323, nil, 323, 323, 323, 323, nil,
- nil, nil, nil, 323, 323, nil, nil, nil, 325, 325,
- 325, 323, 325, 323, 323, 323, 325, 325, nil, nil,
- nil, 325, nil, 325, 325, 325, 325, 325, 325, 325,
- nil, nil, nil, nil, nil, 325, 325, 325, 325, 325,
- 325, 325, nil, nil, 325, nil, nil, nil, nil, nil,
- nil, 325, nil, nil, 325, 325, 325, 325, 325, 325,
- 325, 325, nil, 325, 325, 325, nil, 325, 325, nil,
- 325, 325, 325, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 325, nil, nil, 325, nil, nil, 325, 325,
- nil, nil, 325, nil, nil, nil, nil, nil, 325, nil,
- nil, nil, nil, nil, nil, nil, nil, 325, nil, nil,
- nil, nil, 325, 325, 325, 325, nil, 325, 325, 325,
- 325, nil, nil, nil, nil, 325, 325, nil, nil, nil,
- 340, 340, 340, 325, 340, 325, 325, 325, 340, 340,
- nil, nil, nil, 340, nil, 340, 340, 340, 340, 340,
- 340, 340, nil, nil, nil, nil, nil, 340, 340, 340,
- 340, 340, 340, 340, nil, nil, 340, nil, nil, nil,
- nil, nil, nil, 340, nil, nil, 340, 340, 340, 340,
- 340, 340, 340, 340, nil, 340, 340, 340, nil, 340,
- 340, nil, 340, 340, 340, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 340, nil, nil, 340, nil, nil,
- 340, 340, nil, nil, 340, nil, nil, nil, nil, nil,
- 340, nil, nil, nil, nil, nil, nil, nil, nil, 340,
- nil, nil, nil, nil, 340, 340, 340, 340, nil, 340,
- 340, 340, 340, nil, nil, nil, nil, 340, 340, nil,
- nil, nil, 341, 341, 341, 340, 341, 340, 340, 340,
- 341, 341, nil, nil, nil, 341, nil, 341, 341, 341,
- 341, 341, 341, 341, nil, nil, nil, nil, nil, 341,
- 341, 341, 341, 341, 341, 341, nil, nil, 341, nil,
- nil, nil, nil, nil, nil, 341, nil, nil, 341, 341,
- 341, 341, 341, 341, 341, 341, nil, 341, 341, 341,
- nil, 341, 341, nil, 341, 341, 341, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 341, nil, nil, 341,
- nil, nil, 341, 341, nil, nil, 341, nil, nil, nil,
- nil, nil, 341, nil, nil, nil, nil, nil, nil, nil,
- nil, 341, nil, nil, nil, nil, 341, 341, 341, 341,
- nil, 341, 341, 341, 341, nil, nil, nil, nil, 341,
- 341, nil, nil, nil, 360, 360, 360, 341, 360, 341,
- 341, 341, 360, 360, nil, nil, nil, 360, nil, 360,
- 360, 360, 360, 360, 360, 360, nil, nil, nil, nil,
- nil, 360, 360, 360, 360, 360, 360, 360, nil, nil,
- 360, nil, nil, nil, nil, nil, nil, 360, nil, nil,
- 360, 360, 360, 360, 360, 360, 360, 360, nil, 360,
- 360, 360, nil, 360, 360, nil, 360, 360, 360, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 360, nil,
- nil, 360, nil, nil, 360, 360, nil, nil, 360, nil,
- nil, nil, nil, nil, 360, nil, nil, nil, nil, nil,
- nil, nil, nil, 360, nil, nil, nil, nil, 360, 360,
- 360, 360, nil, 360, 360, 360, 360, nil, nil, nil,
- nil, 360, 360, nil, nil, nil, 376, 376, 376, 360,
- 376, 360, 360, 360, 376, 376, nil, nil, nil, 376,
- nil, 376, 376, 376, 376, 376, 376, 376, nil, nil,
- nil, nil, nil, 376, 376, 376, 376, 376, 376, 376,
- nil, nil, 376, nil, nil, nil, nil, nil, nil, 376,
- nil, nil, 376, 376, 376, 376, 376, 376, 376, 376,
- nil, 376, 376, 376, nil, 376, 376, nil, 376, 376,
- 376, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 376, nil, nil, 376, nil, nil, 376, 376, nil, nil,
- 376, nil, nil, nil, nil, nil, 376, nil, nil, nil,
- nil, nil, nil, nil, nil, 376, nil, nil, nil, nil,
- 376, 376, 376, 376, nil, 376, 376, 376, 376, nil,
- nil, nil, nil, 376, 376, nil, nil, nil, 404, 404,
- 404, 376, 404, 376, 376, 376, 404, 404, nil, nil,
- nil, 404, nil, 404, 404, 404, 404, 404, 404, 404,
- nil, nil, nil, nil, nil, 404, 404, 404, 404, 404,
- 404, 404, nil, nil, 404, nil, nil, nil, nil, nil,
- nil, 404, nil, nil, 404, 404, 404, 404, 404, 404,
- 404, 404, nil, 404, 404, 404, nil, 404, 404, nil,
- 404, 404, 404, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 404, nil, nil, 404, nil, nil, 404, 404,
- nil, nil, 404, nil, nil, nil, nil, nil, 404, nil,
- nil, nil, nil, nil, nil, nil, nil, 404, nil, nil,
- nil, nil, 404, 404, 404, 404, nil, 404, 404, 404,
- 404, nil, nil, nil, nil, 404, 404, nil, nil, nil,
- 442, 442, 442, 404, 442, 404, 404, 404, 442, 442,
- nil, nil, nil, 442, nil, 442, 442, 442, 442, 442,
- 442, 442, nil, nil, nil, nil, nil, 442, 442, 442,
- 442, 442, 442, 442, nil, nil, 442, nil, nil, nil,
- nil, nil, nil, 442, nil, nil, 442, 442, 442, 442,
- 442, 442, 442, 442, 442, 442, 442, 442, nil, 442,
- 442, nil, 442, 442, 442, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 442, nil, nil, 442, nil, nil,
- 442, 442, nil, nil, 442, nil, 442, nil, 442, nil,
- 442, nil, nil, 442, nil, nil, nil, nil, nil, 442,
- nil, nil, nil, nil, 442, 442, 442, 442, nil, 442,
- 442, 442, 442, nil, nil, nil, nil, 442, 442, nil,
- nil, nil, 444, 444, 444, 442, 444, 442, 442, 442,
- 444, 444, nil, nil, nil, 444, nil, 444, 444, 444,
- 444, 444, 444, 444, nil, nil, nil, nil, nil, 444,
- 444, 444, 444, 444, 444, 444, nil, nil, 444, nil,
- nil, nil, nil, nil, nil, 444, nil, nil, 444, 444,
- 444, 444, 444, 444, 444, 444, nil, 444, 444, 444,
- nil, 444, 444, nil, 444, 444, 444, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 444, nil, nil, 444,
- nil, nil, 444, 444, nil, nil, 444, nil, nil, nil,
- nil, nil, 444, nil, nil, nil, nil, nil, nil, nil,
- nil, 444, nil, nil, nil, nil, 444, 444, 444, 444,
- nil, 444, 444, 444, 444, nil, nil, nil, nil, 444,
- 444, nil, nil, nil, 445, 445, 445, 444, 445, 444,
- 444, 444, 445, 445, nil, nil, nil, 445, nil, 445,
- 445, 445, 445, 445, 445, 445, nil, nil, nil, nil,
- nil, 445, 445, 445, 445, 445, 445, 445, nil, nil,
- 445, nil, nil, nil, nil, nil, nil, 445, nil, nil,
- 445, 445, 445, 445, 445, 445, 445, 445, nil, 445,
- 445, 445, nil, 445, 445, nil, 445, 445, 445, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 445, nil,
- nil, 445, nil, nil, 445, 445, nil, nil, 445, nil,
- nil, nil, nil, nil, 445, nil, nil, nil, nil, nil,
- nil, nil, nil, 445, nil, nil, nil, nil, 445, 445,
- 445, 445, nil, 445, 445, 445, 445, nil, nil, nil,
- nil, 445, 445, nil, nil, nil, 446, 446, 446, 445,
- 446, 445, 445, 445, 446, 446, nil, nil, nil, 446,
- nil, 446, 446, 446, 446, 446, 446, 446, nil, nil,
- nil, nil, nil, 446, 446, 446, 446, 446, 446, 446,
- nil, nil, 446, nil, nil, nil, nil, nil, nil, 446,
- nil, nil, 446, 446, 446, 446, 446, 446, 446, 446,
- nil, 446, 446, 446, nil, 446, 446, nil, 446, 446,
- 446, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 446, nil, nil, 446, nil, nil, 446, 446, nil, nil,
- 446, nil, nil, nil, nil, nil, 446, nil, nil, nil,
- nil, nil, nil, nil, nil, 446, nil, nil, nil, nil,
- 446, 446, 446, 446, nil, 446, 446, 446, 446, nil,
- nil, nil, nil, 446, 446, nil, nil, nil, 472, 472,
- 472, 446, 472, 446, 446, 446, 472, 472, nil, nil,
- nil, 472, nil, 472, 472, 472, 472, 472, 472, 472,
- nil, nil, nil, nil, nil, 472, 472, 472, 472, 472,
- 472, 472, nil, nil, 472, nil, nil, nil, nil, nil,
- nil, 472, nil, nil, 472, 472, 472, 472, 472, 472,
- 472, 472, nil, 472, 472, 472, nil, 472, 472, nil,
- 472, 472, 472, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 472, nil, nil, 472, nil, nil, 472, 472,
- nil, nil, 472, nil, nil, nil, nil, nil, 472, nil,
- nil, nil, nil, nil, nil, nil, nil, 472, nil, nil,
- nil, nil, 472, 472, 472, 472, nil, 472, 472, 472,
- 472, nil, nil, nil, nil, 472, 472, nil, nil, nil,
- 486, 486, 486, 472, 486, 472, 472, 472, 486, 486,
- nil, nil, nil, 486, nil, 486, 486, 486, 486, 486,
- 486, 486, nil, nil, nil, nil, nil, 486, 486, 486,
- 486, 486, 486, 486, nil, nil, 486, nil, nil, nil,
- nil, nil, nil, 486, nil, nil, 486, 486, 486, 486,
- 486, 486, 486, 486, 486, 486, 486, 486, nil, 486,
- 486, nil, 486, 486, 486, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 486, nil, nil, 486, nil, nil,
- 486, 486, nil, nil, 486, nil, 486, nil, 486, nil,
- 486, nil, nil, 486, nil, nil, nil, nil, nil, 486,
- nil, nil, nil, nil, 486, 486, 486, 486, nil, 486,
- 486, 486, 486, nil, nil, nil, nil, 486, 486, nil,
- nil, nil, 488, 488, 488, 486, 488, 486, 486, 486,
- 488, 488, nil, nil, nil, 488, nil, 488, 488, 488,
- 488, 488, 488, 488, nil, nil, nil, nil, nil, 488,
- 488, 488, 488, 488, 488, 488, nil, nil, 488, nil,
- nil, nil, nil, nil, nil, 488, nil, nil, 488, 488,
- 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- nil, 488, 488, nil, 488, 488, 488, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 488, nil, nil, 488,
- nil, nil, 488, 488, nil, nil, 488, nil, nil, nil,
- 488, nil, 488, nil, nil, 488, nil, nil, nil, nil,
- nil, 488, nil, nil, nil, nil, 488, 488, 488, 488,
- nil, 488, 488, 488, 488, nil, nil, nil, nil, 488,
- 488, nil, nil, nil, 490, 490, 490, 488, 490, 488,
- 488, 488, 490, 490, nil, nil, nil, 490, nil, 490,
- 490, 490, 490, 490, 490, 490, nil, nil, nil, nil,
- nil, 490, 490, 490, 490, 490, 490, 490, nil, nil,
- 490, nil, nil, nil, nil, nil, nil, 490, nil, nil,
- 490, 490, 490, 490, 490, 490, 490, 490, nil, 490,
- 490, 490, nil, 490, 490, nil, 490, 490, 490, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 490, nil,
- nil, 490, nil, nil, 490, 490, nil, nil, 490, nil,
- nil, nil, nil, nil, 490, nil, nil, nil, nil, nil,
- nil, nil, nil, 490, nil, nil, nil, nil, 490, 490,
- 490, 490, nil, 490, 490, 490, 490, nil, nil, nil,
- nil, 490, 490, nil, nil, nil, nil, nil, nil, 490,
- nil, 490, 490, 490, 496, 496, 496, 496, 496, nil,
- nil, nil, 496, 496, nil, nil, nil, 496, nil, 496,
- 496, 496, 496, 496, 496, 496, nil, nil, nil, nil,
- nil, 496, 496, 496, 496, 496, 496, 496, nil, nil,
- 496, nil, nil, nil, nil, nil, 496, 496, 496, 496,
- 496, 496, 496, 496, 496, 496, 496, 496, nil, 496,
- 496, 496, nil, 496, 496, nil, 496, 496, 496, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 496, nil,
- nil, 496, nil, nil, 496, 496, nil, nil, 496, nil,
- 496, nil, nil, nil, 496, nil, nil, nil, nil, nil,
- nil, nil, nil, 496, nil, nil, nil, nil, 496, 496,
- 496, 496, nil, 496, 496, 496, 496, nil, nil, nil,
- nil, 496, 496, nil, nil, nil, nil, nil, 496, 496,
- nil, 496, 496, 496, 504, 504, 504, nil, 504, nil,
- nil, nil, 504, 504, nil, nil, nil, 504, nil, 504,
- 504, 504, 504, 504, 504, 504, nil, nil, nil, nil,
- nil, 504, 504, 504, 504, 504, 504, 504, nil, nil,
- 504, nil, nil, nil, nil, nil, nil, 504, nil, nil,
- 504, 504, 504, 504, 504, 504, 504, 504, nil, 504,
- 504, 504, nil, 504, 504, nil, nil, nil, 504, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 504, nil,
- nil, 504, nil, nil, 504, 504, nil, nil, 504, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 504, 504,
- 504, 504, nil, 504, 504, 504, 504, nil, nil, nil,
- nil, 504, 504, nil, nil, nil, 506, 506, 506, 504,
- 506, 504, 504, 504, 506, 506, nil, nil, nil, 506,
- nil, 506, 506, 506, 506, 506, 506, 506, nil, nil,
- nil, nil, nil, 506, 506, 506, 506, 506, 506, 506,
- nil, nil, 506, nil, nil, nil, nil, nil, nil, 506,
- nil, nil, 506, 506, 506, 506, 506, 506, 506, 506,
- 506, 506, 506, 506, nil, 506, 506, nil, 506, 506,
- 506, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 506, nil, nil, 506, nil, nil, 506, 506, nil, nil,
- 506, nil, 506, nil, 506, nil, 506, nil, nil, 506,
- nil, nil, nil, nil, nil, 506, nil, nil, nil, nil,
- 506, 506, 506, 506, nil, 506, 506, 506, 506, nil,
- nil, nil, nil, 506, 506, nil, nil, nil, 512, 512,
- 512, 506, 512, 506, 506, 506, 512, 512, nil, nil,
- nil, 512, nil, 512, 512, 512, 512, 512, 512, 512,
- nil, nil, nil, nil, nil, 512, 512, 512, 512, 512,
- 512, 512, nil, nil, 512, nil, nil, nil, nil, nil,
- nil, 512, nil, nil, 512, 512, 512, 512, 512, 512,
- 512, 512, nil, 512, 512, 512, nil, 512, 512, nil,
- nil, nil, 512, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 512, nil, nil, 512, nil, nil, 512, 512,
- nil, nil, 512, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 512, 512, 512, 512, nil, 512, 512, 512,
- 512, nil, nil, nil, nil, 512, 512, nil, nil, nil,
- 515, 515, 515, 512, 515, 512, 512, 512, 515, 515,
- nil, nil, nil, 515, nil, 515, 515, 515, 515, 515,
- 515, 515, nil, nil, nil, nil, nil, 515, 515, 515,
- 515, 515, 515, 515, nil, nil, 515, nil, nil, nil,
- nil, nil, nil, 515, nil, nil, 515, 515, 515, 515,
- 515, 515, 515, 515, nil, 515, 515, 515, nil, 515,
- 515, nil, 515, 515, 515, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 515, nil, nil, 515, nil, nil,
- 515, 515, nil, nil, 515, nil, nil, nil, nil, nil,
- 515, nil, nil, nil, nil, nil, nil, nil, nil, 515,
- nil, nil, nil, nil, 515, 515, 515, 515, nil, 515,
- 515, 515, 515, nil, nil, nil, nil, 515, 515, nil,
- nil, nil, 516, 516, 516, 515, 516, 515, 515, 515,
- 516, 516, nil, nil, nil, 516, nil, 516, 516, 516,
- 516, 516, 516, 516, nil, nil, nil, nil, nil, 516,
- 516, 516, 516, 516, 516, 516, nil, nil, 516, nil,
- nil, nil, nil, nil, nil, 516, nil, nil, 516, 516,
- 516, 516, 516, 516, 516, 516, nil, 516, 516, 516,
- nil, 516, 516, nil, 516, 516, 516, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 516, nil, nil, 516,
- nil, nil, 516, 516, nil, nil, 516, nil, nil, nil,
- nil, nil, 516, nil, nil, nil, nil, nil, nil, nil,
- nil, 516, nil, nil, nil, nil, 516, 516, 516, 516,
- nil, 516, 516, 516, 516, nil, nil, nil, nil, 516,
- 516, nil, nil, nil, 520, 520, 520, 516, 520, 516,
- 516, 516, 520, 520, nil, nil, nil, 520, nil, 520,
- 520, 520, 520, 520, 520, 520, nil, nil, nil, nil,
- nil, 520, 520, 520, 520, 520, 520, 520, nil, nil,
- 520, nil, nil, nil, nil, nil, nil, 520, nil, nil,
- 520, 520, 520, 520, 520, 520, 520, 520, nil, 520,
- 520, 520, nil, 520, 520, nil, 520, 520, 520, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 520, nil,
- nil, 520, nil, nil, 520, 520, nil, nil, 520, nil,
- nil, nil, nil, nil, 520, nil, nil, nil, nil, nil,
- nil, nil, nil, 520, nil, nil, nil, nil, 520, 520,
- 520, 520, nil, 520, 520, 520, 520, nil, nil, nil,
- nil, 520, 520, nil, nil, nil, 526, 526, 526, 520,
- 526, 520, 520, 520, 526, 526, nil, nil, nil, 526,
- nil, 526, 526, 526, 526, 526, 526, 526, nil, nil,
- nil, nil, nil, 526, 526, 526, 526, 526, 526, 526,
- nil, nil, 526, nil, nil, nil, nil, nil, nil, 526,
- nil, nil, 526, 526, 526, 526, 526, 526, 526, 526,
- 526, 526, 526, 526, nil, 526, 526, nil, 526, 526,
- 526, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 526, nil, nil, 526, nil, nil, 526, 526, nil, nil,
- 526, nil, 526, nil, nil, nil, 526, nil, nil, 526,
- nil, nil, nil, nil, nil, 526, nil, nil, nil, nil,
- 526, 526, 526, 526, nil, 526, 526, 526, 526, nil,
- nil, nil, nil, 526, 526, nil, nil, nil, 529, 529,
- 529, 526, 529, 526, 526, 526, 529, 529, nil, nil,
- nil, 529, nil, 529, 529, 529, 529, 529, 529, 529,
- nil, nil, nil, nil, nil, 529, 529, 529, 529, 529,
- 529, 529, nil, nil, 529, nil, nil, nil, nil, nil,
- nil, 529, nil, nil, 529, 529, 529, 529, 529, 529,
- 529, 529, 529, 529, 529, 529, nil, 529, 529, nil,
- 529, 529, 529, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 529, nil, nil, 529, nil, nil, 529, 529,
- nil, nil, 529, nil, nil, nil, nil, nil, 529, nil,
- nil, 529, nil, nil, nil, nil, nil, 529, nil, nil,
- nil, nil, 529, 529, 529, 529, nil, 529, 529, 529,
- 529, nil, nil, nil, nil, 529, 529, nil, nil, nil,
- 554, 554, 554, 529, 554, 529, 529, 529, 554, 554,
- nil, nil, nil, 554, nil, 554, 554, 554, 554, 554,
- 554, 554, nil, nil, nil, nil, nil, 554, 554, 554,
- 554, 554, 554, 554, nil, nil, 554, nil, nil, nil,
- nil, nil, nil, 554, nil, nil, 554, 554, 554, 554,
- 554, 554, 554, 554, nil, 554, 554, 554, nil, 554,
- 554, nil, 554, 554, 554, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 554, nil, nil, 554, nil, nil,
- 554, 554, nil, nil, 554, nil, nil, nil, nil, nil,
- 554, nil, nil, nil, nil, nil, nil, nil, nil, 554,
- nil, nil, nil, nil, 554, 554, 554, 554, nil, 554,
- 554, 554, 554, nil, nil, nil, nil, 554, 554, nil,
- nil, nil, 574, 574, 574, 554, 574, 554, 554, 554,
- 574, 574, nil, nil, nil, 574, nil, 574, 574, 574,
- 574, 574, 574, 574, nil, nil, nil, nil, nil, 574,
- 574, 574, 574, 574, 574, 574, nil, nil, 574, nil,
- nil, nil, nil, nil, nil, 574, nil, nil, 574, 574,
- 574, 574, 574, 574, 574, 574, nil, 574, 574, 574,
- nil, 574, 574, nil, 574, 574, 574, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 574, nil, nil, 574,
- nil, nil, 574, 574, nil, nil, 574, nil, 574, nil,
- nil, nil, 574, nil, nil, nil, nil, nil, nil, nil,
- nil, 574, nil, nil, nil, nil, 574, 574, 574, 574,
- nil, 574, 574, 574, 574, nil, nil, nil, nil, 574,
- 574, nil, nil, nil, 575, 575, 575, 574, 575, 574,
- 574, 574, 575, 575, nil, nil, nil, 575, nil, 575,
- 575, 575, 575, 575, 575, 575, nil, nil, nil, nil,
- nil, 575, 575, 575, 575, 575, 575, 575, nil, nil,
- 575, nil, nil, nil, nil, nil, nil, 575, nil, nil,
- 575, 575, 575, 575, 575, 575, 575, 575, 575, 575,
- 575, 575, nil, 575, 575, nil, 575, 575, 575, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 575, nil,
- nil, 575, nil, nil, 575, 575, nil, nil, 575, nil,
- 575, nil, 575, nil, 575, nil, nil, 575, nil, nil,
- nil, nil, nil, 575, nil, nil, nil, nil, 575, 575,
- 575, 575, nil, 575, 575, 575, 575, nil, nil, nil,
- nil, 575, 575, nil, nil, nil, 585, 585, 585, 575,
- 585, 575, 575, 575, 585, 585, nil, nil, nil, 585,
- nil, 585, 585, 585, 585, 585, 585, 585, nil, nil,
- nil, nil, nil, 585, 585, 585, 585, 585, 585, 585,
- nil, nil, 585, nil, nil, nil, nil, nil, nil, 585,
- nil, nil, 585, 585, 585, 585, 585, 585, 585, 585,
- 585, 585, 585, 585, nil, 585, 585, nil, 585, 585,
- 585, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 585, nil, nil, 585, nil, nil, 585, 585, nil, nil,
- 585, nil, 585, nil, 585, nil, 585, nil, nil, 585,
- nil, nil, nil, nil, nil, 585, nil, nil, nil, nil,
- 585, 585, 585, 585, nil, 585, 585, 585, 585, nil,
- nil, nil, nil, 585, 585, nil, nil, nil, 619, 619,
- 619, 585, 619, 585, 585, 585, 619, 619, nil, nil,
- nil, 619, nil, 619, 619, 619, 619, 619, 619, 619,
- nil, nil, nil, nil, nil, 619, 619, 619, 619, 619,
- 619, 619, nil, nil, 619, nil, nil, nil, nil, nil,
- nil, 619, nil, nil, 619, 619, 619, 619, 619, 619,
- 619, 619, nil, 619, 619, 619, nil, 619, 619, nil,
- 619, 619, 619, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 619, nil, nil, 619, nil, nil, 619, 619,
- nil, nil, 619, nil, 619, nil, nil, nil, 619, nil,
- nil, nil, nil, nil, nil, nil, nil, 619, nil, nil,
- nil, nil, 619, 619, 619, 619, nil, 619, 619, 619,
- 619, nil, nil, nil, nil, 619, 619, nil, nil, nil,
- 620, 620, 620, 619, 620, 619, 619, 619, 620, 620,
- nil, nil, nil, 620, nil, 620, 620, 620, 620, 620,
- 620, 620, nil, nil, nil, nil, nil, 620, 620, 620,
- 620, 620, 620, 620, nil, nil, 620, nil, nil, nil,
- nil, nil, nil, 620, nil, nil, 620, 620, 620, 620,
- 620, 620, 620, 620, nil, 620, 620, 620, nil, 620,
- 620, nil, 620, 620, 620, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 620, nil, nil, 620, nil, nil,
- 620, 620, nil, nil, 620, nil, nil, nil, nil, nil,
- 620, nil, nil, nil, nil, nil, nil, nil, nil, 620,
- nil, nil, nil, nil, 620, 620, 620, 620, nil, 620,
- 620, 620, 620, nil, nil, nil, nil, 620, 620, nil,
- nil, nil, 623, 623, 623, 620, 623, 620, 620, 620,
- 623, 623, nil, nil, nil, 623, nil, 623, 623, 623,
- 623, 623, 623, 623, nil, nil, nil, nil, nil, 623,
- 623, 623, 623, 623, 623, 623, nil, nil, 623, nil,
- nil, nil, nil, nil, nil, 623, nil, nil, 623, 623,
- 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
- nil, 623, 623, nil, 623, 623, 623, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 623, nil, nil, 623,
- nil, nil, 623, 623, nil, nil, 623, nil, 623, nil,
- 623, nil, 623, nil, nil, 623, nil, nil, nil, nil,
- nil, 623, nil, nil, nil, nil, 623, 623, 623, 623,
- nil, 623, 623, 623, 623, nil, nil, nil, nil, 623,
- 623, nil, nil, nil, 624, 624, 624, 623, 624, 623,
- 623, 623, 624, 624, nil, nil, nil, 624, nil, 624,
- 624, 624, 624, 624, 624, 624, nil, nil, nil, nil,
- nil, 624, 624, 624, 624, 624, 624, 624, nil, nil,
- 624, nil, nil, nil, nil, nil, nil, 624, nil, nil,
- 624, 624, 624, 624, 624, 624, 624, 624, 624, 624,
- 624, 624, nil, 624, 624, nil, 624, 624, 624, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 624, nil,
- nil, 624, nil, nil, 624, 624, nil, nil, 624, nil,
- nil, nil, 624, nil, 624, nil, nil, 624, nil, nil,
- nil, nil, nil, 624, nil, nil, nil, nil, 624, 624,
- 624, 624, nil, 624, 624, 624, 624, nil, nil, nil,
- nil, 624, 624, nil, nil, nil, 625, 625, 625, 624,
- 625, 624, 624, 624, 625, 625, nil, nil, nil, 625,
- nil, 625, 625, 625, 625, 625, 625, 625, nil, nil,
- nil, nil, nil, 625, 625, 625, 625, 625, 625, 625,
- nil, nil, 625, nil, nil, nil, nil, nil, nil, 625,
- nil, nil, 625, 625, 625, 625, 625, 625, 625, 625,
- nil, 625, 625, 625, nil, 625, 625, nil, 625, 625,
- 625, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 625, nil, nil, 625, nil, nil, 625, 625, nil, nil,
- 625, nil, nil, nil, nil, nil, 625, nil, nil, nil,
- nil, nil, nil, nil, nil, 625, nil, nil, nil, nil,
- 625, 625, 625, 625, nil, 625, 625, 625, 625, nil,
- nil, nil, nil, 625, 625, nil, nil, nil, 626, 626,
- 626, 625, 626, 625, 625, 625, 626, 626, nil, nil,
- nil, 626, nil, 626, 626, 626, 626, 626, 626, 626,
- nil, nil, nil, nil, nil, 626, 626, 626, 626, 626,
- 626, 626, nil, nil, 626, nil, nil, nil, nil, nil,
- nil, 626, nil, nil, 626, 626, 626, 626, 626, 626,
- 626, 626, nil, 626, 626, 626, nil, 626, 626, nil,
- 626, 626, 626, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 626, nil, nil, 626, nil, nil, 626, 626,
- nil, nil, 626, nil, nil, nil, nil, nil, 626, nil,
- nil, nil, nil, nil, nil, nil, nil, 626, nil, nil,
- nil, nil, 626, 626, 626, 626, nil, 626, 626, 626,
- 626, nil, nil, nil, nil, 626, 626, nil, nil, nil,
- 630, 630, 630, 626, 630, 626, 626, 626, 630, 630,
- nil, nil, nil, 630, nil, 630, 630, 630, 630, 630,
- 630, 630, nil, nil, nil, nil, nil, 630, 630, 630,
- 630, 630, 630, 630, nil, nil, 630, nil, nil, nil,
- nil, nil, nil, 630, nil, nil, 630, 630, 630, 630,
- 630, 630, 630, 630, nil, 630, 630, 630, nil, 630,
- 630, nil, 630, 630, 630, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 630, nil, nil, 630, nil, nil,
- 630, 630, nil, nil, 630, nil, nil, nil, nil, nil,
- 630, nil, nil, nil, nil, nil, nil, nil, nil, 630,
- nil, nil, nil, nil, 630, 630, 630, 630, nil, 630,
- 630, 630, 630, nil, nil, nil, nil, 630, 630, nil,
- nil, nil, 631, 631, 631, 630, 631, 630, 630, 630,
- 631, 631, nil, nil, nil, 631, nil, 631, 631, 631,
- 631, 631, 631, 631, nil, nil, nil, nil, nil, 631,
- 631, 631, 631, 631, 631, 631, nil, nil, 631, nil,
- nil, nil, nil, nil, nil, 631, nil, nil, 631, 631,
- 631, 631, 631, 631, 631, 631, nil, 631, 631, 631,
- nil, 631, 631, nil, 631, 631, 631, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 631, nil, nil, 631,
- nil, nil, 631, 631, nil, nil, 631, nil, nil, nil,
- nil, nil, 631, nil, nil, nil, nil, nil, nil, nil,
- nil, 631, nil, nil, nil, nil, 631, 631, 631, 631,
- nil, 631, 631, 631, 631, nil, nil, nil, nil, 631,
- 631, nil, nil, nil, 634, 634, 634, 631, 634, 631,
- 631, 631, 634, 634, nil, nil, nil, 634, nil, 634,
- 634, 634, 634, 634, 634, 634, nil, nil, nil, nil,
- nil, 634, 634, 634, 634, 634, 634, 634, nil, nil,
- 634, nil, nil, nil, nil, nil, nil, 634, nil, nil,
- 634, 634, 634, 634, 634, 634, 634, 634, nil, 634,
- 634, 634, nil, 634, 634, nil, 634, 634, 634, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 634, nil,
- nil, 634, nil, nil, 634, 634, nil, nil, 634, nil,
- nil, nil, nil, nil, 634, nil, nil, nil, nil, nil,
- nil, nil, nil, 634, nil, nil, nil, nil, 634, 634,
- 634, 634, nil, 634, 634, 634, 634, nil, nil, nil,
- nil, 634, 634, nil, nil, nil, 635, 635, 635, 634,
- 635, 634, 634, 634, 635, 635, nil, nil, nil, 635,
- nil, 635, 635, 635, 635, 635, 635, 635, nil, nil,
- nil, nil, nil, 635, 635, 635, 635, 635, 635, 635,
- nil, nil, 635, nil, nil, nil, nil, nil, nil, 635,
- nil, nil, 635, 635, 635, 635, 635, 635, 635, 635,
- nil, 635, 635, 635, nil, 635, 635, nil, 635, 635,
- 635, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 635, nil, nil, 635, nil, nil, 635, 635, nil, nil,
- 635, nil, nil, nil, nil, nil, 635, nil, nil, nil,
- nil, nil, nil, nil, nil, 635, nil, nil, nil, nil,
- 635, 635, 635, 635, nil, 635, 635, 635, 635, nil,
- nil, nil, nil, 635, 635, nil, nil, nil, 659, 659,
- 659, 635, 659, 635, 635, 635, 659, 659, nil, nil,
- nil, 659, nil, 659, 659, 659, 659, 659, 659, 659,
- nil, nil, nil, nil, nil, 659, 659, 659, 659, 659,
- 659, 659, nil, nil, 659, nil, nil, nil, nil, nil,
- nil, 659, nil, nil, 659, 659, 659, 659, 659, 659,
- 659, 659, nil, 659, 659, 659, nil, 659, 659, nil,
- 659, 659, 659, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 659, nil, nil, 659, nil, nil, 659, 659,
- nil, nil, 659, nil, nil, nil, nil, nil, 659, nil,
- nil, nil, nil, nil, nil, nil, nil, 659, nil, nil,
- nil, nil, 659, 659, 659, 659, nil, 659, 659, 659,
- 659, nil, nil, nil, nil, 659, 659, nil, nil, nil,
- 662, 662, 662, 659, 662, 659, 659, 659, 662, 662,
- nil, nil, nil, 662, nil, 662, 662, 662, 662, 662,
- 662, 662, nil, nil, nil, nil, nil, 662, 662, 662,
- 662, 662, 662, 662, nil, nil, 662, nil, nil, nil,
- nil, nil, nil, 662, nil, nil, 662, 662, 662, 662,
- 662, 662, 662, 662, nil, 662, 662, 662, nil, 662,
- 662, nil, 662, 662, 662, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 662, nil, nil, 662, nil, nil,
- 662, 662, nil, nil, 662, nil, nil, nil, nil, nil,
- 662, nil, nil, nil, nil, nil, nil, nil, nil, 662,
- nil, nil, nil, nil, 662, 662, 662, 662, nil, 662,
- 662, 662, 662, nil, nil, nil, nil, 662, 662, nil,
- nil, nil, 666, 666, 666, 662, 666, 662, 662, 662,
- 666, 666, nil, nil, nil, 666, nil, 666, 666, 666,
- 666, 666, 666, 666, nil, nil, nil, nil, nil, 666,
- 666, 666, 666, 666, 666, 666, nil, nil, 666, nil,
- nil, nil, nil, nil, nil, 666, nil, nil, 666, 666,
- 666, 666, 666, 666, 666, 666, nil, 666, 666, 666,
- nil, 666, 666, nil, nil, nil, 666, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 666, nil, nil, 666,
- nil, nil, 666, 666, nil, nil, 666, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 666, 666, 666, 666,
- nil, 666, 666, 666, 666, nil, nil, nil, nil, 666,
- 666, nil, nil, nil, 677, 677, 677, 666, 677, 666,
- 666, 666, 677, 677, nil, nil, nil, 677, nil, 677,
- 677, 677, 677, 677, 677, 677, nil, nil, nil, nil,
- nil, 677, 677, 677, 677, 677, 677, 677, nil, nil,
- 677, nil, nil, nil, nil, nil, nil, 677, nil, nil,
- 677, 677, 677, 677, 677, 677, 677, 677, nil, 677,
- 677, 677, nil, 677, 677, nil, nil, nil, 677, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 677, nil,
- nil, 677, nil, nil, 677, 677, nil, nil, 677, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 677, 677,
- 677, 677, nil, 677, 677, 677, 677, nil, nil, nil,
- nil, 677, 677, nil, nil, nil, 682, 682, 682, 677,
- 682, 677, 677, 677, 682, 682, nil, nil, nil, 682,
- nil, 682, 682, 682, 682, 682, 682, 682, nil, nil,
- nil, nil, nil, 682, 682, 682, 682, 682, 682, 682,
- nil, nil, 682, nil, nil, nil, nil, nil, nil, 682,
- nil, nil, 682, 682, 682, 682, 682, 682, 682, 682,
- nil, 682, 682, 682, nil, 682, 682, nil, 682, 682,
- 682, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 682, nil, nil, 682, nil, nil, 682, 682, nil, nil,
- 682, nil, 682, nil, nil, nil, 682, nil, nil, nil,
- nil, nil, nil, nil, nil, 682, nil, nil, nil, nil,
- 682, 682, 682, 682, nil, 682, 682, 682, 682, nil,
- nil, nil, nil, 682, 682, nil, nil, nil, 699, 699,
- 699, 682, 699, 682, 682, 682, 699, 699, nil, nil,
- nil, 699, nil, 699, 699, 699, 699, 699, 699, 699,
- nil, nil, nil, nil, nil, 699, 699, 699, 699, 699,
- 699, 699, nil, nil, 699, nil, nil, nil, nil, nil,
- nil, 699, nil, nil, 699, 699, 699, 699, 699, 699,
- 699, 699, nil, 699, 699, 699, nil, 699, 699, nil,
- 699, 699, 699, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 699, nil, nil, 699, nil, nil, 699, 699,
- nil, nil, 699, nil, nil, nil, nil, nil, 699, nil,
- nil, nil, nil, nil, nil, nil, nil, 699, nil, nil,
- nil, nil, 699, 699, 699, 699, nil, 699, 699, 699,
- 699, nil, nil, nil, nil, 699, 699, nil, nil, nil,
- 725, 725, 725, 699, 725, 699, 699, 699, 725, 725,
- nil, nil, nil, 725, nil, 725, 725, 725, 725, 725,
- 725, 725, nil, nil, nil, nil, nil, 725, 725, 725,
- 725, 725, 725, 725, nil, nil, 725, nil, nil, nil,
- nil, nil, nil, 725, nil, nil, 725, 725, 725, 725,
- 725, 725, 725, 725, nil, 725, 725, 725, nil, 725,
- 725, nil, 725, 725, 725, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 725, nil, nil, 725, nil, nil,
- 725, 725, nil, nil, 725, nil, nil, nil, nil, nil,
- 725, nil, nil, nil, nil, nil, nil, nil, nil, 725,
- nil, nil, nil, nil, 725, 725, 725, 725, nil, 725,
- 725, 725, 725, nil, nil, nil, nil, 725, 725, nil,
- nil, nil, 731, 731, 731, 725, 731, 725, 725, 725,
- 731, 731, nil, nil, nil, 731, nil, 731, 731, 731,
- 731, 731, 731, 731, nil, nil, nil, nil, nil, 731,
- 731, 731, 731, 731, 731, 731, nil, nil, 731, nil,
- nil, nil, nil, nil, nil, 731, nil, nil, 731, 731,
- 731, 731, 731, 731, 731, 731, nil, 731, 731, 731,
- nil, 731, 731, nil, 731, 731, 731, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 731, nil, nil, 731,
- nil, nil, 731, 731, nil, nil, 731, nil, nil, nil,
- nil, nil, 731, nil, nil, nil, nil, nil, nil, nil,
- nil, 731, nil, nil, nil, nil, 731, 731, 731, 731,
- nil, 731, 731, 731, 731, nil, nil, nil, nil, 731,
- 731, nil, nil, nil, 754, 754, 754, 731, 754, 731,
- 731, 731, 754, 754, nil, nil, nil, 754, nil, 754,
- 754, 754, 754, 754, 754, 754, nil, nil, nil, nil,
- nil, 754, 754, 754, 754, 754, 754, 754, nil, nil,
- 754, nil, nil, nil, nil, nil, nil, 754, nil, nil,
- 754, 754, 754, 754, 754, 754, 754, 754, nil, 754,
- 754, 754, nil, 754, 754, nil, 754, 754, 754, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 754, nil,
- nil, 754, nil, nil, 754, 754, nil, nil, 754, nil,
- nil, nil, nil, nil, 754, nil, nil, nil, nil, nil,
- nil, nil, nil, 754, nil, nil, nil, nil, 754, 754,
- 754, 754, nil, 754, 754, 754, 754, nil, nil, nil,
- nil, 754, 754, nil, nil, nil, 756, 756, 756, 754,
- 756, 754, 754, 754, 756, 756, nil, nil, nil, 756,
- nil, 756, 756, 756, 756, 756, 756, 756, nil, nil,
- nil, nil, nil, 756, 756, 756, 756, 756, 756, 756,
- nil, nil, 756, nil, nil, nil, nil, nil, nil, 756,
- nil, nil, 756, 756, 756, 756, 756, 756, 756, 756,
- nil, 756, 756, 756, nil, 756, 756, nil, 756, 756,
- 756, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 756, nil, nil, 756, nil, nil, 756, 756, nil, nil,
- 756, nil, nil, nil, nil, nil, 756, nil, nil, nil,
- nil, nil, nil, nil, nil, 756, nil, nil, nil, nil,
- 756, 756, 756, 756, nil, 756, 756, 756, 756, nil,
- nil, nil, nil, 756, 756, nil, nil, nil, 770, 770,
- 770, 756, 770, 756, 756, 756, 770, 770, nil, nil,
- nil, 770, nil, 770, 770, 770, 770, 770, 770, 770,
- nil, nil, nil, nil, nil, 770, 770, 770, 770, 770,
- 770, 770, nil, nil, 770, nil, nil, nil, nil, nil,
- nil, 770, nil, nil, 770, 770, 770, 770, 770, 770,
- 770, 770, nil, 770, 770, 770, nil, 770, 770, nil,
- 770, 770, 770, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 770, nil, nil, 770, nil, nil, 770, 770,
- nil, nil, 770, nil, nil, nil, nil, nil, 770, nil,
- nil, nil, nil, nil, nil, nil, nil, 770, nil, nil,
- nil, nil, 770, 770, 770, 770, nil, 770, 770, 770,
- 770, nil, nil, nil, nil, 770, 770, nil, nil, nil,
- 771, 771, 771, 770, 771, 770, 770, 770, 771, 771,
- nil, nil, nil, 771, nil, 771, 771, 771, 771, 771,
- 771, 771, nil, nil, nil, nil, nil, 771, 771, 771,
- 771, 771, 771, 771, nil, nil, 771, nil, nil, nil,
- nil, nil, nil, 771, nil, nil, 771, 771, 771, 771,
- 771, 771, 771, 771, nil, 771, 771, 771, nil, 771,
- 771, nil, 771, 771, 771, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 771, nil, nil, 771, nil, nil,
- 771, 771, nil, nil, 771, nil, nil, nil, nil, nil,
- 771, nil, nil, nil, nil, nil, nil, nil, nil, 771,
- nil, nil, nil, nil, 771, 771, 771, 771, nil, 771,
- 771, 771, 771, nil, nil, nil, nil, 771, 771, nil,
- nil, nil, 772, 772, 772, 771, 772, 771, 771, 771,
- 772, 772, nil, nil, nil, 772, nil, 772, 772, 772,
- 772, 772, 772, 772, nil, nil, nil, nil, nil, 772,
- 772, 772, 772, 772, 772, 772, nil, nil, 772, nil,
- nil, nil, nil, nil, nil, 772, nil, nil, 772, 772,
- 772, 772, 772, 772, 772, 772, nil, 772, 772, 772,
- nil, 772, 772, nil, 772, 772, 772, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 772, nil, nil, 772,
- nil, nil, 772, 772, nil, nil, 772, nil, nil, nil,
- nil, nil, 772, nil, nil, nil, nil, nil, nil, nil,
- nil, 772, nil, nil, nil, nil, 772, 772, 772, 772,
- nil, 772, 772, 772, 772, nil, nil, nil, nil, 772,
- 772, nil, nil, nil, 773, 773, 773, 772, 773, 772,
- 772, 772, 773, 773, nil, nil, nil, 773, nil, 773,
- 773, 773, 773, 773, 773, 773, nil, nil, nil, nil,
- nil, 773, 773, 773, 773, 773, 773, 773, nil, nil,
- 773, nil, nil, nil, nil, nil, nil, 773, nil, nil,
- 773, 773, 773, 773, 773, 773, 773, 773, nil, 773,
- 773, 773, nil, 773, 773, nil, 773, 773, 773, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 773, nil,
- nil, 773, nil, nil, 773, 773, nil, nil, 773, nil,
- nil, nil, nil, nil, 773, nil, nil, nil, nil, nil,
- nil, nil, nil, 773, nil, nil, nil, nil, 773, 773,
- 773, 773, nil, 773, 773, 773, 773, nil, nil, nil,
- nil, 773, 773, nil, nil, nil, 787, 787, 787, 773,
- 787, 773, 773, 773, 787, 787, nil, nil, nil, 787,
- nil, 787, 787, 787, 787, 787, 787, 787, nil, nil,
- nil, nil, nil, 787, 787, 787, 787, 787, 787, 787,
- nil, nil, 787, nil, nil, nil, nil, nil, nil, 787,
- nil, nil, 787, 787, 787, 787, 787, 787, 787, 787,
- nil, 787, 787, 787, nil, 787, 787, nil, nil, nil,
- 787, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 787, nil, nil, 787, nil, nil, 787, 787, nil, nil,
- 787, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 787, 787, 787, 787, nil, 787, 787, 787, 787, nil,
- nil, nil, nil, 787, 787, nil, nil, nil, 837, 837,
- 837, 787, 837, 787, 787, 787, 837, 837, nil, nil,
- nil, 837, nil, 837, 837, 837, 837, 837, 837, 837,
- nil, nil, nil, nil, nil, 837, 837, 837, 837, 837,
- 837, 837, nil, nil, 837, nil, nil, nil, nil, nil,
- nil, 837, nil, nil, 837, 837, 837, 837, 837, 837,
- 837, 837, nil, 837, 837, 837, nil, 837, 837, nil,
- 837, 837, 837, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 837, nil, nil, 837, nil, nil, 837, 837,
- nil, nil, 837, nil, nil, nil, nil, nil, 837, nil,
- nil, nil, nil, nil, nil, nil, nil, 837, nil, nil,
- nil, nil, 837, 837, 837, 837, nil, 837, 837, 837,
- 837, nil, nil, nil, nil, 837, 837, nil, nil, nil,
- 842, 842, 842, 837, 842, 837, 837, 837, 842, 842,
- nil, nil, nil, 842, nil, 842, 842, 842, 842, 842,
- 842, 842, nil, nil, nil, nil, nil, 842, 842, 842,
- 842, 842, 842, 842, nil, nil, 842, nil, nil, nil,
- nil, nil, nil, 842, nil, nil, 842, 842, 842, 842,
- 842, 842, 842, 842, nil, 842, 842, 842, nil, 842,
- 842, nil, 842, 842, 842, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 842, nil, nil, 842, nil, nil,
- 842, 842, nil, nil, 842, nil, 842, nil, nil, nil,
- 842, nil, nil, nil, nil, nil, nil, nil, nil, 842,
- nil, nil, nil, nil, 842, 842, 842, 842, nil, 842,
- 842, 842, 842, nil, nil, nil, nil, 842, 842, nil,
- nil, nil, 859, 859, 859, 842, 859, 842, 842, 842,
- 859, 859, nil, nil, nil, 859, nil, 859, 859, 859,
- 859, 859, 859, 859, nil, nil, nil, nil, nil, 859,
- 859, 859, 859, 859, 859, 859, nil, nil, 859, nil,
- nil, nil, nil, nil, nil, 859, nil, nil, 859, 859,
- 859, 859, 859, 859, 859, 859, 859, 859, 859, 859,
- nil, 859, 859, nil, 859, 859, 859, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 859, nil, nil, 859,
- nil, nil, 859, 859, nil, nil, 859, nil, nil, nil,
- 859, nil, 859, nil, nil, 859, nil, nil, nil, nil,
- nil, 859, nil, nil, nil, nil, 859, 859, 859, 859,
- nil, 859, 859, 859, 859, nil, nil, nil, nil, 859,
- 859, nil, nil, nil, 860, 860, 860, 859, 860, 859,
- 859, 859, 860, 860, nil, nil, nil, 860, nil, 860,
- 860, 860, 860, 860, 860, 860, nil, nil, nil, nil,
- nil, 860, 860, 860, 860, 860, 860, 860, nil, nil,
- 860, nil, nil, nil, nil, nil, nil, 860, nil, nil,
- 860, 860, 860, 860, 860, 860, 860, 860, nil, 860,
- 860, 860, nil, 860, 860, nil, 860, 860, 860, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 860, nil,
- nil, 860, nil, nil, 860, 860, nil, nil, 860, nil,
- nil, nil, nil, nil, 860, nil, nil, nil, nil, nil,
- nil, nil, nil, 860, nil, nil, nil, nil, 860, 860,
- 860, 860, nil, 860, 860, 860, 860, nil, nil, nil,
- nil, 860, 860, nil, nil, nil, 874, 874, 874, 860,
- 874, 860, 860, 860, 874, 874, nil, nil, nil, 874,
- nil, 874, 874, 874, 874, 874, 874, 874, nil, nil,
- nil, nil, nil, 874, 874, 874, 874, 874, 874, 874,
- nil, nil, 874, nil, nil, nil, nil, nil, nil, 874,
- nil, nil, 874, 874, 874, 874, 874, 874, 874, 874,
- nil, 874, 874, 874, nil, 874, 874, nil, nil, nil,
- 874, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 874, nil, nil, 874, nil, nil, 874, 874, nil, nil,
- 874, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 874, 874, 874, 874, nil, 874, 874, 874, 874, nil,
- nil, nil, nil, 874, 874, nil, nil, nil, 886, 886,
- 886, 874, 886, 874, 874, 874, 886, 886, nil, nil,
- nil, 886, nil, 886, 886, 886, 886, 886, 886, 886,
- nil, nil, nil, nil, nil, 886, 886, 886, 886, 886,
- 886, 886, nil, nil, 886, nil, nil, nil, nil, nil,
- nil, 886, nil, nil, 886, 886, 886, 886, 886, 886,
- 886, 886, nil, 886, 886, 886, nil, 886, 886, nil,
- nil, nil, 886, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 886, nil, nil, 886, nil, nil, 886, 886,
- nil, nil, 886, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 886, 886, 886, 886, nil, 886, 886, 886,
- 886, nil, nil, nil, nil, 886, 886, nil, nil, nil,
- 923, 923, 923, 886, 923, 886, 886, 886, 923, 923,
- nil, nil, nil, 923, nil, 923, 923, 923, 923, 923,
- 923, 923, nil, nil, nil, nil, nil, 923, 923, 923,
- 923, 923, 923, 923, nil, nil, 923, nil, nil, nil,
- nil, nil, nil, 923, nil, nil, 923, 923, 923, 923,
- 923, 923, 923, 923, nil, 923, 923, 923, nil, 923,
- 923, nil, 923, 923, 923, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 923, nil, nil, 923, nil, nil,
- 923, 923, nil, nil, 923, nil, nil, nil, nil, nil,
- 923, nil, nil, nil, nil, nil, nil, nil, nil, 923,
- nil, nil, nil, nil, 923, 923, 923, 923, nil, 923,
- 923, 923, 923, nil, nil, nil, nil, 923, 923, nil,
- nil, nil, 985, 985, 985, 923, 985, 923, 923, 923,
- 985, 985, nil, nil, nil, 985, nil, 985, 985, 985,
- 985, 985, 985, 985, nil, nil, nil, nil, nil, 985,
- 985, 985, 985, 985, 985, 985, nil, nil, 985, nil,
- nil, nil, nil, nil, nil, 985, nil, nil, 985, 985,
- 985, 985, 985, 985, 985, 985, 985, 985, 985, 985,
- nil, 985, 985, nil, 985, 985, 985, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 985, nil, nil, 985,
- nil, nil, 985, 985, nil, nil, 985, nil, 985, nil,
- 985, nil, 985, nil, nil, 985, nil, nil, nil, nil,
- nil, 985, nil, nil, nil, nil, 985, 985, 985, 985,
- nil, 985, 985, 985, 985, nil, nil, nil, nil, 985,
- 985, nil, nil, nil, nil, 56, nil, 985, nil, 985,
- 985, 985, 56, 56, 56, nil, nil, 56, 56, 56,
- nil, 56, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 56, 56, 56, nil, nil, nil, nil, nil, nil,
- nil, 56, 56, nil, 56, 56, 56, 56, 56, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, nil, nil, 56, 56,
- 56, nil, nil, 56, nil, nil, 56, nil, nil, 56,
- 56, nil, 56, nil, 56, nil, 56, nil, 56, 56,
- nil, 56, 56, 56, 56, 56, nil, 56, nil, 56,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 56, nil, nil, 56, 56, 56, 56,
- 424, 56, nil, 56, nil, nil, nil, 424, 424, 424,
- nil, nil, 424, 424, 424, nil, 424, nil, nil, nil,
- nil, nil, nil, nil, nil, 424, 424, 424, 424, nil,
- nil, nil, nil, nil, nil, nil, 424, 424, nil, 424,
- 424, 424, 424, 424, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 424, 424, 424,
- 424, 424, 424, 424, 424, 424, 424, 424, 424, 424,
- 424, nil, nil, 424, 424, 424, nil, nil, 424, nil,
- nil, 424, nil, nil, 424, 424, nil, 424, nil, 424,
- nil, 424, nil, 424, 424, nil, 424, 424, 424, 424,
- 424, nil, 424, 424, 424, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 424, nil,
- nil, 424, 424, 424, 424, 425, 424, nil, 424, nil,
- nil, nil, 425, 425, 425, nil, nil, 425, 425, 425,
- nil, 425, nil, nil, nil, nil, nil, nil, nil, nil,
- 425, 425, 425, 425, nil, nil, nil, nil, nil, nil,
- nil, 425, 425, nil, 425, 425, 425, 425, 425, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 425, 425, 425, 425, 425, 425, 425, 425,
- 425, 425, 425, 425, 425, 425, nil, nil, 425, 425,
- 425, nil, nil, 425, nil, nil, 425, nil, nil, 425,
- 425, nil, 425, nil, 425, nil, 425, nil, 425, 425,
- nil, 425, 425, 425, 425, 425, nil, 425, 425, 425,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 425, nil, nil, 425, 425, 425, 425,
- 27, 425, nil, 425, nil, nil, nil, 27, 27, 27,
- nil, nil, 27, 27, 27, nil, 27, nil, nil, nil,
- nil, nil, nil, nil, nil, 27, 27, 27, nil, nil,
- nil, nil, nil, nil, nil, nil, 27, 27, nil, 27,
- 27, 27, 27, 27, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 27, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
- 27, nil, nil, 27, 27, 27, nil, nil, 27, nil,
- 27, 27, nil, nil, 27, 27, nil, 27, nil, 27,
- nil, 27, nil, 27, 27, nil, 27, 27, 27, 27,
- 27, 28, 27, 27, 27, nil, nil, nil, 28, 28,
- 28, nil, nil, 28, 28, 28, nil, 28, 27, nil,
- nil, 27, 27, nil, 27, nil, 27, 28, 28, nil,
- nil, nil, nil, nil, nil, nil, nil, 28, 28, nil,
- 28, 28, 28, 28, 28, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, nil, nil, 28, 28, 28, nil, nil, 28,
- nil, 28, 28, nil, nil, 28, 28, nil, 28, nil,
- 28, nil, 28, nil, 28, 28, nil, 28, 28, 28,
- 28, 28, nil, 28, 415, 28, nil, nil, nil, nil,
- nil, 415, 415, 415, nil, nil, 415, 415, 415, 28,
- 415, nil, 28, 28, nil, 28, nil, 28, nil, 415,
- 415, 415, nil, nil, nil, nil, nil, nil, nil, nil,
- 415, 415, nil, 415, 415, 415, 415, 415, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 415, 415, 415, 415, 415, 415, 415, 415, 415,
- 415, 415, 415, 415, 415, nil, nil, 415, 415, 415,
- nil, nil, 415, nil, 415, 415, nil, nil, 415, 415,
- nil, 415, nil, 415, nil, 415, nil, 415, 415, nil,
- 415, 415, 415, 415, 415, nil, 415, 415, 415, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 415, nil, 474, 415, 415, nil, 415, nil,
- 415, 474, 474, 474, nil, nil, 474, 474, 474, 646,
- 474, 646, 646, 646, 646, 646, nil, nil, nil, 474,
- 474, nil, nil, nil, nil, 646, nil, nil, nil, nil,
- 474, 474, nil, 474, 474, 474, 474, 474, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 646, 336, nil,
- 336, 336, 336, 336, 336, nil, 646, 646, 646, 646,
- nil, nil, nil, 646, 336, 534, nil, 534, 534, 534,
- 534, 534, 474, nil, nil, nil, nil, nil, nil, 474,
- nil, 534, nil, nil, 474, 474, 336, 336, nil, 646,
- nil, nil, nil, nil, nil, 336, 336, 336, 336, nil,
- nil, nil, 336, 534, nil, nil, nil, 474, 474, nil,
- nil, nil, 534, 534, 534, 534, nil, nil, nil, 534,
- nil, nil, 474, nil, nil, 474, nil, nil, nil, nil,
- 474, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, nil, nil, nil, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, nil, nil,
- nil, nil, nil, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, nil, 8, nil, nil, nil, nil, nil,
- nil, nil, nil, 8, 8, nil, 8, 8, 8, 8,
- 8, 8, 8, nil, nil, 8, 8, nil, nil, nil,
- 8, 8, 8, 8, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 8, 8, nil,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, nil, nil, 8, 8, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 8,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9, nil, nil, nil, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, nil, nil, nil,
- nil, nil, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, nil, nil, 9, nil, nil, nil, nil, nil, nil,
- nil, nil, 9, 9, nil, 9, 9, 9, 9, 9,
- 9, 9, nil, nil, 9, 9, nil, nil, nil, 9,
- 9, 9, 9, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 9, 9, nil, 9,
- 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, nil, nil, 9, 9, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 9, 395,
- 395, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- 395, 395, 395, nil, nil, nil, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, nil, nil, nil, nil,
- nil, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- nil, nil, 395, nil, nil, nil, nil, nil, nil, nil,
- nil, 395, 395, nil, 395, 395, 395, 395, 395, 395,
- 395, nil, nil, 395, 395, nil, nil, nil, 395, 395,
- 395, 395, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 395, 395, nil, 395, 395,
- 395, 395, 395, 395, 395, 395, 395, 395, 395, 395,
- nil, nil, 395, 395, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 395, 616, 616,
- 616, 616, 616, 616, 616, 616, 616, 616, 616, 616,
- 616, 616, 616, 616, 616, 616, 616, 616, 616, 616,
- 616, 616, nil, nil, nil, 616, 616, 616, 616, 616,
- 616, 616, 616, 616, 616, nil, nil, nil, nil, nil,
- 616, 616, 616, 616, 616, 616, 616, 616, 616, nil,
- nil, 616, nil, nil, nil, nil, nil, nil, nil, nil,
- 616, 616, nil, 616, 616, 616, 616, 616, 616, 616,
- nil, nil, 616, 616, nil, nil, nil, 616, 616, 616,
- 616, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 616, 616, nil, 616, 616, 616,
- 616, 616, 616, 616, 616, 616, 616, 616, 616, nil,
- nil, 616, 616, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 616, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, nil, nil, nil, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, nil, nil, nil, nil, nil, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, nil, 71, nil, nil, nil, nil, nil, nil, 71,
- 71, nil, 71, 71, 71, 71, 71, 71, 71, nil,
- nil, 71, 71, nil, nil, nil, 71, 71, 71, 71,
- nil, nil, nil, nil, nil, 71, nil, nil, nil, nil,
- nil, nil, nil, 71, 71, nil, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, nil, nil,
- 71, 738, 738, 738, 738, 738, 738, 738, 738, 738,
- 738, 738, 738, 738, 738, 738, 738, 738, 738, 738,
- 738, 738, 738, 738, 738, nil, nil, nil, 738, 738,
- 738, 738, 738, 738, 738, 738, 738, 738, nil, nil,
- nil, nil, nil, 738, 738, 738, 738, 738, 738, 738,
- 738, 738, nil, nil, 738, nil, nil, nil, nil, nil,
- nil, nil, nil, 738, 738, nil, 738, 738, 738, 738,
- 738, 738, 738, nil, nil, 738, 738, nil, nil, nil,
- 738, 738, 738, 738, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 738, 738, nil,
- 738, 738, 738, 738, 738, 738, 738, 738, 738, 738,
- 738, 738, 210, 210, 738, nil, 210, nil, nil, nil,
- nil, nil, nil, nil, nil, 210, 210, nil, 210, 210,
- 210, 210, 210, 210, 210, nil, nil, 210, 210, nil,
- nil, nil, 210, 210, 210, 210, nil, nil, nil, nil,
- nil, 210, nil, nil, nil, nil, nil, nil, nil, 210,
- 210, nil, 210, 210, 210, 210, 210, 210, 210, 210,
- 210, 210, 210, 210, 211, 211, 210, nil, 211, nil,
- nil, nil, nil, nil, nil, nil, nil, 211, 211, nil,
- 211, 211, 211, 211, 211, 211, 211, nil, nil, 211,
- 211, nil, nil, nil, 211, 211, 211, 211, nil, nil,
- nil, nil, nil, 211, nil, nil, nil, nil, nil, nil,
- nil, 211, 211, nil, 211, 211, 211, 211, 211, 211,
- 211, 211, 211, 211, 211, 211, 259, 259, 211, nil,
- 259, nil, nil, nil, nil, nil, nil, nil, nil, 259,
- 259, nil, 259, 259, 259, 259, 259, 259, 259, nil,
- nil, 259, 259, nil, nil, nil, 259, 259, 259, 259,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 259, 259, nil, 259, 259, 259, 259,
- 259, 259, 259, 259, 259, 259, 259, 259, 440, 440,
- 259, nil, 440, nil, nil, nil, nil, nil, nil, nil,
- nil, 440, 440, nil, 440, 440, 440, 440, 440, 440,
- 440, nil, nil, 440, 440, nil, nil, nil, 440, 440,
- 440, 440, nil, nil, nil, nil, nil, 440, nil, nil,
- nil, nil, nil, nil, nil, 440, 440, nil, 440, 440,
- 440, 440, 440, 440, 440, 440, 440, 440, 440, 440,
- 441, 441, 440, nil, 441, nil, nil, nil, nil, nil,
- nil, nil, nil, 441, 441, nil, 441, 441, 441, 441,
- 441, 441, 441, nil, nil, 441, 441, nil, nil, nil,
- 441, 441, 441, 441, nil, nil, nil, nil, nil, 441,
- nil, nil, nil, nil, nil, nil, nil, 441, 441, nil,
- 441, 441, 441, 441, 441, 441, 441, 441, 441, 441,
- 441, 441, 507, 507, 441, nil, 507, nil, nil, nil,
- nil, nil, nil, nil, nil, 507, 507, nil, 507, 507,
- 507, 507, 507, 507, 507, nil, nil, 507, 507, nil,
- nil, nil, 507, 507, 507, 507, nil, nil, nil, nil,
- nil, 507, nil, nil, nil, nil, nil, nil, nil, 507,
- 507, nil, 507, 507, 507, 507, 507, 507, 507, 507,
- 507, 507, 507, 507, 508, 508, 507, nil, 508, nil,
- nil, nil, nil, nil, nil, nil, nil, 508, 508, nil,
- 508, 508, 508, 508, 508, 508, 508, nil, nil, 508,
- 508, nil, nil, nil, 508, 508, 508, 508, nil, nil,
- nil, nil, nil, 508, nil, nil, nil, nil, nil, nil,
- nil, 508, 508, nil, 508, 508, 508, 508, 508, 508,
- 508, 508, 508, 508, 508, 508, 517, 517, 508, nil,
- 517, nil, nil, nil, nil, nil, nil, nil, nil, 517,
- 517, nil, 517, 517, 517, 517, 517, 517, 517, nil,
- nil, 517, 517, nil, nil, nil, 517, 517, 517, 517,
- nil, nil, nil, nil, nil, 517, nil, nil, nil, nil,
- nil, nil, nil, 517, 517, nil, 517, 517, 517, 517,
- 517, 517, 517, 517, 517, 517, 517, 517, 518, 518,
- 517, nil, 518, nil, nil, nil, nil, nil, nil, nil,
- nil, 518, 518, nil, 518, 518, 518, 518, 518, 518,
- 518, nil, nil, 518, 518, nil, nil, nil, 518, 518,
- 518, 518, nil, nil, nil, nil, nil, 518, nil, nil,
- nil, nil, nil, nil, nil, 518, 518, nil, 518, 518,
- 518, 518, 518, 518, 518, 518, 518, 518, 518, 518,
- 576, 576, 518, nil, 576, nil, nil, nil, nil, nil,
- nil, nil, nil, 576, 576, nil, 576, 576, 576, 576,
- 576, 576, 576, nil, nil, 576, 576, nil, nil, nil,
- 576, 576, 576, 576, nil, nil, nil, nil, nil, 576,
- nil, nil, nil, nil, nil, nil, nil, 576, 576, nil,
- 576, 576, 576, 576, 576, 576, 576, 576, 576, 576,
- 576, 576, 577, 577, 576, nil, 577, nil, nil, nil,
- nil, nil, nil, nil, nil, 577, 577, nil, 577, 577,
- 577, 577, 577, 577, 577, nil, nil, 577, 577, nil,
- nil, nil, 577, 577, 577, 577, nil, nil, nil, nil,
- nil, 577, nil, nil, nil, nil, nil, nil, nil, 577,
- 577, nil, 577, 577, 577, 577, 577, 577, 577, 577,
- 577, 577, 577, 577, 583, 583, 577, nil, 583, nil,
- nil, nil, nil, nil, nil, nil, nil, 583, 583, nil,
- 583, 583, 583, 583, 583, 583, 583, nil, nil, 583,
- 583, nil, nil, nil, 583, 583, 583, 583, nil, nil,
- nil, nil, nil, 583, nil, nil, nil, nil, nil, nil,
- nil, 583, 583, nil, 583, 583, 583, 583, 583, 583,
- 583, 583, 583, 583, 583, 583, 584, 584, 583, nil,
- 584, nil, nil, nil, nil, nil, nil, nil, nil, 584,
- 584, nil, 584, 584, 584, 584, 584, 584, 584, nil,
- nil, 584, 584, nil, nil, nil, 584, 584, 584, 584,
- nil, nil, nil, nil, nil, 584, nil, nil, nil, nil,
- nil, nil, nil, 584, 584, nil, 584, 584, 584, 584,
- 584, 584, 584, 584, 584, 584, 584, 584, 939, 939,
- 584, nil, 939, nil, nil, nil, nil, nil, nil, nil,
- nil, 939, 939, nil, 939, 939, 939, 939, 939, 939,
- 939, nil, nil, 939, 939, nil, nil, nil, 939, 939,
- 939, 939, nil, nil, nil, nil, nil, 939, nil, nil,
- nil, nil, nil, nil, nil, 939, 939, nil, 939, 939,
- 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- 986, 986, 939, nil, 986, nil, nil, nil, nil, nil,
- nil, nil, nil, 986, 986, nil, 986, 986, 986, 986,
- 986, 986, 986, nil, nil, 986, 986, nil, nil, nil,
- 986, 986, 986, 986, nil, nil, nil, nil, nil, 986,
- nil, nil, nil, nil, nil, nil, nil, 986, 986, nil,
- 986, 986, 986, 986, 986, 986, 986, 986, 986, 986,
- 986, 986, 987, 987, 986, nil, 987, nil, nil, nil,
- nil, nil, nil, nil, nil, 987, 987, nil, 987, 987,
- 987, 987, 987, 987, 987, nil, nil, 987, 987, nil,
- nil, nil, 987, 987, 987, 987, nil, nil, nil, nil,
- nil, 987, nil, nil, nil, nil, nil, nil, nil, 987,
- 987, nil, 987, 987, 987, 987, 987, 987, 987, 987,
- 987, 987, 987, 987, nil, 693, 987, 693, 693, 693,
- 693, 693, nil, 695, nil, 695, 695, 695, 695, 695,
- nil, 693, nil, nil, nil, nil, nil, nil, 736, 695,
- 736, 736, 736, 736, 736, nil, nil, nil, nil, nil,
- nil, nil, nil, 693, 736, nil, nil, nil, nil, nil,
- nil, 695, 693, 693, 693, 693, nil, nil, nil, 693,
- 695, 695, 695, 695, nil, nil, 736, 695, 737, nil,
- 737, 737, 737, 737, 737, 736, 736, 736, 736, nil,
- nil, nil, 736, 865, 737, 865, 865, 865, 865, 865,
- nil, 867, nil, 867, 867, 867, 867, 867, nil, 865,
- nil, nil, nil, nil, nil, nil, 737, 867, 893, nil,
- 893, 893, 893, 893, 893, 737, 737, 737, 737, nil,
- nil, 865, 737, nil, 893, nil, nil, nil, nil, 867,
- 865, 865, 865, 865, nil, nil, nil, 865, 867, 867,
- 867, 867, nil, nil, nil, 867, 893, 897, nil, 897,
- 897, 897, 897, 897, nil, 893, 893, 893, 893, nil,
- nil, nil, 893, 897, 899, nil, 899, 899, 899, 899,
- 899, nil, 971, nil, 971, 971, 971, 971, 971, nil,
- 899, nil, nil, nil, nil, 897, nil, 973, 971, 973,
- 973, 973, 973, 973, nil, nil, 897, 897, nil, nil,
- nil, 897, 899, 973, nil, nil, nil, nil, nil, nil,
- 971, nil, nil, 899, 899, nil, nil, nil, 899, 971,
- 971, 971, 971, nil, nil, 973, 971, 975, nil, 975,
- 975, 975, 975, 975, nil, nil, 973, 973, nil, nil,
- nil, 973, 977, 975, 977, 977, 977, 977, 977, nil,
- 989, nil, 989, 989, 989, 989, 989, 1015, 977, 1015,
- 1015, 1015, 1015, 1015, nil, 975, 989, nil, nil, nil,
- nil, nil, nil, 1015, nil, nil, 975, 975, nil, nil,
- 977, 975, nil, nil, nil, nil, nil, nil, 989, nil,
- nil, 977, 977, nil, nil, 1015, 977, nil, nil, 989,
- 989, nil, nil, nil, 989, nil, 1015, 1015, nil, nil,
- nil, 1015 ]
-
-racc_action_pointer = [
- 750, 47, nil, 123, nil, 5120, 1299, -62, 23249, 23378,
- -21, nil, -43, 71, 533, -41, 34, -4, nil, -72,
- 5252, 1173, 168, nil, 157, nil, 6, 22760, 22871, 5384,
- 5516, 5648, nil, 891, 5780, 5912, nil, 71, 227, 254,
- 154, 228, 6052, 6184, 6316, 95, 544, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 22355, nil, -71, 6448,
- 6580, -23, nil, 6712, 6844, nil, nil, 6976, 7116, 7248,
- 7380, 23765, nil, nil, nil, nil, nil, 470, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 0, nil, nil, 113, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 262,
- nil, 7520, nil, nil, nil, nil, 7660, 7792, 7924, 8056,
- 8196, 1032, nil, 220, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 141, nil, 1173, 8328, 8460, 8592,
- 23941, 24003, 8724, 8856, 8988, 9120, 9252, 9384, nil, nil,
- 546, -77, -62, 233, 131, 196, 256, nil, 9516, 1314,
- 273, 9648, 9780, 9912, 10044, 10176, 10308, 10440, 10572, 10704,
- 10836, 10968, 11100, 11232, 11364, 11496, 11628, 11760, 11892, 12024,
- 12156, 12288, 12420, 12552, 12684, 12816, nil, nil, nil, 24065,
- nil, nil, 275, 12948, 13080, nil, nil, nil, nil, nil,
- nil, nil, 13212, nil, 1314, nil, 262, 314, nil, 13344,
- 366, 13476, nil, nil, 13608, 13740, nil, nil, 296, nil,
- 13880, 1440, 368, 362, 1455, 384, 444, 418, 14012, 1596,
- 578, 615, 681, 505, 750, nil, 478, 439, 33, nil,
- nil, nil, 501, 258, 478, 14152, nil, 299, 561, 753,
- nil, 569, nil, 14284, 1737, 14416, 528, nil, 105, 259,
- 571, 585, 454, 619, nil, nil, 23117, 488, -1, 26,
- 14548, 14680, 458, 706, 596, -23, -19, 792, 691, -18,
- 724, nil, nil, 227, 281, -34, nil, 822, nil, 34,
- 14812, nil, nil, nil, 264, 409, 448, 451, 478, 508,
- 512, 532, 554, nil, 567, nil, 14944, nil, 275, 335,
- 363, 375, 392, -45, -41, 395, nil, nil, nil, nil,
- nil, nil, nil, nil, 643, 23507, nil, nil, nil, nil,
- 650, nil, nil, 642, 15076, 644, nil, nil, 891, 658,
- nil, 672, 676, 332, 342, 22984, nil, nil, nil, 224,
- 337, 723, nil, nil, 22490, 22625, nil, 1455, nil, 689,
- nil, nil, 750, nil, nil, nil, nil, -33, nil, 746,
- 24127, 24189, 15208, 239, 15340, 15472, 15604, 3147, 3288, 538,
- 659, 778, 783, 788, 798, 5120, 5252, 5384, 3429, 3570,
- 3711, 3852, 3993, 4134, 4275, 4416, 4557, 4698, 621, 630,
- 4839, 4980, 15736, -46, 23114, nil, nil, nil, nil, 747,
- nil, 159, 279, 750, nil, nil, 15868, nil, 16000, nil,
- 16132, nil, 332, nil, nil, nil, 16272, 1455, 1878, 752,
- 751, nil, nil, 754, 16412, 767, 16544, 24251, 24313, 891,
- 809, nil, 16676, 769, nil, 16808, 16940, 24375, 24437, 1596,
- 17072, 897, 896, 694, 824, nil, 17204, nil, nil, 17336,
- nil, nil, nil, nil, 23134, nil, 783, 784, nil, 785,
- 793, 794, nil, nil, nil, nil, nil, nil, nil, nil,
- 787, 477, nil, nil, 17468, nil, nil, nil, 880, nil,
- nil, nil, 881, nil, nil, 882, 2019, 935, nil, 2160,
- 63, 119, 935, 945, 17600, 17732, 24499, 24561, 10, nil,
- nil, 894, nil, 24623, 24685, 17864, nil, nil, nil, 587,
- 193, 2301, 883, nil, -14, nil, nil, nil, 733, nil,
- nil, nil, 858, nil, nil, 151, nil, 222, nil, nil,
- 846, nil, 847, nil, nil, nil, 23636, nil, 852, 17996,
- 18128, 380, 896, 18260, 18392, 18524, 18656, 899, nil, nil,
- 18788, 18920, 907, nil, 19052, 19184, nil, nil, 350, 416,
- 470, 607, 874, 1032, 1737, nil, 23078, nil, 2442, 979,
- 5, 316, nil, 2583, 2724, nil, 882, nil, 929, 19316,
- nil, nil, 19448, nil, 905, -81, 19580, 888, nil, 893,
- 137, 179, 935, 340, 1032, 936, 895, 19712, 1878, 972,
- 20, 1026, 19844, nil, 913, nil, 539, 21, 914, 495,
- nil, nil, 740, 24934, nil, 24942, nil, 5959, nil, 19976,
- nil, 607, nil, 912, 230, 925, nil, nil, nil, nil,
- 850, nil, 1044, nil, nil, nil, nil, 1050, nil, 32,
- 929, 26, 41, 123, 182, 20108, 414, 1173, nil, 937,
- 2865, 20240, nil, nil, 1060, 3006, 24957, 24997, 23879, nil,
- nil, nil, nil, nil, nil, 3147, nil, nil, nil, nil,
- nil, nil, nil, 937, 20372, 2019, 20504, nil, 938, nil,
- 2160, nil, 2301, nil, nil, 2442, nil, 2583, nil, 2724,
- 20636, 20768, 20900, 21032, 429, 940, 940, 954, nil, 958,
- 961, 980, nil, 1009, 992, 991, 989, 21164, nil, nil,
- 1128, nil, nil, 3288, 1031, 1137, nil, nil, nil, nil,
- 1013, 378, nil, nil, 1149, nil, 3429, 1024, 1072, nil,
- nil, 1072, nil, nil, 3570, 3711, 1074, 1032, nil, nil,
- nil, 1033, 1036, nil, 1046, 1047, nil, 1051, nil, nil,
- 1055, 614, 1053, 600, nil, 1188, nil, 21296, 1190, 3852,
- 3993, nil, 21428, 4134, 81, 122, nil, 1191, 611, 4275,
- nil, 1192, 1078, 613, nil, 1087, 1095, nil, 2865, 21560,
- 21692, nil, 525, nil, nil, 25012, nil, 25020, nil, 7427,
- nil, nil, 1123, 1159, 21824, 933, 1181, nil, 1141, nil,
- nil, nil, 4416, nil, nil, 33, 21956, nil, nil, 1146,
- 1255, nil, nil, 25037, nil, 14059, nil, 25076, nil, 25093,
- nil, nil, nil, nil, 330, 3415, 1134, nil, 36, nil,
- 1264, 1269, nil, 47, nil, nil, nil, 1277, nil, nil,
- nil, 1197, nil, 22088, 1154, nil, nil, 1164, 1165, 1167,
- 1170, nil, 1172, nil, 643, nil, nil, nil, 963, 24747,
- nil, nil, nil, 4557, 1035, 1074, 1104, 1252, 1176, nil,
- nil, nil, 1174, 1177, 1187, 1188, 1189, 3556, 1192, 3589,
- 4698, nil, nil, nil, nil, nil, 4839, nil, 4980, 3006,
- nil, 25101, nil, 25116, nil, 25156, nil, 25171, nil, nil,
- nil, 1300, 1237, 1238, 1323, 22220, 24809, 24871, 1215, 25179,
- nil, nil, nil, nil, 3697, 1216, 862, 1347, 1361, 1240,
- 1243, 1261, 1262, nil, nil, 1270, 40, 42, 112, 1314,
- 1268, 1271, nil, nil, nil, 25186, nil, nil, nil, nil,
- 43, nil, 1275, nil ]
-
-racc_action_default = [
- -3, -597, -1, -583, -4, -597, -7, -597, -597, -597,
- -597, -29, -597, -597, -597, -281, -597, -40, -43, -585,
- -597, -48, -50, -51, -52, -56, -258, -258, -258, -295,
- -330, -331, -68, -11, -72, -80, -82, -597, -488, -489,
- -597, -597, -597, -597, -597, -585, -239, -272, -273, -274,
- -275, -276, -277, -278, -279, -280, -573, -283, -285, -596,
- -563, -303, -391, -597, -597, -308, -311, -583, -597, -597,
- -597, -597, -332, -333, -429, -430, -431, -432, -433, -454,
- -436, -437, -456, -458, -441, -446, -450, -452, -468, -456,
- -470, -472, -473, -474, -475, -571, -477, -478, -572, -480,
- -481, -482, -483, -484, -485, -486, -487, -492, -493, -597,
- -2, -584, -592, -593, -594, -6, -597, -597, -597, -597,
- -597, -3, -17, -597, -111, -112, -113, -114, -115, -116,
- -117, -118, -119, -123, -124, -125, -126, -127, -128, -129,
- -130, -131, -132, -133, -134, -135, -136, -137, -138, -139,
- -140, -141, -142, -143, -144, -145, -146, -147, -148, -149,
- -150, -151, -152, -153, -154, -155, -156, -157, -158, -159,
- -160, -161, -162, -163, -164, -165, -166, -167, -168, -169,
- -170, -171, -172, -173, -174, -175, -176, -177, -178, -179,
- -180, -181, -182, -183, -184, -185, -186, -187, -188, -189,
- -190, -191, -192, -193, -22, -120, -11, -597, -597, -248,
- -597, -597, -597, -597, -597, -597, -597, -585, -586, -47,
- -597, -488, -489, -597, -281, -597, -597, -229, -597, -11,
- -597, -597, -597, -597, -597, -597, -597, -597, -597, -597,
- -597, -597, -597, -597, -597, -597, -597, -597, -597, -597,
- -597, -597, -597, -597, -597, -597, -236, -398, -400, -597,
- -581, -582, -57, -248, -597, -302, -404, -413, -415, -63,
- -410, -64, -585, -65, -240, -253, -262, -262, -257, -597,
- -263, -597, -454, -565, -597, -597, -66, -67, -583, -12,
- -597, -15, -597, -70, -11, -585, -597, -73, -76, -11,
- -88, -89, -597, -597, -96, -295, -298, -585, -597, -330,
- -331, -334, -411, -597, -78, -597, -84, -292, -471, -597,
- -214, -215, -230, -597, -11, -597, -585, -241, -589, -589,
- -597, -597, -589, -597, -304, -305, -521, -49, -597, -597,
- -597, -597, -583, -597, -584, -488, -489, -597, -597, -281,
- -597, -344, -345, -106, -107, -597, -109, -597, -281, -597,
- -597, -488, -489, -323, -111, -112, -153, -154, -155, -171,
- -176, -183, -186, -325, -597, -561, -597, -434, -597, -597,
- -597, -597, -597, -597, -597, -597, 1024, -5, -595, -23,
- -24, -25, -26, -27, -597, -597, -19, -20, -21, -121,
- -597, -30, -39, -268, -597, -597, -267, -31, -196, -585,
- -249, -262, -262, -574, -575, -258, -408, -576, -577, -575,
- -574, -258, -407, -409, -576, -577, -37, -204, -38, -597,
- -41, -42, -194, -263, -44, -45, -46, -585, -301, -597,
- -597, -597, -248, -292, -597, -597, -597, -205, -206, -207,
- -208, -209, -210, -211, -212, -216, -217, -218, -219, -220,
- -221, -222, -223, -224, -225, -226, -227, -228, -231, -232,
- -233, -234, -597, -380, -258, -574, -575, -54, -58, -585,
- -259, -380, -380, -585, -297, -254, -597, -255, -597, -260,
- -597, -264, -597, -568, -570, -10, -584, -14, -3, -585,
- -69, -290, -85, -74, -597, -585, -248, -597, -597, -95,
- -597, -471, -597, -81, -86, -597, -597, -597, -597, -235,
- -597, -421, -597, -286, -597, -242, -591, -590, -244, -591,
- -293, -294, -564, -392, -521, -395, -560, -560, -504, -506,
- -506, -506, -520, -522, -523, -524, -525, -526, -527, -528,
- -529, -597, -531, -533, -535, -540, -542, -543, -545, -550,
- -552, -553, -555, -556, -557, -597, -11, -335, -336, -11,
- -597, -597, -597, -597, -597, -248, -597, -597, -292, -316,
- -106, -107, -108, -597, -597, -248, -319, -494, -495, -597,
- -597, -11, -499, -327, -585, -435, -455, -460, -597, -462,
- -438, -457, -597, -459, -440, -597, -443, -597, -445, -448,
- -597, -449, -597, -469, -8, -18, -597, -28, -271, -597,
- -597, -412, -597, -250, -252, -597, -597, -59, -247, -405,
- -597, -597, -61, -406, -597, -597, -300, -587, -574, -575,
- -574, -575, -585, -194, -585, -381, -585, -383, -11, -53,
- -401, -380, -245, -11, -11, -296, -262, -261, -265, -597,
- -566, -567, -597, -13, -597, -71, -597, -77, -83, -585,
- -574, -575, -246, -92, -94, -597, -79, -597, -203, -213,
- -585, -596, -596, -284, -585, -289, -589, -597, -585, -597,
- -502, -503, -597, -597, -513, -597, -516, -597, -518, -597,
- -346, -597, -348, -350, -357, -585, -534, -544, -554, -558,
- -596, -337, -596, -309, -338, -339, -312, -597, -315, -597,
- -585, -574, -575, -578, -291, -597, -106, -107, -110, -585,
- -11, -597, -497, -321, -597, -11, -521, -521, -597, -562,
- -461, -464, -465, -466, -467, -11, -439, -442, -444, -447,
- -451, -453, -122, -269, -597, -197, -597, -588, -262, -33,
- -199, -34, -200, -60, -35, -202, -36, -201, -62, -195,
- -597, -597, -597, -597, -412, -597, -560, -560, -362, -364,
- -364, -364, -379, -597, -585, -385, -529, -537, -538, -548,
- -597, -403, -402, -11, -597, -597, -256, -266, -569, -16,
- -75, -90, -87, -299, -596, -342, -11, -422, -596, -423,
- -424, -597, -243, -393, -11, -11, -597, -560, -541, -559,
- -505, -506, -506, -532, -506, -506, -551, -506, -529, -546,
- -585, -597, -355, -597, -530, -597, -340, -597, -597, -11,
- -11, -314, -597, -11, -412, -597, -412, -597, -597, -11,
- -324, -597, -585, -597, -328, -597, -270, -32, -198, -251,
- -597, -237, -597, -360, -361, -370, -372, -597, -375, -597,
- -377, -382, -597, -597, -597, -536, -597, -399, -597, -414,
- -416, -9, -11, -428, -343, -597, -597, -426, -287, -597,
- -597, -394, -501, -597, -509, -597, -511, -597, -514, -597,
- -517, -519, -347, -349, -353, -597, -358, -306, -597, -307,
- -597, -597, -265, -596, -317, -320, -496, -597, -326, -498,
- -500, -499, -463, -597, -560, -539, -363, -364, -364, -364,
- -364, -549, -364, -384, -585, -387, -389, -390, -547, -597,
- -292, -55, -427, -11, -97, -98, -597, -597, -105, -425,
- -396, -397, -506, -506, -506, -506, -351, -597, -356, -597,
- -11, -310, -313, -417, -418, -419, -11, -322, -11, -238,
- -359, -597, -367, -597, -369, -597, -373, -597, -376, -378,
- -386, -597, -291, -578, -421, -248, -597, -597, -104, -597,
- -507, -510, -512, -515, -597, -354, -596, -597, -597, -364,
- -364, -364, -364, -388, -420, -585, -574, -575, -578, -103,
- -506, -352, -341, -318, -329, -597, -365, -368, -371, -374,
- -412, -508, -364, -366 ]
-
-racc_goto_table = [
- 216, 275, 275, 275, 14, 327, 373, 409, 573, 14,
- 522, 276, 276, 276, 266, 270, 311, 311, 258, 2,
- 415, 421, 334, 431, 220, 681, 323, 259, 122, 205,
- 535, 127, 127, 220, 220, 220, 406, 14, 302, 302,
- 550, 328, 428, 478, 297, 130, 130, 132, 132, 542,
- 311, 311, 311, 110, 114, 338, 339, 487, 438, 342,
- 513, 479, 735, 835, 582, 318, 660, 220, 220, 474,
- 111, 220, 347, 357, 357, 705, 621, 826, 219, 6,
- 314, 690, 691, 804, 6, 783, 566, 569, 713, 716,
- 378, 293, 295, 780, 127, 262, 269, 271, 906, 903,
- 525, 528, 115, 931, 532, 379, 935, 660, 389, 390,
- 391, 392, 385, 484, 838, 14, 937, 343, 114, 1,
- 220, 220, 220, 220, 14, 14, 881, 816, 359, 363,
- 648, 273, 286, 287, 605, 607, 500, 663, 653, 654,
- 394, 823, 204, 352, 402, 395, 277, 277, 277, 651,
- 616, 472, 657, 13, 657, 923, 330, 650, 13, 375,
- 331, 335, 350, 586, 374, 324, 325, 684, 326, 340,
- 958, 694, 696, 698, 839, 341, 329, 332, 840, 725,
- 966, 275, 730, 849, 591, 592, 13, 738, 921, 405,
- 6, 782, 487, 784, 934, 405, 533, 813, 416, 393,
- 6, 700, 660, 336, 687, 473, 481, 931, 387, 482,
- 14, 220, 220, 220, 1003, 963, 220, 220, 220, 220,
- 220, 220, 995, 872, 937, 830, 808, 903, 688, 885,
- 377, 296, 380, 14, 425, 275, 275, 717, 550, 381,
- 642, 382, 383, 384, 275, 740, 276, 542, 745, 667,
- 415, 421, 731, 821, 276, 818, 925, 676, nil, 1011,
- nil, nil, nil, nil, 13, 401, 407, 220, 220, nil,
- 426, 430, nil, 13, 13, 826, 220, 734, 636, nil,
- 311, 601, 603, 606, 606, nil, nil, 601, 510, 657,
- 657, nil, 728, 492, 14, nil, 266, 311, 14, nil,
- 270, nil, 302, 14, 669, nil, nil, 524, 793, 774,
- nil, nil, 927, 823, nil, 964, nil, 672, nil, 302,
- 652, 863, 864, nil, 655, 514, nil, 672, 14, 220,
- nil, nil, 570, 571, nil, nil, 801, 511, 495, 114,
- 665, nil, nil, 503, 220, 220, 668, 823, nil, 1012,
- 786, 700, 293, 499, 832, 496, nil, 293, 505, 13,
- nil, nil, 892, 914, 220, nil, 480, nil, nil, 497,
- nil, nil, nil, 720, 483, nil, nil, 593, nil, nil,
- 220, 277, 13, 729, nil, nil, 672, 844, nil, 277,
- 622, 968, 572, 114, 672, nil, 846, 550, nil, 550,
- nil, nil, nil, 628, 400, nil, nil, nil, 763, 633,
- 587, 800, nil, 768, 275, 615, 847, nil, 127, nil,
- nil, 851, nil, nil, nil, 823, nil, 296, 416, nil,
- 852, 853, 130, nil, 132, 739, 796, 660, nil, nil,
- 550, 550, nil, 13, 431, nil, 220, 13, nil, 542,
- 542, nil, 13, 894, 896, nil, 898, 900, 812, 901,
- nil, 333, 628, nil, 425, nil, nil, 843, nil, 970,
- nil, nil, nil, nil, nil, nil, nil, 13, 275, nil,
- nil, 700, nil, 700, 627, nil, 311, nil, 1004, nil,
- 632, nil, 296, nil, 311, 416, nil, 296, nil, 26,
- 14, nil, 14, nil, 26, 416, nil, 748, 302, 748,
- 220, 809, 781, nil, 514, nil, 302, 664, nil, 26,
- nil, 803, 514, nil, 220, 657, nil, nil, 26, 26,
- 26, 425, 26, nil, nil, 917, nil, nil, 796, nil,
- nil, 425, nil, 649, nil, nil, 834, 275, nil, nil,
- nil, nil, nil, nil, 956, 700, 719, 275, nil, 822,
- nil, 824, 26, 26, 416, nil, 26, nil, nil, 786,
- 14, 786, 416, 14, nil, nil, nil, 6, 965, 220,
- nil, nil, nil, nil, 990, 991, 992, 993, nil, 220,
- nil, nil, nil, nil, nil, 14, nil, 550, nil, nil,
- 425, nil, nil, 656, nil, nil, 425, 700, 403, 700,
- 26, 792, nil, nil, 433, 26, 26, 26, 26, 26,
- 26, 714, 714, 622, nil, 775, nil, 785, 810, 220,
- 220, nil, nil, 943, 220, 220, 752, nil, 220, 127,
- 732, 733, 1021, 686, 700, 791, nil, nil, 311, 13,
- 622, 13, 14, 130, 998, 132, 960, 14, 14, 311,
- 628, nil, nil, 633, 405, 811, nil, nil, nil, 785,
- 302, 902, 1020, 854, nil, 786, 514, nil, nil, nil,
- 489, 302, 491, 759, 761, 493, 494, 802, 764, 766,
- nil, nil, 430, 919, nil, nil, nil, nil, nil, nil,
- nil, 622, nil, nil, nil, 26, 26, 26, 26, nil,
- 622, 26, 26, 26, 26, 26, 26, 845, nil, 13,
- nil, nil, 13, 848, nil, nil, nil, nil, 26, 220,
- nil, 928, nil, 929, 14, 220, nil, nil, nil, 14,
- 758, nil, nil, nil, 13, nil, nil, nil, nil, 14,
- 883, nil, 15, nil, 887, nil, nil, 15, nil, 952,
- 220, 127, 26, 26, 710, 785, nil, 712, nil, 311,
- nil, 26, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 1005, nil, 15, 304, 304, nil, 26,
- nil, 875, nil, 26, nil, nil, 672, 14, 26, nil,
- nil, 13, nil, 16, nil, 618, 13, 13, 16, nil,
- 14, nil, nil, nil, 857, nil, nil, nil, 14, 14,
- 349, 358, 358, 26, 26, nil, nil, nil, nil, 908,
- nil, nil, nil, nil, nil, nil, 16, 999, nil, 26,
- 26, 220, nil, 14, 14, nil, 790, 14, nil, nil,
- nil, 794, 795, 14, 777, nil, 311, nil, nil, 26,
- nil, nil, nil, 15, nil, nil, 778, nil, 311, nil,
- nil, 351, 15, 15, nil, 26, nil, nil, 938, nil,
- nil, nil, nil, 13, nil, nil, 14, 658, 13, 333,
- 946, 661, nil, 779, nil, nil, 714, 817, 13, 916,
- nil, nil, nil, nil, 920, nil, nil, nil, nil, 819,
- nil, nil, 819, nil, 16, 980, nil, nil, nil, nil,
- nil, nil, nil, 16, 16, nil, nil, 658, nil, nil,
- 333, nil, nil, nil, nil, nil, nil, nil, 787, nil,
- nil, 26, 825, 855, 827, nil, 13, 14, nil, nil,
- nil, nil, nil, nil, nil, 706, nil, 275, 15, 13,
- nil, nil, 425, nil, 14, nil, nil, 13, 13, nil,
- 14, nil, 14, nil, 416, 433, nil, nil, nil, nil,
- nil, 15, nil, nil, nil, nil, 622, nil, nil, 220,
- nil, 878, 13, 13, nil, 26, 13, 26, nil, nil,
- nil, nil, 13, nil, 884, 26, nil, nil, nil, 16,
- 425, nil, 889, 890, nil, nil, 429, nil, nil, 26,
- 753, nil, nil, nil, 658, 333, nil, nil, nil, nil,
- nil, nil, 16, nil, nil, 13, nil, 910, 911, nil,
- nil, 913, 15, nil, nil, nil, 15, nil, nil, nil,
- 304, 15, nil, nil, nil, 337, 337, nil, nil, 337,
- 797, nil, nil, 798, nil, 26, nil, 304, 26, nil,
- 924, nil, nil, 777, 26, 777, 15, 777, nil, nil,
- 942, nil, 819, 807, 26, 778, nil, 778, nil, 778,
- 26, nil, nil, 16, nil, nil, 13, 16, nil, nil,
- 829, nil, 16, nil, nil, nil, nil, nil, 337, 337,
- 337, 337, nil, 13, 930, nil, 932, nil, nil, 13,
- nil, 13, nil, nil, 26, 26, nil, 16, nil, 26,
- 26, nil, nil, 26, 866, 868, 870, nil, nil, nil,
- 953, 984, 954, nil, 955, nil, nil, 26, nil, nil,
- nil, nil, 26, 26, 787, 856, nil, 787, 996, 787,
- nil, 787, nil, nil, 997, nil, nil, nil, nil, nil,
- 38, nil, nil, nil, nil, 38, nil, nil, nil, 777,
- nil, 777, nil, 777, nil, 777, nil, nil, nil, nil,
- nil, 778, nil, 778, nil, 778, nil, 778, nil, nil,
- nil, nil, nil, 38, 300, 300, 434, 435, 436, 437,
- nil, nil, nil, nil, nil, nil, nil, nil, 1000, nil,
- 1001, nil, 1002, 777, 26, nil, nil, nil, nil, 26,
- 26, nil, nil, nil, 26, 778, 1010, nil, 345, 361,
- 361, 361, nil, 912, 26, nil, nil, nil, 15, nil,
- 15, nil, nil, nil, nil, 26, 304, nil, nil, nil,
- 333, nil, 1022, 787, 304, 787, nil, 787, nil, 787,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 38, 972, 974, 976, 978, nil, 979, nil, nil,
- 38, 38, 26, nil, nil, nil, nil, nil, nil, 16,
- nil, 16, nil, nil, nil, 26, nil, 787, nil, nil,
- nil, nil, nil, 26, 26, nil, nil, 523, 15, nil,
- nil, 15, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 337, 337, nil, nil, 26, nil, 26, 26,
- nil, nil, 26, 15, nil, nil, nil, nil, 26, nil,
- 744, nil, 590, nil, 1016, 1017, 1018, 1019, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 594, 16,
- nil, nil, 16, nil, nil, nil, 38, 1023, nil, nil,
- nil, 26, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 16, nil, nil, nil, nil, 38,
- 15, nil, nil, nil, nil, 15, 15, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 304, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 304,
- nil, nil, nil, nil, nil, nil, nil, 429, nil, nil,
- nil, nil, 26, nil, nil, nil, nil, nil, nil, nil,
- nil, 16, nil, nil, nil, nil, 16, 16, 39, 26,
- 38, nil, nil, 39, 38, 26, nil, 26, 300, 38,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 15, nil, 26, 300, nil, 15, nil, nil,
- nil, 39, 301, 301, 38, nil, nil, 15, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 680, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 346, 362, 362, 362,
- nil, nil, nil, 16, nil, nil, nil, nil, 16, 358,
- nil, nil, nil, nil, nil, 15, nil, nil, 16, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 15, nil,
- nil, nil, nil, nil, nil, nil, 15, 15, nil, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, 39, 39,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 15, 15, nil, nil, 15, 16, nil, nil, nil,
- nil, 15, nil, nil, nil, nil, nil, nil, nil, 16,
- nil, nil, nil, nil, nil, nil, nil, 16, 16, nil,
- nil, nil, nil, nil, nil, nil, 358, nil, nil, nil,
- nil, nil, nil, nil, 15, nil, nil, nil, 948, nil,
- nil, nil, 16, 16, nil, nil, 16, nil, nil, nil,
- nil, nil, 16, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 39, nil, 38, nil, 38, nil,
- nil, nil, nil, nil, 300, nil, nil, nil, nil, nil,
- nil, nil, 300, nil, nil, 16, nil, 39, nil, 949,
- nil, nil, nil, nil, nil, 15, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 15, nil, nil, nil, nil, 337, 15, nil,
- 15, nil, nil, 337, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 38, nil, nil, 38,
- nil, nil, nil, nil, nil, nil, 16, nil, 39, nil,
- nil, nil, 39, nil, nil, nil, 301, 39, nil, nil,
- nil, 38, nil, 16, nil, nil, nil, nil, nil, 16,
- nil, 16, nil, 301, nil, nil, nil, nil, nil, nil,
- nil, nil, 39, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 38, nil,
- nil, nil, nil, 38, 38, nil, nil, nil, nil, 337,
- nil, nil, nil, nil, nil, nil, 300, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 300, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 38, nil, nil, nil, nil, 38, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 38, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 39, nil, 39, 361, nil, nil,
- nil, nil, 301, 38, nil, nil, nil, nil, nil, nil,
- 301, nil, nil, nil, nil, nil, 38, nil, nil, nil,
- nil, nil, nil, nil, 38, 38, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 38,
- 38, nil, nil, 38, nil, nil, nil, nil, nil, 38,
- nil, nil, nil, nil, 39, nil, nil, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 361, nil, nil, nil, nil, 39,
- nil, nil, 38, nil, nil, nil, 944, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 39, nil, nil, nil,
- nil, 39, 39, 38, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 301, nil, nil, nil, nil, nil,
- 38, nil, nil, nil, 227, 301, 38, nil, 38, nil,
- nil, nil, nil, 274, 274, 274, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 320, 321, 322, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 274, 274, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 39, nil,
- nil, nil, nil, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 362, nil, nil, nil, nil,
- nil, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 39, nil, nil, nil, nil, nil,
- nil, nil, 39, 39, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 39, 39, nil,
- nil, 39, nil, nil, nil, nil, nil, 39, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 274, 408, 274, nil, nil, 427, 432, nil, nil,
- nil, nil, 362, nil, nil, nil, nil, nil, nil, nil,
- 39, nil, 227, nil, 945, 447, 448, 449, 450, 451,
- 452, 453, 454, 455, 456, 457, 458, 459, 460, 461,
- 462, 463, 464, 465, 466, 467, 468, 469, 470, 471,
- nil, nil, nil, nil, nil, nil, nil, 274, 274, nil,
- nil, nil, nil, nil, nil, nil, 274, nil, nil, nil,
- nil, nil, nil, 274, nil, 274, nil, nil, 274, 274,
- nil, 39, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 39, nil,
- nil, nil, nil, nil, 39, nil, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 519, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 274, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 274, nil, 427, 643,
- 408, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 644, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 274, nil, 274, nil, 274, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 274, nil, nil, nil, nil, nil, nil, nil, nil, 678,
- 679, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 274, nil, nil, 274, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 274, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 274, 274,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 274,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 274, 755, nil, nil, 274, 274, 760,
- 762, nil, nil, nil, 765, 767, nil, nil, 643, 769,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 274, nil, nil, 274, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 274, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 274, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 274, nil,
- 858, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 760, 762, 767, 765, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 274, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 274, 858, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 969, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 274 ]
-
-racc_goto_check = [
- 31, 33, 33, 33, 22, 69, 56, 23, 94, 22,
- 8, 70, 70, 70, 73, 73, 64, 64, 140, 2,
- 37, 37, 88, 18, 22, 10, 31, 36, 15, 15,
- 139, 57, 57, 22, 22, 22, 27, 22, 22, 22,
- 168, 70, 27, 39, 49, 60, 60, 61, 61, 163,
- 64, 64, 64, 4, 97, 17, 17, 75, 47, 17,
- 51, 23, 98, 92, 54, 63, 178, 22, 22, 37,
- 6, 22, 22, 22, 22, 118, 24, 174, 20, 7,
- 50, 123, 123, 11, 7, 131, 91, 91, 93, 93,
- 151, 45, 46, 128, 57, 38, 38, 38, 119, 116,
- 71, 71, 5, 175, 71, 152, 133, 178, 17, 17,
- 17, 17, 152, 47, 11, 22, 134, 4, 97, 1,
- 22, 22, 22, 22, 22, 22, 12, 131, 55, 55,
- 40, 44, 44, 44, 155, 155, 47, 14, 40, 40,
- 2, 169, 16, 19, 28, 30, 72, 72, 72, 42,
- 62, 66, 76, 21, 76, 67, 68, 74, 21, 86,
- 87, 90, 95, 96, 99, 100, 101, 102, 103, 104,
- 119, 166, 166, 166, 105, 106, 72, 72, 107, 108,
- 109, 33, 110, 111, 112, 113, 21, 114, 115, 70,
- 7, 120, 75, 126, 132, 70, 135, 136, 73, 7,
- 7, 117, 178, 137, 138, 141, 143, 175, 5, 144,
- 22, 22, 22, 22, 133, 145, 22, 22, 22, 22,
- 22, 22, 119, 131, 134, 118, 146, 116, 139, 147,
- 150, 9, 153, 22, 57, 33, 33, 94, 168, 154,
- 23, 157, 158, 159, 33, 160, 70, 163, 161, 51,
- 37, 37, 162, 167, 70, 171, 172, 51, nil, 119,
- nil, nil, nil, nil, 21, 20, 20, 22, 22, nil,
- 20, 20, nil, 21, 21, 174, 22, 8, 47, nil,
- 64, 156, 156, 156, 156, nil, nil, 156, 31, 76,
- 76, nil, 54, 151, 22, nil, 73, 64, 22, nil,
- 73, nil, 22, 22, 23, nil, nil, 31, 40, 24,
- nil, nil, 128, 169, nil, 11, nil, 37, nil, 22,
- 47, 123, 123, nil, 47, 49, nil, 37, 22, 22,
- nil, nil, 17, 17, nil, nil, 24, 63, 4, 97,
- 47, nil, nil, 50, 22, 22, 47, 169, nil, 92,
- 168, 117, 45, 46, 117, 6, nil, 45, 46, 21,
- nil, nil, 123, 93, 22, nil, 44, nil, nil, 7,
- nil, nil, nil, 23, 44, nil, nil, 36, nil, nil,
- 22, 72, 21, 23, nil, nil, 37, 24, nil, 72,
- 31, 98, 4, 97, 37, nil, 24, 168, nil, 168,
- nil, nil, nil, 73, 9, nil, nil, nil, 39, 73,
- 97, 51, nil, 39, 33, 15, 8, nil, 57, nil,
- nil, 8, nil, nil, nil, 169, nil, 9, 73, nil,
- 139, 139, 60, nil, 61, 47, 75, 178, nil, nil,
- 168, 168, nil, 21, 18, nil, 22, 21, nil, 163,
- 163, nil, 21, 166, 166, nil, 166, 166, 71, 166,
- nil, 65, 73, nil, 57, nil, nil, 91, nil, 123,
- nil, nil, nil, nil, nil, nil, nil, 21, 33, nil,
- nil, 117, nil, 117, 38, nil, 64, nil, 10, nil,
- 38, nil, 9, nil, 64, 73, nil, 9, nil, 41,
- 22, nil, 22, nil, 41, 73, nil, 156, 22, 156,
- 22, 27, 129, nil, 49, nil, 22, 2, nil, 41,
- nil, 47, 49, nil, 22, 76, nil, nil, 41, 41,
- 41, 57, 41, nil, nil, 8, nil, nil, 75, nil,
- nil, 57, nil, 38, nil, nil, 47, 33, nil, nil,
- nil, nil, nil, nil, 117, 117, 70, 33, nil, 129,
- nil, 129, 41, 41, 73, nil, 41, nil, nil, 168,
- 22, 168, 73, 22, nil, nil, nil, 7, 94, 22,
- nil, nil, nil, nil, 166, 166, 166, 166, nil, 22,
- nil, nil, nil, nil, nil, 22, nil, 168, nil, nil,
- 57, nil, nil, 72, nil, nil, 57, 117, 65, 117,
- 41, 88, nil, nil, 65, 41, 41, 41, 41, 41,
- 41, 97, 97, 31, nil, 31, nil, 31, 69, 22,
- 22, nil, nil, 91, 22, 22, 15, nil, 22, 57,
- 97, 97, 166, 72, 117, 140, nil, nil, 64, 21,
- 31, 21, 22, 60, 8, 61, 91, 22, 22, 64,
- 73, nil, nil, 73, 70, 31, nil, nil, nil, 31,
- 22, 47, 24, 56, nil, 168, 49, nil, nil, nil,
- 65, 22, 65, 20, 20, 65, 65, 49, 20, 20,
- nil, nil, 20, 47, nil, nil, nil, nil, nil, nil,
- nil, 31, nil, nil, nil, 41, 41, 41, 41, nil,
- 31, 41, 41, 41, 41, 41, 41, 17, nil, 21,
- nil, nil, 21, 17, nil, nil, nil, nil, 41, 22,
- nil, 129, nil, 129, 22, 22, nil, nil, nil, 22,
- 72, nil, nil, nil, 21, nil, nil, nil, nil, 22,
- 69, nil, 25, nil, 69, nil, nil, 25, nil, 129,
- 22, 57, 41, 41, 9, 31, nil, 9, nil, 64,
- nil, 41, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 23, nil, 25, 25, 25, nil, 41,
- nil, 22, nil, 41, nil, nil, 37, 22, 41, nil,
- nil, 21, nil, 26, nil, 65, 21, 21, 26, nil,
- 22, nil, nil, nil, 20, nil, nil, nil, 22, 22,
- 25, 25, 25, 41, 41, nil, nil, nil, nil, 17,
- nil, nil, nil, nil, nil, nil, 26, 129, nil, 41,
- 41, 22, nil, 22, 22, nil, 9, 22, nil, nil,
- nil, 9, 9, 22, 122, nil, 64, nil, nil, 41,
- nil, nil, nil, 25, nil, nil, 124, nil, 64, nil,
- nil, 26, 25, 25, nil, 41, nil, nil, 22, nil,
- nil, nil, nil, 21, nil, nil, 22, 65, 21, 65,
- 22, 65, nil, 127, nil, nil, 97, 122, 21, 97,
- nil, nil, nil, nil, 97, nil, nil, nil, nil, 124,
- nil, nil, 124, nil, 26, 31, nil, nil, nil, nil,
- nil, nil, nil, 26, 26, nil, nil, 65, nil, nil,
- 65, nil, nil, nil, nil, nil, nil, nil, 170, nil,
- nil, 41, 127, 9, 127, nil, 21, 22, nil, nil,
- nil, nil, nil, nil, nil, 65, nil, 33, 25, 21,
- nil, nil, 57, nil, 22, nil, nil, 21, 21, nil,
- 22, nil, 22, nil, 73, 65, nil, nil, nil, nil,
- nil, 25, nil, nil, nil, nil, 31, nil, nil, 22,
- nil, 9, 21, 21, nil, 41, 21, 41, nil, nil,
- nil, nil, 21, nil, 9, 41, nil, nil, nil, 26,
- 57, nil, 9, 9, nil, nil, 26, nil, nil, 41,
- 65, nil, nil, nil, 65, 65, nil, nil, nil, nil,
- nil, nil, 26, nil, nil, 21, nil, 9, 9, nil,
- nil, 9, 25, nil, nil, nil, 25, nil, nil, nil,
- 25, 25, nil, nil, nil, 29, 29, nil, nil, 29,
- 65, nil, nil, 65, nil, 41, nil, 25, 41, nil,
- 122, nil, nil, 122, 41, 122, 25, 122, nil, nil,
- 9, nil, 124, 65, 41, 124, nil, 124, nil, 124,
- 41, nil, nil, 26, nil, nil, 21, 26, nil, nil,
- 65, nil, 26, nil, nil, nil, nil, nil, 29, 29,
- 29, 29, nil, 21, 127, nil, 127, nil, nil, 21,
- nil, 21, nil, nil, 41, 41, nil, 26, nil, 41,
- 41, nil, nil, 41, 125, 125, 125, nil, nil, nil,
- 127, 9, 127, nil, 127, nil, nil, 41, nil, nil,
- nil, nil, 41, 41, 170, 65, nil, 170, 9, 170,
- nil, 170, nil, nil, 9, nil, nil, nil, nil, nil,
- 52, nil, nil, nil, nil, 52, nil, nil, nil, 122,
- nil, 122, nil, 122, nil, 122, nil, nil, nil, nil,
- nil, 124, nil, 124, nil, 124, nil, 124, nil, nil,
- nil, nil, nil, 52, 52, 52, 29, 29, 29, 29,
- nil, nil, nil, nil, nil, nil, nil, nil, 127, nil,
- 127, nil, 127, 122, 41, nil, nil, nil, nil, 41,
- 41, nil, nil, nil, 41, 124, 127, nil, 52, 52,
- 52, 52, nil, 65, 41, nil, nil, nil, 25, nil,
- 25, nil, nil, nil, nil, 41, 25, nil, nil, nil,
- 65, nil, 127, 170, 25, 170, nil, 170, nil, 170,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 52, 125, 125, 125, 125, nil, 125, nil, nil,
- 52, 52, 41, nil, nil, nil, nil, nil, nil, 26,
- nil, 26, nil, nil, nil, 41, nil, 170, nil, nil,
- nil, nil, nil, 41, 41, nil, nil, 29, 25, nil,
- nil, 25, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 29, 29, nil, nil, 41, nil, 41, 41,
- nil, nil, 41, 25, nil, nil, nil, nil, 41, nil,
- 25, nil, 29, nil, 125, 125, 125, 125, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 29, 26,
- nil, nil, 26, nil, nil, nil, 52, 125, nil, nil,
- nil, 41, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 26, nil, nil, nil, nil, 52,
- 25, nil, nil, nil, nil, 25, 25, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 25, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 25,
- nil, nil, nil, nil, nil, nil, nil, 26, nil, nil,
- nil, nil, 41, nil, nil, nil, nil, nil, nil, nil,
- nil, 26, nil, nil, nil, nil, 26, 26, 53, 41,
- 52, nil, nil, 53, 52, 41, nil, 41, 52, 52,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 25, nil, 41, 52, nil, 25, nil, nil,
- nil, 53, 53, 53, 52, nil, nil, 25, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 29, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 53, 53, 53, 53,
- nil, nil, nil, 26, nil, nil, nil, nil, 26, 25,
- nil, nil, nil, nil, nil, 25, nil, nil, 26, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 25, nil,
- nil, nil, nil, nil, nil, nil, 25, 25, nil, 53,
- nil, nil, nil, nil, nil, nil, nil, nil, 53, 53,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 25, 25, nil, nil, 25, 26, nil, nil, nil,
- nil, 25, nil, nil, nil, nil, nil, nil, nil, 26,
- nil, nil, nil, nil, nil, nil, nil, 26, 26, nil,
- nil, nil, nil, nil, nil, nil, 25, nil, nil, nil,
- nil, nil, nil, nil, 25, nil, nil, nil, 25, nil,
- nil, nil, 26, 26, nil, nil, 26, nil, nil, nil,
- nil, nil, 26, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 53, nil, 52, nil, 52, nil,
- nil, nil, nil, nil, 52, nil, nil, nil, nil, nil,
- nil, nil, 52, nil, nil, 26, nil, 53, nil, 26,
- nil, nil, nil, nil, nil, 25, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 25, nil, nil, nil, nil, 29, 25, nil,
- 25, nil, nil, 29, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 52, nil, nil, 52,
- nil, nil, nil, nil, nil, nil, 26, nil, 53, nil,
- nil, nil, 53, nil, nil, nil, 53, 53, nil, nil,
- nil, 52, nil, 26, nil, nil, nil, nil, nil, 26,
- nil, 26, nil, 53, nil, nil, nil, nil, nil, nil,
- nil, nil, 53, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 52, nil,
- nil, nil, nil, 52, 52, nil, nil, nil, nil, 29,
- nil, nil, nil, nil, nil, nil, 52, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 52, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 52, nil, nil, nil, nil, 52, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 52, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 53, nil, 53, 52, nil, nil,
- nil, nil, 53, 52, nil, nil, nil, nil, nil, nil,
- 53, nil, nil, nil, nil, nil, 52, nil, nil, nil,
- nil, nil, nil, nil, 52, 52, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 52,
- 52, nil, nil, 52, nil, nil, nil, nil, nil, 52,
- nil, nil, nil, nil, 53, nil, nil, 53, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 52, nil, nil, nil, nil, 53,
- nil, nil, 52, nil, nil, nil, 52, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 53, nil, nil, nil,
- nil, 53, 53, 52, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 53, nil, nil, nil, nil, nil,
- 52, nil, nil, nil, 32, 53, 52, nil, 52, nil,
- nil, nil, nil, 32, 32, 32, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 32, 32, 32, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 32, 32, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 53, nil,
- nil, nil, nil, 53, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 53, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 53, nil, nil, nil, nil,
- nil, 53, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 53, nil, nil, nil, nil, nil,
- nil, nil, 53, 53, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 53, 53, nil,
- nil, 53, nil, nil, nil, nil, nil, 53, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 32, 32, 32, nil, nil, 32, 32, nil, nil,
- nil, nil, 53, nil, nil, nil, nil, nil, nil, nil,
- 53, nil, 32, nil, 53, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
- nil, nil, nil, nil, nil, nil, nil, 32, 32, nil,
- nil, nil, nil, nil, nil, nil, 32, nil, nil, nil,
- nil, nil, nil, 32, nil, 32, nil, nil, 32, 32,
- nil, 53, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 53, nil,
- nil, nil, nil, nil, 53, nil, 53, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 32, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 32, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 32, nil, 32, 32,
- 32, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 32, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 32, nil, 32, nil, 32, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 32, nil, nil, nil, nil, nil, nil, nil, nil, 32,
- 32, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 32, nil, nil, 32, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 32, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 32, 32,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 32,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 32, 32, nil, nil, 32, 32, 32,
- 32, nil, nil, nil, 32, 32, nil, nil, 32, 32,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 32, nil, nil, 32, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 32, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 32, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, 32, nil,
- 32, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, 32, 32, 32, 32, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 32, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 32, 32, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 32, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 32 ]
-
-racc_goto_pointer = [
- nil, 119, 19, nil, 50, 97, 67, 79, -314, 198,
- -496, -598, -678, nil, -359, 20, 133, -8, -190, 75,
- 58, 153, 4, -202, -333, 752, 803, -171, -63, 992,
- 23, -19, 2114, -28, nil, nil, 3, -190, 69, -219,
- -343, 499, -328, nil, 102, 58, 59, -159, nil, 10,
- 45, -255, 1170, 1458, -291, 59, -65, 23, nil, nil,
- 37, 39, -249, 24, -18, 401, -105, -706, 97, -54,
- -18, -228, 117, -12, -317, -220, -334, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 88, 100, -39, nil,
- 99, -252, -647, -482, -335, 94, -196, 51, -530, 93,
- 108, 108, -356, 110, 104, -539, 109, -538, -400, -734,
- -404, -550, -179, -188, -406, -666, -732, -350, -476, -735,
- -455, nil, 208, -455, 220, 355, -453, 247, -553, -134,
- nil, -561, -679, -767, -757, -140, -490, 141, -329, -306,
- -4, -52, nil, -61, -59, -698, -456, -579, nil, nil,
- 153, 11, 23, 149, 155, -247, -98, 156, 156, 156,
- -353, -351, -336, -287, nil, nil, -368, -440, -296, -552,
- 292, -434, -606, nil, -618, -764, nil, nil, -422 ]
-
-racc_goto_default = [
- nil, nil, nil, 3, nil, 4, 344, 291, nil, 521,
- nil, 836, nil, 288, 289, nil, nil, nil, 11, 12,
- 18, 226, 319, nil, nil, 224, 225, nil, nil, 17,
- nil, 439, 21, 22, 23, 24, nil, 675, nil, nil,
- nil, 308, nil, 25, 410, 32, nil, nil, 34, 37,
- 36, nil, 221, 222, 356, nil, 129, 418, 128, 131,
- 75, 76, nil, 90, 46, 280, nil, nil, nil, 805,
- 411, nil, 412, 423, 629, 485, 278, 264, 47, 48,
- 49, 50, 51, 52, 53, 54, 55, nil, 265, 61,
- nil, nil, nil, nil, nil, nil, nil, 567, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 702, 549, nil, 703,
- 926, 776, 537, nil, 538, nil, nil, 539, nil, 541,
- 645, nil, nil, nil, 547, nil, nil, nil, nil, nil,
- nil, nil, 422, nil, nil, nil, nil, nil, 74, 77,
- 78, nil, nil, nil, nil, nil, 596, nil, nil, nil,
- nil, nil, nil, 820, 737, 536, nil, 540, 828, 552,
- 554, 555, 788, 558, 559, 789, 562, 565, 283 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 146, :_reduce_none,
- 2, 147, :_reduce_2,
- 0, 148, :_reduce_3,
- 1, 148, :_reduce_4,
- 3, 148, :_reduce_5,
- 2, 148, :_reduce_6,
- 1, 150, :_reduce_none,
- 4, 150, :_reduce_8,
- 4, 153, :_reduce_9,
- 2, 154, :_reduce_10,
- 0, 158, :_reduce_11,
- 1, 158, :_reduce_12,
- 3, 158, :_reduce_13,
- 2, 158, :_reduce_14,
- 1, 159, :_reduce_none,
- 4, 159, :_reduce_16,
- 0, 175, :_reduce_17,
- 4, 152, :_reduce_18,
- 3, 152, :_reduce_19,
- 3, 152, :_reduce_20,
- 3, 152, :_reduce_21,
- 2, 152, :_reduce_22,
- 3, 152, :_reduce_23,
- 3, 152, :_reduce_24,
- 3, 152, :_reduce_25,
- 3, 152, :_reduce_26,
- 3, 152, :_reduce_27,
- 4, 152, :_reduce_28,
- 1, 152, :_reduce_none,
- 3, 152, :_reduce_30,
- 3, 152, :_reduce_31,
- 6, 152, :_reduce_32,
- 5, 152, :_reduce_33,
- 5, 152, :_reduce_34,
- 5, 152, :_reduce_35,
- 5, 152, :_reduce_36,
- 3, 152, :_reduce_37,
- 3, 152, :_reduce_38,
- 3, 152, :_reduce_39,
- 1, 152, :_reduce_none,
- 3, 163, :_reduce_41,
- 3, 163, :_reduce_42,
- 1, 174, :_reduce_none,
- 3, 174, :_reduce_44,
- 3, 174, :_reduce_45,
- 3, 174, :_reduce_46,
- 2, 174, :_reduce_47,
- 1, 174, :_reduce_none,
- 1, 162, :_reduce_none,
- 1, 165, :_reduce_none,
- 1, 165, :_reduce_none,
- 1, 179, :_reduce_none,
- 4, 179, :_reduce_53,
- 0, 187, :_reduce_54,
- 5, 184, :_reduce_55,
- 1, 186, :_reduce_none,
- 2, 178, :_reduce_57,
- 3, 178, :_reduce_58,
- 4, 178, :_reduce_59,
- 5, 178, :_reduce_60,
- 4, 178, :_reduce_61,
- 5, 178, :_reduce_62,
- 2, 178, :_reduce_63,
- 2, 178, :_reduce_64,
- 2, 178, :_reduce_65,
- 2, 178, :_reduce_66,
- 2, 178, :_reduce_67,
- 1, 164, :_reduce_68,
- 3, 164, :_reduce_69,
- 1, 191, :_reduce_70,
- 3, 191, :_reduce_71,
- 1, 190, :_reduce_none,
- 2, 190, :_reduce_73,
- 3, 190, :_reduce_74,
- 5, 190, :_reduce_75,
- 2, 190, :_reduce_76,
- 4, 190, :_reduce_77,
- 2, 190, :_reduce_78,
- 4, 190, :_reduce_79,
- 1, 190, :_reduce_80,
- 3, 190, :_reduce_81,
- 1, 194, :_reduce_none,
- 3, 194, :_reduce_83,
- 2, 193, :_reduce_84,
- 3, 193, :_reduce_85,
- 1, 196, :_reduce_86,
- 3, 196, :_reduce_87,
- 1, 195, :_reduce_88,
- 1, 195, :_reduce_89,
- 4, 195, :_reduce_90,
- 3, 195, :_reduce_91,
- 3, 195, :_reduce_92,
- 3, 195, :_reduce_93,
- 3, 195, :_reduce_94,
- 2, 195, :_reduce_95,
- 1, 195, :_reduce_96,
- 1, 171, :_reduce_97,
- 1, 171, :_reduce_98,
- 4, 171, :_reduce_99,
- 3, 171, :_reduce_100,
- 3, 171, :_reduce_101,
- 3, 171, :_reduce_102,
- 3, 171, :_reduce_103,
- 2, 171, :_reduce_104,
- 1, 171, :_reduce_105,
- 1, 199, :_reduce_106,
- 1, 199, :_reduce_none,
- 2, 200, :_reduce_108,
- 1, 200, :_reduce_109,
- 3, 200, :_reduce_110,
- 1, 201, :_reduce_none,
- 1, 201, :_reduce_none,
- 1, 201, :_reduce_none,
- 1, 201, :_reduce_none,
- 1, 201, :_reduce_none,
- 1, 204, :_reduce_116,
- 1, 204, :_reduce_none,
- 1, 160, :_reduce_none,
- 1, 160, :_reduce_none,
- 1, 161, :_reduce_120,
- 0, 207, :_reduce_121,
- 4, 161, :_reduce_122,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 202, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 1, 203, :_reduce_none,
- 3, 177, :_reduce_194,
- 5, 177, :_reduce_195,
- 3, 177, :_reduce_196,
- 5, 177, :_reduce_197,
- 6, 177, :_reduce_198,
- 5, 177, :_reduce_199,
- 5, 177, :_reduce_200,
- 5, 177, :_reduce_201,
- 5, 177, :_reduce_202,
- 4, 177, :_reduce_203,
- 3, 177, :_reduce_204,
- 3, 177, :_reduce_205,
- 3, 177, :_reduce_206,
- 3, 177, :_reduce_207,
- 3, 177, :_reduce_208,
- 3, 177, :_reduce_209,
- 3, 177, :_reduce_210,
- 3, 177, :_reduce_211,
- 3, 177, :_reduce_212,
- 4, 177, :_reduce_213,
- 2, 177, :_reduce_214,
- 2, 177, :_reduce_215,
- 3, 177, :_reduce_216,
- 3, 177, :_reduce_217,
- 3, 177, :_reduce_218,
- 3, 177, :_reduce_219,
- 3, 177, :_reduce_220,
- 3, 177, :_reduce_221,
- 3, 177, :_reduce_222,
- 3, 177, :_reduce_223,
- 3, 177, :_reduce_224,
- 3, 177, :_reduce_225,
- 3, 177, :_reduce_226,
- 3, 177, :_reduce_227,
- 3, 177, :_reduce_228,
- 2, 177, :_reduce_229,
- 2, 177, :_reduce_230,
- 3, 177, :_reduce_231,
- 3, 177, :_reduce_232,
- 3, 177, :_reduce_233,
- 3, 177, :_reduce_234,
- 3, 177, :_reduce_235,
- 0, 211, :_reduce_236,
- 0, 212, :_reduce_237,
- 8, 177, :_reduce_238,
- 1, 177, :_reduce_none,
- 1, 210, :_reduce_none,
- 1, 213, :_reduce_none,
- 2, 213, :_reduce_none,
- 4, 213, :_reduce_243,
- 2, 213, :_reduce_244,
- 3, 218, :_reduce_245,
- 0, 219, :_reduce_246,
- 1, 219, :_reduce_none,
- 0, 168, :_reduce_248,
- 1, 168, :_reduce_none,
- 2, 168, :_reduce_none,
- 4, 168, :_reduce_251,
- 2, 168, :_reduce_252,
- 1, 189, :_reduce_253,
- 2, 189, :_reduce_254,
- 2, 189, :_reduce_255,
- 4, 189, :_reduce_256,
- 1, 189, :_reduce_257,
- 0, 222, :_reduce_258,
- 2, 183, :_reduce_259,
- 2, 221, :_reduce_260,
- 2, 220, :_reduce_261,
- 0, 220, :_reduce_262,
- 1, 215, :_reduce_263,
- 2, 215, :_reduce_264,
- 3, 215, :_reduce_265,
- 4, 215, :_reduce_266,
- 1, 173, :_reduce_267,
- 1, 173, :_reduce_none,
- 3, 172, :_reduce_269,
- 4, 172, :_reduce_270,
- 2, 172, :_reduce_271,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_none,
- 1, 209, :_reduce_282,
- 0, 245, :_reduce_283,
- 4, 209, :_reduce_284,
- 0, 246, :_reduce_285,
- 0, 247, :_reduce_286,
- 6, 209, :_reduce_287,
- 0, 248, :_reduce_288,
- 4, 209, :_reduce_289,
- 3, 209, :_reduce_290,
- 3, 209, :_reduce_291,
- 2, 209, :_reduce_292,
- 3, 209, :_reduce_293,
- 3, 209, :_reduce_294,
- 1, 209, :_reduce_295,
- 4, 209, :_reduce_296,
- 3, 209, :_reduce_297,
- 1, 209, :_reduce_298,
- 5, 209, :_reduce_299,
- 4, 209, :_reduce_300,
- 3, 209, :_reduce_301,
- 2, 209, :_reduce_302,
- 1, 209, :_reduce_none,
- 2, 209, :_reduce_304,
- 2, 209, :_reduce_305,
- 6, 209, :_reduce_306,
- 6, 209, :_reduce_307,
- 0, 249, :_reduce_308,
- 0, 250, :_reduce_309,
- 7, 209, :_reduce_310,
- 0, 251, :_reduce_311,
- 0, 252, :_reduce_312,
- 7, 209, :_reduce_313,
- 5, 209, :_reduce_314,
- 4, 209, :_reduce_315,
- 0, 253, :_reduce_316,
- 0, 254, :_reduce_317,
- 9, 209, :_reduce_318,
- 0, 255, :_reduce_319,
- 6, 209, :_reduce_320,
- 0, 256, :_reduce_321,
- 7, 209, :_reduce_322,
- 0, 257, :_reduce_323,
- 5, 209, :_reduce_324,
- 0, 258, :_reduce_325,
- 6, 209, :_reduce_326,
- 0, 259, :_reduce_327,
- 0, 260, :_reduce_328,
- 9, 209, :_reduce_329,
- 1, 209, :_reduce_330,
- 1, 209, :_reduce_331,
- 1, 209, :_reduce_332,
- 1, 209, :_reduce_333,
- 1, 167, :_reduce_none,
- 1, 236, :_reduce_none,
- 1, 236, :_reduce_none,
- 2, 236, :_reduce_337,
- 1, 238, :_reduce_none,
- 1, 238, :_reduce_none,
- 1, 237, :_reduce_none,
- 5, 237, :_reduce_341,
- 1, 156, :_reduce_none,
- 2, 156, :_reduce_343,
- 1, 240, :_reduce_none,
- 1, 240, :_reduce_none,
- 1, 261, :_reduce_346,
- 3, 261, :_reduce_347,
- 1, 264, :_reduce_348,
- 3, 264, :_reduce_349,
- 1, 263, :_reduce_none,
- 4, 263, :_reduce_351,
- 6, 263, :_reduce_352,
- 3, 263, :_reduce_353,
- 5, 263, :_reduce_354,
- 2, 263, :_reduce_355,
- 4, 263, :_reduce_356,
- 1, 263, :_reduce_357,
- 3, 263, :_reduce_358,
- 4, 265, :_reduce_359,
- 2, 265, :_reduce_360,
- 2, 265, :_reduce_361,
- 1, 265, :_reduce_362,
- 2, 270, :_reduce_363,
- 0, 270, :_reduce_364,
- 6, 271, :_reduce_365,
- 8, 271, :_reduce_366,
- 4, 271, :_reduce_367,
- 6, 271, :_reduce_368,
- 4, 271, :_reduce_369,
- 2, 271, :_reduce_none,
- 6, 271, :_reduce_371,
- 2, 271, :_reduce_372,
- 4, 271, :_reduce_373,
- 6, 271, :_reduce_374,
- 2, 271, :_reduce_375,
- 4, 271, :_reduce_376,
- 2, 271, :_reduce_377,
- 4, 271, :_reduce_378,
- 1, 271, :_reduce_none,
- 0, 185, :_reduce_380,
- 1, 185, :_reduce_381,
- 3, 275, :_reduce_382,
- 1, 275, :_reduce_383,
- 4, 275, :_reduce_384,
- 1, 276, :_reduce_385,
- 4, 276, :_reduce_386,
- 1, 277, :_reduce_387,
- 3, 277, :_reduce_388,
- 1, 278, :_reduce_389,
- 1, 278, :_reduce_none,
- 0, 282, :_reduce_391,
- 0, 283, :_reduce_392,
- 4, 235, :_reduce_393,
- 4, 280, :_reduce_394,
- 1, 280, :_reduce_395,
- 3, 281, :_reduce_396,
- 3, 281, :_reduce_397,
- 0, 286, :_reduce_398,
- 5, 285, :_reduce_399,
- 2, 180, :_reduce_400,
- 4, 180, :_reduce_401,
- 5, 180, :_reduce_402,
- 5, 180, :_reduce_403,
- 2, 234, :_reduce_404,
- 4, 234, :_reduce_405,
- 4, 234, :_reduce_406,
- 3, 234, :_reduce_407,
- 3, 234, :_reduce_408,
- 3, 234, :_reduce_409,
- 2, 234, :_reduce_410,
- 1, 234, :_reduce_411,
- 4, 234, :_reduce_412,
- 0, 288, :_reduce_413,
- 5, 233, :_reduce_414,
- 0, 289, :_reduce_415,
- 5, 233, :_reduce_416,
- 5, 239, :_reduce_417,
- 1, 290, :_reduce_418,
- 1, 290, :_reduce_none,
- 6, 155, :_reduce_420,
- 0, 155, :_reduce_421,
- 1, 291, :_reduce_422,
- 1, 291, :_reduce_none,
- 1, 291, :_reduce_none,
- 2, 292, :_reduce_425,
- 1, 292, :_reduce_none,
- 2, 157, :_reduce_427,
- 1, 157, :_reduce_none,
- 1, 223, :_reduce_none,
- 1, 223, :_reduce_none,
- 1, 223, :_reduce_none,
- 1, 224, :_reduce_432,
- 1, 294, :_reduce_433,
- 2, 294, :_reduce_434,
- 3, 295, :_reduce_435,
- 1, 295, :_reduce_436,
- 1, 295, :_reduce_437,
- 3, 225, :_reduce_438,
- 4, 226, :_reduce_439,
- 3, 227, :_reduce_440,
- 0, 299, :_reduce_441,
- 3, 299, :_reduce_442,
- 1, 300, :_reduce_443,
- 2, 300, :_reduce_444,
- 3, 229, :_reduce_445,
- 0, 302, :_reduce_446,
- 3, 302, :_reduce_447,
- 3, 228, :_reduce_448,
- 3, 230, :_reduce_449,
- 0, 303, :_reduce_450,
- 3, 303, :_reduce_451,
- 0, 304, :_reduce_452,
- 3, 304, :_reduce_453,
- 0, 296, :_reduce_454,
- 2, 296, :_reduce_455,
- 0, 297, :_reduce_456,
- 2, 297, :_reduce_457,
- 0, 298, :_reduce_458,
- 2, 298, :_reduce_459,
- 1, 301, :_reduce_460,
- 2, 301, :_reduce_461,
- 0, 306, :_reduce_462,
- 4, 301, :_reduce_463,
- 1, 305, :_reduce_464,
- 1, 305, :_reduce_465,
- 1, 305, :_reduce_466,
- 1, 305, :_reduce_none,
- 1, 205, :_reduce_468,
- 3, 206, :_reduce_469,
- 1, 293, :_reduce_470,
- 2, 293, :_reduce_471,
- 1, 208, :_reduce_472,
- 1, 208, :_reduce_473,
- 1, 208, :_reduce_474,
- 1, 208, :_reduce_475,
- 1, 197, :_reduce_476,
- 1, 197, :_reduce_477,
- 1, 197, :_reduce_478,
- 1, 197, :_reduce_479,
- 1, 197, :_reduce_480,
- 1, 198, :_reduce_481,
- 1, 198, :_reduce_482,
- 1, 198, :_reduce_483,
- 1, 198, :_reduce_484,
- 1, 198, :_reduce_485,
- 1, 198, :_reduce_486,
- 1, 198, :_reduce_487,
- 1, 231, :_reduce_488,
- 1, 231, :_reduce_489,
- 1, 166, :_reduce_490,
- 1, 166, :_reduce_491,
- 1, 170, :_reduce_492,
- 1, 170, :_reduce_493,
- 1, 241, :_reduce_494,
- 0, 307, :_reduce_495,
- 4, 241, :_reduce_496,
- 2, 241, :_reduce_497,
- 3, 243, :_reduce_498,
- 0, 309, :_reduce_499,
- 3, 243, :_reduce_500,
- 4, 308, :_reduce_501,
- 2, 308, :_reduce_502,
- 2, 308, :_reduce_503,
- 1, 308, :_reduce_504,
- 2, 311, :_reduce_505,
- 0, 311, :_reduce_506,
- 6, 284, :_reduce_507,
- 8, 284, :_reduce_508,
- 4, 284, :_reduce_509,
- 6, 284, :_reduce_510,
- 4, 284, :_reduce_511,
- 6, 284, :_reduce_512,
- 2, 284, :_reduce_513,
- 4, 284, :_reduce_514,
- 6, 284, :_reduce_515,
- 2, 284, :_reduce_516,
- 4, 284, :_reduce_517,
- 2, 284, :_reduce_518,
- 4, 284, :_reduce_519,
- 1, 284, :_reduce_520,
- 0, 284, :_reduce_521,
- 1, 279, :_reduce_522,
- 1, 279, :_reduce_523,
- 1, 279, :_reduce_524,
- 1, 279, :_reduce_525,
- 1, 262, :_reduce_none,
- 1, 262, :_reduce_527,
- 1, 313, :_reduce_528,
- 1, 314, :_reduce_529,
- 3, 314, :_reduce_530,
- 1, 272, :_reduce_531,
- 3, 272, :_reduce_532,
- 1, 315, :_reduce_533,
- 2, 316, :_reduce_534,
- 1, 316, :_reduce_535,
- 2, 317, :_reduce_536,
- 1, 317, :_reduce_537,
- 1, 266, :_reduce_538,
- 3, 266, :_reduce_539,
- 1, 310, :_reduce_540,
- 3, 310, :_reduce_541,
- 1, 318, :_reduce_none,
- 1, 318, :_reduce_none,
- 2, 267, :_reduce_544,
- 1, 267, :_reduce_545,
- 3, 319, :_reduce_546,
- 3, 320, :_reduce_547,
- 1, 273, :_reduce_548,
- 3, 273, :_reduce_549,
- 1, 312, :_reduce_550,
- 3, 312, :_reduce_551,
- 1, 321, :_reduce_none,
- 1, 321, :_reduce_none,
- 2, 274, :_reduce_554,
- 1, 274, :_reduce_555,
- 1, 322, :_reduce_none,
- 1, 322, :_reduce_none,
- 2, 269, :_reduce_558,
- 2, 268, :_reduce_559,
- 0, 268, :_reduce_560,
- 1, 244, :_reduce_none,
- 3, 244, :_reduce_562,
- 0, 232, :_reduce_563,
- 2, 232, :_reduce_none,
- 1, 217, :_reduce_565,
- 3, 217, :_reduce_566,
- 3, 323, :_reduce_567,
- 2, 323, :_reduce_568,
- 4, 323, :_reduce_569,
- 2, 323, :_reduce_570,
- 1, 188, :_reduce_none,
- 1, 188, :_reduce_none,
- 1, 188, :_reduce_none,
- 1, 182, :_reduce_none,
- 1, 182, :_reduce_none,
- 1, 182, :_reduce_none,
- 1, 182, :_reduce_none,
- 1, 287, :_reduce_none,
- 1, 287, :_reduce_none,
- 1, 287, :_reduce_none,
- 1, 181, :_reduce_none,
- 1, 181, :_reduce_none,
- 0, 149, :_reduce_none,
- 1, 149, :_reduce_none,
- 0, 176, :_reduce_none,
- 1, 176, :_reduce_none,
- 2, 192, :_reduce_587,
- 2, 169, :_reduce_588,
- 0, 216, :_reduce_none,
- 1, 216, :_reduce_none,
- 1, 216, :_reduce_none,
- 1, 242, :_reduce_592,
- 1, 242, :_reduce_none,
- 1, 151, :_reduce_none,
- 2, 151, :_reduce_none,
- 0, 214, :_reduce_596 ]
-
-racc_reduce_n = 597
-
-racc_shift_n = 1024
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :kCLASS => 2,
- :kMODULE => 3,
- :kDEF => 4,
- :kUNDEF => 5,
- :kBEGIN => 6,
- :kRESCUE => 7,
- :kENSURE => 8,
- :kEND => 9,
- :kIF => 10,
- :kUNLESS => 11,
- :kTHEN => 12,
- :kELSIF => 13,
- :kELSE => 14,
- :kCASE => 15,
- :kWHEN => 16,
- :kWHILE => 17,
- :kUNTIL => 18,
- :kFOR => 19,
- :kBREAK => 20,
- :kNEXT => 21,
- :kREDO => 22,
- :kRETRY => 23,
- :kIN => 24,
- :kDO => 25,
- :kDO_COND => 26,
- :kDO_BLOCK => 27,
- :kDO_LAMBDA => 28,
- :kRETURN => 29,
- :kYIELD => 30,
- :kSUPER => 31,
- :kSELF => 32,
- :kNIL => 33,
- :kTRUE => 34,
- :kFALSE => 35,
- :kAND => 36,
- :kOR => 37,
- :kNOT => 38,
- :kIF_MOD => 39,
- :kUNLESS_MOD => 40,
- :kWHILE_MOD => 41,
- :kUNTIL_MOD => 42,
- :kRESCUE_MOD => 43,
- :kALIAS => 44,
- :kDEFINED => 45,
- :klBEGIN => 46,
- :klEND => 47,
- :k__LINE__ => 48,
- :k__FILE__ => 49,
- :k__ENCODING__ => 50,
- :tIDENTIFIER => 51,
- :tFID => 52,
- :tGVAR => 53,
- :tIVAR => 54,
- :tCONSTANT => 55,
- :tLABEL => 56,
- :tCVAR => 57,
- :tNTH_REF => 58,
- :tBACK_REF => 59,
- :tSTRING_CONTENT => 60,
- :tINTEGER => 61,
- :tFLOAT => 62,
- :tREGEXP_END => 63,
- :tUPLUS => 64,
- :tUMINUS => 65,
- :tUMINUS_NUM => 66,
- :tPOW => 67,
- :tCMP => 68,
- :tEQ => 69,
- :tEQQ => 70,
- :tNEQ => 71,
- :tGEQ => 72,
- :tLEQ => 73,
- :tANDOP => 74,
- :tOROP => 75,
- :tMATCH => 76,
- :tNMATCH => 77,
- :tDOT => 78,
- :tDOT2 => 79,
- :tDOT3 => 80,
- :tAREF => 81,
- :tASET => 82,
- :tLSHFT => 83,
- :tRSHFT => 84,
- :tCOLON2 => 85,
- :tCOLON3 => 86,
- :tOP_ASGN => 87,
- :tASSOC => 88,
- :tLPAREN => 89,
- :tLPAREN2 => 90,
- :tRPAREN => 91,
- :tLPAREN_ARG => 92,
- :tLBRACK => 93,
- :tLBRACK2 => 94,
- :tRBRACK => 95,
- :tLBRACE => 96,
- :tLBRACE_ARG => 97,
- :tSTAR => 98,
- :tSTAR2 => 99,
- :tAMPER => 100,
- :tAMPER2 => 101,
- :tTILDE => 102,
- :tPERCENT => 103,
- :tDIVIDE => 104,
- :tDSTAR => 105,
- :tPLUS => 106,
- :tMINUS => 107,
- :tLT => 108,
- :tGT => 109,
- :tPIPE => 110,
- :tBANG => 111,
- :tCARET => 112,
- :tLCURLY => 113,
- :tRCURLY => 114,
- :tBACK_REF2 => 115,
- :tSYMBEG => 116,
- :tSTRING_BEG => 117,
- :tXSTRING_BEG => 118,
- :tREGEXP_BEG => 119,
- :tREGEXP_OPT => 120,
- :tWORDS_BEG => 121,
- :tQWORDS_BEG => 122,
- :tSYMBOLS_BEG => 123,
- :tQSYMBOLS_BEG => 124,
- :tSTRING_DBEG => 125,
- :tSTRING_DVAR => 126,
- :tSTRING_END => 127,
- :tSTRING_DEND => 128,
- :tSTRING => 129,
- :tSYMBOL => 130,
- :tNL => 131,
- :tEH => 132,
- :tCOLON => 133,
- :tCOMMA => 134,
- :tSPACE => 135,
- :tSEMI => 136,
- :tLAMBDA => 137,
- :tLAMBEG => 138,
- :tCHARACTER => 139,
- :tRATIONAL => 140,
- :tIMAGINARY => 141,
- :tLABEL_END => 142,
- :tEQL => 143,
- :tLOWEST => 144 }
-
-racc_nt_base = 145
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "kCLASS",
- "kMODULE",
- "kDEF",
- "kUNDEF",
- "kBEGIN",
- "kRESCUE",
- "kENSURE",
- "kEND",
- "kIF",
- "kUNLESS",
- "kTHEN",
- "kELSIF",
- "kELSE",
- "kCASE",
- "kWHEN",
- "kWHILE",
- "kUNTIL",
- "kFOR",
- "kBREAK",
- "kNEXT",
- "kREDO",
- "kRETRY",
- "kIN",
- "kDO",
- "kDO_COND",
- "kDO_BLOCK",
- "kDO_LAMBDA",
- "kRETURN",
- "kYIELD",
- "kSUPER",
- "kSELF",
- "kNIL",
- "kTRUE",
- "kFALSE",
- "kAND",
- "kOR",
- "kNOT",
- "kIF_MOD",
- "kUNLESS_MOD",
- "kWHILE_MOD",
- "kUNTIL_MOD",
- "kRESCUE_MOD",
- "kALIAS",
- "kDEFINED",
- "klBEGIN",
- "klEND",
- "k__LINE__",
- "k__FILE__",
- "k__ENCODING__",
- "tIDENTIFIER",
- "tFID",
- "tGVAR",
- "tIVAR",
- "tCONSTANT",
- "tLABEL",
- "tCVAR",
- "tNTH_REF",
- "tBACK_REF",
- "tSTRING_CONTENT",
- "tINTEGER",
- "tFLOAT",
- "tREGEXP_END",
- "tUPLUS",
- "tUMINUS",
- "tUMINUS_NUM",
- "tPOW",
- "tCMP",
- "tEQ",
- "tEQQ",
- "tNEQ",
- "tGEQ",
- "tLEQ",
- "tANDOP",
- "tOROP",
- "tMATCH",
- "tNMATCH",
- "tDOT",
- "tDOT2",
- "tDOT3",
- "tAREF",
- "tASET",
- "tLSHFT",
- "tRSHFT",
- "tCOLON2",
- "tCOLON3",
- "tOP_ASGN",
- "tASSOC",
- "tLPAREN",
- "tLPAREN2",
- "tRPAREN",
- "tLPAREN_ARG",
- "tLBRACK",
- "tLBRACK2",
- "tRBRACK",
- "tLBRACE",
- "tLBRACE_ARG",
- "tSTAR",
- "tSTAR2",
- "tAMPER",
- "tAMPER2",
- "tTILDE",
- "tPERCENT",
- "tDIVIDE",
- "tDSTAR",
- "tPLUS",
- "tMINUS",
- "tLT",
- "tGT",
- "tPIPE",
- "tBANG",
- "tCARET",
- "tLCURLY",
- "tRCURLY",
- "tBACK_REF2",
- "tSYMBEG",
- "tSTRING_BEG",
- "tXSTRING_BEG",
- "tREGEXP_BEG",
- "tREGEXP_OPT",
- "tWORDS_BEG",
- "tQWORDS_BEG",
- "tSYMBOLS_BEG",
- "tQSYMBOLS_BEG",
- "tSTRING_DBEG",
- "tSTRING_DVAR",
- "tSTRING_END",
- "tSTRING_DEND",
- "tSTRING",
- "tSYMBOL",
- "tNL",
- "tEH",
- "tCOLON",
- "tCOMMA",
- "tSPACE",
- "tSEMI",
- "tLAMBDA",
- "tLAMBEG",
- "tCHARACTER",
- "tRATIONAL",
- "tIMAGINARY",
- "tLABEL_END",
- "tEQL",
- "tLOWEST",
- "$start",
- "program",
- "top_compstmt",
- "top_stmts",
- "opt_terms",
- "top_stmt",
- "terms",
- "stmt",
- "bodystmt",
- "compstmt",
- "opt_rescue",
- "opt_else",
- "opt_ensure",
- "stmts",
- "stmt_or_begin",
- "fitem",
- "undef_list",
- "expr_value",
- "command_asgn",
- "mlhs",
- "command_call",
- "var_lhs",
- "primary_value",
- "opt_call_args",
- "rbracket",
- "backref",
- "lhs",
- "mrhs",
- "mrhs_arg",
- "expr",
- "@1",
- "opt_nl",
- "arg",
- "command",
- "block_command",
- "block_call",
- "dot_or_colon",
- "operation2",
- "command_args",
- "cmd_brace_block",
- "opt_block_param",
- "fcall",
- "@2",
- "operation",
- "call_args",
- "mlhs_basic",
- "mlhs_inner",
- "rparen",
- "mlhs_head",
- "mlhs_item",
- "mlhs_node",
- "mlhs_post",
- "user_variable",
- "keyword_variable",
- "cname",
- "cpath",
- "fname",
- "op",
- "reswords",
- "fsym",
- "symbol",
- "dsym",
- "@3",
- "simple_numeric",
- "primary",
- "arg_value",
- "@4",
- "@5",
- "aref_args",
- "none",
- "args",
- "trailer",
- "assocs",
- "paren_args",
- "opt_paren_args",
- "opt_block_arg",
- "block_arg",
- "@6",
- "literal",
- "strings",
- "xstring",
- "regexp",
- "words",
- "qwords",
- "symbols",
- "qsymbols",
- "var_ref",
- "assoc_list",
- "brace_block",
- "method_call",
- "lambda",
- "then",
- "if_tail",
- "do",
- "case_body",
- "for_var",
- "superclass",
- "term",
- "f_arglist",
- "singleton",
- "@7",
- "@8",
- "@9",
- "@10",
- "@11",
- "@12",
- "@13",
- "@14",
- "@15",
- "@16",
- "@17",
- "@18",
- "@19",
- "@20",
- "@21",
- "@22",
- "f_marg",
- "f_norm_arg",
- "f_margs",
- "f_marg_list",
- "block_args_tail",
- "f_block_kwarg",
- "f_kwrest",
- "opt_f_block_arg",
- "f_block_arg",
- "opt_block_args_tail",
- "block_param",
- "f_arg",
- "f_block_optarg",
- "f_rest_arg",
- "block_param_def",
- "opt_bv_decl",
- "bv_decls",
- "bvar",
- "f_bad_arg",
- "f_larglist",
- "lambda_body",
- "@23",
- "@24",
- "f_args",
- "do_block",
- "@25",
- "operation3",
- "@26",
- "@27",
- "cases",
- "exc_list",
- "exc_var",
- "numeric",
- "string",
- "string1",
- "string_contents",
- "xstring_contents",
- "regexp_contents",
- "word_list",
- "word",
- "string_content",
- "symbol_list",
- "qword_list",
- "qsym_list",
- "string_dvar",
- "@28",
- "@29",
- "args_tail",
- "@30",
- "f_kwarg",
- "opt_args_tail",
- "f_optarg",
- "f_arg_asgn",
- "f_arg_item",
- "f_label",
- "f_kw",
- "f_block_kw",
- "kwrest_mark",
- "f_opt",
- "f_block_opt",
- "restarg_mark",
- "blkarg_mark",
- "assoc" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-# reduce 1 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 78)
- def _reduce_2(val, _values, result)
- result = @builder.compstmt(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 83)
- def _reduce_3(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 87)
- def _reduce_4(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 91)
- def _reduce_5(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 95)
- def _reduce_6(val, _values, result)
- result = [ val[1] ]
-
- result
- end
-.,.,
-
-# reduce 7 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 101)
- def _reduce_8(val, _values, result)
- result = @builder.preexe(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 106)
- def _reduce_9(val, _values, result)
- rescue_bodies = val[1]
- else_t, else_ = val[2]
- ensure_t, ensure_ = val[3]
-
- if rescue_bodies.empty? && !else_.nil?
- diagnostic :warning, :useless_else, nil, else_t
- end
-
- result = @builder.begin_body(val[0],
- rescue_bodies,
- else_t, else_,
- ensure_t, ensure_)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 122)
- def _reduce_10(val, _values, result)
- result = @builder.compstmt(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 127)
- def _reduce_11(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 131)
- def _reduce_12(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 135)
- def _reduce_13(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 139)
- def _reduce_14(val, _values, result)
- result = [ val[1] ]
-
- result
- end
-.,.,
-
-# reduce 15 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 145)
- def _reduce_16(val, _values, result)
- diagnostic :error, :begin_in_method, nil, val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 150)
- def _reduce_17(val, _values, result)
- @lexer.state = :expr_fname
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 154)
- def _reduce_18(val, _values, result)
- result = @builder.alias(val[0], val[1], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 158)
- def _reduce_19(val, _values, result)
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.gvar(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 164)
- def _reduce_20(val, _values, result)
- result = @builder.alias(val[0],
- @builder.gvar(val[1]),
- @builder.back_ref(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 170)
- def _reduce_21(val, _values, result)
- diagnostic :error, :nth_ref_alias, nil, val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 174)
- def _reduce_22(val, _values, result)
- result = @builder.undef_method(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 178)
- def _reduce_23(val, _values, result)
- result = @builder.condition_mod(val[0], nil,
- val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 183)
- def _reduce_24(val, _values, result)
- result = @builder.condition_mod(nil, val[0],
- val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 188)
- def _reduce_25(val, _values, result)
- result = @builder.loop_mod(:while, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 192)
- def _reduce_26(val, _values, result)
- result = @builder.loop_mod(:until, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 196)
- def _reduce_27(val, _values, result)
- rescue_body = @builder.rescue_body(val[1],
- nil, nil, nil,
- nil, val[2])
-
- result = @builder.begin_body(val[0], [ rescue_body ])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 204)
- def _reduce_28(val, _values, result)
- result = @builder.postexe(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-# reduce 29 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 209)
- def _reduce_30(val, _values, result)
- result = @builder.multi_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 213)
- def _reduce_31(val, _values, result)
- result = @builder.op_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 217)
- def _reduce_32(val, _values, result)
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 224)
- def _reduce_33(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 231)
- def _reduce_34(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 238)
- def _reduce_35(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 245)
- def _reduce_36(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 252)
- def _reduce_37(val, _values, result)
- @builder.op_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 256)
- def _reduce_38(val, _values, result)
- result = @builder.assign(val[0], val[1],
- @builder.array(nil, val[2], nil))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 261)
- def _reduce_39(val, _values, result)
- result = @builder.multi_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-# reduce 40 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 267)
- def _reduce_41(val, _values, result)
- result = @builder.assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 271)
- def _reduce_42(val, _values, result)
- result = @builder.assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-# reduce 43 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 277)
- def _reduce_44(val, _values, result)
- result = @builder.logical_op(:and, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 281)
- def _reduce_45(val, _values, result)
- result = @builder.logical_op(:or, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 285)
- def _reduce_46(val, _values, result)
- result = @builder.not_op(val[0], nil, val[2], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 289)
- def _reduce_47(val, _values, result)
- result = @builder.not_op(val[0], nil, val[1], nil)
-
- result
- end
-.,.,
-
-# reduce 48 omitted
-
-# reduce 49 omitted
-
-# reduce 50 omitted
-
-# reduce 51 omitted
-
-# reduce 52 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 301)
- def _reduce_53(val, _values, result)
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 307)
- def _reduce_54(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 311)
- def _reduce_55(val, _values, result)
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-# reduce 56 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 320)
- def _reduce_57(val, _values, result)
- result = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 325)
- def _reduce_58(val, _values, result)
- method_call = @builder.call_method(nil, nil, val[0],
- nil, val[1], nil)
-
- begin_t, args, body, end_t = val[2]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 334)
- def _reduce_59(val, _values, result)
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 339)
- def _reduce_60(val, _values, result)
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 348)
- def _reduce_61(val, _values, result)
- result = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 353)
- def _reduce_62(val, _values, result)
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 362)
- def _reduce_63(val, _values, result)
- result = @builder.keyword_cmd(:super, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 367)
- def _reduce_64(val, _values, result)
- result = @builder.keyword_cmd(:yield, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 372)
- def _reduce_65(val, _values, result)
- result = @builder.keyword_cmd(:return, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 377)
- def _reduce_66(val, _values, result)
- result = @builder.keyword_cmd(:break, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 382)
- def _reduce_67(val, _values, result)
- result = @builder.keyword_cmd(:next, val[0],
- nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 388)
- def _reduce_68(val, _values, result)
- result = @builder.multi_lhs(nil, val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 392)
- def _reduce_69(val, _values, result)
- result = @builder.begin(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 397)
- def _reduce_70(val, _values, result)
- result = @builder.multi_lhs(nil, val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 401)
- def _reduce_71(val, _values, result)
- result = @builder.multi_lhs(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-# reduce 72 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 407)
- def _reduce_73(val, _values, result)
- result = val[0].
- push(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 412)
- def _reduce_74(val, _values, result)
- result = val[0].
- push(@builder.splat(val[1], val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 417)
- def _reduce_75(val, _values, result)
- result = val[0].
- push(@builder.splat(val[1], val[2])).
- concat(val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 423)
- def _reduce_76(val, _values, result)
- result = val[0].
- push(@builder.splat(val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 428)
- def _reduce_77(val, _values, result)
- result = val[0].
- push(@builder.splat(val[1])).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 434)
- def _reduce_78(val, _values, result)
- result = [ @builder.splat(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 438)
- def _reduce_79(val, _values, result)
- result = [ @builder.splat(val[0], val[1]),
- *val[3] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 443)
- def _reduce_80(val, _values, result)
- result = [ @builder.splat(val[0]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 447)
- def _reduce_81(val, _values, result)
- result = [ @builder.splat(val[0]),
- *val[2] ]
-
- result
- end
-.,.,
-
-# reduce 82 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 454)
- def _reduce_83(val, _values, result)
- result = @builder.begin(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 459)
- def _reduce_84(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 463)
- def _reduce_85(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 468)
- def _reduce_86(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 472)
- def _reduce_87(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 477)
- def _reduce_88(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 481)
- def _reduce_89(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 485)
- def _reduce_90(val, _values, result)
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 489)
- def _reduce_91(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 493)
- def _reduce_92(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 497)
- def _reduce_93(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 501)
- def _reduce_94(val, _values, result)
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 506)
- def _reduce_95(val, _values, result)
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 511)
- def _reduce_96(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 516)
- def _reduce_97(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 520)
- def _reduce_98(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 524)
- def _reduce_99(val, _values, result)
- result = @builder.index_asgn(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 528)
- def _reduce_100(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 532)
- def _reduce_101(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 536)
- def _reduce_102(val, _values, result)
- result = @builder.attr_asgn(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 540)
- def _reduce_103(val, _values, result)
- result = @builder.assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 545)
- def _reduce_104(val, _values, result)
- result = @builder.assignable(
- @builder.const_global(val[0], val[1]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 550)
- def _reduce_105(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 555)
- def _reduce_106(val, _values, result)
- diagnostic :error, :module_name_const, nil, val[0]
-
- result
- end
-.,.,
-
-# reduce 107 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 561)
- def _reduce_108(val, _values, result)
- result = @builder.const_global(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 565)
- def _reduce_109(val, _values, result)
- result = @builder.const(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 569)
- def _reduce_110(val, _values, result)
- result = @builder.const_fetch(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-# reduce 111 omitted
-
-# reduce 112 omitted
-
-# reduce 113 omitted
-
-# reduce 114 omitted
-
-# reduce 115 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 578)
- def _reduce_116(val, _values, result)
- result = @builder.symbol(val[0])
-
- result
- end
-.,.,
-
-# reduce 117 omitted
-
-# reduce 118 omitted
-
-# reduce 119 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 587)
- def _reduce_120(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 591)
- def _reduce_121(val, _values, result)
- @lexer.state = :expr_fname
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 595)
- def _reduce_122(val, _values, result)
- result = val[0] << val[3]
-
- result
- end
-.,.,
-
-# reduce 123 omitted
-
-# reduce 124 omitted
-
-# reduce 125 omitted
-
-# reduce 126 omitted
-
-# reduce 127 omitted
-
-# reduce 128 omitted
-
-# reduce 129 omitted
-
-# reduce 130 omitted
-
-# reduce 131 omitted
-
-# reduce 132 omitted
-
-# reduce 133 omitted
-
-# reduce 134 omitted
-
-# reduce 135 omitted
-
-# reduce 136 omitted
-
-# reduce 137 omitted
-
-# reduce 138 omitted
-
-# reduce 139 omitted
-
-# reduce 140 omitted
-
-# reduce 141 omitted
-
-# reduce 142 omitted
-
-# reduce 143 omitted
-
-# reduce 144 omitted
-
-# reduce 145 omitted
-
-# reduce 146 omitted
-
-# reduce 147 omitted
-
-# reduce 148 omitted
-
-# reduce 149 omitted
-
-# reduce 150 omitted
-
-# reduce 151 omitted
-
-# reduce 152 omitted
-
-# reduce 153 omitted
-
-# reduce 154 omitted
-
-# reduce 155 omitted
-
-# reduce 156 omitted
-
-# reduce 157 omitted
-
-# reduce 158 omitted
-
-# reduce 159 omitted
-
-# reduce 160 omitted
-
-# reduce 161 omitted
-
-# reduce 162 omitted
-
-# reduce 163 omitted
-
-# reduce 164 omitted
-
-# reduce 165 omitted
-
-# reduce 166 omitted
-
-# reduce 167 omitted
-
-# reduce 168 omitted
-
-# reduce 169 omitted
-
-# reduce 170 omitted
-
-# reduce 171 omitted
-
-# reduce 172 omitted
-
-# reduce 173 omitted
-
-# reduce 174 omitted
-
-# reduce 175 omitted
-
-# reduce 176 omitted
-
-# reduce 177 omitted
-
-# reduce 178 omitted
-
-# reduce 179 omitted
-
-# reduce 180 omitted
-
-# reduce 181 omitted
-
-# reduce 182 omitted
-
-# reduce 183 omitted
-
-# reduce 184 omitted
-
-# reduce 185 omitted
-
-# reduce 186 omitted
-
-# reduce 187 omitted
-
-# reduce 188 omitted
-
-# reduce 189 omitted
-
-# reduce 190 omitted
-
-# reduce 191 omitted
-
-# reduce 192 omitted
-
-# reduce 193 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 616)
- def _reduce_194(val, _values, result)
- result = @builder.assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 620)
- def _reduce_195(val, _values, result)
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.assign(val[0], val[1], rescue_)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 630)
- def _reduce_196(val, _values, result)
- result = @builder.op_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 634)
- def _reduce_197(val, _values, result)
- rescue_body = @builder.rescue_body(val[3],
- nil, nil, nil,
- nil, val[4])
-
- rescue_ = @builder.begin_body(val[2], [ rescue_body ])
-
- result = @builder.op_assign(val[0], val[1], rescue_)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 644)
- def _reduce_198(val, _values, result)
- result = @builder.op_assign(
- @builder.index(
- val[0], val[1], val[2], val[3]),
- val[4], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 651)
- def _reduce_199(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 658)
- def _reduce_200(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 665)
- def _reduce_201(val, _values, result)
- result = @builder.op_assign(
- @builder.call_method(
- val[0], val[1], val[2]),
- val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 672)
- def _reduce_202(val, _values, result)
- const = @builder.const_op_assignable(
- @builder.const_fetch(val[0], val[1], val[2]))
- result = @builder.op_assign(const, val[3], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 678)
- def _reduce_203(val, _values, result)
- const = @builder.const_op_assignable(
- @builder.const_global(val[0], val[1]))
- result = @builder.op_assign(const, val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 684)
- def _reduce_204(val, _values, result)
- result = @builder.op_assign(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 688)
- def _reduce_205(val, _values, result)
- result = @builder.range_inclusive(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 692)
- def _reduce_206(val, _values, result)
- result = @builder.range_exclusive(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 696)
- def _reduce_207(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 700)
- def _reduce_208(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 704)
- def _reduce_209(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 708)
- def _reduce_210(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 712)
- def _reduce_211(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 716)
- def _reduce_212(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 720)
- def _reduce_213(val, _values, result)
- result = @builder.unary_op(val[0],
- @builder.binary_op(
- val[1], val[2], val[3]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 726)
- def _reduce_214(val, _values, result)
- result = @builder.unary_op(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 730)
- def _reduce_215(val, _values, result)
- result = @builder.unary_op(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 734)
- def _reduce_216(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 738)
- def _reduce_217(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 742)
- def _reduce_218(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 746)
- def _reduce_219(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 750)
- def _reduce_220(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 754)
- def _reduce_221(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 758)
- def _reduce_222(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 762)
- def _reduce_223(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 766)
- def _reduce_224(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 770)
- def _reduce_225(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 774)
- def _reduce_226(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 778)
- def _reduce_227(val, _values, result)
- result = @builder.match_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 782)
- def _reduce_228(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 786)
- def _reduce_229(val, _values, result)
- result = @builder.not_op(val[0], nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 790)
- def _reduce_230(val, _values, result)
- result = @builder.unary_op(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 794)
- def _reduce_231(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 798)
- def _reduce_232(val, _values, result)
- result = @builder.binary_op(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 802)
- def _reduce_233(val, _values, result)
- result = @builder.logical_op(:and, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 806)
- def _reduce_234(val, _values, result)
- result = @builder.logical_op(:or, val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 810)
- def _reduce_235(val, _values, result)
- result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 820)
- def _reduce_236(val, _values, result)
- @lexer.push_cond
- @lexer.cond.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 825)
- def _reduce_237(val, _values, result)
- @lexer.pop_cond
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 829)
- def _reduce_238(val, _values, result)
- result = @builder.ternary(val[0], val[1],
- val[3], val[5], val[7])
-
- result
- end
-.,.,
-
-# reduce 239 omitted
-
-# reduce 240 omitted
-
-# reduce 241 omitted
-
-# reduce 242 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 840)
- def _reduce_243(val, _values, result)
- result = val[0] << @builder.associate(nil, val[2], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 844)
- def _reduce_244(val, _values, result)
- result = [ @builder.associate(nil, val[0], nil) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 849)
- def _reduce_245(val, _values, result)
- result = val
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 854)
- def _reduce_246(val, _values, result)
- result = [ nil, [], nil ]
-
- result
- end
-.,.,
-
-# reduce 247 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 860)
- def _reduce_248(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-# reduce 249 omitted
-
-# reduce 250 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 866)
- def _reduce_251(val, _values, result)
- result = val[0] << @builder.associate(nil, val[2], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 870)
- def _reduce_252(val, _values, result)
- result = [ @builder.associate(nil, val[0], nil) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 875)
- def _reduce_253(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 879)
- def _reduce_254(val, _values, result)
- result = val[0].concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 883)
- def _reduce_255(val, _values, result)
- result = [ @builder.associate(nil, val[0], nil) ]
- result.concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 888)
- def _reduce_256(val, _values, result)
- assocs = @builder.associate(nil, val[2], nil)
- result = val[0] << assocs
- result.concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 894)
- def _reduce_257(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 898)
- def _reduce_258(val, _values, result)
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 903)
- def _reduce_259(val, _values, result)
- @lexer.cmdarg = val[0]
-
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 910)
- def _reduce_260(val, _values, result)
- result = @builder.block_pass(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 915)
- def _reduce_261(val, _values, result)
- result = [ val[1] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 919)
- def _reduce_262(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 924)
- def _reduce_263(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 928)
- def _reduce_264(val, _values, result)
- result = [ @builder.splat(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 932)
- def _reduce_265(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 936)
- def _reduce_266(val, _values, result)
- result = val[0] << @builder.splat(val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 941)
- def _reduce_267(val, _values, result)
- result = @builder.array(nil, val[0], nil)
-
- result
- end
-.,.,
-
-# reduce 268 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 947)
- def _reduce_269(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 951)
- def _reduce_270(val, _values, result)
- result = val[0] << @builder.splat(val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 955)
- def _reduce_271(val, _values, result)
- result = [ @builder.splat(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-# reduce 272 omitted
-
-# reduce 273 omitted
-
-# reduce 274 omitted
-
-# reduce 275 omitted
-
-# reduce 276 omitted
-
-# reduce 277 omitted
-
-# reduce 278 omitted
-
-# reduce 279 omitted
-
-# reduce 280 omitted
-
-# reduce 281 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 970)
- def _reduce_282(val, _values, result)
- result = @builder.call_method(nil, nil, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 974)
- def _reduce_283(val, _values, result)
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 979)
- def _reduce_284(val, _values, result)
- @lexer.cmdarg = val[1]
-
- result = @builder.begin_keyword(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 985)
- def _reduce_285(val, _values, result)
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 990)
- def _reduce_286(val, _values, result)
- @lexer.state = :expr_endarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 994)
- def _reduce_287(val, _values, result)
- @lexer.cmdarg = val[1]
-
- result = @builder.begin(val[0], val[2], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1000)
- def _reduce_288(val, _values, result)
- @lexer.state = :expr_endarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1004)
- def _reduce_289(val, _values, result)
- result = @builder.begin(val[0], nil, val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1008)
- def _reduce_290(val, _values, result)
- result = @builder.begin(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1012)
- def _reduce_291(val, _values, result)
- result = @builder.const_fetch(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1016)
- def _reduce_292(val, _values, result)
- result = @builder.const_global(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1020)
- def _reduce_293(val, _values, result)
- result = @builder.array(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1024)
- def _reduce_294(val, _values, result)
- result = @builder.associate(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1028)
- def _reduce_295(val, _values, result)
- result = @builder.keyword_cmd(:return, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1032)
- def _reduce_296(val, _values, result)
- result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1036)
- def _reduce_297(val, _values, result)
- result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1040)
- def _reduce_298(val, _values, result)
- result = @builder.keyword_cmd(:yield, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1044)
- def _reduce_299(val, _values, result)
- result = @builder.keyword_cmd(:defined?, val[0],
- val[2], [ val[3] ], val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1049)
- def _reduce_300(val, _values, result)
- result = @builder.not_op(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1053)
- def _reduce_301(val, _values, result)
- result = @builder.not_op(val[0], val[1], nil, val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1057)
- def _reduce_302(val, _values, result)
- method_call = @builder.call_method(nil, nil, val[0])
-
- begin_t, args, body, end_t = val[1]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-# reduce 303 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1066)
- def _reduce_304(val, _values, result)
- begin_t, args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1072)
- def _reduce_305(val, _values, result)
- lambda_call = @builder.call_lambda(val[0])
-
- args, (begin_t, body, end_t) = val[1]
- result = @builder.block(lambda_call,
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1080)
- def _reduce_306(val, _values, result)
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1087)
- def _reduce_307(val, _values, result)
- else_t, else_ = val[4]
- result = @builder.condition(val[0], val[1], val[2],
- else_, else_t,
- val[3], val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1094)
- def _reduce_308(val, _values, result)
- @lexer.cond.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1098)
- def _reduce_309(val, _values, result)
- @lexer.cond.pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1102)
- def _reduce_310(val, _values, result)
- result = @builder.loop(:while, val[0], val[2], val[3],
- val[5], val[6])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1107)
- def _reduce_311(val, _values, result)
- @lexer.cond.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1111)
- def _reduce_312(val, _values, result)
- @lexer.cond.pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1115)
- def _reduce_313(val, _values, result)
- result = @builder.loop(:until, val[0], val[2], val[3],
- val[5], val[6])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1120)
- def _reduce_314(val, _values, result)
- *when_bodies, (else_t, else_body) = *val[3]
-
- result = @builder.case(val[0], val[1],
- when_bodies, else_t, else_body,
- val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1128)
- def _reduce_315(val, _values, result)
- *when_bodies, (else_t, else_body) = *val[2]
-
- result = @builder.case(val[0], nil,
- when_bodies, else_t, else_body,
- val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1136)
- def _reduce_316(val, _values, result)
- @lexer.cond.push(true)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1140)
- def _reduce_317(val, _values, result)
- @lexer.cond.pop
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1144)
- def _reduce_318(val, _values, result)
- result = @builder.for(val[0], val[1],
- val[2], val[4],
- val[5], val[7], val[8])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1150)
- def _reduce_319(val, _values, result)
- @static_env.extend_static
- @lexer.push_cmdarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1155)
- def _reduce_320(val, _values, result)
- if in_def?
- diagnostic :error, :class_in_def, nil, val[0]
- end
-
- lt_t, superclass = val[2]
- result = @builder.def_class(val[0], val[1],
- lt_t, superclass,
- val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1169)
- def _reduce_321(val, _values, result)
- result = @def_level
- @def_level = 0
-
- @static_env.extend_static
- @lexer.push_cmdarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1177)
- def _reduce_322(val, _values, result)
- result = @builder.def_sclass(val[0], val[1], val[2],
- val[5], val[6])
-
- @lexer.pop_cmdarg
- @static_env.unextend
-
- @def_level = val[4]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1187)
- def _reduce_323(val, _values, result)
- @static_env.extend_static
- @lexer.push_cmdarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1192)
- def _reduce_324(val, _values, result)
- if in_def?
- diagnostic :error, :module_in_def, nil, val[0]
- end
-
- result = @builder.def_module(val[0], val[1],
- val[3], val[4])
-
- @lexer.pop_cmdarg
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1204)
- def _reduce_325(val, _values, result)
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1210)
- def _reduce_326(val, _values, result)
- result = @builder.def_method(val[0], val[1],
- val[3], val[4], val[5])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1219)
- def _reduce_327(val, _values, result)
- @lexer.state = :expr_fname
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1223)
- def _reduce_328(val, _values, result)
- @def_level += 1
- @static_env.extend_static
- @lexer.push_cmdarg
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1229)
- def _reduce_329(val, _values, result)
- result = @builder.def_singleton(val[0], val[1], val[2],
- val[4], val[6], val[7], val[8])
-
- @lexer.pop_cmdarg
- @static_env.unextend
- @def_level -= 1
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1238)
- def _reduce_330(val, _values, result)
- result = @builder.keyword_cmd(:break, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1242)
- def _reduce_331(val, _values, result)
- result = @builder.keyword_cmd(:next, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1246)
- def _reduce_332(val, _values, result)
- result = @builder.keyword_cmd(:redo, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1250)
- def _reduce_333(val, _values, result)
- result = @builder.keyword_cmd(:retry, val[0])
-
- result
- end
-.,.,
-
-# reduce 334 omitted
-
-# reduce 335 omitted
-
-# reduce 336 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1259)
- def _reduce_337(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-# reduce 338 omitted
-
-# reduce 339 omitted
-
-# reduce 340 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1268)
- def _reduce_341(val, _values, result)
- else_t, else_ = val[4]
- result = [ val[0],
- @builder.condition(val[0], val[1], val[2],
- val[3], else_t,
- else_, nil),
- ]
-
- result
- end
-.,.,
-
-# reduce 342 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1279)
- def _reduce_343(val, _values, result)
- result = val
-
- result
- end
-.,.,
-
-# reduce 344 omitted
-
-# reduce 345 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1287)
- def _reduce_346(val, _values, result)
- result = @builder.arg(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1291)
- def _reduce_347(val, _values, result)
- result = @builder.multi_lhs(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1296)
- def _reduce_348(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1300)
- def _reduce_349(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-# reduce 350 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1306)
- def _reduce_351(val, _values, result)
- result = val[0].
- push(@builder.restarg(val[2], val[3]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1311)
- def _reduce_352(val, _values, result)
- result = val[0].
- push(@builder.restarg(val[2], val[3])).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1317)
- def _reduce_353(val, _values, result)
- result = val[0].
- push(@builder.restarg(val[2]))
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1322)
- def _reduce_354(val, _values, result)
- result = val[0].
- push(@builder.restarg(val[2])).
- concat(val[4])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1328)
- def _reduce_355(val, _values, result)
- result = [ @builder.restarg(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1332)
- def _reduce_356(val, _values, result)
- result = [ @builder.restarg(val[0], val[1]),
- *val[3] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1337)
- def _reduce_357(val, _values, result)
- result = [ @builder.restarg(val[0]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1341)
- def _reduce_358(val, _values, result)
- result = [ @builder.restarg(val[0]),
- *val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1347)
- def _reduce_359(val, _values, result)
- result = val[0].concat(val[2]).concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1351)
- def _reduce_360(val, _values, result)
- result = val[0].concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1355)
- def _reduce_361(val, _values, result)
- result = val[0].concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1359)
- def _reduce_362(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1365)
- def _reduce_363(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1369)
- def _reduce_364(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1374)
- def _reduce_365(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1381)
- def _reduce_366(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1389)
- def _reduce_367(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1395)
- def _reduce_368(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1402)
- def _reduce_369(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-# reduce 370 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1409)
- def _reduce_371(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1416)
- def _reduce_372(val, _values, result)
- result = val[0].concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1420)
- def _reduce_373(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1426)
- def _reduce_374(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1433)
- def _reduce_375(val, _values, result)
- result = val[0].
- concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1438)
- def _reduce_376(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1444)
- def _reduce_377(val, _values, result)
- result = val[0].
- concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1449)
- def _reduce_378(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-# reduce 379 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1457)
- def _reduce_380(val, _values, result)
- result = @builder.args(nil, [], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1461)
- def _reduce_381(val, _values, result)
- @lexer.state = :expr_value
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1466)
- def _reduce_382(val, _values, result)
- result = @builder.args(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1470)
- def _reduce_383(val, _values, result)
- result = @builder.args(val[0], [], val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1474)
- def _reduce_384(val, _values, result)
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1479)
- def _reduce_385(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1483)
- def _reduce_386(val, _values, result)
- result = val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1488)
- def _reduce_387(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1492)
- def _reduce_388(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1497)
- def _reduce_389(val, _values, result)
- result = @builder.shadowarg(val[0])
-
- result
- end
-.,.,
-
-# reduce 390 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1502)
- def _reduce_391(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1506)
- def _reduce_392(val, _values, result)
- result = @lexer.cmdarg.dup
- @lexer.cmdarg.clear
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1511)
- def _reduce_393(val, _values, result)
- @lexer.cmdarg = val[2]
- @lexer.cmdarg.lexpop
-
- result = [ val[1], val[3] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1521)
- def _reduce_394(val, _values, result)
- result = @builder.args(val[0], val[1].concat(val[2]), val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1525)
- def _reduce_395(val, _values, result)
- result = @builder.args(nil, val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1530)
- def _reduce_396(val, _values, result)
- result = [ val[0], val[1], val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1534)
- def _reduce_397(val, _values, result)
- result = [ val[0], val[1], val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1539)
- def _reduce_398(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1543)
- def _reduce_399(val, _values, result)
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1550)
- def _reduce_400(val, _values, result)
- begin_t, block_args, body, end_t = val[1]
- result = @builder.block(val[0],
- begin_t, block_args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1556)
- def _reduce_401(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1562)
- def _reduce_402(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- method_call = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1572)
- def _reduce_403(val, _values, result)
- method_call = @builder.call_method(val[0], val[1], val[2],
- nil, val[3], nil)
-
- begin_t, args, body, end_t = val[4]
- result = @builder.block(method_call,
- begin_t, args, body, end_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1582)
- def _reduce_404(val, _values, result)
- lparen_t, args, rparen_t = val[1]
- result = @builder.call_method(nil, nil, val[0],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1588)
- def _reduce_405(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1594)
- def _reduce_406(val, _values, result)
- lparen_t, args, rparen_t = val[3]
- result = @builder.call_method(val[0], val[1], val[2],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1600)
- def _reduce_407(val, _values, result)
- result = @builder.call_method(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1604)
- def _reduce_408(val, _values, result)
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1610)
- def _reduce_409(val, _values, result)
- lparen_t, args, rparen_t = val[2]
- result = @builder.call_method(val[0], val[1], nil,
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1616)
- def _reduce_410(val, _values, result)
- lparen_t, args, rparen_t = val[1]
- result = @builder.keyword_cmd(:super, val[0],
- lparen_t, args, rparen_t)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1622)
- def _reduce_411(val, _values, result)
- result = @builder.keyword_cmd(:zsuper, val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1626)
- def _reduce_412(val, _values, result)
- result = @builder.index(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1631)
- def _reduce_413(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1635)
- def _reduce_414(val, _values, result)
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1641)
- def _reduce_415(val, _values, result)
- @static_env.extend_dynamic
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1645)
- def _reduce_416(val, _values, result)
- result = [ val[0], val[2], val[3], val[4] ]
-
- @static_env.unextend
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1652)
- def _reduce_417(val, _values, result)
- result = [ @builder.when(val[0], val[1], val[2], val[3]),
- *val[4] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1658)
- def _reduce_418(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-# reduce 419 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1664)
- def _reduce_420(val, _values, result)
- assoc_t, exc_var = val[2]
-
- if val[1]
- exc_list = @builder.array(nil, val[1], nil)
- end
-
- result = [ @builder.rescue_body(val[0],
- exc_list, assoc_t, exc_var,
- val[3], val[4]),
- *val[5] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1677)
- def _reduce_421(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1682)
- def _reduce_422(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-# reduce 423 omitted
-
-# reduce 424 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1689)
- def _reduce_425(val, _values, result)
- result = [ val[0], val[1] ]
-
- result
- end
-.,.,
-
-# reduce 426 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1695)
- def _reduce_427(val, _values, result)
- result = [ val[0], val[1] ]
-
- result
- end
-.,.,
-
-# reduce 428 omitted
-
-# reduce 429 omitted
-
-# reduce 430 omitted
-
-# reduce 431 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1705)
- def _reduce_432(val, _values, result)
- result = @builder.string_compose(nil, val[0], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1710)
- def _reduce_433(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1714)
- def _reduce_434(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1719)
- def _reduce_435(val, _values, result)
- result = @builder.string_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1723)
- def _reduce_436(val, _values, result)
- result = @builder.string(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1727)
- def _reduce_437(val, _values, result)
- result = @builder.character(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1732)
- def _reduce_438(val, _values, result)
- result = @builder.xstring_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1737)
- def _reduce_439(val, _values, result)
- opts = @builder.regexp_options(val[3])
- result = @builder.regexp_compose(val[0], val[1], val[2], opts)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1743)
- def _reduce_440(val, _values, result)
- result = @builder.words_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1748)
- def _reduce_441(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1752)
- def _reduce_442(val, _values, result)
- result = val[0] << @builder.word(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1757)
- def _reduce_443(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1761)
- def _reduce_444(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1766)
- def _reduce_445(val, _values, result)
- result = @builder.symbols_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1771)
- def _reduce_446(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1775)
- def _reduce_447(val, _values, result)
- result = val[0] << @builder.word(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1780)
- def _reduce_448(val, _values, result)
- result = @builder.words_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1785)
- def _reduce_449(val, _values, result)
- result = @builder.symbols_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1790)
- def _reduce_450(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1794)
- def _reduce_451(val, _values, result)
- result = val[0] << @builder.string_internal(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1799)
- def _reduce_452(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1803)
- def _reduce_453(val, _values, result)
- result = val[0] << @builder.symbol_internal(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1808)
- def _reduce_454(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1812)
- def _reduce_455(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1817)
- def _reduce_456(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1821)
- def _reduce_457(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1826)
- def _reduce_458(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1830)
- def _reduce_459(val, _values, result)
- result = val[0] << val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1835)
- def _reduce_460(val, _values, result)
- result = @builder.string_internal(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1839)
- def _reduce_461(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1843)
- def _reduce_462(val, _values, result)
- @lexer.cond.push(false)
- @lexer.cmdarg.push(false)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1848)
- def _reduce_463(val, _values, result)
- @lexer.cond.lexpop
- @lexer.cmdarg.lexpop
-
- result = @builder.begin(val[0], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1856)
- def _reduce_464(val, _values, result)
- result = @builder.gvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1860)
- def _reduce_465(val, _values, result)
- result = @builder.ivar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1864)
- def _reduce_466(val, _values, result)
- result = @builder.cvar(val[0])
-
- result
- end
-.,.,
-
-# reduce 467 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 1871)
- def _reduce_468(val, _values, result)
- result = @builder.symbol(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1876)
- def _reduce_469(val, _values, result)
- result = @builder.symbol_compose(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1881)
- def _reduce_470(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1885)
- def _reduce_471(val, _values, result)
- result = @builder.negate(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1890)
- def _reduce_472(val, _values, result)
- result = @builder.integer(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1894)
- def _reduce_473(val, _values, result)
- result = @builder.float(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1898)
- def _reduce_474(val, _values, result)
- result = @builder.rational(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1902)
- def _reduce_475(val, _values, result)
- result = @builder.complex(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1907)
- def _reduce_476(val, _values, result)
- result = @builder.ident(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1911)
- def _reduce_477(val, _values, result)
- result = @builder.ivar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1915)
- def _reduce_478(val, _values, result)
- result = @builder.gvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1919)
- def _reduce_479(val, _values, result)
- result = @builder.const(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1923)
- def _reduce_480(val, _values, result)
- result = @builder.cvar(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1928)
- def _reduce_481(val, _values, result)
- result = @builder.nil(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1932)
- def _reduce_482(val, _values, result)
- result = @builder.self(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1936)
- def _reduce_483(val, _values, result)
- result = @builder.true(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1940)
- def _reduce_484(val, _values, result)
- result = @builder.false(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1944)
- def _reduce_485(val, _values, result)
- result = @builder.__FILE__(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1948)
- def _reduce_486(val, _values, result)
- result = @builder.__LINE__(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1952)
- def _reduce_487(val, _values, result)
- result = @builder.__ENCODING__(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1957)
- def _reduce_488(val, _values, result)
- result = @builder.accessible(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1961)
- def _reduce_489(val, _values, result)
- result = @builder.accessible(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1966)
- def _reduce_490(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1970)
- def _reduce_491(val, _values, result)
- result = @builder.assignable(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1975)
- def _reduce_492(val, _values, result)
- result = @builder.nth_ref(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1979)
- def _reduce_493(val, _values, result)
- result = @builder.back_ref(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1984)
- def _reduce_494(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1988)
- def _reduce_495(val, _values, result)
- @lexer.state = :expr_value
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1992)
- def _reduce_496(val, _values, result)
- result = [ val[0], val[2] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 1996)
- def _reduce_497(val, _values, result)
- yyerrok
- result = nil
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2002)
- def _reduce_498(val, _values, result)
- result = @builder.args(val[0], val[1], val[2])
-
- @lexer.state = :expr_value
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2007)
- def _reduce_499(val, _values, result)
- result = @lexer.in_kwarg
- @lexer.in_kwarg = true
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2012)
- def _reduce_500(val, _values, result)
- @lexer.in_kwarg = val[0]
- result = @builder.args(nil, val[1], nil)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2018)
- def _reduce_501(val, _values, result)
- result = val[0].concat(val[2]).concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2022)
- def _reduce_502(val, _values, result)
- result = val[0].concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2026)
- def _reduce_503(val, _values, result)
- result = val[0].concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2030)
- def _reduce_504(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2035)
- def _reduce_505(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2039)
- def _reduce_506(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2044)
- def _reduce_507(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2051)
- def _reduce_508(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[6]).
- concat(val[7])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2059)
- def _reduce_509(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2065)
- def _reduce_510(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2072)
- def _reduce_511(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2078)
- def _reduce_512(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2085)
- def _reduce_513(val, _values, result)
- result = val[0].
- concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2090)
- def _reduce_514(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2096)
- def _reduce_515(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[4]).
- concat(val[5])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2103)
- def _reduce_516(val, _values, result)
- result = val[0].
- concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2108)
- def _reduce_517(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2114)
- def _reduce_518(val, _values, result)
- result = val[0].
- concat(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2119)
- def _reduce_519(val, _values, result)
- result = val[0].
- concat(val[2]).
- concat(val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2125)
- def _reduce_520(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2129)
- def _reduce_521(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2134)
- def _reduce_522(val, _values, result)
- diagnostic :error, :argument_const, nil, val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2138)
- def _reduce_523(val, _values, result)
- diagnostic :error, :argument_ivar, nil, val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2142)
- def _reduce_524(val, _values, result)
- diagnostic :error, :argument_gvar, nil, val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2146)
- def _reduce_525(val, _values, result)
- diagnostic :error, :argument_cvar, nil, val[0]
-
- result
- end
-.,.,
-
-# reduce 526 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2152)
- def _reduce_527(val, _values, result)
- @static_env.declare val[0][0]
-
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2159)
- def _reduce_528(val, _values, result)
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2164)
- def _reduce_529(val, _values, result)
- result = @builder.arg(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2168)
- def _reduce_530(val, _values, result)
- result = @builder.multi_lhs(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2173)
- def _reduce_531(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2177)
- def _reduce_532(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2182)
- def _reduce_533(val, _values, result)
- check_kwarg_name(val[0])
-
- @static_env.declare val[0][0]
-
- result = val[0]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2191)
- def _reduce_534(val, _values, result)
- result = @builder.kwoptarg(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2195)
- def _reduce_535(val, _values, result)
- result = @builder.kwarg(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2200)
- def _reduce_536(val, _values, result)
- result = @builder.kwoptarg(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2204)
- def _reduce_537(val, _values, result)
- result = @builder.kwarg(val[0])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2209)
- def _reduce_538(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2213)
- def _reduce_539(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2218)
- def _reduce_540(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2222)
- def _reduce_541(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-# reduce 542 omitted
-
-# reduce 543 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2229)
- def _reduce_544(val, _values, result)
- @static_env.declare val[1][0]
-
- result = [ @builder.kwrestarg(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2235)
- def _reduce_545(val, _values, result)
- result = [ @builder.kwrestarg(val[0]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2240)
- def _reduce_546(val, _values, result)
- result = @builder.optarg(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2245)
- def _reduce_547(val, _values, result)
- result = @builder.optarg(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2250)
- def _reduce_548(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2254)
- def _reduce_549(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2259)
- def _reduce_550(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2263)
- def _reduce_551(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-# reduce 552 omitted
-
-# reduce 553 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2270)
- def _reduce_554(val, _values, result)
- @static_env.declare val[1][0]
-
- result = [ @builder.restarg(val[0], val[1]) ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2276)
- def _reduce_555(val, _values, result)
- result = [ @builder.restarg(val[0]) ]
-
- result
- end
-.,.,
-
-# reduce 556 omitted
-
-# reduce 557 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2283)
- def _reduce_558(val, _values, result)
- @static_env.declare val[1][0]
-
- result = @builder.blockarg(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2290)
- def _reduce_559(val, _values, result)
- result = [ val[1] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2294)
- def _reduce_560(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-# reduce 561 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2300)
- def _reduce_562(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2305)
- def _reduce_563(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-# reduce 564 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2311)
- def _reduce_565(val, _values, result)
- result = [ val[0] ]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2315)
- def _reduce_566(val, _values, result)
- result = val[0] << val[2]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2320)
- def _reduce_567(val, _values, result)
- result = @builder.pair(val[0], val[1], val[2])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2324)
- def _reduce_568(val, _values, result)
- result = @builder.pair_keyword(val[0], val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2328)
- def _reduce_569(val, _values, result)
- result = @builder.pair_quoted(val[0], val[1], val[2], val[3])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2332)
- def _reduce_570(val, _values, result)
- result = @builder.kwsplat(val[0], val[1])
-
- result
- end
-.,.,
-
-# reduce 571 omitted
-
-# reduce 572 omitted
-
-# reduce 573 omitted
-
-# reduce 574 omitted
-
-# reduce 575 omitted
-
-# reduce 576 omitted
-
-# reduce 577 omitted
-
-# reduce 578 omitted
-
-# reduce 579 omitted
-
-# reduce 580 omitted
-
-# reduce 581 omitted
-
-# reduce 582 omitted
-
-# reduce 583 omitted
-
-# reduce 584 omitted
-
-# reduce 585 omitted
-
-# reduce 586 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2343)
- def _reduce_587(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'ruby22.y', 2347)
- def _reduce_588(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-# reduce 589 omitted
-
-# reduce 590 omitted
-
-# reduce 591 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2353)
- def _reduce_592(val, _values, result)
- yyerrok
-
- result
- end
-.,.,
-
-# reduce 593 omitted
-
-# reduce 594 omitted
-
-# reduce 595 omitted
-
-module_eval(<<'.,.,', 'ruby22.y', 2362)
- def _reduce_596(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Ruby22
-end # module Parser
diff --git a/test/racc/regress/tp_plus b/test/racc/regress/tp_plus
deleted file mode 100644
index 34b6284db7..0000000000
--- a/test/racc/regress/tp_plus
+++ /dev/null
@@ -1,1933 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-module TPPlus
- class Parser < Racc::Parser
-
-module_eval(<<'...end tp_plus.y/module_eval...', 'tp_plus.y', 592)
-
- include TPPlus::Nodes
-
- attr_reader :interpreter
- def initialize(scanner, interpreter = TPPlus::Interpreter.new)
- @scanner = scanner
- @interpreter = interpreter
- super()
- end
-
- def next_token
- t = @scanner.next_token
- @interpreter.line_count += 1 if t && t[0] == :NEWLINE
-
- #puts t.inspect
- t
- end
-
- def parse
- #@yydebug =true
-
- do_parse
- @interpreter
- end
-
- def on_error(t, val, vstack)
- raise ParseError, sprintf("Parse error on line #{@scanner.tok_line} column #{@scanner.tok_col}: %s (%s)",
- val.inspect, token_to_str(t) || '?')
- end
-
- class ParseError < StandardError ; end
-...end tp_plus.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 62, 62, 62, 62, 101, 122, 62, 41, 38, 130,
- 275, 265, 72, 41, 72, 98, 113, 72, 53, 114,
- 41, 67, 67, 67, 67, 234, 38, 26, 152, 151,
- 101, 36, 64, 159, 81, 82, 72, 308, 159, 81,
- 82, 72, 122, 70, 308, 60, 74, 60, 42, 308,
- 60, 43, 44, 131, 45, 31, 32, 300, 75, 34,
- 35, 46, 47, 102, 60, 273, 30, 72, 29, 28,
- 25, 63, 76, 37, 27, 24, 62, 41, 38, 37,
- 69, 69, 69, 69, 33, 61, 37, 97, 53, 102,
- 61, 37, 81, 82, 355, 61, 103, 26, 82, 72,
- 60, 36, 159, 81, 82, 72, 208, 221, 209, 371,
- 82, 72, 105, 220, 33, 81, 82, 72, 42, 72,
- 317, 43, 44, 111, 45, 31, 32, 96, 72, 34,
- 35, 46, 47, 96, 60, 223, 30, 224, 29, 28,
- 25, 63, 115, 37, 27, 24, 62, 41, 38, 72,
- 60, 81, 82, 72, 33, 61, 121, 116, 53, 61,
- 122, 88, 94, 96, 321, 117, 118, 26, 317, 352,
- 125, 36, 323, 127, 203, 349, 350, 351, 353, 303,
- 304, 96, 367, 81, 82, 72, 60, 255, 42, 209,
- 101, 43, 44, 122, 45, 31, 32, 185, 94, 34,
- 35, 46, 47, 186, 60, 191, 30, 61, 29, 28,
- 25, 63, 321, 37, 27, 24, 62, 41, 38, 188,
- 323, 122, 203, 122, 33, 61, 82, 72, 53, 336,
- 335, 182, 181, 179, 180, 177, 173, 26, 176, 174,
- 199, 36, 81, 82, 72, 81, 82, 72, 81, 82,
- 72, 81, 82, 81, 82, 72, 200, 201, 42, 203,
- 204, 43, 44, 96, 45, 31, 32, 210, 211, 34,
- 35, 46, 47, 212, 60, 213, 30, 214, 29, 28,
- 25, 63, 215, 37, 27, 24, 216, 178, 217, 175,
- 81, 82, 72, 218, 33, 61, 81, 82, 72, 219,
- 88, 317, 96, 81, 82, 72, 88, 227, 96, 81,
- 82, 72, 227, 88, 96, 96, 81, 82, 72, 88,
- 229, 96, 81, 82, 72, 60, 88, 230, 96, 231,
- 234, 60, 88, 235, 96, 238, 122, 94, 60, 81,
- 82, 72, 122, 94, 60, 321, 61, 81, 82, 72,
- 94, 60, 61, 323, 241, 203, 94, 60, 242, 61,
- 244, 245, 246, 94, 247, 61, 248, 249, 250, 94,
- 251, 252, 61, 81, 82, 72, 253, 254, 61, 81,
- 82, 72, 257, 88, 188, 96, 81, 82, 72, 88,
- 259, 96, 81, 82, 72, 269, 88, 271, 96, 81,
- 82, 72, 88, 276, 96, 122, 281, 282, 60, 88,
- 283, 96, 284, 285, 60, 286, 287, 288, 289, 290,
- 94, 60, 82, 292, 293, 294, 94, 60, 122, 61,
- 122, 72, 298, 94, 60, 61, 301, 302, 305, 94,
- 306, 313, 61, 314, 122, 122, 94, 325, 61, 135,
- 136, 139, 140, 137, 138, 61, 141, 142, 144, 145,
- 146, 148, 143, 147, 135, 136, 139, 140, 137, 138,
- 326, 141, 142, 144, 145, 146, 148, 143, 147, 327,
- 328, 188, 97, 333, 275, 122, 33, 135, 136, 139,
- 140, 137, 138, 205, 141, 142, 144, 145, 146, 148,
- 143, 147, 188, 188, 333, 122, 346, 347, 207, 135,
- 136, 139, 140, 137, 138, 348, 141, 142, 144, 145,
- 146, 148, 143, 147, 188, 356, 357, 358, 359, 360,
- 135, 136, 139, 140, 137, 138, 361, 141, 142, 144,
- 145, 146, 148, 143, 147, 135, 136, 139, 140, 137,
- 138, 362, 141, 142, 144, 145, 146, 148, 143, 147,
- 135, 136, 139, 140, 137, 138, 122, 141, 142, 144,
- 145, 146, 148, 143, 147, 135, 136, 139, 140, 137,
- 138, 364, 141, 142, 144, 145, 146, 148, 143, 147,
- 135, 136, 139, 140, 137, 138, 72, 141, 142, 144,
- 145, 146, 148, 143, 147, 135, 136, 139, 140, 137,
- 138, 33, 141, 142, 144, 145, 146, 148, 143, 147,
- 135, 136, 139, 140, 137, 138, 378, 141, 142, 144,
- 145, 146, 148, 143, 147, 135, 136, 139, 140, 137,
- 138, 379, 141, 142, 144, 145, 146, 148, 143, 147,
- 380, 381, 382, 383, 385, 386, 390, 72, 392 ]
-
-racc_action_check = [
- 3, 65, 309, 312, 72, 272, 0, 0, 0, 70,
- 240, 232, 28, 295, 29, 36, 48, 105, 0, 48,
- 296, 3, 65, 309, 312, 232, 383, 0, 95, 95,
- 36, 0, 1, 97, 97, 97, 97, 295, 186, 186,
- 186, 186, 343, 27, 296, 28, 30, 29, 0, 383,
- 105, 0, 0, 70, 0, 0, 0, 272, 31, 0,
- 0, 0, 0, 72, 0, 240, 0, 38, 0, 0,
- 0, 0, 32, 0, 0, 0, 2, 2, 2, 295,
- 3, 65, 309, 312, 0, 0, 296, 36, 2, 36,
- 97, 383, 224, 224, 343, 186, 37, 2, 358, 358,
- 38, 2, 209, 209, 209, 209, 153, 184, 153, 358,
- 229, 229, 38, 184, 41, 88, 88, 88, 2, 44,
- 301, 2, 2, 46, 2, 2, 2, 88, 47, 2,
- 2, 2, 2, 301, 2, 187, 2, 187, 2, 2,
- 2, 2, 53, 2, 2, 2, 188, 188, 188, 58,
- 88, 35, 35, 35, 2, 2, 60, 55, 188, 209,
- 63, 35, 88, 35, 301, 55, 55, 188, 337, 342,
- 64, 188, 301, 68, 301, 342, 342, 342, 342, 280,
- 280, 337, 357, 357, 357, 357, 35, 222, 188, 222,
- 99, 188, 188, 101, 188, 188, 188, 102, 35, 188,
- 188, 188, 188, 103, 188, 109, 188, 35, 188, 188,
- 188, 188, 337, 188, 188, 188, 225, 225, 225, 111,
- 337, 112, 337, 115, 188, 188, 293, 293, 225, 320,
- 320, 98, 98, 98, 98, 98, 98, 225, 98, 98,
- 117, 225, 34, 34, 34, 75, 75, 75, 234, 234,
- 234, 98, 98, 238, 238, 238, 118, 121, 225, 123,
- 132, 225, 225, 98, 225, 225, 225, 173, 174, 225,
- 225, 225, 225, 175, 225, 176, 225, 177, 225, 225,
- 225, 225, 178, 225, 225, 225, 179, 98, 180, 98,
- 42, 42, 42, 181, 225, 225, 43, 43, 43, 182,
- 42, 363, 42, 45, 45, 45, 43, 189, 43, 76,
- 76, 76, 190, 45, 363, 45, 94, 94, 94, 76,
- 191, 76, 113, 113, 113, 42, 94, 192, 94, 193,
- 194, 43, 113, 197, 113, 201, 202, 42, 45, 326,
- 326, 326, 203, 43, 76, 363, 42, 360, 360, 360,
- 45, 94, 43, 363, 204, 363, 76, 113, 205, 45,
- 210, 211, 212, 94, 213, 76, 214, 215, 216, 113,
- 217, 218, 94, 114, 114, 114, 219, 221, 113, 116,
- 116, 116, 226, 114, 227, 114, 134, 134, 134, 116,
- 228, 116, 199, 199, 199, 235, 134, 239, 134, 200,
- 200, 200, 199, 241, 199, 242, 244, 245, 114, 200,
- 246, 200, 247, 248, 116, 249, 250, 251, 252, 253,
- 114, 134, 254, 256, 260, 263, 116, 199, 265, 114,
- 266, 269, 270, 134, 200, 116, 275, 277, 291, 199,
- 292, 297, 134, 299, 300, 302, 200, 303, 199, 133,
- 133, 133, 133, 133, 133, 200, 133, 133, 133, 133,
- 133, 133, 133, 133, 150, 150, 150, 150, 150, 150,
- 304, 150, 150, 150, 150, 150, 150, 150, 150, 306,
- 307, 107, 308, 313, 315, 323, 325, 107, 107, 107,
- 107, 107, 107, 133, 107, 107, 107, 107, 107, 107,
- 107, 107, 328, 108, 331, 333, 338, 339, 150, 108,
- 108, 108, 108, 108, 108, 340, 108, 108, 108, 108,
- 108, 108, 108, 108, 110, 347, 349, 350, 351, 352,
- 110, 110, 110, 110, 110, 110, 353, 110, 110, 110,
- 110, 110, 110, 110, 110, 83, 83, 83, 83, 83,
- 83, 354, 83, 83, 83, 83, 83, 83, 83, 83,
- 195, 195, 195, 195, 195, 195, 355, 195, 195, 195,
- 195, 195, 195, 195, 195, 196, 196, 196, 196, 196,
- 196, 356, 196, 196, 196, 196, 196, 196, 196, 196,
- 198, 198, 198, 198, 198, 198, 359, 198, 198, 198,
- 198, 198, 198, 198, 198, 206, 206, 206, 206, 206,
- 206, 361, 206, 206, 206, 206, 206, 206, 206, 206,
- 236, 236, 236, 236, 236, 236, 365, 236, 236, 236,
- 236, 236, 236, 236, 236, 237, 237, 237, 237, 237,
- 237, 366, 237, 237, 237, 237, 237, 237, 237, 237,
- 368, 371, 372, 373, 376, 379, 384, 385, 387 ]
-
-racc_action_pointer = [
- 2, 32, 72, -4, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 13, -17, -15,
- 20, -16, -2, nil, 215, 124, 13, 67, 38, nil,
- nil, 32, 263, 269, 90, 276, 94, 99, -30, nil,
- nil, nil, nil, 125, nil, 127, nil, nil, 120, nil,
- 82, nil, nil, 135, 170, -3, nil, nil, 148, nil,
- -17, nil, -13, nil, nil, 218, 282, nil, nil, nil,
- nil, nil, nil, 514, nil, nil, nil, nil, 88, nil,
- nil, nil, nil, nil, 289, 1, nil, 7, 224, 173,
- nil, 168, 121, 129, nil, -12, nil, 456, 478, 154,
- 499, 194, 196, 295, 346, 198, 352, 210, 226, nil,
- nil, 231, nil, 179, nil, nil, nil, nil, nil, nil,
- nil, nil, 183, 418, 359, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- 433, nil, nil, 31, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 189, 190, 195, 197, 199, 204, 208,
- 210, 215, 221, nil, 84, nil, 12, 60, 142, 260,
- 265, 246, 279, 281, 269, 529, 544, 315, 559, 365,
- 372, 258, 311, 317, 328, 341, 574, nil, nil, 76,
- 332, 333, 334, 336, 338, 339, 340, 342, 343, 348,
- nil, 303, 112, nil, 65, 212, 334, 359, 342, 82,
- nil, nil, -36, nil, 221, 321, 589, 604, 226, 349,
- -16, 328, 380, nil, 327, 328, 331, 333, 334, 336,
- 337, 338, 339, 340, 394, nil, 346, nil, nil, nil,
- 406, nil, nil, 377, nil, 403, 405, nil, nil, 402,
- 357, nil, -20, nil, nil, 360, nil, 420, nil, nil,
- 124, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 363, 414, 198, nil, 8, 15, 366, nil, 362,
- 419, 94, 420, 373, 396, nil, 404, 405, 408, -2,
- nil, nil, -1, 466, nil, 458, nil, nil, nil, nil,
- 202, nil, nil, 460, nil, 404, 312, nil, 477, nil,
- nil, 487, nil, 480, nil, nil, nil, 142, 431, 430,
- 467, nil, 156, 17, nil, nil, nil, 499, nil, 452,
- 453, 454, 455, 462, 472, 541, 506, 156, 70, 567,
- 320, 529, nil, 275, nil, 551, 564, nil, 575, nil,
- nil, 623, 577, 576, nil, nil, 577, nil, nil, 629,
- nil, nil, nil, 20, 581, 628, nil, 583, nil, nil,
- nil, nil, nil ]
-
-racc_action_default = [
- -2, -210, -1, -188, -8, -9, -10, -11, -12, -13,
- -14, -15, -16, -17, -18, -19, -20, -21, -22, -23,
- -24, -25, -26, -27, -28, -29, -30, -210, -210, -210,
- -210, -210, -210, -45, -210, -210, -118, -210, -210, -61,
- -62, -210, -210, -210, -210, -210, -210, -210, -81, -84,
- -85, -86, -87, -210, -111, -210, -116, -117, -210, -125,
- -210, -183, -184, -190, -210, -188, -3, -185, -7, -187,
- -210, -34, -118, -35, -36, -210, -210, -46, -103, -104,
- -158, -159, -160, -47, -128, -129, -130, -131, -210, -148,
- -149, -150, -151, -152, -210, -210, -157, -52, -210, -119,
- -121, -190, -210, -210, -58, -210, -63, -210, -210, -210,
- -210, -210, -190, -210, -210, -190, -210, -210, -210, -120,
- -126, -210, -189, -210, -192, 393, -4, -6, -186, -31,
- -32, -33, -210, -210, -210, -134, -135, -136, -137, -138,
- -139, -140, -141, -142, -143, -144, -145, -146, -147, -132,
- -210, -155, -156, -210, -50, -53, -54, -55, -56, -57,
- -112, -161, -162, -163, -164, -165, -166, -167, -168, -169,
- -170, -171, -172, -210, -210, -210, -210, -210, -210, -210,
- -210, -210, -210, -122, -210, -127, -52, -210, -210, -89,
- -89, -210, -210, -210, -210, -82, -83, -210, -113, -210,
- -210, -210, -190, -190, -210, -38, -133, -153, -48, -210,
- -210, -210, -210, -210, -210, -210, -210, -210, -210, -210,
- -123, -210, -210, -59, -210, -5, -210, -210, -210, -210,
- -67, -70, -78, -72, -210, -210, -114, -115, -210, -210,
- -210, -210, -190, -51, -210, -210, -210, -210, -210, -210,
- -210, -210, -210, -210, -210, -49, -210, -64, -88, -65,
- -210, -68, -69, -210, -73, -190, -190, -75, -76, -210,
- -210, -191, -190, -194, -195, -210, -37, -39, -41, -42,
- -210, -173, -174, -175, -176, -177, -178, -179, -180, -181,
- -182, -210, -210, -210, -71, -210, -210, -210, -154, -210,
- -190, -205, -190, -210, -210, -124, -210, -210, -210, -188,
- -79, -80, -188, -210, -193, -210, -197, -198, -199, -200,
- -210, -203, -204, -190, -40, -210, -210, -60, -210, -77,
- -74, -90, -91, -190, -196, -201, -202, -205, -210, -210,
- -210, -92, -210, -190, -207, -209, -43, -210, -66, -210,
- -210, -210, -210, -210, -210, -190, -210, -210, -210, -210,
- -210, -210, -206, -205, -44, -210, -210, -110, -210, -98,
- -99, -210, -210, -210, -107, -108, -102, -208, -93, -210,
- -94, -100, -95, -210, -210, -210, -109, -210, -105, -106,
- -97, -101, -96 ]
-
-racc_goto_table = [
- 39, 106, 39, 66, 78, 65, 123, 68, 77, 184,
- 9, 2, 9, 153, 40, 261, 40, 274, 310, 310,
- 194, 189, 190, 197, 192, 193, 71, 73, 39, 39,
- 277, 260, 233, 344, 79, 1, 104, 322, 39, 332,
- 291, 128, 40, 40, 109, 78, 129, 112, 243, 132,
- 311, 311, 40, 83, 226, 228, 389, 341, 232, 377,
- 107, 108, 263, 110, 266, 126, 331, 155, 167, 68,
- 264, 309, 312, 322, 365, 79, 368, 373, 387, 261,
- 384, 160, 119, 183, 120, 149, 168, 161, 162, 163,
- 324, 164, 334, 165, 133, 307, 166, 156, 169, 322,
- 170, 171, 222, 187, 172, 39, 388, 158, 202, 272,
- 316, 343, 150, nil, nil, nil, nil, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 195, 196, nil, 198, nil, nil, nil, nil, nil,
- nil, 258, nil, nil, 369, 239, 240, nil, nil, nil,
- 280, nil, 206, nil, nil, nil, 155, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 295, 296, nil, nil, nil, nil, 155,
- nil, nil, nil, nil, nil, nil, 156, nil, 39, nil,
- nil, nil, nil, nil, 256, nil, 158, nil, 9, 225,
- nil, nil, 40, nil, 267, nil, nil, nil, 78, 156,
- 280, nil, 270, nil, nil, 299, nil, 236, 237, 158,
- nil, nil, nil, nil, nil, 39, nil, nil, 65, 262,
- nil, nil, nil, nil, 268, 9, nil, nil, 79, 40,
- nil, 342, 340, 315, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 337, nil, nil, 297,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 338, 354, nil, nil, nil,
- nil, nil, nil, 262, nil, nil, 78, nil, 363, nil,
- 339, nil, nil, nil, nil, nil, nil, nil, nil, 329,
- nil, nil, 330, 68, nil, nil, 68, nil, nil, nil,
- nil, 376, nil, nil, nil, nil, 79, 78, nil, nil,
- 375, 366, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 79, 370, 372,
- 374, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 391 ]
-
-racc_goto_check = [
- 40, 35, 40, 4, 39, 3, 86, 7, 29, 34,
- 12, 2, 12, 37, 43, 47, 43, 89, 36, 36,
- 34, 5, 5, 34, 5, 5, 28, 28, 40, 40,
- 31, 46, 50, 94, 40, 1, 28, 75, 40, 56,
- 47, 6, 43, 43, 40, 39, 27, 40, 38, 29,
- 44, 44, 43, 30, 45, 45, 42, 56, 48, 94,
- 30, 30, 49, 30, 51, 4, 55, 39, 39, 7,
- 50, 52, 52, 75, 57, 40, 58, 59, 60, 47,
- 61, 62, 63, 67, 68, 71, 73, 76, 77, 78,
- 31, 79, 89, 80, 30, 46, 81, 40, 82, 75,
- 83, 84, 37, 28, 85, 40, 36, 12, 87, 88,
- 90, 93, 30, nil, nil, nil, nil, nil, nil, 43,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 30, 30, nil, 30, nil, nil, nil, nil, nil,
- nil, 5, nil, nil, 47, 86, 86, nil, nil, nil,
- 34, nil, 30, nil, nil, nil, 39, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, 34, 34, nil, nil, nil, nil, 39,
- nil, nil, nil, nil, nil, nil, 40, nil, 40, nil,
- nil, nil, nil, nil, 39, nil, 12, nil, 12, 2,
- nil, nil, 43, nil, 39, nil, nil, nil, 39, 40,
- 34, nil, 29, nil, nil, 86, nil, 30, 30, 12,
- nil, nil, nil, nil, nil, 40, nil, nil, 3, 40,
- nil, nil, nil, nil, 40, 12, nil, nil, 40, 43,
- nil, 34, 5, 86, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, 86, nil, nil, 40,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 35, 86, nil, nil, nil,
- nil, nil, nil, 40, nil, nil, 39, nil, 86, nil,
- 29, nil, nil, nil, nil, nil, nil, nil, nil, 4,
- nil, nil, 4, 7, nil, nil, 7, nil, nil, nil,
- nil, 35, nil, nil, nil, nil, 40, 39, nil, nil,
- 39, 29, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 40, 40, 40,
- 40, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, 40 ]
-
-racc_goto_pointer = [
- nil, 35, 11, 3, 0, -86, -27, 4, nil, nil,
- nil, nil, 10, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, -24, -2, -26,
- 18, -212, nil, nil, -92, -40, -277, -84, -161, -30,
- 0, nil, -327, 14, -245, -135, -198, -214, -136, -170,
- -162, -170, -224, nil, nil, -247, -274, -283, -282, -283,
- -305, -296, -17, 24, nil, nil, nil, -16, 26, nil,
- nil, -3, nil, -12, nil, -264, -11, -10, -9, -7,
- -5, -2, 0, 2, 3, 6, -57, -15, -131, -223,
- -191, nil, nil, -226, -304 ]
-
-racc_goto_default = [
- nil, nil, nil, 3, nil, nil, nil, 4, 5, 6,
- 7, 8, 87, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, nil, 55, nil,
- nil, nil, 278, 279, 124, 54, 52, nil, 154, 89,
- 91, 157, 51, 92, 49, nil, nil, 80, nil, nil,
- nil, nil, nil, 48, 50, nil, nil, nil, nil, nil,
- nil, nil, nil, 56, 57, 99, 58, 100, 59, 84,
- 85, 86, 134, 90, 93, 95, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, 318, nil, nil,
- 345, 319, 320, nil, nil ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 86, :_reduce_1,
- 0, 86, :_reduce_none,
- 2, 87, :_reduce_3,
- 3, 87, :_reduce_4,
- 2, 90, :_reduce_5,
- 1, 91, :_reduce_none,
- 0, 91, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_none,
- 1, 88, :_reduce_28,
- 1, 88, :_reduce_29,
- 1, 111, :_reduce_30,
- 3, 110, :_reduce_31,
- 1, 112, :_reduce_none,
- 1, 112, :_reduce_none,
- 2, 109, :_reduce_34,
- 2, 107, :_reduce_35,
- 2, 106, :_reduce_36,
- 6, 104, :_reduce_37,
- 4, 104, :_reduce_38,
- 6, 104, :_reduce_39,
- 8, 104, :_reduce_40,
- 1, 116, :_reduce_none,
- 1, 116, :_reduce_none,
- 5, 117, :_reduce_43,
- 7, 118, :_reduce_44,
- 1, 120, :_reduce_45,
- 2, 102, :_reduce_46,
- 2, 103, :_reduce_47,
- 4, 121, :_reduce_48,
- 5, 121, :_reduce_49,
- 1, 122, :_reduce_50,
- 3, 122, :_reduce_51,
- 0, 122, :_reduce_52,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 123, :_reduce_none,
- 1, 126, :_reduce_57,
- 2, 127, :_reduce_58,
- 4, 127, :_reduce_59,
- 8, 127, :_reduce_60,
- 1, 113, :_reduce_none,
- 1, 113, :_reduce_none,
- 2, 129, :_reduce_63,
- 5, 98, :_reduce_64,
- 5, 98, :_reduce_65,
- 10, 100, :_reduce_66,
- 4, 101, :_reduce_67,
- 1, 131, :_reduce_none,
- 1, 131, :_reduce_none,
- 4, 94, :_reduce_70,
- 6, 105, :_reduce_71,
- 1, 133, :_reduce_72,
- 2, 133, :_reduce_73,
- 5, 135, :_reduce_74,
- 1, 136, :_reduce_none,
- 1, 136, :_reduce_none,
- 4, 134, :_reduce_77,
- 0, 134, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 137, :_reduce_none,
- 1, 99, :_reduce_none,
- 3, 99, :_reduce_82,
- 3, 99, :_reduce_83,
- 1, 138, :_reduce_none,
- 1, 138, :_reduce_none,
- 1, 138, :_reduce_none,
- 1, 138, :_reduce_none,
- 2, 130, :_reduce_88,
- 0, 130, :_reduce_89,
- 8, 95, :_reduce_90,
- 1, 140, :_reduce_91,
- 2, 140, :_reduce_92,
- 6, 141, :_reduce_93,
- 6, 141, :_reduce_94,
- 6, 141, :_reduce_95,
- 8, 141, :_reduce_96,
- 7, 141, :_reduce_97,
- 1, 143, :_reduce_none,
- 1, 143, :_reduce_none,
- 2, 143, :_reduce_100,
- 2, 146, :_reduce_101,
- 0, 146, :_reduce_none,
- 1, 114, :_reduce_none,
- 1, 114, :_reduce_none,
- 1, 145, :_reduce_none,
- 1, 145, :_reduce_none,
- 1, 144, :_reduce_none,
- 1, 144, :_reduce_none,
- 3, 142, :_reduce_109,
- 1, 142, :_reduce_110,
- 1, 96, :_reduce_111,
- 3, 93, :_reduce_112,
- 3, 139, :_reduce_113,
- 4, 139, :_reduce_114,
- 4, 139, :_reduce_115,
- 1, 125, :_reduce_none,
- 1, 125, :_reduce_none,
- 1, 148, :_reduce_118,
- 2, 148, :_reduce_119,
- 2, 149, :_reduce_120,
- 1, 150, :_reduce_121,
- 2, 150, :_reduce_122,
- 3, 152, :_reduce_123,
- 6, 152, :_reduce_124,
- 1, 151, :_reduce_125,
- 2, 151, :_reduce_126,
- 3, 153, :_reduce_127,
- 1, 115, :_reduce_none,
- 1, 115, :_reduce_none,
- 1, 154, :_reduce_130,
- 1, 154, :_reduce_none,
- 2, 154, :_reduce_132,
- 3, 155, :_reduce_133,
- 1, 157, :_reduce_134,
- 1, 157, :_reduce_135,
- 1, 157, :_reduce_136,
- 1, 157, :_reduce_137,
- 1, 157, :_reduce_138,
- 1, 157, :_reduce_139,
- 1, 157, :_reduce_140,
- 1, 157, :_reduce_141,
- 1, 157, :_reduce_142,
- 1, 157, :_reduce_143,
- 1, 157, :_reduce_144,
- 1, 157, :_reduce_145,
- 1, 157, :_reduce_146,
- 1, 157, :_reduce_147,
- 1, 156, :_reduce_none,
- 1, 156, :_reduce_none,
- 1, 156, :_reduce_none,
- 1, 156, :_reduce_none,
- 1, 156, :_reduce_none,
- 3, 159, :_reduce_153,
- 6, 128, :_reduce_154,
- 2, 158, :_reduce_155,
- 2, 158, :_reduce_156,
- 1, 160, :_reduce_157,
- 1, 124, :_reduce_none,
- 1, 124, :_reduce_159,
- 1, 132, :_reduce_160,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 1, 147, :_reduce_none,
- 4, 170, :_reduce_173,
- 4, 169, :_reduce_174,
- 4, 168, :_reduce_175,
- 4, 167, :_reduce_176,
- 4, 166, :_reduce_177,
- 4, 165, :_reduce_178,
- 4, 161, :_reduce_179,
- 4, 164, :_reduce_180,
- 4, 162, :_reduce_181,
- 4, 163, :_reduce_182,
- 1, 97, :_reduce_183,
- 1, 92, :_reduce_184,
- 1, 89, :_reduce_185,
- 2, 89, :_reduce_186,
- 1, 89, :_reduce_none,
- 0, 89, :_reduce_none,
- 1, 119, :_reduce_189,
- 0, 119, :_reduce_none,
- 5, 108, :_reduce_191,
- 1, 171, :_reduce_none,
- 5, 172, :_reduce_193,
- 3, 172, :_reduce_194,
- 1, 173, :_reduce_195,
- 4, 173, :_reduce_196,
- 3, 174, :_reduce_197,
- 1, 175, :_reduce_none,
- 1, 175, :_reduce_none,
- 1, 175, :_reduce_none,
- 2, 175, :_reduce_201,
- 2, 175, :_reduce_202,
- 1, 175, :_reduce_203,
- 1, 177, :_reduce_none,
- 0, 177, :_reduce_none,
- 5, 176, :_reduce_206,
- 1, 178, :_reduce_207,
- 4, 178, :_reduce_208,
- 1, 179, :_reduce_none ]
-
-racc_reduce_n = 210
-
-racc_shift_n = 393
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :ASSIGN => 2,
- :AT_SYM => 3,
- :COMMENT => 4,
- :JUMP => 5,
- :IO_METHOD => 6,
- :INPUT => 7,
- :OUTPUT => 8,
- :NUMREG => 9,
- :POSREG => 10,
- :VREG => 11,
- :SREG => 12,
- :TIME_SEGMENT => 13,
- :ARG => 14,
- :UALM => 15,
- :MOVE => 16,
- :DOT => 17,
- :TO => 18,
- :AT => 19,
- :TERM => 20,
- :OFFSET => 21,
- :SKIP => 22,
- :GROUP => 23,
- :SEMICOLON => 24,
- :NEWLINE => 25,
- :STRING => 26,
- :REAL => 27,
- :DIGIT => 28,
- :WORD => 29,
- :EQUAL => 30,
- :EEQUAL => 31,
- :NOTEQUAL => 32,
- :GTE => 33,
- :LTE => 34,
- :LT => 35,
- :GT => 36,
- :BANG => 37,
- :PLUS => 38,
- :MINUS => 39,
- :STAR => 40,
- :SLASH => 41,
- :DIV => 42,
- :AND => 43,
- :OR => 44,
- :MOD => 45,
- :IF => 46,
- :ELSE => 47,
- :END => 48,
- :UNLESS => 49,
- :FOR => 50,
- :IN => 51,
- :WHILE => 52,
- :WAIT_FOR => 53,
- :WAIT_UNTIL => 54,
- :TIMEOUT => 55,
- :AFTER => 56,
- :FANUC_USE => 57,
- :SET_SKIP_CONDITION => 58,
- :NAMESPACE => 59,
- :CASE => 60,
- :WHEN => 61,
- :INDIRECT => 62,
- :POSITION => 63,
- :EVAL => 64,
- :TIMER => 65,
- :TIMER_METHOD => 66,
- :RAISE => 67,
- :ABORT => 68,
- :POSITION_DATA => 69,
- :TRUE_FALSE => 70,
- :RUN => 71,
- :TP_HEADER => 72,
- :PAUSE => 73,
- :LPAREN => 74,
- :RPAREN => 75,
- :COLON => 76,
- :COMMA => 77,
- :LBRACK => 78,
- :RBRACK => 79,
- :LBRACE => 80,
- :RBRACE => 81,
- :LABEL => 82,
- :ADDRESS => 83,
- :false => 84 }
-
-racc_nt_base = 85
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "ASSIGN",
- "AT_SYM",
- "COMMENT",
- "JUMP",
- "IO_METHOD",
- "INPUT",
- "OUTPUT",
- "NUMREG",
- "POSREG",
- "VREG",
- "SREG",
- "TIME_SEGMENT",
- "ARG",
- "UALM",
- "MOVE",
- "DOT",
- "TO",
- "AT",
- "TERM",
- "OFFSET",
- "SKIP",
- "GROUP",
- "SEMICOLON",
- "NEWLINE",
- "STRING",
- "REAL",
- "DIGIT",
- "WORD",
- "EQUAL",
- "EEQUAL",
- "NOTEQUAL",
- "GTE",
- "LTE",
- "LT",
- "GT",
- "BANG",
- "PLUS",
- "MINUS",
- "STAR",
- "SLASH",
- "DIV",
- "AND",
- "OR",
- "MOD",
- "IF",
- "ELSE",
- "END",
- "UNLESS",
- "FOR",
- "IN",
- "WHILE",
- "WAIT_FOR",
- "WAIT_UNTIL",
- "TIMEOUT",
- "AFTER",
- "FANUC_USE",
- "SET_SKIP_CONDITION",
- "NAMESPACE",
- "CASE",
- "WHEN",
- "INDIRECT",
- "POSITION",
- "EVAL",
- "TIMER",
- "TIMER_METHOD",
- "RAISE",
- "ABORT",
- "POSITION_DATA",
- "TRUE_FALSE",
- "RUN",
- "TP_HEADER",
- "PAUSE",
- "LPAREN",
- "RPAREN",
- "COLON",
- "COMMA",
- "LBRACK",
- "RBRACK",
- "LBRACE",
- "RBRACE",
- "LABEL",
- "ADDRESS",
- "false",
- "$start",
- "program",
- "statements",
- "statement",
- "terminator",
- "block",
- "optional_newline",
- "comment",
- "definition",
- "namespace",
- "motion_statement",
- "label_definition",
- "address",
- "conditional",
- "inline_conditional",
- "forloop",
- "while_loop",
- "use_statement",
- "set_skip_statement",
- "wait_statement",
- "case_statement",
- "fanuc_eval",
- "timer_method",
- "position_data",
- "raise",
- "tp_header_definition",
- "empty_stmt",
- "tp_header_value",
- "var_or_indirect",
- "indirectable",
- "expression",
- "wait_modifier",
- "timeout_modifier",
- "after_modifier",
- "swallow_newlines",
- "label",
- "program_call",
- "args",
- "arg",
- "number",
- "var",
- "string",
- "io_method",
- "indirect_thing",
- "jump",
- "else_block",
- "minmax_val",
- "integer",
- "case_conditions",
- "case_else",
- "case_condition",
- "case_allowed_condition",
- "case_allowed_statement",
- "inlineable",
- "assignment",
- "motion_modifiers",
- "motion_modifier",
- "speed",
- "valid_terminations",
- "time",
- "time_seg_actions",
- "optional_lpos_arg",
- "definable",
- "var_without_namespaces",
- "var_with_namespaces",
- "var_method_modifiers",
- "namespaces",
- "var_method_modifier",
- "ns",
- "unary_expression",
- "binary_expression",
- "factor",
- "operator",
- "signed_number",
- "paren_expr",
- "sign",
- "numreg",
- "output",
- "input",
- "posreg",
- "position",
- "vreg",
- "argument",
- "timer",
- "ualm",
- "sreg",
- "sn",
- "hash",
- "hash_attributes",
- "hash_attribute",
- "hash_value",
- "array",
- "optional_sign",
- "array_values",
- "array_value" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 35)
- def _reduce_1(val, _values, result)
- @interpreter.nodes = val[0]
- result
- end
-.,.,
-
-# reduce 2 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 42)
- def _reduce_3(val, _values, result)
- result = [val[0]]
- result << val[1] unless val[1].nil?
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 46)
- def _reduce_4(val, _values, result)
- result = val[0] << val[1]
- result << val[2] unless val[2].nil?
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 52)
- def _reduce_5(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-# reduce 6 omitted
-
-# reduce 7 omitted
-
-# reduce 8 omitted
-
-# reduce 9 omitted
-
-# reduce 10 omitted
-
-# reduce 11 omitted
-
-# reduce 12 omitted
-
-# reduce 13 omitted
-
-# reduce 14 omitted
-
-# reduce 15 omitted
-
-# reduce 16 omitted
-
-# reduce 17 omitted
-
-# reduce 18 omitted
-
-# reduce 19 omitted
-
-# reduce 20 omitted
-
-# reduce 21 omitted
-
-# reduce 22 omitted
-
-# reduce 23 omitted
-
-# reduce 24 omitted
-
-# reduce 25 omitted
-
-# reduce 26 omitted
-
-# reduce 27 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 85)
- def _reduce_28(val, _values, result)
- result = PauseNode.new
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 86)
- def _reduce_29(val, _values, result)
- result = AbortNode.new
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 90)
- def _reduce_30(val, _values, result)
- result = EmptyStmtNode.new()
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 94)
- def _reduce_31(val, _values, result)
- result = HeaderNode.new(val[0],val[2])
- result
- end
-.,.,
-
-# reduce 32 omitted
-
-# reduce 33 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 103)
- def _reduce_34(val, _values, result)
- result = RaiseNode.new(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 107)
- def _reduce_35(val, _values, result)
- result = TimerMethodNode.new(val[0],val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 111)
- def _reduce_36(val, _values, result)
- result = EvalNode.new(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 116)
- def _reduce_37(val, _values, result)
- result = WaitForNode.new(val[2], val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 118)
- def _reduce_38(val, _values, result)
- result = WaitUntilNode.new(val[2], nil)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 120)
- def _reduce_39(val, _values, result)
- result = WaitUntilNode.new(val[2],val[5])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 122)
- def _reduce_40(val, _values, result)
- result = WaitUntilNode.new(val[2],val[5].merge(val[7]))
- result
- end
-.,.,
-
-# reduce 41 omitted
-
-# reduce 42 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 132)
- def _reduce_43(val, _values, result)
- result = { label: val[3] }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 137)
- def _reduce_44(val, _values, result)
- result = { timeout: [val[3],val[5]] }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 141)
- def _reduce_45(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 145)
- def _reduce_46(val, _values, result)
- result = UseNode.new(val[0],val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 150)
- def _reduce_47(val, _values, result)
- result = SetSkipNode.new(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 154)
- def _reduce_48(val, _values, result)
- result = CallNode.new(val[0],val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 155)
- def _reduce_49(val, _values, result)
- result = CallNode.new(val[1],val[3],async: true)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 159)
- def _reduce_50(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 160)
- def _reduce_51(val, _values, result)
- result = val[0] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 161)
- def _reduce_52(val, _values, result)
- result = []
- result
- end
-.,.,
-
-# reduce 53 omitted
-
-# reduce 54 omitted
-
-# reduce 55 omitted
-
-# reduce 56 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 172)
- def _reduce_57(val, _values, result)
- result = StringNode.new(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 176)
- def _reduce_58(val, _values, result)
- result = IOMethodNode.new(val[0],val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 178)
- def _reduce_59(val, _values, result)
- result = IOMethodNode.new(val[0],val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 180)
- def _reduce_60(val, _values, result)
- result = IOMethodNode.new(val[0],val[2],{ pulse_time: val[4], pulse_units: val[6] })
- result
- end
-.,.,
-
-# reduce 61 omitted
-
-# reduce 62 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 190)
- def _reduce_63(val, _values, result)
- result = JumpNode.new(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 195)
- def _reduce_64(val, _values, result)
- result = ConditionalNode.new("if",val[1],val[2],val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 197)
- def _reduce_65(val, _values, result)
- result = ConditionalNode.new("unless",val[1],val[2],val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 202)
- def _reduce_66(val, _values, result)
- result = ForNode.new(val[1],val[4],val[6],val[8])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 206)
- def _reduce_67(val, _values, result)
- result = WhileNode.new(val[1],val[2])
- result
- end
-.,.,
-
-# reduce 68 omitted
-
-# reduce 69 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 215)
- def _reduce_70(val, _values, result)
- result = NamespaceNode.new(val[1],val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 222)
- def _reduce_71(val, _values, result)
- result = CaseNode.new(val[1],val[3],val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 226)
- def _reduce_72(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 228)
- def _reduce_73(val, _values, result)
- result = val[0] << val[1] << val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 233)
- def _reduce_74(val, _values, result)
- result = CaseConditionNode.new(val[1],val[3])
- result
- end
-.,.,
-
-# reduce 75 omitted
-
-# reduce 76 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 243)
- def _reduce_77(val, _values, result)
- result = CaseConditionNode.new(nil,val[2])
- result
- end
-.,.,
-
-# reduce 78 omitted
-
-# reduce 79 omitted
-
-# reduce 80 omitted
-
-# reduce 81 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 254)
- def _reduce_82(val, _values, result)
- result = InlineConditionalNode.new(val[1], val[2], val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 255)
- def _reduce_83(val, _values, result)
- result = InlineConditionalNode.new(val[1], val[2], val[0])
- result
- end
-.,.,
-
-# reduce 84 omitted
-
-# reduce 85 omitted
-
-# reduce 86 omitted
-
-# reduce 87 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 266)
- def _reduce_88(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 267)
- def _reduce_89(val, _values, result)
- result = []
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 272)
- def _reduce_90(val, _values, result)
- result = MotionNode.new(val[0],val[5],val[7])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 276)
- def _reduce_91(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 278)
- def _reduce_92(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 283)
- def _reduce_93(val, _values, result)
- result = SpeedNode.new(val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 285)
- def _reduce_94(val, _values, result)
- result = TerminationNode.new(val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 287)
- def _reduce_95(val, _values, result)
- result = OffsetNode.new(val[2],val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 289)
- def _reduce_96(val, _values, result)
- result = TimeNode.new(val[2],val[4],val[6])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 291)
- def _reduce_97(val, _values, result)
- result = SkipNode.new(val[4],val[5])
- result
- end
-.,.,
-
-# reduce 98 omitted
-
-# reduce 99 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 298)
- def _reduce_100(val, _values, result)
- raise Racc::ParseError, sprintf("\ninvalid termination type: (%s)", val[1]) if val[1] != 1
-
- result = DigitNode.new(val[1].to_i * -1)
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 305)
- def _reduce_101(val, _values, result)
- result = val[1]
- result
- end
-.,.,
-
-# reduce 102 omitted
-
-# reduce 103 omitted
-
-# reduce 104 omitted
-
-# reduce 105 omitted
-
-# reduce 106 omitted
-
-# reduce 107 omitted
-
-# reduce 108 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 325)
- def _reduce_109(val, _values, result)
- result = { speed: val[0], units: val[2] }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 326)
- def _reduce_110(val, _values, result)
- result = { speed: val[0], units: nil }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 330)
- def _reduce_111(val, _values, result)
- result = LabelDefinitionNode.new(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 334)
- def _reduce_112(val, _values, result)
- result = DefinitionNode.new(val[0],val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 338)
- def _reduce_113(val, _values, result)
- result = AssignmentNode.new(val[0],val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 339)
- def _reduce_114(val, _values, result)
- result = AssignmentNode.new(
- val[0],
- ExpressionNode.new(val[0],"+",val[3])
- )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 344)
- def _reduce_115(val, _values, result)
- result = AssignmentNode.new(
- val[0],
- ExpressionNode.new(val[0],"-",val[3])
- )
-
- result
- end
-.,.,
-
-# reduce 116 omitted
-
-# reduce 117 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 357)
- def _reduce_118(val, _values, result)
- result = VarNode.new(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 358)
- def _reduce_119(val, _values, result)
- result = VarMethodNode.new(val[0],val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 363)
- def _reduce_120(val, _values, result)
- result = NamespacedVarNode.new(val[0],val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 367)
- def _reduce_121(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 369)
- def _reduce_122(val, _values, result)
- result = val[0].merge(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 373)
- def _reduce_123(val, _values, result)
- result = { method: val[2] }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 375)
- def _reduce_124(val, _values, result)
- result = { group: val[4] }
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 379)
- def _reduce_125(val, _values, result)
- result = [val[0]]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 380)
- def _reduce_126(val, _values, result)
- result = val[0] << val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 384)
- def _reduce_127(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-# reduce 128 omitted
-
-# reduce 129 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 394)
- def _reduce_130(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-# reduce 131 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 396)
- def _reduce_132(val, _values, result)
- result = ExpressionNode.new(val[1], "!", nil)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 401)
- def _reduce_133(val, _values, result)
- result = ExpressionNode.new(val[0], val[1], val[2])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 405)
- def _reduce_134(val, _values, result)
- result = "=="
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 406)
- def _reduce_135(val, _values, result)
- result = "<>"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 407)
- def _reduce_136(val, _values, result)
- result = "<"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 408)
- def _reduce_137(val, _values, result)
- result = ">"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 409)
- def _reduce_138(val, _values, result)
- result = ">="
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 410)
- def _reduce_139(val, _values, result)
- result = "<="
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 411)
- def _reduce_140(val, _values, result)
- result = "+"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 412)
- def _reduce_141(val, _values, result)
- result = "-"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 413)
- def _reduce_142(val, _values, result)
- result = "||"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 414)
- def _reduce_143(val, _values, result)
- result = "*"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 415)
- def _reduce_144(val, _values, result)
- result = "/"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 416)
- def _reduce_145(val, _values, result)
- result = "DIV"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 417)
- def _reduce_146(val, _values, result)
- result = "%"
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 418)
- def _reduce_147(val, _values, result)
- result = "&&"
- result
- end
-.,.,
-
-# reduce 148 omitted
-
-# reduce 149 omitted
-
-# reduce 150 omitted
-
-# reduce 151 omitted
-
-# reduce 152 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 430)
- def _reduce_153(val, _values, result)
- result = ParenExpressionNode.new(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 435)
- def _reduce_154(val, _values, result)
- result = IndirectNode.new(val[2].to_sym, val[4])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 440)
- def _reduce_155(val, _values, result)
- val[1] = val[1].to_i * -1 if val[0] == "-"
- result = DigitNode.new(val[1])
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 443)
- def _reduce_156(val, _values, result)
- val[1] = val[1].to_f * -1 if val[0] == "-"; result = RealNode.new(val[1])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 447)
- def _reduce_157(val, _values, result)
- result = "-"
- result
- end
-.,.,
-
-# reduce 158 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 452)
- def _reduce_159(val, _values, result)
- result = RealNode.new(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 456)
- def _reduce_160(val, _values, result)
- result = DigitNode.new(val[0])
- result
- end
-.,.,
-
-# reduce 161 omitted
-
-# reduce 162 omitted
-
-# reduce 163 omitted
-
-# reduce 164 omitted
-
-# reduce 165 omitted
-
-# reduce 166 omitted
-
-# reduce 167 omitted
-
-# reduce 168 omitted
-
-# reduce 169 omitted
-
-# reduce 170 omitted
-
-# reduce 171 omitted
-
-# reduce 172 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 476)
- def _reduce_173(val, _values, result)
- result = StringRegisterNode.new(val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 480)
- def _reduce_174(val, _values, result)
- result = UserAlarmNode.new(val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 484)
- def _reduce_175(val, _values, result)
- result = TimerNode.new(val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 488)
- def _reduce_176(val, _values, result)
- result = ArgumentNode.new(val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 492)
- def _reduce_177(val, _values, result)
- result = VisionRegisterNode.new(val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 496)
- def _reduce_178(val, _values, result)
- result = PositionNode.new(val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 500)
- def _reduce_179(val, _values, result)
- result = NumregNode.new(val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 504)
- def _reduce_180(val, _values, result)
- result = PosregNode.new(val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 508)
- def _reduce_181(val, _values, result)
- result = IONode.new(val[0], val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 512)
- def _reduce_182(val, _values, result)
- result = IONode.new(val[0], val[2].to_i)
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 516)
- def _reduce_183(val, _values, result)
- result = AddressNode.new(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 520)
- def _reduce_184(val, _values, result)
- result = CommentNode.new(val[0])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 524)
- def _reduce_185(val, _values, result)
- result = TerminatorNode.new
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 525)
- def _reduce_186(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-# reduce 187 omitted
-
-# reduce 188 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 532)
- def _reduce_189(val, _values, result)
- result = TerminatorNode.new
- result
- end
-.,.,
-
-# reduce 190 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 538)
- def _reduce_191(val, _values, result)
- result = PositionDataNode.new(val[2])
- result
- end
-.,.,
-
-# reduce 192 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 546)
- def _reduce_193(val, _values, result)
- result = val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 547)
- def _reduce_194(val, _values, result)
- result = {}
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 551)
- def _reduce_195(val, _values, result)
- result = val[0]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 553)
- def _reduce_196(val, _values, result)
- result = val[0].merge(val[3])
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 557)
- def _reduce_197(val, _values, result)
- result = { val[0].to_sym => val[2] }
- result
- end
-.,.,
-
-# reduce 198 omitted
-
-# reduce 199 omitted
-
-# reduce 200 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 564)
- def _reduce_201(val, _values, result)
- val[1] = val[1].to_i * -1 if val[0] == "-"; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 565)
- def _reduce_202(val, _values, result)
- val[1] = val[1].to_f * -1 if val[0] == "-"; result = val[1]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 566)
- def _reduce_203(val, _values, result)
- result = val[0] == "true"
- result
- end
-.,.,
-
-# reduce 204 omitted
-
-# reduce 205 omitted
-
-module_eval(<<'.,.,', 'tp_plus.y', 575)
- def _reduce_206(val, _values, result)
- result = val[2]
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 579)
- def _reduce_207(val, _values, result)
- result = val
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'tp_plus.y', 580)
- def _reduce_208(val, _values, result)
- result = val[0] << val[3]
- result
- end
-.,.,
-
-# reduce 209 omitted
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module TPPlus
diff --git a/test/racc/regress/twowaysql b/test/racc/regress/twowaysql
deleted file mode 100644
index 219f1a8b04..0000000000
--- a/test/racc/regress/twowaysql
+++ /dev/null
@@ -1,556 +0,0 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by Racc 1.5.0
-# from Racc grammar file "".
-#
-
-require 'racc/parser.rb'
-module TwoWaySQL
- class Parser < Racc::Parser
-
-module_eval(<<'...end twowaysql.y/module_eval...', 'twowaysql.y', 148)
-
-require 'strscan'
-
-def initialize(opts={})
- opts = {
- :debug => false,
- :preserve_space => true,
- :preserve_comment => false
- }.merge(opts)
- @yydebug = opts[:debug]
- @preserve_space = opts[:preserve_space]
- @preserve_comment = opts[:preserve_comment]
- @num_questions = 0
-end
-
-
-PAREN_EXAMPLE = '\([^\)]+\)'
-BEGIN_BIND_VARIABLE = '(\/|\#)\*([^\*]+)\*\1'
-BIND_VARIABLE_PATTERN = /\A#{BEGIN_BIND_VARIABLE}\s*/
-PAREN_BIND_VARIABLE_PATTERN = /\A#{BEGIN_BIND_VARIABLE}\s*#{PAREN_EXAMPLE}/
-EMBED_VARIABLE_PATTERN = /\A(\/|\#)\*\$([^\*]+)\*\1\s*/
-
-CONDITIONAL_PATTERN = /\A(\/|\#)\*(IF)\s+([^\*]+)\s*\*\1/
-BEGIN_END_PATTERN = /\A(\/|\#)\*(BEGIN|END)\s*\*\1/
-STRING_LITERAL_PATTERN = /\A(\'(?:[^\']+|\'\')*\')/ ## quoted string
-SPLIT_TOKEN_PATTERN = /\A(\S+?)(?=\s*(?:(?:\/|\#)\*|-{2,}|\(|\)|\,))/ ## stop on delimiters --,/*,#*,',',(,)
-LITERAL_PATTERN = /\A([^;\s]+)/
-SPACES_PATTERN = /\A(\s+)/
-QUESTION_PATTERN = /\A\?/
-COMMA_PATTERN = /\A\,/
-LPAREN_PATTERN = /\A\(/
-RPAREN_PATTERN = /\A\)/
-ACTUAL_COMMENT_PATTERN = /\A(\/|\#)\*(\s{1,}(?:.*?))\*\1/m ## start with spaces
-SEMICOLON_AT_INPUT_END_PATTERN = /\A\;\s*\Z/
-UNMATCHED_COMMENT_START_PATTERN = /\A(?:(?:\/|\#)\*)/
-
-#TODO: remove trailing spaces for S2Dao compatibility, but this spec sometimes causes SQL bugs...
-ELSE_PATTERN = /\A\-{2,}\s*ELSE\s*/
-AND_PATTERN = /\A(\ *AND)\b/i
-OR_PATTERN = /\A(\ *OR)\b/i
-
-
-def parse( io )
- @q = []
- io.each_line(nil) do |whole|
- @s = StringScanner.new(whole)
- end
- scan_str
-
- # @q.push [ false, nil ]
- @q.push [ false, [@s.pos, nil] ]
-
- ## call racc's private parse method
- do_parse
-end
-
-
-## called by racc
-def next_token
- @q.shift
-end
-
-
-def scan_str
- until @s.eos? do
- case
- when @s.scan(AND_PATTERN)
- @q.push [ :AND, [@s.pos, @s[1]] ]
- when @s.scan(OR_PATTERN)
- @q.push [ :OR, [@s.pos, @s[1]] ]
- when @s.scan(SPACES_PATTERN)
- @q.push [ :SPACES, [@s.pos, @s[1]] ]
- when @s.scan(QUESTION_PATTERN)
- @q.push [ :QUESTION, [@s.pos, nil] ]
- when @s.scan(COMMA_PATTERN)
- @q.push [ :COMMA, [@s.pos, ','] ]
- when @s.scan(LPAREN_PATTERN)
- @q.push [ :LPAREN, [@s.pos, '('] ]
- when @s.scan(RPAREN_PATTERN)
- @q.push [ :RPAREN, [@s.pos, ')'] ]
- when @s.scan(ELSE_PATTERN)
- @q.push [ :ELSE, [@s.pos, nil] ]
- when @s.scan(ACTUAL_COMMENT_PATTERN)
- @q.push [ :ACTUAL_COMMENT, [@s.pos, @s[1], @s[2]] ] if @preserve_comment
- when @s.scan(BEGIN_END_PATTERN)
- @q.push [ @s[2].intern, [@s.pos, nil] ]
- when @s.scan(CONDITIONAL_PATTERN)
- @q.push [ @s[2].intern, [@s.pos, @s[3]] ]
- when @s.scan(EMBED_VARIABLE_PATTERN)
- @q.push [ :EMBED_VARIABLE, [@s.pos, @s[2]] ]
- when @s.scan(PAREN_BIND_VARIABLE_PATTERN)
- @q.push [ :PAREN_BIND_VARIABLE, [@s.pos, @s[2]] ]
- when @s.scan(BIND_VARIABLE_PATTERN)
- @q.push [ :BIND_VARIABLE, [@s.pos, @s[2]] ]
- when @s.scan(STRING_LITERAL_PATTERN)
- @q.push [ :STRING_LITERAL, [@s.pos, @s[1]] ]
- when @s.scan(SPLIT_TOKEN_PATTERN)
- @q.push [ :IDENT, [@s.pos, @s[1]] ]
- when @s.scan(UNMATCHED_COMMENT_START_PATTERN) ## unmatched comment start, '/*','#*'
- raise Racc::ParseError, "unmatched comment. line:[#{line_no(@s.pos)}], str:[#{@s.rest}]"
- when @s.scan(LITERAL_PATTERN) ## other string token
- @q.push [ :IDENT, [@s.pos, @s[1]] ]
- when @s.scan(SEMICOLON_AT_INPUT_END_PATTERN)
- #drop semicolon at input end
- else
- raise Racc::ParseError, "syntax error at or near line:[#{line_no(@s.pos)}], str:[#{@s.rest}]"
- end
- end
-end
-
-
-## override racc's default on_error method
-def on_error(t, v, vstack)
- ## cursor in value-stack is an array of two items,
- ## that have position value as 0th item. like [731, "ctx[:limit] "]
- cursor = vstack.find do |tokens|
- tokens.size == 2 and tokens[0].kind_of?(Fixnum)
- end
- pos = cursor[0]
- line = line_no(pos)
- rest = @s.string[pos .. -1]
- raise Racc::ParseError, "syntax error at or near line:[#{line}], str:[#{rest}]"
-end
-
-
-def line_no(pos)
- lines = 0
- scanned = @s.string[0..(pos)]
- scanned.each_line { lines += 1 }
- lines
-end
-...end twowaysql.y/module_eval...
-##### State transition tables begin ###
-
-racc_action_table = [
- 8, 36, 9, 37, 12, 13, 10, 11, 14, 15,
- 16, 17, 18, 19, 22, 23, 24, 8, 38, 9,
- 3, 12, 13, 10, 11, 14, 15, 16, 17, 18,
- 19, 22, 23, 24, 8, 25, 9, 40, 12, 13,
- 10, 11, 14, 15, 16, 17, 18, 19, 22, 23,
- 24, 8, 45, 9, 46, 12, 13, 10, 11, 14,
- 15, 16, 17, 18, 19, 22, 23, 24, 8, nil,
- 9, nil, 12, 13, 10, 11, 14, 15, 16, 17,
- 18, 19, 22, 23, 24, 35, 33, 34, 31, 32,
- 44, 43, 31, 32 ]
-
-racc_action_check = [
- 2, 24, 2, 24, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 26, 26, 26,
- 1, 26, 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 27, 3, 27, 28, 27, 27,
- 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
- 27, 41, 37, 41, 39, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41, 42, nil,
- 42, nil, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 22, 22, 22, 9, 9,
- 34, 34, 40, 40 ]
-
-racc_action_pointer = [
- nil, 20, -2, 35, nil, nil, nil, nil, nil, 82,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, 77, nil, -7, nil, 15, 32, 32, nil,
- nil, nil, nil, nil, 82, nil, nil, 44, nil, 51,
- 86, 49, 66, nil, nil, nil, nil, nil ]
-
-racc_action_default = [
- -2, -35, -1, -35, -3, -4, -5, -6, -2, -2,
- -16, -17, -18, -19, -20, -21, -22, -23, -24, -25,
- -26, -27, -35, -32, -35, 48, -35, -13, -10, -11,
- -12, -2, -2, -28, -35, -30, -33, -35, -7, -35,
- -2, -14, -15, -29, -31, -34, -8, -9 ]
-
-racc_goto_table = [
- 2, 1, 28, 39, nil, nil, nil, nil, 26, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 41, 42, 47 ]
-
-racc_goto_check = [
- 2, 1, 7, 8, nil, nil, nil, nil, 2, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
- nil, 2, 2, 7 ]
-
-racc_goto_pointer = [
- nil, 1, 0, nil, nil, nil, nil, -7, -25, nil,
- nil, nil, nil ]
-
-racc_goto_default = [
- nil, nil, 27, 4, 5, 6, 7, nil, nil, 29,
- 30, 20, 21 ]
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 20, :_reduce_1,
- 0, 21, :_reduce_2,
- 2, 21, :_reduce_3,
- 1, 22, :_reduce_none,
- 1, 22, :_reduce_none,
- 1, 22, :_reduce_none,
- 3, 25, :_reduce_7,
- 4, 24, :_reduce_8,
- 2, 27, :_reduce_9,
- 0, 27, :_reduce_10,
- 1, 26, :_reduce_none,
- 1, 26, :_reduce_none,
- 1, 26, :_reduce_none,
- 2, 28, :_reduce_14,
- 2, 29, :_reduce_15,
- 1, 23, :_reduce_16,
- 1, 23, :_reduce_17,
- 1, 23, :_reduce_18,
- 1, 23, :_reduce_19,
- 1, 23, :_reduce_20,
- 1, 23, :_reduce_21,
- 1, 23, :_reduce_22,
- 1, 23, :_reduce_23,
- 1, 23, :_reduce_24,
- 1, 23, :_reduce_25,
- 1, 23, :_reduce_none,
- 1, 23, :_reduce_none,
- 2, 30, :_reduce_28,
- 3, 30, :_reduce_29,
- 2, 30, :_reduce_30,
- 3, 30, :_reduce_31,
- 1, 30, :_reduce_32,
- 2, 31, :_reduce_33,
- 3, 31, :_reduce_34 ]
-
-racc_reduce_n = 35
-
-racc_shift_n = 48
-
-racc_token_table = {
- false => 0,
- :error => 1,
- :BEGIN => 2,
- :END => 3,
- :IF => 4,
- :ELSE => 5,
- :AND => 6,
- :OR => 7,
- :IDENT => 8,
- :STRING_LITERAL => 9,
- :SPACES => 10,
- :COMMA => 11,
- :LPAREN => 12,
- :RPAREN => 13,
- :QUESTION => 14,
- :ACTUAL_COMMENT => 15,
- :BIND_VARIABLE => 16,
- :PAREN_BIND_VARIABLE => 17,
- :EMBED_VARIABLE => 18 }
-
-racc_nt_base = 19
-
-racc_use_result_var = true
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
- "$end",
- "error",
- "BEGIN",
- "END",
- "IF",
- "ELSE",
- "AND",
- "OR",
- "IDENT",
- "STRING_LITERAL",
- "SPACES",
- "COMMA",
- "LPAREN",
- "RPAREN",
- "QUESTION",
- "ACTUAL_COMMENT",
- "BIND_VARIABLE",
- "PAREN_BIND_VARIABLE",
- "EMBED_VARIABLE",
- "$start",
- "sql",
- "stmt_list",
- "stmt",
- "primary",
- "if_stmt",
- "begin_stmt",
- "sub_stmt",
- "else_stmt",
- "and_stmt",
- "or_stmt",
- "bind_var",
- "embed_var" ]
-
-Racc_debug_parser = false
-
-##### State transition tables end #####
-
-# reduce 0 omitted
-
-module_eval(<<'.,.,', 'twowaysql.y', 20)
- def _reduce_1(val, _values, result)
- result = RootNode.new( val[0] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 25)
- def _reduce_2(val, _values, result)
- result = []
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 29)
- def _reduce_3(val, _values, result)
- result.push val[1]
-
- result
- end
-.,.,
-
-# reduce 4 omitted
-
-# reduce 5 omitted
-
-# reduce 6 omitted
-
-module_eval(<<'.,.,', 'twowaysql.y', 38)
- def _reduce_7(val, _values, result)
- result = BeginNode.new( val[1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 43)
- def _reduce_8(val, _values, result)
- result = IfNode.new( val[0][1], val[1], val[2] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 48)
- def _reduce_9(val, _values, result)
- result = val[1]
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 52)
- def _reduce_10(val, _values, result)
- result = nil
-
- result
- end
-.,.,
-
-# reduce 11 omitted
-
-# reduce 12 omitted
-
-# reduce 13 omitted
-
-module_eval(<<'.,.,', 'twowaysql.y', 61)
- def _reduce_14(val, _values, result)
- result = SubStatementNode.new( val[0][1], val[1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 66)
- def _reduce_15(val, _values, result)
- result = SubStatementNode.new( val[0][1], val[1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 71)
- def _reduce_16(val, _values, result)
- result = LiteralNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 75)
- def _reduce_17(val, _values, result)
- result = LiteralNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 79)
- def _reduce_18(val, _values, result)
- result = LiteralNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 83)
- def _reduce_19(val, _values, result)
- result = LiteralNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 87)
- def _reduce_20(val, _values, result)
- result = WhiteSpaceNode.new( val[0][1], @preserve_space )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 91)
- def _reduce_21(val, _values, result)
- result = LiteralNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 95)
- def _reduce_22(val, _values, result)
- result = LiteralNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 99)
- def _reduce_23(val, _values, result)
- result = LiteralNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 103)
- def _reduce_24(val, _values, result)
- @num_questions += 1
- result = QuestionNode.new( @num_questions )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 108)
- def _reduce_25(val, _values, result)
- result = ActualCommentNode.new( val[0][1] , val[0][2] )
-
- result
- end
-.,.,
-
-# reduce 26 omitted
-
-# reduce 27 omitted
-
-module_eval(<<'.,.,', 'twowaysql.y', 115)
- def _reduce_28(val, _values, result)
- result = BindVariableNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 119)
- def _reduce_29(val, _values, result)
- result = BindVariableNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 123)
- def _reduce_30(val, _values, result)
- result = BindVariableNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 127)
- def _reduce_31(val, _values, result)
- result = BindVariableNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 131)
- def _reduce_32(val, _values, result)
- result = ParenBindVariableNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 136)
- def _reduce_33(val, _values, result)
- result = EmbedVariableNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-module_eval(<<'.,.,', 'twowaysql.y', 140)
- def _reduce_34(val, _values, result)
- result = EmbedVariableNode.new( val[0][1] )
-
- result
- end
-.,.,
-
-def _reduce_none(val, _values, result)
- val[0]
-end
-
- end # class Parser
-end # module TwoWaySQL
diff --git a/test/racc/scandata/brace b/test/racc/scandata/brace
deleted file mode 100644
index f6c843853e..0000000000
--- a/test/racc/scandata/brace
+++ /dev/null
@@ -1,7 +0,0 @@
-{ {
- } { } {
- { { { } } }
- { { { {} } } }
- {} {} {}
- }
-}
diff --git a/test/racc/scandata/gvar b/test/racc/scandata/gvar
deleted file mode 100644
index 50528ce97b..0000000000
--- a/test/racc/scandata/gvar
+++ /dev/null
@@ -1 +0,0 @@
-{ $' $" $& $-a $/ $\ $( $1 $2 $3 $? $-i }
diff --git a/test/racc/scandata/normal b/test/racc/scandata/normal
deleted file mode 100644
index e705131536..0000000000
--- a/test/racc/scandata/normal
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- # comment
- result = "string".match(/regexp/)[0]
-}
diff --git a/test/racc/scandata/percent b/test/racc/scandata/percent
deleted file mode 100644
index fded9a385c..0000000000
--- a/test/racc/scandata/percent
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- 3 % 5 # mod
- 3%5 # mod
- 3% 5 # mod
- i % 5 # mod
- i%5 # mod
- i% 5 # mod
- call %{str} # string
- call(%{str}) # string
- %q{string} # string
- %Q{string} # string
- %r{string} # string
- %w(array) # array
- %x{array} # command string
- %{string} # string
- %_string_ # string
- %/string/ # regexp
-}
diff --git a/test/racc/scandata/slash b/test/racc/scandata/slash
deleted file mode 100644
index 190135b3bd..0000000000
--- a/test/racc/scandata/slash
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- # here's many '/'s
- i = 5/1 # div
- re = /regex/ # regexp
- i /= 5 # div
- result = 5 / 1 # div
- result = 5/ 1 # div
- call(/regex/) # regexp
- call /regex/ # regexp
-}
diff --git a/test/racc/src.intp b/test/racc/src.intp
deleted file mode 100644
index 4d2460e8ed..0000000000
--- a/test/racc/src.intp
+++ /dev/null
@@ -1,34 +0,0 @@
-def assert( no, cond )
- if cond then
- else
- raise( 'assert ' + to_s(no) + ' failed' )
- end
-end
-
-assert( 1, concat(concat(concat('str=', 'a'), "b"), 'c') == 'str=abc' )
-assert( 2, 'operator' + ' ok' == 'operator ok' )
-assert( 3, 1 + 1 == 2 )
-assert( 4, 4 * 1 + 10 * 1 == 14 )
-
-if true then
- assert( 5, true )
-else
- assert( 6, false )
-end
-
-i = 1
-while i == 1 do
- i = false
-end
-assert( 7, i == false )
-assert( 8, nil == nil )
-
-def func
- assert( 9, true )
-end
-func
-
-def argfunc( str )
- assert( 10, str == 'ok' )
-end
-argfunc 'ok'
diff --git a/test/racc/start.y b/test/racc/start.y
deleted file mode 100644
index 86296899b8..0000000000
--- a/test/racc/start.y
+++ /dev/null
@@ -1,20 +0,0 @@
-class S
-
-start st
-
-rule
-
-n: D { result = 'no' }
-st : A B C n { result = 'ok' }
-
-end
-
----- inner
-
- def parse
- do_parse
- end
-
----- footer
-
-S.new.parse == 'ok' or raise 'start stmt not worked'
diff --git a/test/racc/test_chk_y.rb b/test/racc/test_chk_y.rb
deleted file mode 100644
index 883737c45f..0000000000
--- a/test/racc/test_chk_y.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require File.expand_path(File.join(__dir__, 'case'))
-
-module Racc
- class TestChkY < TestCase
- def setup
- super
- file = File.join(ASSET_DIR, 'chk.y')
- @debug_flags = Racc::DebugFlags.parse_option_string('o')
- parser = Racc::GrammarFileParser.new(@debug_flags)
- @result = parser.parse(File.read(file), File.basename(file))
- @states = Racc::States.new(@result.grammar).nfa
- @states.dfa
- end
-
- def test_compile_chk_y
- generator = Racc::ParserFileGenerator.new(@states, @result.params.dup)
-
- # it generates valid ruby
- assert Module.new {
- self.instance_eval(generator.generate_parser, __FILE__, __LINE__)
- }
-
- grammar = @states.grammar
-
- assert_equal 0, @states.n_srconflicts
- assert_equal 0, @states.n_rrconflicts
- assert_equal 0, grammar.n_useless_nonterminals
- assert_equal 0, grammar.n_useless_rules
- assert_nil grammar.n_expected_srconflicts
- end
-
- def test_compile_chk_y_line_convert
- params = @result.params.dup
- params.convert_line_all = true
-
- generator = Racc::ParserFileGenerator.new(@states, @result.params.dup)
-
- # it generates valid ruby
- assert Module.new {
- self.instance_eval(generator.generate_parser, __FILE__, __LINE__)
- }
-
- grammar = @states.grammar
-
- assert_equal 0, @states.n_srconflicts
- assert_equal 0, @states.n_rrconflicts
- assert_equal 0, grammar.n_useless_nonterminals
- assert_equal 0, grammar.n_useless_rules
- assert_nil grammar.n_expected_srconflicts
- end
- end
-end
diff --git a/test/racc/test_grammar_file_parser.rb b/test/racc/test_grammar_file_parser.rb
deleted file mode 100644
index 8f6e090cb2..0000000000
--- a/test/racc/test_grammar_file_parser.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require File.expand_path(File.join(__dir__, 'case'))
-
-module Racc
- class TestGrammarFileParser < TestCase
- def test_parse
- file = File.join(ASSET_DIR, 'yyerr.y')
-
- debug_flags = Racc::DebugFlags.parse_option_string('o')
- assert debug_flags.status_logging
-
- parser = Racc::GrammarFileParser.new(debug_flags)
- parser.parse(File.read(file), File.basename(file))
- end
- end
-end
diff --git a/test/racc/test_racc_command.rb b/test/racc/test_racc_command.rb
deleted file mode 100644
index 5bfebf150b..0000000000
--- a/test/racc/test_racc_command.rb
+++ /dev/null
@@ -1,339 +0,0 @@
-require File.expand_path(File.join(__dir__, 'case'))
-
-module Racc
- class TestRaccCommand < TestCase
- def test_syntax_y
- assert_compile 'syntax.y', '-v'
- assert_debugfile 'syntax.y', [0,0,0,0,0]
- end
-
- def test_percent_y
- assert_compile 'percent.y'
- assert_debugfile 'percent.y', []
- assert_exec 'percent.y'
- end
-
- def test_scan_y
- assert_compile 'scan.y'
- assert_debugfile 'scan.y', []
- assert_exec 'scan.y'
- end
-
- def test_newsyn_y
- assert_compile 'newsyn.y'
- assert_debugfile 'newsyn.y', []
- end
-
- def test_normal_y
- assert_compile 'normal.y'
- assert_debugfile 'normal.y', []
-
- assert_compile 'normal.y', '-vg'
- assert_debugfile 'normal.y', []
- end
-
- def test_chk_y
- assert_compile 'chk.y', '-vg'
- assert_debugfile 'chk.y', []
- assert_exec 'chk.y'
-
- assert_compile 'chk.y', '--line-convert-all'
- assert_debugfile 'chk.y', []
- assert_exec 'chk.y'
- end
-
- def test_echk_y
- assert_compile 'echk.y', '-E'
- assert_debugfile 'echk.y', []
- assert_exec 'echk.y'
- end
-
- def test_err_y
- assert_compile 'err.y'
- assert_debugfile 'err.y', []
- assert_exec 'err.y'
- end
-
- def test_mailp_y
- assert_compile 'mailp.y'
- assert_debugfile 'mailp.y', []
- end
-
- def test_conf_y
- assert_compile 'conf.y', '-v'
- assert_debugfile 'conf.y', [4,1,1,2]
- end
-
- def test_rrconf_y
- assert_compile 'rrconf.y'
- assert_debugfile 'rrconf.y', [1,1,0,0]
- end
-
- def test_useless_y
- assert_compile 'useless.y'
- assert_debugfile 'useless.y', [0,0,1,2]
- end
-
- def test_opt_y
- assert_compile 'opt.y'
- assert_debugfile 'opt.y', []
- assert_exec 'opt.y'
- end
-
- def test_yyerr_y
- assert_compile 'yyerr.y'
- assert_debugfile 'yyerr.y', []
- assert_exec 'yyerr.y'
- end
-
- def test_recv_y
- assert_compile 'recv.y'
- assert_debugfile 'recv.y', [5,10,1,4]
- end
-
- def test_ichk_y
- assert_compile 'ichk.y'
- assert_debugfile 'ichk.y', []
- assert_exec 'ichk.y'
- end
-
- def test_intp_y
- assert_compile 'intp.y'
- assert_debugfile 'intp.y', []
- assert_exec 'intp.y'
- end
-
- def test_expect_y
- assert_compile 'expect.y'
- assert_debugfile 'expect.y', [1,0,0,0,1]
- end
-
- def test_nullbug1_y
- assert_compile 'nullbug1.y'
- assert_debugfile 'nullbug1.y', [0,0,0,0]
- end
-
- def test_nullbug2_y
- assert_compile 'nullbug2.y'
- assert_debugfile 'nullbug2.y', [0,0,0,0]
- end
-
- def test_firstline_y
- assert_compile 'firstline.y'
- assert_debugfile 'firstline.y', []
- end
-
- def test_nonass_y
- assert_compile 'nonass.y'
- assert_debugfile 'nonass.y', []
- assert_exec 'nonass.y'
- end
-
- def test_digraph_y
- assert_compile 'digraph.y'
- assert_debugfile 'digraph.y', []
- assert_exec 'digraph.y'
- end
-
- def test_noend_y
- assert_compile 'noend.y'
- assert_debugfile 'noend.y', []
- end
-
- def test_norule_y
- assert_raise(Test::Unit::AssertionFailedError) {
- assert_compile 'norule.y'
- }
- end
-
- def test_unterm_y
- assert_raise(Test::Unit::AssertionFailedError) {
- assert_compile 'unterm.y'
- }
- end
-
- # Regression test for a problem where error recovery at EOF would cause
- # a Racc-generated parser to go into an infinite loop (on some grammars)
- def test_error_recovery_y
- assert_compile 'error_recovery.y'
- Timeout.timeout(10) do
- assert_exec 'error_recovery.y'
- end
- end
-
- # .y files from `parser` gem
-
- def test_ruby18
- assert_compile 'ruby18.y', [], timeout: 60
- assert_debugfile 'ruby18.y', []
- assert_output_unchanged 'ruby18.y'
- end
-
- def test_ruby22
- assert_compile 'ruby22.y', [], timeout: 60
- assert_debugfile 'ruby22.y', []
- assert_output_unchanged 'ruby22.y'
- end
-
- # .y file from csspool gem
-
- def test_csspool
- assert_compile 'csspool.y'
- assert_debugfile 'csspool.y', [5, 3]
- assert_output_unchanged 'csspool.y'
- end
-
- # .y file from opal gem
-
- def test_opal
- assert_compile 'opal.y', [], timeout: 60
- assert_debugfile 'opal.y', []
- assert_output_unchanged 'opal.y'
- end
-
- # .y file from journey gem
-
- def test_journey
- assert_compile 'journey.y'
- assert_debugfile 'journey.y', []
- assert_output_unchanged 'journey.y'
- end
-
- # .y file from nokogiri gem
-
- def test_nokogiri_css
- assert_compile 'nokogiri-css.y'
- assert_debugfile 'nokogiri-css.y', [0, 1]
- assert_output_unchanged 'nokogiri-css.y'
- end
-
- # .y file from edtf-ruby gem
-
- def test_edtf
- assert_compile 'edtf.y'
- assert_debugfile 'edtf.y', [0, 0, 0, 0, 0]
- assert_output_unchanged 'edtf.y'
- end
-
- # .y file from namae gem
-
- def test_namae
- assert_compile 'namae.y'
- assert_debugfile 'namae.y', [0, 0, 0, 0, 0]
- assert_output_unchanged 'namae.y'
- end
-
- # .y file from liquor gem
-
- def test_liquor
- assert_compile 'liquor.y'
- assert_debugfile 'liquor.y', [0, 0, 0, 0, 15]
- assert_output_unchanged 'liquor.y'
- end
-
- # .y file from nasl gem
-
- def test_nasl
- assert_compile 'nasl.y'
- assert_debugfile 'nasl.y', [0, 0, 0, 0, 1]
- assert_output_unchanged 'nasl.y'
- end
-
- # .y file from riml gem
-
- def test_riml
- assert_compile 'riml.y'
- assert_debugfile 'riml.y', [289, 0, 0, 0]
- assert_output_unchanged 'riml.y'
- end
-
- # .y file from ruby-php-serialization gem
-
- def test_php_serialization
- assert_compile 'php_serialization.y'
- assert_debugfile 'php_serialization.y', [0, 0, 0, 0]
- assert_output_unchanged 'php_serialization.y'
- end
-
- # .y file from huia language implementation
-
- def test_huia
- assert_compile 'huia.y'
- assert_debugfile 'huia.y', [285, 0, 0, 0]
- assert_output_unchanged 'huia.y'
- end
-
- # .y file from cast gem
-
- def test_cast
- assert_compile 'cast.y'
- assert_debugfile 'cast.y', [0, 0, 0, 0, 1]
- assert_output_unchanged 'cast.y'
- end
-
- # .y file from cadenza gem
-
- def test_cadenza
- assert_compile 'cadenza.y'
- assert_debugfile 'cadenza.y', [0, 0, 0, 0, 37]
- assert_output_unchanged 'cadenza.y'
- end
-
- # .y file from mediacloth gem
-
- def test_mediacloth
- assert_compile 'mediacloth.y'
- assert_debugfile 'mediacloth.y', [0, 0, 0, 0]
- assert_output_unchanged 'mediacloth.y'
- end
-
- # .y file from twowaysql gem
-
- def test_twowaysql
- assert_compile 'twowaysql.y'
- assert_debugfile 'twowaysql.y', [4, 0, 0, 0]
- assert_output_unchanged 'twowaysql.y'
- end
-
- # .y file from machete gem
-
- def test_machete
- assert_compile 'machete.y'
- assert_debugfile 'machete.y', [0, 0, 0, 0]
- assert_output_unchanged 'machete.y'
- end
-
- # .y file from mof gem
-
- def test_mof
- assert_compile 'mof.y'
- assert_debugfile 'mof.y', [7, 4, 0, 0]
- assert_output_unchanged 'mof.y'
- end
-
- # .y file from tp_plus gem
-
- def test_tp_plus
- assert_compile 'tp_plus.y'
- assert_debugfile 'tp_plus.y', [21, 0, 0, 0]
- assert_output_unchanged 'tp_plus.y'
- end
-
- def test_ifelse
- omit if RUBY_PLATFORM =~ /java/
-
- stderr = nil
- racc "-o#{@TAB_DIR}/ifelse", "#{ASSET_DIR}/ifelse.y", stdout_filter: ->(s) { stderr = s }
- stderr = stderr.lines[1..-1].join if RUBY_PLATFORM.match?(/java/)
- assert_equal(<<~STDERR, stderr)
- 1 useless nonterminals:
- dummy
- 2 useless rules:
- #4 (dummy)
- #5 (dummy)
- 1 shift/reduce conflicts
- Turn on logging with "-v" and check ".output" file for details
- STDERR
- end
- end
-end
diff --git a/test/racc/test_scan_y.rb b/test/racc/test_scan_y.rb
deleted file mode 100644
index fcd7e53c99..0000000000
--- a/test/racc/test_scan_y.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-require File.expand_path(File.join(__dir__, 'case'))
-
-module Racc
- class TestScanY < TestCase
- def setup
- super
- file = File.join(ASSET_DIR, 'scan.y')
- @debug_flags = Racc::DebugFlags.parse_option_string('o')
- parser = Racc::GrammarFileParser.new(@debug_flags)
- @result = parser.parse(File.read(file), File.basename(file))
- @states = Racc::States.new(@result.grammar).nfa
- @states.dfa
- end
-
- def test_compile
- generator = Racc::ParserFileGenerator.new(@states, @result.params.dup)
-
- # it generates valid ruby
- assert Module.new {
- self.class_eval(generator.generate_parser)
- }
-
- grammar = @states.grammar
-
- assert_equal 0, @states.n_srconflicts
- assert_equal 0, @states.n_rrconflicts
- assert_equal 0, grammar.n_useless_nonterminals
- assert_equal 0, grammar.n_useless_rules
- assert_nil grammar.n_expected_srconflicts
- end
-
- def test_compile_line_convert
- params = @result.params.dup
- params.convert_line_all = true
-
- generator = Racc::ParserFileGenerator.new(@states, @result.params.dup)
-
- # it generates valid ruby
- assert Module.new {
- self.class_eval(generator.generate_parser)
- }
-
- grammar = @states.grammar
-
- assert_equal 0, @states.n_srconflicts
- assert_equal 0, @states.n_rrconflicts
- assert_equal 0, grammar.n_useless_nonterminals
- assert_equal 0, grammar.n_useless_rules
- assert_nil grammar.n_expected_srconflicts
- end
- end
-end
diff --git a/test/racc/testscanner.rb b/test/racc/testscanner.rb
deleted file mode 100644
index d7877511ec..0000000000
--- a/test/racc/testscanner.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# racc scanner tester
-#
-
-require 'racc/raccs'
-
-
-class ScanError < StandardError; end
-
-def testdata( dir, argv )
- if argv.empty? then
- Dir.glob( dir + '/*' ) -
- Dir.glob( dir + '/*.swp' ) -
- [ dir + '/CVS' ]
- else
- argv.collect {|i| dir + '/' + i }
- end
-end
-
-
-if ARGV.delete '--print' then
- $raccs_print_type = true
- printonly = true
-else
- printonly = false
-end
-
-testdata( File.dirname($0) + '/scandata', ARGV ).each do |file|
- $stderr.print File.basename(file) + ': '
- begin
- ok = File.read(file)
- s = Racc::GrammarFileScanner.new( ok )
- sym, (val, _lineno) = s.scan
- if printonly then
- $stderr.puts
- $stderr.puts val
- next
- end
-
- val = '{' + val + "}\n"
- sym == :ACTION or raise ScanError, 'is not action!'
- val == ok or raise ScanError, "\n>>>\n#{ok}----\n#{val}<<<"
-
- $stderr.puts 'ok'
- rescue => err
- $stderr.puts 'fail (' + err.type.to_s + ')'
- $stderr.puts err.message
- $stderr.puts err.backtrace
- $stderr.puts
- end
-end
diff --git a/test/rdoc/support/test_case.rb b/test/rdoc/support/test_case.rb
index 36009111e2..d98dbe0d7b 100644
--- a/test/rdoc/support/test_case.rb
+++ b/test/rdoc/support/test_case.rb
@@ -37,7 +37,8 @@ class RDoc::TestCase < Test::Unit::TestCase
super
@orig_home = ENV["HOME"]
- ENV["HOME"] = Dir.tmpdir
+ FileUtils.mkdir_p(@test_home = Dir.mktmpdir("test_rdoc_"))
+ ENV["HOME"] = @test_home
@top_level = nil
@@ -64,6 +65,7 @@ class RDoc::TestCase < Test::Unit::TestCase
def teardown
ENV["HOME"] = @orig_home if defined?(@orig_home)
+ defined?(@test_home) and FileUtils.rm_rf @test_home
super
end
diff --git a/test/rdoc/support/text_formatter_test_case.rb b/test/rdoc/support/text_formatter_test_case.rb
index 22a762b5f0..e359028a29 100644
--- a/test/rdoc/support/text_formatter_test_case.rb
+++ b/test/rdoc/support/text_formatter_test_case.rb
@@ -112,4 +112,3 @@ class RDoc::Markup::TextFormatterTestCase < RDoc::Markup::FormatterTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_any_method.rb b/test/rdoc/test_rdoc_any_method.rb
index 6915b466f0..b11c15420c 100644
--- a/test/rdoc/test_rdoc_any_method.rb
+++ b/test/rdoc/test_rdoc_any_method.rb
@@ -69,6 +69,20 @@ each_line(foo)
assert_equal 'C1::m', @c1.method_list.first.full_name
end
+ def test_has_call_seq?
+ m = RDoc::AnyMethod.new nil, "each_line"
+ m2 = RDoc::AnyMethod.new nil, "each"
+ assert_equal false, m.has_call_seq?
+ m.call_seq = "each_line()"
+ assert_equal true, m.has_call_seq?
+
+ m = RDoc::AnyMethod.new nil, "each_line"
+ m.is_alias_for = m2
+ assert_equal false, m.has_call_seq?
+ m2.call_seq = "each_line()"
+ assert_equal true, m.has_call_seq?
+ end
+
def test_is_alias_for
assert_equal @c2_b, @c2_a.is_alias_for
@@ -515,6 +529,30 @@ method(a, b) { |c, d| ... }
assert_equal 'C1', @c1.method_list.last.parent_name
end
+ def test_skip_description?
+ m = RDoc::AnyMethod.new nil, "each_line"
+ m2 = RDoc::AnyMethod.new nil, "each"
+ assert_equal false, m.skip_description?
+ assert_equal false, m2.skip_description?
+
+ m.is_alias_for = m2
+ m2.aliases << m
+ assert_equal false, m.skip_description?
+ assert_equal false, m2.skip_description?
+
+ m2.call_seq = "each()"
+ assert_equal true, m.skip_description?
+ assert_equal false, m2.skip_description?
+
+ m2.call_seq = "each_line()"
+ assert_equal false, m.skip_description?
+ assert_equal true, m2.skip_description?
+
+ m2.call_seq = "each()\neach_line()"
+ assert_equal false, m.skip_description?
+ assert_equal false, m2.skip_description?
+ end
+
def test_store_equals
loaded = Marshal.load Marshal.dump(@c1.method_list.last)
diff --git a/test/rdoc/test_rdoc_comment.rb b/test/rdoc/test_rdoc_comment.rb
index d3c16bceca..28e8cf76b4 100644
--- a/test/rdoc/test_rdoc_comment.rb
+++ b/test/rdoc/test_rdoc_comment.rb
@@ -206,6 +206,15 @@ lines, one line per element. Lines are assumed to be separated by _sep_.
assert_equal expected, comment.text
end
+ def test_extract_call_linear_performance
+ pre = ->(n) {[n, RDoc::Comment.new("\n"*n + 'call-seq:' + 'a'*n)]}
+ method_obj = RDoc::AnyMethod.new nil, 'blah'
+ assert_linear_performance((2..5).map {|i| 10**i}, pre: pre) do |n, comment|
+ comment.extract_call_seq method_obj
+ assert_equal n, method_obj.call_seq.size
+ end
+ end
+
def test_force_encoding
@comment = RDoc::Encoding.change_encoding @comment, Encoding::UTF_8
diff --git a/test/rdoc/test_rdoc_context.rb b/test/rdoc/test_rdoc_context.rb
index 85665599fb..c4de04e083 100644
--- a/test/rdoc/test_rdoc_context.rb
+++ b/test/rdoc/test_rdoc_context.rb
@@ -927,6 +927,12 @@ class TestRDocContext < XrefTestCase
assert_equal :private, @c6.find_method_named('priv6').visibility
assert_equal :protected, @c6.find_method_named('prot6').visibility
assert_equal :public, @c6.find_method_named('pub6').visibility
+ assert_equal :public, @c6.find_method_named('s_pub1').visibility
+ assert_equal :public, @c6.find_method_named('s_pub2').visibility
+ assert_equal :public, @c6.find_method_named('s_pub3').visibility
+ assert_equal :public, @c6.find_method_named('s_pub4').visibility
+ assert_equal :private, @c6.find_method_named('s_priv1').visibility
+ assert_equal :protected, @c6.find_method_named('s_prot1').visibility
end
def util_visibilities
diff --git a/test/rdoc/test_rdoc_context_section.rb b/test/rdoc/test_rdoc_context_section.rb
index 24c68c49dd..6834cccafb 100644
--- a/test/rdoc/test_rdoc_context_section.rb
+++ b/test/rdoc/test_rdoc_context_section.rb
@@ -144,4 +144,3 @@ class TestRDocContextSection < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_generator_darkfish.rb b/test/rdoc/test_rdoc_generator_darkfish.rb
index ae3a4c5ebf..96319bb4f7 100644
--- a/test/rdoc/test_rdoc_generator_darkfish.rb
+++ b/test/rdoc/test_rdoc_generator_darkfish.rb
@@ -73,6 +73,22 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
top_level = @store.add_file 'file.rb'
top_level.add_class @klass.class, @klass.name
@klass.add_class RDoc::NormalClass, 'Inner'
+ @klass.add_comment <<~RDOC, top_level
+ = Heading 1
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
+ == Heading 1.1
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
+ === Heading 1.1.1
+ quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+ ==== Heading 1.1.1.1
+ consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
+ == Heading 1.2
+ cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
+ == Heading 1.3
+ non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+ === Heading 1.3.1
+ etc etc...
+ RDOC
@g.generate
@@ -91,12 +107,31 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
encoding = Regexp.escape Encoding::UTF_8.name
- assert_match %r%<meta charset="#{encoding}">%, File.read('index.html')
- assert_match %r%<meta charset="#{encoding}">%, File.read('Object.html')
+ assert_match %r%<meta charset="#{encoding}">%, File.binread('index.html')
+ assert_match %r%<meta charset="#{encoding}">%, File.binread('Object.html')
- refute_match(/Ignored/, File.read('index.html'))
- summary = File.read('index.html')[%r[<summary.*Klass\.html.*</summary>.*</details>]m]
+ refute_match(/Ignored/, File.binread('index.html'))
+ summary = File.binread('index.html')[%r[<summary.*Klass\.html.*</summary>.*</details>]m]
assert_match(%r[Klass/Inner\.html".*>Inner<], summary)
+
+ klass = File.binread('Klass.html')
+ klassnav = klass[%r[<div class="nav-section">.*<div id="class-metadata">]m]
+ assert_match(
+ %r[<li>\s*<details open>\s*<summary>\s*<a href=\S+>Heading 1</a>\s*</summary>\s*<ul]m,
+ klassnav
+ )
+ assert_match(
+ %r[<li>\s*<a href=\S+>Heading 1.1.1.1</a>\s*</ul>\s*</details>\s*</li>]m,
+ klassnav
+ )
+
+ assert_match(/<h1 id="class-Klass-label-Heading\+1">Heading 1(?!\.)/,
+ klass[%r[<section class=\"description\">.*</section>]m])
+ toc = File.binread('table_of_contents.html')
+ assert_match(
+ %r[<a\s+href="Klass\.html#class-Klass-label-Heading\+1">Heading 1</a>]m,
+ toc[%r[<h2\s+id=\"classes\">.*(?=<h2\b)]m][%r[<a\s+href="Klass\.html".*(?=</li\b)]m]
+ )
end
def test_generate_page
@@ -105,15 +140,15 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
@g.generate
assert_file 'outer_rdoc.html'
assert_file 'outer/inner_rdoc.html'
- index = File.read('index.html')
+ index = File.binread('index.html')
re = %r[<summary><a href="\./outer_rdoc\.html">outer</a></summary>.*?</details>]m
assert_match(re, index)
summary = index[re]
assert_match %r[<a href="\./outer/inner_rdoc.html">inner</a>], summary
re = %r[<details open><summary><a href="\./outer_rdoc\.html">outer</a></summary>.*?</details>]m
- assert_match(re, File.read('outer_rdoc.html'))
+ assert_match(re, File.binread('outer_rdoc.html'))
re = %r[<details open><summary><a href="\.\./outer_rdoc\.html">outer</a></summary>.*?</details>]m
- assert_match(re, File.read('outer/inner_rdoc.html'))
+ assert_match(re, File.binread('outer/inner_rdoc.html'))
end
def test_generate_dry_run
@@ -233,6 +268,29 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
assert_includes method_name, '{ |%&lt;&lt;script&gt;alert(&quot;atui&quot;)&lt;/script&gt;&gt;, yield_arg| ... }'
end
+ def test_generated_filename_with_html_tag
+ filename = '"><em>should be escaped'
+ begin # in @tmpdir
+ File.write(filename, '')
+ rescue SystemCallError
+ # ", <, > chars are prohibited as filename
+ return
+ else
+ File.unlink(filename)
+ end
+ @store.add_file filename
+ doc = @store.all_files.last
+ doc.parser = RDoc::Parser::Simple
+
+ @g.generate
+
+ Dir.glob("*.html", base: @tmpdir) do |html|
+ File.binread(File.join(@tmpdir, html)).scan(/.*should be escaped.*/) do |line|
+ assert_not_include line, "<em>", html
+ end
+ end
+ end
+
def test_template_stylesheets
css = Tempfile.create(%W'hoge .css', Dir.mktmpdir('tmp', '.'))
File.write(css, '')
@@ -245,7 +303,23 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
@g.generate
assert_file base
- assert_include File.read('index.html'), %Q[href="./#{base}"]
+ assert_include File.binread('index.html'), %Q[href="./#{base}"]
+ end
+
+ def test_title
+ title = "RDoc Test".freeze
+ @options.title = title
+ @g.generate
+
+ assert_main_title(File.binread('index.html'), title)
+ end
+
+ def test_title_escape
+ title = %[<script>alert("RDoc")</script>].freeze
+ @options.title = title
+ @g.generate
+
+ assert_main_title(File.binread('index.html'), title)
end
##
@@ -271,4 +345,9 @@ class TestRDocGeneratorDarkfish < RDoc::TestCase
"#{filename} is not hard-linked"
end
+ def assert_main_title(content, title)
+ title = CGI.escapeHTML(title)
+ assert_equal(title, content[%r[<title>(.*?)<\/title>]im, 1])
+ assert_include(content[%r[<main\s[^<>]*+>\s*(.*?)</main>]im, 1], title)
+ end
end
diff --git a/test/rdoc/test_rdoc_generator_json_index.rb b/test/rdoc/test_rdoc_generator_json_index.rb
index 6b69337b45..62d1ccec95 100644
--- a/test/rdoc/test_rdoc_generator_json_index.rb
+++ b/test/rdoc/test_rdoc_generator_json_index.rb
@@ -104,8 +104,20 @@ class TestRDocGeneratorJsonIndex < RDoc::TestCase
orig_file = Pathname(File.join srcdir, 'generator/template/json_index/js/navigation.js')
generated_file = Pathname(File.join @tmpdir, 'js/navigation.js')
+ # The following assertion for the generated file's modified time randomly
+ # fails in a ppc64le environment.
+ # https://github.com/ruby/rdoc/issues/1048
+ if orig_file.mtime.inspect != generated_file.mtime.inspect &&
+ RUBY_PLATFORM =~ /powerpc64le/
+ pend <<~EOC
+ Unstable test in ppc64le.
+ <#{orig_file.mtime.inspect}> expected but was
+ <#{generated_file.mtime.inspect}>.
+ EOC
+ end
+
# This is dirty hack on JRuby
- assert orig_file.mtime.inspect == generated_file.mtime.inspect,
+ assert_equal orig_file.mtime.inspect, generated_file.mtime.inspect,
'.js files should be the same timestamp of original'
json = File.read 'js/search_index.js'
diff --git a/test/rdoc/test_rdoc_generator_markup.rb b/test/rdoc/test_rdoc_generator_markup.rb
index 5491b7c61e..7c021e432e 100644
--- a/test/rdoc/test_rdoc_generator_markup.rb
+++ b/test/rdoc/test_rdoc_generator_markup.rb
@@ -57,4 +57,3 @@ class TestRDocGeneratorMarkup < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markdown.rb b/test/rdoc/test_rdoc_markdown.rb
index ca76c34f43..31d5b068f9 100644
--- a/test/rdoc/test_rdoc_markdown.rb
+++ b/test/rdoc/test_rdoc_markdown.rb
@@ -305,6 +305,25 @@ that also extends to two lines
assert_equal expected, doc
end
+ def test_parse_definition_list_rich_label
+ doc = parse <<-MD
+`one`
+: This is a definition
+
+**two**
+: This is another definition
+ MD
+
+ expected = doc(
+ list(:NOTE,
+ item(%w[<code>one</code>],
+ para("This is a definition")),
+ item(%w[*two*],
+ para("This is another definition"))))
+
+ assert_equal expected, doc
+ end
+
def test_parse_definition_list_no
@parser.definition_lists = false
@@ -1062,6 +1081,27 @@ and an extra note.[^2]
assert_equal expected, doc
end
+ def test_gfm_table_2
+ doc = parse <<~'MD'
+ | Cmd | Returns | Meaning
+ ----- | :-----: | -------
+ |"b" | boolean | True if file1 is a block device
+ "c" | boolean | True if file1 is a character device
+ |"\|" | boolean | escaped bar \| test
+ MD
+
+ head = %w[Cmd Returns Meaning]
+ align = [nil, :center, nil]
+ body = [
+ ['"b"', 'boolean', 'True if file1 is a block device'],
+ ['"c"', 'boolean', 'True if file1 is a character device'],
+ ['"|"', 'boolean', 'escaped bar | test'],
+ ]
+ expected = doc(@RM::Table.new(head, align, body))
+
+ assert_equal expected, doc
+ end
+
def parse text
@parser.parse text
end
diff --git a/test/rdoc/test_rdoc_markup.rb b/test/rdoc/test_rdoc_markup.rb
index b9bdafab2a..4d79f8bc3f 100644
--- a/test/rdoc/test_rdoc_markup.rb
+++ b/test/rdoc/test_rdoc_markup.rb
@@ -93,4 +93,3 @@ the time
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_attribute_manager.rb b/test/rdoc/test_rdoc_markup_attribute_manager.rb
index e8ff602f96..dcae48525d 100644
--- a/test/rdoc/test_rdoc_markup_attribute_manager.rb
+++ b/test/rdoc/test_rdoc_markup_attribute_manager.rb
@@ -393,4 +393,3 @@ class TestRDocMarkupAttributeManager < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_attributes.rb b/test/rdoc/test_rdoc_markup_attributes.rb
index 0dfd72bdb6..1ab408d801 100644
--- a/test/rdoc/test_rdoc_markup_attributes.rb
+++ b/test/rdoc/test_rdoc_markup_attributes.rb
@@ -37,4 +37,3 @@ class TestRDocMarkupAttributes < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_document.rb b/test/rdoc/test_rdoc_markup_document.rb
index 3db834b85d..e4f3b9daf1 100644
--- a/test/rdoc/test_rdoc_markup_document.rb
+++ b/test/rdoc/test_rdoc_markup_document.rb
@@ -205,4 +205,3 @@ class TestRDocMarkupDocument < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_formatter.rb b/test/rdoc/test_rdoc_markup_formatter.rb
index 8702db379d..af19d832ca 100644
--- a/test/rdoc/test_rdoc_markup_formatter.rb
+++ b/test/rdoc/test_rdoc_markup_formatter.rb
@@ -104,6 +104,12 @@ class TestRDocMarkupFormatter < RDoc::TestCase
formatted = document.accept @to
assert_equal '<{foo}[rdoc-label:bar]>.', formatted
+
+ document = doc(para('<tt>{abc}</tt>: {foo}[rdoc-label:bar].'))
+
+ formatted = document.accept @to
+
+ assert_equal '<code>{abc}</code>: <{foo}[rdoc-label:bar]>.', formatted
end
def test_parse_url
diff --git a/test/rdoc/test_rdoc_markup_hard_break.rb b/test/rdoc/test_rdoc_markup_hard_break.rb
index adebfdc311..ac67c68d10 100644
--- a/test/rdoc/test_rdoc_markup_hard_break.rb
+++ b/test/rdoc/test_rdoc_markup_hard_break.rb
@@ -29,4 +29,3 @@ class TestRDocMarkupHardBreak < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_heading.rb b/test/rdoc/test_rdoc_markup_heading.rb
index 05a8e005ba..de92af91a0 100644
--- a/test/rdoc/test_rdoc_markup_heading.rb
+++ b/test/rdoc/test_rdoc_markup_heading.rb
@@ -27,4 +27,3 @@ class TestRDocMarkupHeading < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_include.rb b/test/rdoc/test_rdoc_markup_include.rb
index 9126526b73..b3e9b845c3 100644
--- a/test/rdoc/test_rdoc_markup_include.rb
+++ b/test/rdoc/test_rdoc_markup_include.rb
@@ -17,4 +17,3 @@ class TestRDocMarkupInclude < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_indented_paragraph.rb b/test/rdoc/test_rdoc_markup_indented_paragraph.rb
index 7b5758998f..d2a9cbe5ca 100644
--- a/test/rdoc/test_rdoc_markup_indented_paragraph.rb
+++ b/test/rdoc/test_rdoc_markup_indented_paragraph.rb
@@ -51,4 +51,3 @@ class TestRDocMarkupIndentedParagraph < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_paragraph.rb b/test/rdoc/test_rdoc_markup_paragraph.rb
index ca89a74fc3..1b26846eb3 100644
--- a/test/rdoc/test_rdoc_markup_paragraph.rb
+++ b/test/rdoc/test_rdoc_markup_paragraph.rb
@@ -30,4 +30,3 @@ class TestRDocMarkupParagraph < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_raw.rb b/test/rdoc/test_rdoc_markup_raw.rb
index c7795b24e1..52887e6f6c 100644
--- a/test/rdoc/test_rdoc_markup_raw.rb
+++ b/test/rdoc/test_rdoc_markup_raw.rb
@@ -20,4 +20,3 @@ class TestRDocMarkupRaw < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_to_ansi.rb b/test/rdoc/test_rdoc_markup_to_ansi.rb
index 1d1fc7db46..81372c64d2 100644
--- a/test/rdoc/test_rdoc_markup_to_ansi.rb
+++ b/test/rdoc/test_rdoc_markup_to_ansi.rb
@@ -367,4 +367,3 @@ bar:
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_to_html.rb b/test/rdoc/test_rdoc_markup_to_html.rb
index a5927dccae..e3affa533c 100644
--- a/test/rdoc/test_rdoc_markup_to_html.rb
+++ b/test/rdoc/test_rdoc_markup_to_html.rb
@@ -391,11 +391,43 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
end
def test_accept_paragraph_newline
+ hellos = ["hello", "\u{393 3b5 3b9 3ac} \u{3c3 3bf 3c5}"]
+ worlds = ["world", "\u{3ba 3cc 3c3 3bc 3bf 3c2}"]
+ ohayo, sekai = %W"\u{304a 306f 3088 3046} \u{4e16 754c}"
+
+ hellos.product(worlds) do |hello, world|
+ @to.start_accepting
+ @to.accept_paragraph para("#{hello}\n", "#{world}\n")
+ assert_equal "\n<p>#{hello} #{world}</p>\n", @to.res.join
+ end
+
+ hellos.each do |hello|
+ @to.start_accepting
+ @to.accept_paragraph para("#{hello}\n", "#{sekai}\n")
+ assert_equal "\n<p>#{hello}#{sekai}</p>\n", @to.res.join
+ end
+
+ worlds.each do |world|
+ @to.start_accepting
+ @to.accept_paragraph para("#{ohayo}\n", "#{world}\n")
+ assert_equal "\n<p>#{ohayo}#{world}</p>\n", @to.res.join
+ end
+
@to.start_accepting
+ @to.accept_paragraph para("#{ohayo}\n", "#{sekai}\n")
+ assert_equal "\n<p>#{ohayo}#{sekai}</p>\n", @to.res.join
- @to.accept_paragraph para("hello\n", "world\n")
+ @to.start_accepting
+ @to.accept_paragraph para("+hello+\n", "world\n")
+ assert_equal "\n<p><code>hello</code> world</p>\n", @to.res.join
- assert_equal "\n<p>hello world </p>\n", @to.res.join
+ @to.start_accepting
+ @to.accept_paragraph para("hello\n", "+world+\n")
+ assert_equal "\n<p>hello <code>world</code></p>\n", @to.res.join
+
+ @to.start_accepting
+ @to.accept_paragraph para("+hello+\n", "+world+\n")
+ assert_equal "\n<p><code>hello</code> <code>world</code></p>\n", @to.res.join
end
def test_accept_heading_output_decoration
@@ -602,9 +634,9 @@ end
end
def test_accept_verbatim_redefinable_operators
- functions = %w[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ` ! != !~].map { |redefinable_op|
+ functions = %w[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ` ! != !~].flat_map { |redefinable_op|
["def #{redefinable_op}\n", "end\n"]
- }.flatten
+ }
verb = @RM::Verbatim.new(*functions)
@@ -665,6 +697,26 @@ EXPECTED
assert_equal "\n<p>C</p>\n", result
end
+ def test_convert_RDOCLINK_escape_image
+ assert_escaped '<script>', 'rdoc-image:"><script>alert(`rdoc-image`)</script>"'
+ end
+
+ def test_convert_RDOCLINK_escape_label_id
+ assert_escaped '<script>', 'rdoc-label::path::"><script>alert(`rdoc-label_id`)</script>"'
+ end
+
+ def test_convert_RDOCLINK_escape_label_path
+ assert_escaped '<script>', 'rdoc-label::"><script>alert(`rdoc-label_path`)</script>"'
+ end
+
+ def test_convert_RDOCLINK_escape_ref
+ assert_escaped '<script>', 'rdoc-ref:"><script>alert(`rdoc-ref`)</script>"'
+ end
+
+ def test_convert_RDOCLINK_escape_xxx
+ assert_escaped '<script>', 'rdoc-xxx:"><script>alert(`rdoc-xxx`)</script>"'
+ end
+
def test_convert_TIDYLINK_footnote
result = @to.convert 'text{*1}[rdoc-label:foottext-1:footmark-1]'
@@ -690,6 +742,11 @@ EXPECTED
"\n<p><a href=\"http://example.com\"><img src=\"path/to/image.jpg\"></a></p>\n"
assert_equal expected, result
+
+ result =
+ @to.convert '{rdoc-image:<script>alert`link text`</script>}[http://example.com]'
+
+ assert_not_include result, "<script>"
end
def test_convert_TIDYLINK_rdoc_label
@@ -704,6 +761,23 @@ EXPECTED
assert_equal "\n<p><a href=\"irc://irc.freenode.net/#ruby-lang\">ruby-lang</a></p>\n", result
end
+ def test_convert_TIDYLINK_escape_text
+ assert_escaped '<script>', '{<script>alert`link text`</script>}[a]'
+ assert_escaped '<script>', 'x:/<script>alert(1);</script>[[]'
+ end
+
+ def test_convert_TIDYLINK_escape_javascript
+ assert_not_include '{click}[javascript:alert`javascript_scheme`]', '<a href="javascript:'
+ end
+
+ def test_convert_TIDYLINK_escape_onmouseover
+ assert_escaped '"/onmouseover="', '{onmouseover}[http://"/onmouseover="alert`on_mouse_link`"]'
+ end
+
+ def test_convert_TIDYLINK_escape_onerror
+ assert_escaped '"onerror="', '{link_image}[http://"onerror="alert`link_image`".png]'
+ end
+
def test_convert_with_exclude_tag
assert_equal "\n<p><code>aaa</code>[:symbol]</p>\n", @to.convert('+aaa+[:symbol]')
assert_equal "\n<p><code>aaa[:symbol]</code></p>\n", @to.convert('+aaa[:symbol]+')
@@ -794,6 +868,11 @@ EXPECTED
assert_equal '<a href="irc://irc.freenode.net/#ruby-lang">irc.freenode.net/#ruby-lang</a>', link
end
+ def test_handle_regexp_HYPERLINK_escape
+ code = 'irc://irc.freenode.net/"><script>alert(`irc`)</script><a"'
+ assert_escaped '<script>', code
+ end
+
def test_list_verbatim_2
str = "* one\n verb1\n verb2\n* two\n"
@@ -876,5 +955,37 @@ EXPECTED
@to.end_accepting
end
+ def test_accept_table
+ header = %w[Col1 Col2 Col3]
+ body = [
+ %w[cell1_1 cell1_2 cell1_3],
+ %w[cell2_1 cell2_2 cell2_3],
+ ['<script>alert("foo");</script>',],
+ %w[+code+ _em_ **strong**],
+ ]
+ aligns = [:left, :right, nil]
+ @to.start_accepting
+ @to.accept_table(header, body, aligns)
+ res = @to.end_accepting
+ assert_include(res[%r<<th[^<>]*>Col1</th>>], 'align="left"')
+ assert_include(res[%r<<th[^<>]*>Col2</th>>], 'align="right"')
+ assert_not_include(res[%r<<th[^<>]*>Col3</th>>], 'align=')
+ assert_include(res[%r<<td[^<>]*>cell1_1</td>>], 'align="left"')
+ assert_include(res[%r<<td[^<>]*>cell1_2</td>>], 'align="right"')
+ assert_not_include(res[%r<<td[^<>]*>cell1_3</td>>], 'align=')
+ assert_include(res[%r<<td[^<>]*>cell2_1</td>>], 'align="left"')
+ assert_include(res[%r<<td[^<>]*>cell2_2</td>>], 'align="right"')
+ assert_not_include(res[%r<<td[^<>]*>cell2_3</td>>], 'align=')
+ assert_not_include(res, '<script>')
+ assert_include(res[%r<<td[^<>]*>.*script.*</td>>], '&lt;script&gt;')
+ assert_include(res[%r<<td[^<>]*>.*code.*</td>>], '<code>code</code>')
+ assert_include(res[%r<<td[^<>]*>.*em.*</td>>], '<em>em</em>')
+ assert_include(res[%r<<td[^<>]*>.*strong.*</td>>], '<strong>strong</strong>')
+ end
+
+ def assert_escaped(unexpected, code)
+ result = @to.convert(code)
+ assert_not_include result, unexpected
+ assert_include result, CGI.escapeHTML(unexpected)
+ end
end
-
diff --git a/test/rdoc/test_rdoc_markup_to_html_crossref.rb b/test/rdoc/test_rdoc_markup_to_html_crossref.rb
index 4b87dd5da5..dc4488195a 100644
--- a/test/rdoc/test_rdoc_markup_to_html_crossref.rb
+++ b/test/rdoc/test_rdoc_markup_to_html_crossref.rb
@@ -133,6 +133,18 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
'rdoc-ref:C1@foo'
end
+ def test_convert_RDOCLINK_rdoc_ref_label_in_current_file
+ result = @to.convert 'rdoc-ref:@foo'
+
+ assert_equal para("<a href=\"#label-foo\">foo</a>"), result,
+ 'rdoc-ref:@foo'
+
+ result = @to.convert '{Foo}[rdoc-ref:@foo]'
+
+ assert_equal para("<a href=\"#label-foo\">Foo</a>"), result,
+ '{Foo}[rdoc-ref:@foo]'
+ end
+
def test_gen_url
assert_equal '<a href="C1.html">Some class</a>',
@to.gen_url('rdoc-ref:C1', 'Some class')
diff --git a/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb b/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb
index cbaf75a04e..8bd2d67247 100644
--- a/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb
+++ b/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb
@@ -30,4 +30,3 @@ class TestRDocMarkupToJoinedParagraph < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_to_label.rb b/test/rdoc/test_rdoc_markup_to_label.rb
index 70ea7f0f1b..2bf2e0ecdf 100644
--- a/test/rdoc/test_rdoc_markup_to_label.rb
+++ b/test/rdoc/test_rdoc_markup_to_label.rb
@@ -110,4 +110,3 @@ class TestRDocMarkupToLabel < RDoc::Markup::FormatterTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_to_markdown.rb b/test/rdoc/test_rdoc_markup_to_markdown.rb
index c8c5fd4d52..92ed37bc50 100644
--- a/test/rdoc/test_rdoc_markup_to_markdown.rb
+++ b/test/rdoc/test_rdoc_markup_to_markdown.rb
@@ -69,7 +69,7 @@ class TestRDocMarkupToMarkdown < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_label
- assert_equal "cat\n: ", @to.res.join
+ assert_equal "cat\n: \n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -79,7 +79,7 @@ class TestRDocMarkupToMarkdown < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_note
- assert_equal "cat\n: ", @to.res.join
+ assert_equal "cat\n: \n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -319,9 +319,7 @@ words words words words
expected = <<-EXPECTED
* l1
* l1.1
-
* l2
-
EXPECTED
assert_equal expected, @to.end_accepting
@@ -343,7 +341,6 @@ words words words words
* second
-
EXPECTED
assert_equal expected, @to.end_accepting
@@ -387,4 +384,3 @@ words words words words
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_to_rdoc.rb b/test/rdoc/test_rdoc_markup_to_rdoc.rb
index 1d833b156a..50f4b6dc8b 100644
--- a/test/rdoc/test_rdoc_markup_to_rdoc.rb
+++ b/test/rdoc/test_rdoc_markup_to_rdoc.rb
@@ -69,7 +69,7 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_label
- assert_equal "cat:\n", @to.res.join
+ assert_equal "[cat]\n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -79,7 +79,7 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_note
- assert_equal "cat:\n", @to.res.join
+ assert_equal "cat::\n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -100,7 +100,7 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
def accept_list_item_start_label
assert_equal [""], @to.res
- assert_equal "cat:\n ", @to.prefix
+ assert_equal "[cat]\n ", @to.prefix
assert_equal 2, @to.indent
end
@@ -115,7 +115,7 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
def accept_list_item_start_note
assert_equal [""], @to.res
- assert_equal "cat:\n ", @to.prefix
+ assert_equal "cat::\n ", @to.prefix
assert_equal 2, @to.indent
end
@@ -243,16 +243,16 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_start_note_2
- assert_equal "<tt>teletype</tt>:\n teletype description\n\n", @to.res.join
+ assert_equal "<tt>teletype</tt>::\n teletype description\n\n", @to.res.join
end
def accept_list_item_start_note_multi_description
- assert_equal "label:\n description one\n\n description two\n\n",
+ assert_equal "label::\n description one\n\n description two\n\n",
@to.res.join
end
def accept_list_item_start_note_multi_label
- assert_equal "one\ntwo:\n two headers\n\n", @to.res.join
+ assert_equal "one::\ntwo::\n two headers\n\n", @to.res.join
end
def accept_paragraph_b
@@ -355,8 +355,8 @@ bar ::
NOTE_LIST
expected = <<-EXPECTED
-foo
-bar:
+foo::
+bar::
hi
EXPECTED
@@ -375,4 +375,3 @@ bar:
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_to_table_of_contents.rb b/test/rdoc/test_rdoc_markup_to_table_of_contents.rb
index 11ab6f197b..7512495aec 100644
--- a/test/rdoc/test_rdoc_markup_to_table_of_contents.rb
+++ b/test/rdoc/test_rdoc_markup_to_table_of_contents.rb
@@ -124,4 +124,3 @@ class TestRDocMarkupToTableOfContents < RDoc::Markup::FormatterTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_to_tt_only.rb b/test/rdoc/test_rdoc_markup_to_tt_only.rb
index 8508f823df..c709d7a4d5 100644
--- a/test/rdoc/test_rdoc_markup_to_tt_only.rb
+++ b/test/rdoc/test_rdoc_markup_to_tt_only.rb
@@ -244,4 +244,3 @@ class TestRDocMarkupToTtOnly < RDoc::Markup::FormatterTestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_markup_verbatim.rb b/test/rdoc/test_rdoc_markup_verbatim.rb
index 1a650c44ef..2f8a57266a 100644
--- a/test/rdoc/test_rdoc_markup_verbatim.rb
+++ b/test/rdoc/test_rdoc_markup_verbatim.rb
@@ -27,4 +27,3 @@ class TestRDocMarkupVerbatim < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_options.rb b/test/rdoc/test_rdoc_options.rb
index 009dcdd998..5e8b1ae3d8 100644
--- a/test/rdoc/test_rdoc_options.rb
+++ b/test/rdoc/test_rdoc_options.rb
@@ -68,7 +68,6 @@ class TestRDocOptions < RDoc::TestCase
'exclude' => %w[~\z \.orig\z \.rej\z \.bak\z \.gemspec\z],
'hyperlink_all' => false,
'line_numbers' => false,
- 'locale' => nil,
'locale_dir' => 'locale',
'locale_name' => nil,
'main_page' => nil,
@@ -83,6 +82,7 @@ class TestRDocOptions < RDoc::TestCase
'title' => nil,
'visibility' => :protected,
'webcvs' => nil,
+ 'skip_tests' => true,
}
assert_equal expected, coder
@@ -208,6 +208,13 @@ rdoc_include:
assert @options.force_update
end
+ def test_parse_coverage_C
+ @options.parse %w[-C]
+
+ assert @options.coverage_report
+ assert @options.force_update
+ end
+
def test_parse_coverage_no
@options.parse %w[--no-dcov]
@@ -220,6 +227,19 @@ rdoc_include:
assert_equal 1, @options.coverage_report
end
+ def test_parse_coverage_C_level_1
+ @options.parse %w[-C1]
+
+ assert_equal 1, @options.coverage_report
+ end
+
+ def test_parse_coverage_C_level_0
+ @options.parse %w[-C0]
+
+ assert_equal 0, @options.coverage_report
+ assert @options.force_update
+ end
+
def test_parse_dash_p
out, err = capture_output do
@options.parse %w[-p]
@@ -699,6 +719,28 @@ rdoc_include:
assert_empty err
end
+ def test_parse_locale_name_default
+ temp_dir do
+ @options.parse %w[]
+ assert_equal 'locale', @options.instance_variable_get(:@locale_dir)
+ assert_nil @options.instance_variable_get(:@locale_name)
+ assert_nil @options.locale
+ @options.finish
+ assert_nil @options.locale
+ end
+ end
+
+ def test_parse_locale_name
+ temp_dir do
+ @options.parse %w[--locale fr]
+ assert_equal 'locale', @options.instance_variable_get(:@locale_dir)
+ assert_equal 'fr', @options.instance_variable_get(:@locale_name)
+ assert_nil @options.locale
+ @options.finish
+ assert_equal 'fr', @options.locale.name
+ end
+ end
+
def test_setup_generator
test_generator = Class.new do
def self.setup_options op
@@ -871,6 +913,16 @@ rdoc_include:
end
end
+ def test_skip_test_default_value
+ @options.parse %w[]
+ assert_equal true, @options.skip_tests
+ end
+
+ def test_no_skip_test_value
+ @options.parse %w[--no-skipping-tests]
+ assert_equal false, @options.skip_tests
+ end
+
class DummyCoder < Hash
alias add :[]=
def tag=(tag)
diff --git a/test/rdoc/test_rdoc_parser.rb b/test/rdoc/test_rdoc_parser.rb
index 7cc3c2d926..fa6443f3d3 100644
--- a/test/rdoc/test_rdoc_parser.rb
+++ b/test/rdoc/test_rdoc_parser.rb
@@ -151,6 +151,20 @@ class TestRDocParser < RDoc::TestCase
File.unlink readme_ext
end
+ def test_can_parse_modeline_c
+ readme_inc = File.join Dir.tmpdir, "README.inc.#{$$}"
+
+ File.open readme_inc, 'w' do |io|
+ io.puts "/* README.inc - -*- c -*- created at: Mon Aug 7 16:45:54 JST 1995 */"
+ io.puts
+ io.puts "/* This document explains how to make extension libraries for Ruby. */"
+ end
+
+ assert_equal RDoc::Parser::C, @RP.can_parse(readme_inc)
+ ensure
+ File.unlink readme_inc
+ end
+
##
# Selenium hides a .jar file using a .txt extension.
diff --git a/test/rdoc/test_rdoc_parser_c.rb b/test/rdoc/test_rdoc_parser_c.rb
index b65561b2bb..ab4f149869 100644
--- a/test/rdoc/test_rdoc_parser_c.rb
+++ b/test/rdoc/test_rdoc_parser_c.rb
@@ -460,7 +460,7 @@ VALUE mFoo = rb_define_module_under(rb_mKernel, "Foo");
end
def test_do_constants
- content = <<-EOF
+ content = <<-'EOF'
#include <ruby.h>
void Init_foo(){
@@ -475,6 +475,9 @@ void Init_foo(){
/* TEST\:TEST: Checking to see if escaped colon works */
rb_define_const(cFoo, "TEST", rb_str_new2("TEST:TEST"));
+ /* TEST: TEST:Checking to see if only word-ending colon works */
+ rb_define_const(cFoo, "TEST2", rb_str_new2("TEST:TEST"));
+
/* \\: The file separator on MS Windows */
rb_define_const(cFoo, "MSEPARATOR", rb_str_new2("\\"));
@@ -538,6 +541,9 @@ void Init_foo(){
assert_equal ['TEST', 'TEST:TEST',
'Checking to see if escaped colon works '],
constants.shift
+ assert_equal ['TEST2', 'TEST',
+ 'TEST:Checking to see if only word-ending colon works '],
+ constants.shift
assert_equal ['MSEPARATOR', '\\',
'The file separator on MS Windows '],
constants.shift
@@ -577,8 +583,6 @@ void Init_curses(){
mCurses = rb_define_module("Curses");
/*
- * Document-const: Curses::COLOR_BLACK
- *
* Value of the color black
*/
rb_curses_define_const(COLOR_BLACK);
@@ -603,8 +607,7 @@ void Init_curses(){
def test_do_constants_file
content = <<-EOF
void Init_File(void) {
- /* Document-const: LOCK_SH
- *
+ /*
* Shared lock
*/
rb_file_const("LOCK_SH", INT2FIX(LOCK_SH));
@@ -1373,6 +1376,36 @@ Init_Foo(void) {
assert_equal "DLL_LOCAL VALUE\nother_function() {\n}", code
end
+ def test_find_body_static_inline
+ content = <<-EOF
+/*
+ * a comment for other_function
+ */
+static inline VALUE
+other_function() {
+}
+
+void
+Init_Foo(void) {
+ VALUE foo = rb_define_class("Foo", rb_cObject);
+
+ rb_define_method(foo, "my_method", other_function, 0);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+ other_function = klass.method_list.first
+
+ assert_equal 'my_method', other_function.name
+ assert_equal "a comment for other_function",
+ other_function.comment.text
+ assert_equal '()', other_function.params
+
+ code = other_function.token_stream.first[:text]
+
+ assert_equal "static inline VALUE\nother_function() {\n}", code
+ end
+
def test_find_modifiers_call_seq
comment = RDoc::Comment.new <<-COMMENT
call-seq:
@@ -2068,4 +2101,3 @@ void Init_Blah(void) {
end
end
-
diff --git a/test/rdoc/test_rdoc_parser_changelog.rb b/test/rdoc/test_rdoc_parser_changelog.rb
index 6584840572..587a156d3a 100644
--- a/test/rdoc/test_rdoc_parser_changelog.rb
+++ b/test/rdoc/test_rdoc_parser_changelog.rb
@@ -482,4 +482,3 @@ ChangeLog
RDoc::Parser::ChangeLog::Git::LogEntry.new(*a)
end
end
-
diff --git a/test/rdoc/test_rdoc_parser_markdown.rb b/test/rdoc/test_rdoc_parser_markdown.rb
index 06c6700d96..cca9c1ddfd 100644
--- a/test/rdoc/test_rdoc_parser_markdown.rb
+++ b/test/rdoc/test_rdoc_parser_markdown.rb
@@ -59,4 +59,3 @@ class TestRDocParserMarkdown < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_parser_rd.rb b/test/rdoc/test_rdoc_parser_rd.rb
index bac9c65592..48663e6d7d 100644
--- a/test/rdoc/test_rdoc_parser_rd.rb
+++ b/test/rdoc/test_rdoc_parser_rd.rb
@@ -53,4 +53,3 @@ class TestRDocParserRd < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb
index ef8ad91668..3e2a85ffba 100644
--- a/test/rdoc/test_rdoc_parser_ruby.rb
+++ b/test/rdoc/test_rdoc_parser_ruby.rb
@@ -1960,10 +1960,10 @@ end
def test_parse_method_bracket
util_parser <<-RUBY
class C
- def [] end
- def self.[] end
- def []= end
- def self.[]= end
+ def []; end
+ def self.[]; end
+ def []=; end
+ def self.[]=; end
end
RUBY
@@ -3065,6 +3065,28 @@ RUBY
assert_nil m.params, 'Module parameter not removed'
end
+ def test_parse_statements_nodoc_identifier_alias
+ klass = @top_level.add_class RDoc::NormalClass, 'Foo'
+
+ util_parser "\nalias :old :new # :nodoc:"
+
+ @parser.parse_statements klass, RDoc::Parser::Ruby::NORMAL, nil
+
+ assert_empty klass.aliases
+ assert_empty klass.unmatched_alias_lists
+ end
+
+ def test_parse_statements_nodoc_identifier_alias_method
+ klass = @top_level.add_class RDoc::NormalClass, 'Foo'
+
+ util_parser "\nalias_method :old :new # :nodoc:"
+
+ @parser.parse_statements klass, RDoc::Parser::Ruby::NORMAL, nil
+
+ assert_empty klass.aliases
+ assert_empty klass.unmatched_alias_lists
+ end
+
def test_parse_statements_stopdoc_alias
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
@@ -3205,6 +3227,14 @@ RUBY
assert_nil @parser.parse_symbol_in_arg
end
+ def test_parse_percent_symbol
+ content = '%s[foo bar]'
+ util_parser content
+ tk = @parser.get_tk
+ assert_equal :on_symbol, tk[:kind]
+ assert_equal content, tk[:text]
+ end
+
def test_parse_statements_alias_method
content = <<-CONTENT
class A
@@ -3350,6 +3380,13 @@ end
assert_equal :on_const, parser.get_tk[:kind]
end
+ def test_read_directive_linear_performance
+ pre = ->(i) {util_parser '# ' + '0'*i + '=000:'}
+ assert_linear_performance((1..5).map{|i|10**i}, pre: pre) do |parser|
+ assert_nil parser.read_directive []
+ end
+ end
+
def test_read_documentation_modifiers
c = RDoc::Context.new
diff --git a/test/rdoc/test_rdoc_parser_simple.rb b/test/rdoc/test_rdoc_parser_simple.rb
index 2f1ad00de4..4255cb97d8 100644
--- a/test/rdoc/test_rdoc_parser_simple.rb
+++ b/test/rdoc/test_rdoc_parser_simple.rb
@@ -113,4 +113,3 @@ contents of a string.
end
end
-
diff --git a/test/rdoc/test_rdoc_rd.rb b/test/rdoc/test_rdoc_rd.rb
index 83ee423455..38de575bb0 100644
--- a/test/rdoc/test_rdoc_rd.rb
+++ b/test/rdoc/test_rdoc_rd.rb
@@ -28,4 +28,3 @@ class TestRDocRd < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_rd_block_parser.rb b/test/rdoc/test_rdoc_rd_block_parser.rb
index 22f432eaf4..ca0ac9f9e9 100644
--- a/test/rdoc/test_rdoc_rd_block_parser.rb
+++ b/test/rdoc/test_rdoc_rd_block_parser.rb
@@ -168,6 +168,27 @@ class TestRDocRdBlockParser < RDoc::TestCase
tf.close!
end
+=begin
+ def test_parse_include_other_format
+ @block_parser.include_path = [Dir.tmpdir]
+
+ expected =
+ doc(
+ blank_line,
+ para("include ((*worked*))"),
+ blank_line,
+ blank_line)
+
+ str = <<~STR
+ =begin nonrd
+ <<< worked
+ =end
+ STR
+
+ assert_equal(expected, @block_parser.parse str.lines.to_a)
+ end
+=end
+
def test_parse_heading
assert_equal doc(head(1, "H")), parse("= H")
assert_equal doc(head(2, "H")), parse("== H")
diff --git a/test/rdoc/test_rdoc_rd_inline.rb b/test/rdoc/test_rdoc_rd_inline.rb
index 13ab86d3d9..6bfb229933 100644
--- a/test/rdoc/test_rdoc_rd_inline.rb
+++ b/test/rdoc/test_rdoc_rd_inline.rb
@@ -61,4 +61,3 @@ class TestRDocRdInline < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb
index e958e5f2f6..5168932430 100644
--- a/test/rdoc/test_rdoc_rdoc.rb
+++ b/test/rdoc/test_rdoc_rdoc.rb
@@ -165,12 +165,7 @@ class TestRDocRDoc < RDoc::TestCase
b = Dir.glob(b).first
c = Dir.glob(c).first
- dot_doc = File.expand_path('.document')
- FileUtils.touch dot_doc
- open(dot_doc, 'w') do |f|
- f.puts 'a.rb'
- f.puts 'b.rb'
- end
+ File.write('.document', "a.rb\n""b.rb\n")
expected_files << a
expected_files << b
@@ -196,12 +191,7 @@ class TestRDocRDoc < RDoc::TestCase
b = Dir.glob(b).first
c = Dir.glob(c).first
- dot_doc = File.expand_path('.document')
- FileUtils.touch dot_doc
- open(dot_doc, 'w') do |f|
- f.puts 'a.rb'
- f.puts 'b.rb'
- end
+ File.write('.document', "a.rb\n""b.rb\n")
expected_files << a
@rdoc.options.exclude = Regexp.new(['b.rb'].join('|'))
@@ -213,6 +203,48 @@ class TestRDocRDoc < RDoc::TestCase
assert_equal expected_files, files
end
+ def test_normalized_file_list_with_skipping_tests_enabled
+ files = temp_dir do |dir|
+ @a = File.expand_path('a.rb')
+ spec_dir = File.expand_path('spec')
+ spec_file = File.expand_path(File.join('spec', 'my_spec.rb'))
+ test_dir = File.expand_path('test')
+ test_file = File.expand_path(File.join('test', 'my_test.rb'))
+ FileUtils.touch @a
+ FileUtils.mkdir_p spec_dir
+ FileUtils.touch spec_file
+ FileUtils.mkdir_p test_dir
+ FileUtils.touch test_file
+
+ @rdoc.options.skip_tests = true
+ @rdoc.normalized_file_list [File.realpath(dir)]
+ end
+
+ files = files.map { |file, *| File.expand_path file }
+ assert_equal [@a], files
+ end
+
+ def test_normalized_file_list_with_skipping_tests_disabled
+ files = temp_dir do |dir|
+ @a = File.expand_path('a.rb')
+ spec_dir = File.expand_path('spec')
+ @spec_file = File.expand_path(File.join('spec', 'my_spec.rb'))
+ test_dir = File.expand_path('test')
+ @test_file = File.expand_path(File.join('test', 'my_test.rb'))
+ FileUtils.touch @a
+ FileUtils.mkdir_p spec_dir
+ FileUtils.touch @spec_file
+ FileUtils.mkdir_p test_dir
+ FileUtils.touch @test_file
+
+ @rdoc.options.skip_tests = false
+ @rdoc.normalized_file_list [File.realpath(dir)]
+ end
+
+ files = files.map { |file, *| File.expand_path file }
+ assert_equal [@a, @spec_file, @test_file], files.sort
+ end
+
def test_parse_file
@rdoc.store = RDoc::Store.new
diff --git a/test/rdoc/test_rdoc_ri_driver.rb b/test/rdoc/test_rdoc_ri_driver.rb
index fc15c25cea..39e6e67759 100644
--- a/test/rdoc/test_rdoc_ri_driver.rb
+++ b/test/rdoc/test_rdoc_ri_driver.rb
@@ -6,17 +6,13 @@ class TestRDocRIDriver < RDoc::TestCase
def setup
super
- @tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_driver_#{$$}"
- @home_ri = File.join @tmpdir, 'dot_ri'
+ @home_ri = File.join @test_home, 'dot_ri'
- FileUtils.mkdir_p @tmpdir
FileUtils.mkdir_p @home_ri
- @orig_ri = ENV['RI']
- ENV['HOME'] = @tmpdir
- @rdoc_home = File.join ENV["HOME"], ".rdoc"
+ @orig_ri = ENV.delete('RI')
+ @rdoc_home = File.join @test_home, ".rdoc"
FileUtils.mkdir_p @rdoc_home
- ENV.delete 'RI'
@options = RDoc::RI::Driver.default_options
@options[:use_system] = false
@@ -24,7 +20,7 @@ class TestRDocRIDriver < RDoc::TestCase
@options[:use_home] = false
@options[:use_gems] = false
- @options[:home] = @tmpdir
+ @options[:home] = @rdoc_home
@options[:use_stdout] = true
@options[:formatter] = @RM::ToRdoc
@@ -33,7 +29,6 @@ class TestRDocRIDriver < RDoc::TestCase
def teardown
defined?(@orig_ri) and ENV['RI'] = @orig_ri
- defined?(@tmpdir) and FileUtils.rm_rf @tmpdir
super
end
@@ -603,7 +598,7 @@ class TestRDocRIDriver < RDoc::TestCase
assert_match %r%^= Attributes:%, out
assert_match %r%^ attr_accessor attr%, out
- assert_equal 1, out.scan(/-\n/).length
+ assert_equal 1, out.scan(/^-{50,}$/).length, out
refute_match %r%Foo::Bar#blah%, out
end
@@ -627,7 +622,7 @@ class TestRDocRIDriver < RDoc::TestCase
assert_match %r%^= Attributes:%, out
assert_match %r%^ attr_accessor attr%, out
- assert_equal 6, out.scan(/-\n/).length
+ assert_equal 6, out.scan(/^-{50,}$/).length, out
assert_match %r%Foo::Bar#blah%, out
end
diff --git a/test/rdoc/test_rdoc_ri_paths.rb b/test/rdoc/test_rdoc_ri_paths.rb
index c01a4711ee..6dccd6dbdd 100644
--- a/test/rdoc/test_rdoc_ri_paths.rb
+++ b/test/rdoc/test_rdoc_ri_paths.rb
@@ -155,4 +155,3 @@ class TestRDocRIPaths < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_single_class.rb b/test/rdoc/test_rdoc_single_class.rb
index ee242d7bc9..e81a1498ba 100644
--- a/test/rdoc/test_rdoc_single_class.rb
+++ b/test/rdoc/test_rdoc_single_class.rb
@@ -18,4 +18,3 @@ class TestRDocSingleClass < RDoc::TestCase
end
end
-
diff --git a/test/rdoc/test_rdoc_stats.rb b/test/rdoc/test_rdoc_stats.rb
index b9918e4fd3..ce272d36cf 100644
--- a/test/rdoc/test_rdoc_stats.rb
+++ b/test/rdoc/test_rdoc_stats.rb
@@ -720,4 +720,3 @@ m(a, b) { |c, d| ... }
end
end
-
diff --git a/test/rdoc/test_rdoc_store.rb b/test/rdoc/test_rdoc_store.rb
index aa4db4c65e..50e8667d81 100644
--- a/test/rdoc/test_rdoc_store.rb
+++ b/test/rdoc/test_rdoc_store.rb
@@ -319,8 +319,7 @@ class TestRDocStore < XrefTestCase
end
def test_friendly_path
- @orig_xdg_data_home = ENV['XDG_DATA_HOME']
- ENV.delete('XDG_DATA_HOME')
+ @orig_xdg_data_home = ENV.delete('XDG_DATA_HOME')
@s.path = @tmpdir
@s.type = nil
@@ -374,9 +373,9 @@ class TestRDocStore < XrefTestCase
assert_equal [@mod], s.all_modules.sort
assert_equal [@page, @top_level], s.all_files.sort
- methods = s.all_classes_and_modules.map do |mod|
+ methods = s.all_classes_and_modules.flat_map do |mod|
mod.method_list
- end.flatten.sort
+ end.sort
_meth_bang_alias = RDoc::AnyMethod.new nil, 'method_bang'
_meth_bang_alias.parent = @klass
@@ -389,9 +388,9 @@ class TestRDocStore < XrefTestCase
assert_equal @klass, methods.last.parent
- attributes = s.all_classes_and_modules.map do |mod|
+ attributes = s.all_classes_and_modules.flat_map do |mod|
mod.attributes
- end.flatten.sort
+ end.sort
assert_equal [@attr], attributes
diff --git a/test/rdoc/test_rdoc_task.rb b/test/rdoc/test_rdoc_task.rb
index 23add7d5fe..67d223087b 100644
--- a/test/rdoc/test_rdoc_task.rb
+++ b/test/rdoc/test_rdoc_task.rb
@@ -50,6 +50,7 @@ class TestRDocTask < RDoc::TestCase
assert Rake::Task[:rdoc]
assert Rake::Task[:clobber_rdoc]
assert Rake::Task[:rerdoc]
+ assert Rake::Task[:"rdoc:coverage"]
assert_equal ["html/created.rid"], Rake::Task[:rdoc].prerequisites
end
@@ -58,6 +59,7 @@ class TestRDocTask < RDoc::TestCase
assert Rake::Task[:rdoc_dev]
assert Rake::Task[:clobber_rdoc_dev]
assert Rake::Task[:rerdoc_dev]
+ assert Rake::Task[:"rdoc_dev:coverage"]
assert_equal :rdoc_dev, rd.name
end
@@ -110,11 +112,16 @@ class TestRDocTask < RDoc::TestCase
assert_equal 'Rebuild RDoc HTML files', @t.rerdoc_task_description
end
+ def test_coverage_task_description
+ assert_equal 'Print RDoc coverage report', @t.coverage_task_description
+ end
+
def test_tasks_creation_with_custom_name_string
rd = RDoc::Task.new("rdoc_dev")
assert Rake::Task[:rdoc_dev]
assert Rake::Task[:clobber_rdoc_dev]
assert Rake::Task[:rerdoc_dev]
+ assert Rake::Task[:"rdoc_dev:coverage"]
assert_equal "rdoc_dev", rd.name
end
@@ -131,6 +138,7 @@ class TestRDocTask < RDoc::TestCase
assert Rake::Task[:"rdoc"]
assert Rake::Task[:"rdoc:clean"]
assert Rake::Task[:"rdoc:force"]
+ assert Rake::Task[:"rdoc:coverage"]
assert_raise(RuntimeError) { Rake::Task[:clobber_rdoc] }
assert_equal options, rd.name
end
@@ -140,6 +148,7 @@ class TestRDocTask < RDoc::TestCase
assert Rake::Task[:rdoc]
assert Rake::Task[:"rdoc:clean"]
assert Rake::Task[:rerdoc]
+ assert Rake::Task[:"rdoc:coverage"]
end
def test_tasks_creation_with_custom_name_hash_raises_exception_if_invalid_option_given
diff --git a/test/rdoc/test_rdoc_token_stream.rb b/test/rdoc/test_rdoc_token_stream.rb
index cdfa615dae..8fcd3d8f68 100644
--- a/test/rdoc/test_rdoc_token_stream.rb
+++ b/test/rdoc/test_rdoc_token_stream.rb
@@ -39,6 +39,49 @@ class TestRDocTokenStream < RDoc::TestCase
assert_equal '', RDoc::TokenStream.to_html([])
end
+ def test_add_tokens
+ foo = Class.new do
+ include RDoc::TokenStream
+ end.new
+ foo.collect_tokens
+ foo.add_tokens([:token])
+ assert_equal [:token], foo.token_stream
+ end
+
+ def test_add_token
+ foo = Class.new do
+ include RDoc::TokenStream
+ end.new
+ foo.collect_tokens
+ foo.add_token(:token)
+ assert_equal [:token], foo.token_stream
+ end
+
+ def test_collect_tokens
+ foo = Class.new do
+ include RDoc::TokenStream
+ end.new
+ foo.collect_tokens
+ assert_equal [], foo.token_stream
+ end
+
+ def test_pop_token
+ foo = Class.new do
+ include RDoc::TokenStream
+ end.new
+ foo.collect_tokens
+ foo.add_token(:token)
+ foo.pop_token
+ assert_equal [], foo.token_stream
+ end
+
+ def test_token_stream
+ foo = Class.new do
+ include RDoc::TokenStream
+ end.new
+ assert_equal nil, foo.token_stream
+ end
+
def test_tokens_to_s
foo = Class.new do
include RDoc::TokenStream
@@ -53,6 +96,14 @@ class TestRDocTokenStream < RDoc::TestCase
end.new
assert_equal "foo 'bar'", foo.tokens_to_s
+
+ foo = Class.new do
+ include RDoc::TokenStream
+
+ def initialize
+ @token_stream = nil
+ end
+ end.new
+ assert_equal "", foo.tokens_to_s
end
end
-
diff --git a/test/rdoc/xref_data.rb b/test/rdoc/xref_data.rb
index de76a90602..257b821f4f 100644
--- a/test/rdoc/xref_data.rb
+++ b/test/rdoc/xref_data.rb
@@ -74,6 +74,12 @@ class C6
def priv4() end
public def pub5() end
def priv5() end
+ def self.s_pub1() end
+ class << self
+ def s_pub2() end
+ private
+ def s_priv1() end
+ end
protected
private def priv6() end
@@ -82,6 +88,12 @@ class C6
def prot5() end
public def pub6() end
def prot6() end
+ def self.s_pub3() end
+ class << self
+ def s_pub4() end
+ protected
+ def s_prot1() end
+ end
end
class C7
@@ -149,4 +161,3 @@ class Child < Parent
end
XREF_DATA
-
diff --git a/test/rdoc/xref_test_case.rb b/test/rdoc/xref_test_case.rb
index 22b00d04bc..0f7395e516 100644
--- a/test/rdoc/xref_test_case.rb
+++ b/test/rdoc/xref_test_case.rb
@@ -91,4 +91,3 @@ class XrefTestCase < RDoc::TestCase
end
end
-
diff --git a/test/readline/helper.rb b/test/readline/helper.rb
deleted file mode 100644
index 2d28d18a7e..0000000000
--- a/test/readline/helper.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-begin
- require "readline.so"
- ReadlineSo = Readline
-rescue LoadError
-end
-
-def use_ext_readline # Use ext/readline as Readline
- Object.send(:remove_const, :Readline) if Object.const_defined?(:Readline)
- Object.const_set(:Readline, ReadlineSo)
-end
-
-begin
- require "reline"
-rescue LoadError
- Object.class_eval {remove_const :Reline} if defined?(Reline)
-else
- def use_lib_reline # Use lib/reline as Readline
- Reline.send(:remove_const, 'IOGate') if Reline.const_defined?('IOGate')
- Reline.const_set('IOGate', Reline::GeneralIO)
- Reline.send(:core).config.instance_variable_set(:@test_mode, true)
- Reline.send(:core).config.reset
- Object.send(:remove_const, :Readline) if Object.const_defined?(:Readline)
- Object.const_set(:Readline, Reline)
- end
-
- def finish_using_lib_reline
- Reline.instance_variable_set(:@core, nil)
- end
-end
diff --git a/test/readline/test_readline.rb b/test/readline/test_readline.rb
deleted file mode 100644
index be338c6c0d..0000000000
--- a/test/readline/test_readline.rb
+++ /dev/null
@@ -1,950 +0,0 @@
-# frozen_string_literal: false
-require_relative "helper"
-require "test/unit"
-require "tempfile"
-require "timeout"
-require "open3"
-
-module BasetestReadline
- INPUTRC = "INPUTRC"
- TERM = "TERM"
- SAVED_ENV = %w[COLUMNS LINES]
-
- TIMEOUT = 8
-
- def setup
- @saved_env = ENV.values_at(*SAVED_ENV)
- @inputrc, ENV[INPUTRC] = ENV[INPUTRC], IO::NULL
- @term, ENV[TERM] = ENV[TERM], "vt100"
- end
-
- def teardown
- ENV[INPUTRC] = @inputrc
- ENV[TERM] = @term
- Readline.instance_variable_set("@completion_proc", nil)
- begin
- Readline.delete_text
- Readline.point = 0
- rescue NotImplementedError
- end
- Readline.special_prefixes = ""
- Readline.completion_append_character = nil
- Readline.input = nil
- Readline.output = nil
- SAVED_ENV.each_with_index {|k, i| ENV[k] = @saved_env[i] }
- end
-
- def test_readline
- Readline::HISTORY.clear
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- with_temp_stdio do |stdin, stdout|
- stdin.write("hello\n")
- stdin.close
- stdout.flush
- line = replace_stdio(stdin.path, stdout.path) {
- Readline.readline("> ", true)
- }
- assert_equal("hello", line)
- assert_equal(true, line.tainted?) if RUBY_VERSION < '2.7'
- stdout.rewind
- assert_equal("> ", stdout.read(2))
- assert_equal(1, Readline::HISTORY.length)
- assert_equal("hello", Readline::HISTORY[0])
-
- # Work around lack of SecurityError in Reline
- # test mode with tainted prompt.
- # Also skip test on Ruby 2.7+, where $SAFE/taint is deprecated.
- if RUBY_VERSION < '2.7' && defined?(TestRelineAsReadline) && !kind_of?(TestRelineAsReadline)
- begin
- Thread.start {
- $SAFE = 1
- assert_raise(SecurityError) do
- replace_stdio(stdin.path, stdout.path) do
- Readline.readline("> ".taint)
- end
- end
- }.join
- ensure
- $SAFE = 0
- end
- end
- end
- end
-
- # line_buffer
- # point
- def test_line_buffer__point
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- omit "GNU Readline has special behaviors" if defined?(Reline) and Readline == Reline
- begin
- Readline.line_buffer
- Readline.point
- rescue NotImplementedError
- return
- end
-
- with_temp_stdio do |stdin, stdout|
- actual_text = nil
- actual_line_buffer = nil
- actual_point = nil
- Readline.completion_proc = ->(text) {
- actual_text = text
- actual_point = Readline.point
- actual_line_buffer = Readline.line_buffer
- stdin.write(" finish\n")
- stdin.flush
- stdout.flush
- return ["complete"]
- }
-
- stdin.write("first second\t")
- stdin.flush
- Readline.completion_append_character = " "
- replace_stdio(stdin.path, stdout.path) {
- Readline.readline("> ", false)
- }
- assert_equal("second", actual_text)
- assert_equal("first second", actual_line_buffer)
- assert_equal(12, actual_point)
- assert_equal("first complete finish", Readline.line_buffer)
- assert_equal(Encoding.find("locale"), Readline.line_buffer.encoding)
- assert_equal(true, Readline.line_buffer.tainted?) if RUBY_VERSION < '2.7'
-
- assert_equal(22, Readline.point)
-
- stdin.rewind
- stdout.rewind
-
- stdin.write("first second\t")
- stdin.flush
- Readline.completion_append_character = nil
- replace_stdio(stdin.path, stdout.path) {
- Readline.readline("> ", false)
- }
- assert_equal("second", actual_text)
- assert_equal("first second", actual_line_buffer)
- assert_equal(12, actual_point)
- assert_equal("first complete finish", Readline.line_buffer)
- assert_equal(Encoding.find("locale"), Readline.line_buffer.encoding)
- assert_equal(true, Readline.line_buffer.tainted?) if RUBY_VERSION < '2.7'
-
- assert_equal(21, Readline.point)
- end
- end
-
- def test_input=
- assert_raise(TypeError) do
- Readline.input = "This is not a file."
- end
- end
-
- def test_output=
- assert_raise(TypeError) do
- Readline.output = "This is not a file."
- end
- end
-
- def test_completion_proc
- expected = proc { |input| input }
- Readline.completion_proc = expected
- assert_equal(expected, Readline.completion_proc)
-
- assert_raise(ArgumentError) do
- Readline.completion_proc = "This does not have call method."
- end
- end
-
- def test_completion_case_fold
- expected = [true, false, "string", {"a" => "b"}]
- completion_case_fold = Readline.completion_case_fold
- expected.each do |e|
- Readline.completion_case_fold = e
- assert_equal(e, Readline.completion_case_fold)
- end
- ensure
- Readline.completion_case_fold = completion_case_fold
- end
-
- def test_completion_proc_empty_result
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- with_temp_stdio do |stdin, stdout|
- stdin.write("first\t")
- stdin.flush
- Readline.completion_proc = ->(text) {[]}
- line1 = line2 = nil
- replace_stdio(stdin.path, stdout.path) {
- assert_nothing_raised(NoMemoryError) {line1 = Readline.readline("> ")}
- stdin.write("\n")
- stdin.flush
- assert_nothing_raised(NoMemoryError) {line2 = Readline.readline("> ")}
- }
- assert_equal("first", line1)
- assert_equal("", line2)
- begin
- assert_equal("", Readline.line_buffer)
- rescue NotImplementedError
- end
- end
- end
-
- def test_get_screen_size
- begin
- res = Readline.get_screen_size
- assert(res.is_a?(Array))
- rows, columns = *res
- assert(rows.is_a?(Integer))
- assert(rows >= 0)
- assert(columns.is_a?(Integer))
- assert(columns >= 0)
- rescue NotImplementedError
- end
- end
-
- # vi_editing_mode
- # emacs_editing_mode
- def test_editing_mode
- begin
- assert_equal(false, Readline.vi_editing_mode?)
- assert_equal(true, Readline.emacs_editing_mode?)
-
- assert_equal(nil, Readline.vi_editing_mode)
- assert_equal(true, Readline.vi_editing_mode?)
- assert_equal(false, Readline.emacs_editing_mode?)
- assert_equal(nil, Readline.vi_editing_mode)
- assert_equal(true, Readline.vi_editing_mode?)
- assert_equal(false, Readline.emacs_editing_mode?)
-
- assert_equal(nil, Readline.emacs_editing_mode)
- assert_equal(false, Readline.vi_editing_mode?)
- assert_equal(true, Readline.emacs_editing_mode?)
- assert_equal(nil, Readline.emacs_editing_mode)
- assert_equal(false, Readline.vi_editing_mode?)
- assert_equal(true, Readline.emacs_editing_mode?)
- rescue NotImplementedError
- end
- end
-
- def test_completion_append_character
- begin
- enc = get_default_internal_encoding
- data_expected = [
- ["x", "x"],
- ["xyx", "x"],
- [" ", " "],
- ["\t", "\t"],
- ]
- data_expected.each do |(data, expected)|
- Readline.completion_append_character = data
- assert_equal(expected, Readline.completion_append_character)
- assert_equal(enc, Readline.completion_append_character.encoding)
- end
- Readline.completion_append_character = ""
- assert_equal(nil, Readline.completion_append_character)
- rescue NotImplementedError
- end
- end
-
- def test_completion_encoding
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- bug5941 = '[Bug #5941]'
- append_character = Readline.completion_append_character
- Readline.completion_append_character = ""
- completion_case_fold = Readline.completion_case_fold
- locale = get_default_internal_encoding
- if locale == Encoding::UTF_8
- enc1 = Encoding::EUC_JP
- else
- enc1 = Encoding::UTF_8
- end
- results = nil
- Readline.completion_proc = ->(text) {results}
-
- [%W"\u{3042 3042} \u{3042 3044}", %W"\u{fe5b fe5b} \u{fe5b fe5c}"].any? do |w|
- begin
- results = w.map {|s| s.encode(locale)}
- rescue Encoding::UndefinedConversionError
- end
- end or
- begin
- "\xa1\xa2".encode(Encoding::UTF_8, locale)
- rescue
- else
- results = %W"\xa1\xa1 \xa1\xa2".map {|s| s.force_encoding(locale)}
- end or
- begin
- return if assert_under_utf8
- omit("missing test for locale #{locale.name}")
- end
- expected = results[0][0...1]
- Readline.completion_case_fold = false
- assert_equal(expected, with_pipe {|r, w| w << "\t"}, bug5941)
- Readline.completion_case_fold = true
- assert_equal(expected, with_pipe {|r, w| w << "\t"}, bug5941)
- results.map! {|s| s.encode(enc1)}
- assert_raise(Encoding::CompatibilityError, bug5941) do
- with_pipe {|r, w| w << "\t"}
- end
- ensure
- return if /EditLine/n.match(Readline::VERSION)
- Readline.completion_case_fold = completion_case_fold
- Readline.completion_append_character = append_character
- end
-
- # basic_word_break_characters
- # completer_word_break_characters
- # basic_quote_characters
- # completer_quote_characters
- # filename_quote_characters
- # special_prefixes
- def test_some_characters_methods
- end
-
- def test_closed_outstream
- bug5803 = '[ruby-dev:45043]'
- IO.pipe do |r, w|
- Readline.input = r
- Readline.output = w
- (w << "##\t").close
- assert_raise(IOError, bug5803) {Readline.readline}
- end
- end
-
- def test_pre_input_hook
- begin
- pr = proc {}
- Readline.pre_input_hook = pr
- assert_equal(pr, Readline.pre_input_hook)
- Readline.pre_input_hook = nil
- assert_nil(Readline.pre_input_hook)
- rescue NotImplementedError
- end
- end
-
- def test_point
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- assert_equal(0, Readline.point)
- Readline.insert_text('12345')
- assert_equal(5, Readline.point)
-
- assert_equal(4, Readline.point=(4))
-
- Readline.insert_text('abc')
- assert_equal(7, Readline.point)
-
- assert_equal('1234abc5', Readline.line_buffer)
- rescue NotImplementedError
- end
-
- def test_insert_text
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- str = "test_insert_text"
- assert_equal(0, Readline.point)
- assert_equal(Readline, Readline.insert_text(str))
- assert_equal(str, Readline.line_buffer)
- assert_equal(16, Readline.point)
- assert_equal(get_default_internal_encoding,
- Readline.line_buffer.encoding)
-
- Readline.delete_text(1, 3)
- assert_equal("t_insert_text", Readline.line_buffer)
- Readline.delete_text(11)
- assert_equal("t_insert_te", Readline.line_buffer)
- Readline.delete_text(-3...-1)
- assert_equal("t_inserte", Readline.line_buffer)
- Readline.delete_text(-3..-1)
- assert_equal("t_inse", Readline.line_buffer)
- Readline.delete_text(3..-3)
- assert_equal("t_ise", Readline.line_buffer)
- Readline.delete_text(3, 1)
- assert_equal("t_ie", Readline.line_buffer)
- Readline.delete_text(1..1)
- assert_equal("tie", Readline.line_buffer)
- Readline.delete_text(1...2)
- assert_equal("te", Readline.line_buffer)
- Readline.delete_text
- assert_equal("", Readline.line_buffer)
- rescue NotImplementedError
- end
-
- def test_delete_text
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- str = "test_insert_text"
- assert_equal(0, Readline.point)
- assert_equal(Readline, Readline.insert_text(str))
- assert_equal(16, Readline.point)
- assert_equal(str, Readline.line_buffer)
- Readline.delete_text
-
- if !defined?(Reline) or Readline != Reline
- # NOTE: unexpected but GNU Readline's spec
- assert_equal(16, Readline.point)
- assert_equal("", Readline.line_buffer)
- assert_equal(Readline, Readline.insert_text(str))
- assert_equal(32, Readline.point)
- assert_equal("", Readline.line_buffer)
- end
- rescue NotImplementedError
- end
-
- def test_modify_text_in_pre_input_hook
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- with_temp_stdio {|stdin, stdout|
- begin
- stdin.write("world\n")
- stdin.close
- Readline.pre_input_hook = proc do
- assert_equal("", Readline.line_buffer)
- Readline.insert_text("hello ")
- Readline.redisplay
- end
- replace_stdio(stdin.path, stdout.path) do
- line = Readline.readline("> ")
- assert_equal("hello world", line)
- end
- # Readline 4.3 doesn't include inserted text or input
- # Reline's rendering logic is tricky
- if Readline::VERSION != '4.3' and (!defined?(Reline) or Readline != Reline)
- assert_equal("> hello world\n", stdout.read)
- end
- stdout.close
- rescue NotImplementedError
- ensure
- begin
- Readline.pre_input_hook = nil
- rescue NotImplementedError
- end
- end
- }
- end
-
- def test_input_metachar
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- # test will pass on Windows reline, but not readline
- omit "Won't pass on mingw readline.so using 8.0.001" if /mingw/ =~ RUBY_PLATFORM and defined?(TestReadline) and kind_of?(TestReadline)
- omit 'Needs GNU Readline 6 or later' if /mswin|mingw/ =~ RUBY_PLATFORM and defined?(TestReadline) and kind_of?(TestReadline) and Readline::VERSION < '6.0'
- bug6601 = '[ruby-core:45682]'
- Readline::HISTORY << "hello"
- wo = nil
- line = with_pipe do |r, w|
- wo = w.dup
- wo.write("\C-re\ef\n")
- end
- assert_equal("hello", line, bug6601)
- ensure
- wo&.close
- return if /EditLine/n.match(Readline::VERSION)
- Readline.delete_text
- Readline::HISTORY.clear
- end
-
- def test_input_metachar_multibyte
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- unless Encoding.find("locale") == Encoding::UTF_8
- return if assert_under_utf8
- omit 'this test needs UTF-8 locale'
- end
- bug6602 = '[ruby-core:45683]'
- Readline::HISTORY << "\u3042\u3093"
- Readline::HISTORY << "\u3044\u3093"
- Readline::HISTORY << "\u3046\u3093"
- open(IO::NULL, 'w') do |null|
- IO.pipe do |r, w|
- Readline.input = r
- Readline.output = null
- w << "\cr\u3093\n\n"
- w << "\cr\u3042\u3093"
- w.reopen(IO::NULL)
- assert_equal("\u3046\u3093", Readline.readline("", true), bug6602)
- Timeout.timeout(TIMEOUT) do
- assert_equal("\u3042\u3093", Readline.readline("", true), bug6602)
- end
- assert_equal(nil, Readline.readline("", true), bug6602)
- end
- end
- ensure
- return if /EditLine/n.match(Readline::VERSION)
- Readline.delete_text
- Readline::HISTORY.clear
- end
-
- def test_refresh_line
- omit "Only when refresh_line exists" unless Readline.respond_to?(:refresh_line)
- omit unless respond_to?(:assert_ruby_status)
- bug6232 = '[ruby-core:43957] [Bug #6232] refresh_line after set_screen_size'
- with_temp_stdio do |stdin, stdout|
- replace_stdio(stdin.path, stdout.path) do
- assert_ruby_status(%w[-rreadline -], <<-'end;', bug6232)
- Readline.set_screen_size(40, 80)
- Readline.refresh_line
- end;
- end
- end
- end
-
- # TODO Green CI for arm32-linux (Travis CI), and Readline 7.0.
- def test_interrupt_in_other_thread
- # Editline and Readline 7.0 can't treat I/O that is not tty.
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- omit "Skip Readline 7.0" if Readline::VERSION == "7.0"
- omit unless respond_to?(:assert_ruby_status)
- omit if /mswin|mingw/ =~ RUBY_PLATFORM
-
- # On 32-bit machine, readline library (or libtinfo) seems to cause SEGV internally even with Readline 8.0
- # GDB Backtrace: https://gist.github.com/mame/d12b9de3bbc3f16d440c1927398d176a
- # Maybe the same issue: https://github.com/facebookresearch/nle/issues/120
- omit if /i[3-6]86-linux/ =~ RUBY_PLATFORM
-
- if defined?(TestReadline) && self.class == TestReadline
- use = "use_ext_readline"
- elsif defined?(TestRelineAsReadline) && self.class == TestRelineAsReadline
- use = "use_lib_reline"
- end
- code = <<-"end;"
- $stdout.sync = true
- require 'readline'
- require 'helper'
- #{use}
- puts "Readline::VERSION is \#{Readline::VERSION}."
- Readline.input = STDIN
- # 0. Send SIGINT to this script.
- begin
- Thread.new{
- trap(:INT) {
- puts 'TRAP' # 2. Show 'TRAP' message.
- }
- Readline.readline('input> ') # 1. Should keep working and call old trap.
- # 4. Receive "\\n" and return because still working.
- }.value
- rescue Interrupt
- puts 'FAILED' # 3. "Interrupt" shouldn't be raised because trapped.
- raise
- end
- puts 'SUCCEEDED' # 5. Finish correctly.
- end;
-
- script = Tempfile.new("interrupt_in_other_thread")
- script.write code
- script.close
-
- log = String.new
-
- EnvUtil.invoke_ruby(["-I#{__dir__}", script.path], "", true, :merge_to_stdout) do |_in, _out, _, pid|
- Timeout.timeout(TIMEOUT) do
- log << "** START **"
- loop do
- c = _out.read(1)
- log << c if c
- break if log.include?('input> ')
- end
- log << "** SIGINT **"
- sleep 0.5
- Process.kill(:INT, pid)
- sleep 0.5
- loop do
- c = _out.read(1)
- log << c if c
- break if log.include?('TRAP')
- end
- begin
- log << "** NEWLINE **"
- _in.write "\n"
- rescue Errno::EPIPE
- log << "** Errno::EPIPE **"
- # The "write" will fail if Reline crashed by SIGINT.
- end
- interrupt_suppressed = nil
- loop do
- c = _out.read(1)
- log << c if c
- if log.include?('FAILED')
- interrupt_suppressed = false
- break
- end
- if log.include?('SUCCEEDED')
- interrupt_suppressed = true
- break
- end
- end
- assert interrupt_suppressed, "Should handle SIGINT correctly but raised interrupt.\nLog: #{log}\n----"
- end
- rescue Timeout::Error => e
- Process.kill(:KILL, pid)
- log << "\nKilled by timeout"
- assert false, "Timed out to handle SIGINT!\nLog: #{log}\nBacktrace:\n#{e.full_message(highlight: false)}\n----"
- ensure
- status = nil
- begin
- Timeout.timeout(TIMEOUT) do
- status = Process.wait2(pid).last
- end
- rescue Timeout::Error => e
- log << "\nKilled by timeout to wait2"
- Process.kill(:KILL, pid)
- assert false, "Timed out to wait for terminating a process in a test of SIGINT!\nLog: #{log}\nBacktrace:\n#{e.full_message(highlight: false)}\n----"
- end
- assert status&.success?, "Unknown failure with exit status #{status.inspect}\nLog: #{log}\n----"
- end
-
- assert log.include?('INT'), "Interrupt was handled correctly."
- ensure
- script&.close!
- end
-
- def test_setting_quoting_detection_proc
- return unless Readline.respond_to?(:quoting_detection_proc=)
-
- expected = proc { |text, index| false }
- Readline.quoting_detection_proc = expected
- assert_equal(expected, Readline.quoting_detection_proc)
-
- assert_raise(ArgumentError) do
- Readline.quoting_detection_proc = "This does not have call method."
- end
- end
-
- def test_using_quoting_detection_proc
- saved_completer_quote_characters = Readline.completer_quote_characters
- saved_completer_word_break_characters = Readline.completer_word_break_characters
-
- # skip if previous value is nil because Readline... = nil is not allowed.
- omit "No completer_quote_characters" unless saved_completer_quote_characters
- omit "No completer_word_break_characters" unless saved_completer_word_break_characters
-
- return unless Readline.respond_to?(:quoting_detection_proc=)
-
- begin
- passed_text = nil
- line = nil
-
- with_temp_stdio do |stdin, stdout|
- replace_stdio(stdin.path, stdout.path) do
- Readline.completion_proc = ->(text) do
- passed_text = text
- ['completion'].map { |i|
- i.encode(Encoding.default_external)
- }
- end
- Readline.completer_quote_characters = '\'"'
- Readline.completer_word_break_characters = ' '
- Readline.quoting_detection_proc = ->(text, index) do
- index > 0 && text[index-1] == '\\'
- end
-
- stdin.write("first second\\ third\t")
- stdin.flush
- line = Readline.readline('> ', false)
- end
- end
-
- assert_equal('second\\ third', passed_text)
- assert_equal('first completion', line.chomp(' '))
- ensure
- Readline.completer_quote_characters = saved_completer_quote_characters
- Readline.completer_word_break_characters = saved_completer_word_break_characters
- end
- end
-
- def test_using_quoting_detection_proc_with_multibyte_input
- Readline.completion_append_character = nil
- saved_completer_quote_characters = Readline.completer_quote_characters
- saved_completer_word_break_characters = Readline.completer_word_break_characters
-
- # skip if previous value is nil because Readline... = nil is not allowed.
- omit "No completer_quote_characters" unless saved_completer_quote_characters
- omit "No completer_word_break_characters" unless saved_completer_word_break_characters
-
- return unless Readline.respond_to?(:quoting_detection_proc=)
- unless get_default_internal_encoding == Encoding::UTF_8
- return if assert_under_utf8
- omit 'this test needs UTF-8 locale'
- end
-
- begin
- passed_text = nil
- escaped_char_indexes = []
- line = nil
-
- with_temp_stdio do |stdin, stdout|
- replace_stdio(stdin.path, stdout.path) do
- Readline.completion_proc = ->(text) do
- passed_text = text
- ['completion'].map { |i|
- i.encode(Encoding.default_external)
- }
- end
- Readline.completer_quote_characters = '\'"'
- Readline.completer_word_break_characters = ' '
- Readline.quoting_detection_proc = ->(text, index) do
- escaped = index > 0 && text[index-1] == '\\'
- escaped_char_indexes << index if escaped
- escaped
- end
-
- stdin.write("\u3042\u3093 second\\ third\t")
- stdin.flush
- line = Readline.readline('> ', false)
- end
- end
-
- assert_equal([10], escaped_char_indexes)
- assert_equal('second\\ third', passed_text)
- assert_equal("\u3042\u3093 completion#{Readline.completion_append_character}", line)
- ensure
- Readline.completer_quote_characters = saved_completer_quote_characters
- Readline.completer_word_break_characters = saved_completer_word_break_characters
- end
- end
-
- def test_simple_completion
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
-
- line = nil
-
- open(IO::NULL, 'w') do |null|
- IO.pipe do |r, w|
- Readline.input = r
- Readline.output = null
- Readline.completion_proc = ->(text) do
- ['abcde', 'abc12'].map { |i|
- i.encode(get_default_internal_encoding)
- }
- end
- w.write("a\t\n")
- w.flush
- begin
- stderr = $stderr.dup
- $stderr.reopen(null)
- line = Readline.readline('> ', false)
- ensure
- $stderr.reopen(stderr)
- stderr.close
- end
- end
- end
-
- assert_equal('abc', line)
- end
-
- def test_completion_with_completion_append_character
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- omit "Readline.completion_append_character is not implemented" unless Readline.respond_to?(:completion_append_character=)
- line = nil
-
- append_character = Readline.completion_append_character
- open(IO::NULL, 'w') do |null|
- IO.pipe do |r, w|
- Readline.input = r
- Readline.output = null
- Readline.completion_append_character = '!'
- Readline.completion_proc = ->(text) do
- ['abcde'].map { |i|
- i.encode(get_default_internal_encoding)
- }
- end
- w.write("a\t\n")
- w.flush
- line = Readline.readline('> ', false)
- end
- end
-
- assert_equal('abcde!', line)
- ensure
- return if /EditLine/n.match(Readline::VERSION)
- return unless Readline.respond_to?(:completion_append_character=)
- Readline.completion_append_character = append_character
- end
-
- def test_completion_quote_character_completing_unquoted_argument
- return unless Readline.respond_to?(:completion_quote_character)
-
- saved_completer_quote_characters = Readline.completer_quote_characters
-
- quote_character = "original value"
- Readline.completion_proc = -> (_) do
- quote_character = Readline.completion_quote_character
- []
- end
- Readline.completer_quote_characters = "'\""
-
- with_temp_stdio do |stdin, stdout|
- replace_stdio(stdin.path, stdout.path) do
- stdin.write("input\t")
- stdin.flush
- Readline.readline("> ", false)
- end
- end
-
- assert_nil(quote_character)
- ensure
- Readline.completer_quote_characters = saved_completer_quote_characters if saved_completer_quote_characters
- end
-
- def test_completion_quote_character_completing_quoted_argument
- return unless Readline.respond_to?(:completion_quote_character)
-
- saved_completer_quote_characters = Readline.completer_quote_characters
-
- quote_character = "original value"
- Readline.completion_proc = -> (_) do
- quote_character = Readline.completion_quote_character
- []
- end
- Readline.completer_quote_characters = "'\""
-
- with_temp_stdio do |stdin, stdout|
- replace_stdio(stdin.path, stdout.path) do
- stdin.write("'input\t")
- stdin.flush
- Readline.readline("> ", false)
- end
- end
-
- assert_equal("'", quote_character)
- ensure
- Readline.completer_quote_characters = saved_completer_quote_characters if saved_completer_quote_characters
- end
-
- def test_completion_quote_character_after_completion
- return unless Readline.respond_to?(:completion_quote_character)
- if /solaris/i =~ RUBY_PLATFORM
- # http://rubyci.s3.amazonaws.com/solaris11s-sunc/ruby-trunk/log/20181228T102505Z.fail.html.gz
- omit 'This test does not succeed on Oracle Developer Studio for now'
- end
- omit 'Needs GNU Readline 6 or later' if /mswin|mingw/ =~ RUBY_PLATFORM and defined?(TestReadline) and kind_of?(TestReadline) and Readline::VERSION < '6.0'
-
- saved_completer_quote_characters = Readline.completer_quote_characters
-
- Readline.completion_proc = -> (_) { [] }
- Readline.completer_quote_characters = "'\""
-
- with_temp_stdio do |stdin, stdout|
- replace_stdio(stdin.path, stdout.path) do
- stdin.write("'input\t")
- stdin.flush
- Readline.readline("> ", false)
- end
- end
-
- assert_nil(Readline.completion_quote_character)
- ensure
- Readline.completer_quote_characters = saved_completer_quote_characters if saved_completer_quote_characters
- end
-
- def test_without_tty
- omit "Skip Editline" if /EditLine/n.match(Readline::VERSION)
- loader = nil
- if defined?(TestReadline) && self.class == TestReadline
- loader = "use_ext_readline"
- elsif defined?(TestRelineAsReadline) && self.class == TestRelineAsReadline
- loader = "use_lib_reline"
- end
- if loader
- res, exit_status = Open3.capture2e("ruby -I#{__dir__} -Ilib -rhelper -e '#{loader}; Readline.readline(%{y or n?})'", stdin_data: "y\n")
- assert exit_status.success?, "It should work fine without tty, but it failed.\nError output:\n#{res}"
- end
- end
-
- private
-
- def replace_stdio(stdin_path, stdout_path)
- open(stdin_path, "r"){|stdin|
- open(stdout_path, "w"){|stdout|
- orig_stdin = STDIN.dup
- orig_stdout = STDOUT.dup
- orig_stderr = STDERR.dup
- STDIN.reopen(stdin)
- STDOUT.reopen(stdout)
- STDERR.reopen(stdout)
- begin
- Readline.input = STDIN
- Readline.output = STDOUT
- yield
- ensure
- STDERR.reopen(orig_stderr)
- STDIN.reopen(orig_stdin)
- STDOUT.reopen(orig_stdout)
- orig_stdin.close
- orig_stdout.close
- orig_stderr.close
- end
- }
- }
- end
-
- def with_temp_stdio
- Tempfile.create("test_readline_stdin") {|stdin|
- Tempfile.create("test_readline_stdout") {|stdout|
- yield stdin, stdout
- if /mswin|mingw/ =~ RUBY_PLATFORM
- # needed since readline holds refs to tempfiles, can't delete on Windows
- Readline.input = STDIN
- Readline.output = STDOUT
- end
- }
- }
- end
-
- def with_pipe
- stderr = nil
- IO.pipe do |r, w|
- yield(r, w)
- Readline.input = r
- Readline.output = w.reopen(IO::NULL)
- stderr = STDERR.dup
- STDERR.reopen(w)
- Readline.readline
- end
- ensure
- if stderr
- STDERR.reopen(stderr)
- stderr.close
- end
- Readline.input = STDIN
- Readline.output = STDOUT
- end
-
- def get_default_internal_encoding
- return Encoding.default_internal || Encoding.find("locale")
- end
-
- def assert_under_utf8
- return false if ENV['LC_ALL'] == 'UTF-8'
- loc = caller_locations(1, 1)[0].base_label.to_s
- assert_separately([{"LC_ALL"=>"UTF-8"}, "-r", __FILE__], <<SRC)
-#omit "test \#{ENV['LC_ALL']}"
-#{self.class.name}.new(#{loc.dump}).run(Test::Unit::Runner.new)
-SRC
- return true
- end
-end
-
-class TestReadline < Test::Unit::TestCase
- include BasetestReadline
-
- def setup
- use_ext_readline
- super
- end
-end if defined?(ReadlineSo) && ENV["TEST_READLINE_OR_RELINE"] != "Reline"
-
-class TestRelineAsReadline < Test::Unit::TestCase
- include BasetestReadline
-
- def setup
- use_lib_reline
- super
- end
-
- def teardown
- finish_using_lib_reline
- super
- end
-
- def get_default_internal_encoding
- if RUBY_PLATFORM =~ /mswin|mingw/
- Encoding.default_internal || Encoding::UTF_8
- else
- Reline::IOGate.encoding
- end
- end
-end if defined?(Reline) && ENV["TEST_READLINE_OR_RELINE"] != "Readline"
diff --git a/test/readline/test_readline_history.rb b/test/readline/test_readline_history.rb
deleted file mode 100644
index 39ad4fe85a..0000000000
--- a/test/readline/test_readline_history.rb
+++ /dev/null
@@ -1,292 +0,0 @@
-# frozen_string_literal: false
-require_relative "helper"
-require "test/unit"
-
-module BasetestReadlineHistory
- def setup
- Readline::HISTORY.clear
- end
-
- def test_to_s
- expected = "HISTORY"
- assert_equal(expected, Readline::HISTORY.to_s)
- end
-
- def test_get
- lines = push_history(5)
- lines.each_with_index do |s, i|
- assert_external_string_equal(s, Readline::HISTORY[i])
- end
- end
-
- def test_get__negative
- lines = push_history(5)
- (1..5).each do |i|
- assert_equal(lines[-i], Readline::HISTORY[-i])
- end
- end
-
- def test_get__out_of_range
- push_history(5)
- invalid_indexes = [5, 6, 100, -6, -7, -100]
- invalid_indexes.each do |i|
- assert_raise(IndexError, "i=<#{i}>") do
- Readline::HISTORY[i]
- end
- end
-
- invalid_indexes = [100_000_000_000_000_000_000,
- -100_000_000_000_000_000_000]
- invalid_indexes.each do |i|
- assert_raise(RangeError, "i=<#{i}>") do
- Readline::HISTORY[i]
- end
- end
- end
-
- def test_set
- begin
- push_history(5)
- 5.times do |i|
- expected = "set: #{i}"
- Readline::HISTORY[i] = expected
- assert_external_string_equal(expected, Readline::HISTORY[i])
- end
- rescue NotImplementedError
- end
- end
-
- def test_set__out_of_range
- assert_raise(IndexError, NotImplementedError, "index=<0>") do
- Readline::HISTORY[0] = "set: 0"
- end
-
- push_history(5)
- invalid_indexes = [5, 6, 100, -6, -7, -100]
- invalid_indexes.each do |i|
- assert_raise(IndexError, NotImplementedError, "index=<#{i}>") do
- Readline::HISTORY[i] = "set: #{i}"
- end
- end
-
- invalid_indexes = [100_000_000_000_000_000_000,
- -100_000_000_000_000_000_000]
- invalid_indexes.each do |i|
- assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do
- Readline::HISTORY[i] = "set: #{i}"
- end
- end
- end
-
- def test_push
- 5.times do |i|
- s = i.to_s
- assert_equal(Readline::HISTORY, Readline::HISTORY.push(s))
- assert_external_string_equal(s, Readline::HISTORY[i])
- end
- assert_equal(5, Readline::HISTORY.length)
- end
-
- def test_push__operator
- 5.times do |i|
- s = i.to_s
- assert_equal(Readline::HISTORY, Readline::HISTORY << s)
- assert_external_string_equal(s, Readline::HISTORY[i])
- end
- assert_equal(5, Readline::HISTORY.length)
- end
-
- def test_push__plural
- assert_equal(Readline::HISTORY, Readline::HISTORY.push("0", "1", "2", "3", "4"))
- (0..4).each do |i|
- assert_external_string_equal(i.to_s, Readline::HISTORY[i])
- end
- assert_equal(5, Readline::HISTORY.length)
-
- assert_equal(Readline::HISTORY, Readline::HISTORY.push("5", "6", "7", "8", "9"))
- (5..9).each do |i|
- assert_external_string_equal(i.to_s, Readline::HISTORY[i])
- end
- assert_equal(10, Readline::HISTORY.length)
- end
-
- def test_pop
- begin
- assert_equal(nil, Readline::HISTORY.pop)
-
- lines = push_history(5)
- (1..5).each do |i|
- assert_external_string_equal(lines[-i], Readline::HISTORY.pop)
- assert_equal(lines.length - i, Readline::HISTORY.length)
- end
-
- assert_equal(nil, Readline::HISTORY.pop)
- rescue NotImplementedError
- end
- end
-
- def test_shift
- begin
- assert_equal(nil, Readline::HISTORY.shift)
-
- lines = push_history(5)
- (0..4).each do |i|
- assert_external_string_equal(lines[i], Readline::HISTORY.shift)
- assert_equal(lines.length - (i + 1), Readline::HISTORY.length)
- end
-
- assert_equal(nil, Readline::HISTORY.shift)
- rescue NotImplementedError
- end
- end
-
- def test_each
- e = Readline::HISTORY.each do |s|
- assert(false) # not reachable
- end
- assert_equal(Readline::HISTORY, e)
- lines = push_history(5)
- i = 0
- e = Readline::HISTORY.each do |s|
- assert_external_string_equal(Readline::HISTORY[i], s)
- assert_external_string_equal(lines[i], s)
- i += 1
- end
- assert_equal(Readline::HISTORY, e)
- end
-
- def test_each__enumerator
- e = Readline::HISTORY.each
- assert_instance_of(Enumerator, e)
- end
-
- def test_length
- assert_equal(0, Readline::HISTORY.length)
- push_history(1)
- assert_equal(1, Readline::HISTORY.length)
- push_history(4)
- assert_equal(5, Readline::HISTORY.length)
- Readline::HISTORY.clear
- assert_equal(0, Readline::HISTORY.length)
- end
-
- def test_empty_p
- 2.times do
- assert(Readline::HISTORY.empty?)
- Readline::HISTORY.push("s")
- assert_equal(false, Readline::HISTORY.empty?)
- Readline::HISTORY.clear
- assert(Readline::HISTORY.empty?)
- end
- end
-
- def test_delete_at
- begin
- lines = push_history(5)
- (0..4).each do |i|
- assert_external_string_equal(lines[i], Readline::HISTORY.delete_at(0))
- end
- assert(Readline::HISTORY.empty?)
-
- lines = push_history(5)
- (1..5).each do |i|
- assert_external_string_equal(lines[lines.length - i], Readline::HISTORY.delete_at(-1))
- end
- assert(Readline::HISTORY.empty?)
-
- lines = push_history(5)
- assert_external_string_equal(lines[0], Readline::HISTORY.delete_at(0))
- assert_external_string_equal(lines[4], Readline::HISTORY.delete_at(3))
- assert_external_string_equal(lines[1], Readline::HISTORY.delete_at(0))
- assert_external_string_equal(lines[3], Readline::HISTORY.delete_at(1))
- assert_external_string_equal(lines[2], Readline::HISTORY.delete_at(0))
- assert(Readline::HISTORY.empty?)
- rescue NotImplementedError
- end
- end
-
- def test_delete_at__out_of_range
- assert_raise(IndexError, NotImplementedError, "index=<0>") do
- Readline::HISTORY.delete_at(0)
- end
-
- push_history(5)
- invalid_indexes = [5, 6, 100, -6, -7, -100]
- invalid_indexes.each do |i|
- assert_raise(IndexError, NotImplementedError, "index=<#{i}>") do
- Readline::HISTORY.delete_at(i)
- end
- end
-
- invalid_indexes = [100_000_000_000_000_000_000,
- -100_000_000_000_000_000_000]
- invalid_indexes.each do |i|
- assert_raise(RangeError, NotImplementedError, "index=<#{i}>") do
- Readline::HISTORY.delete_at(i)
- end
- end
- end
-
- private
-
- def push_history(num)
- lines = []
- num.times do |i|
- s = "a"
- i.times do
- s = s.succ
- end
- lines.push("#{i + 1}:#{s}")
- end
- Readline::HISTORY.push(*lines)
- return lines
- end
-
- def assert_external_string_equal(expected, actual)
- assert_equal(expected, actual)
- assert_equal(get_default_internal_encoding, actual.encoding)
- end
-
- def get_default_internal_encoding
- return Encoding.default_internal || Encoding.find("locale")
- end
-end
-
-class TestReadlineHistory < Test::Unit::TestCase
- include BasetestReadlineHistory
-
- def setup
- use_ext_readline
- super
- end
-end if defined?(::ReadlineSo) && defined?(::ReadlineSo::HISTORY) &&
- ENV["TEST_READLINE_OR_RELINE"] != "Reline" &&
- (
- begin
- ReadlineSo::HISTORY.clear
- rescue NotImplementedError
- false
- end
- )
-
-class TestRelineAsReadlineHistory < Test::Unit::TestCase
- include BasetestReadlineHistory
-
- def setup
- use_lib_reline
- super
- end
-
- def teardown
- finish_using_lib_reline
- super
- end
-
- def get_default_internal_encoding
- if RUBY_PLATFORM =~ /mswin|mingw/
- Encoding.default_internal || Encoding::UTF_8
- else
- Reline::IOGate.encoding
- end
- end
-end if defined?(Reline) && ENV["TEST_READLINE_OR_RELINE"] != "Readline"
diff --git a/test/reline/helper.rb b/test/reline/helper.rb
index e8b8e3a6e1..f2f3421ded 100644
--- a/test/reline/helper.rb
+++ b/test/reline/helper.rb
@@ -5,33 +5,77 @@ ENV['TERM'] = 'xterm' # for some CI environments
require 'reline'
require 'test/unit'
+begin
+ require 'rbconfig'
+rescue LoadError
+end
+
+begin
+ # This should exist and available in load path when this file is mirrored to ruby/ruby and running at there
+ if File.exist?(File.expand_path('../../tool/lib/envutil.rb', __dir__))
+ require 'envutil'
+ end
+rescue LoadError
+end
+
module Reline
class <<self
- def test_mode
- remove_const('IOGate') if const_defined?('IOGate')
- const_set('IOGate', Reline::GeneralIO)
- if ENV['RELINE_TEST_ENCODING']
- encoding = Encoding.find(ENV['RELINE_TEST_ENCODING'])
- else
- encoding = Encoding::UTF_8
- end
- Reline::GeneralIO.reset(encoding: encoding)
- send(:core).config.instance_variable_set(:@test_mode, true)
- send(:core).config.reset
+ def test_mode(ansi: false)
+ @original_iogate = IOGate
+ remove_const('IOGate')
+ const_set('IOGate', ansi ? Reline::ANSI : Reline::GeneralIO)
+ if ENV['RELINE_TEST_ENCODING']
+ encoding = Encoding.find(ENV['RELINE_TEST_ENCODING'])
+ else
+ encoding = Encoding::UTF_8
+ end
+ @original_get_screen_size = IOGate.method(:get_screen_size)
+ IOGate.singleton_class.remove_method(:get_screen_size)
+ def IOGate.get_screen_size
+ [24, 80]
+ end
+ Reline::GeneralIO.reset(encoding: encoding) unless ansi
+ core.config.instance_variable_set(:@test_mode, true)
+ core.config.reset
end
def test_reset
+ IOGate.singleton_class.remove_method(:get_screen_size)
+ IOGate.define_singleton_method(:get_screen_size, @original_get_screen_size)
+ remove_const('IOGate')
+ const_set('IOGate', @original_iogate)
+ Reline::GeneralIO.reset
Reline.instance_variable_set(:@core, nil)
end
- end
-end
-def start_pasting
- Reline::GeneralIO.start_pasting
-end
+ # Return a executable name to spawn Ruby process. In certain build configuration,
+ # "ruby" may not be available.
+ def test_rubybin
+ # When this test suite is running in ruby/ruby, prefer EnvUtil result over original implementation
+ if const_defined?(:EnvUtil)
+ return EnvUtil.rubybin
+ end
-def finish_pasting
- Reline::GeneralIO.finish_pasting
+ # The following is a simplified port of EnvUtil.rubybin in ruby/ruby
+ if ruby = ENV["RUBY"]
+ return ruby
+ end
+ ruby = "ruby"
+ exeext = RbConfig::CONFIG["EXEEXT"]
+ rubyexe = (ruby + exeext if exeext and !exeext.empty?)
+ if File.exist? ruby and File.executable? ruby and !File.directory? ruby
+ return File.expand_path(ruby)
+ end
+ if rubyexe and File.exist? rubyexe and File.executable? rubyexe
+ return File.expand_path(rubyexe)
+ end
+ if defined?(RbConfig.ruby)
+ RbConfig.ruby
+ else
+ "ruby"
+ end
+ end
+ end
end
class Reline::TestCase < Test::Unit::TestCase
@@ -84,9 +128,14 @@ class Reline::TestCase < Test::Unit::TestCase
end
end
- def assert_line(expected)
- expected = convert_str(expected)
- assert_equal(expected, @line_editor.line)
+ def assert_line_around_cursor(before, after)
+ before = convert_str(before)
+ after = convert_str(after)
+ line = @line_editor.line
+ byte_pointer = @line_editor.instance_variable_get(:@byte_pointer)
+ actual_before = line.byteslice(0, byte_pointer)
+ actual_after = line.byteslice(byte_pointer..)
+ assert_equal([before, after], [actual_before, actual_after])
end
def assert_byte_pointer_size(expected)
@@ -101,25 +150,18 @@ class Reline::TestCase < Test::Unit::TestCase
EOM
end
- def assert_cursor(expected)
- assert_equal(expected, @line_editor.instance_variable_get(:@cursor))
- end
-
- def assert_cursor_max(expected)
- assert_equal(expected, @line_editor.instance_variable_get(:@cursor_max))
- end
-
def assert_line_index(expected)
assert_equal(expected, @line_editor.instance_variable_get(:@line_index))
end
def assert_whole_lines(expected)
- previous_line_index = @line_editor.instance_variable_get(:@previous_line_index)
- if previous_line_index
- lines = @line_editor.whole_lines(index: previous_line_index)
- else
- lines = @line_editor.whole_lines
+ assert_equal(expected, @line_editor.whole_lines)
+ end
+
+ def assert_key_binding(input, method_symbol, editing_modes = [:emacs, :vi_insert, :vi_command])
+ editing_modes.each do |editing_mode|
+ @config.editing_mode = editing_mode
+ assert_equal(method_symbol, @config.editing_mode.default_key_bindings[input.bytes])
end
- assert_equal(expected, lines)
end
end
diff --git a/test/reline/test_ansi_with_terminfo.rb b/test/reline/test_ansi_with_terminfo.rb
new file mode 100644
index 0000000000..e1c56b9ee1
--- /dev/null
+++ b/test/reline/test_ansi_with_terminfo.rb
@@ -0,0 +1,112 @@
+require_relative 'helper'
+require 'reline/ansi'
+
+class Reline::ANSI::TestWithTerminfo < Reline::TestCase
+ def setup
+ Reline.send(:test_mode, ansi: true)
+ @config = Reline::Config.new
+ Reline.core.io_gate.set_default_key_bindings(@config, allow_terminfo: true)
+ end
+
+ def teardown
+ Reline.test_reset
+ end
+
+ # Home key
+ def test_khome
+ assert_key_binding(Reline::Terminfo.tigetstr('khome'), :ed_move_to_beg)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # End key
+ def test_kend
+ assert_key_binding(Reline::Terminfo.tigetstr('kend'), :ed_move_to_end)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Delete key
+ def test_kdch1
+ assert_key_binding(Reline::Terminfo.tigetstr('kdch1'), :key_delete)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # PgUp key
+ def test_kpp
+ assert_key_binding(Reline::Terminfo.tigetstr('kpp'), :ed_search_prev_history)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # PgDn key
+ def test_knp
+ assert_key_binding(Reline::Terminfo.tigetstr('knp'), :ed_search_next_history)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Up arrow key
+ def test_kcuu1
+ assert_key_binding(Reline::Terminfo.tigetstr('kcuu1'), :ed_prev_history)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Down arrow key
+ def test_kcud1
+ assert_key_binding(Reline::Terminfo.tigetstr('kcud1'), :ed_next_history)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Right arrow key
+ def test_kcuf1
+ assert_key_binding(Reline::Terminfo.tigetstr('kcuf1'), :ed_next_char)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Left arrow key
+ def test_kcub1
+ assert_key_binding(Reline::Terminfo.tigetstr('kcub1'), :ed_prev_char)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Home and End; always mapped regardless of terminfo enabled or not
+ def test_home_end
+ assert_key_binding("\e[H", :ed_move_to_beg)
+ assert_key_binding("\e[F", :ed_move_to_end)
+ end
+
+ # Arrow; always mapped regardless of terminfo enabled or not
+ def test_arrow
+ assert_key_binding("\e[A", :ed_prev_history)
+ assert_key_binding("\e[B", :ed_next_history)
+ assert_key_binding("\e[C", :ed_next_char)
+ assert_key_binding("\e[D", :ed_prev_char)
+ end
+
+ # Ctrl+arrow and Meta+arrow; always mapped regardless of terminfo enabled or not
+ def test_extended
+ assert_key_binding("\e[1;5C", :em_next_word) # Ctrl+→
+ assert_key_binding("\e[1;5D", :ed_prev_word) # Ctrl+←
+ assert_key_binding("\e[1;3C", :em_next_word) # Meta+→
+ assert_key_binding("\e[1;3D", :ed_prev_word) # Meta+←
+ assert_key_binding("\e\e[C", :em_next_word) # Meta+→
+ assert_key_binding("\e\e[D", :ed_prev_word) # Meta+←
+ end
+
+ # Shift-Tab; always mapped regardless of terminfo enabled or not
+ def test_shift_tab
+ assert_key_binding("\e[Z", :completion_journey_up, [:emacs, :vi_insert])
+ end
+
+ # A few emacs bindings that are always mapped regardless of terminfo enabled or not
+ def test_more_emacs
+ assert_key_binding("\e ", :em_set_mark, [:emacs])
+ assert_key_binding("\C-x\C-x", :em_exchange_mark, [:emacs])
+ end
+end if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
diff --git a/test/reline/test_ansi_without_terminfo.rb b/test/reline/test_ansi_without_terminfo.rb
new file mode 100644
index 0000000000..3d153514f3
--- /dev/null
+++ b/test/reline/test_ansi_without_terminfo.rb
@@ -0,0 +1,77 @@
+require_relative 'helper'
+require 'reline/ansi'
+
+class Reline::ANSI::TestWithoutTerminfo < Reline::TestCase
+ def setup
+ Reline.send(:test_mode, ansi: true)
+ @config = Reline::Config.new
+ Reline.core.io_gate.set_default_key_bindings(@config, allow_terminfo: false)
+ end
+
+ def teardown
+ Reline.test_reset
+ end
+
+ def test_home
+ assert_key_binding("\e[1~", :ed_move_to_beg) # Console (80x25)
+ assert_key_binding("\e[H", :ed_move_to_beg) # KDE
+ assert_key_binding("\e[7~", :ed_move_to_beg) # urxvt / exoterm
+ assert_key_binding("\eOH", :ed_move_to_beg) # GNOME
+ end
+
+ def test_end
+ assert_key_binding("\e[4~", :ed_move_to_end) # Console (80x25)
+ assert_key_binding("\e[F", :ed_move_to_end) # KDE
+ assert_key_binding("\e[8~", :ed_move_to_end) # urxvt / exoterm
+ assert_key_binding("\eOF", :ed_move_to_end) # GNOME
+ end
+
+ def test_delete
+ assert_key_binding("\e[3~", :key_delete)
+ end
+
+ def test_up_arrow
+ assert_key_binding("\e[A", :ed_prev_history) # Console (80x25)
+ assert_key_binding("\eGA", :ed_prev_history) # KDE
+ assert_key_binding("\eOA", :ed_prev_history)
+ end
+
+ def test_down_arrow
+ assert_key_binding("\e[B", :ed_next_history) # Console (80x25)
+ assert_key_binding("\eGB", :ed_next_history) # KDE
+ assert_key_binding("\eOB", :ed_next_history)
+ end
+
+ def test_right_arrow
+ assert_key_binding("\e[C", :ed_next_char) # Console (80x25)
+ assert_key_binding("\eGC", :ed_next_char) # KDE
+ assert_key_binding("\eOC", :ed_next_char)
+ end
+
+ def test_left_arrow
+ assert_key_binding("\e[D", :ed_prev_char) # Console (80x25)
+ assert_key_binding("\eGD", :ed_prev_char) # KDE
+ assert_key_binding("\eOD", :ed_prev_char)
+ end
+
+ # Ctrl+arrow and Meta+arrow; always mapped regardless of terminfo enabled or not
+ def test_extended
+ assert_key_binding("\e[1;5C", :em_next_word) # Ctrl+→
+ assert_key_binding("\e[1;5D", :ed_prev_word) # Ctrl+←
+ assert_key_binding("\e[1;3C", :em_next_word) # Meta+→
+ assert_key_binding("\e[1;3D", :ed_prev_word) # Meta+←
+ assert_key_binding("\e\e[C", :em_next_word) # Meta+→
+ assert_key_binding("\e\e[D", :ed_prev_word) # Meta+←
+ end
+
+ # Shift-Tab; always mapped regardless of terminfo enabled or not
+ def test_shift_tab
+ assert_key_binding("\e[Z", :completion_journey_up, [:emacs, :vi_insert])
+ end
+
+ # A few emacs bindings that are always mapped regardless of terminfo enabled or not
+ def test_more_emacs
+ assert_key_binding("\e ", :em_set_mark, [:emacs])
+ assert_key_binding("\C-x\C-x", :em_exchange_mark, [:emacs])
+ end
+end
diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb
index 6b4dca0b28..9ead047ce4 100644
--- a/test/reline/test_config.rb
+++ b/test/reline/test_config.rb
@@ -85,7 +85,7 @@ class Reline::Config::Test < Reline::TestCase
def test_encoding_is_ascii
@config.reset
- Reline::IOGate.reset(encoding: Encoding::US_ASCII)
+ Reline.core.io_gate.reset(encoding: Encoding::US_ASCII)
@config = Reline::Config.new
assert_equal true, @config.convert_meta
@@ -93,7 +93,7 @@ class Reline::Config::Test < Reline::TestCase
def test_encoding_is_not_ascii
@config.reset
- Reline::IOGate.reset(encoding: Encoding::UTF_8)
+ Reline.core.io_gate.reset(encoding: Encoding::UTF_8)
@config = Reline::Config.new
assert_equal nil, @config.convert_meta
@@ -160,6 +160,23 @@ class Reline::Config::Test < Reline::TestCase
assert_equal :audible, @config.instance_variable_get(:@bell_style)
end
+ def test_include_expand_path
+ home_backup = ENV['HOME']
+ File.open('included_partial', 'wt') do |f|
+ f.write(<<~PARTIAL_LINES)
+ set bell-style on
+ PARTIAL_LINES
+ end
+ ENV['HOME'] = Dir.pwd
+ @config.read_lines(<<~LINES.lines)
+ $include ~/included_partial
+ LINES
+
+ assert_equal :audible, @config.instance_variable_get(:@bell_style)
+ ensure
+ ENV['HOME'] = home_backup
+ end
+
def test_if
@config.read_lines(<<~LINES.lines)
$if Ruby
@@ -408,19 +425,5 @@ class Reline::Config::Test < Reline::TestCase
ENV['XDG_CONFIG_HOME'] = xdg_config_home_backup
ENV['HOME'] = home_backup
end
-
- def test_dialog_configurations
- @config.read_lines(<<~LINES.lines)
- set dialog-default-bg-color white
- set dialog-highlight-bg-color black
- set dialog-default-fg-color cyan
- set dialog-highlight-fg-color magenta
- LINES
-
- assert_equal :white, @config.dialog_default_bg_color
- assert_equal :black, @config.dialog_highlight_bg_color
- assert_equal :cyan, @config.dialog_default_fg_color
- assert_equal :magenta, @config.dialog_highlight_fg_color
- end
end
diff --git a/test/reline/test_face.rb b/test/reline/test_face.rb
new file mode 100644
index 0000000000..8fa2be8fa4
--- /dev/null
+++ b/test/reline/test_face.rb
@@ -0,0 +1,257 @@
+# frozen_string_literal: true
+
+require_relative 'helper'
+
+class Reline::Face::Test < Reline::TestCase
+ RESET_SGR = "\e[0m"
+
+ def setup
+ @colorterm_backup = ENV['COLORTERM']
+ ENV['COLORTERM'] = 'truecolor'
+ end
+
+ def teardown
+ Reline::Face.reset_to_initial_configs
+ ENV['COLORTERM'] = @colorterm_backup
+ end
+
+ class WithInsufficientSetupTest < self
+ def setup
+ super
+ Reline::Face.config(:my_insufficient_config) do |face|
+ end
+ @face = Reline::Face[:my_insufficient_config]
+ end
+
+ def test_my_insufficient_config_line
+ assert_equal RESET_SGR, @face[:default]
+ assert_equal RESET_SGR, @face[:enhanced]
+ assert_equal RESET_SGR, @face[:scrollbar]
+ end
+
+ def test_my_insufficient_configs
+ my_configs = Reline::Face.configs[:my_insufficient_config]
+ assert_equal(
+ {
+ default: { style: :reset, escape_sequence: RESET_SGR },
+ enhanced: { style: :reset, escape_sequence: RESET_SGR },
+ scrollbar: { style: :reset, escape_sequence: RESET_SGR }
+ },
+ my_configs
+ )
+ end
+ end
+
+ class WithSetupTest < self
+ def setup
+ super
+ Reline::Face.config(:my_config) do |face|
+ face.define :default, foreground: :blue
+ face.define :enhanced, foreground: "#FF1020", background: :black, style: [:bold, :underlined]
+ end
+ Reline::Face.config(:another_config) do |face|
+ face.define :another_label, foreground: :red
+ end
+ @face = Reline::Face[:my_config]
+ end
+
+ def test_now_there_are_four_configs
+ assert_equal %i(default completion_dialog my_config another_config), Reline::Face.configs.keys
+ end
+
+ def test_resetting_config_discards_user_defined_configs
+ Reline::Face.reset_to_initial_configs
+ assert_equal %i(default completion_dialog), Reline::Face.configs.keys
+ end
+
+ def test_my_configs
+ my_configs = Reline::Face.configs[:my_config]
+ assert_equal(
+ {
+ default: {
+ escape_sequence: "#{RESET_SGR}\e[34m", foreground: :blue
+ },
+ enhanced: {
+ background: :black,
+ foreground: "#FF1020",
+ style: [:bold, :underlined],
+ escape_sequence: "\e[0m\e[38;2;255;16;32;40;1;4m"
+ },
+ scrollbar: {
+ style: :reset,
+ escape_sequence: "\e[0m"
+ }
+ },
+ my_configs
+ )
+ end
+
+ def test_my_config_line
+ assert_equal "#{RESET_SGR}\e[34m", @face[:default]
+ end
+
+ def test_my_config_enhanced
+ assert_equal "#{RESET_SGR}\e[38;2;255;16;32;40;1;4m", @face[:enhanced]
+ end
+
+ def test_not_respond_to_another_label
+ assert_equal false, @face.respond_to?(:another_label)
+ end
+ end
+
+ class WithoutSetupTest < self
+ def test_my_config_default
+ Reline::Face.config(:my_config) do |face|
+ # do nothing
+ end
+ face = Reline::Face[:my_config]
+ assert_equal RESET_SGR, face[:default]
+ end
+
+ def test_style_does_not_exist
+ face = Reline::Face[:default]
+ assert_raise ArgumentError do
+ face[:style_does_not_exist]
+ end
+ end
+
+ def test_invalid_keyword
+ assert_raise ArgumentError do
+ Reline::Face.config(:invalid_config) do |face|
+ face.define :default, invalid_keyword: :red
+ end
+ end
+ end
+
+ def test_invalid_foreground_name
+ assert_raise ArgumentError do
+ Reline::Face.config(:invalid_config) do |face|
+ face.define :default, foreground: :invalid_name
+ end
+ end
+ end
+
+ def test_invalid_background_name
+ assert_raise ArgumentError do
+ Reline::Face.config(:invalid_config) do |face|
+ face.define :default, background: :invalid_name
+ end
+ end
+ end
+
+ def test_invalid_style_name
+ assert_raise ArgumentError do
+ Reline::Face.config(:invalid_config) do |face|
+ face.define :default, style: :invalid_name
+ end
+ end
+ end
+
+ def test_private_constants
+ [:SGR_PARAMETER, :Config, :CONFIGS].each do |name|
+ assert_equal false, Reline::Face.constants.include?(name)
+ end
+ end
+ end
+
+ class ConfigTest < self
+ def setup
+ super
+ @config = Reline::Face.const_get(:Config).new(:my_config) { }
+ end
+
+ def teardown
+ super
+ Reline::Face.instance_variable_set(:@force_truecolor, nil)
+ end
+
+ def test_rgb?
+ assert_equal true, @config.send(:rgb_expression?, "#FFFFFF")
+ end
+
+ def test_invalid_rgb?
+ assert_equal false, @config.send(:rgb_expression?, "FFFFFF")
+ assert_equal false, @config.send(:rgb_expression?, "#FFFFF")
+ end
+
+ def test_format_to_sgr_preserves_order
+ assert_equal(
+ "#{RESET_SGR}\e[37;41;1;3m",
+ @config.send(:format_to_sgr, foreground: :white, background: :red, style: [:bold, :italicized])
+ )
+
+ assert_equal(
+ "#{RESET_SGR}\e[37;1;3;41m",
+ @config.send(:format_to_sgr, foreground: :white, style: [:bold, :italicized], background: :red)
+ )
+ end
+
+ def test_format_to_sgr_with_reset
+ assert_equal(
+ RESET_SGR,
+ @config.send(:format_to_sgr, style: :reset)
+ )
+ assert_equal(
+ "#{RESET_SGR}\e[37;0;41m",
+ @config.send(:format_to_sgr, foreground: :white, style: :reset, background: :red)
+ )
+ end
+
+ def test_format_to_sgr_with_single_style
+ assert_equal(
+ "#{RESET_SGR}\e[37;41;1m",
+ @config.send(:format_to_sgr, foreground: :white, background: :red, style: :bold)
+ )
+ end
+
+ def test_truecolor
+ ENV['COLORTERM'] = 'truecolor'
+ assert_equal true, Reline::Face.truecolor?
+ ENV['COLORTERM'] = '24bit'
+ assert_equal true, Reline::Face.truecolor?
+ ENV['COLORTERM'] = nil
+ assert_equal false, Reline::Face.truecolor?
+ Reline::Face.force_truecolor
+ assert_equal true, Reline::Face.truecolor?
+ end
+
+ def test_sgr_rgb_truecolor
+ ENV['COLORTERM'] = 'truecolor'
+ assert_equal "38;2;255;255;255", @config.send(:sgr_rgb, :foreground, "#ffffff")
+ assert_equal "48;2;18;52;86", @config.send(:sgr_rgb, :background, "#123456")
+ end
+
+ def test_sgr_rgb_256color
+ ENV['COLORTERM'] = nil
+ assert_equal '38;5;231', @config.send(:sgr_rgb, :foreground, '#ffffff')
+ assert_equal '48;5;16', @config.send(:sgr_rgb, :background, '#000000')
+ # Color steps are [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff]
+ assert_equal '38;5;24', @config.send(:sgr_rgb, :foreground, '#005f87')
+ assert_equal '38;5;67', @config.send(:sgr_rgb, :foreground, '#5f87af')
+ assert_equal '48;5;110', @config.send(:sgr_rgb, :background, '#87afd7')
+ assert_equal '48;5;153', @config.send(:sgr_rgb, :background, '#afd7ff')
+ # Boundary values are [0x30, 0x73, 0x9b, 0xc3, 0xeb]
+ assert_equal '38;5;24', @config.send(:sgr_rgb, :foreground, '#2f729a')
+ assert_equal '38;5;67', @config.send(:sgr_rgb, :foreground, '#30739b')
+ assert_equal '48;5;110', @config.send(:sgr_rgb, :background, '#9ac2ea')
+ assert_equal '48;5;153', @config.send(:sgr_rgb, :background, '#9bc3eb')
+ end
+
+ def test_force_truecolor_reconfigure
+ ENV['COLORTERM'] = nil
+
+ Reline::Face.config(:my_config) do |face|
+ face.define :default, foreground: '#005f87'
+ face.define :enhanced, background: '#afd7ff'
+ end
+
+ assert_equal "\e[0m\e[38;5;24m", Reline::Face[:my_config][:default]
+ assert_equal "\e[0m\e[48;5;153m", Reline::Face[:my_config][:enhanced]
+
+ Reline::Face.force_truecolor
+
+ assert_equal "\e[0m\e[38;2;0;95;135m", Reline::Face[:my_config][:default]
+ assert_equal "\e[0m\e[48;2;175;215;255m", Reline::Face[:my_config][:enhanced]
+ end
+ end
+end
diff --git a/test/reline/test_history.rb b/test/reline/test_history.rb
index 53360409bc..ddf8fb1472 100644
--- a/test/reline/test_history.rb
+++ b/test/reline/test_history.rb
@@ -297,7 +297,7 @@ class Reline::History::Test < Reline::TestCase
end
def get_default_internal_encoding
- if encoding = Reline::IOGate.encoding
+ if encoding = Reline.core.encoding
encoding
elsif RUBY_PLATFORM =~ /mswin|mingw/
Encoding.default_internal || Encoding::UTF_8
diff --git a/test/reline/test_key_actor_emacs.rb b/test/reline/test_key_actor_emacs.rb
index 40b26e5058..a9baf9ad37 100644
--- a/test/reline/test_key_actor_emacs.rb
+++ b/test/reline/test_key_actor_emacs.rb
@@ -8,7 +8,7 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
@config.autocompletion = false
Reline::HISTORY.instance_variable_set(:@config, @config)
Reline::HISTORY.clear
- @encoding = Reline::IOGate.encoding
+ @encoding = Reline.core.encoding
@line_editor = Reline::LineEditor.new(@config, @encoding)
@line_editor.reset(@prompt, encoding: @encoding)
end
@@ -19,1234 +19,699 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
def test_ed_insert_one
input_keys('a')
- assert_line('a')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(1)
+ assert_line_around_cursor('a', '')
end
def test_ed_insert_two
input_keys('ab')
- assert_line('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
end
def test_ed_insert_mbchar_one
input_keys('か')
- assert_line('か')
- assert_byte_pointer_size('か')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('か', '')
end
def test_ed_insert_mbchar_two
input_keys('かき')
- assert_line('かき')
- assert_byte_pointer_size('かき')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('かき', '')
end
def test_ed_insert_for_mbchar_by_plural_code_points
input_keys("か\u3099")
- assert_line("か\u3099")
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor("か\u3099", '')
end
def test_ed_insert_for_plural_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099")
- assert_line("か\u3099き\u3099")
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor("か\u3099き\u3099", '')
end
def test_move_next_and_prev
input_keys('abd')
- assert_byte_pointer_size('abd')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abd', '')
input_keys("\C-b", false)
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(3)
+ assert_line_around_cursor('ab', 'd')
input_keys("\C-b", false)
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(3)
+ assert_line_around_cursor('a', 'bd')
input_keys("\C-f", false)
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(3)
+ assert_line_around_cursor('ab', 'd')
input_keys('c')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(4)
- assert_line('abcd')
+ assert_line_around_cursor('abc', 'd')
end
def test_move_next_and_prev_for_mbchar
input_keys('かきけ')
- assert_byte_pointer_size('かきけ')
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor('かきけ', '')
input_keys("\C-b", false)
- assert_byte_pointer_size('かき')
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor('かき', 'け')
input_keys("\C-b", false)
- assert_byte_pointer_size('か')
- assert_cursor(2)
- assert_cursor_max(6)
+ assert_line_around_cursor('か', 'きけ')
input_keys("\C-f", false)
- assert_byte_pointer_size('かき')
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor('かき', 'け')
input_keys('く')
- assert_byte_pointer_size('かきく')
- assert_cursor(6)
- assert_cursor_max(8)
- assert_line('かきくけ')
+ assert_line_around_cursor('かきく', 'け')
end
def test_move_next_and_prev_for_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099け\u3099")
- assert_byte_pointer_size("か\u3099き\u3099け\u3099")
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099き\u3099け\u3099", '')
input_keys("\C-b", false)
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099き\u3099", "け\u3099")
input_keys("\C-b", false)
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099", "き\u3099け\u3099")
input_keys("\C-f", false)
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099き\u3099", "け\u3099")
input_keys("く\u3099")
- assert_byte_pointer_size("か\u3099き\u3099く\u3099")
- assert_cursor(6)
- assert_cursor_max(8)
- assert_line("か\u3099き\u3099く\u3099け\u3099")
+ assert_line_around_cursor("か\u3099き\u3099く\u3099", "け\u3099")
end
def test_move_to_beg_end
input_keys('bcd')
- assert_byte_pointer_size('bcd')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('bcd', '')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
+ assert_line_around_cursor('', 'bcd')
input_keys('a')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(4)
+ assert_line_around_cursor('a', 'bcd')
input_keys("\C-e", false)
- assert_byte_pointer_size('abcd')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('abcd', '')
input_keys('e')
- assert_byte_pointer_size('abcde')
- assert_cursor(5)
- assert_cursor_max(5)
- assert_line('abcde')
+ assert_line_around_cursor('abcde', '')
end
def test_ed_newline_with_cr
input_keys('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
refute(@line_editor.finished?)
input_keys("\C-m", false)
- assert_line('ab')
+ assert_line_around_cursor('ab', '')
assert(@line_editor.finished?)
end
def test_ed_newline_with_lf
input_keys('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
refute(@line_editor.finished?)
input_keys("\C-j", false)
- assert_line('ab')
+ assert_line_around_cursor('ab', '')
assert(@line_editor.finished?)
end
def test_em_delete_prev_char
input_keys('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
input_keys("\C-h", false)
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(1)
- assert_line('a')
+ assert_line_around_cursor('a', '')
end
def test_em_delete_prev_char_for_mbchar
input_keys('かき')
- assert_byte_pointer_size('かき')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('かき', '')
input_keys("\C-h", false)
- assert_byte_pointer_size('か')
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line('か')
+ assert_line_around_cursor('か', '')
end
def test_em_delete_prev_char_for_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099")
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor("か\u3099き\u3099", '')
input_keys("\C-h", false)
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line("か\u3099")
+ assert_line_around_cursor("か\u3099", '')
end
def test_ed_quoted_insert
input_keys("ab\C-v\C-acd")
- assert_line("ab\C-acd")
- assert_byte_pointer_size("ab\C-acd")
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor("ab\C-acd", '')
input_keys("\C-q\C-b")
- assert_line("ab\C-acd\C-b")
- assert_byte_pointer_size("ab\C-acd\C-b")
- assert_cursor(8)
- assert_cursor_max(8)
+ assert_line_around_cursor("ab\C-acd\C-b", '')
end
def test_ed_kill_line
input_keys("\C-k", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('abc')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abc', '')
input_keys("\C-k", false)
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('abc')
+ assert_line_around_cursor('abc', '')
input_keys("\C-b\C-k", false)
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line('ab')
+ assert_line_around_cursor('ab', '')
end
def test_em_kill_line
@line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('abc')
@line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('abc')
input_keys("\C-b", false)
@line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('abc')
input_keys("\C-a", false)
@line_editor.input_key(Reline::Key.new(:em_kill_line, :em_kill_line, false))
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_ed_move_to_beg
input_keys('abd')
- assert_byte_pointer_size('abd')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abd', '')
input_keys("\C-b", false)
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(3)
+ assert_line_around_cursor('ab', 'd')
input_keys('c')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(4)
+ assert_line_around_cursor('abc', 'd')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(4)
+ assert_line_around_cursor('', 'abcd')
input_keys('012')
- assert_byte_pointer_size('012')
- assert_cursor(3)
- assert_cursor_max(7)
- assert_line('012abcd')
+ assert_line_around_cursor('012', 'abcd')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(7)
+ assert_line_around_cursor('', '012abcd')
input_keys('ABC')
- assert_byte_pointer_size('ABC')
- assert_cursor(3)
- assert_cursor_max(10)
- assert_line('ABC012abcd')
+ assert_line_around_cursor('ABC', '012abcd')
input_keys("\C-f" * 10 + "\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(10)
+ assert_line_around_cursor('', 'ABC012abcd')
input_keys('a')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(11)
- assert_line('aABC012abcd')
+ assert_line_around_cursor('a', 'ABC012abcd')
end
def test_ed_move_to_beg_with_blank
input_keys(' abc')
- assert_byte_pointer_size(' abc')
- assert_cursor(5)
- assert_cursor_max(5)
+ assert_line_around_cursor(' abc', '')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
+ assert_line_around_cursor('', ' abc')
end
def test_ed_move_to_end
input_keys('abd')
- assert_byte_pointer_size('abd')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abd', '')
input_keys("\C-b", false)
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(3)
+ assert_line_around_cursor('ab', 'd')
input_keys('c')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(4)
+ assert_line_around_cursor('abc', 'd')
input_keys("\C-e", false)
- assert_byte_pointer_size('abcd')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('abcd', '')
input_keys('012')
- assert_byte_pointer_size('abcd012')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('abcd012')
+ assert_line_around_cursor('abcd012', '')
input_keys("\C-e", false)
- assert_byte_pointer_size('abcd012')
- assert_cursor(7)
- assert_cursor_max(7)
+ assert_line_around_cursor('abcd012', '')
input_keys('ABC')
- assert_byte_pointer_size('abcd012ABC')
- assert_cursor(10)
- assert_cursor_max(10)
- assert_line('abcd012ABC')
+ assert_line_around_cursor('abcd012ABC', '')
input_keys("\C-b" * 10 + "\C-e", false)
- assert_byte_pointer_size('abcd012ABC')
- assert_cursor(10)
- assert_cursor_max(10)
+ assert_line_around_cursor('abcd012ABC', '')
input_keys('a')
- assert_byte_pointer_size('abcd012ABCa')
- assert_cursor(11)
- assert_cursor_max(11)
- assert_line('abcd012ABCa')
+ assert_line_around_cursor('abcd012ABCa', '')
end
def test_em_delete
input_keys('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
+ assert_line_around_cursor('', 'ab')
input_keys("\C-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(1)
- assert_line('b')
+ assert_line_around_cursor('', 'b')
end
def test_em_delete_for_mbchar
input_keys('かき')
- assert_byte_pointer_size('かき')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('かき', '')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(4)
+ assert_line_around_cursor('', 'かき')
input_keys("\C-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
- assert_line('き')
+ assert_line_around_cursor('', 'き')
end
def test_em_delete_for_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099")
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor("か\u3099き\u3099", '')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(4)
+ assert_line_around_cursor('', "か\u3099き\u3099")
input_keys("\C-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
- assert_line("き\u3099")
+ assert_line_around_cursor('', "き\u3099")
+ end
+
+ def test_em_delete_ends_editing
+ input_keys("\C-d") # quit from inputing
+ assert_nil(@line_editor.line)
+ assert(@line_editor.finished?)
end
def test_ed_clear_screen
- refute(@line_editor.instance_variable_get(:@cleared))
+ @line_editor.instance_variable_get(:@rendered_screen).lines = [[]]
input_keys("\C-l", false)
- assert(@line_editor.instance_variable_get(:@cleared))
+ assert_empty(@line_editor.instance_variable_get(:@rendered_screen).lines)
end
def test_ed_clear_screen_with_inputed
input_keys('abc')
input_keys("\C-b", false)
- refute(@line_editor.instance_variable_get(:@cleared))
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(3)
+ @line_editor.instance_variable_get(:@rendered_screen).lines = [[]]
+ assert_line_around_cursor('ab', 'c')
input_keys("\C-l", false)
- assert(@line_editor.instance_variable_get(:@cleared))
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(3)
- assert_line('abc')
+ assert_empty(@line_editor.instance_variable_get(:@rendered_screen).lines)
+ assert_line_around_cursor('ab', 'c')
+ end
+
+ def test_key_delete
+ input_keys('abc')
+ assert_line_around_cursor('abc', '')
+ @line_editor.input_key(Reline::Key.new(:key_delete, :key_delete, false))
+ assert_line_around_cursor('abc', '')
+ end
+
+ def test_key_delete_does_not_end_editing
+ @line_editor.input_key(Reline::Key.new(:key_delete, :key_delete, false))
+ assert_line_around_cursor('', '')
+ refute(@line_editor.finished?)
end
- def test_ed_delete_next_char
+ def test_key_delete_preserves_cursor
input_keys('abc')
- assert_cursor(3)
- assert_cursor_max(3)
+ input_keys("\C-b", false)
+ assert_line_around_cursor('ab', 'c')
@line_editor.input_key(Reline::Key.new(:key_delete, :key_delete, false))
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('abc')
+ assert_line_around_cursor('ab', '')
end
def test_em_next_word
- assert_byte_pointer_size('')
- assert_cursor(0)
+ assert_line_around_cursor('', '')
input_keys('abc def{bbb}ccc')
input_keys("\C-a\M-F", false)
- assert_byte_pointer_size('abc')
- assert_cursor(3)
+ assert_line_around_cursor('abc', ' def{bbb}ccc')
input_keys("\M-F", false)
- assert_byte_pointer_size('abc def')
- assert_cursor(7)
+ assert_line_around_cursor('abc def', '{bbb}ccc')
input_keys("\M-F", false)
- assert_byte_pointer_size('abc def{bbb')
- assert_cursor(11)
+ assert_line_around_cursor('abc def{bbb', '}ccc')
input_keys("\M-F", false)
- assert_byte_pointer_size('abc def{bbb}ccc')
- assert_cursor(15)
+ assert_line_around_cursor('abc def{bbb}ccc', '')
input_keys("\M-F", false)
- assert_byte_pointer_size('abc def{bbb}ccc')
- assert_cursor(15)
+ assert_line_around_cursor('abc def{bbb}ccc', '')
end
def test_em_next_word_for_mbchar
- assert_cursor(0)
+ assert_line_around_cursor('', '')
input_keys('あいう かきく{さしす}たちつ')
input_keys("\C-a\M-F", false)
- assert_byte_pointer_size('あいう')
- assert_cursor(6)
+ assert_line_around_cursor('あいう', ' かきく{さしす}たちつ')
input_keys("\M-F", false)
- assert_byte_pointer_size('あいう かきく')
- assert_cursor(13)
+ assert_line_around_cursor('あいう かきく', '{さしす}たちつ')
input_keys("\M-F", false)
- assert_byte_pointer_size('あいう かきく{さしす')
- assert_cursor(20)
+ assert_line_around_cursor('あいう かきく{さしす', '}たちつ')
input_keys("\M-F", false)
- assert_byte_pointer_size('あいう かきく{さしす}たちつ')
- assert_cursor(27)
+ assert_line_around_cursor('あいう かきく{さしす}たちつ', '')
input_keys("\M-F", false)
- assert_byte_pointer_size('あいう かきく{さしす}たちつ')
- assert_cursor(27)
+ assert_line_around_cursor('あいう かきく{さしす}たちつ', '')
end
def test_em_next_word_for_mbchar_by_plural_code_points
- assert_cursor(0)
+ assert_line_around_cursor("", "")
input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
input_keys("\C-a\M-F", false)
- assert_byte_pointer_size("あいう")
- assert_cursor(6)
+ assert_line_around_cursor("あいう", " か\u3099き\u3099く\u3099{さしす}たちつ")
input_keys("\M-F", false)
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099")
- assert_cursor(13)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099", "{さしす}たちつ")
input_keys("\M-F", false)
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす")
- assert_cursor(20)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす", "}たちつ")
input_keys("\M-F", false)
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
- assert_cursor(27)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", "")
input_keys("\M-F", false)
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
- assert_cursor(27)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", "")
end
def test_em_prev_word
input_keys('abc def{bbb}ccc')
- assert_byte_pointer_size('abc def{bbb}ccc')
- assert_cursor(15)
+ assert_line_around_cursor('abc def{bbb}ccc', '')
input_keys("\M-B", false)
- assert_byte_pointer_size('abc def{bbb}')
- assert_cursor(12)
+ assert_line_around_cursor('abc def{bbb}', 'ccc')
input_keys("\M-B", false)
- assert_byte_pointer_size('abc def{')
- assert_cursor(8)
+ assert_line_around_cursor('abc def{', 'bbb}ccc')
input_keys("\M-B", false)
- assert_byte_pointer_size('abc ')
- assert_cursor(4)
+ assert_line_around_cursor('abc ', 'def{bbb}ccc')
input_keys("\M-B", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
+ assert_line_around_cursor('', 'abc def{bbb}ccc')
input_keys("\M-B", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
+ assert_line_around_cursor('', 'abc def{bbb}ccc')
end
def test_em_prev_word_for_mbchar
input_keys('あいう かきく{さしす}たちつ')
- assert_byte_pointer_size('あいう かきく{さしす}たちつ')
- assert_cursor(27)
+ assert_line_around_cursor('あいう かきく{さしす}たちつ', '')
input_keys("\M-B", false)
- assert_byte_pointer_size('あいう かきく{さしす}')
- assert_cursor(21)
+ assert_line_around_cursor('あいう かきく{さしす}', 'たちつ')
input_keys("\M-B", false)
- assert_byte_pointer_size('あいう かきく{')
- assert_cursor(14)
+ assert_line_around_cursor('あいう かきく{', 'さしす}たちつ')
input_keys("\M-B", false)
- assert_byte_pointer_size('あいう ')
- assert_cursor(7)
+ assert_line_around_cursor('あいう ', 'かきく{さしす}たちつ')
input_keys("\M-B", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
+ assert_line_around_cursor('', 'あいう かきく{さしす}たちつ')
input_keys("\M-B", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
+ assert_line_around_cursor('', 'あいう かきく{さしす}たちつ')
end
def test_em_prev_word_for_mbchar_by_plural_code_points
input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
- assert_cursor(27)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", "")
input_keys("\M-B", false)
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}")
- assert_cursor(21)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}", "たちつ")
input_keys("\M-B", false)
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{")
- assert_cursor(14)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{", "さしす}たちつ")
input_keys("\M-B", false)
- assert_byte_pointer_size('あいう ')
- assert_cursor(7)
+ assert_line_around_cursor("あいう ", "か\u3099き\u3099く\u3099{さしす}たちつ")
input_keys("\M-B", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
+ assert_line_around_cursor("", "あいう か\u3099き\u3099く\u3099{さしす}たちつ")
input_keys("\M-B", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
+ assert_line_around_cursor("", "あいう か\u3099き\u3099く\u3099{さしす}たちつ")
end
def test_em_delete_next_word
input_keys('abc def{bbb}ccc')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(15)
+ assert_line_around_cursor('', 'abc def{bbb}ccc')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(12)
- assert_line(' def{bbb}ccc')
+ assert_line_around_cursor('', ' def{bbb}ccc')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(8)
- assert_line('{bbb}ccc')
+ assert_line_around_cursor('', '{bbb}ccc')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(4)
- assert_line('}ccc')
+ assert_line_around_cursor('', '}ccc')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_em_delete_next_word_for_mbchar
input_keys('あいう かきく{さしす}たちつ')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(27)
+ assert_line_around_cursor('', 'あいう かきく{さしす}たちつ')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(21)
- assert_line(' かきく{さしす}たちつ')
+ assert_line_around_cursor('', ' かきく{さしす}たちつ')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(14)
- assert_line('{さしす}たちつ')
+ assert_line_around_cursor('', '{さしす}たちつ')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(7)
- assert_line('}たちつ')
+ assert_line_around_cursor('', '}たちつ')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_em_delete_next_word_for_mbchar_by_plural_code_points
input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(27)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(27)
+ assert_line_around_cursor('', "あいう か\u3099き\u3099く\u3099{さしす}たちつ")
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(21)
- assert_line(" か\u3099き\u3099く\u3099{さしす}たちつ")
+ assert_line_around_cursor('', " か\u3099き\u3099く\u3099{さしす}たちつ")
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(14)
- assert_line('{さしす}たちつ')
+ assert_line_around_cursor('', '{さしす}たちつ')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(7)
- assert_line('}たちつ')
+ assert_line_around_cursor('', '}たちつ')
input_keys("\M-d", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_ed_delete_prev_word
input_keys('abc def{bbb}ccc')
- assert_byte_pointer_size('abc def{bbb}ccc')
- assert_cursor(15)
- assert_cursor_max(15)
+ assert_line_around_cursor('abc def{bbb}ccc', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('abc def{bbb}')
- assert_cursor(12)
- assert_cursor_max(12)
- assert_line('abc def{bbb}')
+ assert_line_around_cursor('abc def{bbb}', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('abc def{')
- assert_cursor(8)
- assert_cursor_max(8)
- assert_line('abc def{')
+ assert_line_around_cursor('abc def{', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('abc ')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('abc ')
+ assert_line_around_cursor('abc ', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_ed_delete_prev_word_for_mbchar
input_keys('あいう かきく{さしす}たちつ')
- assert_byte_pointer_size('あいう かきく{さしす}たちつ')
- assert_cursor(27)
- assert_cursor_max(27)
+ assert_line_around_cursor('あいう かきく{さしす}たちつ', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('あいう かきく{さしす}')
- assert_cursor(21)
- assert_cursor_max(21)
- assert_line('あいう かきく{さしす}')
+ assert_line_around_cursor('あいう かきく{さしす}', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('あいう かきく{')
- assert_cursor(14)
- assert_cursor_max(14)
- assert_line('あいう かきく{')
+ assert_line_around_cursor('あいう かきく{', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('あいう ')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('あいう ')
+ assert_line_around_cursor('あいう ', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_ed_delete_prev_word_for_mbchar_by_plural_code_points
input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
- assert_cursor(27)
- assert_cursor_max(27)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}")
- assert_cursor(21)
- assert_cursor_max(21)
- assert_line("あいう か\u3099き\u3099く\u3099{さしす}")
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}", '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{")
- assert_cursor(14)
- assert_cursor_max(14)
- assert_line("あいう か\u3099き\u3099く\u3099{")
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{", '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size("あいう ")
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('あいう ')
+ assert_line_around_cursor('あいう ', '')
input_keys("\M-\C-H", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_ed_transpose_chars
input_keys('abc')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
+ assert_line_around_cursor('', 'abc')
input_keys("\C-t", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
- assert_line('abc')
+ assert_line_around_cursor('', 'abc')
input_keys("\C-f\C-t", false)
- assert_byte_pointer_size('ba')
- assert_cursor(2)
- assert_cursor_max(3)
- assert_line('bac')
+ assert_line_around_cursor('ba', 'c')
input_keys("\C-t", false)
- assert_byte_pointer_size('bca')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('bca')
+ assert_line_around_cursor('bca', '')
input_keys("\C-t", false)
- assert_byte_pointer_size('bac')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('bac')
+ assert_line_around_cursor('bac', '')
end
def test_ed_transpose_chars_for_mbchar
input_keys('あかさ')
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'あかさ')
input_keys("\C-t", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
- assert_line('あかさ')
+ assert_line_around_cursor('', 'あかさ')
input_keys("\C-f\C-t", false)
- assert_byte_pointer_size('かあ')
- assert_cursor(4)
- assert_cursor_max(6)
- assert_line('かあさ')
+ assert_line_around_cursor('かあ', 'さ')
input_keys("\C-t", false)
- assert_byte_pointer_size('かさあ')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line('かさあ')
+ assert_line_around_cursor('かさあ', '')
input_keys("\C-t", false)
- assert_byte_pointer_size('かあさ')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line('かあさ')
+ assert_line_around_cursor('かあさ', '')
end
def test_ed_transpose_chars_for_mbchar_by_plural_code_points
input_keys("あか\u3099さ")
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', "あか\u3099さ")
input_keys("\C-t", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
- assert_line("あか\u3099さ")
+ assert_line_around_cursor('', "あか\u3099さ")
input_keys("\C-f\C-t", false)
- assert_byte_pointer_size("か\u3099あ")
- assert_cursor(4)
- assert_cursor_max(6)
- assert_line("か\u3099あさ")
+ assert_line_around_cursor("か\u3099あ", 'さ')
input_keys("\C-t", false)
- assert_byte_pointer_size("か\u3099さあ")
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line("か\u3099さあ")
+ assert_line_around_cursor("か\u3099さあ", '')
input_keys("\C-t", false)
- assert_byte_pointer_size("か\u3099あさ")
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line("か\u3099あさ")
+ assert_line_around_cursor("か\u3099あさ", '')
end
def test_ed_transpose_words
input_keys('abc def')
- assert_line('abc def')
- assert_byte_pointer_size('abc def')
- assert_cursor(7)
- assert_cursor_max(7)
+ assert_line_around_cursor('abc def', '')
input_keys("\M-t", false)
- assert_line('def abc')
- assert_byte_pointer_size('def abc')
- assert_cursor(7)
- assert_cursor_max(7)
+ assert_line_around_cursor('def abc', '')
input_keys("\C-a\C-k", false)
input_keys(' abc def ')
input_keys("\C-b" * 4, false)
- assert_line(' abc def ')
- assert_byte_pointer_size(' abc de')
- assert_cursor(8)
- assert_cursor_max(12)
+ assert_line_around_cursor(' abc de', 'f ')
input_keys("\M-t", false)
- assert_line(' def abc ')
- assert_byte_pointer_size(' def abc')
- assert_cursor(9)
- assert_cursor_max(12)
+ assert_line_around_cursor(' def abc', ' ')
input_keys("\C-a\C-k", false)
input_keys(' abc def ')
input_keys("\C-b" * 6, false)
- assert_line(' abc def ')
- assert_byte_pointer_size(' abc ')
- assert_cursor(6)
- assert_cursor_max(12)
+ assert_line_around_cursor(' abc ', 'def ')
input_keys("\M-t", false)
- assert_line(' def abc ')
- assert_byte_pointer_size(' def abc')
- assert_cursor(9)
- assert_cursor_max(12)
+ assert_line_around_cursor(' def abc', ' ')
input_keys("\M-t", false)
- assert_line(' abc def')
- assert_byte_pointer_size(' abc def')
- assert_cursor(12)
- assert_cursor_max(12)
+ assert_line_around_cursor(' abc def', '')
end
def test_ed_transpose_words_for_mbchar
input_keys('あいう かきく')
- assert_line('あいう かきく')
- assert_byte_pointer_size('あいう かきく')
- assert_cursor(13)
- assert_cursor_max(13)
+ assert_line_around_cursor('あいう かきく', '')
input_keys("\M-t", false)
- assert_line('かきく あいう')
- assert_byte_pointer_size('かきく あいう')
- assert_cursor(13)
- assert_cursor_max(13)
+ assert_line_around_cursor('かきく あいう', '')
input_keys("\C-a\C-k", false)
input_keys(' あいう かきく ')
input_keys("\C-b" * 4, false)
- assert_line(' あいう かきく ')
- assert_byte_pointer_size(' あいう かき')
- assert_cursor(13)
- assert_cursor_max(18)
+ assert_line_around_cursor(' あいう かき', 'く ')
input_keys("\M-t", false)
- assert_line(' かきく あいう ')
- assert_byte_pointer_size(' かきく あいう')
- assert_cursor(15)
- assert_cursor_max(18)
+ assert_line_around_cursor(' かきく あいう', ' ')
input_keys("\C-a\C-k", false)
input_keys(' あいう かきく ')
input_keys("\C-b" * 6, false)
- assert_line(' あいう かきく ')
- assert_byte_pointer_size(' あいう ')
- assert_cursor(9)
- assert_cursor_max(18)
+ assert_line_around_cursor(' あいう ', 'かきく ')
input_keys("\M-t", false)
- assert_line(' かきく あいう ')
- assert_byte_pointer_size(' かきく あいう')
- assert_cursor(15)
- assert_cursor_max(18)
+ assert_line_around_cursor(' かきく あいう', ' ')
input_keys("\M-t", false)
- assert_line(' あいう かきく')
- assert_byte_pointer_size(' あいう かきく')
- assert_cursor(18)
- assert_cursor_max(18)
+ assert_line_around_cursor(' あいう かきく', '')
end
def test_ed_transpose_words_with_one_word
input_keys('abc ')
- assert_line('abc ')
- assert_byte_pointer_size('abc ')
- assert_cursor(5)
- assert_cursor_max(5)
+ assert_line_around_cursor('abc ', '')
input_keys("\M-t", false)
- assert_line('abc ')
- assert_byte_pointer_size('abc ')
- assert_cursor(5)
- assert_cursor_max(5)
+ assert_line_around_cursor('abc ', '')
input_keys("\C-b", false)
- assert_line('abc ')
- assert_byte_pointer_size('abc ')
- assert_cursor(4)
- assert_cursor_max(5)
+ assert_line_around_cursor('abc ', ' ')
input_keys("\M-t", false)
- assert_line('abc ')
- assert_byte_pointer_size('abc ')
- assert_cursor(4)
- assert_cursor_max(5)
+ assert_line_around_cursor('abc ', ' ')
input_keys("\C-b" * 2, false)
- assert_line('abc ')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(5)
+ assert_line_around_cursor('ab', 'c ')
input_keys("\M-t", false)
- assert_line('abc ')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(5)
+ assert_line_around_cursor('ab', 'c ')
input_keys("\M-t", false)
- assert_line('abc ')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(5)
+ assert_line_around_cursor('ab', 'c ')
end
def test_ed_transpose_words_with_one_word_for_mbchar
input_keys('あいう ')
- assert_line('あいう ')
- assert_byte_pointer_size('あいう ')
- assert_cursor(8)
- assert_cursor_max(8)
+ assert_line_around_cursor('あいう ', '')
input_keys("\M-t", false)
- assert_line('あいう ')
- assert_byte_pointer_size('あいう ')
- assert_cursor(8)
- assert_cursor_max(8)
+ assert_line_around_cursor('あいう ', '')
input_keys("\C-b", false)
- assert_line('あいう ')
- assert_byte_pointer_size('あいう ')
- assert_cursor(7)
- assert_cursor_max(8)
+ assert_line_around_cursor('あいう ', ' ')
input_keys("\M-t", false)
- assert_line('あいう ')
- assert_byte_pointer_size('あいう ')
- assert_cursor(7)
- assert_cursor_max(8)
+ assert_line_around_cursor('あいう ', ' ')
input_keys("\C-b" * 2, false)
- assert_line('あいう ')
- assert_byte_pointer_size('あい')
- assert_cursor(4)
- assert_cursor_max(8)
+ assert_line_around_cursor('あい', 'う ')
input_keys("\M-t", false)
- assert_line('あいう ')
- assert_byte_pointer_size('あい')
- assert_cursor(4)
- assert_cursor_max(8)
+ assert_line_around_cursor('あい', 'う ')
input_keys("\M-t", false)
- assert_line('あいう ')
- assert_byte_pointer_size('あい')
- assert_cursor(4)
- assert_cursor_max(8)
+ assert_line_around_cursor('あい', 'う ')
end
def test_ed_digit
input_keys('0123')
- assert_byte_pointer_size('0123')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('0123')
+ assert_line_around_cursor('0123', '')
end
def test_ed_next_and_prev_char
input_keys('abc')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abc', '')
input_keys("\C-b", false)
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(3)
+ assert_line_around_cursor('ab', 'c')
input_keys("\C-b", false)
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(3)
+ assert_line_around_cursor('a', 'bc')
input_keys("\C-b", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
+ assert_line_around_cursor('', 'abc')
input_keys("\C-b", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
+ assert_line_around_cursor('', 'abc')
input_keys("\C-f", false)
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(3)
+ assert_line_around_cursor('a', 'bc')
input_keys("\C-f", false)
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(3)
+ assert_line_around_cursor('ab', 'c')
input_keys("\C-f", false)
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abc', '')
input_keys("\C-f", false)
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abc', '')
end
def test_ed_next_and_prev_char_for_mbchar
input_keys('あいう')
- assert_byte_pointer_size('あいう')
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor('あいう', '')
input_keys("\C-b", false)
- assert_byte_pointer_size('あい')
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor('あい', 'う')
input_keys("\C-b", false)
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(6)
+ assert_line_around_cursor('あ', 'いう')
input_keys("\C-b", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'あいう')
input_keys("\C-b", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'あいう')
input_keys("\C-f", false)
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(6)
+ assert_line_around_cursor('あ', 'いう')
input_keys("\C-f", false)
- assert_byte_pointer_size('あい')
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor('あい', 'う')
input_keys("\C-f", false)
- assert_byte_pointer_size('あいう')
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor('あいう', '')
input_keys("\C-f", false)
- assert_byte_pointer_size('あいう')
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor('あいう', '')
end
def test_ed_next_and_prev_char_for_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099く\u3099")
- assert_byte_pointer_size("か\u3099き\u3099く\u3099")
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099き\u3099く\u3099", '')
input_keys("\C-b", false)
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099き\u3099", "く\u3099")
input_keys("\C-b", false)
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099", "き\u3099く\u3099")
input_keys("\C-b", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', "か\u3099き\u3099く\u3099")
input_keys("\C-b", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', "か\u3099き\u3099く\u3099")
input_keys("\C-f", false)
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099", "き\u3099く\u3099")
input_keys("\C-f", false)
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099き\u3099", "く\u3099")
input_keys("\C-f", false)
- assert_byte_pointer_size("か\u3099き\u3099く\u3099")
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099き\u3099く\u3099", '')
input_keys("\C-f", false)
- assert_byte_pointer_size("か\u3099き\u3099く\u3099")
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor("か\u3099き\u3099く\u3099", '')
end
def test_em_capitol_case
input_keys('abc def{bbb}ccc')
input_keys("\C-a\M-c", false)
- assert_byte_pointer_size('Abc')
- assert_cursor(3)
- assert_cursor_max(15)
- assert_line('Abc def{bbb}ccc')
+ assert_line_around_cursor('Abc', ' def{bbb}ccc')
input_keys("\M-c", false)
- assert_byte_pointer_size('Abc Def')
- assert_cursor(7)
- assert_cursor_max(15)
- assert_line('Abc Def{bbb}ccc')
+ assert_line_around_cursor('Abc Def', '{bbb}ccc')
input_keys("\M-c", false)
- assert_byte_pointer_size('Abc Def{Bbb')
- assert_cursor(11)
- assert_cursor_max(15)
- assert_line('Abc Def{Bbb}ccc')
+ assert_line_around_cursor('Abc Def{Bbb', '}ccc')
input_keys("\M-c", false)
- assert_byte_pointer_size('Abc Def{Bbb}Ccc')
- assert_cursor(15)
- assert_cursor_max(15)
- assert_line('Abc Def{Bbb}Ccc')
+ assert_line_around_cursor('Abc Def{Bbb}Ccc', '')
end
def test_em_capitol_case_with_complex_example
input_keys('{}#* AaA!!!cCc ')
input_keys("\C-a\M-c", false)
- assert_byte_pointer_size('{}#* Aaa')
- assert_cursor(11)
- assert_cursor_max(20)
- assert_line('{}#* Aaa!!!cCc ')
+ assert_line_around_cursor('{}#* Aaa', '!!!cCc ')
input_keys("\M-c", false)
- assert_byte_pointer_size('{}#* Aaa!!!Ccc')
- assert_cursor(17)
- assert_cursor_max(20)
- assert_line('{}#* Aaa!!!Ccc ')
+ assert_line_around_cursor('{}#* Aaa!!!Ccc', ' ')
input_keys("\M-c", false)
- assert_byte_pointer_size('{}#* Aaa!!!Ccc ')
- assert_cursor(20)
- assert_cursor_max(20)
- assert_line('{}#* Aaa!!!Ccc ')
+ assert_line_around_cursor('{}#* Aaa!!!Ccc ', '')
end
def test_em_lower_case
input_keys('AbC def{bBb}CCC')
input_keys("\C-a\M-l", false)
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(15)
- assert_line('abc def{bBb}CCC')
+ assert_line_around_cursor('abc', ' def{bBb}CCC')
input_keys("\M-l", false)
- assert_byte_pointer_size('abc def')
- assert_cursor(7)
- assert_cursor_max(15)
- assert_line('abc def{bBb}CCC')
+ assert_line_around_cursor('abc def', '{bBb}CCC')
input_keys("\M-l", false)
- assert_byte_pointer_size('abc def{bbb')
- assert_cursor(11)
- assert_cursor_max(15)
- assert_line('abc def{bbb}CCC')
+ assert_line_around_cursor('abc def{bbb', '}CCC')
input_keys("\M-l", false)
- assert_byte_pointer_size('abc def{bbb}ccc')
- assert_cursor(15)
- assert_cursor_max(15)
- assert_line('abc def{bbb}ccc')
+ assert_line_around_cursor('abc def{bbb}ccc', '')
end
def test_em_lower_case_with_complex_example
input_keys('{}#* AaA!!!cCc ')
input_keys("\C-a\M-l", false)
- assert_byte_pointer_size('{}#* aaa')
- assert_cursor(11)
- assert_cursor_max(20)
- assert_line('{}#* aaa!!!cCc ')
+ assert_line_around_cursor('{}#* aaa', '!!!cCc ')
input_keys("\M-l", false)
- assert_byte_pointer_size('{}#* aaa!!!ccc')
- assert_cursor(17)
- assert_cursor_max(20)
- assert_line('{}#* aaa!!!ccc ')
+ assert_line_around_cursor('{}#* aaa!!!ccc', ' ')
input_keys("\M-l", false)
- assert_byte_pointer_size('{}#* aaa!!!ccc ')
- assert_cursor(20)
- assert_cursor_max(20)
- assert_line('{}#* aaa!!!ccc ')
+ assert_line_around_cursor('{}#* aaa!!!ccc ', '')
end
def test_em_upper_case
input_keys('AbC def{bBb}CCC')
input_keys("\C-a\M-u", false)
- assert_byte_pointer_size('ABC')
- assert_cursor(3)
- assert_cursor_max(15)
- assert_line('ABC def{bBb}CCC')
+ assert_line_around_cursor('ABC', ' def{bBb}CCC')
input_keys("\M-u", false)
- assert_byte_pointer_size('ABC DEF')
- assert_cursor(7)
- assert_cursor_max(15)
- assert_line('ABC DEF{bBb}CCC')
+ assert_line_around_cursor('ABC DEF', '{bBb}CCC')
input_keys("\M-u", false)
- assert_byte_pointer_size('ABC DEF{BBB')
- assert_cursor(11)
- assert_cursor_max(15)
- assert_line('ABC DEF{BBB}CCC')
+ assert_line_around_cursor('ABC DEF{BBB', '}CCC')
input_keys("\M-u", false)
- assert_byte_pointer_size('ABC DEF{BBB}CCC')
- assert_cursor(15)
- assert_cursor_max(15)
- assert_line('ABC DEF{BBB}CCC')
+ assert_line_around_cursor('ABC DEF{BBB}CCC', '')
end
def test_em_upper_case_with_complex_example
input_keys('{}#* AaA!!!cCc ')
input_keys("\C-a\M-u", false)
- assert_byte_pointer_size('{}#* AAA')
- assert_cursor(11)
- assert_cursor_max(20)
- assert_line('{}#* AAA!!!cCc ')
+ assert_line_around_cursor('{}#* AAA', '!!!cCc ')
input_keys("\M-u", false)
- assert_byte_pointer_size('{}#* AAA!!!CCC')
- assert_cursor(17)
- assert_cursor_max(20)
- assert_line('{}#* AAA!!!CCC ')
+ assert_line_around_cursor('{}#* AAA!!!CCC', ' ')
input_keys("\M-u", false)
- assert_byte_pointer_size('{}#* AAA!!!CCC ')
- assert_cursor(20)
- assert_cursor_max(20)
- assert_line('{}#* AAA!!!CCC ')
+ assert_line_around_cursor('{}#* AAA!!!CCC ', '')
end
def test_em_delete_or_list
@@ -1261,28 +726,16 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('fooo')
- assert_byte_pointer_size('fooo')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('fooo')
+ assert_line_around_cursor('fooo', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-b", false)
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(4)
- assert_line('fooo')
+ assert_line_around_cursor('foo', 'o')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
@line_editor.input_key(Reline::Key.new(:em_delete_or_list, :em_delete_or_list, false))
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
@line_editor.input_key(Reline::Key.new(:em_delete_or_list, :em_delete_or_list, false))
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
end
@@ -1297,22 +750,13 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('foo_')
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(%w{foo_foo foo_bar}, @line_editor.instance_variable_get(:@menu_info).list)
end
@@ -1328,36 +772,67 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('fo')
- assert_byte_pointer_size('fo')
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line('fo')
+ assert_line_around_cursor('fo', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
input_keys('a')
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_a')
- assert_cursor(5)
- assert_cursor_max(5)
- assert_line('foo_a')
+ assert_line_around_cursor('foo_a', '')
input_keys("\C-h", false)
input_keys('b')
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_ba')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line('foo_ba')
+ assert_line_around_cursor('foo_ba', '')
+ end
+
+ def test_autocompletion_with_upward_navigation
+ @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)
+ 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)
+ assert_line_around_cursor('Readline', '')
+ input_keys("\C-i", false)
+ assert_line_around_cursor('Regexp', '')
+ @line_editor.input_key(Reline::Key.new(:menu_complete_backward, :menu_complete_backward, false))
+ assert_line_around_cursor('Readline', '')
+ ensure
+ @config.autocompletion = false
end
def test_completion_with_indent
@@ -1372,22 +847,13 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys(' fo')
- assert_byte_pointer_size(' fo')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line(' fo')
+ assert_line_around_cursor(' fo', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size(' foo_')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line(' foo_')
+ assert_line_around_cursor(' foo_', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size(' foo_')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line(' foo_')
+ assert_line_around_cursor(' foo_', '')
assert_equal(%w{foo_foo foo_bar foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
end
@@ -1403,22 +869,13 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys(' "".fo')
- assert_byte_pointer_size(' "".fo')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line(' "".fo')
+ assert_line_around_cursor(' "".fo', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size(' "".foo_')
- assert_cursor(9)
- assert_cursor_max(9)
- assert_line(' "".foo_')
+ assert_line_around_cursor(' "".foo_', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size(' "".foo_')
- assert_cursor(9)
- assert_cursor_max(9)
- assert_line(' "".foo_')
+ assert_line_around_cursor(' "".foo_', '')
assert_equal(%w{"".foo_foo "".foo_bar "".foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
end
@@ -1436,54 +893,33 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
matched = m
}
input_keys('fo')
- assert_byte_pointer_size('fo')
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line('fo')
+ assert_line_around_cursor('fo', '')
assert_equal(Reline::LineEditor::CompletionState::NORMAL, @line_editor.instance_variable_get(:@completion_state))
assert_equal(nil, matched)
input_keys("\C-i", false)
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
assert_equal(Reline::LineEditor::CompletionState::MENU_WITH_PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
assert_equal(nil, matched)
input_keys("\C-i", false)
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
assert_equal(nil, matched)
input_keys("\C-i", false)
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
assert_equal('foo', matched)
matched = nil
input_keys('_')
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_bar')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('foo_bar')
+ assert_line_around_cursor('foo_bar', '')
assert_equal(Reline::LineEditor::CompletionState::MENU_WITH_PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
assert_equal(nil, matched)
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_bar')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('foo_bar')
+ assert_line_around_cursor('foo_bar', '')
assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
assert_equal(nil, matched)
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_bar')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('foo_bar')
+ assert_line_around_cursor('foo_bar', '')
assert_equal(Reline::LineEditor::CompletionState::PERFECT_MATCH, @line_editor.instance_variable_get(:@completion_state))
assert_equal('foo_bar', matched)
end
@@ -1500,43 +936,25 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('fo')
- assert_byte_pointer_size('fo')
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line('fo')
+ assert_line_around_cursor('fo', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(%w{foo_foo foo_bar}, @line_editor.instance_variable_get(:@menu_info).list)
@config.completion_ignore_case = true
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(%w{foo_foo foo_bar Foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
input_keys('a')
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_a')
- assert_cursor(5)
- assert_cursor_max(5)
- assert_line('foo_a')
+ assert_line_around_cursor('foo_a', '')
input_keys("\C-h", false)
input_keys('b')
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_ba')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line('foo_ba')
+ assert_line_around_cursor('foo_ba', '')
end
def test_completion_in_middle_of_line
@@ -1551,17 +969,11 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
}
input_keys('abcde fo ABCDE')
- assert_line('abcde fo ABCDE')
+ assert_line_around_cursor('abcde fo ABCDE', '')
input_keys("\C-b" * 6 + "\C-i", false)
- assert_byte_pointer_size('abcde foo_')
- assert_cursor(10)
- assert_cursor_max(16)
- assert_line('abcde foo_ ABCDE')
+ assert_line_around_cursor('abcde foo_', ' ABCDE')
input_keys("\C-b" * 2 + "\C-i", false)
- assert_byte_pointer_size('abcde foo_')
- assert_cursor(10)
- assert_cursor_max(18)
- assert_line('abcde foo_o_ ABCDE')
+ assert_line_around_cursor('abcde foo_', 'o_ ABCDE')
end
def test_completion_with_nil_value
@@ -1577,125 +989,65 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
}
@config.completion_ignore_case = true
input_keys('fo')
- assert_byte_pointer_size('fo')
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line('fo')
+ assert_line_around_cursor('fo', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(nil, @line_editor.instance_variable_get(:@menu_info))
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('foo_')
+ assert_line_around_cursor('foo_', '')
assert_equal(%w{foo_foo foo_bar Foo_baz}, @line_editor.instance_variable_get(:@menu_info).list)
input_keys('a')
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_a')
- assert_cursor(5)
- assert_cursor_max(5)
- assert_line('foo_a')
+ assert_line_around_cursor('foo_a', '')
input_keys("\C-h", false)
input_keys('b')
input_keys("\C-i", false)
- assert_byte_pointer_size('foo_ba')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line('foo_ba')
+ assert_line_around_cursor('foo_ba', '')
end
def test_em_kill_region
input_keys('abc def{bbb}ccc ddd ')
- assert_byte_pointer_size('abc def{bbb}ccc ddd ')
- assert_cursor(26)
- assert_cursor_max(26)
- assert_line('abc def{bbb}ccc ddd ')
+ assert_line_around_cursor('abc def{bbb}ccc ddd ', '')
input_keys("\C-w", false)
- assert_byte_pointer_size('abc def{bbb}ccc ')
- assert_cursor(20)
- assert_cursor_max(20)
- assert_line('abc def{bbb}ccc ')
+ assert_line_around_cursor('abc def{bbb}ccc ', '')
input_keys("\C-w", false)
- assert_byte_pointer_size('abc ')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line('abc ')
+ assert_line_around_cursor('abc ', '')
input_keys("\C-w", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys("\C-w", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_em_kill_region_mbchar
input_keys('あ い う{う}う ')
- assert_byte_pointer_size('あ い う{う}う ')
- assert_cursor(21)
- assert_cursor_max(21)
- assert_line('あ い う{う}う ')
+ assert_line_around_cursor('あ い う{う}う ', '')
input_keys("\C-w", false)
- assert_byte_pointer_size('あ い ')
- assert_cursor(10)
- assert_cursor_max(10)
- assert_line('あ い ')
+ assert_line_around_cursor('あ い ', '')
input_keys("\C-w", false)
- assert_byte_pointer_size('あ ')
- assert_cursor(5)
- assert_cursor_max(5)
- assert_line('あ ')
+ assert_line_around_cursor('あ ', '')
input_keys("\C-w", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_vi_search_prev
Reline::HISTORY.concat(%w{abc 123 AAA})
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-ra\C-j")
- assert_line('abc')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
+ assert_line_around_cursor('', 'abc')
end
def test_larger_histories_than_history_size
history_size = @config.history_size
@config.history_size = 2
Reline::HISTORY.concat(%w{abc 123 AAA})
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-p")
- assert_line('AAA')
- assert_byte_pointer_size('AAA')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('AAA', '')
input_keys("\C-p")
- assert_line('123')
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('123', '')
input_keys("\C-p")
- assert_line('123')
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('123', '')
ensure
@config.history_size = history_size
end
@@ -1706,25 +1058,13 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-r123")
- assert_line('1234')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0) # doesn't determine yet
+ assert_line_around_cursor('1234', '')
input_keys("\C-ha")
- assert_line('12aa')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('12aa', '')
input_keys("\C-h3")
- assert_line('1235')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('1235', '')
end
def test_search_history_to_front
@@ -1733,25 +1073,13 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-s123")
- assert_line('1235')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0) # doesn't determine yet
+ assert_line_around_cursor('1235', '')
input_keys("\C-ha")
- assert_line('12aa')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('12aa', '')
input_keys("\C-h3")
- assert_line('1234')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('1234', '')
end
def test_search_history_front_and_back
@@ -1760,30 +1088,15 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-s12")
- assert_line('1235')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0) # doesn't determine yet
+ assert_line_around_cursor('1235', '')
input_keys("\C-s")
- assert_line('12aa')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('12aa', '')
input_keys("\C-r")
- assert_line('12aa')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('12aa', '')
input_keys("\C-r")
- assert_line('1235')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('1235', '')
end
def test_search_history_back_and_front
@@ -1792,30 +1105,15 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-r12")
- assert_line('1234')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0) # doesn't determine yet
+ assert_line_around_cursor('1234', '')
input_keys("\C-r")
- assert_line('12aa')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('12aa', '')
input_keys("\C-s")
- assert_line('12aa')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('12aa', '')
input_keys("\C-s")
- assert_line('1234')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('1234', '')
end
def test_search_history_to_back_in_the_middle_of_histories
@@ -1824,20 +1122,11 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-p\C-p")
- assert_line('12aa')
- assert_byte_pointer_size('12aa')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('12aa', '')
input_keys("\C-r123")
- assert_line('1235')
- assert_byte_pointer_size('1235')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('1235', '')
end
def test_search_history_twice
@@ -1846,20 +1135,11 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-r123")
- assert_line('1234')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0) # doesn't determine yet
+ assert_line_around_cursor('1234', '')
input_keys("\C-r")
- assert_line('1235')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('1235', '')
end
def test_search_history_by_last_determined
@@ -1868,35 +1148,17 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-r123")
- assert_line('1234')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0) # doesn't determine yet
+ assert_line_around_cursor('1234', '')
input_keys("\C-j")
- assert_line('1234')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(4)
+ assert_line_around_cursor('', '1234')
input_keys("\C-k") # delete
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-r")
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-r")
- assert_line('1235')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('1235', '')
end
def test_search_history_with_isearch_terminator
@@ -1908,76 +1170,40 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
'12aa',
'1234' # new
])
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys("\C-r12a")
- assert_line('12aa')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0) # doesn't determine yet
+ assert_line_around_cursor('12aa', '')
input_keys('Y')
- assert_line('12aa')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(4)
+ assert_line_around_cursor('', '12aa')
input_keys('x')
- assert_line('x12aa')
- assert_byte_pointer_size('x')
- assert_cursor(1)
- assert_cursor_max(5)
+ assert_line_around_cursor('x', '12aa')
end
def test_em_set_mark_and_em_exchange_mark
input_keys('aaa bbb ccc ddd')
- assert_byte_pointer_size('aaa bbb ccc ddd')
- assert_cursor(15)
- assert_cursor_max(15)
- assert_line('aaa bbb ccc ddd')
+ assert_line_around_cursor('aaa bbb ccc ddd', '')
input_keys("\C-a\M-F\M-F", false)
- assert_byte_pointer_size('aaa bbb')
- assert_cursor(7)
- assert_cursor_max(15)
- assert_line('aaa bbb ccc ddd')
+ assert_line_around_cursor('aaa bbb', ' ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
input_keys("\x00", false) # C-Space
- assert_byte_pointer_size('aaa bbb')
- assert_cursor(7)
- assert_cursor_max(15)
- assert_line('aaa bbb ccc ddd')
+ assert_line_around_cursor('aaa bbb', ' ccc ddd')
assert_equal([7, 0], @line_editor.instance_variable_get(:@mark_pointer))
input_keys("\C-a", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(15)
- assert_line('aaa bbb ccc ddd')
+ assert_line_around_cursor('', 'aaa bbb ccc ddd')
assert_equal([7, 0], @line_editor.instance_variable_get(:@mark_pointer))
input_key_by_symbol(:em_exchange_mark)
- assert_byte_pointer_size('aaa bbb')
- assert_cursor(7)
- assert_cursor_max(15)
- assert_line('aaa bbb ccc ddd')
+ assert_line_around_cursor('aaa bbb', ' ccc ddd')
assert_equal([0, 0], @line_editor.instance_variable_get(:@mark_pointer))
end
def test_em_exchange_mark_without_mark
input_keys('aaa bbb ccc ddd')
- assert_byte_pointer_size('aaa bbb ccc ddd')
- assert_cursor(15)
- assert_cursor_max(15)
- assert_line('aaa bbb ccc ddd')
+ assert_line_around_cursor('aaa bbb ccc ddd', '')
input_keys("\C-a\M-f", false)
- assert_byte_pointer_size('aaa')
- assert_cursor(3)
- assert_cursor_max(15)
- assert_line('aaa bbb ccc ddd')
+ assert_line_around_cursor('aaa', ' bbb ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
input_key_by_symbol(:em_exchange_mark)
- assert_byte_pointer_size('aaa')
- assert_cursor(3)
- assert_cursor_max(15)
- assert_line('aaa bbb ccc ddd')
+ assert_line_around_cursor('aaa', ' bbb ccc ddd')
assert_equal(nil, @line_editor.instance_variable_get(:@mark_pointer))
end
@@ -1988,7 +1214,7 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
$VERBOSE = verbose
@line_editor.output_modifier_proc = proc { |output| Reline::Unicode.escape_for_print(output) }
input_keys("abcdef\n")
- result = @line_editor.__send__(:modify_lines, @line_editor.whole_lines)
+ result = @line_editor.__send__(:modify_lines, @line_editor.whole_lines, @line_editor.finished?)
$/ = nil
assert_equal(['abcdef'], result)
ensure
@@ -2006,20 +1232,11 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
input_keys('123')
# The ed_search_prev_history doesn't have default binding
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(5)
- assert_line('12345')
+ assert_line_around_cursor('123', '45')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(5)
- assert_line('12356')
+ assert_line_around_cursor('123', '56')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(5)
- assert_line('12356')
+ assert_line_around_cursor('123', '56')
end
def test_ed_search_prev_history_with_empty
@@ -2030,25 +1247,13 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
])
# The ed_search_prev_history doesn't have default binding
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12345')
+ assert_line_around_cursor('', '12345')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12aaa')
+ assert_line_around_cursor('', '12aaa')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12356')
+ assert_line_around_cursor('', '12356')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12356')
+ assert_line_around_cursor('', '12356')
end
def test_ed_search_prev_history_without_match
@@ -2060,10 +1265,7 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
input_keys('ABC')
# The ed_search_prev_history doesn't have default binding
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('ABC')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('ABC')
+ assert_line_around_cursor('ABC', '')
end
def test_ed_search_next_history
@@ -2075,30 +1277,15 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
input_keys('123')
# The ed_search_prev_history and ed_search_next_history doesn't have default binding
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(5)
- assert_line('12345')
+ assert_line_around_cursor('123', '45')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(5)
- assert_line('12356')
+ assert_line_around_cursor('123', '56')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(5)
- assert_line('12356')
+ assert_line_around_cursor('123', '56')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(5)
- assert_line('12345')
+ assert_line_around_cursor('123', '45')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_byte_pointer_size('123')
- assert_cursor(3)
- assert_cursor_max(5)
- assert_line('12345')
+ assert_line_around_cursor('123', '45')
end
def test_ed_search_next_history_with_empty
@@ -2109,133 +1296,75 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
])
# The ed_search_prev_history and ed_search_next_history doesn't have default binding
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12345')
+ assert_line_around_cursor('', '12345')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12aaa')
+ assert_line_around_cursor('', '12aaa')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12356')
+ assert_line_around_cursor('', '12356')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12aaa')
+ assert_line_around_cursor('', '12aaa')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
- assert_line('12345')
+ assert_line_around_cursor('', '12345')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
+ end
+
+ def test_incremental_search_history_cancel_by_symbol_key
+ # ed_prev_char should move cursor left and cancel incremental search
+ input_keys("abc\C-r")
+ input_key_by_symbol(:ed_prev_char)
+ input_keys('d')
+ assert_line_around_cursor('abd', 'c')
end
# Unicode emoji test
def test_ed_insert_for_include_zwj_emoji
- omit "This test is for UTF-8 but the locale is #{Reline::IOGate.encoding}" if Reline::IOGate.encoding != Encoding::UTF_8
+ omit "This test is for UTF-8 but the locale is #{Reline.core.encoding}" if Reline.core.encoding != Encoding::UTF_8
# U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466 is family: man, woman, girl, boy "👨‍👩‍👧‍👦"
input_keys("\u{1F468}") # U+1F468 is man "👨"
- assert_line("\u{1F468}")
- assert_byte_pointer_size("\u{1F468}")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('👨', '')
input_keys("\u200D") # U+200D is ZERO WIDTH JOINER
- assert_line("\u{1F468 200D}")
- assert_byte_pointer_size("\u{1F468 200D}")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('👨‍', '')
input_keys("\u{1F469}") # U+1F469 is woman "👩"
- assert_line("\u{1F468 200D 1F469}")
- assert_byte_pointer_size("\u{1F468 200D 1F469}")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('👨‍👩', '')
input_keys("\u200D") # U+200D is ZERO WIDTH JOINER
- assert_line("\u{1F468 200D 1F469 200D}")
- assert_byte_pointer_size("\u{1F468 200D 1F469 200D}")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('👨‍👩‍', '')
input_keys("\u{1F467}") # U+1F467 is girl "👧"
- assert_line("\u{1F468 200D 1F469 200D 1F467}")
- assert_byte_pointer_size("\u{1F468 200D 1F469 200D 1F467}")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('👨‍👩‍👧', '')
input_keys("\u200D") # U+200D is ZERO WIDTH JOINER
- assert_line("\u{1F468 200D 1F469 200D 1F467 200D}")
- assert_byte_pointer_size("\u{1F468 200D 1F469 200D 1F467 200D}")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('👨‍👩‍👧‍', '')
input_keys("\u{1F466}") # U+1F466 is boy "👦"
- assert_line("\u{1F468 200D 1F469 200D 1F467 200D 1F466}")
- assert_byte_pointer_size("\u{1F468 200D 1F469 200D 1F467 200D 1F466}")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('👨‍👩‍👧‍👦', '')
# U+1F468 U+200D U+1F469 U+200D U+1F467 U+200D U+1F466 is family: man, woman, girl, boy "👨‍👩‍👧‍👦"
input_keys("\u{1F468 200D 1F469 200D 1F467 200D 1F466}")
- assert_line("\u{1F468 200D 1F469 200D 1F467 200D 1F466 1F468 200D 1F469 200D 1F467 200D 1F466}")
- assert_byte_pointer_size("\u{1F468 200D 1F469 200D 1F467 200D 1F466 1F468 200D 1F469 200D 1F467 200D 1F466}")
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('👨‍👩‍👧‍👦👨‍👩‍👧‍👦', '')
end
def test_ed_insert_for_include_valiation_selector
- omit "This test is for UTF-8 but the locale is #{Reline::IOGate.encoding}" if Reline::IOGate.encoding != Encoding::UTF_8
+ omit "This test is for UTF-8 but the locale is #{Reline.core.encoding}" if Reline.core.encoding != Encoding::UTF_8
# U+0030 U+FE00 is DIGIT ZERO + VARIATION SELECTOR-1 "0︀"
input_keys("\u0030") # U+0030 is DIGIT ZERO
- assert_line("\u0030")
- assert_byte_pointer_size("\u0030")
- assert_cursor(1)
- assert_cursor_max(1)
+ assert_line_around_cursor('0', '')
input_keys("\uFE00") # U+FE00 is VARIATION SELECTOR-1
- assert_line("\u{0030 FE00}")
- assert_byte_pointer_size("\u{0030 FE00}")
- assert_cursor(1)
- assert_cursor_max(1)
+ assert_line_around_cursor('0︀', '')
end
def test_em_yank_pop
input_keys("def hoge\C-w\C-b\C-f\C-w", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys("\C-y", false)
- assert_byte_pointer_size('def ')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('def ')
+ assert_line_around_cursor('def ', '')
input_keys("\M-\C-y", false)
- assert_byte_pointer_size('hoge')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('hoge')
+ assert_line_around_cursor('hoge', '')
end
def test_em_kill_region_with_kill_ring
input_keys("def hoge\C-b\C-b\C-b\C-b", false)
- assert_byte_pointer_size('def ')
- assert_cursor(4)
- assert_cursor_max(8)
- assert_line('def hoge')
+ assert_line_around_cursor('def ', 'hoge')
input_keys("\C-k\C-w", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys("\C-y", false)
- assert_byte_pointer_size('def hoge')
- assert_cursor(8)
- assert_cursor_max(8)
- assert_line('def hoge')
+ assert_line_around_cursor('def hoge', '')
end
def test_ed_search_prev_next_history_in_multibyte
@@ -2251,104 +1380,65 @@ class Reline::KeyActor::Emacs::Test < Reline::TestCase
assert_whole_lines(['def foo', ' 12345', 'end'])
assert_line_index(1)
assert_whole_lines(['def foo', ' 12345', 'end'])
- assert_byte_pointer_size(' 123')
- assert_cursor(5)
- assert_cursor_max(7)
- assert_line(' 12345')
+ assert_line_around_cursor(' 123', '45')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
assert_line_index(2)
assert_whole_lines(['def hoge', ' 67890', ' 12345', 'end'])
- assert_byte_pointer_size(' 123')
- assert_cursor(5)
- assert_cursor_max(7)
- assert_line(' 12345')
+ assert_line_around_cursor(' 123', '45')
@line_editor.__send__(:ed_search_prev_history, "\C-p".ord)
assert_line_index(2)
assert_whole_lines(['def hoge', ' 67890', ' 12345', 'end'])
- assert_byte_pointer_size(' 123')
- assert_cursor(5)
- assert_cursor_max(7)
- assert_line(' 12345')
+ assert_line_around_cursor(' 123', '45')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
assert_line_index(1)
assert_whole_lines(['def foo', ' 12345', 'end'])
- assert_byte_pointer_size(' 123')
- assert_cursor(5)
- assert_cursor_max(7)
- assert_line(' 12345')
+ assert_line_around_cursor(' 123', '45')
@line_editor.__send__(:ed_search_next_history, "\C-n".ord)
assert_line_index(1)
assert_whole_lines(['def foo', ' 12345', 'end'])
- assert_byte_pointer_size(' 123')
- assert_cursor(5)
- assert_cursor_max(7)
- assert_line(' 12345')
+ assert_line_around_cursor(' 123', '45')
end
def test_ignore_NUL_by_ed_quoted_insert
input_keys(%Q{"\C-v\C-@"}, false)
- assert_byte_pointer_size('""')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('""', '')
end
def test_ed_argument_digit_by_meta_num
input_keys('abcdef')
- assert_byte_pointer_size('abcdef')
- assert_cursor(6)
- assert_cursor_max(6)
- assert_line('abcdef')
+ assert_line_around_cursor('abcdef', '')
input_keys("\M-2", false)
input_keys("\C-h", false)
- assert_byte_pointer_size('abcd')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('abcd')
+ assert_line_around_cursor('abcd', '')
end
def test_halfwidth_kana_width_dakuten
input_raw_keys('ガギゲゴ')
- assert_byte_pointer_size('ガギゲゴ')
- assert_cursor(8)
- assert_cursor_max(8)
+ assert_line_around_cursor('ガギゲゴ', '')
input_keys("\C-b\C-b", false)
- assert_byte_pointer_size('ガギ')
- assert_cursor(4)
- assert_cursor_max(8)
+ assert_line_around_cursor('ガギ', 'ゲゴ')
input_raw_keys('グ', false)
- assert_byte_pointer_size('ガギグ')
- assert_cursor(6)
- assert_cursor_max(10)
- assert_line('ガギグゲゴ')
+ assert_line_around_cursor('ガギグ', 'ゲゴ')
end
def test_input_unknown_char
input_keys('͸') # U+0378 (unassigned)
- assert_line('͸')
- assert_byte_pointer_size('͸')
- assert_cursor(1)
- assert_cursor_max(1)
+ assert_line_around_cursor('͸', '')
end
def test_unix_line_discard
input_keys("\C-u", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('abc')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abc', '')
input_keys("\C-b\C-u", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(1)
- assert_line('c')
+ assert_line_around_cursor('', 'c')
input_keys("\C-f\C-u", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
+ end
+
+ def test_vi_editing_mode
+ @line_editor.__send__(:vi_editing_mode, nil)
+ assert(@config.editing_mode_is?(:vi_insert))
end
end
diff --git a/test/reline/test_key_actor_vi.rb b/test/reline/test_key_actor_vi.rb
index b3d49c9bbb..4deae2dd83 100644
--- a/test/reline/test_key_actor_vi.rb
+++ b/test/reline/test_key_actor_vi.rb
@@ -8,7 +8,7 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
@config.read_lines(<<~LINES.split(/(?<=\n)/))
set editing-mode vi
LINES
- @encoding = Reline::IOGate.encoding
+ @encoding = Reline.core.encoding
@line_editor = Reline::LineEditor.new(@config, @encoding)
@line_editor.reset(@prompt, encoding: @encoding)
end
@@ -25,950 +25,513 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
def test_vi_command_mode_with_input
input_keys("abc\C-[")
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
- assert_line('abc')
+ assert_line_around_cursor('ab', 'c')
end
def test_vi_insert
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys('i')
- assert_line('i')
- assert_cursor(1)
+ assert_line_around_cursor('i', '')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys("\C-[")
- assert_line('i')
- assert_cursor(0)
+ assert_line_around_cursor('', 'i')
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
input_keys('i')
- assert_line('i')
- assert_cursor(0)
+ assert_line_around_cursor('', 'i')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
end
def test_vi_add
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys('a')
- assert_line('a')
- assert_cursor(1)
+ assert_line_around_cursor('a', '')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys("\C-[")
- assert_line('a')
- assert_cursor(0)
+ assert_line_around_cursor('', 'a')
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
input_keys('a')
- assert_line('a')
- assert_cursor(1)
+ assert_line_around_cursor('a', '')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
end
def test_vi_insert_at_bol
input_keys('I')
- assert_line('I')
+ assert_line_around_cursor('I', '')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys("12345\C-[hh")
- assert_line('I12345')
- assert_byte_pointer_size('I12')
- assert_cursor(3)
- assert_cursor_max(6)
+ assert_line_around_cursor('I12', '345')
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
input_keys('I')
- assert_line('I12345')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'I12345')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
end
def test_vi_add_at_eol
input_keys('A')
- assert_line('A')
+ assert_line_around_cursor('A', '')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
input_keys("12345\C-[hh")
- assert_line('A12345')
- assert_byte_pointer_size('A12')
- assert_cursor(3)
- assert_cursor_max(6)
+ assert_line_around_cursor('A12', '345')
assert_instance_of(Reline::KeyActor::ViCommand, @config.editing_mode)
input_keys('A')
- assert_line('A12345')
- assert_byte_pointer_size('A12345')
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor('A12345', '')
assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
end
def test_ed_insert_one
input_keys('a')
- assert_line('a')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(1)
+ assert_line_around_cursor('a', '')
end
def test_ed_insert_two
input_keys('ab')
- assert_line('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
end
def test_ed_insert_mbchar_one
input_keys('か')
- assert_line('か')
- assert_byte_pointer_size('か')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('か', '')
end
def test_ed_insert_mbchar_two
input_keys('かき')
- assert_line('かき')
- assert_byte_pointer_size('かき')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('かき', '')
end
def test_ed_insert_for_mbchar_by_plural_code_points
input_keys("か\u3099")
- assert_line("か\u3099")
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor("か\u3099", '')
end
def test_ed_insert_for_plural_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099")
- assert_line("か\u3099き\u3099")
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor("か\u3099き\u3099", '')
end
def test_ed_next_char
input_keys("abcdef\C-[0")
- assert_line('abcdef')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'abcdef')
input_keys('l')
- assert_line('abcdef')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(6)
+ assert_line_around_cursor('a', 'bcdef')
input_keys('2l')
- assert_line('abcdef')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(6)
+ assert_line_around_cursor('abc', 'def')
end
def test_ed_prev_char
input_keys("abcdef\C-[")
- assert_line('abcdef')
- assert_byte_pointer_size('abcde')
- assert_cursor(5)
- assert_cursor_max(6)
+ assert_line_around_cursor('abcde', 'f')
input_keys('h')
- assert_line('abcdef')
- assert_byte_pointer_size('abcd')
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor('abcd', 'ef')
input_keys('2h')
- assert_line('abcdef')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(6)
+ assert_line_around_cursor('ab', 'cdef')
end
def test_history
Reline::HISTORY.concat(%w{abc 123 AAA})
input_keys("\C-[")
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys('k')
- assert_line('AAA')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
+ assert_line_around_cursor('', 'AAA')
input_keys('2k')
- assert_line('abc')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
+ assert_line_around_cursor('', 'abc')
input_keys('j')
- assert_line('123')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
+ assert_line_around_cursor('', '123')
input_keys('2j')
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
end
def test_vi_paste_prev
input_keys("abcde\C-[3h")
- assert_line('abcde')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(5)
+ assert_line_around_cursor('a', 'bcde')
input_keys('P')
- assert_line('abcde')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(5)
+ assert_line_around_cursor('a', 'bcde')
input_keys('d$')
- assert_line('a')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(1)
+ assert_line_around_cursor('', 'a')
input_keys('P')
- assert_line('bcdea')
- assert_byte_pointer_size('bcd')
- assert_cursor(3)
- assert_cursor_max(5)
+ assert_line_around_cursor('bcd', 'ea')
input_keys('2P')
- assert_line('bcdbcdbcdeeea')
- assert_byte_pointer_size('bcdbcdbcd')
- assert_cursor(9)
- assert_cursor_max(13)
+ assert_line_around_cursor('bcdbcdbcd', 'eeea')
end
def test_vi_paste_next
input_keys("abcde\C-[3h")
- assert_line('abcde')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(5)
+ assert_line_around_cursor('a', 'bcde')
input_keys('p')
- assert_line('abcde')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(5)
+ assert_line_around_cursor('a', 'bcde')
input_keys('d$')
- assert_line('a')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(1)
+ assert_line_around_cursor('', 'a')
input_keys('p')
- assert_line('abcde')
- assert_byte_pointer_size('abcd')
- assert_cursor(4)
- assert_cursor_max(5)
+ assert_line_around_cursor('abcd', 'e')
input_keys('2p')
- assert_line('abcdebcdebcde')
- assert_byte_pointer_size('abcdebcdebcd')
- assert_cursor(12)
- assert_cursor_max(13)
+ assert_line_around_cursor('abcdebcdebcd', 'e')
end
def test_vi_paste_prev_for_mbchar
input_keys("あいうえお\C-[3h")
- assert_line('あいうえお')
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor('あ', 'いうえお')
input_keys('P')
- assert_line('あいうえお')
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor('あ', 'いうえお')
input_keys('d$')
- assert_line('あ')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
+ assert_line_around_cursor('', 'あ')
input_keys('P')
- assert_line('いうえおあ')
- assert_byte_pointer_size('いうえ')
- assert_cursor(6)
- assert_cursor_max(10)
+ assert_line_around_cursor('いうえ', 'おあ')
input_keys('2P')
- assert_line('いうえいうえいうえおおおあ')
- assert_byte_pointer_size('いうえいうえいうえ')
- assert_cursor(18)
- assert_cursor_max(26)
+ assert_line_around_cursor('いうえいうえいうえ', 'おおおあ')
end
def test_vi_paste_next_for_mbchar
input_keys("あいうえお\C-[3h")
- assert_line('あいうえお')
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor('あ', 'いうえお')
input_keys('p')
- assert_line('あいうえお')
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor('あ', 'いうえお')
input_keys('d$')
- assert_line('あ')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
+ assert_line_around_cursor('', 'あ')
input_keys('p')
- assert_line('あいうえお')
- assert_byte_pointer_size('あいうえ')
- assert_cursor(8)
- assert_cursor_max(10)
+ assert_line_around_cursor('あいうえ', 'お')
input_keys('2p')
- assert_line('あいうえおいうえおいうえお')
- assert_byte_pointer_size('あいうえおいうえおいうえ')
- assert_cursor(24)
- assert_cursor_max(26)
+ assert_line_around_cursor('あいうえおいうえおいうえ', 'お')
end
def test_vi_paste_prev_for_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099く\u3099け\u3099こ\u3099\C-[3h")
- assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor("か\u3099", "き\u3099く\u3099け\u3099こ\u3099")
input_keys('P')
- assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor("か\u3099", "き\u3099く\u3099け\u3099こ\u3099")
input_keys('d$')
- assert_line("か\u3099")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
+ assert_line_around_cursor('', "か\u3099")
input_keys('P')
- assert_line("き\u3099く\u3099け\u3099こ\u3099か\u3099")
- assert_byte_pointer_size("き\u3099く\u3099け\u3099")
- assert_cursor(6)
- assert_cursor_max(10)
+ assert_line_around_cursor("き\u3099く\u3099け\u3099", "こ\u3099か\u3099")
input_keys('2P')
- assert_line("き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099こ\u3099こ\u3099こ\u3099か\u3099")
- assert_byte_pointer_size("き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099")
- assert_cursor(18)
- assert_cursor_max(26)
+ assert_line_around_cursor("き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099き\u3099く\u3099け\u3099", "こ\u3099こ\u3099こ\u3099か\u3099")
end
def test_vi_paste_next_for_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099く\u3099け\u3099こ\u3099\C-[3h")
- assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor("か\u3099", "き\u3099く\u3099け\u3099こ\u3099")
input_keys('p')
- assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor("か\u3099", "き\u3099く\u3099け\u3099こ\u3099")
input_keys('d$')
- assert_line("か\u3099")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
+ assert_line_around_cursor('', "か\u3099")
input_keys('p')
- assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099")
- assert_byte_pointer_size("か\u3099き\u3099く\u3099け\u3099")
- assert_cursor(8)
- assert_cursor_max(10)
+ assert_line_around_cursor("か\u3099き\u3099く\u3099け\u3099", "こ\u3099")
input_keys('2p')
- assert_line("か\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099")
- assert_byte_pointer_size("か\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099")
- assert_cursor(24)
- assert_cursor_max(26)
+ assert_line_around_cursor("か\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099こ\u3099き\u3099く\u3099け\u3099", "こ\u3099")
end
def test_vi_prev_next_word
input_keys("aaa b{b}b ccc\C-[0")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(13)
+ assert_line_around_cursor('', 'aaa b{b}b ccc')
input_keys('w')
- assert_byte_pointer_size('aaa ')
- assert_cursor(4)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa ', 'b{b}b ccc')
input_keys('w')
- assert_byte_pointer_size('aaa b')
- assert_cursor(5)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b', '{b}b ccc')
input_keys('w')
- assert_byte_pointer_size('aaa b{')
- assert_cursor(6)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{', 'b}b ccc')
input_keys('w')
- assert_byte_pointer_size('aaa b{b')
- assert_cursor(7)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b', '}b ccc')
input_keys('w')
- assert_byte_pointer_size('aaa b{b}')
- assert_cursor(8)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}', 'b ccc')
input_keys('w')
- assert_byte_pointer_size('aaa b{b}b ')
- assert_cursor(10)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b ', 'ccc')
input_keys('w')
- assert_byte_pointer_size('aaa b{b}b cc')
- assert_cursor(12)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b cc', 'c')
input_keys('b')
- assert_byte_pointer_size('aaa b{b}b ')
- assert_cursor(10)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b ', 'ccc')
input_keys('b')
- assert_byte_pointer_size('aaa b{b}')
- assert_cursor(8)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}', 'b ccc')
input_keys('b')
- assert_byte_pointer_size('aaa b{b')
- assert_cursor(7)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b', '}b ccc')
input_keys('b')
- assert_byte_pointer_size('aaa b{')
- assert_cursor(6)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{', 'b}b ccc')
input_keys('b')
- assert_byte_pointer_size('aaa b')
- assert_cursor(5)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b', '{b}b ccc')
input_keys('b')
- assert_byte_pointer_size('aaa ')
- assert_cursor(4)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa ', 'b{b}b ccc')
input_keys('b')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(13)
+ assert_line_around_cursor('', 'aaa b{b}b ccc')
input_keys('3w')
- assert_byte_pointer_size('aaa b{')
- assert_cursor(6)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{', 'b}b ccc')
input_keys('3w')
- assert_byte_pointer_size('aaa b{b}b ')
- assert_cursor(10)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b ', 'ccc')
input_keys('3w')
- assert_byte_pointer_size('aaa b{b}b cc')
- assert_cursor(12)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b cc', 'c')
input_keys('3b')
- assert_byte_pointer_size('aaa b{b')
- assert_cursor(7)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b', '}b ccc')
input_keys('3b')
- assert_byte_pointer_size('aaa ')
- assert_cursor(4)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa ', 'b{b}b ccc')
input_keys('3b')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(13)
+ assert_line_around_cursor('', 'aaa b{b}b ccc')
end
def test_vi_end_word
input_keys("aaa b{b}}}b ccc\C-[0")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(19)
+ assert_line_around_cursor('', 'aaa b{b}}}b ccc')
input_keys('e')
- assert_byte_pointer_size('aa')
- assert_cursor(2)
- assert_cursor_max(19)
+ assert_line_around_cursor('aa', 'a b{b}}}b ccc')
input_keys('e')
- assert_byte_pointer_size('aaa ')
- assert_cursor(6)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa ', 'b{b}}}b ccc')
input_keys('e')
- assert_byte_pointer_size('aaa b')
- assert_cursor(7)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b', '{b}}}b ccc')
input_keys('e')
- assert_byte_pointer_size('aaa b{')
- assert_cursor(8)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{', 'b}}}b ccc')
input_keys('e')
- assert_byte_pointer_size('aaa b{b}}')
- assert_cursor(11)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}', '}b ccc')
input_keys('e')
- assert_byte_pointer_size('aaa b{b}}}')
- assert_cursor(12)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}}', 'b ccc')
input_keys('e')
- assert_byte_pointer_size('aaa b{b}}}b cc')
- assert_cursor(18)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}}b cc', 'c')
input_keys('e')
- assert_byte_pointer_size('aaa b{b}}}b cc')
- assert_cursor(18)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}}b cc', 'c')
input_keys('03e')
- assert_byte_pointer_size('aaa b')
- assert_cursor(7)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b', '{b}}}b ccc')
input_keys('3e')
- assert_byte_pointer_size('aaa b{b}}}')
- assert_cursor(12)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}}', 'b ccc')
input_keys('3e')
- assert_byte_pointer_size('aaa b{b}}}b cc')
- assert_cursor(18)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}}b cc', 'c')
end
def test_vi_prev_next_big_word
input_keys("aaa b{b}b ccc\C-[0")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(13)
+ assert_line_around_cursor('', 'aaa b{b}b ccc')
input_keys('W')
- assert_byte_pointer_size('aaa ')
- assert_cursor(4)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa ', 'b{b}b ccc')
input_keys('W')
- assert_byte_pointer_size('aaa b{b}b ')
- assert_cursor(10)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b ', 'ccc')
input_keys('W')
- assert_byte_pointer_size('aaa b{b}b cc')
- assert_cursor(12)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b cc', 'c')
input_keys('B')
- assert_byte_pointer_size('aaa b{b}b ')
- assert_cursor(10)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b ', 'ccc')
input_keys('B')
- assert_byte_pointer_size('aaa ')
- assert_cursor(4)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa ', 'b{b}b ccc')
input_keys('B')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(13)
+ assert_line_around_cursor('', 'aaa b{b}b ccc')
input_keys('2W')
- assert_byte_pointer_size('aaa b{b}b ')
- assert_cursor(10)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b ', 'ccc')
input_keys('2W')
- assert_byte_pointer_size('aaa b{b}b cc')
- assert_cursor(12)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa b{b}b cc', 'c')
input_keys('2B')
- assert_byte_pointer_size('aaa ')
- assert_cursor(4)
- assert_cursor_max(13)
+ assert_line_around_cursor('aaa ', 'b{b}b ccc')
input_keys('2B')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(13)
+ assert_line_around_cursor('', 'aaa b{b}b ccc')
end
def test_vi_end_big_word
input_keys("aaa b{b}}}b ccc\C-[0")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(19)
+ assert_line_around_cursor('', 'aaa b{b}}}b ccc')
input_keys('E')
- assert_byte_pointer_size('aa')
- assert_cursor(2)
- assert_cursor_max(19)
+ assert_line_around_cursor('aa', 'a b{b}}}b ccc')
input_keys('E')
- assert_byte_pointer_size('aaa b{b}}}')
- assert_cursor(12)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}}', 'b ccc')
input_keys('E')
- assert_byte_pointer_size('aaa b{b}}}b cc')
- assert_cursor(18)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}}b cc', 'c')
input_keys('E')
- assert_byte_pointer_size('aaa b{b}}}b cc')
- assert_cursor(18)
- assert_cursor_max(19)
+ assert_line_around_cursor('aaa b{b}}}b cc', 'c')
end
def test_ed_quoted_insert
input_keys("ab\C-v\C-acd")
- assert_line("ab\C-acd")
- assert_byte_pointer_size("ab\C-acd")
- assert_cursor(6)
- assert_cursor_max(6)
+ assert_line_around_cursor("ab\C-acd", '')
end
def test_ed_quoted_insert_with_vi_arg
input_keys("ab\C-[3\C-v\C-aacd")
- assert_line("a\C-a\C-a\C-abcd")
- assert_byte_pointer_size("a\C-a\C-a\C-abcd")
- assert_cursor(10)
- assert_cursor_max(10)
+ assert_line_around_cursor("a\C-a\C-a\C-abcd", '')
end
def test_vi_replace_char
input_keys("abcdef\C-[03l")
- assert_line('abcdef')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(6)
+ assert_line_around_cursor('abc', 'def')
input_keys('rz')
- assert_line('abczef')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(6)
+ assert_line_around_cursor('abc', 'zef')
input_keys('2rx')
- assert_line('abcxxf')
- assert_byte_pointer_size('abcxx')
- assert_cursor(5)
- assert_cursor_max(6)
+ assert_line_around_cursor('abcxx', 'f')
end
def test_vi_replace_char_with_mbchar
input_keys("あいうえお\C-[0l")
- assert_line('あいうえお')
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor('あ', 'いうえお')
input_keys('rx')
- assert_line('あxうえお')
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(9)
+ assert_line_around_cursor('あ', 'xうえお')
input_keys('l2ry')
- assert_line('あxyyお')
- assert_byte_pointer_size('あxyy')
- assert_cursor(5)
- assert_cursor_max(7)
+ assert_line_around_cursor('あxyy', 'お')
end
def test_vi_next_char
input_keys("abcdef\C-[0")
- assert_line('abcdef')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'abcdef')
input_keys('fz')
- assert_line('abcdef')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'abcdef')
input_keys('fe')
- assert_line('abcdef')
- assert_byte_pointer_size('abcd')
- assert_cursor(4)
- assert_cursor_max(6)
+ assert_line_around_cursor('abcd', 'ef')
end
def test_vi_to_next_char
input_keys("abcdef\C-[0")
- assert_line('abcdef')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'abcdef')
input_keys('tz')
- assert_line('abcdef')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'abcdef')
input_keys('te')
- assert_line('abcdef')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(6)
+ assert_line_around_cursor('abc', 'def')
end
def test_vi_prev_char
input_keys("abcdef\C-[")
- assert_line('abcdef')
- assert_byte_pointer_size('abcde')
- assert_cursor(5)
- assert_cursor_max(6)
+ assert_line_around_cursor('abcde', 'f')
input_keys('Fz')
- assert_line('abcdef')
- assert_byte_pointer_size('abcde')
- assert_cursor(5)
- assert_cursor_max(6)
+ assert_line_around_cursor('abcde', 'f')
input_keys('Fa')
- assert_line('abcdef')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', 'abcdef')
end
def test_vi_to_prev_char
input_keys("abcdef\C-[")
- assert_line('abcdef')
- assert_byte_pointer_size('abcde')
- assert_cursor(5)
- assert_cursor_max(6)
+ assert_line_around_cursor('abcde', 'f')
input_keys('Tz')
- assert_line('abcdef')
- assert_byte_pointer_size('abcde')
- assert_cursor(5)
- assert_cursor_max(6)
+ assert_line_around_cursor('abcde', 'f')
input_keys('Ta')
- assert_line('abcdef')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(6)
+ assert_line_around_cursor('a', 'bcdef')
end
def test_vi_delete_next_char
input_keys("abc\C-[h")
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(3)
- assert_line('abc')
+ assert_line_around_cursor('a', 'bc')
input_keys('x')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(2)
- assert_line('ac')
+ assert_line_around_cursor('a', 'c')
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(1)
- assert_line('a')
+ assert_line_around_cursor('', 'a')
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_vi_delete_next_char_for_mbchar
input_keys("あいう\C-[h")
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(6)
- assert_line('あいう')
+ assert_line_around_cursor('あ', 'いう')
input_keys('x')
- assert_byte_pointer_size('あ')
- assert_cursor(2)
- assert_cursor_max(4)
- assert_line('あう')
+ assert_line_around_cursor('あ', 'う')
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
- assert_line('あ')
+ assert_line_around_cursor('', 'あ')
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_vi_delete_next_char_for_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099く\u3099\C-[h")
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(6)
- assert_line("か\u3099き\u3099く\u3099")
+ assert_line_around_cursor("か\u3099", "き\u3099く\u3099")
input_keys('x')
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(4)
- assert_line("か\u3099く\u3099")
+ assert_line_around_cursor("か\u3099", "く\u3099")
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(2)
- assert_line("か\u3099")
+ assert_line_around_cursor('', "か\u3099")
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('x')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_vi_delete_prev_char
input_keys('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
input_keys("\C-h")
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(1)
- assert_line('a')
+ assert_line_around_cursor('a', '')
end
def test_vi_delete_prev_char_for_mbchar
input_keys('かき')
- assert_byte_pointer_size('かき')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('かき', '')
input_keys("\C-h")
- assert_byte_pointer_size('か')
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line('か')
+ assert_line_around_cursor('か', '')
end
def test_vi_delete_prev_char_for_mbchar_by_plural_code_points
input_keys("か\u3099き\u3099")
- assert_byte_pointer_size("か\u3099き\u3099")
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor("か\u3099き\u3099", '')
input_keys("\C-h")
- assert_byte_pointer_size("か\u3099")
- assert_cursor(2)
- assert_cursor_max(2)
- assert_line("か\u3099")
+ assert_line_around_cursor("か\u3099", '')
end
def test_ed_delete_prev_char
input_keys("abcdefg\C-[h")
- assert_byte_pointer_size('abcde')
- assert_cursor(5)
- assert_cursor_max(7)
- assert_line('abcdefg')
+ assert_line_around_cursor('abcde', 'fg')
input_keys('X')
- assert_byte_pointer_size('abcd')
- assert_cursor(4)
- assert_cursor_max(6)
- assert_line('abcdfg')
+ assert_line_around_cursor('abcd', 'fg')
input_keys('3X')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(3)
- assert_line('afg')
+ assert_line_around_cursor('a', 'fg')
input_keys('p')
- assert_byte_pointer_size('abcd')
- assert_cursor(4)
- assert_cursor_max(6)
- assert_line('afbcdg')
+ assert_line_around_cursor('afbc', 'dg')
end
def test_ed_delete_prev_word
input_keys('abc def{bbb}ccc')
- assert_byte_pointer_size('abc def{bbb}ccc')
- assert_cursor(15)
- assert_cursor_max(15)
+ assert_line_around_cursor('abc def{bbb}ccc', '')
input_keys("\C-w")
- assert_byte_pointer_size('abc def{bbb}')
- assert_cursor(12)
- assert_cursor_max(12)
- assert_line('abc def{bbb}')
+ assert_line_around_cursor('abc def{bbb}', '')
input_keys("\C-w")
- assert_byte_pointer_size('abc def{')
- assert_cursor(8)
- assert_cursor_max(8)
- assert_line('abc def{')
+ assert_line_around_cursor('abc def{', '')
input_keys("\C-w")
- assert_byte_pointer_size('abc ')
- assert_cursor(4)
- assert_cursor_max(4)
- assert_line('abc ')
+ assert_line_around_cursor('abc ', '')
input_keys("\C-w")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_ed_delete_prev_word_for_mbchar
input_keys('あいう かきく{さしす}たちつ')
- assert_byte_pointer_size('あいう かきく{さしす}たちつ')
- assert_cursor(27)
- assert_cursor_max(27)
+ assert_line_around_cursor('あいう かきく{さしす}たちつ', '')
input_keys("\C-w")
- assert_byte_pointer_size('あいう かきく{さしす}')
- assert_cursor(21)
- assert_cursor_max(21)
- assert_line('あいう かきく{さしす}')
+ assert_line_around_cursor('あいう かきく{さしす}', '')
input_keys("\C-w")
- assert_byte_pointer_size('あいう かきく{')
- assert_cursor(14)
- assert_cursor_max(14)
- assert_line('あいう かきく{')
+ assert_line_around_cursor('あいう かきく{', '')
input_keys("\C-w")
- assert_byte_pointer_size('あいう ')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('あいう ')
+ assert_line_around_cursor('あいう ', '')
input_keys("\C-w")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_ed_delete_prev_word_for_mbchar_by_plural_code_points
input_keys("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}たちつ")
- assert_cursor(27)
- assert_cursor_max(27)
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}たちつ", '')
input_keys("\C-w")
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{さしす}")
- assert_cursor(21)
- assert_cursor_max(21)
- assert_line("あいう か\u3099き\u3099く\u3099{さしす}")
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{さしす}", '')
input_keys("\C-w")
- assert_byte_pointer_size("あいう か\u3099き\u3099く\u3099{")
- assert_cursor(14)
- assert_cursor_max(14)
- assert_line("あいう か\u3099き\u3099く\u3099{")
+ assert_line_around_cursor("あいう か\u3099き\u3099く\u3099{", '')
input_keys("\C-w")
- assert_byte_pointer_size('あいう ')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('あいう ')
+ assert_line_around_cursor('あいう ', '')
input_keys("\C-w")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_ed_newline_with_cr
input_keys('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
refute(@line_editor.finished?)
input_keys("\C-m")
- assert_line('ab')
+ assert_line_around_cursor('ab', '')
assert(@line_editor.finished?)
end
def test_ed_newline_with_lf
input_keys('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
refute(@line_editor.finished?)
input_keys("\C-j")
- assert_line('ab')
+ assert_line_around_cursor('ab', '')
assert(@line_editor.finished?)
end
def test_vi_list_or_eof
input_keys("\C-d") # quit from inputing
- assert_line(nil)
+ assert_nil(@line_editor.line)
assert(@line_editor.finished?)
end
def test_vi_list_or_eof_with_non_empty_line
input_keys('ab')
- assert_byte_pointer_size('ab')
- assert_cursor(2)
- assert_cursor_max(2)
+ assert_line_around_cursor('ab', '')
refute(@line_editor.finished?)
input_keys("\C-d")
- assert_line('ab')
+ assert_line_around_cursor('ab', '')
assert(@line_editor.finished?)
end
@@ -982,40 +545,19 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('foo')
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
input_keys("\C-n")
- assert_byte_pointer_size('foo_bar')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('foo_bar')
+ assert_line_around_cursor('foo_bar', '')
input_keys("\C-n")
- assert_byte_pointer_size('foo_bar_baz')
- assert_cursor(11)
- assert_cursor_max(11)
- assert_line('foo_bar_baz')
+ assert_line_around_cursor('foo_bar_baz', '')
input_keys("\C-n")
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
input_keys("\C-n")
- assert_byte_pointer_size('foo_bar')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('foo_bar')
+ assert_line_around_cursor('foo_bar', '')
input_keys("_\C-n")
- assert_byte_pointer_size('foo_bar_baz')
- assert_cursor(11)
- assert_cursor_max(11)
- assert_line('foo_bar_baz')
+ assert_line_around_cursor('foo_bar_baz', '')
input_keys("\C-n")
- assert_byte_pointer_size('foo_bar_')
- assert_cursor(8)
- assert_cursor_max(8)
- assert_line('foo_bar_')
+ assert_line_around_cursor('foo_bar_', '')
end
def test_completion_journey_reverse
@@ -1028,40 +570,19 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('foo')
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
input_keys("\C-p")
- assert_byte_pointer_size('foo_bar_baz')
- assert_cursor(11)
- assert_cursor_max(11)
- assert_line('foo_bar_baz')
+ assert_line_around_cursor('foo_bar_baz', '')
input_keys("\C-p")
- assert_byte_pointer_size('foo_bar')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('foo_bar')
+ assert_line_around_cursor('foo_bar', '')
input_keys("\C-p")
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
input_keys("\C-p")
- assert_byte_pointer_size('foo_bar_baz')
- assert_cursor(11)
- assert_cursor_max(11)
- assert_line('foo_bar_baz')
+ assert_line_around_cursor('foo_bar_baz', '')
input_keys("\C-h\C-p")
- assert_byte_pointer_size('foo_bar_baz')
- assert_cursor(11)
- assert_cursor_max(11)
- assert_line('foo_bar_baz')
+ assert_line_around_cursor('foo_bar_baz', '')
input_keys("\C-p")
- assert_byte_pointer_size('foo_bar_ba')
- assert_cursor(10)
- assert_cursor_max(10)
- assert_line('foo_bar_ba')
+ assert_line_around_cursor('foo_bar_ba', '')
end
def test_completion_journey_in_middle_of_line
@@ -1074,42 +595,21 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('abcde fo ABCDE')
- assert_line('abcde fo ABCDE')
+ assert_line_around_cursor('abcde fo ABCDE', '')
input_keys("\C-[" + 'h' * 5 + "i\C-n")
- assert_byte_pointer_size('abcde foo_bar')
- assert_cursor(13)
- assert_cursor_max(19)
- assert_line('abcde foo_bar ABCDE')
+ assert_line_around_cursor('abcde foo_bar', ' ABCDE')
input_keys("\C-n")
- assert_byte_pointer_size('abcde foo_bar_baz')
- assert_cursor(17)
- assert_cursor_max(23)
- assert_line('abcde foo_bar_baz ABCDE')
+ assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE')
input_keys("\C-n")
- assert_byte_pointer_size('abcde fo')
- assert_cursor(8)
- assert_cursor_max(14)
- assert_line('abcde fo ABCDE')
+ assert_line_around_cursor('abcde fo', ' ABCDE')
input_keys("\C-n")
- assert_byte_pointer_size('abcde foo_bar')
- assert_cursor(13)
- assert_cursor_max(19)
- assert_line('abcde foo_bar ABCDE')
+ assert_line_around_cursor('abcde foo_bar', ' ABCDE')
input_keys("_\C-n")
- assert_byte_pointer_size('abcde foo_bar_baz')
- assert_cursor(17)
- assert_cursor_max(23)
- assert_line('abcde foo_bar_baz ABCDE')
+ assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE')
input_keys("\C-n")
- assert_byte_pointer_size('abcde foo_bar_')
- assert_cursor(14)
- assert_cursor_max(20)
- assert_line('abcde foo_bar_ ABCDE')
+ assert_line_around_cursor('abcde foo_bar_', ' ABCDE')
input_keys("\C-n")
- assert_byte_pointer_size('abcde foo_bar_baz')
- assert_cursor(17)
- assert_cursor_max(23)
- assert_line('abcde foo_bar_baz ABCDE')
+ assert_line_around_cursor('abcde foo_bar_baz', ' ABCDE')
end
def test_completion
@@ -1122,15 +622,55 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('foo')
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
input_keys("\C-i")
- assert_byte_pointer_size('foo_bar')
- assert_cursor(7)
- assert_cursor_max(7)
- assert_line('foo_bar')
+ assert_line_around_cursor('foo_bar', '')
+ end
+
+ def test_autocompletion_with_upward_navigation
+ @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)
+ 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)
+ assert_line_around_cursor('Readline', '')
+ input_keys("\C-i", false)
+ assert_line_around_cursor('Regexp', '')
+ @line_editor.input_key(Reline::Key.new(:menu_complete_backward, :menu_complete_backward, false))
+ assert_line_around_cursor('Readline', '')
+ ensure
+ @config.autocompletion = false
end
def test_completion_with_disable_completion
@@ -1144,314 +684,236 @@ class Reline::KeyActor::ViInsert::Test < Reline::TestCase
}
}
input_keys('foo')
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
input_keys("\C-i")
- assert_byte_pointer_size('foo')
- assert_cursor(3)
- assert_cursor_max(3)
- assert_line('foo')
+ assert_line_around_cursor('foo', '')
end
def test_vi_first_print
input_keys("abcde\C-[^")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
+ assert_line_around_cursor('', 'abcde')
input_keys("0\C-ki")
input_keys(" abcde\C-[^")
- assert_byte_pointer_size(' ')
- assert_cursor(1)
- assert_cursor_max(6)
+ assert_line_around_cursor(' ', 'abcde')
input_keys("0\C-ki")
input_keys(" abcde ABCDE \C-[^")
- assert_byte_pointer_size(' ')
- assert_cursor(3)
- assert_cursor_max(17)
+ assert_line_around_cursor(' ', 'abcde ABCDE ')
end
def test_ed_move_to_beg
input_keys("abcde\C-[0")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(5)
+ assert_line_around_cursor('', 'abcde')
input_keys("0\C-ki")
input_keys(" abcde\C-[0")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(6)
+ assert_line_around_cursor('', ' abcde')
input_keys("0\C-ki")
input_keys(" abcde ABCDE \C-[0")
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(17)
+ assert_line_around_cursor('', ' abcde ABCDE ')
+ end
+
+ def test_vi_to_column
+ input_keys("a一二三\C-[0")
+ input_keys('1|')
+ assert_line_around_cursor('', 'a一二三')
+ input_keys('2|')
+ assert_line_around_cursor('a', '一二三')
+ input_keys('3|')
+ assert_line_around_cursor('a', '一二三')
+ input_keys('4|')
+ assert_line_around_cursor('a一', '二三')
+ input_keys('9|')
+ assert_line_around_cursor('a一二', '三')
end
def test_vi_delete_meta
input_keys("aaa bbb ccc ddd eee\C-[02w")
- assert_byte_pointer_size('aaa bbb ')
- assert_cursor(8)
- assert_cursor_max(19)
- assert_line('aaa bbb ccc ddd eee')
+ assert_line_around_cursor('aaa bbb ', 'ccc ddd eee')
input_keys('dw')
- assert_byte_pointer_size('aaa bbb ')
- assert_cursor(8)
- assert_cursor_max(15)
- assert_line('aaa bbb ddd eee')
+ assert_line_around_cursor('aaa bbb ', 'ddd eee')
input_keys('db')
- assert_byte_pointer_size('aaa ')
- assert_cursor(4)
- assert_cursor_max(11)
- assert_line('aaa ddd eee')
+ assert_line_around_cursor('aaa ', 'ddd eee')
end
def test_vi_delete_meta_with_vi_next_word_at_eol
input_keys("foo bar\C-[0w")
- assert_byte_pointer_size('foo ')
- assert_cursor(4)
- assert_cursor_max(7)
- assert_line('foo bar')
+ assert_line_around_cursor('foo ', 'bar')
input_keys('w')
- assert_byte_pointer_size('foo ba')
- assert_cursor(6)
- assert_cursor_max(7)
- assert_line('foo bar')
+ assert_line_around_cursor('foo ba', 'r')
input_keys('0dw')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
- assert_line('bar')
+ assert_line_around_cursor('', 'bar')
input_keys('dw')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
end
def test_vi_delete_meta_with_vi_next_char
input_keys("aaa bbb ccc ___ ddd\C-[02w")
- assert_byte_pointer_size('aaa bbb ')
- assert_cursor(8)
- assert_cursor_max(19)
- assert_line('aaa bbb ccc ___ ddd')
+ assert_line_around_cursor('aaa bbb ', 'ccc ___ ddd')
input_keys('df_')
- assert_byte_pointer_size('aaa bbb ')
- assert_cursor(8)
- assert_cursor_max(14)
- assert_line('aaa bbb __ ddd')
+ assert_line_around_cursor('aaa bbb ', '__ ddd')
end
def test_vi_delete_meta_with_arg
- input_keys("aaa bbb ccc\C-[02w")
- assert_byte_pointer_size('aaa bbb ')
- assert_cursor(8)
- assert_cursor_max(11)
- assert_line('aaa bbb ccc')
+ input_keys("aaa bbb ccc ddd\C-[03w")
+ assert_line_around_cursor('aaa bbb ccc ', 'ddd')
input_keys('2dl')
- assert_byte_pointer_size('aaa bbb ')
- assert_cursor(8)
- assert_cursor_max(9)
- assert_line('aaa bbb c')
+ assert_line_around_cursor('aaa bbb ccc ', 'd')
+ input_keys('d2h')
+ assert_line_around_cursor('aaa bbb cc', 'd')
+ input_keys('2d3h')
+ assert_line_around_cursor('aaa ', 'd')
+ input_keys('dd')
+ assert_line_around_cursor('', '')
end
def test_vi_change_meta
input_keys("aaa bbb ccc ddd eee\C-[02w")
- assert_byte_pointer_size('aaa bbb ')
- assert_cursor(8)
- assert_cursor_max(19)
- assert_line('aaa bbb ccc ddd eee')
+ assert_line_around_cursor('aaa bbb ', 'ccc ddd eee')
input_keys('cwaiueo')
- assert_byte_pointer_size('aaa bbb aiueo')
- assert_cursor(13)
- assert_cursor_max(21)
- assert_line('aaa bbb aiueo ddd eee')
+ assert_line_around_cursor('aaa bbb aiueo', ' ddd eee')
input_keys("\C-[")
- assert_byte_pointer_size('aaa bbb aiue')
- assert_cursor(12)
- assert_cursor_max(21)
- assert_line('aaa bbb aiueo ddd eee')
+ assert_line_around_cursor('aaa bbb aiue', 'o ddd eee')
input_keys('cb')
- assert_byte_pointer_size('aaa bbb ')
- assert_cursor(8)
- assert_cursor_max(17)
- assert_line('aaa bbb o ddd eee')
+ assert_line_around_cursor('aaa bbb ', 'o ddd eee')
end
def test_vi_change_meta_with_vi_next_word
input_keys("foo bar baz\C-[0w")
- assert_byte_pointer_size('foo ')
- assert_cursor(5)
- assert_cursor_max(13)
- assert_line('foo bar baz')
+ assert_line_around_cursor('foo ', 'bar baz')
input_keys('cwhoge')
- assert_byte_pointer_size('foo hoge')
- assert_cursor(9)
- assert_cursor_max(14)
- assert_line('foo hoge baz')
+ assert_line_around_cursor('foo hoge', ' baz')
input_keys("\C-[")
- assert_byte_pointer_size('foo hog')
- assert_cursor(8)
- assert_cursor_max(14)
- assert_line('foo hoge baz')
+ assert_line_around_cursor('foo hog', 'e baz')
+ end
+
+ def test_vi_waiting_operator_with_waiting_proc
+ input_keys("foo foo foo foo foo\C-[0")
+ input_keys('2d3fo')
+ assert_line_around_cursor('', ' foo foo')
+ input_keys('fo')
+ assert_line_around_cursor(' f', 'oo foo')
+ end
+
+ def test_vi_waiting_operator_cancel
+ input_keys("aaa bbb ccc\C-[02w")
+ assert_line_around_cursor('aaa bbb ', 'ccc')
+ # dc dy should cancel delete_meta
+ input_keys('dch')
+ input_keys('dyh')
+ # cd cy should cancel change_meta
+ input_keys('cdh')
+ input_keys('cyh')
+ # yd yc should cancel yank_meta
+ # P should not paste yanked text because yank_meta is canceled
+ input_keys('ydhP')
+ input_keys('ychP')
+ assert_line_around_cursor('aa', 'a bbb ccc')
+ end
+
+ def test_cancel_waiting_with_symbol_key
+ input_keys("aaa bbb lll\C-[0")
+ assert_line_around_cursor('', 'aaa bbb lll')
+ # ed_next_char should move cursor right and cancel vi_next_char
+ input_keys('f')
+ input_key_by_symbol(:ed_next_char)
+ input_keys('l')
+ assert_line_around_cursor('aa', 'a bbb lll')
+ # ed_next_char should move cursor right and cancel delete_meta
+ input_keys('d')
+ input_key_by_symbol(:ed_next_char)
+ input_keys('l')
+ assert_line_around_cursor('aaa ', 'bbb lll')
end
def test_unimplemented_vi_command_should_be_no_op
input_keys("abc\C-[h")
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(3)
- assert_line('abc')
+ assert_line_around_cursor('a', 'bc')
input_keys('@')
- assert_byte_pointer_size('a')
- assert_cursor(1)
- assert_cursor_max(3)
- assert_line('abc')
+ assert_line_around_cursor('a', 'bc')
end
def test_vi_yank
- input_keys("foo bar\C-[0")
- assert_line('foo bar')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(7)
+ input_keys("foo bar\C-[2h")
+ assert_line_around_cursor('foo ', 'bar')
input_keys('y3l')
- assert_line('foo bar')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(7)
+ assert_line_around_cursor('foo ', 'bar')
input_keys('P')
- assert_line('foofoo bar')
- assert_byte_pointer_size('fo')
- assert_cursor(2)
- assert_cursor_max(10)
+ assert_line_around_cursor('foo ba', 'rbar')
+ input_keys('3h3yhP')
+ assert_line_around_cursor('foofo', 'o barbar')
+ input_keys('yyP')
+ assert_line_around_cursor('foofofoofoo barba', 'ro barbar')
end
def test_vi_end_word_with_operator
input_keys("foo bar\C-[0")
- assert_line('foo bar')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(7)
+ assert_line_around_cursor('', 'foo bar')
input_keys('de')
- assert_line(' bar')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(4)
+ assert_line_around_cursor('', ' bar')
input_keys('de')
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys('de')
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
end
def test_vi_end_big_word_with_operator
input_keys("aaa b{b}}}b\C-[0")
- assert_line('aaa b{b}}}b')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(13)
+ assert_line_around_cursor('', 'aaa b{b}}}b')
input_keys('dE')
- assert_line(' b{b}}}b')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(10)
+ assert_line_around_cursor('', ' b{b}}}b')
input_keys('dE')
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
input_keys('dE')
- assert_line('')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
+ assert_line_around_cursor('', '')
end
def test_vi_next_char_with_operator
input_keys("foo bar\C-[0")
- assert_line('foo bar')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(7)
+ assert_line_around_cursor('', 'foo bar')
input_keys('df ')
- assert_line('bar')
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(3)
- end
-
- def test_pasting
- start_pasting
- input_keys('ab')
- finish_pasting
- input_keys('c')
- assert_line('abc')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
- end
-
- def test_pasting_fullwidth
- start_pasting
- input_keys('あ')
- finish_pasting
- input_keys('い')
- assert_line('あい')
- assert_byte_pointer_size('あい')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('', 'bar')
end
def test_ed_delete_next_char_at_eol
input_keys('"あ"')
- assert_line('"あ"')
- assert_byte_pointer_size('"あ"')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('"あ"', '')
input_keys("\C-[")
- assert_line('"あ"')
- assert_byte_pointer_size('"あ')
- assert_cursor(3)
- assert_cursor_max(4)
+ assert_line_around_cursor('"あ', '"')
input_keys('xa"')
- assert_line('"あ"')
- assert_byte_pointer_size('"あ"')
- assert_cursor(4)
- assert_cursor_max(4)
+ assert_line_around_cursor('"あ"', '')
end
def test_vi_kill_line_prev
input_keys("\C-u", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('abc')
- assert_byte_pointer_size('abc')
- assert_cursor(3)
- assert_cursor_max(3)
+ assert_line_around_cursor('abc', '')
input_keys("\C-u", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(0)
- assert_line('')
+ assert_line_around_cursor('', '')
input_keys('abc')
input_keys("\C-[\C-u", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(1)
- assert_line('c')
+ assert_line_around_cursor('', 'c')
input_keys("\C-u", false)
- assert_byte_pointer_size('')
- assert_cursor(0)
- assert_cursor_max(1)
- assert_line('c')
+ assert_line_around_cursor('', 'c')
+ end
+
+ def test_vi_change_to_eol
+ input_keys("abcdef\C-[2hC")
+ assert_line_around_cursor('abc', '')
+ input_keys("\C-[0C")
+ assert_line_around_cursor('', '')
+ assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+ end
+
+ def test_vi_motion_operators
+ assert_instance_of(Reline::KeyActor::ViInsert, @config.editing_mode)
+
+ assert_nothing_raised do
+ input_keys("test = { foo: bar }\C-[BBBldt}b")
+ end
+ end
+
+ def test_emacs_editing_mode
+ @line_editor.__send__(:emacs_editing_mode, nil)
+ assert(@config.editing_mode_is?(:emacs))
end
end
diff --git a/test/reline/test_key_stroke.rb b/test/reline/test_key_stroke.rb
index d377a1e972..cd205c7d9e 100644
--- a/test/reline/test_key_stroke.rb
+++ b/test/reline/test_key_stroke.rb
@@ -36,6 +36,27 @@ class Reline::KeyStroke::Test < Reline::TestCase
assert_equal(:matched, stroke.match_status("abzwabk".bytes))
end
+ def test_match_unknown
+ config = Reline::Config.new
+ config.add_default_key_binding("\e[9abc".bytes, 'x')
+ stroke = Reline::KeyStroke.new(config)
+ sequences = [
+ "\e[9abc",
+ "\e[9d",
+ "\e[A", # Up
+ "\e[1;1R", # Cursor position report
+ "\e[15~", # F5
+ "\eOP", # F1
+ "\e\e[A" # Option+Up
+ ]
+ sequences.each do |seq|
+ assert_equal(:matched, stroke.match_status(seq.bytes))
+ (1...seq.size).each do |i|
+ assert_equal(:matching, stroke.match_status(seq.bytes.take(i)))
+ end
+ end
+ end
+
def test_expand
config = Reline::Config.new
{
@@ -45,6 +66,11 @@ class Reline::KeyStroke::Test < Reline::TestCase
end
stroke = Reline::KeyStroke.new(config)
assert_equal('123'.bytes, stroke.expand('abc'.bytes))
+ # CSI sequence
+ assert_equal([:ed_unassigned] + 'bc'.bytes, stroke.expand("\e[1;2;3;4;5abc".bytes))
+ assert_equal([:ed_unassigned] + 'BC'.bytes, stroke.expand("\e\e[ABC".bytes))
+ # SS3 sequence
+ assert_equal([:ed_unassigned] + 'QR'.bytes, stroke.expand("\eOPQR".bytes))
end
def test_oneshot_key_bindings
diff --git a/test/reline/test_line_editor.rb b/test/reline/test_line_editor.rb
new file mode 100644
index 0000000000..bf688ac3c6
--- /dev/null
+++ b/test/reline/test_line_editor.rb
@@ -0,0 +1,155 @@
+require_relative 'helper'
+require 'reline/line_editor'
+require 'stringio'
+
+class Reline::LineEditor
+ class RenderLineDifferentialTest < Reline::TestCase
+ module TestIO
+ RESET_COLOR = "\e[0m"
+
+ def self.move_cursor_column(col)
+ @output << "[COL_#{col}]"
+ end
+
+ def self.erase_after_cursor
+ @output << '[ERASE]'
+ end
+ end
+
+ def setup
+ verbose, $VERBOSE = $VERBOSE, nil
+ @line_editor = Reline::LineEditor.new(nil, Encoding::UTF_8)
+ @original_iogate = Reline::IOGate
+ @output = StringIO.new
+ @line_editor.instance_variable_set(:@screen_size, [24, 80])
+ @line_editor.instance_variable_set(:@output, @output)
+ Reline.send(:remove_const, :IOGate)
+ Reline.const_set(:IOGate, TestIO)
+ Reline::IOGate.instance_variable_set(:@output, @output)
+ ensure
+ $VERBOSE = verbose
+ end
+
+ def assert_output(expected)
+ @output.reopen(+'')
+ yield
+ actual = @output.string
+ assert_equal(expected, actual.gsub("\e[0m", ''))
+ end
+
+ def teardown
+ Reline.send(:remove_const, :IOGate)
+ Reline.const_set(:IOGate, @original_iogate)
+ end
+
+ def test_line_increase_decrease
+ assert_output '[COL_0]bb' do
+ @line_editor.render_line_differential([[0, 1, 'a']], [[0, 2, 'bb']])
+ end
+
+ assert_output '[COL_0]b[COL_1][ERASE]' do
+ @line_editor.render_line_differential([[0, 2, 'aa']], [[0, 1, 'b']])
+ end
+ end
+
+ def test_dialog_appear_disappear
+ assert_output '[COL_3]dialog' do
+ @line_editor.render_line_differential([[0, 1, 'a']], [[0, 1, 'a'], [3, 6, 'dialog']])
+ end
+
+ assert_output '[COL_3]dialog' do
+ @line_editor.render_line_differential([[0, 10, 'a' * 10]], [[0, 10, 'a' * 10], [3, 6, 'dialog']])
+ end
+
+ assert_output '[COL_1][ERASE]' do
+ @line_editor.render_line_differential([[0, 1, 'a'], [3, 6, 'dialog']], [[0, 1, 'a']])
+ end
+
+ assert_output '[COL_3]aaaaaa' do
+ @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10]])
+ end
+ end
+
+ def test_dialog_change
+ assert_output '[COL_3]DIALOG' do
+ @line_editor.render_line_differential([[0, 2, 'a'], [3, 6, 'dialog']], [[0, 2, 'a'], [3, 6, 'DIALOG']])
+ end
+
+ assert_output '[COL_3]DIALOG' do
+ @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10], [3, 6, 'DIALOG']])
+ end
+ end
+
+ def test_update_under_dialog
+ assert_output '[COL_0]b[COL_1] ' do
+ @line_editor.render_line_differential([[0, 2, 'aa'], [4, 6, 'dialog']], [[0, 1, 'b'], [4, 6, 'dialog']])
+ end
+
+ assert_output '[COL_0]bbb[COL_9]b' do
+ @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'b' * 10], [3, 6, 'dialog']])
+ end
+
+ assert_output '[COL_0]b[COL_1] [COL_9][ERASE]' do
+ @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 1, 'b'], [3, 6, 'dialog']])
+ end
+ end
+
+ def test_dialog_move
+ assert_output '[COL_3]dialog[COL_9][ERASE]' do
+ @line_editor.render_line_differential([[0, 1, 'a'], [4, 6, 'dialog']], [[0, 1, 'a'], [3, 6, 'dialog']])
+ end
+
+ assert_output '[COL_4] [COL_5]dialog' do
+ @line_editor.render_line_differential([[0, 1, 'a'], [4, 6, 'dialog']], [[0, 1, 'a'], [5, 6, 'dialog']])
+ end
+
+ assert_output '[COL_2]dialog[COL_8]a' do
+ @line_editor.render_line_differential([[0, 10, 'a' * 10], [3, 6, 'dialog']], [[0, 10, 'a' * 10], [2, 6, 'dialog']])
+ end
+
+ assert_output '[COL_2]a[COL_3]dialog' do
+ @line_editor.render_line_differential([[0, 10, 'a' * 10], [2, 6, 'dialog']], [[0, 10, 'a' * 10], [3, 6, 'dialog']])
+ 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']]
+ # state_a: " fff h dddddccggeeecbbb"
+ # state_b: " hh aaaaaaaaa ccggEEEc ffff"
+
+ assert_output '[COL_1] [COL_2]hh[COL_5]aaaaaaaaa[COL_14] [COL_19]EEE[COL_23] [COL_25]ffff' do
+ @line_editor.render_line_differential(state_a, state_b)
+ end
+
+ assert_output '[COL_1]fff[COL_5] [COL_7]h[COL_8] [COL_10]ddddd[COL_19]eee[COL_23]bbb[COL_26][ERASE]' do
+ @line_editor.render_line_differential(state_b, state_a)
+ end
+ end
+ end
+
+ def test_menu_info_format
+ list = %w[aa b c d e f g hhh i j k]
+ col3 = [
+ 'aa e i',
+ 'b f j',
+ 'c g k',
+ 'd hhh'
+ ]
+ col2 = [
+ 'aa g',
+ 'b hhh',
+ 'c i',
+ 'd j',
+ 'e k',
+ 'f'
+ ]
+ assert_equal(col3, Reline::LineEditor::MenuInfo.new(list).lines(19))
+ assert_equal(col3, Reline::LineEditor::MenuInfo.new(list).lines(15))
+ assert_equal(col2, Reline::LineEditor::MenuInfo.new(list).lines(14))
+ assert_equal(col2, Reline::LineEditor::MenuInfo.new(list).lines(10))
+ assert_equal(list, Reline::LineEditor::MenuInfo.new(list).lines(9))
+ assert_equal(list, Reline::LineEditor::MenuInfo.new(list).lines(0))
+ assert_equal([], Reline::LineEditor::MenuInfo.new([]).lines(10))
+ end
+end
diff --git a/test/reline/test_macro.rb b/test/reline/test_macro.rb
index 76a677c834..04aa6474b4 100644
--- a/test/reline/test_macro.rb
+++ b/test/reline/test_macro.rb
@@ -4,9 +4,8 @@ class Reline::MacroTest < Reline::TestCase
def setup
Reline.send(:test_mode)
@config = Reline::Config.new
- @encoding = Reline::IOGate.encoding
+ @encoding = Reline.core.encoding
@line_editor = Reline::LineEditor.new(@config, @encoding)
- @line_editor.instance_variable_set(:@screen_size, [24, 80])
@output = @line_editor.output = File.open(IO::NULL, "w")
end
diff --git a/test/reline/test_reline.rb b/test/reline/test_reline.rb
index 8828e41985..40c880c11f 100644
--- a/test/reline/test_reline.rb
+++ b/test/reline/test_reline.rb
@@ -8,6 +8,7 @@ class Reline::Test < Reline::TestCase
end
def setup
+ Reline.send(:test_mode)
Reline.output_modifier_proc = nil
Reline.completion_proc = nil
Reline.prompt_proc = nil
@@ -46,35 +47,6 @@ class Reline::Test < Reline::TestCase
Reline.completion_append_character = completion_append_character
end
- def test_dialog_color_configuration
- # defaults
- assert_equal(:cyan, Reline.dialog_default_bg_color)
- assert_equal(:white, Reline.dialog_default_fg_color)
- assert_equal(:magenta, Reline.dialog_highlight_bg_color)
- assert_equal(:white, Reline.dialog_highlight_fg_color)
-
- Reline.dialog_default_bg_color = :black
- assert_equal(:black, Reline.dialog_default_bg_color)
- assert_equal(40, Reline.dialog_default_bg_color_sequence)
-
- Reline.dialog_default_fg_color = :white
- assert_equal(:white, Reline.dialog_default_fg_color)
- assert_equal(37, Reline.dialog_default_fg_color_sequence)
-
- Reline.dialog_highlight_bg_color = :white
- assert_equal(:white, Reline.dialog_highlight_bg_color)
- assert_equal(47, Reline.dialog_highlight_bg_color_sequence)
-
- Reline.dialog_highlight_fg_color = :black
- assert_equal(:black, Reline.dialog_highlight_fg_color)
- assert_equal(30, Reline.dialog_highlight_fg_color_sequence)
-
- # test value validation
- assert_raise(ArgumentError) do
- Reline.dialog_highlight_fg_color = :foo
- end
- end
-
def test_basic_word_break_characters
basic_word_break_characters = Reline.basic_word_break_characters
@@ -313,7 +285,7 @@ class Reline::Test < Reline::TestCase
input, to_write = IO.pipe
to_read, output = IO.pipe
unless Reline.__send__(:input=, input)
- omit "Setting to input is not effective on #{Reline::IOGate}"
+ omit "Setting to input is not effective on #{Reline.core.io_gate}"
end
Reline.output = output
@@ -331,12 +303,12 @@ class Reline::Test < Reline::TestCase
def test_vi_editing_mode
Reline.vi_editing_mode
- assert_equal(Reline::KeyActor::ViInsert, Reline.send(:core).config.editing_mode.class)
+ assert_equal(Reline::KeyActor::ViInsert, Reline.core.config.editing_mode.class)
end
def test_emacs_editing_mode
Reline.emacs_editing_mode
- assert_equal(Reline::KeyActor::Emacs, Reline.send(:core).config.editing_mode.class)
+ assert_equal(Reline::KeyActor::Emacs, Reline.core.config.editing_mode.class)
end
def test_add_dialog_proc
@@ -350,6 +322,9 @@ class Reline::Test < Reline::TestCase
d = Reline.dialog_proc(:test_proc)
assert_equal(dummy_proc_2, d.dialog_proc)
+ Reline.add_dialog_proc(:test_proc, nil)
+ assert_nil(Reline.dialog_proc(:test_proc))
+
l = lambda {}
Reline.add_dialog_proc(:test_lambda, l)
d = Reline.dialog_proc(:test_lambda)
@@ -397,8 +372,14 @@ class Reline::Test < Reline::TestCase
# TODO in Reline::Core
end
+ def test_dumb_terminal
+ lib = File.expand_path("../../lib", __dir__)
+ out = IO.popen([{"TERM"=>"dumb"}, Reline.test_rubybin, "-I#{lib}", "-rreline", "-e", "p Reline.core.io_gate"], &:read)
+ assert_equal("Reline::GeneralIO", out.chomp)
+ end
+
def get_reline_encoding
- if encoding = Reline::IOGate.encoding
+ if encoding = Reline.core.encoding
encoding
elsif RUBY_PLATFORM =~ /mswin|mingw/
Encoding::UTF_8
diff --git a/test/reline/test_reline_key.rb b/test/reline/test_reline_key.rb
index fb700a6f2e..7f9a11394a 100644
--- a/test/reline/test_reline_key.rb
+++ b/test/reline/test_reline_key.rb
@@ -3,6 +3,7 @@ require "reline"
class Reline::TestKey < Reline::TestCase
def setup
+ Reline.test_mode
end
def teardown
diff --git a/test/reline/test_string_processing.rb b/test/reline/test_string_processing.rb
index 5db97545da..c9b9e38643 100644
--- a/test/reline/test_string_processing.rb
+++ b/test/reline/test_string_processing.rb
@@ -6,7 +6,7 @@ class Reline::LineEditor::StringProcessingTest < Reline::TestCase
@prompt = '> '
@config = Reline::Config.new
Reline::HISTORY.instance_variable_set(:@config, @config)
- @encoding = Reline::IOGate.encoding
+ @encoding = Reline.core.encoding
@line_editor = Reline::LineEditor.new(@config, @encoding)
@line_editor.reset(@prompt, encoding: @encoding)
end
@@ -30,10 +30,7 @@ class Reline::LineEditor::StringProcessingTest < Reline::TestCase
@line_editor.instance_variable_set(:@is_multiline, true)
@line_editor.instance_variable_set(:@buffer_of_lines, buf)
- @line_editor.instance_variable_set(:@line, buf[1])
@line_editor.instance_variable_set(:@byte_pointer, 3)
- @line_editor.instance_variable_set(:@cursor, 3)
- @line_editor.instance_variable_set(:@cursor_max, 11)
@line_editor.instance_variable_set(:@line_index, 1)
@line_editor.instance_variable_set(:@completion_proc, proc { |target|
assert_equal('p', target)
@@ -42,10 +39,7 @@ class Reline::LineEditor::StringProcessingTest < Reline::TestCase
@line_editor.instance_variable_set(:@is_multiline, true)
@line_editor.instance_variable_set(:@buffer_of_lines, buf)
- @line_editor.instance_variable_set(:@line, buf[1])
@line_editor.instance_variable_set(:@byte_pointer, 6)
- @line_editor.instance_variable_set(:@cursor, 6)
- @line_editor.instance_variable_set(:@cursor_max, 11)
@line_editor.instance_variable_set(:@line_index, 1)
@line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
assert_equal('puts', target)
@@ -54,10 +48,7 @@ class Reline::LineEditor::StringProcessingTest < Reline::TestCase
})
@line_editor.__send__(:call_completion_proc)
- @line_editor.instance_variable_set(:@line, buf[0])
@line_editor.instance_variable_set(:@byte_pointer, 6)
- @line_editor.instance_variable_set(:@cursor, 6)
- @line_editor.instance_variable_set(:@cursor_max, 8)
@line_editor.instance_variable_set(:@line_index, 0)
@line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
assert_equal('ho', target)
@@ -66,10 +57,7 @@ class Reline::LineEditor::StringProcessingTest < Reline::TestCase
})
@line_editor.__send__(:call_completion_proc)
- @line_editor.instance_variable_set(:@line, buf[2])
@line_editor.instance_variable_set(:@byte_pointer, 1)
- @line_editor.instance_variable_set(:@cursor, 1)
- @line_editor.instance_variable_set(:@cursor_max, 3)
@line_editor.instance_variable_set(:@line_index, 2)
@line_editor.instance_variable_set(:@completion_proc, proc { |target, pre, post|
assert_equal('e', target)
diff --git a/test/reline/test_terminfo.rb b/test/reline/test_terminfo.rb
index dda9b32495..4e59c54838 100644
--- a/test/reline/test_terminfo.rb
+++ b/test/reline/test_terminfo.rb
@@ -58,4 +58,4 @@ class Reline::Terminfo::Test < Reline::TestCase
assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetnum('unknown') }
assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetnum(nil) }
end
-end if Reline::Terminfo.enabled?
+end if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?
diff --git a/test/reline/test_unicode.rb b/test/reline/test_unicode.rb
index 1233e034e8..834f7114c4 100644
--- a/test/reline/test_unicode.rb
+++ b/test/reline/test_unicode.rb
@@ -18,8 +18,48 @@ class Reline::Unicode::Test < Reline::TestCase
assert_equal 2, Reline::Unicode.calculate_width('√', true)
end
+ def test_csi_regexp
+ csi_sequences = ["\e[m", "\e[1m", "\e[12;34m", "\e[12;34H"]
+ assert_equal(csi_sequences, "text#{csi_sequences.join('text')}text".scan(Reline::Unicode::CSI_REGEXP))
+ end
+
+ def test_osc_regexp
+ osc_sequences = ["\e]1\a", "\e]0;OSC\a", "\e]1\e\\", "\e]0;OSC\e\\"]
+ separator = "text\atext"
+ assert_equal(osc_sequences, "#{separator}#{osc_sequences.join(separator)}#{separator}".scan(Reline::Unicode::OSC_REGEXP))
+ end
+
+ def test_split_by_width
+ assert_equal [['abc', nil, 'de'], 2], Reline::Unicode.split_by_width('abcde', 3)
+ assert_equal [['abc', nil, 'def', nil, ''], 3], Reline::Unicode.split_by_width('abcdef', 3)
+ assert_equal [['ab', nil, 'あd', nil, 'ef'], 3], Reline::Unicode.split_by_width('abあdef', 3)
+ assert_equal [["ab\1zero\2c", nil, 'def', nil, ''], 3], Reline::Unicode.split_by_width("ab\1zero\2cdef", 3)
+ assert_equal [["\e[31mabc", nil, "\e[31md\e[42mef", nil, "\e[31m\e[42mg"], 3], Reline::Unicode.split_by_width("\e[31mabcd\e[42mefg", 3)
+ assert_equal [["ab\e]0;1\ac", nil, "\e]0;1\ad"], 2], Reline::Unicode.split_by_width("ab\e]0;1\acd", 3)
+ end
+
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 "\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)
end
+
+ def test_calculate_width
+ assert_equal 9, Reline::Unicode.calculate_width('abcdefghi')
+ assert_equal 9, Reline::Unicode.calculate_width('abcdefghi', true)
+ assert_equal 7, Reline::Unicode.calculate_width('abあdef')
+ assert_equal 7, Reline::Unicode.calculate_width('abあdef', true)
+ assert_equal 14, Reline::Unicode.calculate_width("ab\1zero\2cdef")
+ assert_equal 6, Reline::Unicode.calculate_width("ab\1zero\2cdef", true)
+ assert_equal 19, Reline::Unicode.calculate_width("\e[31mabcd\e[42mefg")
+ assert_equal 7, Reline::Unicode.calculate_width("\e[31mabcd\e[42mefg", true)
+ assert_equal 12, Reline::Unicode.calculate_width("ab\e]0;1\acd")
+ assert_equal 4, Reline::Unicode.calculate_width("ab\e]0;1\acd", true)
+ assert_equal 10, Reline::Unicode.calculate_width('あいうえお')
+ assert_equal 10, Reline::Unicode.calculate_width('あいうえお', true)
+ end
end
diff --git a/test/reline/test_within_pipe.rb b/test/reline/test_within_pipe.rb
index 43a66f45f4..a42ca755fc 100644
--- a/test/reline/test_within_pipe.rb
+++ b/test/reline/test_within_pipe.rb
@@ -3,14 +3,14 @@ require_relative 'helper'
class Reline::WithinPipeTest < Reline::TestCase
def setup
Reline.send(:test_mode)
- @encoding = Reline::IOGate.encoding
+ @encoding = Reline.core.encoding
@input_reader, @writer = IO.pipe(@encoding)
Reline.input = @input_reader
@reader, @output_writer = IO.pipe(@encoding)
@output = Reline.output = @output_writer
- @config = Reline.send(:core).config
- @config.keyseq_timeout *= 600 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait CI
- @line_editor = Reline.send(:core).line_editor
+ @config = Reline.core.config
+ @config.keyseq_timeout *= 600 if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # for --jit-wait CI
+ @line_editor = Reline.core.line_editor
end
def teardown
diff --git a/test/reline/yamatanooroti/multiline_repl b/test/reline/yamatanooroti/multiline_repl
index d27d216652..66bcf51e1a 100755
--- a/test/reline/yamatanooroti/multiline_repl
+++ b/test/reline/yamatanooroti/multiline_repl
@@ -9,10 +9,6 @@ require 'optparse'
require_relative 'termination_checker'
opt = OptionParser.new
-opt.on('--prompt-list-cache-timeout VAL') { |v|
- Reline::LineEditor.__send__(:remove_const, :PROMPT_LIST_CACHE_TIMEOUT)
- Reline::LineEditor::PROMPT_LIST_CACHE_TIMEOUT = v.to_f
-}
opt.on('--dynamic-prompt') {
Reline.prompt_proc = proc { |lines|
lines.each_with_index.map { |l, i|
@@ -39,8 +35,46 @@ opt.on('--dynamic-prompt-with-newline') {
}
}
}
+opt.on('--broken-dynamic-prompt-assert-no-escape-sequence') {
+ Reline.prompt_proc = proc { |lines|
+ has_escape_sequence = lines.join.include?("\e")
+ (lines.size + 1).times.map { |i|
+ has_escape_sequence ? 'error>' : '[%04d]> ' % i
+ }
+ }
+}
+opt.on('--color-bold') {
+ Reline.output_modifier_proc = ->(output, complete:){
+ output.gsub(/./) { |c| "\e[1m#{c}\e[0m" }
+ }
+}
+opt.on('--dynamic-prompt-show-line') {
+ Reline.prompt_proc = proc { |lines|
+ lines.map { |l|
+ '[%4.4s]> ' % l
+ }
+ }
+}
+
+def assert_auto_indent_params(lines, line_index, byte_pointer, is_newline)
+ raise 'Wrong lines type' unless lines.all?(String)
+
+ line = lines[line_index]
+ raise 'Wrong line_index value' unless line
+
+ # The condition `byte_pointer <= line.bytesize` is not satisfied. Maybe bug.
+ # Instead, loose constraint `byte_pointer <= line.bytesize + 1` seems to be satisfied when is_newline is false.
+ return if is_newline
+
+ raise 'byte_pointer out of bounds' unless byte_pointer <= line.bytesize + 1
+ raise 'Invalid byte_pointer' unless line.byteslice(0, byte_pointer).valid_encoding?
+end
+
opt.on('--auto-indent') {
- AutoIndent.new
+ Reline.auto_indent_proc = lambda do |lines, line_index, byte_pointer, is_newline|
+ assert_auto_indent_params(lines, line_index, byte_pointer, is_newline)
+ AutoIndent.calculate_indent(lines, line_index, byte_pointer, is_newline)
+ end
}
opt.on('--dialog VAL') { |v|
Reline.add_dialog_proc(:simple_dialog, lambda {
@@ -98,7 +132,7 @@ opt.on('--dialog VAL') { |v|
if v.include?('alt-scrollbar')
scrollbar = true
end
- Reline::DialogRenderInfo.new(pos: cursor_pos, contents: contents, height: height, scrollbar: scrollbar)
+ Reline::DialogRenderInfo.new(pos: cursor_pos, contents: contents, height: height, scrollbar: scrollbar, face: :completion_dialog)
})
if v.include?('alt-scrollbar')
ENV['RELINE_ALT_SCROLLBAR'] = '1'
@@ -115,6 +149,10 @@ opt.on('--autocomplete') {
%w{String Struct Symbol ScriptError SyntaxError Signal}.select{ |c| c.start_with?(target) }
}
}
+opt.on('--autocomplete-empty') {
+ Reline.autocompletion = true
+ Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| [] }
+}
opt.on('--autocomplete-long') {
Reline.autocompletion = true
Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil|
@@ -145,7 +183,7 @@ opt.on('--autocomplete-long') {
opt.on('--autocomplete-super-long') {
Reline.autocompletion = true
Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil|
- c = 'A'
+ c = +'A'
2000.times.map{ s = "Str_#{c}"; c.succ!; s }.select{ |c| c.start_with?(target) }
}
}
@@ -181,8 +219,7 @@ end
begin
prompt = ENV['RELINE_TEST_PROMPT'] || 'prompt> '
puts 'Multiline REPL.'
- checker = TerminationChecker.new
- while code = Reline.readmultiline(prompt, true) { |code| checker.terminated?(code) }
+ while code = Reline.readmultiline(prompt, true) { |code| TerminationChecker.terminated?(code) }
case code.chomp
when 'exit', 'quit', 'q'
exit 0
diff --git a/test/reline/yamatanooroti/termination_checker.rb b/test/reline/yamatanooroti/termination_checker.rb
index 24fb24c4b1..b97c798c59 100644
--- a/test/reline/yamatanooroti/termination_checker.rb
+++ b/test/reline/yamatanooroti/termination_checker.rb
@@ -1,30 +1,26 @@
require 'ripper'
-require 'irb/ruby-lex'
-class TerminationChecker < RubyLex
- def terminated?(code)
- code.gsub!(/\n*$/, '').concat("\n")
- @tokens = self.class.ripper_lex_without_warning(code)
- continue = process_continue
- code_block_open = check_code_block(code)
- indent = process_nesting_level
- ltype = process_literal_type
- if code_block_open or ltype or continue or indent > 0
- false
- else
- true
- end
+module TerminationChecker
+ def self.terminated?(code)
+ Ripper.sexp(code) ? true : false
end
end
-class AutoIndent < RubyLex
- def initialize
- set_input(self)
- context = Struct.new(:auto_indent_mode, :workspace).new(true, nil)
- set_auto_indent(context)
+module AutoIndent
+ def self.calculate_indent(lines, line_index, byte_pointer, is_newline)
+ if is_newline
+ 2 * nesting_level(lines[0..line_index - 1])
+ else
+ lines = lines.dup
+ lines[line_index] = lines[line_index]&.byteslice(0, byte_pointer)
+ prev_level = nesting_level(lines[0..line_index - 1])
+ level = nesting_level(lines[0..line_index])
+ 2 * level if level < prev_level
+ end
end
- def auto_indent(&block)
- Reline.auto_indent_proc = block
+ def self.nesting_level(lines)
+ code = lines.join("\n")
+ code.scan(/if|def|\(|\[|\{/).size - code.scan(/end|\)|\]|\}/).size
end
end
diff --git a/test/reline/yamatanooroti/test_rendering.rb b/test/reline/yamatanooroti/test_rendering.rb
index c383112131..fe0f8842ea 100644
--- a/test/reline/yamatanooroti/test_rendering.rb
+++ b/test/reline/yamatanooroti/test_rendering.rb
@@ -3,7 +3,34 @@ require 'reline'
begin
require 'yamatanooroti'
- class Reline::TestRendering < Yamatanooroti::TestCase
+ class Reline::RenderingTest < Yamatanooroti::TestCase
+
+ FACE_CONFIGS = { no_config: "", valid_config: <<~VALID_CONFIG, incomplete_config: <<~INCOMPLETE_CONFIG }
+ require "reline"
+ Reline::Face.config(:completion_dialog) do |face|
+ face.define :default, foreground: :white, background: :blue
+ face.define :enhanced, foreground: :white, background: :magenta
+ face.define :scrollbar, foreground: :white, background: :blue
+ end
+ VALID_CONFIG
+ require "reline"
+ Reline::Face.config(:completion_dialog) do |face|
+ face.define :default, foreground: :white, background: :black
+ face.define :scrollbar, foreground: :white, background: :cyan
+ end
+ INCOMPLETE_CONFIG
+
+ def iterate_over_face_configs(&block)
+ FACE_CONFIGS.each do |config_name, face_config|
+ config_file = Tempfile.create(%w{face_config- .rb})
+ config_file.write face_config
+ block.call(config_name, config_file)
+ config_file.close
+ ensure
+ File.delete(config_file)
+ end
+ end
+
def setup
@pwd = Dir.pwd
suffix = '%010d' % Random.rand(0..65535)
@@ -170,9 +197,12 @@ begin
LINES
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write(":a\n\C-[k")
+ write("i\n:a")
+ write("\C-[h")
close
assert_screen(<<~EOC)
- Multiline REPL.
+ (ins)prompt> :a
+ => :a
(ins)prompt> :a
=> :a
(cmd)prompt> :a
@@ -237,6 +267,21 @@ begin
EOC
end
+ def test_esc_input
+ omit if Reline::IOGate.win?
+ start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("def\C-aabc")
+ write("\e") # single ESC
+ sleep 1
+ write("A")
+ write("B\eAC") # ESC + A (M-A, specified ed_unassigned in Reline::KeyActor::Emacs)
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> abcABCdef
+ EOC
+ end
+
def test_prompt_with_escape_sequence
ENV['RELINE_TEST_PROMPT'] = "\1\e[30m\2prompt> \1\e[m\2"
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
@@ -281,6 +326,23 @@ begin
EOC
end
+ def test_multiline_add_new_line_and_autowrap
+ start_terminal(10, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("def aaaaaaaaaa")
+ write("\n")
+ write(" bbbbbbbbbbbb")
+ write("\n")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> def aaaaaaaa
+ aa
+ prompt> bbbbbbbbbb
+ bb
+ prompt>
+ EOC
+ end
+
def test_clear
start_terminal(10, 15, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("3\C-l")
@@ -405,6 +467,9 @@ begin
write("def a\n 8\nend\ndef b\n 3\nend\C-s8")
close
assert_screen(<<~EOC)
+ prompt> 8
+ prompt> end
+ => :a
(i-search)`8'def a
(i-search)`8' 8
(i-search)`8'end
@@ -416,6 +481,9 @@ begin
write("def a\n 8\nend\ndef b\n 3\nend\C-r8\C-j")
close
assert_screen(<<~EOC)
+ prompt> 8
+ prompt> end
+ => :a
prompt> def a
prompt> 8
prompt> end
@@ -436,32 +504,32 @@ begin
EOC
end
- def test_prompt_list_caching
- start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --prompt-list-cache-timeout 10 --dynamic-prompt}, startup_message: 'Multiline REPL.')
+ def test_broken_prompt_list
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --broken-dynamic-prompt}, startup_message: 'Multiline REPL.')
write("def hoge\n 3\nend")
close
assert_screen(<<~EOC)
Multiline REPL.
[0000]> def hoge
[0001]> 3
- [0002]> end
+ [0001]> end
EOC
end
- def test_broken_prompt_list
- start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --broken-dynamic-prompt}, startup_message: 'Multiline REPL.')
- write("def hoge\n 3\nend")
+ def test_no_escape_sequence_passed_to_dynamic_prompt
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete --color-bold --broken-dynamic-prompt-assert-no-escape-sequence}, startup_message: 'Multiline REPL.')
+ write("%[ S")
+ write("\n")
close
assert_screen(<<~EOC)
Multiline REPL.
- [0000]> def hoge
- [0001]> 3
- [0001]> end
+ [0000]> %[ S
+ [0001]>
EOC
end
def test_enable_bracketed_paste
- omit if Reline::IOGate.win?
+ omit if Reline.core.io_gate.win?
write_inputrc <<~LINES
set enable-bracketed-paste on
LINES
@@ -632,6 +700,31 @@ begin
EOC
end
+ def test_longer_than_screen_height_nearest_cursor_with_scroll_back
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write(<<~EOC.chomp)
+ if 1
+ if 2
+ if 3
+ if 4
+ puts
+ end
+ end
+ end
+ end
+ EOC
+ write("\C-p" * 4 + "\C-e" + "\C-p" * 4)
+ write("2")
+ close
+ assert_screen(<<~EOC)
+ prompt> if 12
+ prompt> if 2
+ prompt> if 3
+ prompt> if 4
+ prompt> puts
+ EOC
+ end
+
def test_update_cursor_correctly_when_just_cursor_moving
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def hoge\n 01234678")
@@ -649,6 +742,66 @@ begin
EOC
end
+ def test_auto_indent
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ "def hoge\nputs(\n1,\n2\n)\nend".lines do |line|
+ write line
+ end
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> def hoge
+ prompt> puts(
+ prompt> 1,
+ prompt> 2
+ prompt> )
+ prompt> end
+ EOC
+ end
+
+ def test_auto_indent_when_inserting_line
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write 'aa(bb(cc(dd(ee('
+ write "\C-b" * 5 + "\n"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> aa(bb(cc(d
+ prompt> d(ee(
+ EOC
+ end
+
+ def test_auto_indent_multibyte_insert_line
+ start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write "if true\n"
+ write "あいうえお\n"
+ 4.times { write "\C-b\C-b\C-b\C-b\e\r" }
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> if true
+ prompt> あ
+ prompt> い
+ prompt> う
+ prompt> え
+ prompt> お
+ prompt>
+ EOC
+ end
+
+ def test_newline_after_wrong_indent
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write "if 1\n aa"
+ write "\n"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> if 1
+ prompt> aa
+ prompt>
+ EOC
+ end
+
def test_suppress_auto_indent_just_after_pasted
start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
write("def hoge\n [[\n 3]]\ned")
@@ -678,6 +831,20 @@ begin
EOC
end
+ def test_auto_indent_with_various_spaces
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write "(\n\C-v"
+ write "\C-k\n\C-v"
+ write "\C-k)"
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> (
+ prompt> ^K
+ prompt> )
+ EOC
+ end
+
def test_autowrap_in_the_middle_of_a_line
start_terminal(5, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
write("def abcdefg; end\C-b\C-b\C-b\C-b\C-b")
@@ -764,7 +931,7 @@ begin
end
def test_with_newline
- omit if Reline::IOGate.win?
+ 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
@@ -785,6 +952,18 @@ begin
EOC
end
+ def test_multiline_completion
+ start_terminal(10, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --complete}, startup_message: 'Multiline REPL.')
+ write("def hoge\n St\n St\C-p\t")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> def hoge
+ prompt> String
+ prompt> St
+ EOC
+ end
+
def test_completion_journey_2nd_line
write_inputrc <<~LINES
set editing-mode vi
@@ -813,41 +992,83 @@ begin
end
def test_simple_dialog
- start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
- write('a')
- write('b')
- write('c')
- write("\C-h")
- close
- assert_screen(<<~'EOC')
- Multiline REPL.
- prompt> ab
- Ruby is...
- A dynamic, open source programming
- language with a focus on simplicity
- and productivity. It has an elegant
- syntax that is natural to read and
- easy to write.
- EOC
+ iterate_over_face_configs do |config_name, config_file|
+ start_terminal(20, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
+ write('a')
+ write('b')
+ write('c')
+ write("\C-h")
+ close
+ assert_screen(<<~'EOC', "Failed with `#{config_name}` in Face")
+ Multiline REPL.
+ prompt> ab
+ Ruby is...
+ A dynamic, open source programming
+ language with a focus on simplicity
+ and productivity. It has an elegant
+ syntax that is natural to read and
+ easy to write.
+ EOC
+ end
end
def test_simple_dialog_at_right_edge
- start_terminal(20, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
- write('a')
- write('b')
- write('c')
- write("\C-h")
- close
- assert_screen(<<~'EOC')
- Multiline REPL.
- prompt> ab
- Ruby is...
- A dynamic, open source programming
- language with a focus on simplicity
- and productivity. It has an elegant
- syntax that is natural to read and
- easy to write.
- EOC
+ iterate_over_face_configs do |config_name, config_file|
+ start_terminal(20, 40, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
+ write('a')
+ write('b')
+ write('c')
+ write("\C-h")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> ab
+ Ruby is...
+ A dynamic, open source programming
+ language with a focus on simplicity
+ and productivity. It has an elegant
+ syntax that is natural to read and
+ easy to write.
+ EOC
+ end
+ end
+
+ def test_dialog_scroll_pushup_condition
+ iterate_over_face_configs do |config_name, config_file|
+ start_terminal(10, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("\n" * 10)
+ write("if 1\n sSts\nend")
+ write("\C-p\C-h\C-e\C-h")
+ close
+ assert_screen(<<~'EOC')
+ prompt>
+ prompt>
+ prompt>
+ prompt>
+ prompt>
+ prompt>
+ prompt> if 1
+ prompt> St
+ prompt> enString
+ Struct
+ EOC
+ end
+ end
+
+ def test_simple_dialog_with_scroll_screen
+ iterate_over_face_configs do |config_name, config_file|
+ start_terminal(5, 50, %W{ruby -I#{@pwd}/lib -r#{config_file.path} #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog simple}, startup_message: 'Multiline REPL.')
+ write("if 1\n 2\n 3\n 4\n 5\n 6")
+ write("\C-p\C-n\C-p\C-p\C-p#")
+ close
+ assert_screen(<<~'EOC')
+ prompt> 2
+ prompt> 3#
+ prompt> 4
+ prompt> 5 Ruby is...
+ prompt> 6 A dynamic, open source programming
+ EOC
+ end
end
def test_autocomplete_at_bottom
@@ -901,6 +1122,19 @@ begin
EOC
end
+ def test_force_insert_before_autocomplete
+ start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write('Sy')
+ write(";St\t\t")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> Sy;Struct
+ String
+ Struct
+ EOC
+ end
+
def test_simple_dialog_with_scroll_key
start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog long,scrollkey}, startup_message: 'Multiline REPL.')
write('a')
@@ -1003,6 +1237,32 @@ begin
EOC
end
+ def test_autocomplete_empty_string
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
+ write("\C-i")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> String
+ String █
+ Struct ▀
+ Symbol
+ EOC
+ end
+
+ def test_paste_code_with_tab_indent_does_not_fail
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-empty}, startup_message: 'Multiline REPL.')
+ write("2.times do\n\tputs\n\tputs\nend")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> 2.times do
+ prompt> puts
+ prompt> puts
+ prompt> end
+ EOC
+ end
+
def test_autocomplete_after_2nd_line
start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
write("def hoge\n Str")
@@ -1031,6 +1291,23 @@ begin
EOC
end
+ def test_rerender_multiple_dialog
+ start_terminal(20, 60, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete --dialog simple}, startup_message: 'Multiline REPL.')
+ write("if\n abcdef\n 123456\n 456789\nend\C-p\C-p\C-p\C-p Str")
+ write("\t")
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> if String
+ prompt> aStringRuby is...
+ prompt> 1StructA dynamic, open source programming
+ prompt> 456789 language with a focus on simplicity
+ prompt> end and productivity. It has an elegant
+ syntax that is natural to read and
+ easy to write.
+ EOC
+ end
+
def test_autocomplete_long_with_scrollbar
start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-long}, startup_message: 'Multiline REPL.')
write('S')
@@ -1081,6 +1358,32 @@ begin
EOC
end
+ def test_autocomplete_super_long_scroll_to_bottom
+ start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-super-long}, startup_message: 'Multiline REPL.')
+ shift_tab = [27, 91, 90]
+ write('S' + shift_tab.map(&:chr).join)
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt> Str_BXX
+ Str_BXJ
+ Str_BXK
+ Str_BXL
+ Str_BXM
+ Str_BXN
+ Str_BXO
+ Str_BXP
+ Str_BXQ
+ Str_BXR
+ Str_BXS
+ Str_BXT
+ Str_BXU
+ Str_BXV
+ Str_BXW
+ Str_BXX▄
+ EOC
+ end
+
def test_autocomplete_super_long_and_backspace
start_terminal(20, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete-super-long}, startup_message: 'Multiline REPL.')
shift_tab = [27, 91, 90]
@@ -1090,15 +1393,15 @@ begin
assert_screen(<<~'EOC')
Multiline REPL.
prompt> Str_BX
- Str_BX
- Str_BXA
- Str_BXB
- Str_BXC
- Str_BXD
- Str_BXE
- Str_BXF
- Str_BXG
- Str_BXH
+ Str_BX █
+ Str_BXA█
+ Str_BXB█
+ Str_BXC█
+ Str_BXD█
+ Str_BXE█
+ Str_BXF█
+ Str_BXG█
+ Str_BXH█
Str_BXI
Str_BXJ
Str_BXK
@@ -1142,7 +1445,7 @@ begin
Multiline R
EPL.
prompt> Sym
- String
+ String █
Struct █
Symbol █
StopIterat█
@@ -1201,21 +1504,21 @@ begin
def test_scroll_at_bottom_for_dialog
start_terminal(10, 40, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
- write("\n\n\n\n\n\n")
- write("def hoge\n\n\n\n\n\n\nend\C-p\C-p\C-p\C-e")
+ write("\n\n\n\n\n\n\n\n\n\n\n")
+ write("def hoge\n\nend\C-p\C-e")
write(" S")
close
assert_screen(<<~'EOC')
- prompt> def hoge
prompt>
prompt>
prompt>
+ prompt>
+ prompt>
+ prompt> def hoge
prompt> S
- prompt> String
- prompt> Struct
- prompt> enSymbol
- ScriptError
- Signal
+ prompt> enString █
+ Struct ▀
+ Symbol
EOC
end
@@ -1255,32 +1558,49 @@ begin
EOC
end
+ def test_lines_passed_to_dynamic_prompt
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dynamic-prompt-show-line}, startup_message: 'Multiline REPL.')
+ write("if true")
+ write("\n")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ [if t]> if true
+ [ ]>
+ EOC
+ end
+
def test_clear_dialog_when_just_move_cursor_at_last_line
start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
- write("class A\n 3\nend\n")
- write("\C-p\C-p\C-p\C-e\C-hS")
+ write("class A\n 3\nend\n\n\n")
+ write("\C-p\C-p\C-e; S")
write("\C-n")
- write("1")
+ write(";")
close
assert_screen(<<~'EOC')
prompt> 3
prompt> end
=> 3
- prompt> class S
- prompt> 31
- prompt> end
+ prompt>
+ prompt>
+ prompt> class A
+ prompt> 3; S
+ prompt> end;
EOC
end
def test_clear_dialog_when_adding_new_line_to_end_of_buffer
start_terminal(10, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
- write("class A\n def a\n 3\n end\nend")
+ write("class A\n def a\n 3\n 3\n end\nend")
write("\n")
write("class S")
write("\n")
write(" 3")
close
assert_screen(<<~'EOC')
+ prompt> def a
+ prompt> 3
+ prompt> 3
prompt> end
prompt> end
=> :a
@@ -1298,6 +1618,7 @@ begin
write(" 3")
close
assert_screen(<<~'EOC')
+ prompt> 3
prompt> end
prompt> end
=> :a
@@ -1333,6 +1654,59 @@ begin
EOC
end
+ def test_bracket_newline_indent
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write("[\n")
+ write("1")
+ close
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt> [
+ prompt> 1
+ EOC
+ end
+
+ def test_repeated_input_delete
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl}, startup_message: 'Multiline REPL.')
+ write("a\C-h" * 4000)
+ close
+ assert_screen(<<~'EOC')
+ Multiline REPL.
+ prompt>
+ EOC
+ end
+
+ def test_exit_with_ctrl_d
+ start_terminal(5, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ begin
+ write("\C-d")
+ close
+ rescue EOFError
+ # EOFError is raised when process terminated.
+ end
+ assert_screen(<<~EOC)
+ Multiline REPL.
+ prompt>
+ EOC
+ end
+
+ def test_thread_safe
+ start_terminal(6, 30, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --auto-indent}, startup_message: 'Multiline REPL.')
+ write("[Thread.new{Reline.readline'>'},Thread.new{Reline.readmultiline('>'){true}}].map(&:join).size\n")
+ write("exit\n")
+ write("exit\n")
+ write("42\n")
+ close
+ assert_screen(<<~EOC)
+ >exit
+ >exit
+ => 2
+ prompt> 42
+ => 42
+ prompt>
+ EOC
+ end
+
def write_inputrc(content)
File.open(@inputrc_file, 'w') do |f|
f.write content
diff --git a/test/resolv/test_dns.rb b/test/resolv/test_dns.rb
index 9d243bbf50..40c5406db8 100644
--- a/test/resolv/test_dns.rb
+++ b/test/resolv/test_dns.rb
@@ -44,6 +44,16 @@ class TestResolvDNS < Test::Unit::TestCase
BasicSocket.do_not_reverse_lookup = @save_do_not_reverse_lookup
end
+ def with_tcp(host, port)
+ t = TCPServer.new(host, port)
+ begin
+ t.listen(1)
+ yield t
+ ensure
+ t.close
+ end
+ end
+
def with_udp(host, port)
u = UDPSocket.new
begin
@@ -54,6 +64,50 @@ class TestResolvDNS < Test::Unit::TestCase
end
end
+ def with_udp_and_tcp(host, port)
+ if port == 0
+ # Automatic port; we might need to retry until we find a port which is free on both UDP _and_ TCP.
+ retries_remaining = 5
+ t = nil
+ u = nil
+ begin
+ begin
+ u = UDPSocket.new
+ u.bind(host, 0)
+ _, udp_port, _, _ = u.addr
+ t = TCPServer.new(host, udp_port)
+ t.listen(1)
+ rescue Errno::EADDRINUSE, Errno::EACCES
+ # ADDRINUSE is what should get thrown if we try and bind a port which is already bound on UNIXen,
+ # but windows can sometimes throw EACCESS.
+ # See: https://stackoverflow.com/questions/48478869/cannot-bind-to-some-ports-due-to-permission-denied
+ retries_remaining -= 1
+ if retries_remaining > 0
+ t&.close
+ t = nil
+ u&.close
+ u = nil
+ retry
+ end
+ raise
+ end
+
+ # If we get to this point, we have a valid t & u socket
+ yield u, t
+ ensure
+ t&.close
+ u&.close
+ end
+ else
+ # Explicitly specified port, don't retry the bind.
+ with_udp(host, port) do |u|
+ with_tcp(host, port) do |t|
+ yield u, t
+ end
+ end
+ end
+ end
+
# [ruby-core:65836]
def test_resolve_with_2_ndots
conf = Resolv::DNS::Config.new :nameserver => ['127.0.0.1'], :ndots => 2
@@ -157,6 +211,166 @@ class TestResolvDNS < Test::Unit::TestCase
}
end
+ def test_query_ipv4_address_truncated_tcp_fallback
+ begin
+ OpenSSL
+ rescue LoadError
+ skip 'autoload problem. see [ruby-dev:45021][Bug #5786]'
+ end if defined?(OpenSSL)
+
+ num_records = 50
+
+ with_udp_and_tcp('127.0.0.1', 0) {|u, t|
+ _, server_port, _, server_address = u.addr
+ client_thread = Thread.new {
+ Resolv::DNS.open(:nameserver_port => [[server_address, server_port]]) {|dns|
+ dns.getresources("foo.example.org", Resolv::DNS::Resource::IN::A)
+ }
+ }
+ udp_server_thread = Thread.new {
+ msg, (_, client_port, _, client_address) = Timeout.timeout(5) {u.recvfrom(4096)}
+ id, word2, qdcount, ancount, nscount, arcount = msg.unpack("nnnnnn")
+ qr = (word2 & 0x8000) >> 15
+ opcode = (word2 & 0x7800) >> 11
+ aa = (word2 & 0x0400) >> 10
+ tc = (word2 & 0x0200) >> 9
+ rd = (word2 & 0x0100) >> 8
+ ra = (word2 & 0x0080) >> 7
+ z = (word2 & 0x0070) >> 4
+ rcode = word2 & 0x000f
+ rest = msg[12..-1]
+ assert_equal(0, qr) # 0:query 1:response
+ assert_equal(0, opcode) # 0:QUERY 1:IQUERY 2:STATUS
+ assert_equal(0, aa) # Authoritative Answer
+ assert_equal(0, tc) # TrunCation
+ assert_equal(1, rd) # Recursion Desired
+ assert_equal(0, ra) # Recursion Available
+ assert_equal(0, z) # Reserved for future use
+ assert_equal(0, rcode) # 0:No-error 1:Format-error 2:Server-failure 3:Name-Error 4:Not-Implemented 5:Refused
+ assert_equal(1, qdcount) # number of entries in the question section.
+ assert_equal(0, ancount) # number of entries in the answer section.
+ assert_equal(0, nscount) # number of entries in the authority records section.
+ assert_equal(0, arcount) # number of entries in the additional records section.
+ name = [3, "foo", 7, "example", 3, "org", 0].pack("Ca*Ca*Ca*C")
+ assert_operator(rest, :start_with?, name)
+ rest = rest[name.length..-1]
+ assert_equal(4, rest.length)
+ qtype, _ = rest.unpack("nn")
+ assert_equal(1, qtype) # A
+ assert_equal(1, qtype) # IN
+ id = id
+ qr = 1
+ opcode = opcode
+ aa = 0
+ tc = 1
+ rd = rd
+ ra = 1
+ z = 0
+ rcode = 0
+ qdcount = 0
+ ancount = num_records
+ nscount = 0
+ arcount = 0
+ word2 = (qr << 15) |
+ (opcode << 11) |
+ (aa << 10) |
+ (tc << 9) |
+ (rd << 8) |
+ (ra << 7) |
+ (z << 4) |
+ rcode
+ msg = [id, word2, qdcount, ancount, nscount, arcount].pack("nnnnnn")
+ type = 1
+ klass = 1
+ ttl = 3600
+ rdlength = 4
+ num_records.times do |i|
+ rdata = [192,0,2,i].pack("CCCC") # 192.0.2.x (TEST-NET address) RFC 3330
+ rr = [name, type, klass, ttl, rdlength, rdata].pack("a*nnNna*")
+ msg << rr
+ end
+ u.send(msg[0...512], 0, client_address, client_port)
+ }
+ tcp_server_thread = Thread.new {
+ ct = t.accept
+ msg = ct.recv(512)
+ msg.slice!(0..1) # Size (only for TCP)
+ id, word2, qdcount, ancount, nscount, arcount = msg.unpack("nnnnnn")
+ qr = (word2 & 0x8000) >> 15
+ opcode = (word2 & 0x7800) >> 11
+ aa = (word2 & 0x0400) >> 10
+ tc = (word2 & 0x0200) >> 9
+ rd = (word2 & 0x0100) >> 8
+ ra = (word2 & 0x0080) >> 7
+ z = (word2 & 0x0070) >> 4
+ rcode = word2 & 0x000f
+ rest = msg[12..-1]
+ assert_equal(0, qr) # 0:query 1:response
+ assert_equal(0, opcode) # 0:QUERY 1:IQUERY 2:STATUS
+ assert_equal(0, aa) # Authoritative Answer
+ assert_equal(0, tc) # TrunCation
+ assert_equal(1, rd) # Recursion Desired
+ assert_equal(0, ra) # Recursion Available
+ assert_equal(0, z) # Reserved for future use
+ assert_equal(0, rcode) # 0:No-error 1:Format-error 2:Server-failure 3:Name-Error 4:Not-Implemented 5:Refused
+ assert_equal(1, qdcount) # number of entries in the question section.
+ assert_equal(0, ancount) # number of entries in the answer section.
+ assert_equal(0, nscount) # number of entries in the authority records section.
+ assert_equal(0, arcount) # number of entries in the additional records section.
+ name = [3, "foo", 7, "example", 3, "org", 0].pack("Ca*Ca*Ca*C")
+ assert_operator(rest, :start_with?, name)
+ rest = rest[name.length..-1]
+ assert_equal(4, rest.length)
+ qtype, _ = rest.unpack("nn")
+ assert_equal(1, qtype) # A
+ assert_equal(1, qtype) # IN
+ id = id
+ qr = 1
+ opcode = opcode
+ aa = 0
+ tc = 0
+ rd = rd
+ ra = 1
+ z = 0
+ rcode = 0
+ qdcount = 0
+ ancount = num_records
+ nscount = 0
+ arcount = 0
+ word2 = (qr << 15) |
+ (opcode << 11) |
+ (aa << 10) |
+ (tc << 9) |
+ (rd << 8) |
+ (ra << 7) |
+ (z << 4) |
+ rcode
+ msg = [id, word2, qdcount, ancount, nscount, arcount].pack("nnnnnn")
+ type = 1
+ klass = 1
+ ttl = 3600
+ rdlength = 4
+ num_records.times do |i|
+ rdata = [192,0,2,i].pack("CCCC") # 192.0.2.x (TEST-NET address) RFC 3330
+ rr = [name, type, klass, ttl, rdlength, rdata].pack("a*nnNna*")
+ msg << rr
+ end
+ msg = "#{[msg.bytesize].pack("n")}#{msg}" # Prefix with size
+ ct.send(msg, 0)
+ ct.close
+ }
+ result, _ = assert_join_threads([client_thread, udp_server_thread, tcp_server_thread])
+ assert_instance_of(Array, result)
+ assert_equal(50, result.length)
+ result.each_with_index do |rr, i|
+ assert_instance_of(Resolv::DNS::Resource::IN::A, rr)
+ assert_instance_of(Resolv::IPv4, rr.address)
+ assert_equal("192.0.2.#{i}", rr.address.to_s)
+ assert_equal(3600, rr.ttl)
+ end
+ }
+ end
+
def test_query_ipv4_duplicate_responses
begin
OpenSSL
@@ -374,7 +588,8 @@ class TestResolvDNS < Test::Unit::TestCase
["2001:db8::1", "2001:db8::0:1"],
["::", "0:0:0:0:0:0:0:0"],
["2001::", "2001::0"],
- ["2001:db8::1:1:1:1:1", "2001:db8:0:1:1:1:1:1"],
+ ["2001:db8:0:1:1:1:1:1", "2001:db8:0:1:1:1:1:1"], # RFC 5952 Section 4.2.2.
+ ["2001:db8::1:1:1:1", "2001:db8:0:0:1:1:1:1"],
["1::1:0:0:0:1", "1:0:0:1:0:0:0:1"],
["1::1:0:0:1", "1:0:0:0:1:0:0:1"],
]
@@ -457,4 +672,30 @@ class TestResolvDNS < Test::Unit::TestCase
end
assert_raise(Resolv::ResolvError) { dns.each_name('example.com') }
end
+
+ def test_unreachable_server
+ unreachable_ip = '127.0.0.1'
+ sock = UDPSocket.new
+ sock.connect(unreachable_ip, 53)
+ begin
+ sock.send('1', 0)
+ rescue Errno::ENETUNREACH, Errno::EHOSTUNREACH
+ else
+ omit('cannot test unreachable server, as IP used is reachable')
+ end
+
+ config = {
+ :nameserver => [unreachable_ip],
+ :search => ['lan'],
+ :ndots => 1
+ }
+ r = Resolv.new([Resolv::DNS.new(config)])
+ assert_equal([], r.getaddresses('www.google.com'))
+
+ config[:raise_timeout_errors] = true
+ r = Resolv.new([Resolv::DNS.new(config)])
+ assert_raise(Resolv::ResolvError) { r.getaddresses('www.google.com') }
+ ensure
+ sock&.close
+ end
end
diff --git a/test/resolv/test_resource.rb b/test/resolv/test_resource.rb
index b75cf67f31..434380236e 100644
--- a/test/resolv/test_resource.rb
+++ b/test/resolv/test_resource.rb
@@ -23,4 +23,80 @@ class TestResolvResource < Test::Unit::TestCase
def test_coord
Resolv::LOC::Coord.create('1 2 1.1 N')
end
+
+ def test_srv_no_compress
+ # Domain name in SRV RDATA should not be compressed
+ issue29 = 'https://github.com/ruby/resolv/issues/29'
+ m = Resolv::DNS::Message.new(0)
+ m.add_answer('example.com', 0, Resolv::DNS::Resource::IN::SRV.new(0, 0, 0, 'www.example.com'))
+ assert_equal "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x07example\x03com\x00\x00\x21\x00\x01\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x03www\x07example\x03com\x00", m.encode, issue29
+ end
+end
+
+class TestResolvResourceCAA < Test::Unit::TestCase
+ def test_caa_roundtrip
+ raw_msg = "\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x03new\x07example\x03com\x00\x01\x01\x00\x01\x00\x00\x00\x00\x00\x16\x00\x05issueca1.example.net\xC0\x0C\x01\x01\x00\x01\x00\x00\x00\x00\x00\x0C\x80\x03tbsUnknown".b
+
+ m = Resolv::DNS::Message.new(0)
+ m.add_answer('new.example.com', 0, Resolv::DNS::Resource::IN::CAA.new(0, 'issue', 'ca1.example.net'))
+ m.add_answer('new.example.com', 0, Resolv::DNS::Resource::IN::CAA.new(128, 'tbs', 'Unknown'))
+ assert_equal raw_msg, m.encode
+
+ m = Resolv::DNS::Message.decode(raw_msg)
+ assert_equal 2, m.answer.size
+ _, _, caa0 = m.answer[0]
+ assert_equal 0, caa0.flags
+ assert_equal false, caa0.critical?
+ assert_equal 'issue', caa0.tag
+ assert_equal 'ca1.example.net', caa0.value
+ _, _, caa1 = m.answer[1]
+ assert_equal true, caa1.critical?
+ assert_equal 128, caa1.flags
+ assert_equal 'tbs', caa1.tag
+ assert_equal 'Unknown', caa1.value
+ end
+
+ def test_caa_stackoverflow
+ # gathered in the wild
+ raw_msg = "\x8D\x32\x81\x80\x00\x01\x00\x0B\x00\x00\x00\x00\x0Dstackoverflow\x03com\x00\x01\x01\x00\x01\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x13\x00\x05issuecomodoca.com\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x2D\x00\x05issuedigicert.com; cansignhttpexchanges=yes\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x16\x00\x05issueletsencrypt.org\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x29\x00\x05issuepki.goog; cansignhttpexchanges=yes\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x12\x00\x05issuesectigo.com\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x17\x00\x09issuewildcomodoca.com\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x31\x00\x09issuewilddigicert.com; cansignhttpexchanges=yes\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x1A\x00\x09issuewildletsencrypt.org\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x2D\x00\x09issuewildpki.goog; cansignhttpexchanges=yes\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x16\x00\x09issuewildsectigo.com\xC0\x0C\x01\x01\x00\x01\x00\x00\x01\x2C\x00\x2D\x80\x05iodefmailto:sysadmin-team@stackoverflow.com".b
+
+ m = Resolv::DNS::Message.decode(raw_msg)
+ assert_equal 11, m.answer.size
+ _, _, caa3 = m.answer[3]
+ assert_equal 0, caa3.flags
+ assert_equal 'issue', caa3.tag
+ assert_equal 'pki.goog; cansignhttpexchanges=yes', caa3.value
+ _, _, caa8 = m.answer[8]
+ assert_equal 0, caa8.flags
+ assert_equal 'issuewild', caa8.tag
+ assert_equal 'pki.goog; cansignhttpexchanges=yes', caa8.value
+ _, _, caa10 = m.answer[10]
+ assert_equal 128, caa10.flags
+ assert_equal 'iodef', caa10.tag
+ assert_equal 'mailto:sysadmin-team@stackoverflow.com', caa10.value
+ end
+
+ def test_caa_flags
+ assert_equal 255,
+ Resolv::DNS::Resource::IN::CAA.new(255, 'issue', 'ca1.example.net').flags
+ assert_raise(ArgumentError) do
+ Resolv::DNS::Resource::IN::CAA.new(256, 'issue', 'ca1.example.net')
+ end
+
+ assert_raise(ArgumentError) do
+ Resolv::DNS::Resource::IN::CAA.new(-1, 'issue', 'ca1.example.net')
+ end
+ end
+
+ def test_caa_tag
+ assert_raise(ArgumentError, 'Empty tag should be rejected') do
+ Resolv::DNS::Resource::IN::CAA.new(0, '', 'ca1.example.net')
+ end
+
+ assert_equal '123456789012345',
+ Resolv::DNS::Resource::IN::CAA.new(0, '123456789012345', 'ca1.example.net').tag
+ assert_raise(ArgumentError, 'Tag longer than 15 bytes should be rejected') do
+ Resolv::DNS::Resource::IN::CAA.new(0, '1234567890123456', 'ca1.example.net')
+ end
+ end
end
diff --git a/test/resolv/test_svcb_https.rb b/test/resolv/test_svcb_https.rb
new file mode 100644
index 0000000000..5dc3163d9e
--- /dev/null
+++ b/test/resolv/test_svcb_https.rb
@@ -0,0 +1,231 @@
+# frozen_string_literal: false
+require 'test/unit'
+require 'resolv'
+
+class TestResolvSvcbHttps < Test::Unit::TestCase
+ # Wraps a RR in answer section
+ def wrap_rdata(rrtype, rrclass, rdata)
+ [
+ "\x00\x00\x00\x00", # ID/FLAGS
+ [0, 1, 0, 0].pack('nnnn'), # QDCOUNT/ANCOUNT/NSCOUNT/ARCOUNT
+ "\x07example\x03com\x00", # NAME
+ [rrtype, rrclass, 0, rdata.bytesize].pack('nnNn'), # TYPE/CLASS/TTL/RDLENGTH
+ rdata,
+ ].join.b
+ end
+
+ def test_svcparams
+ params = Resolv::DNS::SvcParams.new([Resolv::DNS::SvcParam::Mandatory.new([1])])
+
+ assert_equal 1, params.count
+
+ params.add Resolv::DNS::SvcParam::NoDefaultALPN.new
+ params.add Resolv::DNS::SvcParam::ALPN.new(%w[h2 h3])
+
+ assert_equal 3, params.count
+
+ assert_equal [1], params[:mandatory].keys
+ assert_equal [1], params[0].keys
+
+ assert_equal %w[h2 h3], params[:alpn].protocol_ids
+ assert_equal %w[h2 h3], params[1].protocol_ids
+
+ params.delete :mandatory
+ params.delete :alpn
+
+ assert_equal 1, params.count
+
+ assert_nil params[:mandatory]
+ assert_nil params[1]
+
+ ary = params.each.to_a
+
+ assert_instance_of Resolv::DNS::SvcParam::NoDefaultALPN, ary.first
+ end
+
+ def test_svcb
+ rr = Resolv::DNS::Resource::IN::SVCB.new(0, 'example.com.')
+
+ assert_equal 0, rr.priority
+ assert rr.alias_mode?
+ assert !rr.service_mode?
+ assert_equal Resolv::DNS::Name.create('example.com.'), rr.target
+ assert rr.params.empty?
+
+ rr = Resolv::DNS::Resource::IN::SVCB.new(16, 'example.com.', [
+ Resolv::DNS::SvcParam::ALPN.new(%w[h2 h3]),
+ ])
+
+ assert_equal 16, rr.priority
+ assert !rr.alias_mode?
+ assert rr.service_mode?
+
+ assert_equal 1, rr.params.count
+ assert_instance_of Resolv::DNS::SvcParam::ALPN, rr.params[:alpn]
+ end
+
+ def test_svcb_encode_order
+ msg = Resolv::DNS::Message.new(0)
+ msg.add_answer(
+ 'example.com.', 0,
+ Resolv::DNS::Resource::IN::SVCB.new(16, 'foo.example.org.', [
+ Resolv::DNS::SvcParam::ALPN.new(%w[h2 h3-19]),
+ Resolv::DNS::SvcParam::Mandatory.new([4, 1]),
+ Resolv::DNS::SvcParam::IPv4Hint.new(['192.0.2.1']),
+ ])
+ )
+
+ expected = wrap_rdata 64, 1, "\x00\x10\x03foo\x07example\x03org\x00" +
+ "\x00\x00\x00\x04\x00\x01\x00\x04" +
+ "\x00\x01\x00\x09\x02h2\x05h3-19" +
+ "\x00\x04\x00\x04\xc0\x00\x02\x01"
+
+ assert_equal expected, msg.encode
+ end
+
+ ## Test vectors from [RFC9460]
+
+ def test_alias_mode
+ wire = wrap_rdata 65, 1, "\x00\x00\x03foo\x07example\x03com\x00"
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 0, rr.priority
+ assert_equal Resolv::DNS::Name.create('foo.example.com.'), rr.target
+ assert_equal 0, rr.params.count
+
+ assert_equal wire, msg.encode
+ end
+
+ def test_target_name_is_root
+ wire = wrap_rdata 64, 1, "\x00\x01\x00"
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 1, rr.priority
+ assert_equal Resolv::DNS::Name.create('.'), rr.target
+ assert_equal 0, rr.params.count
+
+ assert_equal wire, msg.encode
+ end
+
+ def test_specifies_port
+ wire = wrap_rdata 64, 1, "\x00\x10\x03foo\x07example\x03com\x00" +
+ "\x00\x03\x00\x02\x00\x35"
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 16, rr.priority
+ assert_equal Resolv::DNS::Name.create('foo.example.com.'), rr.target
+ assert_equal 1, rr.params.count
+ assert_equal 53, rr.params[:port].port
+
+ assert_equal wire, msg.encode
+ end
+
+ def test_generic_key
+ wire = wrap_rdata 64, 1, "\x00\x01\x03foo\x07example\x03com\x00" +
+ "\x02\x9b\x00\x05hello"
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 1, rr.priority
+ assert_equal Resolv::DNS::Name.create('foo.example.com.'), rr.target
+ assert_equal 1, rr.params.count
+ assert_equal 'hello', rr.params[:key667].value
+
+ assert_equal wire, msg.encode
+ end
+
+ def test_two_ipv6hints
+ wire = wrap_rdata 64, 1, "\x00\x01\x03foo\x07example\x03com\x00" +
+ "\x00\x06\x00\x20" +
+ ("\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+ "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x01")
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 1, rr.priority
+ assert_equal Resolv::DNS::Name.create('foo.example.com.'), rr.target
+ assert_equal 1, rr.params.count
+ assert_equal [Resolv::IPv6.create('2001:db8::1'), Resolv::IPv6.create('2001:db8::53:1')],
+ rr.params[:ipv6hint].addresses
+
+ assert_equal wire, msg.encode
+ end
+
+ def test_ipv6hint_embedded_ipv4
+ wire = wrap_rdata 64, 1, "\x00\x01\x07example\x03com\x00" +
+ "\x00\x06\x00\x10\x20\x01\x0d\xb8\x01\x22\x03\x44\x00\x00\x00\x00\xc0\x00\x02\x21"
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 1, rr.priority
+ assert_equal Resolv::DNS::Name.create('example.com.'), rr.target
+ assert_equal 1, rr.params.count
+ assert_equal [Resolv::IPv6.create('2001:db8:122:344::192.0.2.33')],
+ rr.params[:ipv6hint].addresses
+
+ assert_equal wire, msg.encode
+ end
+
+ def test_mandatory_alpn_ipv4hint
+ wire = wrap_rdata 64, 1, "\x00\x10\x03foo\x07example\x03org\x00" +
+ "\x00\x00\x00\x04\x00\x01\x00\x04" +
+ "\x00\x01\x00\x09\x02h2\x05h3-19" +
+ "\x00\x04\x00\x04\xc0\x00\x02\x01"
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 16, rr.priority
+ assert_equal Resolv::DNS::Name.create('foo.example.org.'), rr.target
+ assert_equal 3, rr.params.count
+ assert_equal [1, 4], rr.params[:mandatory].keys
+ assert_equal ['h2', 'h3-19'], rr.params[:alpn].protocol_ids
+ assert_equal [Resolv::IPv4.create('192.0.2.1')], rr.params[:ipv4hint].addresses
+
+ assert_equal wire, msg.encode
+ end
+
+ def test_alpn_comma_backslash
+ wire = wrap_rdata 64, 1, "\x00\x10\x03foo\x07example\x03org\x00" +
+ "\x00\x01\x00\x0c\x08f\\oo,bar\x02h2"
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 16, rr.priority
+ assert_equal Resolv::DNS::Name.create('foo.example.org.'), rr.target
+ assert_equal 1, rr.params.count
+ assert_equal ['f\oo,bar', 'h2'], rr.params[:alpn].protocol_ids
+
+ assert_equal wire, msg.encode
+ end
+
+ ## For [RFC9461]
+
+ def test_dohpath
+ wire = wrap_rdata 64, 1, "\x00\x01\x03one\x03one\x03one\x03one\x00" +
+ "\x00\x01\x00\x03\x02h2" +
+ "\x00\x03\x00\x02\x01\xbb" +
+ "\x00\x04\x00\x08\x01\x01\x01\x01\x01\x00\x00\x01" +
+ "\x00\x06\x00\x20" +
+ ("\x26\x06\x47\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11" +
+ "\x26\x06\x47\x00\x47\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x01") +
+ "\x00\x07\x00\x10/dns-query{?dns}"
+ msg = Resolv::DNS::Message.decode(wire)
+ _, _, rr = msg.answer.first
+
+ assert_equal 1, rr.priority
+ assert_equal Resolv::DNS::Name.create('one.one.one.one.'), rr.target
+ assert_equal 5, rr.params.count
+ assert_equal ['h2'], rr.params[:alpn].protocol_ids
+ assert_equal 443, rr.params[:port].port
+ assert_equal [Resolv::IPv4.create('1.1.1.1'), Resolv::IPv4.create('1.0.0.1')],
+ rr.params[:ipv4hint].addresses
+ assert_equal [Resolv::IPv6.create('2606:4700:4700::1111'), Resolv::IPv6.create('2606:4700:4700::1001')],
+ rr.params[:ipv6hint].addresses
+ assert_equal '/dns-query{?dns}', rr.params[:dohpath].template
+
+ assert_equal wire, msg.encode
+ end
+end
diff --git a/test/rinda/test_rinda.rb b/test/rinda/test_rinda.rb
deleted file mode 100644
index dbe414b783..0000000000
--- a/test/rinda/test_rinda.rb
+++ /dev/null
@@ -1,912 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'envutil'
-
-require 'drb/drb'
-require 'drb/eq'
-require 'rinda/ring'
-require 'rinda/tuplespace'
-require 'timeout'
-require 'singleton'
-
-module Rinda
-
-class MockClock
- include Singleton
-
- class MyTS < Rinda::TupleSpace
- def keeper_thread
- nil
- end
-
- def stop_keeper
- if @keeper
- @keeper.kill
- @keeper.join
- @keeper = nil
- end
- end
- end
-
- def initialize
- @now = 2
- @reso = 1
- @ts = nil
- @inf = 2**31 - 1
- end
-
- def start_keeper
- @now = 2
- @reso = 1
- @ts&.stop_keeper
- @ts = MyTS.new
- @ts.write([2, :now])
- @inf = 2**31 - 1
- end
-
- def stop_keeper
- @ts.stop_keeper
- end
-
- def now
- @now.to_f
- end
-
- def at(n)
- n
- end
-
- def _forward(n=nil)
- now ,= @ts.take([nil, :now])
- @now = now + n
- @ts.write([@now, :now])
- end
-
- def forward(n)
- while n > 0
- _forward(@reso)
- n -= @reso
- Thread.pass
- end
- end
-
- def rewind
- @ts.take([nil, :now])
- @ts.write([@inf, :now])
- @ts.take([nil, :now])
- @now = 2
- @ts.write([2, :now])
- end
-
- def sleep(n=nil)
- now ,= @ts.read([nil, :now])
- @ts.read([(now + n)..@inf, :now])
- 0
- end
-end
-
-module Time
- def sleep(n)
- @m.sleep(n)
- end
- module_function :sleep
-
- def at(n)
- n
- end
- module_function :at
-
- def now
- defined?(@m) && @m ? @m.now : 2
- end
- module_function :now
-
- def rewind
- @m.rewind
- end
- module_function :rewind
-
- def forward(n)
- @m.forward(n)
- end
- module_function :forward
-
- @m = MockClock.instance
-end
-
-class TupleSpace
- def sleep(n)
- Kernel.sleep(n * 0.01)
- end
-end
-
-module TupleSpaceTestModule
- def setup
- MockClock.instance.start_keeper
- end
-
- def teardown
- MockClock.instance.stop_keeper
- end
-
- def sleep(n)
- if Thread.current == Thread.main
- Time.forward(n)
- else
- Time.sleep(n)
- end
- end
-
- def thread_join(th)
- while th.alive?
- Kernel.sleep(0.1)
- sleep(1)
- end
- th.value
- end
-
- def test_00_tuple
- tuple = Rinda::TupleEntry.new([1,2,3])
- assert(!tuple.canceled?)
- assert(!tuple.expired?)
- assert(tuple.alive?)
- end
-
- def test_00_template
- tmpl = Rinda::Template.new([1,2,3])
- assert_equal(3, tmpl.size)
- assert_equal(3, tmpl[2])
- assert(tmpl.match([1,2,3]))
- assert(!tmpl.match([1,nil,3]))
-
- tmpl = Rinda::Template.new([/^rinda/i, nil, :hello])
- assert_equal(3, tmpl.size)
- assert(tmpl.match(['Rinda', 2, :hello]))
- assert(!tmpl.match(['Rinda', 2, Symbol]))
- assert(!tmpl.match([1, 2, :hello]))
- assert(tmpl.match([/^rinda/i, 2, :hello]))
-
- tmpl = Rinda::Template.new([Symbol])
- assert_equal(1, tmpl.size)
- assert(tmpl.match([:hello]))
- assert(tmpl.match([Symbol]))
- assert(!tmpl.match(['Symbol']))
-
- tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
- assert_equal(2, tmpl.size)
- assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
- assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
- assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
- assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
-
- assert_raise(Rinda::InvalidHashTupleKey) do
- Rinda::Template.new({:message=>String, "name"=>String})
- end
- tmpl = Rinda::Template.new({"name"=>String})
- assert_equal(1, tmpl.size)
- assert(tmpl.match({"name"=>"Foo"}))
- assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
- assert(!tmpl.match({"message"=>:symbol, "name"=>"Foo", "1"=>2}))
- assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
- assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
-
- tmpl = Rinda::Template.new({"message"=>String, "name"=>String})
- assert_equal(2, tmpl.size)
- assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
- assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
- assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
- assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
-
- tmpl = Rinda::Template.new({"message"=>String})
- assert_equal(1, tmpl.size)
- assert(tmpl.match({"message"=>"Hello"}))
- assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
- assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
- assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
- assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
-
- tmpl = Rinda::Template.new({"message"=>String, "name"=>nil})
- assert_equal(2, tmpl.size)
- assert(tmpl.match({"message"=>"Hello", "name"=>"Foo"}))
- assert(!tmpl.match({"message"=>"Hello", "name"=>"Foo", "1"=>2}))
- assert(!tmpl.match({"message"=>"Hi", "name"=>"Foo", "age"=>1}))
- assert(!tmpl.match({"message"=>"Hello", "no_name"=>"Foo"}))
-
- assert_raise(Rinda::InvalidHashTupleKey) do
- @ts.write({:message=>String, "name"=>String})
- end
-
- @ts.write([1, 2, 3])
- assert_equal([1, 2, 3], @ts.take([1, 2, 3]))
-
- @ts.write({'1'=>1, '2'=>2, '3'=>3})
- assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.take({'1'=>1, '2'=>2, '3'=>3}))
-
- entry = @ts.write(['1'=>1, '2'=>2, '3'=>3])
- assert_raise(Rinda::RequestExpiredError) do
- assert_equal({'1'=>1, '2'=>2, '3'=>3}, @ts.read({'1'=>1}, 0))
- end
- entry.cancel
- end
-
- def test_00_DRbObject
- ro = DRbObject.new(nil, "druby://host:1234")
- tmpl = Rinda::DRbObjectTemplate.new
- assert(tmpl === ro)
-
- tmpl = Rinda::DRbObjectTemplate.new("druby://host:1234")
- assert(tmpl === ro)
-
- tmpl = Rinda::DRbObjectTemplate.new("druby://host:12345")
- assert(!(tmpl === ro))
-
- tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/host:/)
- assert(tmpl === ro)
-
- ro = DRbObject.new_with(12345, 1234)
- assert(!(tmpl === ro))
-
- ro = DRbObject.new_with("druby://foo:12345", 1234)
- assert(!(tmpl === ro))
-
- tmpl = Rinda::DRbObjectTemplate.new(/^druby:\/\/(foo|bar):/)
- assert(tmpl === ro)
-
- ro = DRbObject.new_with("druby://bar:12345", 1234)
- assert(tmpl === ro)
-
- ro = DRbObject.new_with("druby://baz:12345", 1234)
- assert(!(tmpl === ro))
- end
-
- def test_inp_rdp
- assert_raise(Rinda::RequestExpiredError) do
- @ts.take([:empty], 0)
- end
-
- assert_raise(Rinda::RequestExpiredError) do
- @ts.read([:empty], 0)
- end
- end
-
- def test_ruby_talk_264062
- th = Thread.new {
- assert_raise(Rinda::RequestExpiredError) do
- @ts.take([:empty], 1)
- end
- }
- sleep(10)
- thread_join(th)
-
- th = Thread.new {
- assert_raise(Rinda::RequestExpiredError) do
- @ts.read([:empty], 1)
- end
- }
- sleep(10)
- thread_join(th)
- end
-
- def test_symbol_tuple
- @ts.write([:symbol, :symbol])
- @ts.write(['string', :string])
- assert_equal([[:symbol, :symbol]], @ts.read_all([:symbol, nil]))
- assert_equal([[:symbol, :symbol]], @ts.read_all([Symbol, nil]))
- assert_equal([], @ts.read_all([:nil, nil]))
- end
-
- def test_core_01
- 5.times do
- @ts.write([:req, 2])
- end
-
- assert_equal([[:req, 2], [:req, 2], [:req, 2], [:req, 2], [:req, 2]],
- @ts.read_all([nil, nil]))
-
- taker = Thread.new(5) do |count|
- s = 0
- count.times do
- tuple = @ts.take([:req, Integer])
- assert_equal(2, tuple[1])
- s += tuple[1]
- end
- @ts.write([:ans, s])
- s
- end
-
- assert_equal(10, thread_join(taker))
- assert_equal([:ans, 10], @ts.take([:ans, 10]))
- assert_equal([], @ts.read_all([nil, nil]))
- end
-
- def test_core_02
- taker = Thread.new(5) do |count|
- s = 0
- count.times do
- tuple = @ts.take([:req, Integer])
- assert_equal(2, tuple[1])
- s += tuple[1]
- end
- @ts.write([:ans, s])
- s
- end
-
- 5.times do
- @ts.write([:req, 2])
- end
-
- assert_equal(10, thread_join(taker))
- assert_equal([:ans, 10], @ts.take([:ans, 10]))
- assert_equal([], @ts.read_all([nil, nil]))
- end
-
- def test_core_03_notify
- notify1 = @ts.notify(nil, [:req, Integer])
- notify2 = @ts.notify(nil, {"message"=>String, "name"=>String})
-
- 5.times do
- @ts.write([:req, 2])
- end
-
- 5.times do
- tuple = @ts.take([:req, Integer])
- assert_equal(2, tuple[1])
- end
-
- 5.times do
- assert_equal(['write', [:req, 2]], notify1.pop)
- end
- 5.times do
- assert_equal(['take', [:req, 2]], notify1.pop)
- end
-
- @ts.write({"message"=>"first", "name"=>"3"})
- @ts.write({"message"=>"second", "name"=>"1"})
- @ts.write({"message"=>"third", "name"=>"0"})
- @ts.take({"message"=>"third", "name"=>"0"})
- @ts.take({"message"=>"first", "name"=>"3"})
-
- assert_equal(["write", {"message"=>"first", "name"=>"3"}], notify2.pop)
- assert_equal(["write", {"message"=>"second", "name"=>"1"}], notify2.pop)
- assert_equal(["write", {"message"=>"third", "name"=>"0"}], notify2.pop)
- assert_equal(["take", {"message"=>"third", "name"=>"0"}], notify2.pop)
- assert_equal(["take", {"message"=>"first", "name"=>"3"}], notify2.pop)
- end
-
- def test_cancel_01
- entry = @ts.write([:removeme, 1])
- assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
- entry.cancel
- assert_equal([], @ts.read_all([nil, nil]))
-
- template = nil
- taker = Thread.new do
- assert_raise(Rinda::RequestCanceledError) do
- @ts.take([:take, nil], 10) do |t|
- template = t
- Thread.new do
- template.cancel
- end
- end
- end
- end
-
- sleep(2)
- thread_join(taker)
-
- assert(template.canceled?)
-
- @ts.write([:take, 1])
-
- assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
- end
-
- def test_cancel_02
- omit 'this test is unstable with --jit-wait' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
- entry = @ts.write([:removeme, 1])
- assert_equal([[:removeme, 1]], @ts.read_all([nil, nil]))
- entry.cancel
- assert_equal([], @ts.read_all([nil, nil]))
-
- template = nil
- reader = Thread.new do
- assert_raise(Rinda::RequestCanceledError) do
- @ts.read([:take, nil], 10) do |t|
- template = t
- Thread.new do
- template.cancel
- end
- end
- end
- end
-
- sleep(2)
- thread_join(reader)
-
- assert(template.canceled?)
-
- @ts.write([:take, 1])
-
- assert_equal([[:take, 1]], @ts.read_all([nil, nil]))
- end
-
- class SimpleRenewer
- def initialize(sec, n = 1)
- @sec = sec
- @n = n
- end
-
- def renew
- return -1 if @n <= 0
- @n -= 1
- return @sec
- end
- end
-
- def test_00_renewer
- tuple = Rinda::TupleEntry.new([1,2,3], true)
- assert(!tuple.canceled?)
- assert(tuple.expired?)
- assert(!tuple.alive?)
-
- tuple = Rinda::TupleEntry.new([1,2,3], 1)
- assert(!tuple.canceled?)
- assert(!tuple.expired?)
- assert(tuple.alive?)
- sleep(2)
- assert(tuple.expired?)
- assert(!tuple.alive?)
-
- @renewer = SimpleRenewer.new(1,2)
- tuple = Rinda::TupleEntry.new([1,2,3], @renewer)
- assert(!tuple.canceled?)
- assert(!tuple.expired?)
- assert(tuple.alive?)
- sleep(1)
- assert(!tuple.canceled?)
- assert(!tuple.expired?)
- assert(tuple.alive?)
- sleep(2)
- assert(tuple.expired?)
- assert(!tuple.alive?)
- end
-end
-
-class TupleSpaceTest < Test::Unit::TestCase
- include TupleSpaceTestModule
-
- def setup
- super
- ThreadGroup.new.add(Thread.current)
- @ts = Rinda::TupleSpace.new(1)
- end
- def teardown
- # implementation-dependent
- @ts.instance_eval{
- if th = @keeper
- th.kill
- th.join
- end
- }
- super
- end
-end
-
-class TupleSpaceProxyTest < Test::Unit::TestCase
- include TupleSpaceTestModule
-
- def setup
- if RUBY_PLATFORM.match?(/mingw/)
- @omitted = true
- omit 'This test seems to randomly hang on GitHub Actions MinGW UCRT64'
- end
- super
- ThreadGroup.new.add(Thread.current)
- @ts_base = Rinda::TupleSpace.new(1)
- @ts = Rinda::TupleSpaceProxy.new(@ts_base)
- @server = DRb.start_service("druby://localhost:0")
- end
- def teardown
- return if @omitted
- @omitted = false
-
- # implementation-dependent
- @ts_base.instance_eval{
- if th = @keeper
- th.kill
- th.join
- end
- }
- @server.stop_service
- DRb::DRbConn.stop_pool
- super
- end
-
- def test_remote_array_and_hash
- # Don't remove ary/hsh local variables.
- # These are necessary to protect objects from GC.
- ary = [1, 2, 3]
- @ts.write(DRbObject.new(ary))
- assert_equal([1, 2, 3], @ts.take([1, 2, 3], 0))
- hsh = {'head' => 1, 'tail' => 2}
- @ts.write(DRbObject.new(hsh))
- assert_equal({'head' => 1, 'tail' => 2},
- @ts.take({'head' => 1, 'tail' => 2}, 0))
- end
-
- def test_take_bug_8215
- omit "this test randomly fails on mswin" if /mswin/ =~ RUBY_PLATFORM
- service = DRb.start_service("druby://localhost:0", @ts_base)
-
- uri = service.uri
-
- args = [EnvUtil.rubybin, *%W[-rdrb/drb -rdrb/eq -rrinda/ring -rrinda/tuplespace -e]]
-
- take = spawn(*args, <<-'end;', uri)
- uri = ARGV[0]
- DRb.start_service("druby://localhost:0")
- ro = DRbObject.new_with_uri(uri)
- ts = Rinda::TupleSpaceProxy.new(ro)
- th = Thread.new do
- ts.take([:test_take, nil])
- rescue Interrupt
- # Expected
- end
- Kernel.sleep(0.1)
- th.raise(Interrupt) # causes loss of the taken tuple
- ts.write([:barrier, :continue])
- Kernel.sleep
- end;
-
- @ts_base.take([:barrier, :continue])
-
- write = spawn(*args, <<-'end;', uri)
- uri = ARGV[0]
- DRb.start_service("druby://localhost:0")
- ro = DRbObject.new_with_uri(uri)
- ts = Rinda::TupleSpaceProxy.new(ro)
- ts.write([:test_take, 42])
- end;
-
- status = Process.wait(write)
-
- assert_equal([[:test_take, 42]], @ts_base.read_all([:test_take, nil]),
- '[bug:8215] tuple lost')
- ensure
- service.stop_service if service
- DRb::DRbConn.stop_pool
- signal = /mswin|mingw/ =~ RUBY_PLATFORM ? "KILL" : "TERM"
- Process.kill(signal, write) if write && status.nil?
- Process.kill(signal, take) if take
- Process.wait(write) if write && status.nil?
- Process.wait(take) if take
- end
-end
-
-module RingIPv4
- def ipv4_mc(rf)
- begin
- v4mc = rf.make_socket('239.0.0.1')
- rescue Errno::ENETUNREACH, Errno::ENOBUFS, Errno::ENODEV
- omit 'IPv4 multicast not available'
- end
-
- begin
- yield v4mc
- ensure
- v4mc.close
- end
- end
-end
-
-module RingIPv6
- def prepare_ipv6(r)
- begin
- Socket.getifaddrs.each do |ifaddr|
- next unless ifaddr.addr
- next unless ifaddr.addr.ipv6_linklocal?
- next if ifaddr.name[0, 2] == "lo"
- r.multicast_interface = ifaddr.ifindex
- return ifaddr
- end
- rescue NotImplementedError
- # ifindex() function may not be implemented on Windows.
- return if
- Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? && !addrinfo.ipv6_loopback? }
- end
- omit 'IPv6 not available'
- end
-
- def ipv6_mc(rf, hops = nil)
- ifaddr = prepare_ipv6(rf)
- rf.multicast_hops = hops if hops
- begin
- v6mc = rf.make_socket("ff02::1")
- rescue Errno::EINVAL
- # somehow Debian 6.0.7 needs ifname
- v6mc = rf.make_socket("ff02::1%#{ifaddr.name}")
- rescue Errno::EADDRNOTAVAIL
- return # IPv6 address for multicast not available
- rescue Errno::ENETDOWN
- return # Network is down
- rescue Errno::EHOSTUNREACH
- return # Unreachable for some reason
- end
- begin
- yield v6mc
- ensure
- v6mc.close
- end
- end
-end
-
-class TestRingServer < Test::Unit::TestCase
- include RingIPv4
-
- def setup
- @port = Rinda::Ring_PORT
-
- @ts = Rinda::TupleSpace.new
- @rs = Rinda::RingServer.new(@ts, [], @port)
- @server = DRb.start_service("druby://localhost:0")
- end
- def teardown
- @rs.shutdown
- # implementation-dependent
- @ts.instance_eval{
- if th = @keeper
- th.kill
- th.join
- end
- }
- @server.stop_service
- DRb::DRbConn.stop_pool
- end
-
- def test_do_reply
- with_timeout(30) {_test_do_reply}
- end
-
- def _test_do_reply
- called = nil
-
- callback_orig = proc { |ts|
- called = ts
- }
-
- callback = DRb::DRbObject.new callback_orig
-
- @ts.write [:lookup_ring, callback]
-
- @rs.do_reply
-
- wait_for(30) {called}
-
- assert_same @ts, called
- end
-
- def test_do_reply_local
- omit 'timeout-based test becomes unstable with --jit-wait' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
- with_timeout(30) {_test_do_reply_local}
- end
-
- def _test_do_reply_local
- called = nil
-
- callback = proc { |ts|
- called = ts
- }
-
- @ts.write [:lookup_ring, callback]
-
- @rs.do_reply
-
- wait_for(30) {called}
-
- assert_same @ts, called
- end
-
- def test_make_socket_unicast
- v4 = @rs.make_socket('127.0.0.1')
-
- assert_equal('127.0.0.1', v4.local_address.ip_address)
- assert_equal(@port, v4.local_address.ip_port)
- end
-
- def test_make_socket_ipv4_multicast
- ipv4_mc(@rs) do |v4mc|
- begin
- if Socket.const_defined?(:SO_REUSEPORT) then
- assert(v4mc.getsockopt(:SOCKET, :SO_REUSEPORT).bool)
- else
- assert(v4mc.getsockopt(:SOCKET, :SO_REUSEADDR).bool)
- end
- rescue TypeError
- if /aix/ =~ RUBY_PLATFORM
- omit "Known bug in getsockopt(2) on AIX"
- end
- raise $!
- end
-
- assert_equal('0.0.0.0', v4mc.local_address.ip_address)
- assert_equal(@port, v4mc.local_address.ip_port)
- end
- end
-
- def test_make_socket_ipv6_multicast
- omit 'IPv6 not available' unless
- Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? && !addrinfo.ipv6_loopback? }
-
- begin
- v6mc = @rs.make_socket('ff02::1')
- rescue Errno::EADDRNOTAVAIL
- return # IPv6 address for multicast not available
- rescue Errno::ENOBUFS => e
- omit "Missing multicast support in OS: #{e.message}"
- end
-
- if Socket.const_defined?(:SO_REUSEPORT) then
- assert v6mc.getsockopt(:SOCKET, :SO_REUSEPORT).bool
- else
- assert v6mc.getsockopt(:SOCKET, :SO_REUSEADDR).bool
- end
-
- assert_equal('::1', v6mc.local_address.ip_address)
- assert_equal(@port, v6mc.local_address.ip_port)
- end
-
- def test_ring_server_ipv4_multicast
- @rs.shutdown
- begin
- @rs = Rinda::RingServer.new(@ts, [['239.0.0.1', '0.0.0.0']], @port)
- rescue Errno::ENOBUFS, Errno::ENODEV => e
- omit "Missing multicast support in OS: #{e.message}"
- end
-
- v4mc = @rs.instance_variable_get('@sockets').first
-
- begin
- if Socket.const_defined?(:SO_REUSEPORT) then
- assert(v4mc.getsockopt(:SOCKET, :SO_REUSEPORT).bool)
- else
- assert(v4mc.getsockopt(:SOCKET, :SO_REUSEADDR).bool)
- end
- rescue TypeError
- if /aix/ =~ RUBY_PLATFORM
- omit "Known bug in getsockopt(2) on AIX"
- end
- raise $!
- end
-
- assert_equal('0.0.0.0', v4mc.local_address.ip_address)
- assert_equal(@port, v4mc.local_address.ip_port)
- end
-
- def test_ring_server_ipv6_multicast
- omit 'IPv6 not available' unless
- Socket.ip_address_list.any? { |addrinfo| addrinfo.ipv6? && !addrinfo.ipv6_loopback? }
-
- @rs.shutdown
- begin
- @rs = Rinda::RingServer.new(@ts, [['ff02::1', '::1', 0]], @port)
- rescue Errno::EADDRNOTAVAIL
- return # IPv6 address for multicast not available
- end
-
- v6mc = @rs.instance_variable_get('@sockets').first
-
- if Socket.const_defined?(:SO_REUSEPORT) then
- assert v6mc.getsockopt(:SOCKET, :SO_REUSEPORT).bool
- else
- assert v6mc.getsockopt(:SOCKET, :SO_REUSEADDR).bool
- end
-
- assert_equal('::1', v6mc.local_address.ip_address)
- assert_equal(@port, v6mc.local_address.ip_port)
- end
-
- def test_shutdown
- @rs.shutdown
-
- assert_nil(@rs.do_reply, 'otherwise should hang forever')
- end
-
- private
-
- def with_timeout(n)
- aoe = Thread.abort_on_exception
- Thread.abort_on_exception = true
- tl0 = Thread.list
- tl = nil
- th = Thread.new(Thread.current) do |mth|
- sleep n
- (tl = Thread.list - tl0).each {|t|t.raise(Timeout::Error)}
- mth.raise(Timeout::Error)
- end
- tl0 << th
- yield
- rescue Timeout::Error => e
- $stderr.puts "TestRingServer#with_timeout: timeout in #{n}s:"
- $stderr.puts caller
- if tl
- bt = e.backtrace
- tl.each do |t|
- begin
- t.value
- rescue Timeout::Error => e
- bt.unshift("")
- bt[0, 0] = e.backtrace
- end
- end
- end
- raise Timeout::Error, "timeout", bt
- ensure
- if th
- th.kill
- th.join
- end
- Thread.abort_on_exception = aoe
- end
-
- def wait_for(n)
- t = n + Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
- until yield
- if t < Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
- flunk "timeout during waiting call"
- end
- sleep 0.1
- end
- end
-end
-
-class TestRingFinger < Test::Unit::TestCase
- include RingIPv6
- include RingIPv4
-
- def setup
- @rf = Rinda::RingFinger.new
- end
-
- def test_make_socket_unicast
- v4 = @rf.make_socket('127.0.0.1')
-
- assert(v4.getsockopt(:SOL_SOCKET, :SO_BROADCAST).bool)
- rescue TypeError
- if /aix/ =~ RUBY_PLATFORM
- omit "Known bug in getsockopt(2) on AIX"
- end
- raise $!
- ensure
- v4.close if v4
- end
-
- def test_make_socket_ipv4_multicast
- ipv4_mc(@rf) do |v4mc|
- assert_equal(1, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_LOOP).ipv4_multicast_loop)
- assert_equal(1, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL).ipv4_multicast_ttl)
- end
- end
-
- def test_make_socket_ipv6_multicast
- ipv6_mc(@rf) do |v6mc|
- assert_equal(1, v6mc.getsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_LOOP).int)
- assert_equal(1, v6mc.getsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_HOPS).int)
- end
- end
-
- def test_make_socket_ipv4_multicast_hops
- @rf.multicast_hops = 2
- ipv4_mc(@rf) do |v4mc|
- assert_equal(2, v4mc.getsockopt(:IPPROTO_IP, :IP_MULTICAST_TTL).ipv4_multicast_ttl)
- end
- end
-
- def test_make_socket_ipv6_multicast_hops
- ipv6_mc(@rf, 2) do |v6mc|
- assert_equal(2, v6mc.getsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_HOPS).int)
- end
- end
-
-end
-
-end
diff --git a/test/rinda/test_tuplebag.rb b/test/rinda/test_tuplebag.rb
deleted file mode 100644
index ab17ca047c..0000000000
--- a/test/rinda/test_tuplebag.rb
+++ /dev/null
@@ -1,173 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'rinda/tuplespace'
-
-class TestTupleBag < Test::Unit::TestCase
-
- def setup
- @tb = Rinda::TupleBag.new
- end
-
- def test_delete
- assert_nothing_raised do
- val = @tb.delete tup(:val, 1)
- assert_equal nil, val
- end
-
- t = tup(:val, 1)
- @tb.push t
-
- val = @tb.delete t
-
- assert_equal t, val
-
- assert_equal [], @tb.find_all(tem(:val, 1))
-
- t1 = tup(:val, 1)
- t2 = tup(:val, 1)
- @tb.push t1
- @tb.push t2
-
- val = @tb.delete t1
-
- assert_equal t1, val
-
- assert_equal [t2], @tb.find_all(tem(:val, 1))
- end
-
- def test_delete_unless_alive
- assert_equal [], @tb.delete_unless_alive
-
- t1 = tup(:val, nil)
- t2 = tup(:val, nil)
-
- @tb.push t1
- @tb.push t2
-
- assert_equal [], @tb.delete_unless_alive
-
- t1.cancel
-
- assert_equal [t1], @tb.delete_unless_alive, 'canceled'
-
- t2.renew Object.new
-
- assert_equal [t2], @tb.delete_unless_alive, 'expired'
- end
-
- def test_find
- template = tem(:val, nil)
-
- assert_equal nil, @tb.find(template)
-
- t1 = tup(:other, 1)
- @tb.push t1
-
- assert_equal nil, @tb.find(template)
-
- t2 = tup(:val, 1)
- @tb.push t2
-
- assert_equal t2, @tb.find(template)
-
- t2.cancel
-
- assert_equal nil, @tb.find(template), 'canceled'
-
- t3 = tup(:val, 3)
- @tb.push t3
-
- assert_equal t3, @tb.find(template)
-
- t3.renew Object.new
-
- assert_equal nil, @tb.find(template), 'expired'
- end
-
- def test_find_all
- template = tem(:val, nil)
-
- t1 = tup(:other, 1)
- @tb.push t1
-
- assert_equal [], @tb.find_all(template)
-
- t2 = tup(:val, 2)
- t3 = tup(:val, 3)
-
- @tb.push t2
- @tb.push t3
-
- assert_equal [t2, t3], @tb.find_all(template)
-
- t2.cancel
-
- assert_equal [t3], @tb.find_all(template), 'canceled'
-
- t3.renew Object.new
-
- assert_equal [], @tb.find_all(template), 'expired'
- end
-
- def test_find_all_template
- tuple = tup(:val, 1)
-
- t1 = tem(:other, nil)
- @tb.push t1
-
- assert_equal [], @tb.find_all_template(tuple)
-
- t2 = tem(:val, nil)
- t3 = tem(:val, nil)
-
- @tb.push t2
- @tb.push t3
-
- assert_equal [t2, t3], @tb.find_all_template(tuple)
-
- t2.cancel
-
- assert_equal [t3], @tb.find_all_template(tuple), 'canceled'
-
- t3.renew Object.new
-
- assert_equal [], @tb.find_all_template(tuple), 'expired'
- end
-
- def test_has_expires_eh
- assert !@tb.has_expires?
-
- t = tup(:val, 1)
- @tb.push t
-
- assert @tb.has_expires?
-
- t.renew Object.new
-
- assert !@tb.has_expires?
- end
-
- def test_push
- t = tup(:val, 1)
-
- @tb.push t
-
- assert_equal t, @tb.find(tem(:val, 1))
- end
-
- ##
- # Create a tuple with +ary+ for its contents
-
- def tup(*ary)
- Rinda::TupleEntry.new ary
- end
-
- ##
- # Create a template with +ary+ for its contents
-
- def tem(*ary)
- Rinda::TemplateEntry.new ary
- end
-
-end
-
diff --git a/test/ripper/assert_parse_files.rb b/test/ripper/assert_parse_files.rb
index 85d20cf69e..0d583a99e3 100644
--- a/test/ripper/assert_parse_files.rb
+++ b/test/ripper/assert_parse_files.rb
@@ -5,26 +5,39 @@ module TestRipper; end
class TestRipper::Generic < Test::Unit::TestCase
SRCDIR = File.expand_path("../../..", __FILE__)
- def assert_parse_files(dir, pattern = "**/*.rb")
- assert_separately(%W[--disable-gem -rripper - #{SRCDIR}/#{dir} #{pattern}],
+ def assert_parse_files(dir, pattern = "**/*.rb", exclude: nil, gc_stress: GC.stress, test_ratio: nil)
+ test_ratio ||= ENV["TEST_RIPPER_RATIO"]&.tap {|s|break s.to_f} || 0.05 # testing all files needs too long time...
+ assert_separately(%W[-rripper - #{SRCDIR}/#{dir} #{pattern}],
__FILE__, __LINE__, "#{<<-"begin;"}\n#{<<-'end;'}", timeout: Float::INFINITY)
+ GC.stress = false
pattern = "#{pattern}"
+ exclude = (
+ #{exclude if exclude}
+ )
+ test_ratio = (
+ #{test_ratio}
+ )
+ gc_stress = (
+ #{gc_stress}
+ )
begin;
- TEST_RATIO = ENV["TEST_RIPPER_RATIO"]&.tap {|s|break s.to_f} || 0.05 # testing all files needs too long time...
class Parser < Ripper
PARSER_EVENTS.each {|n| eval "def on_#{n}(*args) r = [:#{n}, *args]; r.inspect; Object.new end" }
SCANNER_EVENTS.each {|n| eval "def on_#{n}(*args) r = [:#{n}, *args]; r.inspect; Object.new end" }
end
dir = ARGV.shift
- scripts = Dir.chdir(dir) {Dir[pattern]}
- if (1...scripts.size).include?(num = scripts.size * TEST_RATIO)
+ scripts = Dir.glob(pattern, base: dir)
+ scripts.reject! {|script| File.fnmatch?(exclude, script, File::FNM_PATHNAME)} if exclude
+ if (1...scripts.size).include?(num = scripts.size * test_ratio)
scripts = scripts.sample(num)
end
scripts.sort!
for script in scripts
assert_nothing_raised {
parser = Parser.new(File.read("#{dir}/#{script}"), script)
- parser.instance_eval "parse", "<#{script}>"
+ EnvUtil.under_gc_stress(gc_stress) do
+ parser.instance_eval "parse", "<#{script}>"
+ end
}
end
end;
diff --git a/test/ripper/dummyparser.rb b/test/ripper/dummyparser.rb
index fa834bd0f7..ef5ea49b1f 100644
--- a/test/ripper/dummyparser.rb
+++ b/test/ripper/dummyparser.rb
@@ -4,8 +4,9 @@
#
require 'ripper'
+module TestRipper; end
-class Node
+class TestRipper::Node
def initialize(name, *nodes)
@name = name
@children = nodes
@@ -14,7 +15,7 @@ class Node
attr_reader :name, :children
def to_s
- "#{@name}(#{Node.trim_nil(@children).map {|n| n.to_s }.join(',')})"
+ "#{@name}(#{TestRipper::Node.trim_nil(@children).map {|n| n.to_s }.join(',')})"
end
def self.trim_nil(list)
@@ -36,7 +37,7 @@ class Node
end
end
-class NodeList
+class TestRipper::NodeList
def initialize(list = [])
@list = list
end
@@ -62,7 +63,7 @@ class NodeList
end
end
-class DummyParser < Ripper
+class TestRipper::DummyParser < Ripper
def hook(*names)
class << self; self; end.class_eval do
names.each do |name|
@@ -81,7 +82,7 @@ class DummyParser < Ripper
end
def on_stmts_new
- NodeList.new
+ TestRipper::NodeList.new
end
def on_stmts_add(stmts, st)
@@ -90,23 +91,23 @@ class DummyParser < Ripper
end
def on_void_stmt
- Node.new('void')
+ TestRipper::Node.new('void')
end
def on_var_ref(name)
- Node.new('ref', name)
+ TestRipper::Node.new('ref', name)
end
def on_var_alias(a, b)
- Node.new('valias', a, b)
+ TestRipper::Node.new('valias', a, b)
end
def on_assign_error(mesg = nil, a)
- Node.new('assign_error', a)
+ TestRipper::Node.new('assign_error', a)
end
def on_alias_error(mesg = nil, a)
- Node.new('aliaserr', a)
+ TestRipper::Node.new('aliaserr', a)
end
def on_arg_paren(args)
@@ -114,7 +115,7 @@ class DummyParser < Ripper
end
def on_args_new
- NodeList.new
+ TestRipper::NodeList.new
end
def on_args_add(list, arg)
@@ -156,7 +157,7 @@ class DummyParser < Ripper
end
def on_brace_block(params, code)
- Node.new('block', params, code)
+ TestRipper::Node.new('block', params, code)
end
def on_block_var(params, shadow)
@@ -176,7 +177,7 @@ class DummyParser < Ripper
end
def on_params(required, optional, rest, more, keyword, keyword_rest, block)
- args = NodeList.new
+ args = TestRipper::NodeList.new
required.each do |req|
args.push(req)
@@ -197,15 +198,15 @@ class DummyParser < Ripper
end
def on_assoc_new(a, b)
- Node.new('assoc', a, b)
+ TestRipper::Node.new('assoc', a, b)
end
def on_bare_assoc_hash(assoc_list)
- Node.new('assocs', *assoc_list)
+ TestRipper::Node.new('assocs', *assoc_list)
end
def on_assoclist_from_args(a)
- Node.new('assocs', *a)
+ TestRipper::Node.new('assocs', *a)
end
def on_word_new
@@ -217,7 +218,7 @@ class DummyParser < Ripper
end
def on_words_new
- NodeList.new
+ TestRipper::NodeList.new
end
def on_words_add(words, word)
@@ -225,7 +226,7 @@ class DummyParser < Ripper
end
def on_qwords_new
- NodeList.new
+ TestRipper::NodeList.new
end
def on_qwords_add(words, word)
@@ -233,27 +234,27 @@ class DummyParser < Ripper
end
def on_symbols_new
- NodeList.new
+ TestRipper::NodeList.new
end
def on_symbols_add(symbols, symbol)
- symbols.push Node::Sym.new(symbol)
+ symbols.push TestRipper::Node::Sym.new(symbol)
end
def on_qsymbols_new
- NodeList.new
+ TestRipper::NodeList.new
end
def on_qsymbols_add(symbols, symbol)
- symbols.push Node::Sym.new(symbol)
+ symbols.push TestRipper::Node::Sym.new(symbol)
end
def on_mlhs_new
- NodeList.new
+ TestRipper::NodeList.new
end
def on_mlhs_paren(list)
- Node.new(:mlhs, list)
+ TestRipper::Node.new(:mlhs, list)
end
def on_mlhs_add(list, node)
@@ -277,12 +278,12 @@ class DummyParser < Ripper
end
def on_rescue(exc, *rest)
- Node.new('rescue', (exc && NodeList.new(exc)), *rest)
+ TestRipper::Node.new('rescue', (exc && TestRipper::NodeList.new(exc)), *rest)
end
(Ripper::PARSER_EVENTS.map(&:to_s) - instance_methods(false).map {|n|n.to_s.sub(/^on_/, '')}).each do |event|
define_method(:"on_#{event}") do |*args|
- Node.new(event, *args)
+ TestRipper::Node.new(event, *args)
end
end
end
diff --git a/test/ripper/test_lexer.rb b/test/ripper/test_lexer.rb
index 4f3f4657ef..7d62a7ee28 100644
--- a/test/ripper/test_lexer.rb
+++ b/test/ripper/test_lexer.rb
@@ -171,7 +171,7 @@ class TestRipper::Lexer < Test::Unit::TestCase
end
BAD_CODE = [
- [:parse_error, 'def req(true) end', %r[unexpected `true'], 'true'],
+ [:parse_error, 'def req(true) end', %r[unexpected 'true'], 'true'],
[:parse_error, 'def req(a, a) end', %r[duplicated argument name], 'a'],
[:assign_error, 'begin; nil = 1; end', %r[assign to nil], 'nil'],
[:alias_error, 'begin; alias $x $1; end', %r[number variables], '$1'],
@@ -242,4 +242,96 @@ class TestRipper::Lexer < Test::Unit::TestCase
EOF
assert_equal([[5, 0], :on_heredoc_end, "EOS\n", state(:EXPR_BEG)], Ripper.lex(s).last, bug)
end
+
+ def test_tokenize_with_here_document
+ bug = '[Bug #18963]'
+ code = %[
+<<A + "hello
+A
+world"
+]
+ assert_equal(code, Ripper.tokenize(code).join(""), bug)
+ end
+
+ def test_heredoc_inside_block_param
+ bug = '[Bug #19399]'
+ code = <<~CODE
+ a do |b
+ <<-C
+ C
+ |
+ end
+ CODE
+ assert_equal(code, Ripper.tokenize(code).join(""), bug)
+ end
+
+ def test_heredoc_unterminated_interpolation
+ code = <<~'HEREDOC'
+ <<A+1
+ #{
+ HEREDOC
+
+ assert_include(Ripper.tokenize(code).join(""), "+1")
+ end
+
+ def test_nested_heredoc
+ code = <<~'HEREDOC'
+ <<~H1
+ 1
+ #{<<~H2}
+ 2
+ H2
+ 3
+ H1
+ HEREDOC
+
+ expected = [
+ [[1, 0], :on_heredoc_beg, "<<~H1", state(:EXPR_BEG)],
+ [[1, 5], :on_nl, "\n", state(:EXPR_BEG)],
+ [[2, 0], :on_ignored_sp, " ", state(:EXPR_BEG)],
+ [[2, 2], :on_tstring_content, "1\n", state(:EXPR_BEG)],
+ [[3, 0], :on_ignored_sp, " ", state(:EXPR_BEG)],
+ [[3, 2], :on_embexpr_beg, "\#{", state(:EXPR_BEG)],
+ [[3, 4], :on_heredoc_beg, "<<~H2", state(:EXPR_BEG)],
+ [[3, 9], :on_embexpr_end, "}", state(:EXPR_END)],
+ [[3, 10], :on_tstring_content, "\n", state(:EXPR_BEG)],
+ [[4, 0], :on_ignored_sp, " ", state(:EXPR_BEG)],
+ [[4, 4], :on_tstring_content, "2\n", state(:EXPR_BEG)],
+ [[5, 0], :on_heredoc_end, " H2\n", state(:EXPR_BEG)],
+ [[6, 0], :on_ignored_sp, " ", state(:EXPR_BEG)],
+ [[6, 2], :on_tstring_content, "3\n", state(:EXPR_BEG)],
+ [[7, 0], :on_heredoc_end, "H1\n", state(:EXPR_BEG)],
+ ]
+ assert_equal(code, Ripper.tokenize(code).join(""))
+ assert_equal(expected, result = Ripper.lex(code),
+ proc {expected.zip(result) {|e, r| break diff(e, r) unless e == r}})
+
+ code = <<~'HEREDOC'
+ <<-H1
+ 1
+ #{<<~H2}
+ 2
+ H2
+ 3
+ H1
+ HEREDOC
+
+ expected = [
+ [[1, 0], :on_heredoc_beg, "<<-H1", state(:EXPR_BEG)],
+ [[1, 5], :on_nl, "\n", state(:EXPR_BEG)],
+ [[2, 0], :on_tstring_content, " 1\n ", state(:EXPR_BEG)],
+ [[3, 2], :on_embexpr_beg, "\#{", state(:EXPR_BEG)],
+ [[3, 4], :on_heredoc_beg, "<<~H2", state(:EXPR_BEG)],
+ [[3, 9], :on_embexpr_end, "}", state(:EXPR_END)],
+ [[3, 10], :on_tstring_content, "\n", state(:EXPR_BEG)],
+ [[4, 0], :on_ignored_sp, " ", state(:EXPR_BEG)],
+ [[4, 4], :on_tstring_content, "2\n", state(:EXPR_BEG)],
+ [[5, 0], :on_heredoc_end, " H2\n", state(:EXPR_BEG)],
+ [[6, 0], :on_tstring_content, " 3\n", state(:EXPR_BEG)],
+ [[7, 0], :on_heredoc_end, "H1\n", state(:EXPR_BEG)],
+ ]
+ assert_equal(code, Ripper.tokenize(code).join(""))
+ assert_equal(expected, result = Ripper.lex(code),
+ proc {expected.zip(result) {|e, r| break diff(e, r) unless e == r}})
+ end
end
diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb
index 1ea8d23378..cbae6e7ed5 100644
--- a/test/ripper/test_parser_events.rb
+++ b/test/ripper/test_parser_events.rb
@@ -16,7 +16,7 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
end
def parse(str, nm = nil, &bl)
- dp = DummyParser.new(str)
+ dp = TestRipper::DummyParser.new(str)
dp.hook(*nm, &bl) if nm
dp.parse.to_s
end
@@ -152,6 +152,7 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
thru_args_forward = false
parse(code, :on_args_forward) {thru_args_forward = true}
assert_equal true, thru_args_forward, "no args_forward for: #{code}"
+ parse(code, :on_params) {|*, block| assert_nil(block)}
end
end
@@ -499,6 +500,23 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
assert_equal "[call(ref(self),&.,foo,[])]", tree
end
+ def test_call_colon2
+ hook = Module.new do
+ def on_op(op)
+ super("(op: #{op.inspect})")
+ end
+ def on_call(recv, name, *args)
+ super(recv, "(method: #{name})", *args)
+ end
+ def on_ident(name)
+ super("(ident: #{name.inspect})")
+ end
+ end
+
+ parser = TestRipper::DummyParser.new("a::b").extend(hook)
+ assert_equal '[call(vcall((ident: "a")),(method: (op: "::")),(ident: "b"))]', parser.parse.to_s
+ end
+
def test_excessed_comma
thru_excessed_comma = false
parse("proc{|x,|}", :on_excessed_comma) {thru_excessed_comma = true}
@@ -1626,20 +1644,20 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
end
def test_invalid_instance_variable_name
- assert_equal("`@1' is not allowed as an instance variable name", compile_error('proc{@1}'))
- assert_equal("`@' without identifiers is not allowed as an instance variable name", compile_error('@%'))
- assert_equal("`@' without identifiers is not allowed as an instance variable name", compile_error('@'))
+ assert_equal("'@1' is not allowed as an instance variable name", compile_error('proc{@1}'))
+ assert_equal("'@' without identifiers is not allowed as an instance variable name", compile_error('@%'))
+ assert_equal("'@' without identifiers is not allowed as an instance variable name", compile_error('@'))
end
def test_invalid_class_variable_name
- assert_equal("`@@1' is not allowed as a class variable name", compile_error('@@1'))
- assert_equal("`@@' without identifiers is not allowed as a class variable name", compile_error('@@%'))
- assert_equal("`@@' without identifiers is not allowed as a class variable name", compile_error('@@'))
+ assert_equal("'@@1' is not allowed as a class variable name", compile_error('@@1'))
+ assert_equal("'@@' without identifiers is not allowed as a class variable name", compile_error('@@%'))
+ assert_equal("'@@' without identifiers is not allowed as a class variable name", compile_error('@@'))
end
def test_invalid_global_variable_name
- assert_equal("`$%' is not allowed as a global variable name", compile_error('$%'))
- assert_equal("`$' without identifiers is not allowed as a global variable name", compile_error('$'))
+ assert_equal("'$%' is not allowed as a global variable name", compile_error('$%'))
+ assert_equal("'$' without identifiers is not allowed as a global variable name", compile_error('$'))
end
def test_warning_ignored_magic_comment
@@ -1654,6 +1672,26 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
assert_equal(%w"frozen_string_literal nottrue", args)
end
+ def test_warning_duplicated_when_clause
+ fmt, *args = warning(<<~STR)
+ a = 1
+ case a
+ when 1
+ when 1
+ when 2
+ else
+ end
+ STR
+ assert_match(/duplicated 'when' clause/, fmt)
+ assert_equal([3], args)
+ end
+
+ def test_warn_duplicated_hash_keys
+ fmt, *args = warn("{ a: 1, a: 2 }")
+ assert_match(/is duplicated and overwritten on line/, fmt)
+ assert_equal([:a, 1], args)
+ end
+
def test_warn_cr_in_middle
fmt = nil
assert_warn("") {fmt, = warn("\r;")}
diff --git a/test/ripper/test_ripper.rb b/test/ripper/test_ripper.rb
index 76276c54ef..6061496d9c 100644
--- a/test/ripper/test_ripper.rb
+++ b/test/ripper/test_ripper.rb
@@ -14,6 +14,13 @@ class TestRipper::Ripper < Test::Unit::TestCase
@ripper = Ripper.new '1 + 1'
end
+ def test_new
+ assert_separately(%w[-rripper], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_nil EnvUtil.under_gc_stress {Ripper.new("")}.state
+ end;
+ end
+
def test_column
assert_nil @ripper.column
end
@@ -81,7 +88,7 @@ class TestRipper::Ripper < Test::Unit::TestCase
ripper.yydebug = true
ripper.debug_output = out
ripper.parse
- assert_include out.string[/.*"literal content".*/], 'woot'
+ assert_include out.string[/.*"literal content".*/], '1.1-1.5'
end
def test_regexp_with_option
@@ -141,6 +148,28 @@ end
assert_nothing_raised { Ripper.lex src }
end
+ def test_no_memory_leak
+ assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
+ 2_000_000.times do
+ Ripper.parse("")
+ end
+ end;
+
+ # [Bug #19835]
+ assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
+ 1_000_000.times do
+ Ripper.parse("class Foo")
+ end
+ end;
+
+ # [Bug #19836]
+ assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
+ 1_000_000.times do
+ Ripper.parse("-> {")
+ end
+ end;
+ end
+
class TestInput < self
Input = Struct.new(:lines) do
def gets
diff --git a/test/ripper/test_scanner_events.rb b/test/ripper/test_scanner_events.rb
index 13bd44e83d..792f19ef1a 100644
--- a/test/ripper/test_scanner_events.rb
+++ b/test/ripper/test_scanner_events.rb
@@ -113,11 +113,11 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
[[5, 0], :on_imaginary, "5.6ri", Ripper::EXPR_END],
],
Ripper.lex("1r\n2i\n3ri\n4.2r\n5.6ri")
- assert_lex [[[1, 0], :on_heredoc_beg, "<<~EOS", Ripper::EXPR_BEG],
- [[1, 6], :on_nl, "\n", Ripper::EXPR_BEG],
- [[2, 0], :on_ignored_sp, " ", Ripper::EXPR_BEG],
- [[2, 2], :on_tstring_content, "heredoc\n", Ripper::EXPR_BEG],
- [[3, 0], :on_heredoc_end, "EOS", Ripper::EXPR_BEG]
+ assert_lex [[[1, 0], :on_heredoc_beg, "<<~EOS", Ripper::EXPR_BEG],
+ [[1, 6], :on_nl, "\n", Ripper::EXPR_BEG],
+ [[2, 0], :on_ignored_sp, " ", Ripper::EXPR_BEG],
+ [[2, 2], :on_tstring_content, "heredoc\n", Ripper::EXPR_BEG],
+ [[3, 0], :on_heredoc_end, "EOS", Ripper::EXPR_BEG]
],
Ripper.lex("<<~EOS\n heredoc\nEOS")
assert_lex [[[1, 0], :on_tstring_beg, "'", Ripper::EXPR_BEG],
@@ -179,6 +179,11 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
scan('backtick', %q[p `make all`])
end
+ def test_colon2_call
+ assert_equal ["::"],
+ scan('op', %q[ a::b ])
+ end
+
def test_comma
assert_equal [','] * 6,
scan('comma', %q[ m(0,1,2,3,4,5,6) ])
@@ -712,7 +717,7 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
scan('words_sep', '%w( w w w )')
assert_equal [' ', "\n", ' ', ' '],
scan('words_sep', "%w( w\nw w )")
- assert_equal ["\n\n", "\n ", ' ', ' '],
+ assert_equal ["\n", "\n", "\n", ' ', ' ', ' '],
scan('words_sep', "%w(\n\nw\n w w )")
end
@@ -986,13 +991,27 @@ class TestRipper::ScannerEvents < Test::Unit::TestCase
assert_equal("\e", err[2])
end
- def test_invalid_hex_escape
+ def test_invalid_escape
+ err = nil
+ assert_equal ["\\C-\u{3042}"], scan('tstring_content', %["\\C-\u{3042}"]) {|*e| err = e}
+ assert_equal [:on_parse_error, "Invalid escape character syntax", "\\C-\u{3042}"], err
+ end
+
+ def test_invalid_hex_escape_string
err = nil
- assert_equal ['U'], scan('tstring_content', '"\\xU"') {|*e| err = e}
+ assert_equal ['\\x', 'U'], scan('tstring_content', '"\\xU"') {|*e| err = e}
assert_equal [:on_parse_error, "invalid hex escape", "\\x"], err
+ end
+ def test_invalid_hex_escape_regexp
err = nil
- assert_equal ['U'], scan('tstring_content', '/\\xU/') {|*e| err = e}
+ assert_equal ['\\x', 'U'], scan('tstring_content', '/\\xU/') {|*e| err = e}
assert_equal [:on_parse_error, "invalid hex escape", "\\x"], err
end
+
+ def test_error_token
+ src = "{a:,aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n""hello}"
+ err = scan('parse_error', src) {|*e| break e}
+ assert_equal "", err[2]
+ end
end if ripper_test
diff --git a/test/ripper/test_sexp.rb b/test/ripper/test_sexp.rb
index 9faeaba782..3ebcf3062e 100644
--- a/test/ripper/test_sexp.rb
+++ b/test/ripper/test_sexp.rb
@@ -18,6 +18,11 @@ class TestRipper::Sexp < Test::Unit::TestCase
assert_nil Ripper.sexp("/*")
assert_nil Ripper.sexp("/*/")
assert_nil Ripper.sexp("/+/")
+ assert_nil Ripper.sexp("m(&nil) {}"), '[Bug #10436]'
+ assert_nil Ripper.sexp("/(?<a>)/ =~ ''; x = a **a, **a if false"), '[Bug #18988]'
+ assert_nil Ripper.sexp("return + return"), '[Bug #20055]'
+ assert_nil Ripper.sexp("1 in [a, a]"), '[Bug #20055]'
+ assert_nil Ripper.sexp("1 + (1 => [a, a])"), '[Bug #20055]'
end
def test_regexp_content
@@ -34,6 +39,14 @@ class TestRipper::Sexp < Test::Unit::TestCase
assert_equal '(?<n>a(b|\g<n>))', search_sexp(:@tstring_content, search_sexp(:regexp_literal, sexp))[1]
end
+ def test_regexp_named_capture
+ sexp = Ripper.sexp("/(?<a>)/ =~ ''; x = a **a, a if false")
+ assert_not_nil sexp, '[Bug #18988]'
+
+ sexp = Ripper.sexp("/(?<a>)/ =~ ''; a %(exit)")
+ assert_equal 'exit', search_sexp(:@ident, search_sexp(:paren, sexp))[1], '[Bug #18988]'
+ end
+
def test_heredoc_content
sexp = Ripper.sexp("<<E\nfoo\nE")
assert_equal "foo\n", search_sexp(:@tstring_content, sexp)[1]
@@ -110,6 +123,21 @@ eot
assert_equal(exp, named)
end
+ def test_command
+ sexp = Ripper.sexp("a::C {}")
+ assert_equal(
+ [:program,
+ [
+ [:method_add_block,
+ [:command_call,
+ [:vcall, [:@ident, "a", [1, 0]]],
+ [:@op, "::", [1, 1]],
+ [:@const, "C", [1, 3]],
+ nil],
+ [:brace_block, nil, [[:void_stmt]]]]]],
+ sexp)
+ end
+
def search_sexp(sym, sexp)
return sexp if !sexp or sexp[0] == sym
sexp.find do |e|
@@ -175,7 +203,7 @@ eot
[:aryptn,
nil,
[[:var_field, [:@ident, "a", [1, 11]]]],
- [:var_field, nil],
+ nil,
nil],
[[:void_stmt]],
nil]],
@@ -407,6 +435,14 @@ eot
[[:void_stmt]],
nil]],
+ [__LINE__, %q{ case 0; in [a,]; end }] =>
+ [:case,
+ [:@int, "0", [1, 5]],
+ [:in,
+ [:aryptn, nil, [[:var_field, [:@ident, "a", [1, 12]]]], nil, nil],
+ [[:void_stmt]],
+ nil]],
+
[__LINE__, %q{ case 0; in []; end }] =>
[:case,
[:@int, "0", [1, 5]],
@@ -486,6 +522,22 @@ eot
[:begin, [:binary, [:@int, "0", [1, 13]], :+, [:@int, "0", [1, 15]]]],
[[:void_stmt]],
nil]],
+
+ [__LINE__, %q{ case 0; in [*a]; a; end } ] =>
+ [:case,
+ [:@int, "0", [1, 5]],
+ [:in,
+ [:aryptn, nil, nil, [:var_field, [:@ident, "a", [1, 13]]], nil],
+ [[:var_ref, [:@ident, "a", [1, 17]]]],
+ nil]],
+
+ [__LINE__, %q{ case 0; in {a:}; a; end } ] =>
+ [:case,
+ [:@int, "0", [1, 5]],
+ [:in,
+ [:hshptn, nil, [[[:@label, "a:", [1, 12]], nil]], nil],
+ [[:var_ref, [:@ident, "a", [1, 17]]]],
+ nil]],
}
pattern_matching_data.each do |(i, src), expected|
define_method(:"test_pattern_matching_#{i}") do
diff --git a/test/ruby/enc/test_case_comprehensive.rb b/test/ruby/enc/test_case_comprehensive.rb
index bc57d57ee4..de18ac865c 100644
--- a/test/ruby/enc/test_case_comprehensive.rb
+++ b/test/ruby/enc/test_case_comprehensive.rb
@@ -37,7 +37,7 @@ TestComprehensiveCaseMapping.data_files_available? and class TestComprehensiveC
end
def self.read_data_file(filename)
- IO.foreach(expand_filename(filename), encoding: Encoding::ASCII_8BIT) do |line|
+ File.foreach(expand_filename(filename), encoding: Encoding::ASCII_8BIT) do |line|
if $. == 1
if filename == 'UnicodeData'
elsif line.start_with?("# #{filename}-#{UNICODE_VERSION}.txt")
diff --git a/test/ruby/enc/test_case_mapping.rb b/test/ruby/enc/test_case_mapping.rb
index 31acdc4331..a7d1ed0d16 100644
--- a/test/ruby/enc/test_case_mapping.rb
+++ b/test/ruby/enc/test_case_mapping.rb
@@ -47,7 +47,7 @@ class TestCaseMappingPreliminary < Test::Unit::TestCase
# different properties; careful: roundtrip isn't always guaranteed
def check_swapcase_properties(expected, start, *flags)
assert_equal expected, start.swapcase(*flags)
- temp = start
+ temp = +start
assert_equal expected, temp.swapcase!(*flags)
assert_equal start, start.swapcase(*flags).swapcase(*flags)
assert_equal expected, expected.swapcase(*flags).swapcase(*flags)
@@ -61,10 +61,10 @@ class TestCaseMappingPreliminary < Test::Unit::TestCase
end
def test_invalid
- assert_raise(ArgumentError, "Should not be possible to upcase invalid string.") { "\xEB".force_encoding('UTF-8').upcase }
- assert_raise(ArgumentError, "Should not be possible to downcase invalid string.") { "\xEB".force_encoding('UTF-8').downcase }
- assert_raise(ArgumentError, "Should not be possible to capitalize invalid string.") { "\xEB".force_encoding('UTF-8').capitalize }
- assert_raise(ArgumentError, "Should not be possible to swapcase invalid string.") { "\xEB".force_encoding('UTF-8').swapcase }
+ assert_raise(ArgumentError, "Should not be possible to upcase invalid string.") { "\xEB".dup.force_encoding('UTF-8').upcase }
+ assert_raise(ArgumentError, "Should not be possible to downcase invalid string.") { "\xEB".dup.force_encoding('UTF-8').downcase }
+ assert_raise(ArgumentError, "Should not be possible to capitalize invalid string.") { "\xEB".dup.force_encoding('UTF-8').capitalize }
+ assert_raise(ArgumentError, "Should not be possible to swapcase invalid string.") { "\xEB".dup.force_encoding('UTF-8').swapcase }
end
def test_general
diff --git a/test/ruby/enc/test_case_options.rb b/test/ruby/enc/test_case_options.rb
index e9bf50fcfc..e9c81d804e 100644
--- a/test/ruby/enc/test_case_options.rb
+++ b/test/ruby/enc/test_case_options.rb
@@ -19,7 +19,7 @@ class TestCaseOptions < Test::Unit::TestCase
def assert_raise_both_types(*options)
assert_raise_functional_operations 'a', *options
- assert_raise_bang_operations 'a', *options
+ assert_raise_bang_operations(+'a', *options)
assert_raise_functional_operations :a, *options
end
@@ -51,7 +51,7 @@ class TestCaseOptions < Test::Unit::TestCase
def assert_okay_both_types(*options)
assert_okay_functional_operations 'a', *options
- assert_okay_bang_operations 'a', *options
+ assert_okay_bang_operations(+'a', *options)
assert_okay_functional_operations :a, *options
end
@@ -69,10 +69,10 @@ class TestCaseOptions < Test::Unit::TestCase
assert_raise(ArgumentError) { 'a'.upcase :fold }
assert_raise(ArgumentError) { 'a'.capitalize :fold }
assert_raise(ArgumentError) { 'a'.swapcase :fold }
- assert_nothing_raised { 'a'.downcase! :fold }
- assert_raise(ArgumentError) { 'a'.upcase! :fold }
- assert_raise(ArgumentError) { 'a'.capitalize! :fold }
- assert_raise(ArgumentError) { 'a'.swapcase! :fold }
+ assert_nothing_raised { 'a'.dup.downcase! :fold }
+ assert_raise(ArgumentError) { 'a'.dup.upcase! :fold }
+ assert_raise(ArgumentError) { 'a'.dup.capitalize! :fold }
+ assert_raise(ArgumentError) { 'a'.dup.swapcase! :fold }
assert_nothing_raised { :a.downcase :fold }
assert_raise(ArgumentError) { :a.upcase :fold }
assert_raise(ArgumentError) { :a.capitalize :fold }
diff --git a/test/ruby/enc/test_cesu8.rb b/test/ruby/enc/test_cesu8.rb
index d9debe76cd..68a08389ea 100644
--- a/test/ruby/enc/test_cesu8.rb
+++ b/test/ruby/enc/test_cesu8.rb
@@ -106,4 +106,8 @@ EOT
assert_equal chr, ord.chr("cesu-8")
end
end
+
+ def test_cesu8_left_adjust_char_head
+ assert_equal("", "\u{10000}".encode("cesu-8").chop)
+ end
end
diff --git a/test/ruby/enc/test_emoji_breaks.rb b/test/ruby/enc/test_emoji_breaks.rb
index c96d6088f5..bb5114680e 100644
--- a/test/ruby/enc/test_emoji_breaks.rb
+++ b/test/ruby/enc/test_emoji_breaks.rb
@@ -75,7 +75,7 @@ class TestEmojiBreaks < Test::Unit::TestCase
EMOJI_DATA_FILES.each do |file|
version_mismatch = true
file_tests = []
- IO.foreach(file.fullname, encoding: Encoding::UTF_8) do |line|
+ File.foreach(file.fullname, encoding: Encoding::UTF_8) do |line|
line.chomp!
if $.==1
if line=="# #{file.basename}-#{file.version}.txt"
@@ -84,7 +84,8 @@ class TestEmojiBreaks < Test::Unit::TestCase
raise "File Name Mismatch: line: #{line}, expected filename: #{file.basename}.txt"
end
end
- version_mismatch = false if line =~ /^# Version: #{file.version}/
+ version_mismatch = false if line =~ /^# Version: #{file.version}/ # 13.0 and older
+ version_mismatch = false if line =~ /^# Used with Emoji Version #{EMOJI_VERSION}/ # 14.0 and newer
next if line.match?(/\A(#|\z)/)
if line =~ /^(\h{4,6})\.\.(\h{4,6}) *(;.+)/ # deal with Unicode ranges in emoji-sequences.txt (Bug #18028)
range_start = $1.to_i(16)
diff --git a/test/ruby/enc/test_grapheme_breaks.rb b/test/ruby/enc/test_grapheme_breaks.rb
index f4e3c93b47..7e6d722d40 100644
--- a/test/ruby/enc/test_grapheme_breaks.rb
+++ b/test/ruby/enc/test_grapheme_breaks.rb
@@ -44,7 +44,7 @@ class TestGraphemeBreaksFromFile < Test::Unit::TestCase
if file_available?
def read_data
tests = []
- IO.foreach(GRAPHEME_BREAK_TEST_FILE, encoding: Encoding::UTF_8) do |line|
+ File.foreach(GRAPHEME_BREAK_TEST_FILE, encoding: Encoding::UTF_8) do |line|
if $. == 1 and not line.start_with?("# GraphemeBreakTest-#{UNICODE_VERSION}.txt")
raise "File Version Mismatch"
end
diff --git a/test/ruby/enc/test_regex_casefold.rb b/test/ruby/enc/test_regex_casefold.rb
index eaabbc58a2..b5d5c6e337 100644
--- a/test/ruby/enc/test_regex_casefold.rb
+++ b/test/ruby/enc/test_regex_casefold.rb
@@ -19,7 +19,7 @@ class TestCaseFold < Test::Unit::TestCase
end
def read_tests
- IO.readlines("#{UNICODE_DATA_PATH}/CaseFolding.txt", encoding: Encoding::ASCII_8BIT)
+ File.readlines("#{UNICODE_DATA_PATH}/CaseFolding.txt", encoding: Encoding::ASCII_8BIT)
.collect.with_index { |linedata, linenumber| [linenumber.to_i+1, linedata.chomp] }
.reject { |number, data| data =~ /^(#|$)/ }
.collect do |linenumber, linedata|
diff --git a/test/ruby/rjit/test_assembler.rb b/test/ruby/rjit/test_assembler.rb
new file mode 100644
index 0000000000..fbf780d6c3
--- /dev/null
+++ b/test/ruby/rjit/test_assembler.rb
@@ -0,0 +1,368 @@
+require 'test/unit'
+require_relative '../../lib/jit_support'
+
+return unless JITSupport.rjit_supported?
+return unless RubyVM::RJIT.enabled?
+return unless RubyVM::RJIT::C.HAVE_LIBCAPSTONE
+
+require 'stringio'
+require 'ruby_vm/rjit/assembler'
+
+module RubyVM::RJIT
+ class TestAssembler < Test::Unit::TestCase
+ MEM_SIZE = 16 * 1024
+
+ def setup
+ @mem_block ||= C.mmap(MEM_SIZE)
+ @cb = CodeBlock.new(mem_block: @mem_block, mem_size: MEM_SIZE)
+ end
+
+ def test_add
+ asm = Assembler.new
+ asm.add([:rcx], 1) # ADD r/m64, imm8 (Mod 00: [reg])
+ asm.add(:rax, 0x7f) # ADD r/m64, imm8 (Mod 11: reg)
+ asm.add(:rbx, 0x7fffffff) # ADD r/m64 imm32 (Mod 11: reg)
+ asm.add(:rsi, :rdi) # ADD r/m64, r64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: add qword ptr [rcx], 1
+ 0x4: add rax, 0x7f
+ 0x8: add rbx, 0x7fffffff
+ 0xf: add rsi, rdi
+ EOS
+ end
+
+ def test_and
+ asm = Assembler.new
+ asm.and(:rax, 0) # AND r/m64, imm8 (Mod 11: reg)
+ asm.and(:rbx, 0x7fffffff) # AND r/m64, imm32 (Mod 11: reg)
+ asm.and(:rcx, [:rdi, 8]) # AND r64, r/m64 (Mod 01: [reg]+disp8)
+ assert_compile(asm, <<~EOS)
+ 0x0: and rax, 0
+ 0x4: and rbx, 0x7fffffff
+ 0xb: and rcx, qword ptr [rdi + 8]
+ EOS
+ end
+
+ def test_call
+ asm = Assembler.new
+ asm.call(rel32(0xff)) # CALL rel32
+ asm.call(:rax) # CALL r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: call 0xff
+ 0x5: call rax
+ EOS
+ end
+
+ def test_cmove
+ asm = Assembler.new
+ asm.cmove(:rax, :rcx) # CMOVE r64, r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: cmove rax, rcx
+ EOS
+ end
+
+ def test_cmovg
+ asm = Assembler.new
+ asm.cmovg(:rbx, :rdi) # CMOVG r64, r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: cmovg rbx, rdi
+ EOS
+ end
+
+ def test_cmovge
+ asm = Assembler.new
+ asm.cmovge(:rsp, :rbp) # CMOVGE r64, r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: cmovge rsp, rbp
+ EOS
+ end
+
+ def test_cmovl
+ asm = Assembler.new
+ asm.cmovl(:rdx, :rsp) # CMOVL r64, r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: cmovl rdx, rsp
+ EOS
+ end
+
+ def test_cmovle
+ asm = Assembler.new
+ asm.cmovle(:rax, :rax) # CMOVLE r64, r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: cmovle rax, rax
+ EOS
+ end
+
+ def test_cmovne
+ asm = Assembler.new
+ asm.cmovne(:rax, :rbx) # CMOVNE r64, r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS) # cmovne == cmovnz
+ 0x0: cmovne rax, rbx
+ EOS
+ end
+
+ def test_cmovnz
+ asm = Assembler.new
+ asm.cmovnz(:rax, :rbx) # CMOVNZ r64, r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS) # cmovne == cmovnz
+ 0x0: cmovne rax, rbx
+ EOS
+ end
+
+ def test_cmovz
+ asm = Assembler.new
+ asm.cmovz(:rax, :rbx) # CMOVZ r64, r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS) # cmove == cmovz
+ 0x0: cmove rax, rbx
+ EOS
+ end
+
+ def test_cmp
+ asm = Assembler.new
+ asm.cmp(BytePtr[:rax, 8], 8) # CMP r/m8, imm8 (Mod 01: [reg]+disp8)
+ asm.cmp(DwordPtr[:rax, 8], 0x100) # CMP r/m32, imm32 (Mod 01: [reg]+disp8)
+ asm.cmp([:rax, 8], 8) # CMP r/m64, imm8 (Mod 01: [reg]+disp8)
+ asm.cmp([:rbx, 8], 0x100) # CMP r/m64, imm32 (Mod 01: [reg]+disp8)
+ asm.cmp([:rax, 0x100], 8) # CMP r/m64, imm8 (Mod 10: [reg]+disp32)
+ asm.cmp(:rax, 8) # CMP r/m64, imm8 (Mod 11: reg)
+ asm.cmp(:rax, 0x100) # CMP r/m64, imm32 (Mod 11: reg)
+ asm.cmp([:rax, 8], :rbx) # CMP r/m64, r64 (Mod 01: [reg]+disp8)
+ asm.cmp([:rax, -0x100], :rbx) # CMP r/m64, r64 (Mod 10: [reg]+disp32)
+ asm.cmp(:rax, :rbx) # CMP r/m64, r64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: cmp byte ptr [rax + 8], 8
+ 0x4: cmp dword ptr [rax + 8], 0x100
+ 0xb: cmp qword ptr [rax + 8], 8
+ 0x10: cmp qword ptr [rbx + 8], 0x100
+ 0x18: cmp qword ptr [rax + 0x100], 8
+ 0x20: cmp rax, 8
+ 0x24: cmp rax, 0x100
+ 0x2b: cmp qword ptr [rax + 8], rbx
+ 0x2f: cmp qword ptr [rax - 0x100], rbx
+ 0x36: cmp rax, rbx
+ EOS
+ end
+
+ def test_jbe
+ asm = Assembler.new
+ asm.jbe(rel32(0xff)) # JBE rel32
+ assert_compile(asm, <<~EOS)
+ 0x0: jbe 0xff
+ EOS
+ end
+
+ def test_je
+ asm = Assembler.new
+ asm.je(rel32(0xff)) # JE rel32
+ assert_compile(asm, <<~EOS)
+ 0x0: je 0xff
+ EOS
+ end
+
+ def test_jl
+ asm = Assembler.new
+ asm.jl(rel32(0xff)) # JL rel32
+ assert_compile(asm, <<~EOS)
+ 0x0: jl 0xff
+ EOS
+ end
+
+ def test_jmp
+ asm = Assembler.new
+ label = asm.new_label('label')
+ asm.jmp(label) # JZ rel8
+ asm.write_label(label)
+ asm.jmp(rel32(0xff)) # JMP rel32
+ asm.jmp([:rax, 8]) # JMP r/m64 (Mod 01: [reg]+disp8)
+ asm.jmp(:rax) # JMP r/m64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: jmp 2
+ 0x2: jmp 0xff
+ 0x7: jmp qword ptr [rax + 8]
+ 0xa: jmp rax
+ EOS
+ end
+
+ def test_jne
+ asm = Assembler.new
+ asm.jne(rel32(0xff)) # JNE rel32
+ assert_compile(asm, <<~EOS)
+ 0x0: jne 0xff
+ EOS
+ end
+
+ def test_jnz
+ asm = Assembler.new
+ asm.jnz(rel32(0xff)) # JNZ rel32
+ assert_compile(asm, <<~EOS)
+ 0x0: jne 0xff
+ EOS
+ end
+
+ def test_jo
+ asm = Assembler.new
+ asm.jo(rel32(0xff)) # JO rel32
+ assert_compile(asm, <<~EOS)
+ 0x0: jo 0xff
+ EOS
+ end
+
+ def test_jz
+ asm = Assembler.new
+ asm.jz(rel32(0xff)) # JZ rel32
+ assert_compile(asm, <<~EOS)
+ 0x0: je 0xff
+ EOS
+ end
+
+ def test_lea
+ asm = Assembler.new
+ asm.lea(:rax, [:rax, 8]) # LEA r64,m (Mod 01: [reg]+disp8)
+ asm.lea(:rax, [:rax, 0xffff]) # LEA r64,m (Mod 10: [reg]+disp32)
+ assert_compile(asm, <<~EOS)
+ 0x0: lea rax, [rax + 8]
+ 0x4: lea rax, [rax + 0xffff]
+ EOS
+ end
+
+ def test_mov
+ asm = Assembler.new
+ asm.mov(:eax, DwordPtr[:rbx, 8]) # MOV r32 r/m32 (Mod 01: [reg]+disp8)
+ asm.mov(:eax, 0x100) # MOV r32, imm32 (Mod 11: reg)
+ asm.mov(:rax, [:rbx]) # MOV r64, r/m64 (Mod 00: [reg])
+ asm.mov(:rax, [:rbx, 8]) # MOV r64, r/m64 (Mod 01: [reg]+disp8)
+ asm.mov(:rax, [:rbx, 0x100]) # MOV r64, r/m64 (Mod 10: [reg]+disp32)
+ asm.mov(:rax, :rbx) # MOV r64, r/m64 (Mod 11: reg)
+ asm.mov(:rax, 0x100) # MOV r/m64, imm32 (Mod 11: reg)
+ asm.mov(:rax, 0x100000000) # MOV r64, imm64
+ asm.mov(DwordPtr[:rax, 8], 0x100) # MOV r/m32, imm32 (Mod 01: [reg]+disp8)
+ asm.mov([:rax], 0x100) # MOV r/m64, imm32 (Mod 00: [reg])
+ asm.mov([:rax], :rbx) # MOV r/m64, r64 (Mod 00: [reg])
+ asm.mov([:rax, 8], 0x100) # MOV r/m64, imm32 (Mod 01: [reg]+disp8)
+ asm.mov([:rax, 8], :rbx) # MOV r/m64, r64 (Mod 01: [reg]+disp8)
+ asm.mov([:rax, 0x100], 0x100) # MOV r/m64, imm32 (Mod 10: [reg]+disp32)
+ asm.mov([:rax, 0x100], :rbx) # MOV r/m64, r64 (Mod 10: [reg]+disp32)
+ assert_compile(asm, <<~EOS)
+ 0x0: mov eax, dword ptr [rbx + 8]
+ 0x3: mov eax, 0x100
+ 0x8: mov rax, qword ptr [rbx]
+ 0xb: mov rax, qword ptr [rbx + 8]
+ 0xf: mov rax, qword ptr [rbx + 0x100]
+ 0x16: mov rax, rbx
+ 0x19: mov rax, 0x100
+ 0x20: movabs rax, 0x100000000
+ 0x2a: mov dword ptr [rax + 8], 0x100
+ 0x31: mov qword ptr [rax], 0x100
+ 0x38: mov qword ptr [rax], rbx
+ 0x3b: mov qword ptr [rax + 8], 0x100
+ 0x43: mov qword ptr [rax + 8], rbx
+ 0x47: mov qword ptr [rax + 0x100], 0x100
+ 0x52: mov qword ptr [rax + 0x100], rbx
+ EOS
+ end
+
+ def test_or
+ asm = Assembler.new
+ asm.or(:rax, 0) # OR r/m64, imm8 (Mod 11: reg)
+ asm.or(:rax, 0xffff) # OR r/m64, imm32 (Mod 11: reg)
+ asm.or(:rax, [:rbx, 8]) # OR r64, r/m64 (Mod 01: [reg]+disp8)
+ assert_compile(asm, <<~EOS)
+ 0x0: or rax, 0
+ 0x4: or rax, 0xffff
+ 0xb: or rax, qword ptr [rbx + 8]
+ EOS
+ end
+
+ def test_push
+ asm = Assembler.new
+ asm.push(:rax) # PUSH r64
+ assert_compile(asm, <<~EOS)
+ 0x0: push rax
+ EOS
+ end
+
+ def test_pop
+ asm = Assembler.new
+ asm.pop(:rax) # POP r64
+ assert_compile(asm, <<~EOS)
+ 0x0: pop rax
+ EOS
+ end
+
+ def test_ret
+ asm = Assembler.new
+ asm.ret # RET
+ assert_compile(asm, "0x0: ret \n")
+ end
+
+ def test_sar
+ asm = Assembler.new
+ asm.sar(:rax, 0) # SAR r/m64, imm8 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: sar rax, 0
+ EOS
+ end
+
+ def test_sub
+ asm = Assembler.new
+ asm.sub(:rax, 8) # SUB r/m64, imm8 (Mod 11: reg)
+ asm.sub(:rax, :rbx) # SUB r/m64, r64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: sub rax, 8
+ 0x4: sub rax, rbx
+ EOS
+ end
+
+ def test_test
+ asm = Assembler.new
+ asm.test(BytePtr[:rax, 8], 16) # TEST r/m8*, imm8 (Mod 01: [reg]+disp8)
+ asm.test([:rax, 8], 8) # TEST r/m64, imm32 (Mod 01: [reg]+disp8)
+ asm.test([:rax, 0xffff], 0xffff) # TEST r/m64, imm32 (Mod 10: [reg]+disp32)
+ asm.test(:rax, 0xffff) # TEST r/m64, imm32 (Mod 11: reg)
+ asm.test(:eax, :ebx) # TEST r/m32, r32 (Mod 11: reg)
+ asm.test(:rax, :rbx) # TEST r/m64, r64 (Mod 11: reg)
+ assert_compile(asm, <<~EOS)
+ 0x0: test byte ptr [rax + 8], 0x10
+ 0x4: test qword ptr [rax + 8], 8
+ 0xc: test qword ptr [rax + 0xffff], 0xffff
+ 0x17: test rax, 0xffff
+ 0x1e: test eax, ebx
+ 0x20: test rax, rbx
+ EOS
+ end
+
+ def test_xor
+ asm = Assembler.new
+ asm.xor(:rax, :rbx)
+ assert_compile(asm, <<~EOS)
+ 0x0: xor rax, rbx
+ EOS
+ end
+
+ private
+
+ def rel32(offset)
+ @cb.write_addr + 0xff
+ end
+
+ def assert_compile(asm, expected)
+ actual = compile(asm)
+ assert_equal expected, actual, "---\n#{actual}---"
+ end
+
+ def compile(asm)
+ start_addr = @cb.write_addr
+ @cb.write(asm)
+ end_addr = @cb.write_addr
+
+ io = StringIO.new
+ @cb.dump_disasm(start_addr, end_addr, io:, color: false, test: true)
+ io.seek(0)
+ disasm = io.read
+
+ disasm.gsub!(/^ /, '')
+ disasm.sub!(/\n\z/, '')
+ disasm
+ end
+ end
+end
diff --git a/test/ruby/test_allocation.rb b/test/ruby/test_allocation.rb
new file mode 100644
index 0000000000..48348c0fbd
--- /dev/null
+++ b/test/ruby/test_allocation.rb
@@ -0,0 +1,656 @@
+# frozen_string_literal: false
+require 'test/unit'
+
+class TestAllocation < Test::Unit::TestCase
+ def check_allocations(checks)
+ assert_separately([], <<~RUBY)
+ $allocations = [0, 0]
+ $counts = {}
+ failures = []
+
+ def self.num_allocations
+ ObjectSpace.count_objects($counts)
+ arrays = $counts[:T_ARRAY]
+ hashes = $counts[:T_HASH]
+ yield
+ ObjectSpace.count_objects($counts)
+ arrays -= $counts[:T_ARRAY]
+ hashes -= $counts[:T_HASH]
+ $allocations[0] = -arrays
+ $allocations[1] = -hashes
+ end
+
+ define_singleton_method(:check_allocations) do |num_arrays, num_hashes, check_code|
+ instance_eval <<~RB
+ empty_array = empty_array = []
+ empty_hash = empty_hash = {}
+ array1 = array1 = [1]
+ hash1 = hash1 = {a: 2}
+ nill = nill = nil
+ block = block = lambda{}
+
+ num_allocations do
+ \#{check_code}
+ end
+ RB
+
+ if num_arrays != $allocations[0]
+ failures << "Expected \#{num_arrays} array allocations for \#{check_code.inspect}, but \#{$allocations[0]} arrays allocated"
+ end
+ if num_hashes != $allocations[1]
+ failures << "Expected \#{num_hashes} hash allocations for \#{check_code.inspect}, but \#{$allocations[1]} hashes allocated"
+ end
+ end
+
+ GC.start
+ GC.disable
+
+ #{checks}
+
+ unless failures.empty?
+ assert_equal(true, false, failures.join("\n"))
+ end
+ RUBY
+ end
+
+ class Literal < self
+ def test_array_literal
+ check_allocations(<<~RUBY)
+ check_allocations(1, 0, "[]")
+ check_allocations(1, 0, "[1]")
+ check_allocations(1, 0, "[*empty_array]")
+ check_allocations(1, 0, "[*empty_array, 1, *empty_array]")
+ check_allocations(1, 0, "[*empty_array, *empty_array]")
+ check_allocations(1, 0, "[#{'1,'*100000}]")
+ RUBY
+ end
+
+ def test_hash_literal
+ check_allocations(<<~RUBY)
+ check_allocations(0, 1, "{}")
+ check_allocations(0, 1, "{a: 1}")
+ check_allocations(0, 1, "{**empty_hash}")
+ check_allocations(0, 1, "{**empty_hash, a: 1, **empty_hash}")
+ check_allocations(0, 1, "{**empty_hash, **empty_hash}")
+ check_allocations(0, 1, "{#{100000.times.map{|i| "a#{i}: 1"}.join(',')}}")
+ RUBY
+ end
+ end
+
+ class MethodCall < self
+ def block
+ ''
+ end
+
+ def test_no_parameters
+ only_block = block.empty? ? block : block[2..]
+ check_allocations(<<~RUBY)
+ def self.none(#{only_block}); end
+
+ check_allocations(0, 0, "none(#{only_block})")
+ check_allocations(0, 0, "none(*empty_array#{block})")
+ check_allocations(0, 0, "none(**empty_hash#{block})")
+ check_allocations(0, 0, "none(*empty_array, **empty_hash#{block})")
+
+ 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})")
+ RUBY
+ end
+
+ def test_required_parameter
+ check_allocations(<<~RUBY)
+ def self.required(x#{block}); end
+
+ check_allocations(0, 0, "required(1#{block})")
+ check_allocations(0, 0, "required(1, *empty_array#{block})")
+ check_allocations(0, 0, "required(1, **empty_hash#{block})")
+ check_allocations(0, 0, "required(1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 0, "required(*array1#{block})")
+ check_allocations(0, 1, "required(**hash1#{block})")
+
+ check_allocations(1, 0, "required(*array1, *empty_array#{block})")
+ check_allocations(0, 1, "required(**hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "required(*array1, *empty_array, **empty_hash#{block})")
+
+ # Currently allocates 1 array unnecessarily due to splatarray true
+ check_allocations(1, 1, "required(*empty_array, **hash1, **empty_hash#{block})")
+ RUBY
+ end
+
+ def test_optional_parameter
+ check_allocations(<<~RUBY)
+ def self.optional(x=nil#{block}); end
+
+ check_allocations(0, 0, "optional(1#{block})")
+ check_allocations(0, 0, "optional(1, *empty_array#{block})")
+ check_allocations(0, 0, "optional(1, **empty_hash#{block})")
+ check_allocations(0, 0, "optional(1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 0, "optional(*array1#{block})")
+ check_allocations(0, 1, "optional(**hash1#{block})")
+
+ check_allocations(1, 0, "optional(*array1, *empty_array#{block})")
+ check_allocations(0, 1, "optional(**hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "optional(*array1, *empty_array, **empty_hash#{block})")
+
+ # Currently allocates 1 array unnecessarily due to splatarray true
+ check_allocations(1, 1, "optional(*empty_array, **hash1, **empty_hash#{block})")
+ RUBY
+ end
+
+ def test_positional_splat_parameter
+ check_allocations(<<~RUBY)
+ def self.splat(*x#{block}); end
+
+ check_allocations(1, 0, "splat(1#{block})")
+ check_allocations(1, 0, "splat(1, *empty_array#{block})")
+ check_allocations(1, 0, "splat(1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat(1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat(*array1#{block})")
+ check_allocations(1, 0, "splat(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "splat(*array1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat(1, *array1#{block})")
+ check_allocations(1, 0, "splat(1, *array1, *empty_array#{block})")
+ check_allocations(1, 0, "splat(1, *array1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat(1, *array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat(*array1#{block})")
+ check_allocations(1, 1, "splat(**hash1#{block})")
+
+ check_allocations(1, 0, "splat(*array1, *empty_array#{block})")
+ 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})")
+ RUBY
+ end
+
+ def test_required_and_positional_splat_parameters
+ check_allocations(<<~RUBY)
+ def self.req_splat(x, *y#{block}); end
+
+ check_allocations(1, 0, "req_splat(1#{block})")
+ check_allocations(1, 0, "req_splat(1, *empty_array#{block})")
+ check_allocations(1, 0, "req_splat(1, **empty_hash#{block})")
+ check_allocations(1, 0, "req_splat(1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "req_splat(*array1#{block})")
+ check_allocations(1, 0, "req_splat(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "req_splat(*array1, **empty_hash#{block})")
+ check_allocations(1, 0, "req_splat(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "req_splat(1, *array1#{block})")
+ check_allocations(1, 0, "req_splat(1, *array1, *empty_array#{block})")
+ check_allocations(1, 0, "req_splat(1, *array1, **empty_hash#{block})")
+ check_allocations(1, 0, "req_splat(1, *array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "req_splat(*array1#{block})")
+ check_allocations(1, 1, "req_splat(**hash1#{block})")
+
+ check_allocations(1, 0, "req_splat(*array1, *empty_array#{block})")
+ 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})")
+ RUBY
+ end
+
+ def test_positional_splat_and_post_parameters
+ check_allocations(<<~RUBY)
+ def self.splat_post(*x, y#{block}); end
+
+ check_allocations(1, 0, "splat_post(1#{block})")
+ check_allocations(1, 0, "splat_post(1, *empty_array#{block})")
+ check_allocations(1, 0, "splat_post(1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat_post(1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat_post(*array1#{block})")
+ check_allocations(1, 0, "splat_post(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "splat_post(*array1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat_post(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat_post(1, *array1#{block})")
+ check_allocations(1, 0, "splat_post(1, *array1, *empty_array#{block})")
+ check_allocations(1, 0, "splat_post(1, *array1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat_post(1, *array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat_post(*array1#{block})")
+ check_allocations(1, 1, "splat_post(**hash1#{block})")
+
+ check_allocations(1, 0, "splat_post(*array1, *empty_array#{block})")
+ 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})")
+ RUBY
+ end
+
+ def test_keyword_parameter
+ check_allocations(<<~RUBY)
+ def self.keyword(a: nil#{block}); end
+
+ check_allocations(0, 0, "keyword(a: 2#{block})")
+ check_allocations(0, 0, "keyword(*empty_array, a: 2#{block})")
+ check_allocations(0, 1, "keyword(a:2, **empty_hash#{block})")
+ check_allocations(0, 1, "keyword(**empty_hash, a: 2#{block})")
+
+ check_allocations(0, 0, "keyword(**nil#{block})")
+ check_allocations(0, 0, "keyword(**empty_hash#{block})")
+ check_allocations(0, 0, "keyword(**hash1#{block})")
+ check_allocations(0, 0, "keyword(*empty_array, **hash1#{block})")
+ check_allocations(0, 1, "keyword(**hash1, **empty_hash#{block})")
+ check_allocations(0, 1, "keyword(**empty_hash, **hash1#{block})")
+
+ check_allocations(0, 0, "keyword(*empty_array#{block})")
+ check_allocations(0, 1, "keyword(**hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "keyword(*empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 0, "keyword(*empty_array#{block})")
+ check_allocations(0, 1, "keyword(**hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "keyword(*empty_array, *empty_array, **empty_hash#{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})")
+ RUBY
+ end
+
+ def test_keyword_splat_parameter
+ check_allocations(<<~RUBY)
+ def self.keyword_splat(**kw#{block}); end
+
+ check_allocations(0, 1, "keyword_splat(a: 2#{block})")
+ check_allocations(0, 1, "keyword_splat(*empty_array, a: 2#{block})")
+ check_allocations(0, 1, "keyword_splat(a:2, **empty_hash#{block})")
+ check_allocations(0, 1, "keyword_splat(**empty_hash, a: 2#{block})")
+
+ check_allocations(0, 1, "keyword_splat(**nil#{block})")
+ check_allocations(0, 1, "keyword_splat(**empty_hash#{block})")
+ check_allocations(0, 1, "keyword_splat(**hash1#{block})")
+ check_allocations(0, 1, "keyword_splat(*empty_array, **hash1#{block})")
+ check_allocations(0, 1, "keyword_splat(**hash1, **empty_hash#{block})")
+ check_allocations(0, 1, "keyword_splat(**empty_hash, **hash1#{block})")
+
+ check_allocations(0, 1, "keyword_splat(*empty_array#{block})")
+ 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(0, 1, "keyword_splat(*empty_array#{block})")
+ check_allocations(0, 1, "keyword_splat(**hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "keyword_splat(*empty_array, *empty_array, **empty_hash#{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})")
+ RUBY
+ end
+
+ def test_keyword_and_keyword_splat_parameter
+ check_allocations(<<~RUBY)
+ def self.keyword_and_keyword_splat(a: 1, **kw#{block}); end
+
+ check_allocations(0, 1, "keyword_and_keyword_splat(a: 2#{block})")
+ check_allocations(0, 1, "keyword_and_keyword_splat(*empty_array, a: 2#{block})")
+ check_allocations(0, 1, "keyword_and_keyword_splat(a:2, **empty_hash#{block})")
+ check_allocations(0, 1, "keyword_and_keyword_splat(**empty_hash, a: 2#{block})")
+
+ check_allocations(0, 1, "keyword_and_keyword_splat(**nil#{block})")
+ check_allocations(0, 1, "keyword_and_keyword_splat(**empty_hash#{block})")
+ check_allocations(0, 1, "keyword_and_keyword_splat(**hash1#{block})")
+ check_allocations(0, 1, "keyword_and_keyword_splat(*empty_array, **hash1#{block})")
+ check_allocations(0, 1, "keyword_and_keyword_splat(**hash1, **empty_hash#{block})")
+ check_allocations(0, 1, "keyword_and_keyword_splat(**empty_hash, **hash1#{block})")
+
+ check_allocations(0, 1, "keyword_and_keyword_splat(*empty_array#{block})")
+ 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(0, 1, "keyword_and_keyword_splat(*empty_array#{block})")
+ 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})")
+
+ # 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})")
+ RUBY
+ end
+
+ def test_required_positional_and_keyword_parameter
+ check_allocations(<<~RUBY)
+ def self.required_and_keyword(b, a: nil#{block}); end
+
+ check_allocations(0, 0, "required_and_keyword(1, a: 2#{block})")
+ check_allocations(0, 0, "required_and_keyword(1, *empty_array, a: 2#{block})")
+ check_allocations(0, 1, "required_and_keyword(1, a:2, **empty_hash#{block})")
+ check_allocations(0, 1, "required_and_keyword(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(0, 0, "required_and_keyword(1, **nil#{block})")
+ check_allocations(0, 0, "required_and_keyword(1, **empty_hash#{block})")
+ check_allocations(0, 0, "required_and_keyword(1, **hash1#{block})")
+ check_allocations(0, 0, "required_and_keyword(1, *empty_array, **hash1#{block})")
+ check_allocations(0, 1, "required_and_keyword(1, **hash1, **empty_hash#{block})")
+ check_allocations(0, 1, "required_and_keyword(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(0, 0, "required_and_keyword(1, *empty_array#{block})")
+ check_allocations(0, 1, "required_and_keyword(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "required_and_keyword(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 0, "required_and_keyword(*array1, a: 2#{block})")
+
+ check_allocations(0, 0, "required_and_keyword(*array1, **nill#{block})")
+ check_allocations(0, 0, "required_and_keyword(*array1, **empty_hash#{block})")
+ check_allocations(0, 0, "required_and_keyword(*array1, **hash1#{block})")
+ check_allocations(1, 0, "required_and_keyword(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 0, "required_and_keyword(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "required_and_keyword(*array1, *empty_array, **empty_hash#{block})")
+
+ 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})")
+
+ # 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})")
+ check_allocations(1, 1, "required_and_keyword(*array1, **empty_hash, a: 2#{block})")
+ check_allocations(1, 1, "required_and_keyword(*array1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "required_and_keyword(*array1, **nil#{block})")
+ RUBY
+ end
+
+ def test_positional_splat_and_keyword_parameter
+ check_allocations(<<~RUBY)
+ def self.splat_and_keyword(*b, a: nil#{block}); end
+
+ check_allocations(1, 0, "splat_and_keyword(1, a: 2#{block})")
+ check_allocations(1, 0, "splat_and_keyword(1, *empty_array, a: 2#{block})")
+ check_allocations(1, 1, "splat_and_keyword(1, a:2, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(1, 0, "splat_and_keyword(1, **nil#{block})")
+ check_allocations(1, 0, "splat_and_keyword(1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat_and_keyword(1, **hash1#{block})")
+ check_allocations(1, 0, "splat_and_keyword(1, *empty_array, **hash1#{block})")
+ check_allocations(1, 1, "splat_and_keyword(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(1, 0, "splat_and_keyword(1, *empty_array#{block})")
+ check_allocations(1, 1, "splat_and_keyword(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat_and_keyword(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 0, "splat_and_keyword(*array1, a: 2#{block})")
+
+ check_allocations(1, 0, "splat_and_keyword(*array1, **nill#{block})")
+ check_allocations(1, 0, "splat_and_keyword(*array1, **empty_hash#{block})")
+ check_allocations(1, 0, "splat_and_keyword(*array1, **hash1#{block})")
+ check_allocations(1, 0, "splat_and_keyword(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 0, "splat_and_keyword(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "splat_and_keyword(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword(*array1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword(*array1, *empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword(1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword(1, *empty_array, **hash1, **empty_hash#{block})")
+ 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})")
+ RUBY
+ end
+
+ def test_required_and_keyword_splat_parameter
+ check_allocations(<<~RUBY)
+ def self.required_and_keyword_splat(b, **kw#{block}); end
+
+ check_allocations(0, 1, "required_and_keyword_splat(1, a: 2#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, *empty_array, a: 2#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, a:2, **empty_hash#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(0, 1, "required_and_keyword_splat(1, **nil#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, **empty_hash#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, **hash1#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, *empty_array, **hash1#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, **hash1, **empty_hash#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(0, 1, "required_and_keyword_splat(1, *empty_array#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "required_and_keyword_splat(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 1, "required_and_keyword_splat(*array1, a: 2#{block})")
+
+ check_allocations(0, 1, "required_and_keyword_splat(*array1, **nill#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(*array1, **empty_hash#{block})")
+ check_allocations(0, 1, "required_and_keyword_splat(*array1, **hash1#{block})")
+ check_allocations(1, 1, "required_and_keyword_splat(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 1, "required_and_keyword_splat(*array1, *empty_array#{block})")
+ check_allocations(1, 1, "required_and_keyword_splat(*array1, *empty_array, **empty_hash#{block})")
+
+ 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})")
+
+ # 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})")
+ check_allocations(1, 1, "required_and_keyword_splat(*array1, **empty_hash, a: 2#{block})")
+ check_allocations(1, 1, "required_and_keyword_splat(*array1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "required_and_keyword_splat(*array1, **nil#{block})")
+ RUBY
+ end
+
+ def test_positional_splat_and_keyword_splat_parameter
+ check_allocations(<<~RUBY)
+ def self.splat_and_keyword_splat(*b, **kw#{block}); end
+
+ check_allocations(1, 1, "splat_and_keyword_splat(1, a: 2#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, *empty_array, a: 2#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, a:2, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword_splat(1, **nil#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, **hash1#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, *empty_array, **hash1#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword_splat(1, *empty_array#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, a: 2#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, **nill#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, **hash1#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, *empty_array#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(*array1, *empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 1, "splat_and_keyword_splat(1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "splat_and_keyword_splat(1, *empty_array, **hash1, **empty_hash#{block})")
+ 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})")
+ RUBY
+ end
+
+ def test_anonymous_splat_and_anonymous_keyword_splat_parameters
+ check_allocations(<<~RUBY)
+ def self.anon_splat_and_anon_keyword_splat(*, **#{block}); end
+
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, a: 2#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array, a: 2#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, a:2, **empty_hash#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, **nil#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, **empty_hash#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, **hash1#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array, **hash1#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 0, "anon_splat_and_anon_keyword_splat(*array1, a: 2#{block})")
+
+ check_allocations(0, 0, "anon_splat_and_anon_keyword_splat(*array1, **nill#{block})")
+ check_allocations(0, 0, "anon_splat_and_anon_keyword_splat(*array1, **empty_hash#{block})")
+ check_allocations(0, 0, "anon_splat_and_anon_keyword_splat(*array1, **hash1#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, *empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, *empty_array, **hash1, **empty_hash#{block})")
+ 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})")
+ RUBY
+ end
+
+ def test_nested_anonymous_splat_and_anonymous_keyword_splat_parameters
+ check_allocations(<<~RUBY)
+ def self.anon_splat_and_anon_keyword_splat(*, **#{block}); t(*, **) end; def self.t(*, **#{block}); end
+
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, a: 2#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array, a: 2#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, a:2, **empty_hash#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, **nil#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, **empty_hash#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, **hash1#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array, **hash1#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 0, "anon_splat_and_anon_keyword_splat(*array1, a: 2#{block})")
+
+ check_allocations(0, 0, "anon_splat_and_anon_keyword_splat(*array1, **nill#{block})")
+ check_allocations(0, 0, "anon_splat_and_anon_keyword_splat(*array1, **empty_hash#{block})")
+ check_allocations(0, 0, "anon_splat_and_anon_keyword_splat(*array1, **hash1#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "anon_splat_and_anon_keyword_splat(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(*array1, *empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "anon_splat_and_anon_keyword_splat(1, *empty_array, **hash1, **empty_hash#{block})")
+ 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})")
+ RUBY
+ end
+
+ def test_argument_forwarding
+ check_allocations(<<~RUBY)
+ def self.argument_forwarding(...); end
+
+ check_allocations(1, 1, "argument_forwarding(1, a: 2#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, *empty_array, a: 2#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, a:2, **empty_hash#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(1, 0, "argument_forwarding(1, **nil#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, **empty_hash#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, **hash1#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, *empty_array, **hash1#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(1, 0, "argument_forwarding(1, *empty_array#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 0, "argument_forwarding(*array1, a: 2#{block})")
+
+ check_allocations(0, 0, "argument_forwarding(*array1, **nill#{block})")
+ check_allocations(0, 0, "argument_forwarding(*array1, **empty_hash#{block})")
+ check_allocations(0, 0, "argument_forwarding(*array1, **hash1#{block})")
+ check_allocations(1, 0, "argument_forwarding(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 0, "argument_forwarding(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "argument_forwarding(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "argument_forwarding(*array1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "argument_forwarding(*array1, *empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 1, "argument_forwarding(1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, *empty_array, **hash1, **empty_hash#{block})")
+ 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})")
+ RUBY
+ end
+
+ def test_nested_argument_forwarding
+ check_allocations(<<~RUBY)
+ def self.argument_forwarding(...); t(...) end; def self.t(...) end
+
+ check_allocations(1, 1, "argument_forwarding(1, a: 2#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, *empty_array, a: 2#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, a:2, **empty_hash#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, **empty_hash, a: 2#{block})")
+
+ check_allocations(1, 0, "argument_forwarding(1, **nil#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, **empty_hash#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, **hash1#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, *empty_array, **hash1#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, **empty_hash, **hash1#{block})")
+
+ check_allocations(1, 0, "argument_forwarding(1, *empty_array#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, **hash1, **empty_hash#{block})")
+ check_allocations(1, 0, "argument_forwarding(1, *empty_array, *empty_array, **empty_hash#{block})")
+
+ check_allocations(0, 0, "argument_forwarding(*array1, a: 2#{block})")
+
+ check_allocations(0, 0, "argument_forwarding(*array1, **nill#{block})")
+ check_allocations(0, 0, "argument_forwarding(*array1, **empty_hash#{block})")
+ check_allocations(0, 0, "argument_forwarding(*array1, **hash1#{block})")
+ check_allocations(1, 0, "argument_forwarding(*array1, *empty_array, **hash1#{block})")
+
+ check_allocations(1, 0, "argument_forwarding(*array1, *empty_array#{block})")
+ check_allocations(1, 0, "argument_forwarding(*array1, *empty_array, **empty_hash#{block})")
+
+ check_allocations(1, 1, "argument_forwarding(*array1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "argument_forwarding(*array1, *empty_array, **hash1, **empty_hash#{block})")
+
+ check_allocations(1, 1, "argument_forwarding(1, *empty_array, a: 2, **empty_hash#{block})")
+ check_allocations(1, 1, "argument_forwarding(1, *empty_array, **hash1, **empty_hash#{block})")
+ 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})")
+ RUBY
+ end
+
+ class WithBlock < self
+ def block
+ ', &block'
+ end
+ end
+ end
+end
diff --git a/test/ruby/test_argf.rb b/test/ruby/test_argf.rb
index 12f7d6485a..55a06296aa 100644
--- a/test/ruby/test_argf.rb
+++ b/test/ruby/test_argf.rb
@@ -9,39 +9,23 @@ class TestArgf < Test::Unit::TestCase
def setup
@tmpdir = Dir.mktmpdir
@tmp_count = 0
- @t1 = make_tempfile0("argf-foo")
- @t1.binmode
- @t1.puts "1"
- @t1.puts "2"
- @t1.close
- @t2 = make_tempfile0("argf-bar")
- @t2.binmode
- @t2.puts "3"
- @t2.puts "4"
- @t2.close
- @t3 = make_tempfile0("argf-baz")
- @t3.binmode
- @t3.puts "5"
- @t3.puts "6"
- @t3.close
+ @t1 = make_tempfile("argf-foo", %w"1 2", binmode: true)
+ @t2 = make_tempfile("argf-bar", %w"3 4", binmode: true)
+ @t3 = make_tempfile("argf-baz", %w"5 6", binmode: true)
end
def teardown
FileUtils.rmtree(@tmpdir)
end
- def make_tempfile0(basename)
+ def make_tempfile(basename = "argf-qux", data = %w[foo bar baz], binmode: false)
@tmp_count += 1
- open("#{@tmpdir}/#{basename}-#{@tmp_count}", "w")
- end
-
- def make_tempfile(basename = "argf-qux")
- t = make_tempfile0(basename)
- t.puts "foo"
- t.puts "bar"
- t.puts "baz"
- t.close
- t
+ path = "#{@tmpdir}/#{basename}-#{@tmp_count}"
+ File.open(path, "w") do |f|
+ f.binmode if binmode
+ f.puts(*data)
+ f
+ end
end
def ruby(*args, external_encoding: Encoding::UTF_8)
@@ -571,15 +555,11 @@ class TestArgf < Test::Unit::TestCase
end
end
- t1 = open("#{@tmpdir}/argf-hoge", "w")
- t1.binmode
- t1.puts "foo"
- t1.close
- t2 = open("#{@tmpdir}/argf-moge", "w")
- t2.binmode
- t2.puts "bar"
- t2.close
- ruby('-e', 'STDERR.reopen(STDOUT); ARGF.gets; ARGF.skip; p ARGF.eof?', t1.path, t2.path) do |f|
+ t1 = "#{@tmpdir}/argf-hoge"
+ t2 = "#{@tmpdir}/argf-moge"
+ File.binwrite(t1, "foo\n")
+ File.binwrite(t2, "bar\n")
+ ruby('-e', 'STDERR.reopen(STDOUT); ARGF.gets; ARGF.skip; p ARGF.eof?', t1, t2) do |f|
assert_equal(%w(false), f.read.split(/\n/))
end
end
@@ -593,7 +573,7 @@ class TestArgf < Test::Unit::TestCase
def test_read2
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
{#
- s = ""
+ s = +""
ARGF.read(8, s)
p s
};
@@ -604,7 +584,7 @@ class TestArgf < Test::Unit::TestCase
def test_read2_with_not_empty_buffer
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
{#
- s = "0123456789"
+ s = +"0123456789"
ARGF.read(8, s)
p s
};
@@ -617,7 +597,7 @@ class TestArgf < Test::Unit::TestCase
{#
nil while ARGF.gets
p ARGF.read
- p ARGF.read(0, "")
+ p ARGF.read(0, +"")
};
assert_equal("nil\n\"\"\n", f.read)
end
@@ -626,13 +606,13 @@ class TestArgf < Test::Unit::TestCase
def test_readpartial
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
{#
- s = ""
+ s = +""
begin
loop do
s << ARGF.readpartial(1)
- t = ""; ARGF.readpartial(1, t); s << t
+ t = +""; ARGF.readpartial(1, t); s << t
# not empty buffer
- u = "abcdef"; ARGF.readpartial(1, u); s << u
+ u = +"abcdef"; ARGF.readpartial(1, u); s << u
end
rescue EOFError
puts s
@@ -645,11 +625,11 @@ class TestArgf < Test::Unit::TestCase
def test_readpartial2
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}") do |f|
{#
- s = ""
+ s = +""
begin
loop do
s << ARGF.readpartial(1)
- t = ""; ARGF.readpartial(1, t); s << t
+ t = +""; ARGF.readpartial(1, t); s << t
end
rescue EOFError
$stdout.binmode
@@ -680,7 +660,7 @@ class TestArgf < Test::Unit::TestCase
def test_getc
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
{#
- s = ""
+ s = +""
while c = ARGF.getc
s << c
end
@@ -706,7 +686,7 @@ class TestArgf < Test::Unit::TestCase
def test_readchar
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
{#
- s = ""
+ s = +""
begin
while c = ARGF.readchar
s << c
@@ -784,7 +764,7 @@ class TestArgf < Test::Unit::TestCase
def test_each_char
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}", @t1.path, @t2.path, @t3.path) do |f|
{#
- s = ""
+ s = +""
ARGF.each_char {|c| s << c }
puts s
};
@@ -854,7 +834,7 @@ class TestArgf < Test::Unit::TestCase
def test_binmode
bug5268 = '[ruby-core:39234]'
- open(@t3.path, "wb") {|f| f.write "5\r\n6\r\n"}
+ File.binwrite(@t3.path, "5\r\n6\r\n")
ruby('-e', "ARGF.binmode; STDOUT.binmode; puts ARGF.read", @t1.path, @t2.path, @t3.path) do |f|
f.binmode
assert_equal("1\n2\n3\n4\n5\r\n6\r\n", f.read, bug5268)
@@ -863,7 +843,7 @@ class TestArgf < Test::Unit::TestCase
def test_textmode
bug5268 = '[ruby-core:39234]'
- open(@t3.path, "wb") {|f| f.write "5\r\n6\r\n"}
+ File.binwrite(@t3.path, "5\r\n6\r\n")
ruby('-e', "STDOUT.binmode; puts ARGF.read", @t1.path, @t2.path, @t3.path) do |f|
f.binmode
assert_equal("1\n2\n3\n4\n5\n6\n", f.read, bug5268)
@@ -1073,7 +1053,7 @@ class TestArgf < Test::Unit::TestCase
ruby('-e', "#{<<~"{#"}\n#{<<~'};'}") do |f|
{#
$stdout.sync = true
- :wait_readable == ARGF.read_nonblock(1, "", exception: false) or
+ :wait_readable == ARGF.read_nonblock(1, +"", exception: false) or
abort "did not return :wait_readable"
begin
@@ -1086,7 +1066,7 @@ class TestArgf < Test::Unit::TestCase
IO.select([ARGF]) == [[ARGF], [], []] or
abort 'did not awaken for readability (before byte)'
- buf = ''
+ buf = +''
buf.object_id == ARGF.read_nonblock(1, buf).object_id or
abort "read destination buffer failed"
print buf
@@ -1140,4 +1120,34 @@ class TestArgf < Test::Unit::TestCase
argf.close
end
end
+
+ def test_putc
+ t = make_tempfile("argf-#{__method__}", 'bar')
+ ruby('-pi-', '-e', "print ARGF.putc('x')", t.path) do |f|
+ end
+ assert_equal("xxbar\n", File.read(t.path))
+ end
+
+ def test_puts
+ t = make_tempfile("argf-#{__method__}", 'bar')
+ err = "#{@tmpdir}/errout"
+ ruby('-pi-', '-W2', '-e', "print ARGF.puts('foo')", t.path, {err: err}) do |f|
+ end
+ assert_equal("foo\nbar\n", File.read(t.path))
+ assert_empty File.read(err)
+ end
+
+ def test_print
+ t = make_tempfile("argf-#{__method__}", 'bar')
+ ruby('-pi-', '-e', "print ARGF.print('foo')", t.path) do |f|
+ end
+ assert_equal("foobar\n", File.read(t.path))
+ end
+
+ def test_printf
+ t = make_tempfile("argf-#{__method__}", 'bar')
+ ruby('-pi-', '-e', "print ARGF.printf('%s', 'foo')", t.path) do |f|
+ end
+ assert_equal("foobar\n", File.read(t.path))
+ end
end
diff --git a/test/ruby/test_arity.rb b/test/ruby/test_arity.rb
index d26338e0aa..bd26d5f0f5 100644
--- a/test/ruby/test_arity.rb
+++ b/test/ruby/test_arity.rb
@@ -65,6 +65,5 @@ class TestArity < Test::Unit::TestCase
assert_arity(%w[1 2]) { "".sub!(//) }
assert_arity(%w[0 1..2]) { "".sub!{} }
assert_arity(%w[0 1+]) { exec }
- assert_arity(%w[0 1+]) { Struct.new }
end
end
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 6ee468eaef..9560fca958 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -529,14 +529,19 @@ class TestArray < Test::Unit::TestCase
end
def test_assoc
+ def (a4 = Object.new).to_ary
+ %w( pork porcine )
+ end
+
a1 = @cls[*%w( cat feline )]
a2 = @cls[*%w( dog canine )]
a3 = @cls[*%w( mule asinine )]
- a = @cls[ a1, a2, a3 ]
+ a = @cls[ a1, a2, a3, a4 ]
assert_equal(a1, a.assoc('cat'))
assert_equal(a3, a.assoc('mule'))
+ assert_equal(%w( pork porcine ), a.assoc("pork"))
assert_equal(nil, a.assoc('asinine'))
assert_equal(nil, a.assoc('wombat'))
assert_equal(nil, a.assoc(1..2))
@@ -1294,6 +1299,12 @@ class TestArray < Test::Unit::TestCase
=end
end
+ def test_pack_with_buffer
+ n = [ 65, 66, 67 ]
+ str = "a" * 100
+ assert_equal("aaaABC", n.pack("@3ccc", buffer: str.dup), "[Bug #19116]")
+ end
+
def test_pop
a = @cls[ 'cat', 'dog' ]
assert_equal('dog', a.pop)
@@ -1323,13 +1334,17 @@ class TestArray < Test::Unit::TestCase
end
def test_rassoc
+ def (a4 = Object.new).to_ary
+ %w( pork porcine )
+ end
a1 = @cls[*%w( cat feline )]
a2 = @cls[*%w( dog canine )]
a3 = @cls[*%w( mule asinine )]
- a = @cls[ a1, a2, a3 ]
+ a = @cls[ a1, a2, a3, a4 ]
assert_equal(a1, a.rassoc('feline'))
assert_equal(a3, a.rassoc('asinine'))
+ assert_equal(%w( pork porcine ), a.rassoc("porcine"))
assert_equal(nil, a.rassoc('dog'))
assert_equal(nil, a.rassoc('mule'))
assert_equal(nil, a.rassoc(1..2))
@@ -1687,6 +1702,15 @@ class TestArray < Test::Unit::TestCase
assert_equal([100], a.slice(-1, 1_000_000_000))
end
+ def test_slice_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress { assert_equal([1, 2, 3, 4, 5], (0..10).to_a[1, 5]) }
+ EnvUtil.under_gc_compact_stress do
+ a = [0, 1, 2, 3, 4, 5]
+ assert_equal([2, 1, 0], a.slice((2..).step(-1)))
+ end
+ end
+
def test_slice!
a = @cls[1, 2, 3, 4, 5]
assert_equal(3, a.slice!(2))
@@ -2980,7 +3004,9 @@ class TestArray < Test::Unit::TestCase
assert_raise(RangeError) {
[*0..2].shuffle(random: gen)
}
+ end
+ def test_shuffle_random_clobbering
ary = (0...10000).to_a
gen = proc do
ary.replace([])
@@ -2990,7 +3016,9 @@ class TestArray < Test::Unit::TestCase
alias rand call
end
assert_raise(RuntimeError) {ary.shuffle!(random: gen)}
+ end
+ def test_shuffle_random_zero
zero = Object.new
def zero.to_int
0
@@ -3003,7 +3031,10 @@ class TestArray < Test::Unit::TestCase
end
ary = (0...10000).to_a
assert_equal(ary.rotate, ary.shuffle(random: gen_to_int))
+ end
+ def test_shuffle_random_invalid_generator
+ ary = (0...10).to_a
assert_raise(NoMethodError) {
ary.shuffle(random: Object.new)
}
@@ -3020,7 +3051,9 @@ class TestArray < Test::Unit::TestCase
assert_include([0, 1, 2], sample)
}
end
+ end
+ def test_sample_statistics
srand(0)
a = (1..18).to_a
(0..20).each do |n|
@@ -3037,9 +3070,13 @@ class TestArray < Test::Unit::TestCase
end
assert_operator(h.values.min * 2, :>=, h.values.max) if n != 0
end
+ end
+ def test_sample_invalid_argument
assert_raise(ArgumentError, '[ruby-core:23374]') {[1, 2].sample(-1)}
+ end
+ def test_sample_random_srand0
gen = Random.new(0)
srand(0)
a = (1..18).to_a
@@ -3048,13 +3085,15 @@ class TestArray < Test::Unit::TestCase
assert_equal(a.sample(n), a.sample(n, random: gen), "#{i}/#{n}")
end
end
+ end
+ def test_sample_unknown_keyword
assert_raise_with_message(ArgumentError, /unknown keyword/) do
[0, 1, 2].sample(xawqij: "a")
end
end
- def test_sample_random
+ def test_sample_random_generator
ary = (0...10000).to_a
assert_raise(ArgumentError) {ary.sample(1, 2, random: nil)}
gen0 = proc do |max|
@@ -3097,7 +3136,9 @@ class TestArray < Test::Unit::TestCase
assert_equal([5000, 0, 5001, 2, 5002, 4, 5003, 6, 5004, 8, 5005], ary.sample(11, random: gen0))
ary.sample(11, random: gen1) # implementation detail, may change in the future
assert_equal([], ary)
+ end
+ def test_sample_random_generator_half
half = Object.new
def half.to_int
5000
@@ -3110,7 +3151,10 @@ class TestArray < Test::Unit::TestCase
end
ary = (0...10000).to_a
assert_equal(5000, ary.sample(random: gen_to_int))
+ end
+ def test_sample_random_invalid_generator
+ ary = (0..10).to_a
assert_raise(NoMethodError) {
ary.sample(random: Object.new)
}
@@ -3310,6 +3354,8 @@ class TestArray < Test::Unit::TestCase
assert_equal(nil, a.bsearch {|x| 1 * (2**100) })
assert_equal(nil, a.bsearch {|x| (-1) * (2**100) })
+ assert_equal(4, a.bsearch {|x| (4 - x).to_r })
+
assert_include([4, 7], a.bsearch {|x| (2**100).coerce((1 - x / 4) * (2**100)).first })
end
@@ -3345,6 +3391,8 @@ class TestArray < Test::Unit::TestCase
assert_equal(nil, a.bsearch_index {|x| 1 * (2**100) })
assert_equal(nil, a.bsearch_index {|x| (-1) * (2**100) })
+ assert_equal(1, a.bsearch_index {|x| (4 - x).to_r })
+
assert_include([1, 2], a.bsearch_index {|x| (2**100).coerce((1 - x / 4) * (2**100)).first })
end
@@ -3508,11 +3556,21 @@ class TestArray < Test::Unit::TestCase
assert_equal(10000, eval(lit).size)
end
+ def test_array_safely_modified_by_sort_block
+ var_0 = (1..70).to_a
+ var_0.sort! do |var_0_block_129, var_1_block_129|
+ var_0.pop
+ var_1_block_129 <=> var_0_block_129
+ end.shift(3)
+ assert_equal((1..67).to_a.reverse, var_0)
+ end
+
private
def need_continuation
unless respond_to?(:callcc, true)
EnvUtil.suppress_warning {require 'continuation'}
end
+ omit 'requires callcc support' unless respond_to?(:callcc, true)
end
end
diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb
index d28d7e1fab..29da607fc5 100644
--- a/test/ruby/test_ast.rb
+++ b/test/ruby/test_ast.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: false
require 'test/unit'
require 'tempfile'
+require 'pp'
class RubyVM
module AbstractSyntaxTree
@@ -131,6 +132,34 @@ class TestAst < Test::Unit::TestCase
end
end
+ Dir.glob("test/**/*.rb", base: SRCDIR).each do |path|
+ define_method("test_all_tokens:#{path}") do
+ node = RubyVM::AbstractSyntaxTree.parse_file("#{SRCDIR}/#{path}", keep_tokens: true)
+ tokens = node.all_tokens.sort_by { [_1.last[0], _1.last[1]] }
+ tokens_bytes = tokens.map { _1[2]}.join.bytes
+ source_bytes = File.read("#{SRCDIR}/#{path}").bytes
+
+ assert_equal(source_bytes, tokens_bytes)
+
+ (tokens.count - 1).times do |i|
+ token_0 = tokens[i]
+ token_1 = tokens[i + 1]
+ end_pos = token_0.last[2..3]
+ beg_pos = token_1.last[0..1]
+
+ if end_pos[0] == beg_pos[0]
+ # When both tokens are same line, column should be consecutives
+ assert_equal(beg_pos[1], end_pos[1], "#{token_0}. #{token_1}")
+ else
+ # Line should be next
+ assert_equal(beg_pos[0], end_pos[0] + 1, "#{token_0}. #{token_1}")
+ # It should be on the beginning of the line
+ assert_equal(0, beg_pos[1], "#{token_0}. #{token_1}")
+ end
+ end
+ end
+ end
+
private def parse(src)
EnvUtil.suppress_warning {
RubyVM::AbstractSyntaxTree.parse(src)
@@ -185,6 +214,147 @@ class TestAst < Test::Unit::TestCase
end
end
+ def assert_parse(code, warning: '')
+ node = assert_warning(warning) {RubyVM::AbstractSyntaxTree.parse(code)}
+ assert_kind_of(RubyVM::AbstractSyntaxTree::Node, node, code)
+ end
+
+ def assert_invalid_parse(msg, code)
+ assert_raise_with_message(SyntaxError, msg, code) do
+ RubyVM::AbstractSyntaxTree.parse(code)
+ end
+ end
+
+ def test_invalid_exit
+ [
+ "break",
+ "break true",
+ "next",
+ "next true",
+ "redo",
+ ].each do |code, *args|
+ msg = /Invalid #{code[/\A\w+/]}/
+ assert_parse("while false; #{code}; end")
+ assert_parse("until true; #{code}; end")
+ assert_parse("begin #{code}; end while false")
+ assert_parse("begin #{code}; end until true")
+ assert_parse("->{#{code}}")
+ assert_parse("->{class X; #{code}; end}")
+ assert_invalid_parse(msg, "#{code}")
+ assert_invalid_parse(msg, "def m; #{code}; end")
+ assert_invalid_parse(msg, "begin; #{code}; end")
+ assert_parse("END {#{code}}")
+
+ assert_parse("!defined?(#{code})")
+ assert_parse("def m; defined?(#{code}); end")
+ assert_parse("!begin; defined?(#{code}); end")
+
+ next if code.include?(" ")
+ assert_parse("!defined? #{code}")
+ assert_parse("def m; defined? #{code}; end")
+ assert_parse("!begin; defined? #{code}; end")
+ end
+ end
+
+ def test_invalid_retry
+ msg = /Invalid retry/
+ assert_invalid_parse(msg, "retry")
+ assert_invalid_parse(msg, "def m; retry; end")
+ assert_invalid_parse(msg, "begin retry; end")
+ assert_parse("begin rescue; retry; end")
+ assert_invalid_parse(msg, "begin rescue; else; retry; end")
+ assert_invalid_parse(msg, "begin rescue; ensure; retry; end")
+ assert_parse("nil rescue retry")
+ assert_invalid_parse(msg, "END {retry}")
+ assert_invalid_parse(msg, "begin rescue; END {retry}; end")
+
+ assert_parse("!defined?(retry)")
+ assert_parse("def m; defined?(retry); end")
+ assert_parse("!begin defined?(retry); end")
+ assert_parse("begin rescue; else; defined?(retry); end")
+ assert_parse("begin rescue; ensure; defined?(retry); end")
+ assert_parse("END {defined?(retry)}")
+ assert_parse("begin rescue; END {defined?(retry)}; end")
+ assert_parse("!defined? retry")
+
+ assert_parse("def m; defined? retry; end")
+ assert_parse("!begin defined? retry; end")
+ assert_parse("begin rescue; else; defined? retry; end")
+ assert_parse("begin rescue; ensure; defined? retry; end")
+ assert_parse("END {defined? retry}")
+ assert_parse("begin rescue; END {defined? retry}; end")
+
+ assert_parse("#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ def foo
+ begin
+ yield
+ rescue StandardError => e
+ begin
+ puts "hi"
+ retry
+ rescue
+ retry unless e
+ raise e
+ else
+ retry
+ ensure
+ retry
+ end
+ end
+ end
+ end;
+ end
+
+ def test_invalid_yield
+ msg = /Invalid yield/
+ assert_invalid_parse(msg, "yield")
+ assert_invalid_parse(msg, "class C; yield; end")
+ assert_invalid_parse(msg, "BEGIN {yield}")
+ assert_invalid_parse(msg, "END {yield}")
+ assert_invalid_parse(msg, "-> {yield}")
+
+ assert_invalid_parse(msg, "yield true")
+ assert_invalid_parse(msg, "class C; yield true; end")
+ assert_invalid_parse(msg, "BEGIN {yield true}")
+ assert_invalid_parse(msg, "END {yield true}")
+ assert_invalid_parse(msg, "-> {yield true}")
+
+ assert_parse("!defined?(yield)")
+ assert_parse("class C; defined?(yield); end")
+ assert_parse("BEGIN {defined?(yield)}")
+ assert_parse("END {defined?(yield)}")
+
+ assert_parse("!defined?(yield true)")
+ assert_parse("class C; defined?(yield true); end")
+ assert_parse("BEGIN {defined?(yield true)}")
+ assert_parse("END {defined?(yield true)}")
+
+ assert_parse("!defined? yield")
+ assert_parse("class C; defined? yield; end")
+ assert_parse("BEGIN {defined? yield}")
+ assert_parse("END {defined? yield}")
+ end
+
+ def test_node_id_for_location
+ exception = begin
+ raise
+ rescue => e
+ e
+ end
+ loc = exception.backtrace_locations.first
+ node_id = RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(loc)
+ node = RubyVM::AbstractSyntaxTree.of(loc, keep_script_lines: true)
+
+ assert_equal node.node_id, node_id
+ end
+
+ def test_node_id_for_backtrace_location_raises_argument_error
+ bug19262 = '[ruby-core:111435]'
+
+ assert_raise(TypeError, bug19262) { RubyVM::AbstractSyntaxTree.node_id_for_backtrace_location(1) }
+ end
+
def test_of_proc_and_method
proc = Proc.new { 1 + 2 }
method = self.method(__method__)
@@ -419,7 +589,7 @@ class TestAst < Test::Unit::TestCase
assert_equal("foo", head)
assert_equal(:EVSTR, body.type)
body, = body.children
- assert_equal(:LIT, body.type)
+ assert_equal(:INTEGER, body.type)
assert_equal([1], body.children)
end
@@ -447,6 +617,30 @@ class TestAst < Test::Unit::TestCase
assert_not_equal(type1, type2)
end
+ def test_rest_arg
+ rest_arg = lambda do |arg_str|
+ node = RubyVM::AbstractSyntaxTree.parse("def a(#{arg_str}) end")
+ node = node.children.last.children.last.children[1].children[-4]
+ end
+
+ assert_equal(nil, rest_arg.call(''))
+ assert_equal(:r, rest_arg.call('*r'))
+ assert_equal(:r, rest_arg.call('a, *r'))
+ assert_equal(:*, rest_arg.call('*'))
+ assert_equal(:*, rest_arg.call('a, *'))
+ end
+
+ def test_block_arg
+ block_arg = lambda do |arg_str|
+ node = RubyVM::AbstractSyntaxTree.parse("def a(#{arg_str}) end")
+ node = node.children.last.children.last.children[1].children[-1]
+ end
+
+ assert_equal(nil, block_arg.call(''))
+ assert_equal(:block, block_arg.call('&block'))
+ assert_equal(:&, block_arg.call('&'))
+ end
+
def test_keyword_rest
kwrest = lambda do |arg_str|
node = RubyVM::AbstractSyntaxTree.parse("def a(#{arg_str}) end")
@@ -455,11 +649,21 @@ class TestAst < Test::Unit::TestCase
end
assert_equal(nil, kwrest.call(''))
- assert_equal([nil], kwrest.call('**'))
+ assert_equal([:**], kwrest.call('**'))
assert_equal(false, kwrest.call('**nil'))
assert_equal([:a], kwrest.call('**a'))
end
+ def test_argument_forwarding
+ forwarding = lambda do |arg_str|
+ node = RubyVM::AbstractSyntaxTree.parse("def a(#{arg_str}) end")
+ node = node.children.last.children.last.children[1]
+ node ? [node.children[-4], node.children[-2]&.children, node.children[-1]] : []
+ end
+
+ assert_equal([:*, [:**], :&], forwarding.call('...'))
+ end
+
def test_ranges_numbered_parameter
helper = Helper.new(__FILE__, src: "1.times {_1}")
helper.validate_range
@@ -542,6 +746,54 @@ dummy
assert_equal("def test_keep_script_lines_for_of\n", node_method.source.lines.first)
end
+ def test_keep_script_lines_for_of_with_existing_SCRIPT_LINES__that_has__FILE__as_a_key
+ # This test confirms that the bug that previously occurred because of
+ # `AbstractSyntaxTree.of`s unnecessary dependence on SCRIPT_LINES__ does not reproduce.
+ # The bug occurred only if SCRIPT_LINES__ included __FILE__ as a key.
+ lines = [
+ "SCRIPT_LINES__ = {__FILE__ => []}",
+ "puts RubyVM::AbstractSyntaxTree.of(->{ 1 + 2 }, keep_script_lines: true).script_lines",
+ "p SCRIPT_LINES__"
+ ]
+ test_stdout = lines + ['{"-e"=>[]}']
+ assert_in_out_err(["-e", lines.join("\n")], "", test_stdout, [])
+ end
+
+ def test_source_with_multibyte_characters
+ ast = RubyVM::AbstractSyntaxTree.parse(%{a("\u00a7");b("\u00a9")}, keep_script_lines: true)
+ a_fcall, b_fcall = ast.children[2].children
+
+ assert_equal(%{a("\u00a7")}, a_fcall.source)
+ assert_equal(%{b("\u00a9")}, b_fcall.source)
+ end
+
+ def test_keep_tokens_for_parse
+ node = RubyVM::AbstractSyntaxTree.parse(<<~END, keep_tokens: true)
+ 1.times do
+ end
+ __END__
+ dummy
+ END
+
+ expected = [
+ [:tINTEGER, "1"],
+ [:".", "."],
+ [:tIDENTIFIER, "times"],
+ [:tSP, " "],
+ [:keyword_do, "do"],
+ [:tIGNORED_NL, "\n"],
+ [:keyword_end, "end"],
+ [:nl, "\n"],
+ ]
+ assert_equal(expected, node.all_tokens.map { [_2, _3]})
+ end
+
+ def test_keep_tokens_unexpected_backslash
+ assert_raise_with_message(SyntaxError, /unexpected backslash/) do
+ RubyVM::AbstractSyntaxTree.parse("\\", keep_tokens: true)
+ end
+ end
+
def test_encoding_with_keep_script_lines
# Stop a warning "possibly useless use of a literal in void context"
verbose_bak, $VERBOSE = $VERBOSE, nil
@@ -565,4 +817,438 @@ dummy
assert_in_out_err(["-e", "def foo; end; pp RubyVM::AbstractSyntaxTree.of(method(:foo)).type"],
"", [":SCOPE"], [])
end
+
+ def test_error_tolerant
+ verbose_bak, $VERBOSE = $VERBOSE, false
+ node = RubyVM::AbstractSyntaxTree.parse(<<~STR, error_tolerant: true)
+ class A
+ def m
+ if;
+ a = 10
+ end
+ end
+ STR
+ assert_nil($!)
+
+ assert_equal(:SCOPE, node.type)
+ ensure
+ $VERBOSE = verbose_bak
+ end
+
+ def test_error_tolerant_end_is_short_for_method_define
+ assert_error_tolerant(<<~STR, <<~EXP)
+ def m
+ m2
+ STR
+ (SCOPE@1:0-2:4
+ tbl: []
+ args: nil
+ body:
+ (DEFN@1:0-2:4
+ mid: :m
+ body:
+ (SCOPE@1:0-2:4
+ tbl: []
+ args:
+ (ARGS@1:5-1:5
+ pre_num: 0
+ pre_init: nil
+ opt: nil
+ first_post: nil
+ post_num: 0
+ post_init: nil
+ rest: nil
+ kw: nil
+ kwrest: nil
+ block: nil)
+ body: (VCALL@2:2-2:4 :m2))))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_singleton_method_define
+ assert_error_tolerant(<<~STR, <<~EXP)
+ def obj.m
+ m2
+ STR
+ (SCOPE@1:0-2:4
+ tbl: []
+ args: nil
+ body:
+ (DEFS@1:0-2:4 (VCALL@1:4-1:7 :obj) :m
+ (SCOPE@1:0-2:4
+ tbl: []
+ args:
+ (ARGS@1:9-1:9
+ pre_num: 0
+ pre_init: nil
+ opt: nil
+ first_post: nil
+ post_num: 0
+ post_init: nil
+ rest: nil
+ kw: nil
+ kwrest: nil
+ block: nil)
+ body: (VCALL@2:2-2:4 :m2))))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_begin
+ assert_error_tolerant(<<~STR, <<~EXP)
+ begin
+ a = 1
+ STR
+ (SCOPE@1:0-2:7 tbl: [:a] args: nil body: (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1)))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_if
+ assert_error_tolerant(<<~STR, <<~EXP)
+ if cond
+ a = 1
+ STR
+ (SCOPE@1:0-2:7
+ tbl: [:a]
+ args: nil
+ body:
+ (IF@1:0-2:7 (VCALL@1:3-1:7 :cond) (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1))
+ nil))
+ EXP
+
+ assert_error_tolerant(<<~STR, <<~EXP)
+ if cond
+ a = 1
+ else
+ STR
+ (SCOPE@1:0-3:4
+ tbl: [:a]
+ args: nil
+ body:
+ (IF@1:0-3:4 (VCALL@1:3-1:7 :cond) (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1))
+ (BEGIN@3:4-3:4 nil)))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_unless
+ assert_error_tolerant(<<~STR, <<~EXP)
+ unless cond
+ a = 1
+ STR
+ (SCOPE@1:0-2:7
+ tbl: [:a]
+ args: nil
+ body:
+ (UNLESS@1:0-2:7 (VCALL@1:7-1:11 :cond) (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1))
+ nil))
+ EXP
+
+ assert_error_tolerant(<<~STR, <<~EXP)
+ unless cond
+ a = 1
+ else
+ STR
+ (SCOPE@1:0-3:4
+ tbl: [:a]
+ args: nil
+ body:
+ (UNLESS@1:0-3:4 (VCALL@1:7-1:11 :cond) (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1))
+ (BEGIN@3:4-3:4 nil)))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_while
+ assert_error_tolerant(<<~STR, <<~EXP)
+ while true
+ m
+ STR
+ (SCOPE@1:0-2:3
+ tbl: []
+ args: nil
+ body: (WHILE@1:0-2:3 (TRUE@1:6-1:10) (VCALL@2:2-2:3 :m) true))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_until
+ assert_error_tolerant(<<~STR, <<~EXP)
+ until true
+ m
+ STR
+ (SCOPE@1:0-2:3
+ tbl: []
+ args: nil
+ body: (UNTIL@1:0-2:3 (TRUE@1:6-1:10) (VCALL@2:2-2:3 :m) true))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_case
+ assert_error_tolerant(<<~STR, <<~EXP)
+ case a
+ when 1
+ STR
+ (SCOPE@1:0-2:6
+ tbl: []
+ args: nil
+ body:
+ (CASE@1:0-2:6 (VCALL@1:5-1:6 :a)
+ (WHEN@2:0-2:6 (LIST@2:5-2:6 (INTEGER@2:5-2:6 1) nil) (BEGIN@2:6-2:6 nil)
+ nil)))
+ EXP
+
+
+ assert_error_tolerant(<<~STR, <<~EXP)
+ case
+ when a == 1
+ STR
+ (SCOPE@1:0-2:11
+ tbl: []
+ args: nil
+ body:
+ (CASE2@1:0-2:11 nil
+ (WHEN@2:0-2:11
+ (LIST@2:5-2:11
+ (OPCALL@2:5-2:11 (VCALL@2:5-2:6 :a) :==
+ (LIST@2:10-2:11 (INTEGER@2:10-2:11 1) nil)) nil)
+ (BEGIN@2:11-2:11 nil) nil)))
+ EXP
+
+
+ assert_error_tolerant(<<~STR, <<~EXP)
+ case a
+ in {a: String}
+ STR
+ (SCOPE@1:0-2:14
+ tbl: []
+ args: nil
+ body:
+ (CASE3@1:0-2:14 (VCALL@1:5-1:6 :a)
+ (IN@2:0-2:14
+ (HSHPTN@2:4-2:13
+ const: nil
+ kw:
+ (HASH@2:4-2:13
+ (LIST@2:4-2:13 (SYM@2:4-2:6 :a) (CONST@2:7-2:13 :String) nil))
+ kwrest: nil) (BEGIN@2:14-2:14 nil) nil)))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_for
+ assert_error_tolerant(<<~STR, <<~EXP)
+ for i in ary
+ m
+ STR
+ (SCOPE@1:0-2:3
+ tbl: [:i]
+ args: nil
+ body:
+ (FOR@1:0-2:3 (VCALL@1:9-1:12 :ary)
+ (SCOPE@1:0-2:3
+ tbl: [nil]
+ args:
+ (ARGS@1:4-1:5
+ pre_num: 1
+ pre_init: (LASGN@1:4-1:5 :i (DVAR@1:4-1:5 nil))
+ opt: nil
+ first_post: nil
+ post_num: 0
+ post_init: nil
+ rest: nil
+ kw: nil
+ kwrest: nil
+ block: nil)
+ body: (VCALL@2:2-2:3 :m))))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_class
+ assert_error_tolerant(<<~STR, <<~EXP)
+ class C
+ STR
+ (SCOPE@1:0-1:7
+ tbl: []
+ args: nil
+ body:
+ (CLASS@1:0-1:7 (COLON2@1:6-1:7 nil :C) nil
+ (SCOPE@1:0-1:7 tbl: [] args: nil body: (BEGIN@1:7-1:7 nil))))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_module
+ assert_error_tolerant(<<~STR, <<~EXP)
+ module M
+ STR
+ (SCOPE@1:0-1:8
+ tbl: []
+ args: nil
+ body:
+ (MODULE@1:0-1:8 (COLON2@1:7-1:8 nil :M)
+ (SCOPE@1:0-1:8 tbl: [] args: nil body: (BEGIN@1:8-1:8 nil))))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_do
+ assert_error_tolerant(<<~STR, <<~EXP)
+ m do
+ a
+ STR
+ (SCOPE@1:0-2:3
+ tbl: []
+ args: nil
+ body:
+ (ITER@1:0-2:3 (FCALL@1:0-1:1 :m nil)
+ (SCOPE@1:2-2:3 tbl: [] args: nil body: (VCALL@2:2-2:3 :a))))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_do_block
+ assert_error_tolerant(<<~STR, <<~EXP)
+ m 1 do
+ a
+ STR
+ (SCOPE@1:0-2:3
+ tbl: []
+ args: nil
+ body:
+ (ITER@1:0-2:3 (FCALL@1:0-1:3 :m (LIST@1:2-1:3 (INTEGER@1:2-1:3 1) nil))
+ (SCOPE@1:4-2:3 tbl: [] args: nil body: (VCALL@2:2-2:3 :a))))
+ EXP
+ end
+
+ def test_error_tolerant_end_is_short_for_do_LAMBDA
+ assert_error_tolerant(<<~STR, <<~EXP)
+ -> do
+ a
+ STR
+ (SCOPE@1:0-2:3
+ tbl: []
+ args: nil
+ body:
+ (LAMBDA@1:0-2:3
+ (SCOPE@1:2-2:3
+ tbl: []
+ args:
+ (ARGS@1:2-1:2
+ pre_num: 0
+ pre_init: nil
+ opt: nil
+ first_post: nil
+ post_num: 0
+ post_init: nil
+ rest: nil
+ kw: nil
+ kwrest: nil
+ block: nil)
+ body: (VCALL@2:2-2:3 :a))))
+ EXP
+ end
+
+ def test_error_tolerant_treat_end_as_keyword_based_on_indent
+ assert_error_tolerant(<<~STR, <<~EXP)
+ module Z
+ class Foo
+ foo.
+ end
+
+ def bar
+ end
+ end
+ STR
+ (SCOPE@1:0-8:3
+ tbl: []
+ args: nil
+ body:
+ (MODULE@1:0-8:3 (COLON2@1:7-1:8 nil :Z)
+ (SCOPE@1:0-8:3
+ tbl: []
+ args: nil
+ body:
+ (BLOCK@1:8-7:5 (BEGIN@1:8-1:8 nil)
+ (CLASS@2:2-4:5 (COLON2@2:8-2:11 nil :Foo) nil
+ (SCOPE@2:2-4:5
+ tbl: []
+ args: nil
+ body: (BLOCK@2:11-4:5 (BEGIN@2:11-2:11 nil) (ERROR@3:4-4:5))))
+ (DEFN@6:2-7:5
+ mid: :bar
+ body:
+ (SCOPE@6:2-7:5
+ tbl: []
+ args:
+ (ARGS@6:9-6:9
+ pre_num: 0
+ pre_init: nil
+ opt: nil
+ first_post: nil
+ post_num: 0
+ post_init: nil
+ rest: nil
+ kw: nil
+ kwrest: nil
+ block: nil)
+ body: nil))))))
+ EXP
+ end
+
+ def test_error_tolerant_expr_value_can_be_error
+ assert_error_tolerant(<<~STR, <<~EXP)
+ def m
+ if
+ end
+ STR
+ (SCOPE@1:0-3:3
+ tbl: []
+ args: nil
+ body:
+ (DEFN@1:0-3:3
+ mid: :m
+ body:
+ (SCOPE@1:0-3:3
+ tbl: []
+ args:
+ (ARGS@1:5-1:5
+ pre_num: 0
+ pre_init: nil
+ opt: nil
+ first_post: nil
+ post_num: 0
+ post_init: nil
+ rest: nil
+ kw: nil
+ kwrest: nil
+ block: nil)
+ body: (IF@2:2-3:3 (ERROR@3:0-3:3) nil nil))))
+ EXP
+ end
+
+ def test_error_tolerant_unexpected_backslash
+ node = assert_error_tolerant("\\", <<~EXP, keep_tokens: true)
+ (SCOPE@1:0-1:1 tbl: [] args: nil body: (ERROR@1:0-1:1))
+ EXP
+ assert_equal([[0, :backslash, "\\", [1, 0, 1, 1]]], node.children.last.tokens)
+ end
+
+ def test_with_bom
+ assert_error_tolerant("\u{feff}nil", <<~EXP)
+ (SCOPE@1:0-1:3 tbl: [] args: nil body: (NIL@1:0-1:3))
+ EXP
+ end
+
+ def test_unused_block_local_variable
+ assert_warning('') do
+ RubyVM::AbstractSyntaxTree.parse(%{->(; foo) {}})
+ end
+ end
+
+ def assert_error_tolerant(src, expected, keep_tokens: false)
+ begin
+ verbose_bak, $VERBOSE = $VERBOSE, false
+ node = RubyVM::AbstractSyntaxTree.parse(src, error_tolerant: true, keep_tokens: keep_tokens)
+ ensure
+ $VERBOSE = verbose_bak
+ end
+ assert_nil($!)
+ str = ""
+ PP.pp(node, str, 80)
+ assert_equal(expected, str)
+ node
+ end
end
diff --git a/test/ruby/test_autoload.rb b/test/ruby/test_autoload.rb
index 1528fdd97a..1eb3551e57 100644
--- a/test/ruby/test_autoload.rb
+++ b/test/ruby/test_autoload.rb
@@ -65,6 +65,24 @@ p Foo::Bar
}
end
+ def test_autoload_p_with_static_extensions
+ require 'rbconfig'
+ omit unless RbConfig::CONFIG['EXTSTATIC'] == 'static'
+ begin
+ require 'fcntl.so'
+ rescue LoadError
+ omit('fcntl not included in the build')
+ end
+
+ assert_separately(['--disable-all'], <<~RUBY)
+ autoload :Fcntl, 'fcntl.so'
+
+ assert_equal('fcntl.so', autoload?(:Fcntl))
+ assert(Object.const_defined?(:Fcntl))
+ assert_equal('constant', defined?(Fcntl), '[Bug #19115]')
+ RUBY
+ end
+
def test_autoload_with_unqualified_file_name # [ruby-core:69206]
Object.send(:remove_const, :A) if Object.const_defined?(:A)
@@ -256,6 +274,11 @@ p Foo::Bar
end
def test_bug_13526
+ # Skip this on macOS 10.13 because of the following error:
+ # http://rubyci.s3.amazonaws.com/osx1013/ruby-master/log/20231011T014505Z.fail.html.gz
+ require "rbconfig"
+ omit if RbConfig::CONFIG["target_os"] == "darwin17"
+
script = File.join(__dir__, 'bug-13526.rb')
assert_ruby_status([script], '', '[ruby-core:81016] [Bug #13526]')
end
diff --git a/test/ruby/test_backtrace.rb b/test/ruby/test_backtrace.rb
index bb0562c0bb..cfc65faacb 100644
--- a/test/ruby/test_backtrace.rb
+++ b/test/ruby/test_backtrace.rb
@@ -215,15 +215,15 @@ class TestBacktrace < Test::Unit::TestCase
@res = caller_locations(2, 1).inspect
end
@line = __LINE__ + 1
- 1.times.map { 1.times.map { foo } }
- assert_equal("[\"#{__FILE__}:#{@line}:in `times'\"]", @res)
+ [1].map.map { [1].map.map { foo } }
+ assert_equal("[\"#{__FILE__}:#{@line}:in 'Array#map'\"]", @res)
end
def test_caller_location_path_cfunc_iseq_no_pc
def self.foo
@res = caller_locations(2, 1)[0].path
end
- 1.times.map { 1.times.map { foo } }
+ [1].map.map { [1].map.map { foo } }
assert_equal(__FILE__, @res)
end
@@ -292,13 +292,13 @@ class TestBacktrace < Test::Unit::TestCase
end
def test_caller_locations_label
- assert_equal("#{__method__}", caller_locations(0, 1)[0].label)
+ assert_equal("TestBacktrace##{__method__}", caller_locations(0, 1)[0].label)
loc, = tap {break caller_locations(0, 1)}
- assert_equal("block in #{__method__}", loc.label)
+ assert_equal("block in TestBacktrace##{__method__}", loc.label)
begin
raise
rescue
- assert_equal("rescue in #{__method__}", caller_locations(0, 1)[0].label)
+ assert_equal("TestBacktrace##{__method__}", caller_locations(0, 1)[0].label)
end
end
@@ -378,17 +378,17 @@ class TestBacktrace < Test::Unit::TestCase
def test_core_backtrace_hash_merge
e = assert_raise(TypeError) do
- {**nil}
+ {**1}
end
assert_not_match(/\Acore#/, e.backtrace_locations[0].base_label)
end
def test_notty_backtrace
- err = ["-:1:in `<main>': unhandled exception"]
+ err = ["-:1:in '<main>': unhandled exception"]
assert_in_out_err([], "raise", [], err)
- err = ["-:2:in `foo': foo! (RuntimeError)",
- "\tfrom -:4:in `<main>'"]
+ err = ["-:2:in 'Object#foo': foo! (RuntimeError)",
+ "\tfrom -:4:in '<main>'"]
assert_in_out_err([], <<-"end;", [], err)
def foo
raise "foo!"
@@ -396,12 +396,11 @@ class TestBacktrace < Test::Unit::TestCase
foo
end;
- err = ["-:7:in `rescue in bar': bar! (RuntimeError)",
- "\tfrom -:4:in `bar'",
- "\tfrom -:9:in `<main>'",
- "-:2:in `foo': foo! (RuntimeError)",
- "\tfrom -:5:in `bar'",
- "\tfrom -:9:in `<main>'"]
+ err = ["-:7:in 'Object#bar': bar! (RuntimeError)",
+ "\tfrom -:9:in '<main>'",
+ "-:2:in 'Object#foo': foo! (RuntimeError)",
+ "\tfrom -:5:in 'Object#bar'",
+ "\tfrom -:9:in '<main>'"]
assert_in_out_err([], <<-"end;", [], err)
def foo
raise "foo!"
@@ -416,7 +415,7 @@ class TestBacktrace < Test::Unit::TestCase
end
def test_caller_to_enum
- err = ["-:3:in `foo': unhandled exception", "\tfrom -:in `each'"]
+ err = ["-:3:in 'Object#foo': unhandled exception", "\tfrom -:in 'Enumerator#each'"]
assert_in_out_err([], <<-"end;", [], err, "[ruby-core:91911]")
def foo
return to_enum(__method__) unless block_given?
@@ -428,4 +427,23 @@ class TestBacktrace < Test::Unit::TestCase
enum.next
end;
end
+
+ def test_no_receiver_for_anonymous_class
+ err = ["-:2:in 'bar': unhandled exception", # Not '#<Class:0xXXX>.bar'
+ "\tfrom -:3:in '<main>'"]
+ assert_in_out_err([], <<-"end;", [], err)
+ foo = Class.new
+ def foo.bar = raise
+ foo.bar
+ end;
+
+ err = ["-:3:in 'baz': unhandled exception", # Not '#<Class:0xXXX>::Bar.baz'
+ "\tfrom -:4:in '<main>'"]
+ assert_in_out_err([], <<-"end;", [], err)
+ foo = Class.new
+ foo::Bar = Class.new
+ def (foo::Bar).baz = raise
+ foo::Bar.baz
+ end;
+ end
end
diff --git a/test/ruby/test_beginendblock.rb b/test/ruby/test_beginendblock.rb
index eb8394864f..3706efab52 100644
--- a/test/ruby/test_beginendblock.rb
+++ b/test/ruby/test_beginendblock.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: false
require 'test/unit'
+EnvUtil.suppress_warning {require 'continuation'}
class TestBeginEndBlock < Test::Unit::TestCase
DIR = File.dirname(File.expand_path(__FILE__))
@@ -14,6 +15,11 @@ class TestBeginEndBlock < Test::Unit::TestCase
assert_in_out_err(["-p", "-eBEGIN{p :begin}", "-eEND{p :end}"], "foo\nbar\n", %w(:begin foo bar :end))
end
+ def test_endblock_variable
+ assert_in_out_err(["-n", "-ea = :ok", "-eEND{p a}"], "foo\n", %w(:ok))
+ assert_in_out_err(["-p", "-ea = :ok", "-eEND{p a}"], "foo\n", %w(foo :ok))
+ end
+
def test_begininmethod
assert_raise_with_message(SyntaxError, /BEGIN is permitted only at toplevel/) do
eval("def foo; BEGIN {}; end")
@@ -40,9 +46,9 @@ class TestBeginEndBlock < Test::Unit::TestCase
end
def test_endblockwarn_in_eval
- assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", [], ['(eval):2: warning: END in method; use at_exit'])
+ assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", [], ['test.rb:1: warning: END in method; use at_exit'])
begin;
- eval <<-EOE
+ eval <<-EOE, nil, "test.rb", 0
def end2
END {}
end
@@ -62,7 +68,7 @@ class TestBeginEndBlock < Test::Unit::TestCase
bug8501 = '[ruby-core:55365] [Bug #8501]'
args = ['-e', 'o = Object.new; def o.inspect; raise "[Bug #8501]"; end',
'-e', 'at_exit{o.nope}']
- status = assert_in_out_err(args, '', [], /undefined method `nope'/, bug8501)
+ status = assert_in_out_err(args, '', [], /undefined method 'nope'/, bug8501)
assert_not_predicate(status, :success?, bug8501)
end
@@ -126,6 +132,8 @@ class TestBeginEndBlock < Test::Unit::TestCase
end
def test_callcc_at_exit
+ omit 'requires callcc support' unless respond_to?(:callcc)
+
bug9110 = '[ruby-core:58329][Bug #9110]'
assert_ruby_status([], "#{<<~"begin;"}\n#{<<~'end;'}", bug9110)
begin;
diff --git a/test/ruby/test_bignum.rb b/test/ruby/test_bignum.rb
index 065a944853..1f882c6cb9 100644
--- a/test/ruby/test_bignum.rb
+++ b/test/ruby/test_bignum.rb
@@ -207,7 +207,7 @@ class TestBignum < Test::Unit::TestCase
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
digits = [["3", 700], ["0", 2700], ["1", 1], ["0", 26599]]
- num = digits.inject("") {|s,(c,n)|s << c*n}.to_i
+ num = digits.inject(+"") {|s,(c,n)|s << c*n}.to_i
assert_equal digits.sum {|c,n|n}, num.to_s.size
end;
end
diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb
index 67b3a936d4..a52b75c267 100644
--- a/test/ruby/test_call.rb
+++ b/test/ruby/test_call.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: false
require 'test/unit'
+require '-test-/iter'
class TestCall < Test::Unit::TestCase
def aaa(a, b=100, *rest)
@@ -47,12 +48,19 @@ class TestCall < Test::Unit::TestCase
assert_equal(5, o.y)
o&.z ||= 6
assert_equal(6, o.z)
+ o&.z &&= 7
+ assert_equal(7, o.z)
o = nil
assert_nil(o&.x)
assert_nothing_raised(NoMethodError) {o&.x = raise}
+ assert_nothing_raised(NoMethodError) {o&.x = raise; nil}
assert_nothing_raised(NoMethodError) {o&.x *= raise}
assert_nothing_raised(NoMethodError) {o&.x *= raise; nil}
+ assert_nothing_raised(NoMethodError) {o&.x ||= raise}
+ assert_nothing_raised(NoMethodError) {o&.x ||= raise; nil}
+ assert_nothing_raised(NoMethodError) {o&.x &&= raise}
+ assert_nothing_raised(NoMethodError) {o&.x &&= raise; nil}
end
def test_safe_call_evaluate_arguments_only_method_call_is_made
@@ -92,6 +100,209 @@ class TestCall < Test::Unit::TestCase
}
end
+ def test_frozen_splat_and_keywords
+ a = [1, 2].freeze
+ def self.f(*a); a end
+ assert_equal([1, 2, {kw: 3}], f(*a, kw: 3))
+ end
+
+ def test_call_bmethod_proc
+ pr = proc{|sym| sym}
+ define_singleton_method(:a, &pr)
+ ary = [10]
+ assert_equal(10, a(*ary))
+ end
+
+ def test_call_bmethod_proc_restarg
+ pr = proc{|*sym| sym}
+ define_singleton_method(:a, &pr)
+ ary = [10]
+ assert_equal([10], a(*ary))
+ assert_equal([10], a(10))
+ end
+
+ def test_call_op_asgn_keywords
+ h = Class.new do
+ attr_reader :get, :set
+ def v; yield; [*@get, *@set] end
+ def [](*a, **b, &c) @get = [a, b, c]; @set = []; 3 end
+ def []=(*a, **b, &c) @set = [a, b, c] end
+ end.new
+
+ a = []
+ kw = {}
+ b = lambda{}
+
+ # Prevent "assigned but unused variable" warnings
+ _ = [h, a, kw, b]
+
+ message = /keyword arg given in index/
+
+ # +=, without block, non-popped
+ assert_syntax_error(%q{h[**kw] += 1}, message)
+ assert_syntax_error(%q{h[0, **kw] += 1}, message)
+ assert_syntax_error(%q{h[0, *a, **kw] += 1}, message)
+ assert_syntax_error(%q{h[kw: 5] += 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] += 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] += 1}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2] += 1}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] += 1}, message)
+
+ # +=, with block, non-popped
+ assert_syntax_error(%q{h[**kw, &b] += 1}, message)
+ assert_syntax_error(%q{h[0, **kw, &b] += 1}, message)
+ assert_syntax_error(%q{h[0, *a, **kw, &b] += 1}, message)
+ assert_syntax_error(%q{h[kw: 5, &b] += 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] += 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] += 1}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] += 1}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] += 1}, message)
+
+ # +=, without block, popped
+ assert_syntax_error(%q{h[**kw] += 1; nil}, message)
+ assert_syntax_error(%q{h[0, **kw] += 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, **kw] += 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5] += 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] += 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] += 1; nil}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2] += 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] += 1; nil}, message)
+
+ # +=, with block, popped
+ assert_syntax_error(%q{h[**kw, &b] += 1; nil}, message)
+ assert_syntax_error(%q{h[0, **kw, &b] += 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, **kw, &b] += 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, &b] += 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] += 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] += 1; nil}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] += 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] += 1; nil}, message)
+
+ # &&=, without block, non-popped
+ assert_syntax_error(%q{h[**kw] &&= 1}, message)
+ assert_syntax_error(%q{h[0, **kw] &&= 1}, message)
+ assert_syntax_error(%q{h[0, *a, **kw] &&= 1}, message)
+ assert_syntax_error(%q{h[kw: 5] &&= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] &&= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] &&= 1}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2] &&= 1}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] &&= 1}, message)
+
+ # &&=, with block, non-popped
+ assert_syntax_error(%q{h[**kw, &b] &&= 1}, message)
+ assert_syntax_error(%q{h[0, **kw, &b] &&= 1}, message)
+ assert_syntax_error(%q{h[0, *a, **kw, &b] &&= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, &b] &&= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] &&= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] &&= 1}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] &&= 1}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] &&= 1}, message)
+
+ # &&=, without block, popped
+ assert_syntax_error(%q{h[**kw] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[0, **kw] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, **kw] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] &&= 1; nil}, message)
+
+ # &&=, with block, popped
+ assert_syntax_error(%q{h[**kw, &b] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[0, **kw, &b] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, **kw, &b] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, &b] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] &&= 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] &&= 1; nil}, message)
+
+ # ||=, without block, non-popped
+ assert_syntax_error(%q{h[**kw] ||= 1}, message)
+ assert_syntax_error(%q{h[0, **kw] ||= 1}, message)
+ assert_syntax_error(%q{h[0, *a, **kw] ||= 1}, message)
+ assert_syntax_error(%q{h[kw: 5] ||= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] ||= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] ||= 1}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2] ||= 1}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] ||= 1}, message)
+
+ # ||=, with block, non-popped
+ assert_syntax_error(%q{h[**kw, &b] ||= 1}, message)
+ assert_syntax_error(%q{h[0, **kw, &b] ||= 1}, message)
+ assert_syntax_error(%q{h[0, *a, **kw, &b] ||= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, &b] ||= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] ||= 1}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] ||= 1}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] ||= 1}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] ||= 1}, message)
+
+ # ||=, without block, popped
+ assert_syntax_error(%q{h[**kw] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[0, **kw] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, **kw] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] ||= 1; nil}, message)
+
+ # ||=, with block, popped
+ assert_syntax_error(%q{h[**kw, &b] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[0, **kw, &b] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, **kw, &b] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, &b] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[kw: 5, a: 2, &b] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] ||= 1; nil}, message)
+ assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] ||= 1; nil}, message)
+
+ end
+
+ def test_kwsplat_block_order_op_asgn
+ o = Object.new
+ ary = []
+ o.define_singleton_method(:to_a) {ary << :to_a; []}
+ o.define_singleton_method(:to_hash) {ary << :to_hash; {}}
+ o.define_singleton_method(:to_proc) {ary << :to_proc; lambda{}}
+
+ def o.[](...) 2 end
+ def o.[]=(...) end
+
+ message = /keyword arg given in index/
+
+ assert_syntax_error(%q{o[kw: 1] += 1}, message)
+ assert_syntax_error(%q{o[**o] += 1}, message)
+ assert_syntax_error(%q{o[**o, &o] += 1}, message)
+ assert_syntax_error(%q{o[*o, **o, &o] += 1}, message)
+ end
+
+ def test_call_op_asgn_keywords_mutable
+ h = Class.new do
+ attr_reader :get, :set
+ def v; yield; [*@get, *@set] end
+ def [](*a, **b)
+ @get = [a.dup, b.dup]
+ a << :splat_modified
+ b[:kw_splat_modified] = true
+ @set = []
+ 3
+ end
+ def []=(*a, **b) @set = [a, b] end
+ end.new
+
+ message = /keyword arg given in index/
+
+ a = []
+ kw = {}
+
+ # Prevent "assigned but unused variable" warnings
+ _ = [h, a, kw]
+
+ assert_syntax_error(%q{h[*a, 2, b: 5, **kw] += 1}, message)
+ end
+
def test_call_splat_order
bug12860 = '[ruby-core:77701] [Bug# 12860]'
ary = [1, 2]
@@ -108,4 +319,1014 @@ class TestCall < Test::Unit::TestCase
ary = [1, 2, b]
assert_equal([0, 1, 2, b], aaa(0, *ary, &ary.pop), bug16504)
end
+
+ def test_call_args_splat_with_nonhash_keyword_splat
+ o = Object.new
+ def o.to_hash; {a: 1} end
+ def self.f(*a, **kw)
+ kw
+ end
+ assert_equal Hash, f(*[], **o).class
+ end
+
+ def test_kwsplat_block_order
+ o = Object.new
+ ary = []
+ o.define_singleton_method(:to_a) {ary << :to_a; []}
+ o.define_singleton_method(:to_hash) {ary << :to_hash; {}}
+ o.define_singleton_method(:to_proc) {ary << :to_proc; lambda{}}
+
+ def self.t(...) end
+
+ t(**o, &o)
+ assert_equal([:to_hash, :to_proc], ary)
+
+ ary.clear
+ t(*o, **o, &o)
+ assert_equal([:to_a, :to_hash, :to_proc], ary)
+ end
+
+ def test_kwsplat_block_order_super
+ def self.t(splat)
+ o = Object.new
+ ary = []
+ o.define_singleton_method(:to_a) {ary << :to_a; []}
+ o.define_singleton_method(:to_hash) {ary << :to_hash; {}}
+ o.define_singleton_method(:to_proc) {ary << :to_proc; lambda{}}
+ if splat
+ super(*o, **o, &o)
+ else
+ super(**o, &o)
+ end
+ ary
+ end
+ extend Module.new{def t(...) end}
+
+ assert_equal([:to_hash, :to_proc], t(false))
+ assert_equal([:to_a, :to_hash, :to_proc], t(true))
+ end
+
+ OVER_STACK_LEN = (ENV['RUBY_OVER_STACK_LEN'] || 150).to_i # Greater than VM_ARGC_STACK_MAX
+ OVER_STACK_ARGV = OVER_STACK_LEN.times.to_a.freeze
+
+ def test_call_cfunc_splat_large_array_bug_4040
+ a = OVER_STACK_ARGV
+
+ assert_equal(a, [].push(*a))
+ assert_equal(a, [].push(a[0], *a[1..]))
+ assert_equal(a, [].push(a[0], a[1], *a[2..]))
+ assert_equal(a, [].push(*a[0..1], *a[2..]))
+ assert_equal(a, [].push(*a[...-1], a[-1]))
+ assert_equal(a, [].push(a[0], *a[1...-1], a[-1]))
+ assert_equal(a, [].push(a[0], a[1], *a[2...-1], a[-1]))
+ assert_equal(a, [].push(*a[0..1], *a[2...-1], a[-1]))
+ assert_equal(a, [].push(*a[...-2], a[-2], a[-1]))
+ assert_equal(a, [].push(a[0], *a[1...-2], a[-2], a[-1]))
+ assert_equal(a, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1]))
+ assert_equal(a, [].push(*a[0..1], *a[2...-2], a[-2], a[-1]))
+
+ kw = {x: 1}
+ a_kw = a + [kw]
+
+ assert_equal(a_kw, [].push(*a, **kw))
+ assert_equal(a_kw, [].push(a[0], *a[1..], **kw))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2..], **kw))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2..], **kw))
+ assert_equal(a_kw, [].push(*a[...-1], a[-1], **kw))
+ assert_equal(a_kw, [].push(a[0], *a[1...-1], a[-1], **kw))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2...-1], a[-1], **kw))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2...-1], a[-1], **kw))
+ assert_equal(a_kw, [].push(*a[...-2], a[-2], a[-1], **kw))
+ assert_equal(a_kw, [].push(a[0], *a[1...-2], a[-2], a[-1], **kw))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1], **kw))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2...-2], a[-2], a[-1], **kw))
+
+ assert_equal(a_kw, [].push(*a, x: 1))
+ assert_equal(a_kw, [].push(a[0], *a[1..], x: 1))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2..], x: 1))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2..], x: 1))
+ assert_equal(a_kw, [].push(*a[...-1], a[-1], x: 1))
+ assert_equal(a_kw, [].push(a[0], *a[1...-1], a[-1], x: 1))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2...-1], a[-1], x: 1))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2...-1], a[-1], x: 1))
+ assert_equal(a_kw, [].push(*a[...-2], a[-2], a[-1], x: 1))
+ assert_equal(a_kw, [].push(a[0], *a[1...-2], a[-2], a[-1], x: 1))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1], x: 1))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2...-2], a[-2], a[-1], x: 1))
+
+ a_kw[-1][:y] = 2
+ kw = {y: 2}
+
+ assert_equal(a_kw, [].push(*a, x: 1, **kw))
+ assert_equal(a_kw, [].push(a[0], *a[1..], x: 1, **kw))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2..], x: 1, **kw))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2..], x: 1, **kw))
+ assert_equal(a_kw, [].push(*a[...-1], a[-1], x: 1, **kw))
+ assert_equal(a_kw, [].push(a[0], *a[1...-1], a[-1], x: 1, **kw))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2...-1], a[-1], x: 1, **kw))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2...-1], a[-1], x: 1, **kw))
+ assert_equal(a_kw, [].push(*a[...-2], a[-2], a[-1], x: 1, **kw))
+ assert_equal(a_kw, [].push(a[0], *a[1...-2], a[-2], a[-1], x: 1, **kw))
+ assert_equal(a_kw, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1], x: 1, **kw))
+ assert_equal(a_kw, [].push(*a[0..1], *a[2...-2], a[-2], a[-1], x: 1, **kw))
+
+ kw = {}
+
+ assert_equal(a, [].push(*a, **kw))
+ assert_equal(a, [].push(a[0], *a[1..], **kw))
+ assert_equal(a, [].push(a[0], a[1], *a[2..], **kw))
+ assert_equal(a, [].push(*a[0..1], *a[2..], **kw))
+ assert_equal(a, [].push(*a[...-1], a[-1], **kw))
+ assert_equal(a, [].push(a[0], *a[1...-1], a[-1], **kw))
+ assert_equal(a, [].push(a[0], a[1], *a[2...-1], a[-1], **kw))
+ assert_equal(a, [].push(*a[0..1], *a[2...-1], a[-1], **kw))
+ assert_equal(a, [].push(*a[...-2], a[-2], a[-1], **kw))
+ assert_equal(a, [].push(a[0], *a[1...-2], a[-2], a[-1], **kw))
+ assert_equal(a, [].push(a[0], a[1], *a[2...-2], a[-2], a[-1], **kw))
+ assert_equal(a, [].push(*a[0..1], *a[2...-2], a[-2], a[-1], **kw))
+
+ a_kw = a + [Hash.ruby2_keywords_hash({})]
+ assert_equal(a, [].push(*a_kw))
+
+ # Single test with value that would cause SystemStackError.
+ # Not all tests use such a large array to reduce testing time.
+ assert_equal(1380888, [].push(*1380888.times.to_a).size)
+ end
+
+ def test_call_iseq_large_array_splat_fail
+ def self.a; end
+ def self.b(a=1); end
+ def self.c(k: 1); end
+ def self.d(**kw); end
+ def self.e(k: 1, **kw); end
+ def self.f(a=1, k: 1); end
+ def self.g(a=1, **kw); end
+ def self.h(a=1, k: 1, **kw); end
+
+ (:a..:h).each do |meth|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ instance_eval("#{meth}(*OVER_STACK_ARGV)", __FILE__, __LINE__)
+ end
+ end
+ end
+
+ def test_call_iseq_large_array_splat_pass
+ def self.a(*a); a.length end
+ assert_equal OVER_STACK_LEN, a(*OVER_STACK_ARGV)
+
+ def self.b(_, *a); a.length end
+ assert_equal (OVER_STACK_LEN - 1), b(*OVER_STACK_ARGV)
+
+ def self.c(_, *a, _); a.length end
+ assert_equal (OVER_STACK_LEN - 2), c(*OVER_STACK_ARGV)
+
+ def self.d(b=1, *a); a.length end
+ assert_equal (OVER_STACK_LEN - 1), d(*OVER_STACK_ARGV)
+
+ def self.e(b=1, *a, _); a.length end
+ assert_equal (OVER_STACK_LEN - 2), e(*OVER_STACK_ARGV)
+
+ def self.f(b, *a); a.length end
+ assert_equal (OVER_STACK_LEN - 1), f(*OVER_STACK_ARGV)
+
+ def self.g(*a, k: 1); a.length end
+ assert_equal OVER_STACK_LEN, g(*OVER_STACK_ARGV)
+
+ def self.h(*a, **kw); a.length end
+ assert_equal OVER_STACK_LEN, h(*OVER_STACK_ARGV)
+
+ def self.i(*a, k: 1, **kw); a.length end
+ assert_equal OVER_STACK_LEN, i(*OVER_STACK_ARGV)
+
+ def self.j(b=1, *a, k: 1); a.length end
+ assert_equal (OVER_STACK_LEN - 1), j(*OVER_STACK_ARGV)
+
+ def self.k(b=1, *a, **kw); a.length end
+ assert_equal (OVER_STACK_LEN - 1), k(*OVER_STACK_ARGV)
+
+ def self.l(b=1, *a, k: 1, **kw); a.length end
+ assert_equal (OVER_STACK_LEN - 1), l(*OVER_STACK_ARGV)
+
+ def self.m(b=1, *a, _, k: 1); a.length end
+ assert_equal (OVER_STACK_LEN - 2), m(*OVER_STACK_ARGV)
+
+ def self.n(b=1, *a, _, **kw); a.length end
+ assert_equal (OVER_STACK_LEN - 2), n(*OVER_STACK_ARGV)
+
+ def self.o(b=1, *a, _, k: 1, **kw); a.length end
+ assert_equal (OVER_STACK_LEN - 2), o(*OVER_STACK_ARGV)
+ end
+
+ def test_call_iseq_large_array_splat_with_large_number_of_parameters
+ args = OVER_STACK_ARGV.map{|i| "a#{i}"}.join(',')
+ args1 = (OVER_STACK_LEN-1).times.map{|i| "a#{i}"}.join(',')
+
+ singleton_class.class_eval("def a(#{args}); [#{args}] end")
+ assert_equal OVER_STACK_ARGV, a(*OVER_STACK_ARGV)
+
+ singleton_class.class_eval("def b(#{args}, b=0); [#{args}, b] end")
+ assert_equal(OVER_STACK_ARGV + [0], b(*OVER_STACK_ARGV))
+
+ singleton_class.class_eval("def c(#{args}, *b); [#{args}, b] end")
+ assert_equal(OVER_STACK_ARGV + [[]], c(*OVER_STACK_ARGV))
+
+ singleton_class.class_eval("def d(#{args1}, *b); [#{args1}, b] end")
+ assert_equal(OVER_STACK_ARGV[0...-1] + [[OVER_STACK_ARGV.last]], d(*OVER_STACK_ARGV))
+ end if OVER_STACK_LEN < 200
+
+ def test_call_proc_large_array_splat_pass
+ [
+ proc{0} ,
+ proc{|a=1|a},
+ proc{|k: 1|0},
+ proc{|**kw| 0},
+ proc{|k: 1, **kw| 0},
+ proc{|a=1, k: 1| a},
+ proc{|a=1, **kw| a},
+ proc{|a=1, k: 1, **kw| a},
+ ].each do |l|
+ assert_equal 0, l.call(*OVER_STACK_ARGV)
+ end
+
+ assert_equal OVER_STACK_LEN, proc{|*a| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), proc{|_, *a| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), proc{|_, *a, _| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), proc{|b=1, *a, _| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a| a.length}.(*OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, proc{|*a, k: 1| a.length}.(*OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, proc{|*a, **kw| a.length}.(*OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, proc{|*a, k: 1, **kw| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a, k: 1| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a, **kw| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), proc{|b=1, *a, k: 1, **kw| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), proc{|b=1, *a, _, k: 1| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), proc{|b=1, *a, _, **kw| a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), proc{|b=1, *a, _, k: 1, **kw| a.length}.(*OVER_STACK_ARGV)
+ end
+
+ def test_call_proc_large_array_splat_with_large_number_of_parameters
+ args = OVER_STACK_ARGV.map{|i| "a#{i}"}.join(',')
+ args1 = (OVER_STACK_LEN-1).times.map{|i| "a#{i}"}.join(',')
+
+ l = instance_eval("proc{|#{args}| [#{args}]}")
+ assert_equal OVER_STACK_ARGV, l.(*OVER_STACK_ARGV)
+
+ l = instance_eval("proc{|#{args}, b| [#{args}, b]}")
+ assert_equal(OVER_STACK_ARGV + [nil], l.(*OVER_STACK_ARGV))
+
+ l = instance_eval("proc{|#{args1}| [#{args1}]}")
+ assert_equal(OVER_STACK_ARGV[0...-1], l.(*OVER_STACK_ARGV))
+
+ l = instance_eval("proc{|#{args}, *b| [#{args}, b]}")
+ assert_equal(OVER_STACK_ARGV + [[]], l.(*OVER_STACK_ARGV))
+
+ l = instance_eval("proc{|#{args1}, *b| [#{args1}, b]}")
+ assert_equal(OVER_STACK_ARGV[0...-1] + [[OVER_STACK_ARGV.last]], l.(*OVER_STACK_ARGV))
+
+ l = instance_eval("proc{|#{args}, b, *c| [#{args}, b, c]}")
+ assert_equal(OVER_STACK_ARGV + [nil, []], l.(*OVER_STACK_ARGV))
+
+ l = instance_eval("proc{|#{args}, b, *c, d| [#{args}, b, c, d]}")
+ assert_equal(OVER_STACK_ARGV + [nil, [], nil], l.(*OVER_STACK_ARGV))
+ end if OVER_STACK_LEN < 200
+
+ def test_call_lambda_large_array_splat_fail
+ [
+ ->{} ,
+ ->(a=1){},
+ ->(k: 1){},
+ ->(**kw){},
+ ->(k: 1, **kw){},
+ ->(a=1, k: 1){},
+ ->(a=1, **kw){},
+ ->(a=1, k: 1, **kw){},
+ ].each do |l|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ l.call(*OVER_STACK_ARGV)
+ end
+ end
+ end
+
+ def test_call_lambda_large_array_splat_pass
+ assert_equal OVER_STACK_LEN, ->(*a){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), ->(_, *a){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), ->(_, *a, _){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), ->(b=1, *a){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), ->(b=1, *a, _){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), ->(b, *a){a.length}.(*OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, ->(*a, k: 1){a.length}.(*OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, ->(*a, **kw){a.length}.(*OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, ->(*a, k: 1, **kw){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), ->(b=1, *a, k: 1){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), ->(b=1, *a, **kw){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 1), ->(b=1, *a, k: 1, **kw){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), ->(b=1, *a, _, k: 1){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), ->(b=1, *a, _, **kw){a.length}.(*OVER_STACK_ARGV)
+ assert_equal (OVER_STACK_LEN - 2), ->(b=1, *a, _, k: 1, **kw){a.length}.(*OVER_STACK_ARGV)
+ end
+
+ def test_call_yield_block_large_array_splat_pass
+ def self.a
+ yield(*OVER_STACK_ARGV)
+ end
+
+ [
+ proc{0} ,
+ proc{|a=1|a},
+ proc{|k: 1|0},
+ proc{|**kw| 0},
+ proc{|k: 1, **kw| 0},
+ proc{|a=1, k: 1| a},
+ proc{|a=1, **kw| a},
+ proc{|a=1, k: 1, **kw| a},
+ ].each do |l|
+ assert_equal 0, a(&l)
+ end
+
+ assert_equal OVER_STACK_LEN, a{|*a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), a{|_, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 2), a{|_, *a, _| a.length}
+ assert_equal (OVER_STACK_LEN - 1), a{|b=1, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 2), a{|b=1, *a, _| a.length}
+ assert_equal (OVER_STACK_LEN - 1), a{|b, *a| a.length}
+ assert_equal OVER_STACK_LEN, a{|*a, k: 1| a.length}
+ assert_equal OVER_STACK_LEN, a{|*a, **kw| a.length}
+ assert_equal OVER_STACK_LEN, a{|*a, k: 1, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 1), a{|b=1, *a, k: 1| a.length}
+ assert_equal (OVER_STACK_LEN - 1), a{|b=1, *a, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 1), a{|b=1, *a, k: 1, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 2), a{|b=1, *a, _, k: 1| a.length}
+ assert_equal (OVER_STACK_LEN - 2), a{|b=1, *a, _, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 2), a{|b=1, *a, _, k: 1, **kw| a.length}
+ end
+
+ def test_call_yield_large_array_splat_with_large_number_of_parameters
+ def self.a
+ yield(*OVER_STACK_ARGV)
+ end
+
+ args = OVER_STACK_ARGV.map{|i| "a#{i}"}.join(',')
+ args1 = (OVER_STACK_LEN-1).times.map{|i| "a#{i}"}.join(',')
+
+ assert_equal OVER_STACK_ARGV, instance_eval("a{|#{args}| [#{args}]}", __FILE__, __LINE__)
+ assert_equal(OVER_STACK_ARGV + [nil], instance_eval("a{|#{args}, b| [#{args}, b]}", __FILE__, __LINE__))
+ assert_equal(OVER_STACK_ARGV[0...-1], instance_eval("a{|#{args1}| [#{args1}]}", __FILE__, __LINE__))
+ assert_equal(OVER_STACK_ARGV + [[]], instance_eval("a{|#{args}, *b| [#{args}, b]}", __FILE__, __LINE__))
+ assert_equal(OVER_STACK_ARGV[0...-1] + [[OVER_STACK_ARGV.last]], instance_eval("a{|#{args1}, *b| [#{args1}, b]}", __FILE__, __LINE__))
+ assert_equal(OVER_STACK_ARGV + [nil, []], instance_eval("a{|#{args}, b, *c| [#{args}, b, c]}", __FILE__, __LINE__))
+ assert_equal(OVER_STACK_ARGV + [nil, [], nil], instance_eval("a{|#{args}, b, *c, d| [#{args}, b, c, d]}", __FILE__, __LINE__))
+ end if OVER_STACK_LEN < 200
+
+ def test_call_yield_lambda_large_array_splat_fail
+ def self.a
+ yield(*OVER_STACK_ARGV)
+ end
+ [
+ ->{} ,
+ ->(a=1){},
+ ->(k: 1){},
+ ->(**kw){},
+ ->(k: 1, **kw){},
+ ->(a=1, k: 1){},
+ ->(a=1, **kw){},
+ ->(a=1, k: 1, **kw){},
+ ].each do |l|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ a(&l)
+ end
+ end
+ end
+
+ def test_call_yield_lambda_large_array_splat_pass
+ def self.a
+ yield(*OVER_STACK_ARGV)
+ end
+
+ assert_equal OVER_STACK_LEN, a(&->(*a){a.length})
+ assert_equal (OVER_STACK_LEN - 1), a(&->(_, *a){a.length})
+ assert_equal (OVER_STACK_LEN - 2), a(&->(_, *a, _){a.length})
+ assert_equal (OVER_STACK_LEN - 1), a(&->(b=1, *a){a.length})
+ assert_equal (OVER_STACK_LEN - 2), a(&->(b=1, *a, _){a.length})
+ assert_equal (OVER_STACK_LEN - 1), a(&->(b, *a){a.length})
+ assert_equal OVER_STACK_LEN, a(&->(*a, k: 1){a.length})
+ assert_equal OVER_STACK_LEN, a(&->(*a, **kw){a.length})
+ assert_equal OVER_STACK_LEN, a(&->(*a, k: 1, **kw){a.length})
+ assert_equal (OVER_STACK_LEN - 1), a(&->(b=1, *a, k: 1){a.length})
+ assert_equal (OVER_STACK_LEN - 1), a(&->(b=1, *a, **kw){a.length})
+ assert_equal (OVER_STACK_LEN - 1), a(&->(b=1, *a, k: 1, **kw){a.length})
+ assert_equal (OVER_STACK_LEN - 2), a(&->(b=1, *a, _, k: 1){a.length})
+ assert_equal (OVER_STACK_LEN - 2), a(&->(b=1, *a, _, **kw){a.length})
+ assert_equal (OVER_STACK_LEN - 2), a(&->(b=1, *a, _, k: 1, **kw){a.length})
+ end
+
+ def test_call_send_iseq_large_array_splat_fail
+ def self.a; end
+ def self.b(a=1); end
+ def self.c(k: 1); end
+ def self.d(**kw); end
+ def self.e(k: 1, **kw); end
+ def self.f(a=1, k: 1); end
+ def self.g(a=1, **kw); end
+ def self.h(a=1, k: 1, **kw); end
+
+ (:a..:h).each do |meth|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ send(meth, *OVER_STACK_ARGV)
+ end
+ end
+ end
+
+ def test_call_send_iseq_large_array_splat_pass
+ def self.a(*a); a.length end
+ assert_equal OVER_STACK_LEN, send(:a, *OVER_STACK_ARGV)
+
+ def self.b(_, *a); a.length end
+ assert_equal (OVER_STACK_LEN - 1), send(:b, *OVER_STACK_ARGV)
+
+ def self.c(_, *a, _); a.length end
+ assert_equal (OVER_STACK_LEN - 2), send(:c, *OVER_STACK_ARGV)
+
+ def self.d(b=1, *a); a.length end
+ assert_equal (OVER_STACK_LEN - 1), send(:d, *OVER_STACK_ARGV)
+
+ def self.e(b=1, *a, _); a.length end
+ assert_equal (OVER_STACK_LEN - 2), send(:e, *OVER_STACK_ARGV)
+
+ def self.f(b, *a); a.length end
+ assert_equal (OVER_STACK_LEN - 1), send(:f, *OVER_STACK_ARGV)
+
+ def self.g(*a, k: 1); a.length end
+ assert_equal OVER_STACK_LEN, send(:g, *OVER_STACK_ARGV)
+
+ def self.h(*a, **kw); a.length end
+ assert_equal OVER_STACK_LEN, send(:h, *OVER_STACK_ARGV)
+
+ def self.i(*a, k: 1, **kw); a.length end
+ assert_equal OVER_STACK_LEN, send(:i, *OVER_STACK_ARGV)
+
+ def self.j(b=1, *a, k: 1); a.length end
+ assert_equal (OVER_STACK_LEN - 1), send(:j, *OVER_STACK_ARGV)
+
+ def self.k(b=1, *a, **kw); a.length end
+ assert_equal (OVER_STACK_LEN - 1), send(:k, *OVER_STACK_ARGV)
+
+ def self.l(b=1, *a, k: 1, **kw); a.length end
+ assert_equal (OVER_STACK_LEN - 1), send(:l, *OVER_STACK_ARGV)
+
+ def self.m(b=1, *a, _, k: 1); a.length end
+ assert_equal (OVER_STACK_LEN - 2), send(:m, *OVER_STACK_ARGV)
+
+ def self.n(b=1, *a, _, **kw); a.length end
+ assert_equal (OVER_STACK_LEN - 2), send(:n, *OVER_STACK_ARGV)
+
+ def self.o(b=1, *a, _, k: 1, **kw); a.length end
+ assert_equal (OVER_STACK_LEN - 2), send(:o, *OVER_STACK_ARGV)
+ end
+
+ def test_call_send_iseq_large_array_splat_with_large_number_of_parameters
+ args = OVER_STACK_ARGV.map{|i| "a#{i}"}.join(',')
+ args1 = (OVER_STACK_LEN-1).times.map{|i| "a#{i}"}.join(',')
+
+ singleton_class.class_eval("def a(#{args}); [#{args}] end")
+ assert_equal OVER_STACK_ARGV, send(:a, *OVER_STACK_ARGV)
+
+ singleton_class.class_eval("def b(#{args}, b=0); [#{args}, b] end")
+ assert_equal(OVER_STACK_ARGV + [0], send(:b, *OVER_STACK_ARGV))
+
+ singleton_class.class_eval("def c(#{args}, *b); [#{args}, b] end")
+ assert_equal(OVER_STACK_ARGV + [[]], send(:c, *OVER_STACK_ARGV))
+
+ singleton_class.class_eval("def d(#{args1}, *b); [#{args1}, b] end")
+ assert_equal(OVER_STACK_ARGV[0...-1] + [[OVER_STACK_ARGV.last]], send(:d, *OVER_STACK_ARGV))
+ end if OVER_STACK_LEN < 200
+
+ def test_call_send_cfunc_large_array_splat_fail
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ send(:object_id, *OVER_STACK_ARGV)
+ end
+ end
+
+ def test_call_send_cfunc_large_array_splat_pass
+ assert_equal OVER_STACK_LEN, [].send(:push, *OVER_STACK_ARGV).length
+ end
+
+ def test_call_attr_reader_large_array_splat_fail
+ singleton_class.send(:attr_reader, :a)
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ a(*OVER_STACK_ARGV)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ send(:a, *OVER_STACK_ARGV)
+ end
+ end
+
+ def test_call_attr_writer_large_array_splat_fail
+ singleton_class.send(:attr_writer, :a)
+ singleton_class.send(:alias_method, :a, :a=)
+
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
+ a(*OVER_STACK_ARGV)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
+ send(:a, *OVER_STACK_ARGV)
+ end
+ end
+
+ def test_call_struct_aref_large_array_splat_fail
+ s = Struct.new(:a).new
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ s.a(*OVER_STACK_ARGV)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ s.send(:a, *OVER_STACK_ARGV)
+ end
+ end
+
+ def test_call_struct_aset_large_array_splat_fail
+ s = Struct.new(:a) do
+ alias b a=
+ end.new
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
+ s.b(*OVER_STACK_ARGV)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
+ s.send(:b, *OVER_STACK_ARGV)
+ end
+ end
+
+ def test_call_alias_large_array_splat
+ c = Class.new do
+ def a; end
+ def c(*a); a.length end
+ attr_accessor :e
+ end
+ sc = Class.new(c) do
+ alias b a
+ alias d c
+ alias f e
+ alias g e=
+ end
+
+ obj = sc.new
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ obj.b(*OVER_STACK_ARGV)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ obj.f(*OVER_STACK_ARGV)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 1)") do
+ obj.g(*OVER_STACK_ARGV)
+ end
+
+ assert_equal OVER_STACK_LEN, obj.d(*OVER_STACK_ARGV)
+ end
+
+ def test_call_zsuper_large_array_splat
+ c = Class.new do
+ private
+ def a; end
+ def c(*a); a.length end
+ attr_reader :e
+ end
+ sc = Class.new(c) do
+ public :a
+ public :c
+ public :e
+ end
+
+ obj = sc.new
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ obj.a(*OVER_STACK_ARGV)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ obj.e(*OVER_STACK_ARGV)
+ end
+
+ assert_equal OVER_STACK_LEN, obj.c(*OVER_STACK_ARGV)
+ end
+
+ class RefinedModuleLargeArrayTest
+ c = self
+ using(Module.new do
+ refine c do
+ def a; end
+ def c(*a) a.length end
+ attr_reader :e
+ end
+ end)
+
+ def b
+ a(*OVER_STACK_ARGV)
+ end
+
+ def d
+ c(*OVER_STACK_ARGV)
+ end
+
+ def f
+ e(*OVER_STACK_ARGV)
+ end
+ end
+
+ def test_call_refined_large_array_splat_fail
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ RefinedModuleLargeArrayTest.new.b
+ end
+
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN}, expected 0)") do
+ RefinedModuleLargeArrayTest.new.f
+ end
+ end
+
+ def test_call_refined_large_array_splat_pass
+ assert_equal OVER_STACK_LEN, RefinedModuleLargeArrayTest.new.d
+ end
+
+ def test_call_method_missing_iseq_large_array_splat_fail
+ def self.method_missing(_) end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
+ nonexistent_method(*OVER_STACK_ARGV)
+ end
+
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
+ send(:nonexistent_method, *OVER_STACK_ARGV)
+ end
+
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
+ send("nonexistent_method123", *OVER_STACK_ARGV)
+ end
+ end
+
+ def test_call_method_missing_iseq_large_array_splat_pass
+ def self.method_missing(m, *a)
+ a.length
+ end
+ assert_equal OVER_STACK_LEN, nonexistent_method(*OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, send(:nonexistent_method, *OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, send("nonexistent_method123", *OVER_STACK_ARGV)
+ end
+
+ def test_call_bmethod_large_array_splat_fail
+ define_singleton_method(:a){}
+ define_singleton_method(:b){|a=1|}
+ define_singleton_method(:c){|k: 1|}
+ define_singleton_method(:d){|**kw|}
+ define_singleton_method(:e){|k: 1, **kw|}
+ define_singleton_method(:f){|a=1, k: 1|}
+ define_singleton_method(:g){|a=1, **kw|}
+ define_singleton_method(:h){|a=1, k: 1, **kw|}
+
+ (:a..:h).each do |meth|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ instance_eval("#{meth}(*OVER_STACK_ARGV)", __FILE__, __LINE__)
+ end
+ end
+ end
+
+ def test_call_bmethod_large_array_splat_pass
+ define_singleton_method(:a){|*a| a.length}
+ assert_equal OVER_STACK_LEN, a(*OVER_STACK_ARGV)
+
+ define_singleton_method(:b){|_, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), b(*OVER_STACK_ARGV)
+
+ define_singleton_method(:c){|_, *a, _| a.length}
+ assert_equal (OVER_STACK_LEN - 2), c(*OVER_STACK_ARGV)
+
+ define_singleton_method(:d){|b=1, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), d(*OVER_STACK_ARGV)
+
+ define_singleton_method(:e){|b=1, *a, _| a.length}
+ assert_equal (OVER_STACK_LEN - 2), e(*OVER_STACK_ARGV)
+
+ define_singleton_method(:f){|b, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), f(*OVER_STACK_ARGV)
+
+ define_singleton_method(:g){|*a, k: 1| a.length}
+ assert_equal OVER_STACK_LEN, g(*OVER_STACK_ARGV)
+
+ define_singleton_method(:h){|*a, **kw| a.length}
+ assert_equal OVER_STACK_LEN, h(*OVER_STACK_ARGV)
+
+ define_singleton_method(:i){|*a, k: 1, **kw| a.length}
+ assert_equal OVER_STACK_LEN, i(*OVER_STACK_ARGV)
+
+ define_singleton_method(:j){|b=1, *a, k: 1| a.length}
+ assert_equal (OVER_STACK_LEN - 1), j(*OVER_STACK_ARGV)
+
+ define_singleton_method(:k){|b=1, *a, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 1), k(*OVER_STACK_ARGV)
+
+ define_singleton_method(:l){|b=1, *a, k: 1, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 1), l(*OVER_STACK_ARGV)
+
+ define_singleton_method(:m){|b=1, *a, _, k: 1| a.length}
+ assert_equal (OVER_STACK_LEN - 2), m(*OVER_STACK_ARGV)
+
+ define_singleton_method(:n){|b=1, *a, _, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 2), n(*OVER_STACK_ARGV)
+
+ define_singleton_method(:o){|b=1, *a, _, k: 1, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 2), o(*OVER_STACK_ARGV)
+ end
+
+ def test_call_method_missing_bmethod_large_array_splat_fail
+ define_singleton_method(:method_missing){|_|}
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
+ nonexistent_method(*OVER_STACK_ARGV)
+ end
+
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
+ send(:nonexistent_method, *OVER_STACK_ARGV)
+ end
+
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given #{OVER_STACK_LEN+1}, expected 1)") do
+ send("nonexistent_method123", *OVER_STACK_ARGV)
+ end
+ end
+
+ def test_call_method_missing_bmethod_large_array_splat_pass
+ define_singleton_method(:method_missing){|_, *a| a.length}
+ assert_equal OVER_STACK_LEN, nonexistent_method(*OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, send(:nonexistent_method, *OVER_STACK_ARGV)
+ assert_equal OVER_STACK_LEN, send("nonexistent_method123", *OVER_STACK_ARGV)
+ end
+
+ def test_call_symproc_large_array_splat_fail
+ define_singleton_method(:a){}
+ define_singleton_method(:b){|a=1|}
+ define_singleton_method(:c){|k: 1|}
+ define_singleton_method(:d){|**kw|}
+ define_singleton_method(:e){|k: 1, **kw|}
+ define_singleton_method(:f){|a=1, k: 1|}
+ define_singleton_method(:g){|a=1, **kw|}
+ define_singleton_method(:h){|a=1, k: 1, **kw|}
+
+ (:a..:h).each do |meth|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ instance_eval(":#{meth}.to_proc.(self, *OVER_STACK_ARGV)", __FILE__, __LINE__)
+ end
+ end
+ end
+
+ def test_call_symproc_large_array_splat_pass
+ define_singleton_method(:a){|*a| a.length}
+ assert_equal OVER_STACK_LEN, :a.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:b){|_, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), :b.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:c){|_, *a, _| a.length}
+ assert_equal (OVER_STACK_LEN - 2), :c.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:d){|b=1, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), :d.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:e){|b=1, *a, _| a.length}
+ assert_equal (OVER_STACK_LEN - 2), :e.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:f){|b, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), :f.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:g){|*a, k: 1| a.length}
+ assert_equal OVER_STACK_LEN, :g.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:h){|*a, **kw| a.length}
+ assert_equal OVER_STACK_LEN, :h.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:i){|*a, k: 1, **kw| a.length}
+ assert_equal OVER_STACK_LEN, :i.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:j){|b=1, *a, k: 1| a.length}
+ assert_equal (OVER_STACK_LEN - 1), :j.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:k){|b=1, *a, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 1), :k.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:l){|b=1, *a, k: 1, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 1), :l.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:m){|b=1, *a, _, k: 1| a.length}
+ assert_equal (OVER_STACK_LEN - 2), :m.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:n){|b=1, *a, _, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 2), :n.to_proc.(self, *OVER_STACK_ARGV)
+
+ define_singleton_method(:o){|b=1, *a, _, k: 1, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 2), :o.to_proc.(self, *OVER_STACK_ARGV)
+ end
+
+ def test_call_rb_call_iseq_large_array_splat_fail
+ extend Bug::Iter::Yield
+ l = ->(*a){}
+
+ def self.a; end
+ def self.b(a=1) end
+ def self.c(k: 1) end
+ def self.d(**kw) end
+ def self.e(k: 1, **kw) end
+ def self.f(a=1, k: 1) end
+ def self.g(a=1, **kw) end
+ def self.h(a=1, k: 1, **kw) end
+
+ (:a..:h).each do |meth|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ yield_block(meth, *OVER_STACK_ARGV, &l)
+ end
+ end
+ end
+
+ def test_call_rb_call_iseq_large_array_splat_pass
+ extend Bug::Iter::Yield
+ l = ->(*a){a.length}
+
+ def self.a(*a) a.length end
+ assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ def self.b(_, *a) a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:b, *OVER_STACK_ARGV, &l)
+
+ def self.c(_, *a, _) a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:c, *OVER_STACK_ARGV, &l)
+
+ def self.d(b=1, *a) a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:d, *OVER_STACK_ARGV, &l)
+
+ def self.e(b=1, *a, _) a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:e, *OVER_STACK_ARGV, &l)
+
+ def self.f(b, *a) a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:f, *OVER_STACK_ARGV, &l)
+
+ def self.g(*a, k: 1) a.length end
+ assert_equal OVER_STACK_LEN, yield_block(:g, *OVER_STACK_ARGV, &l)
+
+ def self.h(*a, **kw) a.length end
+ assert_equal OVER_STACK_LEN, yield_block(:h, *OVER_STACK_ARGV, &l)
+
+ def self.i(*a, k: 1, **kw) a.length end
+ assert_equal OVER_STACK_LEN, yield_block(:h, *OVER_STACK_ARGV, &l)
+
+ def self.j(b=1, *a, k: 1) a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:j, *OVER_STACK_ARGV, &l)
+
+ def self.k(b=1, *a, **kw) a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:k, *OVER_STACK_ARGV, &l)
+
+ def self.l(b=1, *a, k: 1, **kw) a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:l, *OVER_STACK_ARGV, &l)
+
+ def self.m(b=1, *a, _, k: 1) a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:m, *OVER_STACK_ARGV, &l)
+
+ def self.n(b=1, *a, _, **kw) a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:n, *OVER_STACK_ARGV, &l)
+
+ def self.o(b=1, *a, _, k: 1, **kw) a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:o, *OVER_STACK_ARGV, &l)
+ end
+
+ def test_call_rb_call_bmethod_large_array_splat_fail
+ extend Bug::Iter::Yield
+ l = ->(*a){}
+
+ define_singleton_method(:a){||}
+ define_singleton_method(:b){|a=1|}
+ define_singleton_method(:c){|k: 1|}
+ define_singleton_method(:d){|**kw|}
+ define_singleton_method(:e){|k: 1, **kw|}
+ define_singleton_method(:f){|a=1, k: 1|}
+ define_singleton_method(:g){|a=1, **kw|}
+ define_singleton_method(:h){|a=1, k: 1, **kw|}
+
+ (:a..:h).each do |meth|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ yield_block(meth, *OVER_STACK_ARGV, &l)
+ end
+ end
+ end
+
+ def test_call_rb_call_bmethod_large_array_splat_pass
+ extend Bug::Iter::Yield
+ l = ->(*a){a.length}
+
+ define_singleton_method(:a){|*a| a.length}
+ assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:b){|_, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:b, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:c){|_, *a, _| a.length}
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:c, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:d){|b=1, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:d, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:e){|b=1, *a, _| a.length}
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:e, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:f){|b, *a| a.length}
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:f, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:g){|*a, k: 1| a.length}
+ assert_equal OVER_STACK_LEN, yield_block(:g, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:h){|*a, **kw| a.length}
+ assert_equal OVER_STACK_LEN, yield_block(:h, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:i){|*a, k: 1, **kw| a.length}
+ assert_equal OVER_STACK_LEN, yield_block(:h, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:j){|b=1, *a, k: 1| a.length}
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:j, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:k){|b=1, *a, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:k, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:l){|b=1, *a, k: 1, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:l, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:m){|b=1, *a, _, k: 1| a.length}
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:m, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:n){|b=1, *a, _, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:n, *OVER_STACK_ARGV, &l)
+
+ define_singleton_method(:o){|b=1, *a, _, k: 1, **kw| a.length}
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:o, *OVER_STACK_ARGV, &l)
+ end
+
+ def test_call_ifunc_iseq_large_array_splat_fail
+ extend Bug::Iter::Yield
+ def self.a(*a)
+ yield(*a)
+ end
+ [
+ ->(){},
+ ->(a=1){},
+ ->(k: 1){},
+ ->(**kw){},
+ ->(k: 1, **kw){},
+ ->(a=1, k: 1){},
+ ->(a=1, **kw){},
+ ->(a=1, k: 1, **kw){},
+ ].each do |l|
+ assert_raise_with_message(ArgumentError, /wrong number of arguments \(given #{OVER_STACK_LEN}, expected 0(\.\.[12])?\)/) do
+ yield_block(:a, *OVER_STACK_ARGV, &l)
+ end
+ end
+ end
+
+ def test_call_ifunc_iseq_large_array_splat_pass
+ extend Bug::Iter::Yield
+ def self.a(*a)
+ yield(*a)
+ end
+
+ l = ->(*a) do a.length end
+ assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(_, *a) do a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(_, *a, _) do a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b=1, *a) do a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b=1, *a, _) do a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b, *a) do a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(*a, k: 1) do a.length end
+ assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(*a, **kw) do a.length end
+ assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(*a, k: 1, **kw) do a.length end
+ assert_equal OVER_STACK_LEN, yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b=1, *a, k: 1) do a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b=1, *a, **kw) do a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b=1, *a, k: 1, **kw) do a.length end
+ assert_equal (OVER_STACK_LEN - 1), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b=1, *a, _, k: 1) do a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b=1, *a, _, **kw) do a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
+
+ l = ->(b=1, *a, _, k: 1, **kw) do a.length end
+ assert_equal (OVER_STACK_LEN - 2), yield_block(:a, *OVER_STACK_ARGV, &l)
+ end
end
diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb
index 07c34ce9d5..710b8a6f7b 100644
--- a/test/ruby/test_class.rb
+++ b/test/ruby/test_class.rb
@@ -96,6 +96,13 @@ class TestClass < Test::Unit::TestCase
def test_superclass_of_basicobject
assert_equal(nil, BasicObject.superclass)
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ module Mod end
+ BasicObject.include(Mod)
+ assert_equal(nil, BasicObject.superclass)
+ end;
end
def test_module_function
@@ -355,6 +362,17 @@ class TestClass < Test::Unit::TestCase
assert_equal(42, PrivateClass.new.foo)
end
+ def test_private_const_access
+ assert_raise_with_message NameError, /uninitialized/ do
+ begin
+ eval('class ::TestClass::PrivateClass; end')
+ rescue NameError
+ end
+
+ Object.const_get "NOT_AVAILABLE_CONST_NAME_#{__LINE__}"
+ end
+ end
+
StrClone = String.clone
Class.new(StrClone)
@@ -759,6 +777,31 @@ class TestClass < Test::Unit::TestCase
end
end
+ def test_attached_object
+ c = Class.new
+ sc = c.singleton_class
+ obj = c.new
+
+ assert_equal(obj, obj.singleton_class.attached_object)
+ assert_equal(c, sc.attached_object)
+
+ assert_raise_with_message(TypeError, /is not a singleton class/) do
+ c.attached_object
+ end
+
+ assert_raise_with_message(TypeError, /'NilClass' is not a singleton class/) do
+ nil.singleton_class.attached_object
+ end
+
+ assert_raise_with_message(TypeError, /'FalseClass' is not a singleton class/) do
+ false.singleton_class.attached_object
+ end
+
+ assert_raise_with_message(TypeError, /'TrueClass' is not a singleton class/) do
+ true.singleton_class.attached_object
+ end
+ end
+
def test_subclass_gc
c = Class.new
10_000.times do
@@ -784,4 +827,13 @@ PREP
3_000_000.times(&code)
CODE
end
+
+ def test_instance_freeze_dont_freeze_the_class_bug_19164
+ klass = Class.new
+ klass.prepend(Module.new)
+
+ klass.new.freeze
+ klass.define_method(:bar) {}
+ assert_equal klass, klass.remove_method(:bar), '[Bug #19164]'
+ end
end
diff --git a/test/ruby/test_clone.rb b/test/ruby/test_clone.rb
index 216eaa39d2..775c9ed848 100644
--- a/test/ruby/test_clone.rb
+++ b/test/ruby/test_clone.rb
@@ -73,6 +73,13 @@ class TestClone < Test::Unit::TestCase
assert_equal(cloned_obj.instance_variable_get(:@a), 1)
end
+ def test_proc_obj_id_flag_reset
+ # [Bug #20250]
+ proc = Proc.new { }
+ proc.object_id
+ proc.clone.object_id # Would crash with RUBY_DEBUG=1
+ end
+
def test_user_flags
assert_separately([], <<-EOS)
#
diff --git a/test/ruby/test_comparable.rb b/test/ruby/test_comparable.rb
index b849217b7d..b689469d9e 100644
--- a/test/ruby/test_comparable.rb
+++ b/test/ruby/test_comparable.rb
@@ -85,7 +85,13 @@ class TestComparable < Test::Unit::TestCase
assert_equal(1, @o.clamp(1, 1))
assert_equal(@o, @o.clamp(0, 0))
- assert_raise_with_message(ArgumentError, 'min argument must be smaller than max argument') {
+ assert_equal(@o, @o.clamp(nil, 2))
+ assert_equal(-2, @o.clamp(nil, -2))
+ assert_equal(@o, @o.clamp(-2, nil))
+ assert_equal(2, @o.clamp(2, nil))
+ assert_equal(@o, @o.clamp(nil, nil))
+
+ assert_raise_with_message(ArgumentError, 'min argument must be less than or equal to max argument') {
@o.clamp(2, 1)
}
end
@@ -115,7 +121,7 @@ class TestComparable < Test::Unit::TestCase
assert_raise_with_message(*exc) {@o.clamp(-1...0)}
assert_raise_with_message(*exc) {@o.clamp(...2)}
- assert_raise_with_message(ArgumentError, 'min argument must be smaller than max argument') {
+ assert_raise_with_message(ArgumentError, 'min argument must be less than or equal to max argument') {
@o.clamp(2..1)
}
end
diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb
new file mode 100644
index 0000000000..d13b150f93
--- /dev/null
+++ b/test/ruby/test_compile_prism.rb
@@ -0,0 +1,2671 @@
+# frozen_string_literal: true
+
+# This file is organized to match itemization in https://github.com/ruby/prism/issues/1335
+module Prism
+ class TestCompilePrism < Test::Unit::TestCase
+ # Subclass is used for tests which need it
+ class Subclass; end
+ ############################################################################
+ # Literals #
+ ############################################################################
+
+ def test_FalseNode
+ assert_prism_eval("false")
+ end
+
+ def test_FloatNode
+ assert_prism_eval("1.2")
+ assert_prism_eval("1.2e3")
+ assert_prism_eval("+1.2e+3")
+ assert_prism_eval("-1.2e-3")
+ end
+
+ def test_ImaginaryNode
+ assert_prism_eval("1i")
+ assert_prism_eval("+1.0i")
+ assert_prism_eval("1ri")
+ end
+
+ def test_IntegerNode
+ assert_prism_eval("1")
+ assert_prism_eval("+1")
+ assert_prism_eval("-1")
+ assert_prism_eval("0x10")
+ assert_prism_eval("0b10")
+ assert_prism_eval("0o10")
+ assert_prism_eval("010")
+ assert_prism_eval("(0o00)")
+ end
+
+ def test_NilNode
+ assert_prism_eval("nil")
+ end
+
+ def test_RationalNode
+ assert_prism_eval("1.2r")
+ assert_prism_eval("+1.2r")
+ end
+
+ def test_SelfNode
+ assert_prism_eval("self")
+ end
+
+ def test_SourceEncodingNode
+ assert_prism_eval("__ENCODING__")
+ end
+
+ def test_SourceFileNode
+ assert_prism_eval("__FILE__")
+ end
+
+ def test_SourceLineNode
+ assert_prism_eval("__LINE__", raw: true)
+ end
+
+ def test_TrueNode
+ assert_prism_eval("true")
+ end
+
+ ############################################################################
+ # Reads #
+ ############################################################################
+
+ def test_BackReferenceReadNode
+ assert_prism_eval("$+")
+ end
+
+ def test_ClassVariableReadNode
+ assert_prism_eval("class Prism::TestCompilePrism; @@pit = 1; @@pit; end")
+ end
+
+ def test_ConstantPathNode
+ assert_prism_eval("Prism::TestCompilePrism")
+ end
+
+ def test_ConstantReadNode
+ assert_prism_eval("Prism")
+ end
+
+ Z = 1
+
+ def test_DefinedNode
+ assert_prism_eval("defined? nil")
+ assert_prism_eval("defined? self")
+ assert_prism_eval("defined? true")
+ assert_prism_eval("defined? false")
+ assert_prism_eval("defined? 1")
+ assert_prism_eval("defined? 1i")
+ assert_prism_eval("defined? 1.0")
+ assert_prism_eval("defined? 1..2")
+ assert_prism_eval("defined? [A, B, C]")
+ assert_prism_eval("defined? [1, 2, 3]")
+ assert_prism_eval("defined?({ a: 1 })")
+ assert_prism_eval("defined? 'str'")
+ assert_prism_eval('defined?("#{expr}")')
+ assert_prism_eval("defined? :sym")
+ assert_prism_eval("defined? /foo/")
+ assert_prism_eval('defined?(/#{1}/)')
+ assert_prism_eval("defined? -> { 1 + 1 }")
+ assert_prism_eval("defined? a && b")
+ assert_prism_eval("defined? a || b")
+ assert_prism_eval("defined? __ENCODING__")
+ assert_prism_eval("defined? __FILE__")
+ assert_prism_eval("defined? __LINE__")
+
+ assert_prism_eval("defined? %[1,2,3]")
+ assert_prism_eval("defined? %q[1,2,3]")
+ assert_prism_eval("defined? %Q[1,2,3]")
+ assert_prism_eval("defined? %r[1,2,3]")
+ assert_prism_eval("defined? %i[1,2,3]")
+ assert_prism_eval("defined? %I[1,2,3]")
+ assert_prism_eval("defined? %w[1,2,3]")
+ assert_prism_eval("defined? %W[1,2,3]")
+ assert_prism_eval("defined? %s[1,2,3]")
+ assert_prism_eval("defined? %x[1,2,3]")
+
+ assert_prism_eval("defined? [*b]")
+ assert_prism_eval("defined? [[*1..2], 3, *4..5]")
+ assert_prism_eval("defined? [a: [:b, :c]]")
+ assert_prism_eval("defined? 1 in 1")
+
+ assert_prism_eval("defined? @a")
+ assert_prism_eval("defined? $a")
+ assert_prism_eval("defined? @@a")
+ assert_prism_eval("defined? A")
+ assert_prism_eval("defined? ::A")
+ assert_prism_eval("defined? A::B")
+ assert_prism_eval("defined? A::B::C")
+ assert_prism_eval("defined? #{self.class.name}::Z::A")
+ assert_prism_eval("defined? yield")
+ assert_prism_eval("defined? super")
+
+ assert_prism_eval("defined? X = 1")
+ assert_prism_eval("defined? X *= 1")
+ assert_prism_eval("defined? X /= 1")
+ assert_prism_eval("defined? X &= 1")
+ assert_prism_eval("defined? X ||= 1")
+
+ assert_prism_eval("defined? $1")
+ assert_prism_eval("defined? $2")
+ assert_prism_eval("defined? $`")
+ assert_prism_eval("defined? $'")
+ assert_prism_eval("defined? $+")
+
+ assert_prism_eval("defined? $X = 1")
+ assert_prism_eval("defined? $X *= 1")
+ assert_prism_eval("defined? $X /= 1")
+ assert_prism_eval("defined? $X &= 1")
+ assert_prism_eval("defined? $X ||= 1")
+
+ assert_prism_eval("defined? @@X = 1")
+ assert_prism_eval("defined? @@X *= 1")
+ assert_prism_eval("defined? @@X /= 1")
+ assert_prism_eval("defined? @@X &= 1")
+ assert_prism_eval("defined? @@X ||= 1")
+
+ assert_prism_eval("defined? @X = 1")
+ assert_prism_eval("defined? @X *= 1")
+ assert_prism_eval("defined? @X /= 1")
+ assert_prism_eval("defined? @X &= 1")
+ assert_prism_eval("defined? @X ||= 1")
+
+ assert_prism_eval("x = 1; defined? x = 1")
+ assert_prism_eval("x = 1; defined? x *= 1")
+ assert_prism_eval("x = 1; defined? x /= 1")
+ assert_prism_eval("x = 1; defined? x &= 1")
+ assert_prism_eval("x = 1; defined? x ||= 1")
+
+ assert_prism_eval("if defined? A; end")
+
+ assert_prism_eval("defined?(())")
+ assert_prism_eval("defined?(('1'))")
+
+ # method chain starting with self that's truthy
+ assert_prism_eval("defined?(self.itself.itself.itself)")
+
+ # method chain starting with self that's false (exception swallowed)
+ assert_prism_eval("defined?(self.itself.itself.neat)")
+
+ # single self with method, truthy
+ assert_prism_eval("defined?(self.itself)")
+
+ # single self with method, false
+ assert_prism_eval("defined?(self.neat!)")
+
+ # method chain implicit self that's truthy
+ assert_prism_eval("defined?(itself.itself.itself)")
+
+ # method chain implicit self that's false
+ assert_prism_eval("defined?(itself.neat.itself)")
+
+ ## single method implicit self that's truthy
+ assert_prism_eval("defined?(itself)")
+
+ ## single method implicit self that's false
+ assert_prism_eval("defined?(neatneat)")
+
+ assert_prism_eval("defined?(a(itself))")
+ assert_prism_eval("defined?(itself(itself))")
+
+ # Method chain on a constant
+ assert_prism_eval(<<~RUBY)
+ class PrismDefinedNode
+ def m1; end
+ end
+
+ defined?(PrismDefinedNode.new.m1)
+ RUBY
+
+ assert_prism_eval("defined?(next)")
+ assert_prism_eval("defined?(break)")
+ assert_prism_eval("defined?(redo)")
+ assert_prism_eval("defined?(retry)")
+
+ assert_prism_eval(<<~RUBY)
+ class PrismDefinedReturnNode
+ def self.m1; defined?(return) end
+ end
+
+ PrismDefinedReturnNode.m1
+ RUBY
+
+ assert_prism_eval("defined?(begin; 1; end)")
+
+ assert_prism_eval("defined?(defined?(a))")
+ assert_prism_eval('defined?(:"#{1}")')
+ assert_prism_eval("defined?(`echo #{1}`)")
+
+ assert_prism_eval("defined?(PrismTestSubclass.test_call_and_write_node &&= 1)")
+ assert_prism_eval("defined?(PrismTestSubclass.test_call_operator_write_node += 1)")
+ assert_prism_eval("defined?(PrismTestSubclass.test_call_or_write_node ||= 1)")
+ assert_prism_eval("defined?(Prism::CPAWN &&= 1)")
+ assert_prism_eval("defined?(Prism::CPOWN += 1)")
+ assert_prism_eval("defined?(Prism::CPOrWN ||= 1)")
+ assert_prism_eval("defined?(Prism::CPWN = 1)")
+ assert_prism_eval("defined?([0][0] &&= 1)")
+ assert_prism_eval("defined?([0][0] += 1)")
+ assert_prism_eval("defined?([0][0] ||= 1)")
+
+ assert_prism_eval("defined?(case :a; when :a; 1; else; 2; end)")
+ assert_prism_eval("defined?(case [1, 2, 3]; in [1, 2, 3]; 4; end)")
+ assert_prism_eval("defined?(class PrismClassA; end)")
+ assert_prism_eval("defined?(def prism_test_def_node; end)")
+ assert_prism_eval("defined?(for i in [1,2] do; i; end)")
+ assert_prism_eval("defined?(if true; 1; end)")
+ assert_prism_eval("defined?(/(?<foo>bar)/ =~ 'barbar')")
+ assert_prism_eval("defined?(1 => 1)")
+ assert_prism_eval("defined?(module M; end)")
+ assert_prism_eval("defined?(1.2r)")
+ assert_prism_eval("defined?(class << self; end)")
+ assert_prism_eval("defined?(while a != 1; end)")
+ assert_prism_eval("defined?(until a == 1; end)")
+ assert_prism_eval("defined?(unless true; 1; end)")
+ end
+
+ def test_GlobalVariableReadNode
+ assert_prism_eval("$pit = 1; $pit")
+ end
+
+ def test_InstanceVariableReadNode
+ assert_prism_eval("class Prism::TestCompilePrism; @pit = 1; @pit; end")
+ end
+
+ def test_LocalVariableReadNode
+ assert_prism_eval("pit = 1; pit")
+ end
+
+ def test_NumberedReferenceReadNode
+ assert_prism_eval("$1")
+ assert_prism_eval("$99999")
+ end
+
+ ############################################################################
+ # Writes #
+ ############################################################################
+
+ def test_ClassVariableAndWriteNode
+ assert_prism_eval("class Prism::TestCompilePrism; @@pit = 0; @@pit &&= 1; end")
+ end
+
+ def test_ClassVariableOperatorWriteNode
+ assert_prism_eval("class Prism::TestCompilePrism; @@pit = 0; @@pit += 1; end")
+ end
+
+ def test_ClassVariableOrWriteNode
+ assert_prism_eval("class Prism::TestCompilePrism; @@pit = 1; @@pit ||= 0; end")
+ assert_prism_eval("class Prism::TestCompilePrism; @@pit = nil; @@pit ||= 1; end")
+ end
+
+ def test_ClassVariableWriteNode
+ assert_prism_eval("class Prism::TestCompilePrism; @@pit = 1; end")
+ end
+
+ def test_ConstantAndWriteNode
+ assert_prism_eval("Constant = 1; Constant &&= 1")
+ end
+
+ def test_ConstantOperatorWriteNode
+ assert_prism_eval("Constant = 1; Constant += 1")
+ end
+
+ def test_ConstantOrWriteNode
+ assert_prism_eval("Constant = 1; Constant ||= 1")
+ end
+
+ def test_ConstantWriteNode
+ # We don't call assert_prism_eval directly in this case because we
+ # don't want to assign the constant multiple times if we run
+ # with `--repeat-count`
+ # Instead, we eval manually here, and remove the constant to
+ constant_name = "YCT"
+ source = "#{constant_name} = 1"
+ prism_eval = RubyVM::InstructionSequence.compile_prism(source).eval
+ assert_equal prism_eval, 1
+ Object.send(:remove_const, constant_name)
+ end
+
+ def test_ConstantPathWriteNode
+ assert_prism_eval("Prism::CPWN = 1")
+ assert_prism_eval("::CPWN = 1")
+ end
+
+ def test_ConstantPathAndWriteNode
+ assert_prism_eval("Prism::CPAWN = 1; Prism::CPAWN &&= 2")
+ assert_prism_eval("Prism::CPAWN &&= 1")
+ assert_prism_eval("::CPAWN = 1; ::CPAWN &&= 2")
+ end
+
+ def test_ConstantPathOrWriteNode
+ assert_prism_eval("Prism::CPOrWN = nil; Prism::CPOrWN ||= 1")
+ assert_prism_eval("Prism::CPOrWN ||= 1")
+ assert_prism_eval("::CPOrWN = nil; ::CPOrWN ||= 1")
+ end
+
+ def test_ConstantPathOperatorWriteNode
+ assert_prism_eval("Prism::CPOWN = 0; Prism::CPOWN += 1")
+ assert_prism_eval("::CPOWN = 0; ::CPOWN += 1")
+ end
+
+ def test_GlobalVariableAndWriteNode
+ assert_prism_eval("$pit = 0; $pit &&= 1")
+ end
+
+ def test_GlobalVariableOperatorWriteNode
+ assert_prism_eval("$pit = 0; $pit += 1")
+ end
+
+ def test_GlobalVariableOrWriteNode
+ assert_prism_eval("$pit ||= 1")
+ end
+
+ def test_GlobalVariableWriteNode
+ assert_prism_eval("$pit = 1")
+ end
+
+ def test_InstanceVariableAndWriteNode
+ assert_prism_eval("@pit = 0; @pit &&= 1")
+ end
+
+ def test_InstanceVariableOperatorWriteNode
+ assert_prism_eval("@pit = 0; @pit += 1")
+ end
+
+ def test_InstanceVariableOrWriteNode
+ assert_prism_eval("@pit ||= 1")
+ end
+
+ def test_InstanceVariableWriteNode
+ assert_prism_eval("class Prism::TestCompilePrism; @pit = 1; end")
+ end
+
+ def test_LocalVariableAndWriteNode
+ assert_prism_eval("pit = 0; pit &&= 1")
+ end
+
+ def test_LocalVariableOperatorWriteNode
+ assert_prism_eval("pit = 0; pit += 1")
+ end
+
+ def test_LocalVariableOrWriteNode
+ assert_prism_eval("pit ||= 1")
+ end
+
+ def test_LocalVariableWriteNode
+ assert_prism_eval("pit = 1")
+ assert_prism_eval(<<-CODE)
+ a = 0
+ [].each do
+ a = 1
+ end
+ a
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ a = 1
+ d = 1
+ [1].each do
+ b = 2
+ a = 2
+ [2].each do
+ c = 3
+ d = 4
+ a = 2
+ end
+ end
+ [a, d]
+ CODE
+ end
+
+ def test_MatchWriteNode
+ assert_prism_eval("/(?<foo>bar)(?<baz>bar>)/ =~ 'barbar'")
+ assert_prism_eval("/(?<foo>bar)/ =~ 'barbar'")
+ end
+
+ ############################################################################
+ # Multi-writes #
+ ############################################################################
+
+ def test_ClassVariableTargetNode
+ assert_prism_eval("class Prism::TestCompilePrism; @@pit, @@pit1 = 1; end")
+ end
+
+ def test_ConstantTargetNode
+ # We don't call assert_prism_eval directly in this case because we
+ # don't want to assign the constant multiple times if we run
+ # with `--repeat-count`
+ # Instead, we eval manually here, and remove the constant to
+ constant_names = ["YCT", "YCT2"]
+ source = "#{constant_names.join(",")} = 1"
+ prism_eval = RubyVM::InstructionSequence.compile_prism(source).eval
+ assert_equal prism_eval, 1
+ constant_names.map { |name|
+ Object.send(:remove_const, name)
+ }
+ end
+
+ def test_ConstantPathTargetNode
+ assert_separately([], <<~'RUBY')
+ verbose = $VERBOSE
+ # Create some temporary nested constants
+ Object.send(:const_set, "MyFoo", Object)
+ Object.const_get("MyFoo").send(:const_set, "Bar", Object)
+
+ constant_names = ["MyBar", "MyFoo::Bar", "MyFoo::Bar::Baz"]
+ source = "#{constant_names.join(",")} = Object"
+ iseq = RubyVM::InstructionSequence.compile_prism(source)
+ $VERBOSE = nil
+ prism_eval = iseq.eval
+ $VERBOSE = verbose
+ assert_equal prism_eval, Object
+ RUBY
+ end
+
+ def test_GlobalVariableTargetNode
+ assert_prism_eval("$pit, $pit1 = 1")
+ end
+
+ def test_InstanceVariableTargetNode
+ assert_prism_eval("class Prism::TestCompilePrism; @pit, @pit1 = 1; end")
+ end
+
+ def test_LocalVariableTargetNode
+ assert_prism_eval("pit, pit1 = 1")
+ assert_prism_eval(<<-CODE)
+ a = 1
+ [1].each do
+ c = 2
+ a, b = 2
+ end
+ a
+ CODE
+ end
+
+ def test_MultiTargetNode
+ assert_prism_eval("a, (b, c) = [1, 2, 3]")
+ assert_prism_eval("a, (b, c) = [1, 2, 3]; a")
+ assert_prism_eval("a, (b, c) = [1, 2, 3]; b")
+ assert_prism_eval("a, (b, c) = [1, 2, 3]; c")
+ assert_prism_eval("a, (b, c) = [1, [2, 3]]; c")
+ assert_prism_eval("a, (b, *c) = [1, [2, 3]]; c")
+ assert_prism_eval("a, (b, *c) = 1, [2, 3]; c")
+ assert_prism_eval("a, (b, *) = 1, [2, 3]; b")
+ assert_prism_eval("a, (b, *c, d) = 1, [2, 3, 4]; [a, b, c, d]")
+ assert_prism_eval("(a, (b, c, d, e), f, g), h = [1, [2, 3]], 4, 5, [6, 7]; c")
+ end
+
+ def test_MultiWriteNode
+ assert_prism_eval("foo, bar = [1, 2]")
+ assert_prism_eval("foo, = [1, 2]")
+ assert_prism_eval("foo, *, bar = [1, 2]")
+ assert_prism_eval("foo, bar = 1, 2")
+ assert_prism_eval("foo, *, bar = 1, 2")
+ assert_prism_eval("foo, *, bar = 1, 2, 3, 4")
+ assert_prism_eval("a, b, *, d = 1, 2, 3, 4")
+ assert_prism_eval("a, b, *, d = 1, 2")
+ assert_prism_eval("(a, b), *, c = [1, 3], 4, 5")
+ assert_prism_eval("(a, b), *, c = [1, 3], 4, 5; a")
+ assert_prism_eval("(a, b), *, c = [1, 3], 4, 5; b")
+ assert_prism_eval("(a, b), *, c = [1, 3], 4, 5; c")
+ assert_prism_eval("a, *, (c, d) = [1, 3], 4, 5; a")
+ assert_prism_eval("a, *, (c, d) = [1, 3], 4, 5; c")
+ assert_prism_eval("(a, b, c), *, (d, e) = [1, 3], 4, 5, [6, 7]")
+ assert_prism_eval("(a, b, c), *, (d, e) = [1, 3], 4, 5, [6, 7]; b")
+ assert_prism_eval("(a, b, c), *, (d, e) = [1, 3], 4, 5, [6, 7]; d")
+ assert_prism_eval("((a, *, b), *, (c, *, (d, *, e, f, g))), *, ((h, i, *, j), *, (k, l, m, *, n, o, p), q, r) = 1; a")
+ assert_prism_eval("*a = 1; a")
+ assert_prism_eval("_, {}[:foo] = 1")
+ assert_prism_eval("_, {}[:foo], _ = 1")
+ assert_prism_eval("_, {}[:foo], _ = 1")
+ assert_prism_eval("_,{}[:foo], _, {}[:bar] = 1")
+ assert_prism_eval("* = :foo")
+ assert_prism_eval("* = *[]")
+ assert_prism_eval("a, * = :foo")
+
+
+ assert_prism_eval(<<~CODE)
+ class Foo
+ def bar=(x); end
+ def baz=(c); end
+ end
+ foo = Foo.new
+ foo.bar, foo.baz = 1
+ CODE
+ assert_prism_eval(<<~CODE)
+ class Foo
+ def bar=(x); end
+ def baz=(c); end
+ end
+ foo = Foo.new
+ _, foo.bar, foo.baz = 1
+ CODE
+ assert_prism_eval(<<~CODE)
+ class Foo
+ def bar=(x); end
+ def baz=(c); end
+ end
+ foo = Foo.new
+ _, foo.bar, _, foo.baz = 1
+ CODE
+
+ # Test nested writes with method calls
+ assert_prism_eval(<<~RUBY)
+ class Foo
+ attr_accessor :bar
+ end
+
+ a = Foo.new
+
+ (a.bar, a.bar), b = [1], 2
+ RUBY
+ assert_prism_eval(<<~RUBY)
+ h = {}
+ (h[:foo], h[:bar]), a = [1], 2
+ RUBY
+ end
+
+ ############################################################################
+ # String-likes #
+ ############################################################################
+
+ def test_EmbeddedStatementsNode
+ assert_prism_eval('"foo #{to_s} baz"')
+ end
+
+ def test_EmbeddedVariableNode
+ assert_prism_eval('class Prism::TestCompilePrism; @pit = 1; "#@pit"; end')
+ assert_prism_eval('class Prism::TestCompilePrism; @@pit = 1; "#@@pit"; end')
+ assert_prism_eval('$pit = 1; "#$pit"')
+ end
+
+ def test_InterpolatedMatchLastLineNode
+ assert_prism_eval('$pit = ".oo"; if /"#{$pit}"/mix; end')
+ end
+
+ def test_InterpolatedRegularExpressionNode
+ assert_prism_eval('$pit = 1; /1 #$pit 1/')
+ assert_prism_eval('$pit = 1; /#$pit/i')
+ assert_prism_eval('/1 #{1 + 2} 1/')
+ assert_prism_eval('/1 #{"2"} #{1 + 2} 1/')
+ end
+
+ def test_InterpolatedStringNode
+ assert_prism_eval('$pit = 1; "1 #$pit 1"')
+ assert_prism_eval('"1 #{1 + 2} 1"')
+ assert_prism_eval('"Prism" "::" "TestCompilePrism"')
+ assert_prism_eval(<<-'RUBY')
+ # frozen_string_literal: true
+
+ !("a""b""#{1}").frozen?
+ RUBY
+ assert_prism_eval(<<-'RUBY')
+ # frozen_string_literal: true
+
+ !("a""#{1}""b").frozen?
+ RUBY
+
+ # Test encoding of interpolated strings
+ assert_prism_eval(<<~'RUBY')
+ "#{"foo"}s".encoding
+ RUBY
+ assert_prism_eval(<<~'RUBY')
+ a = "foo"
+ b = "#{a}" << "Bar"
+ [a, b, b.encoding]
+ RUBY
+ end
+
+ def test_concatenated_StringNode
+ assert_prism_eval('("a""b").frozen?')
+ assert_prism_eval(<<-CODE)
+ # frozen_string_literal: true
+
+ ("a""b").frozen?
+ CODE
+ end
+
+ def test_InterpolatedSymbolNode
+ assert_prism_eval('$pit = 1; :"1 #$pit 1"')
+ assert_prism_eval(':"1 #{1 + 2} 1"')
+ end
+
+ def test_InterpolatedXStringNode
+ assert_prism_eval(<<~RUBY)
+ def self.`(command) = command * 2
+ `echo \#{1}`
+ RUBY
+
+ assert_prism_eval(<<~RUBY)
+ def self.`(command) = command * 2
+ `echo \#{"100"}`
+ RUBY
+ end
+
+ def test_MatchLastLineNode
+ assert_prism_eval("if /foo/; end")
+ assert_prism_eval("if /foo/i; end")
+ assert_prism_eval("if /foo/x; end")
+ assert_prism_eval("if /foo/m; end")
+ assert_prism_eval("if /foo/im; end")
+ assert_prism_eval("if /foo/mx; end")
+ assert_prism_eval("if /foo/xi; end")
+ assert_prism_eval("if /foo/ixm; end")
+ end
+
+ def test_RegularExpressionNode
+ assert_prism_eval('/pit/')
+ assert_prism_eval('/pit/i')
+ assert_prism_eval('/pit/x')
+ assert_prism_eval('/pit/m')
+ assert_prism_eval('/pit/im')
+ assert_prism_eval('/pit/mx')
+ assert_prism_eval('/pit/xi')
+ assert_prism_eval('/pit/ixm')
+
+ assert_prism_eval('/pit/u')
+ assert_prism_eval('/pit/e')
+ assert_prism_eval('/pit/s')
+ assert_prism_eval('/pit/n')
+
+ assert_prism_eval('/pit/me')
+ assert_prism_eval('/pit/ne')
+
+ assert_prism_eval('2.times.map { /#{1}/o }')
+ assert_prism_eval('2.times.map { foo = 1; /#{foo}/o }')
+ end
+
+ def test_StringNode
+ assert_prism_eval('"pit"')
+ assert_prism_eval('"a".frozen?')
+ end
+
+ def test_StringNode_frozen_string_literal_true
+ [
+ # Test that string literal is frozen
+ <<~RUBY,
+ # frozen_string_literal: true
+ "a".frozen?
+ RUBY
+ # Test that two string literals with the same contents are the same string
+ <<~RUBY,
+ # frozen_string_literal: true
+ "hello".equal?("hello")
+ RUBY
+ ].each do |src|
+ assert_prism_eval(src, raw: true)
+ end
+ end
+
+ def test_StringNode_frozen_string_literal_false
+ [
+ # Test that string literal is frozen
+ <<~RUBY,
+ # frozen_string_literal: false
+ !"a".frozen?
+ RUBY
+ # Test that two string literals with the same contents are the same string
+ <<~RUBY,
+ # frozen_string_literal: false
+ !"hello".equal?("hello")
+ RUBY
+ ].each do |src|
+ assert_prism_eval(src, raw: true)
+ end
+ end
+
+ def test_StringNode_frozen_string_literal_default
+ # Test that string literal is chilled
+ assert_prism_eval('"a".frozen?')
+
+ # Test that two identical chilled string literals aren't the same object
+ assert_prism_eval('!"hello".equal?("hello")')
+ end
+
+ def test_SymbolNode
+ assert_prism_eval(":pit")
+
+ # Test UTF-8 symbol in a US-ASCII file
+ assert_prism_eval(<<~'RUBY', raw: true)
+ # -*- coding: us-ascii -*-
+ :"\u{e9}"
+ RUBY
+
+ # Test ASCII-8BIT symbol in a US-ASCII file
+ assert_prism_eval(<<~'RUBY', raw: true)
+ # -*- coding: us-ascii -*-
+ :"\xff"
+ RUBY
+
+ # Test US-ASCII symbol in a ASCII-8BIT file
+ assert_prism_eval(<<~'RUBY', raw: true)
+ # -*- coding: ascii-8bit -*-
+ :a
+ RUBY
+ end
+
+ def test_XStringNode
+ assert_prism_eval(<<~RUBY)
+ class Prism::TestCompilePrism
+ def self.`(command) = command * 2
+ `pit`
+ end
+ RUBY
+ end
+
+ ############################################################################
+ # Structures #
+ ############################################################################
+
+ def test_ArrayNode
+ assert_prism_eval("[]")
+ assert_prism_eval("[1, 2, 3]")
+ assert_prism_eval("%i[foo bar baz]")
+ assert_prism_eval("%w[foo bar baz]")
+ assert_prism_eval("[*1..2]")
+ assert_prism_eval("[*1..2, 3, 4, *5..6, 7, 8]")
+ assert_prism_eval("[*1..2, 3, 4, *5..6, 7, 8, *9..11]")
+ assert_prism_eval("[0, *1..2, 3, 4, *5..6, 7, 8, *9..11]")
+ assert_prism_eval("[-1, true, 0, *1..2, 3, 4, *5..6, 7, 8, *9..11]")
+ assert_prism_eval("a = [1,2]; [0, *a, 3, 4, *5..6, 7, 8, *9..11]")
+ assert_prism_eval("[[*1..2], 3, *4..5]")
+
+ # Test keyword splat inside of array
+ assert_prism_eval("[**{x: 'hello'}]")
+
+ # Test UTF-8 string array literal in a US-ASCII file
+ assert_prism_eval(<<~'RUBY', raw: true)
+ # -*- coding: us-ascii -*-
+ # frozen_string_literal: true
+ %W"\u{1f44b} \u{1f409}"
+ RUBY
+ end
+
+ def test_AssocNode
+ assert_prism_eval("{ foo: :bar }")
+ end
+
+ def test_AssocSplatNode
+ assert_prism_eval("foo = { a: 1 }; { **foo }")
+ assert_prism_eval("foo = { a: 1 }; bar = foo; { **foo, b: 2, **bar, c: 3 }")
+ assert_prism_eval("foo = { a: 1 }; { b: 2, **foo, c: 3}")
+
+ # Test anonymous AssocSplatNode
+ assert_prism_eval(<<~RUBY)
+ o = Object.new
+ def o.bar(**) = Hash(**)
+
+ o.bar(hello: "world")
+ RUBY
+
+ # Test that AssocSplatNode is evaluated before BlockArgumentNode using
+ # the splatkw instruction
+ assert_prism_eval(<<~RUBY)
+ o = Struct.new(:ary) do
+ def to_hash
+ ary << :to_hash
+ {}
+ end
+
+ def to_proc
+ ary << :to_proc
+ -> {}
+ end
+
+ def t(...); end
+ end.new
+ o.ary = []
+
+ o.t(**o, &o)
+ o.ary
+ RUBY
+ end
+
+ def test_HashNode
+ assert_prism_eval("{}")
+ assert_prism_eval("{ a: :a }")
+ assert_prism_eval("{ a: :a, b: :b }")
+ assert_prism_eval("a = 1; { a: a }")
+ assert_prism_eval("a = 1; { a: }")
+ assert_prism_eval("{ to_s: }")
+ assert_prism_eval("{ Prism: }")
+ assert_prism_eval("[ Prism: [:b, :c]]")
+ assert_prism_eval("{ [] => 1}")
+ end
+
+ def test_ImplicitNode
+ assert_prism_eval("{ to_s: }")
+ end
+
+ def test_RangeNode
+ assert_prism_eval("1..2")
+ assert_prism_eval("1...2")
+ assert_prism_eval("..2")
+ assert_prism_eval("...2")
+ assert_prism_eval("1..")
+ assert_prism_eval("1...")
+ end
+
+ def test_SplatNode
+ assert_prism_eval("*b = []; b")
+ assert_prism_eval("*b = [1, 2, 3]; b")
+ assert_prism_eval("a, *b = [1, 2, 3]; a")
+ assert_prism_eval("a, *b = [1, 2, 3]; b")
+ assert_prism_eval("a, *b, c = [1, 2, 3]; a")
+ assert_prism_eval("a, *b, c = [1, 2, 3]; b")
+ assert_prism_eval("a, *b, c = [1, 2, 3]; c")
+ assert_prism_eval("*b, c = [1, 2, 3]; b")
+ assert_prism_eval("*b, c = [1, 2, 3]; c")
+ assert_prism_eval("a, *, c = [1, 2, 3]; a")
+ assert_prism_eval("a, *, c = [1, 2, 3]; c")
+
+ # Test anonymous splat node
+ assert_prism_eval(<<~RUBY)
+ def self.bar(*) = Array(*)
+
+ bar([1, 2, 3])
+ RUBY
+ end
+
+ ############################################################################
+ # Jumps #
+ ############################################################################
+
+ def test_AndNode
+ assert_prism_eval("true && 1")
+ assert_prism_eval("false && 1")
+ end
+
+ def test_CaseNode
+ assert_prism_eval("case :a; when :a; 1; else; 2; end")
+ assert_prism_eval("case :a; when :b; 1; else; 2; end")
+ assert_prism_eval("case :a; when :a; 1; else; 2; end")
+ assert_prism_eval("case :a; when :a; end")
+ assert_prism_eval("case :a; when :b, :c; end")
+ assert_prism_eval("case; when :a; end")
+ assert_prism_eval("case; when :a, :b; 1; else; 2 end")
+ assert_prism_eval("case :a; when :b; else; end")
+ assert_prism_eval("b = 1; case :a; when b; else; end")
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_case_node
+ case :a
+ when :b
+ else
+ return 2
+ end
+ 1
+ end
+ prism_test_case_node
+ CODE
+
+ # Test splat in when
+ assert_prism_eval(<<~RUBY)
+ ary = [1, 2]
+ case 1
+ when *ary
+ :ok
+ else
+ :ng
+ end
+ RUBY
+
+ # Test splat in when
+ assert_prism_eval(<<~RUBY)
+ ary = [1, 2]
+ case 1
+ when :foo, *ary
+ :ok
+ else
+ :ng
+ end
+ RUBY
+
+ # Test case without predicate
+ assert_prism_eval(<<~RUBY)
+ case
+ when 1 == 2
+ :ng
+ else
+ :ok
+ end
+ RUBY
+
+ # test splat with no predicate
+ assert_prism_eval(<<~RUBY)
+ case
+ when *[true]
+ :ok
+ else
+ :ng
+ end
+ RUBY
+ end
+
+ def test_ElseNode
+ assert_prism_eval("if false; 0; else; 1; end")
+ assert_prism_eval("if true; 0; else; 1; end")
+ assert_prism_eval("true ? 1 : 0")
+ assert_prism_eval("false ? 0 : 1")
+ end
+
+ def test_FlipFlopNode
+ assert_prism_eval("not (1 == 1) .. (2 == 2)")
+ assert_prism_eval("not (1 == 1) ... (2 == 2)")
+ end
+
+ def test_IfNode
+ assert_prism_eval("if true; 1; end")
+ assert_prism_eval("1 if true")
+ assert_prism_eval('a = b = 1; if a..b; end')
+ assert_prism_eval('if "a".."b"; end')
+ assert_prism_eval('if "a"..; end')
+ assert_prism_eval('if .."b"; end')
+ assert_prism_eval('if ..1; end')
+ assert_prism_eval('if 1..; end')
+ assert_prism_eval('if 1..2; end')
+ assert_prism_eval('if true or true; end');
+ end
+
+ def test_OrNode
+ assert_prism_eval("true || 1")
+ assert_prism_eval("false || 1")
+ end
+
+ def test_UnlessNode
+ assert_prism_eval("1 unless true")
+ assert_prism_eval("1 unless false")
+ assert_prism_eval("unless true; 1; end")
+ assert_prism_eval("unless false; 1; end")
+ end
+
+ def test_UntilNode
+ assert_prism_eval("a = 0; until a == 1; a = a + 1; end")
+
+ # Test UntilNode in rescue
+ assert_prism_eval(<<~RUBY)
+ o = Object.new
+ o.instance_variable_set(:@ret, [])
+ def o.foo = @ret << @ret.length
+ def o.bar = @ret.length > 3
+ begin
+ raise
+ rescue
+ o.foo until o.bar
+ end
+ o.instance_variable_get(:@ret)
+ RUBY
+ end
+
+ def test_WhileNode
+ assert_prism_eval("a = 0; while a != 1; a = a + 1; end")
+
+ # Test WhileNode in rescue
+ assert_prism_eval(<<~RUBY)
+ o = Object.new
+ o.instance_variable_set(:@ret, [])
+ def o.foo = @ret << @ret.length
+ def o.bar = @ret.length < 3
+ begin
+ raise
+ rescue
+ o.foo while o.bar
+ end
+ o.instance_variable_get(:@ret)
+ RUBY
+ end
+
+ def test_ForNode
+ assert_prism_eval("for i in [1,2] do; i; end")
+ assert_prism_eval("for @i in [1,2] do; @i; end")
+ assert_prism_eval("for $i in [1,2] do; $i; end")
+
+ assert_prism_eval("for foo, in [1,2,3] do end")
+
+ assert_prism_eval("for i, j in {a: 'b'} do; i; j; end")
+ end
+
+ ############################################################################
+ # Throws #
+ ############################################################################
+
+ def test_BeginNode
+ assert_prism_eval("begin; 1; end")
+ assert_prism_eval("begin; end; 1")
+ end
+
+ def test_BreakNode
+ assert_prism_eval("while true; break; end")
+ assert_prism_eval("while true; break 1; end")
+ assert_prism_eval("while true; break 1, 2; end")
+
+ assert_prism_eval("[].each { break }")
+ assert_prism_eval("[true].map { break }")
+ end
+
+ def test_ensure_in_methods
+ assert_prism_eval(<<-CODE)
+def self.m
+ a = []
+ensure
+ a << 5
+ return a
+end
+m
+ CODE
+ end
+
+ def test_break_runs_ensure
+ assert_prism_eval(<<-CODE)
+a = []
+while true
+ begin
+ break
+ ensure
+ a << 1
+ end
+end
+a
+ CODE
+ end
+
+ def test_EnsureNode
+ assert_prism_eval("begin; 1; ensure; 2; end")
+ assert_prism_eval("begin; 1; begin; 3; ensure; 4; end; ensure; 2; end")
+ assert_prism_eval(<<-CODE)
+ begin
+ a = 2
+ ensure
+ end
+ CODE
+ assert_prism_eval(<<-CODE)
+ begin
+ a = 2
+ ensure
+ a = 3
+ end
+ a
+ CODE
+
+ # Test that ensure block only evaluated once
+ assert_prism_eval(<<~RUBY)
+ res = []
+ begin
+ begin
+ raise
+ ensure
+ res << $!.to_s
+ end
+ rescue
+ res
+ end
+ RUBY
+
+ assert_prism_eval(<<-CODE)
+ a = 1
+ begin
+ a = 2
+ ensure
+ a = 3
+ end
+ a
+ CODE
+ assert_prism_eval(<<-CODE)
+ a = 1
+ begin
+ b = 2
+ ensure
+ c = 3
+ end
+ a + b + c
+ CODE
+ assert_prism_eval(<<~CODE)
+ foo = 1
+ begin
+ ensure
+ begin
+ ensure
+ foo.nil?
+ end
+ end
+ CODE
+ assert_prism_eval(<<~CODE)
+ def test
+ ensure
+ {}.each do |key, value|
+ {}[key] = value
+ end
+ end
+ CODE
+ assert_prism_eval(<<~CODE)
+ def test
+ a = 1
+ ensure
+ {}.each do |key, value|
+ {}[key] = a
+ end
+ end
+ CODE
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_ensure_node
+ begin
+ ensure
+ end
+ return
+ end
+ prism_test_ensure_node
+ CODE
+
+ # Test empty ensure block
+ assert_prism_eval(<<~RUBY)
+ res = []
+
+ begin
+ begin
+ raise
+ ensure
+ end
+ rescue
+ res << "rescue"
+ end
+
+ res
+ RUBY
+ end
+
+ def test_NextNode
+ assert_prism_eval("2.times do |i|; next if i == 1; end")
+
+ assert_prism_eval(<<-CODE)
+ res = []
+ i = 0
+ while i < 5
+ i += 1
+ next if i == 3
+ res << i
+ end
+ res
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ res = []
+ (1..5).each do |i|
+ next if i.even?
+ res << i
+ end
+ res
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ (1..5).map do |i|
+ next i, :even if i.even?
+ i
+ end
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ res = []
+ i = 0
+ begin
+ i += 1
+ next if i == 3
+ res << i
+ end while i < 5
+ res
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ while false
+ begin
+ ensure
+ end
+ next
+ end
+ CODE
+
+ assert_prism_eval(<<~CODE)
+ [].each do
+ begin
+ rescue
+ next
+ end
+ end
+ CODE
+ end
+
+ def test_RedoNode
+ assert_prism_eval(<<-CODE)
+ counter = 0
+
+ 5.times do |i|
+ counter += 1
+ if i == 2 && counter < 3
+ redo
+ end
+ end
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ for i in 1..5
+ if i == 3
+ i = 0
+ redo
+ end
+ end
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ i = 0
+ begin
+ i += 1
+ redo if i == 3
+ end while i < 5
+ CODE
+ end
+
+ def test_RescueNode
+ assert_prism_eval("begin; 1; rescue; 2; end")
+ assert_prism_eval(<<~CODE)
+ begin
+ 1
+ rescue SyntaxError
+ 2
+ end
+ CODE
+ assert_prism_eval(<<~CODE)
+ begin
+ 1
+ raise 'boom'
+ rescue StandardError
+ 2
+ end
+ CODE
+ assert_prism_eval(<<~CODE)
+ begin
+ a = 1
+ rescue StandardError => e
+ end
+ CODE
+ assert_prism_eval(<<~CODE)
+ begin
+ raise StandardError
+ rescue StandardError => e
+ end
+ CODE
+ assert_prism_eval(<<~CODE)
+ begin
+ 1
+ rescue StandardError => e
+ e
+ rescue SyntaxError => f
+ f
+ else
+ 4
+ end
+ CODE
+ assert_prism_eval(<<-CODE)
+ begin
+ a = 2
+ rescue
+ a = 3
+ end
+ a
+ CODE
+ assert_prism_eval(<<-CODE)
+ a = 1
+ begin
+ a = 2
+ rescue
+ a = 3
+ end
+ a
+ CODE
+ assert_prism_eval(<<-CODE)
+ a = 1
+ begin
+ b = 2
+ raise "bang"
+ rescue
+ c = 3
+ end
+ a + b + c
+ CODE
+ assert_prism_eval("begin; rescue; end")
+
+ assert_prism_eval(<<~CODE)
+ begin
+ rescue
+ args.each do |key, value|
+ tmp[key] = 1
+ end
+ end
+ CODE
+ assert_prism_eval(<<~CODE)
+ 10.times do
+ begin
+ rescue
+ break
+ end
+ end
+ CODE
+
+ # Test RescueNode with ElseNode
+ assert_prism_eval(<<~RUBY)
+ calls = []
+ begin
+ begin
+ rescue RuntimeError
+ calls << 1
+ else
+ calls << 2
+ raise RuntimeError
+ end
+ rescue RuntimeError
+ end
+
+ calls
+ RUBY
+ end
+
+ def test_RescueModifierNode
+ assert_prism_eval("1.nil? rescue false")
+ assert_prism_eval("1.nil? rescue 1")
+ assert_prism_eval("raise 'bang' rescue nil")
+ assert_prism_eval("raise 'bang' rescue a = 1; a.nil?")
+ assert_prism_eval("a = 0 rescue (a += 1 && retry if a <= 1)")
+ end
+
+ def test_RetryNode
+ assert_prism_eval(<<~CODE)
+ a = 1
+ begin
+ a
+ raise "boom"
+ rescue
+ a += 1
+ retry unless a > 1
+ ensure
+ a = 3
+ end
+ CODE
+
+ assert_prism_eval(<<~CODE)
+ begin
+ rescue
+ foo = 2
+ retry
+ end
+ CODE
+
+ assert_prism_eval(<<~CODE)
+ begin
+ a = 2
+ rescue
+ retry
+ end
+ CODE
+ end
+
+ def test_ReturnNode
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_return_node
+ return 1
+ end
+ prism_test_return_node
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_return_node
+ return 1, 2
+ end
+ prism_test_return_node
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_return_node
+ [1].each do |e|
+ return true
+ end
+ end
+ prism_test_return_node
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_return_node
+ [1].map do |i|
+ return i if i == 1
+ 2
+ end
+ end
+ prism_test_return_node
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_return_node(*args, **kwargs)
+ return *args, *args, **kwargs
+ end
+ prism_test_return_node(1, foo: 0)
+ CODE
+ end
+
+ ############################################################################
+ # Scopes/statements #
+ ############################################################################
+
+ def test_BlockNode
+ assert_prism_eval("[1, 2, 3].each { |num| num }")
+
+ assert_prism_eval("[].tap { _1 }")
+
+ assert_prism_eval("[].each { |a,| }")
+ assert_prism_eval("[[1, 2, 3]].map { |_, _, a| a }")
+ assert_prism_eval("[[1, 2, 3]].map { |_, a| a }")
+
+ assert_prism_eval("[[]].map { |a| a }")
+ assert_prism_eval("[[]].map { |a| a }")
+ assert_prism_eval("[[]].map { |a, &block| a }")
+ assert_prism_eval("[[]].map { |a, &block| a }")
+ assert_prism_eval("[{}].map { |a,| }")
+ assert_prism_eval("[[]].map { |a,b=1| a }")
+ assert_prism_eval("[{}].map { |a,| }")
+ assert_prism_eval("[{}].map { |a| a }")
+
+ # Test blocks with MultiTargetNode
+ assert_prism_eval("[[1, 2]].each.map { |(a), (b)| [a, b] }")
+ end
+
+ def test_ClassNode
+ assert_prism_eval("class PrismClassA; end")
+ assert_prism_eval("class PrismClassA; end; class PrismClassB < PrismClassA; end")
+ assert_prism_eval("class PrismClassA; end; class PrismClassA::PrismClassC; end")
+ assert_prism_eval(<<-HERE
+ class PrismClassA; end
+ class PrismClassA::PrismClassC; end
+ class PrismClassB; end
+ class PrismClassB::PrismClassD < PrismClassA::PrismClassC; end
+ HERE
+ )
+ end
+
+ # Many of these tests are versions of tests at bootstraptest/test_method.rb
+ def test_DefNode
+ assert_prism_eval("def prism_test_def_node; end")
+ assert_prism_eval("a = Object.new; def a.prism_singleton; :ok; end; a.prism_singleton")
+ assert_prism_eval("def self.prism_test_def_node() 1 end; prism_test_def_node()")
+ assert_prism_eval("def self.prism_test_def_node(a,b) [a, b] end; prism_test_def_node(1,2)")
+ assert_prism_eval("def self.prism_test_def_node(a,x=7,y=1) x end; prism_test_def_node(7,1)")
+ assert_prism_eval("def self.prism_test_def_node(a = 1); x = 2; end; prism_test_def_node")
+
+ # rest argument
+ assert_prism_eval("def self.prism_test_def_node(*a) a end; prism_test_def_node().inspect")
+ assert_prism_eval("def self.prism_test_def_node(*a) a end; prism_test_def_node(1).inspect")
+ assert_prism_eval("def self.prism_test_def_node(x,y,*a) a end; prism_test_def_node(7,7,1,2).inspect")
+ assert_prism_eval("def self.prism_test_def_node(x,y=7,*a) a end; prism_test_def_node(7).inspect")
+ assert_prism_eval("def self.prism_test_def_node(x,y,z=7,*a) a end; prism_test_def_node(7,7).inspect")
+ assert_prism_eval("def self.prism_test_def_node(x,y,z=7,zz=7,*a) a end; prism_test_def_node(7,7,7).inspect")
+
+ # keyword arguments
+ assert_prism_eval("def self.prism_test_def_node(a: 1, b: 2, c: 4) a + b + c; end; prism_test_def_node(a: 2)")
+ assert_prism_eval("def self.prism_test_def_node(a: 1, b: 2, c: 4) a + b + c; end; prism_test_def_node(b: 3)")
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_def_node(x = 1, y, a: 8, b: 2, c: 4)
+ a + b + c + x + y
+ end
+ prism_test_def_node(10, b: 3)
+ CODE
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_def_node(a: [])
+ a
+ end
+ prism_test_def_node
+ CODE
+
+ # block arguments
+ assert_prism_eval("def self.prism_test_def_node(&block) block end; prism_test_def_node{}.class")
+ assert_prism_eval("def self.prism_test_def_node(&block) block end; prism_test_def_node().inspect")
+ assert_prism_eval("def self.prism_test_def_node(a,b=7,*c,&block) b end; prism_test_def_node(7,1).inspect")
+ assert_prism_eval("def self.prism_test_def_node(a,b=7,*c,&block) c end; prism_test_def_node(7,7,1).inspect")
+
+ # splat
+ assert_prism_eval("def self.prism_test_def_node(a) a end; prism_test_def_node(*[1])")
+ assert_prism_eval("def self.prism_test_def_node(x,a) a end; prism_test_def_node(7,*[1])")
+ assert_prism_eval("def self.prism_test_def_node(x,y,a) a end; prism_test_def_node(7,7,*[1])")
+ assert_prism_eval("def self.prism_test_def_node(x,y,a,b,c) a end; prism_test_def_node(7,7,*[1,7,7])")
+
+ # recursive call
+ assert_prism_eval("def self.prism_test_def_node(n) n == 0 ? 1 : prism_test_def_node(n-1) end; prism_test_def_node(5)")
+
+ # instance method
+ assert_prism_eval("class PrismTestDefNode; def prism_test_def_node() 1 end end; PrismTestDefNode.new.prism_test_def_node")
+ assert_prism_eval("class PrismTestDefNode; def prism_test_def_node(*a) a end end; PrismTestDefNode.new.prism_test_def_node(1).inspect")
+
+ # block argument
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_def_node(&block) prism_test_def_node2(&block) end
+ def self.prism_test_def_node2() yield 1 end
+ prism_test_def_node2 {|a| a }
+ CODE
+
+ # multi argument
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_def_node(a, (b, *c, d))
+ [a, b, c, d]
+ end
+ prism_test_def_node("a", ["b", "c", "d"])
+ CODE
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_def_node(a, (b, c, *))
+ [a, b, c]
+ end
+ prism_test_def_node("a", ["b", "c"])
+ CODE
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_def_node(a, (*, b, c))
+ [a, b, c]
+ end
+ prism_test_def_node("a", ["b", "c"])
+ CODE
+
+ # recursive multis
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_def_node(a, (b, *c, (d, *e, f)))
+ [a, b, c, d, d, e, f]
+ end
+ prism_test_def_node("a", ["b", "c", ["d", "e", "f"]])
+ CODE
+
+ # Many arguments
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_def_node(a, (b, *c, d), e = 1, *f, g, (h, *i, j), k:, l: 1, **m)
+ [a, b, c, d, e, f, g, h, i, j, k, l, m]
+ end
+ prism_test_def_node(
+ "a",
+ ["b", "c1", "c2", "d"],
+ "e",
+ "f1", "f2",
+ "g",
+ ["h", "i1", "i2", "j"],
+ k: "k",
+ l: "l",
+ m1: "m1",
+ m2: "m2"
+ )
+ CODE
+ end
+
+ def test_pow_parameters
+ assert_prism_eval("def self.m(a, **); end; method(:m).parameters")
+ end
+
+ def test_star_parameters
+ assert_prism_eval("def self.m(a, *, b); end; method(:m).parameters")
+ end
+
+ def test_repeated_block_params
+ assert_prism_eval("def self.x(&blk); blk; end; x { |_, _, _ = 1, *_, _:, _: 2, **_, &_| }.parameters")
+ end
+
+ def test_repeated_proc_params
+ assert_prism_eval("proc {|_, _, _ = 1, *_, _:, _: 2, **_, &_| }.parameters")
+ end
+
+ def test_forward_parameters_block
+ assert_prism_eval("def self.m(&); end; method(:m).parameters")
+ end
+
+ def test_forward_parameters
+ assert_prism_eval("def self.m(...); end; method(:m).parameters")
+ end
+
+ def test_repeated_block_underscore
+ assert_prism_eval("def self.m(_, **_, &_); _; end; method(:m).parameters")
+ end
+
+ def test_repeated_kw_rest_underscore
+ assert_prism_eval("def self.m(_, **_); _; end; method(:m).parameters")
+ end
+
+ def test_repeated_required_keyword_underscore
+ assert_prism_eval("def self.m(_, _, *_, _, _:); _; end; method(:m).parameters")
+ assert_prism_eval("def self.m(_, _, *_, _, _:, _: 2); _; end; method(:m).parameters")
+ end
+
+ def test_repeated_required_post_underscore
+ assert_prism_eval("def self.m(_, _, *_, _); _; end; method(:m).parameters")
+ end
+
+ def test_repeated_splat_underscore
+ assert_prism_eval("def self.m(_, _, _ = 1, _ = 2, *_); end; method(:m).parameters")
+ end
+
+ def test_repeated_optional_underscore
+ assert_prism_eval("def self.m(a, _, _, _ = 1, _ = 2, b); end; method(:m).parameters")
+ end
+
+ def test_repeated_required_underscore
+ assert_prism_eval("def self.m(a, _, _, b); end; method(:m).parameters")
+ end
+
+ def test_locals_in_parameters
+ assert_prism_eval("def self.m(a = b = c = 1); [a, b, c]; end; self.m")
+ end
+
+ def test_trailing_comma_on_block
+ assert_prism_eval("def self.m; yield [:ok]; end; m {|v0,| v0 }")
+ end
+
+ def test_complex_default_params
+ assert_prism_eval("def self.foo(a:, b: '2'.to_i); [a, b]; end; foo(a: 1)")
+ assert_prism_eval("def self.foo(a:, b: 2, c: '3'.to_i); [a, b, c]; end; foo(a: 1)")
+ end
+
+ def test_numbered_params
+ assert_prism_eval("[1, 2, 3].then { _3 }")
+ assert_prism_eval("1.then { one = 1; one + _1 }")
+ end
+
+ def test_rescue_with_ensure
+ assert_prism_eval(<<-CODE)
+begin
+ begin
+ raise "a"
+ rescue
+ raise "b"
+ ensure
+ raise "c"
+ end
+rescue => e
+ e.message
+end
+ CODE
+ end
+
+ def test_required_kwarg_ordering
+ assert_prism_eval("def self.foo(a: 1, b:); [a, b]; end; foo(b: 2)")
+ end
+
+ def test_trailing_keyword_method_params
+ # foo(1, b: 2, c: 3) # argc -> 3
+ assert_prism_eval("def self.foo(a, b:, c:); [a, b, c]; end; foo(1, b: 2, c: 3)")
+ end
+
+ def test_keyword_method_params_only
+ # foo(a: 1, b: 2) # argc -> 2
+ assert_prism_eval("def self.foo(a:, b:); [a, b]; end; foo(a: 1, b: 2)")
+ end
+
+ def test_keyword_method_params_with_splat
+ # foo(a: 1, **b) # argc -> 1
+ assert_prism_eval("def self.foo(a:, b:); [a, b]; end; b = { b: 2 }; foo(a: 1, **b)")
+ end
+
+ def test_positional_and_splat_keyword_method_params
+ # foo(a, **b) # argc -> 2
+ assert_prism_eval("def self.foo(a, b); [a, b]; end; b = { b: 2 }; foo(1, **b)")
+ end
+
+ def test_positional_and_splat_method_params
+ # foo(a, *b, c, *d, e) # argc -> 2
+ assert_prism_eval("def self.foo(a, b, c, d, e); [a, b, c, d, e]; end; b = [2]; d = [4]; foo(1, *b, 3, *d, 5)")
+ end
+
+ def test_positional_with_splat_and_splat_keyword_method_params
+ # foo(a, *b, c, *d, **e) # argc -> 3
+ assert_prism_eval("def self.foo(a, b, c, d, e); [a, b, c, d, e]; end; b = [2]; d = [4]; e = { e: 5 }; foo(1, *b, 3, *d, **e)")
+ end
+
+ def test_positional_with_splat_and_keyword_method_params
+ # foo(a, *b, c, *d, e:) # argc -> 3
+ assert_prism_eval("def self.foo(a, b, c, d, e:); [a, b, c, d, e]; end; b = [2]; d = [4]; foo(1, *b, 3, *d, e: 5)")
+ end
+
+ def test_leading_splat_and_keyword_method_params
+ # foo(*a, b:) # argc -> 2
+ assert_prism_eval("def self.foo(a, b:); [a, b]; end; a = [1]; foo(*a, b: 2)")
+ end
+
+ def test_repeated_method_params
+ assert_prism_eval("def self.foo(_a, _a); _a; end; foo(1, 2)")
+ end
+
+ def test_splat_params_with_no_lefties
+ assert_prism_eval("def self.foo(v, (*)); v; end; foo(1, [2, 3, 4])")
+ end
+
+ def test_method_parameters
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_method_parameters(a, b=1, *c, d:, e: 2, **f, &g)
+ end
+
+ method(:prism_test_method_parameters).parameters
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_method_parameters(d:, e: 2, **f, &g)
+ end
+
+ method(:prism_test_method_parameters).parameters
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_method_parameters(**f, &g)
+ end
+
+ method(:prism_test_method_parameters).parameters
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_method_parameters(&g)
+ end
+
+ method(:prism_test_method_parameters).parameters
+ CODE
+ end
+
+ def test_LambdaNode
+ assert_prism_eval("-> { to_s }.call")
+ end
+
+ def test_LambdaNode_with_multiline_args
+ assert_prism_eval(<<-CODE)
+ -> (a,
+ b) {
+ a + b
+ }.call(1, 2)
+ CODE
+ end
+
+ def test_ModuleNode
+ assert_prism_eval("module M; end")
+ assert_prism_eval("module M::N; end")
+ assert_prism_eval("module ::O; end")
+ end
+
+ def test_ParenthesesNode
+ assert_prism_eval("()")
+ assert_prism_eval("(1)")
+ end
+
+ def test_PreExecutionNode
+ assert_prism_eval("BEGIN { a = 1 }; 2", raw: true)
+ assert_prism_eval("b = 2; BEGIN { a = 1 }; a + b", raw: true)
+ end
+
+ def test_PostExecutionNode
+ assert_prism_eval("END { 1 }")
+ assert_prism_eval("END { @b }; @b = 1")
+ assert_prism_eval("END { @b; 0 }; @b = 1")
+ assert_prism_eval("foo = 1; END { foo.nil? }")
+ assert_prism_eval("foo = 1; END { END { foo.nil? }}")
+ end
+
+ def test_ProgramNode
+ assert_prism_eval("")
+ assert_prism_eval("1")
+ end
+
+ def test_SingletonClassNode
+ assert_prism_eval("class << self; end")
+ end
+
+ def test_StatementsNode
+ assert_prism_eval("1")
+ end
+
+ def test_YieldNode
+ assert_prism_eval("def prism_test_yield_node; yield; end")
+ assert_prism_eval("def prism_test_yield_node; yield 1, 2; end")
+ assert_prism_eval("def prism_test_yield_node; yield **kw if condition; end")
+
+ # Test case where there's a call directly after the yield call
+ assert_prism_eval("def prism_test_yield_node; yield; 1; end")
+ assert_prism_eval("def prism_test_yield_node; yield 1, 2; 1; end")
+ end
+
+ ############################################################################
+ # Calls / arguments #
+ ############################################################################
+
+ def test_ArgumentsNode
+ # assert_prism_eval("[].push 1")
+ end
+
+ def test_BlockArgumentNode
+ assert_prism_eval("1.then(&:to_s)")
+
+ # Test anonymous block forwarding
+ assert_prism_eval(<<~RUBY)
+ o = Object.new
+ def o.foo(&) = yield
+ def o.bar(&) = foo(&)
+
+ o.bar { :ok }
+ RUBY
+ end
+
+ def test_BlockLocalVariableNode
+ assert_prism_eval(<<-CODE
+ pm_var = "outer scope variable"
+
+ 1.times { |;pm_var| pm_var = "inner scope variable"; pm_var }
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE
+ pm_var = "outer scope variable"
+
+ 1.times { |;pm_var| pm_var = "inner scope variable"; pm_var }
+ pm_var
+ CODE
+ )
+ end
+
+ def test_CallNode
+ assert_prism_eval("to_s")
+
+ # with arguments
+ assert_prism_eval("eval '1'")
+
+ # with arguments and popped
+ assert_prism_eval("eval '1'; 1")
+
+ # With different types of calling arguments
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_call_node_double_splat(**); end
+ prism_test_call_node_double_splat(b: 1, **{})
+ CODE
+ assert_prism_eval(<<-CODE)
+ prism_test_call_node_double_splat(:b => 1)
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_test_call_node_splat(*); end
+ prism_test_call_node_splat(*[], 1)
+ CODE
+
+ assert_prism_eval("prism_test_call_node_splat(*[], 1, 2)")
+
+ assert_prism_eval(<<~RUBY)
+ def self.prism_test_call_node_splat_and_double_splat(a, b, **opts); end
+ prism_test_call_node_splat_and_double_splat(*[1], 2, **{})
+ RUBY
+
+ assert_prism_eval(<<-CODE)
+ class Foo
+ def []=(a, b)
+ 1234
+ end
+ end
+
+ def self.foo(i, j)
+ tbl = Foo.new
+ tbl[i] = j
+ end
+ foo(1, 2)
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ class Foo
+ def i=(a)
+ 1234
+ end
+ end
+
+ def self.foo(j)
+ tbl = Foo.new
+ tbl.i = j
+ end
+ foo(1)
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ foo = Object.new
+ def foo.[]=(k,v); 42; end
+ foo.[]=(1,2)
+ CODE
+
+ # With splat inside of []=
+ assert_prism_eval(<<~RUBY)
+ obj = Object.new
+ def obj.[]=(a, b); 10; end
+ obj[*[1]] = 3
+ RUBY
+
+ assert_prism_eval(<<-CODE)
+ def self.prism_opt_var_trail_hash(a = nil, *b, c, **d); end
+ prism_opt_var_trail_hash("a")
+ prism_opt_var_trail_hash("a", c: 1)
+ prism_opt_var_trail_hash("a", "b")
+ prism_opt_var_trail_hash("a", "b", "c")
+ prism_opt_var_trail_hash("a", "b", "c", c: 1)
+ prism_opt_var_trail_hash("a", "b", "c", "c" => 0, c: 1)
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.foo(*args, **kwargs) = [args, kwargs]
+
+ [
+ foo(2 => 3),
+ foo([] => 42),
+ foo(a: 42, b: 61),
+ foo(1, 2, 3, a: 42, "b" => 61),
+ foo(:a => 42, :b => 61),
+ ]
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ class PrivateMethod
+ def initialize
+ self.instance_var
+ end
+ private
+ attr_accessor :instance_var
+ end
+ pm = PrivateMethod.new
+ pm.send(:instance_var)
+ CODE
+
+ # Testing safe navigation operator
+ assert_prism_eval(<<-CODE)
+ def self.test_prism_call_node
+ if [][0]&.first
+ 1
+ end
+ end
+ test_prism_call_node
+ CODE
+
+ # Test opt_str_freeze instruction when calling #freeze on a string literal
+ assert_prism_eval(<<~RUBY)
+ "foo".freeze.equal?("foo".freeze)
+ RUBY
+ # Test encoding in opt_str_freeze
+ assert_prism_eval(<<~'RUBY', raw: true)
+ # -*- coding: us-ascii -*-
+ "\xff".freeze.encoding
+ RUBY
+
+ # Test opt_aref_with instruction when calling [] with a string
+ assert_prism_eval(<<~RUBY)
+ ObjectSpace.count_objects
+
+ h = {"abc" => 1}
+ before = ObjectSpace.count_objects[:T_STRING]
+ 5.times{ h["abc"] }
+ after = ObjectSpace.count_objects[:T_STRING]
+
+ before == after
+ RUBY
+
+ # Test opt_aset_with instruction when calling []= with a string key
+ assert_prism_eval(<<~RUBY)
+ ObjectSpace.count_objects
+
+ h = {"abc" => 1}
+ before = ObjectSpace.count_objects[:T_STRING]
+ 5.times{ h["abc"] = 2}
+ after = ObjectSpace.count_objects[:T_STRING]
+
+ before == after
+ RUBY
+ end
+
+ def test_CallAndWriteNode
+ assert_prism_eval(<<-CODE
+ class PrismTestSubclass; end
+ def PrismTestSubclass.test_call_and_write_node; end;
+ PrismTestSubclass.test_call_and_write_node &&= 1
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE
+ def PrismTestSubclass.test_call_and_write_node
+ "str"
+ end
+ def PrismTestSubclass.test_call_and_write_node=(val)
+ val
+ end
+ PrismTestSubclass.test_call_and_write_node &&= 1
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE
+ def self.test_call_and_write_node; end;
+ self.test_call_and_write_node &&= 1
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE
+ def self.test_call_and_write_node
+ "str"
+ end
+ def self.test_call_and_write_node=(val)
+ val
+ end
+ self.test_call_and_write_node &&= 1
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE)
+ def self.test_prism_call_node; end
+ def self.test_prism_call_node=(val)
+ val
+ end
+ self&.test_prism_call_node &&= 1
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.test_prism_call_node
+ 2
+ end
+ def self.test_prism_call_node=(val)
+ val
+ end
+ self&.test_prism_call_node &&= 1
+ CODE
+ end
+
+ def test_CallOrWriteNode
+ assert_prism_eval(<<-CODE
+ class PrismTestSubclass; end
+ def PrismTestSubclass.test_call_or_write_node; end;
+ def PrismTestSubclass.test_call_or_write_node=(val)
+ val
+ end
+ PrismTestSubclass.test_call_or_write_node ||= 1
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE
+ def PrismTestSubclass.test_call_or_write_node
+ "str"
+ end
+ PrismTestSubclass.test_call_or_write_node ||= 1
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE
+ def self.test_call_or_write_node; end;
+ def self.test_call_or_write_node=(val)
+ val
+ end
+ self.test_call_or_write_node ||= 1
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE
+ def self.test_call_or_write_node
+ "str"
+ end
+ self.test_call_or_write_node ||= 1
+ CODE
+ )
+
+ assert_prism_eval(<<-CODE)
+ def self.test_prism_call_node
+ 2
+ end
+ def self.test_prism_call_node=(val)
+ val
+ end
+ self&.test_prism_call_node ||= 1
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def self.test_prism_call_node; end
+ def self.test_prism_call_node=(val)
+ val
+ end
+ self&.test_prism_call_node ||= 1
+ CODE
+ end
+
+ def test_CallOperatorWriteNode
+ assert_prism_eval(<<-CODE
+ class PrismTestSubclass; end
+ def PrismTestSubclass.test_call_operator_write_node
+ 2
+ end
+ def PrismTestSubclass.test_call_operator_write_node=(val)
+ val
+ end
+ PrismTestSubclass.test_call_operator_write_node += 1
+ CODE
+ )
+ end
+
+ def test_ForwardingArgumentsNode
+ assert_prism_eval(<<-CODE)
+ def prism_test_forwarding_arguments_node(...); end;
+ def prism_test_forwarding_arguments_node1(...)
+ prism_test_forwarding_arguments_node(...)
+ end
+ CODE
+
+ assert_prism_eval(<<-CODE)
+ def prism_test_forwarding_arguments_node(...); end;
+ def prism_test_forwarding_arguments_node1(a, ...)
+ prism_test_forwarding_arguments_node(1,2, 3, ...)
+ end
+ CODE
+
+ assert_prism_eval(<<~RUBY)
+ o = Object.new
+ def o.bar(a, b, c) = [a, b, c]
+ def o.foo(...) = 1.times { bar(...) }
+
+ o.foo(1, 2, 3)
+ RUBY
+ end
+
+ def test_ForwardingSuperNode
+ assert_prism_eval("class Forwarding; def to_s; super; end; end")
+ assert_prism_eval("class Forwarding; def eval(code); super { code }; end; end")
+ assert_prism_eval(<<-CODE)
+ class A
+ def initialize(a, b)
+ end
+ end
+
+ class B < A
+ attr_reader :res
+ def initialize(a, b, *)
+ super
+ @res = [a, b]
+ end
+ end
+
+ B.new(1, 2).res
+ CODE
+ end
+
+ def test_KeywordHashNode
+ assert_prism_eval("[a: [:b, :c]]")
+ end
+
+ def test_SuperNode
+ assert_prism_eval("def to_s; super 1; end")
+ assert_prism_eval("def to_s; super(); end")
+ assert_prism_eval("def to_s; super('a', :b, [1,2,3]); end")
+ assert_prism_eval("def to_s; super(1, 2, 3, &:foo); end")
+ end
+
+ ############################################################################
+ # Methods / parameters #
+ ############################################################################
+
+ def test_AliasGlobalVariableNode
+ assert_prism_eval("alias $prism_foo $prism_bar")
+ end
+
+ def test_AliasMethodNode
+ assert_prism_eval("alias :prism_a :to_s")
+ end
+
+ def test_BlockParameterNode
+ assert_prism_eval("def prism_test_block_parameter_node(&bar) end")
+ assert_prism_eval("->(b, c=1, *d, e, &f){}")
+
+ # Test BlockParameterNode with no name
+ assert_prism_eval("->(&){}")
+ assert_prism_eval("def prism_test_block_parameter_node(&); end")
+ end
+
+ def test_BlockParametersNode
+ assert_prism_eval("Object.tap { || }")
+ assert_prism_eval("[1].map { |num| num }")
+ assert_prism_eval("[1].map { |a; b| b = 2; a + b}")
+
+ # Test block parameters with multiple _
+ assert_prism_eval(<<~RUBY)
+ [[1, 2, 3, 4, 5, 6]].map { |(_, _, _, _, _, _)| _ }
+ RUBY
+ end
+
+ def test_FowardingParameterNode
+ assert_prism_eval("def prism_test_forwarding_parameter_node(...); end")
+ end
+
+ def test_KeywordRestParameterNode
+ assert_prism_eval("def prism_test_keyword_rest_parameter_node(a, **b); end")
+ assert_prism_eval("Object.tap { |**| }")
+
+ # Test that KeywordRestParameterNode creates a copy
+ assert_prism_eval(<<~RUBY)
+ hash = {}
+ o = Object.new
+ def o.foo(**a) = a[:foo] = 1
+
+ o.foo(**hash)
+ hash
+ RUBY
+ end
+
+ def test_NoKeywordsParameterNode
+ assert_prism_eval("def prism_test_no_keywords(**nil); end")
+ assert_prism_eval("def prism_test_no_keywords(a, b = 2, **nil); end")
+ end
+
+ def test_OptionalParameterNode
+ assert_prism_eval("def prism_test_optional_param_node(bar = nil); end")
+ end
+
+ def test_OptionalKeywordParameterNode
+ assert_prism_eval("def prism_test_optional_keyword_param_node(bar: nil); end")
+
+ # Test with optional argument and method call in OptionalKeywordParameterNode
+ assert_prism_eval(<<~RUBY)
+ o = Object.new
+ def o.foo = 1
+ def o.bar(a = nil, b: foo) = b
+ o.bar
+ RUBY
+ end
+
+ def test_ParametersNode
+ assert_prism_eval("def prism_test_parameters_node(bar, baz); end")
+ assert_prism_eval("def prism_test_parameters_node(a, b = 2); end")
+ end
+
+ def test_RequiredParameterNode
+ assert_prism_eval("def prism_test_required_param_node(bar); end")
+ assert_prism_eval("def prism_test_required_param_node(foo, bar); end")
+ end
+
+ def test_RequiredKeywordParameterNode
+ assert_prism_eval("def prism_test_required_param_node(bar:); end")
+ assert_prism_eval("def prism_test_required_param_node(foo:, bar:); end")
+ assert_prism_eval("-> a, b = 1, c:, d:, &e { a }")
+ end
+
+ def test_RestParameterNode
+ assert_prism_eval("def prism_test_rest_parameter_node(*a); end")
+ end
+
+ def test_UndefNode
+ assert_prism_eval("def prism_undef_node_1; end; undef prism_undef_node_1")
+ assert_prism_eval(<<-HERE
+ def prism_undef_node_2
+ end
+ def prism_undef_node_3
+ end
+ undef prism_undef_node_2, prism_undef_node_3
+ HERE
+ )
+ assert_prism_eval(<<-HERE
+ def prism_undef_node_4
+ end
+ undef :'prism_undef_node_#{4}'
+ HERE
+ )
+ end
+
+ ############################################################################
+ # Pattern matching #
+ ############################################################################
+
+ def test_AlternationPatternNode
+ assert_prism_eval("1 in 1 | 2")
+ assert_prism_eval("1 in 2 | 1")
+ assert_prism_eval("1 in 2 | 3 | 4 | 1")
+ assert_prism_eval("1 in 2 | 3")
+ end
+
+ def test_ArrayPatternNode
+ assert_prism_eval("[] => []")
+
+ ["in", "=>"].each do |operator|
+ ["", "Array"].each do |constant|
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[1, 2, 3]")
+
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[*]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[1, *]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[1, 2, *]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[1, 2, 3, *]")
+
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[*foo]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[1, *foo]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[1, 2, *foo]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[1, 2, 3, *foo]")
+
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[*, 3]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[*, 2, 3]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[*, 1, 2, 3]")
+
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[*foo, 3]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[*foo, 2, 3]")
+ assert_prism_eval("[1, 2, 3] #{operator} #{constant}[*foo, 1, 2, 3]")
+ end
+ end
+
+ assert_prism_eval("begin; Object.new => [1, 2, 3]; rescue NoMatchingPatternError; true; end")
+ assert_prism_eval("begin; [1, 2, 3] => Object[1, 2, 3]; rescue NoMatchingPatternError; true; end")
+ end
+
+ def test_CapturePatternNode
+ assert_prism_eval("[1] => [Integer => foo]")
+ end
+
+ def test_CaseMatchNode
+ assert_prism_eval(<<~RUBY)
+ case [1, 2, 3]
+ in [1, 2, 3]
+ 4
+ end
+ RUBY
+
+ assert_prism_eval(<<~RUBY)
+ case { a: 5, b: 6 }
+ in [1, 2, 3]
+ 4
+ in { a: 5, b: 6 }
+ 7
+ end
+ RUBY
+
+ assert_prism_eval(<<~RUBY)
+ case [1, 2, 3, 4]
+ in [1, 2, 3]
+ 4
+ in { a: 5, b: 6 }
+ 7
+ else
+ end
+ RUBY
+
+ assert_prism_eval(<<~RUBY)
+ case [1, 2, 3, 4]
+ in [1, 2, 3]
+ 4
+ in { a: 5, b: 6 }
+ 7
+ else
+ 8
+ end
+ RUBY
+
+ assert_prism_eval(<<~RUBY)
+ case [1, 2, 3]
+ in [1, 2, 3] unless to_s
+ in [1, 2, 3] if to_s.nil?
+ in [1, 2, 3]
+ true
+ end
+ RUBY
+ end
+
+ def test_FindPatternNode
+ ["in", "=>"].each do |operator|
+ ["", "Array"].each do |constant|
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 1, 2, 3, 4, 5, *]")
+
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 1, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 3, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 5, *]")
+
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 1, 2, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 2, 3, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 3, 4, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 4, 5, *]")
+
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 1, 2, 3, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 2, 3, 4, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 3, 4, 5, *]")
+
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 1, 2, 3, 4, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 2, 3, 4, 5, *]")
+
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*foo, 3, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*foo, 3, 4, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*foo, 3, 4, 5, *]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*foo, 1, 2, 3, 4, *]")
+
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 3, *foo]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 3, 4, *foo]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 3, 4, 5, *foo]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*, 1, 2, 3, 4, *foo]")
+
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*foo, 3, *bar]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*foo, 3, 4, *bar]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*foo, 3, 4, 5, *bar]")
+ assert_prism_eval("[1, 2, 3, 4, 5] #{operator} #{constant}[*foo, 1, 2, 3, 4, *bar]")
+ end
+ end
+
+ assert_prism_eval("[1, [2, [3, [4, [5]]]]] => [*, [*, [*, [*, [*]]]]]")
+ assert_prism_eval("[1, [2, [3, [4, [5]]]]] => [1, [2, [3, [4, [5]]]]]")
+
+ assert_prism_eval("begin; Object.new => [*, 2, *]; rescue NoMatchingPatternError; true; end")
+ assert_prism_eval("begin; [1, 2, 3] => Object[*, 2, *]; rescue NoMatchingPatternError; true; end")
+ end
+
+ def test_HashPatternNode
+ assert_prism_eval("{} => {}")
+
+ [["{ ", " }"], ["Hash[", "]"]].each do |(prefix, suffix)|
+ assert_prism_eval("{} => #{prefix} **nil #{suffix}")
+
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1 #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, b: 2 #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} b: 2, c: 3 #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, b: 2, c: 3 #{suffix}")
+
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} ** #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, ** #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, b: 2, ** #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} b: 2, c: 3, ** #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, b: 2, c: 3, ** #{suffix}")
+
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} **foo #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, **foo #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, b: 2, **foo #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} b: 2, c: 3, **foo #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, b: 2, c: 3, **foo #{suffix}")
+
+ assert_prism_eval("{ a: 1 } => #{prefix} a: 1, **nil #{suffix}")
+ assert_prism_eval("{ a: 1, b: 2, c: 3 } => #{prefix} a: 1, b: 2, c: 3, **nil #{suffix}")
+ end
+
+ assert_prism_eval("{ a: { b: { c: 1 } } } => { a: { b: { c: 1 } } }")
+ end
+
+ def test_MatchPredicateNode
+ assert_prism_eval("1 in 1")
+ assert_prism_eval("1.0 in 1.0")
+ assert_prism_eval("1i in 1i")
+ assert_prism_eval("1r in 1r")
+
+ assert_prism_eval("\"foo\" in \"foo\"")
+ assert_prism_eval("\"foo \#{1}\" in \"foo \#{1}\"")
+
+ assert_prism_eval("false in false")
+ assert_prism_eval("nil in nil")
+ assert_prism_eval("self in self")
+ assert_prism_eval("true in true")
+
+ assert_prism_eval("5 in 0..10")
+ assert_prism_eval("5 in 0...10")
+
+ assert_prism_eval("[\"5\"] in %w[5]")
+
+ assert_prism_eval("Prism in Prism")
+ assert_prism_eval("Prism in ::Prism")
+
+ assert_prism_eval(":prism in :prism")
+ assert_prism_eval("%s[prism\#{1}] in %s[prism\#{1}]")
+ assert_prism_eval("\"foo\" in /.../")
+ assert_prism_eval("\"foo1\" in /...\#{1}/")
+ assert_prism_eval("4 in ->(v) { v.even? }")
+
+ assert_prism_eval("5 in foo")
+
+ assert_prism_eval("1 in 2")
+ end
+
+ def test_MatchRequiredNode
+ assert_prism_eval("1 => 1")
+ assert_prism_eval("1.0 => 1.0")
+ assert_prism_eval("1i => 1i")
+ assert_prism_eval("1r => 1r")
+
+ assert_prism_eval("\"foo\" => \"foo\"")
+ assert_prism_eval("\"foo \#{1}\" => \"foo \#{1}\"")
+
+ assert_prism_eval("false => false")
+ assert_prism_eval("nil => nil")
+ assert_prism_eval("true => true")
+
+ assert_prism_eval("5 => 0..10")
+ assert_prism_eval("5 => 0...10")
+
+ assert_prism_eval("[\"5\"] => %w[5]")
+
+ assert_prism_eval(":prism => :prism")
+ assert_prism_eval("%s[prism\#{1}] => %s[prism\#{1}]")
+ assert_prism_eval("\"foo\" => /.../")
+ assert_prism_eval("\"foo1\" => /...\#{1}/")
+ assert_prism_eval("4 => ->(v) { v.even? }")
+
+ assert_prism_eval("5 => foo")
+ end
+
+ def test_PinnedExpressionNode
+ assert_prism_eval("4 in ^(4)")
+ end
+
+ def test_PinnedVariableNode
+ assert_prism_eval("module Prism; @@prism = 1; 1 in ^@@prism; end")
+ assert_prism_eval("module Prism; @prism = 1; 1 in ^@prism; end")
+ assert_prism_eval("$prism = 1; 1 in ^$prism")
+ assert_prism_eval("prism = 1; 1 in ^prism")
+ end
+
+ ############################################################################
+ # Miscellaneous #
+ ############################################################################
+
+ def test_eval
+ assert_prism_eval("eval('1 + 1')", raw: true)
+ assert_prism_eval("a = 1; eval('a + 1')", raw: true)
+
+ assert_prism_eval(<<~CODE, raw: true)
+ def prism_eval_splat(**bar)
+ eval("bar")
+ end
+ prism_eval_splat(bar: 10)
+ CODE
+
+ assert_prism_eval(<<~CODE, raw: true)
+ def prism_eval_keywords(baz:)
+ eval("baz")
+ end
+ prism_eval_keywords(baz: 10)
+ CODE
+
+ assert_prism_eval(<<~CODE, raw: true)
+ [1].each do |a|
+ [2].each do |b|
+ c = 3
+ eval("a + b + c")
+ end
+ end
+ CODE
+
+ assert_prism_eval(<<~CODE, raw: true)
+ def prism_eval_binding(b)
+ eval("bar", b)
+ end
+
+ bar = :ok
+ prism_eval_binding(binding)
+ CODE
+ end
+
+ def test_ScopeNode
+ assert_separately(%w[], <<~'RUBY')
+ def compare_eval(source)
+ ruby_eval = RubyVM::InstructionSequence.compile("module A; " + source + "; end").eval
+ prism_eval = RubyVM::InstructionSequence.compile_prism("module B; " + source + "; end").eval
+
+ assert_equal ruby_eval, prism_eval
+ end
+
+ def assert_prism_eval(source)
+ $VERBOSE, verbose_bak = nil, $VERBOSE
+
+ begin
+ compare_eval(source)
+
+ # Test "popped" functionality
+ compare_eval("#{source}; 1")
+ ensure
+ $VERBOSE = verbose_bak
+ end
+ end
+
+ assert_prism_eval("a = 1; 1.times do; { a: }; end")
+ assert_prism_eval("a = 1; def foo(a); a; end")
+ RUBY
+ end
+
+ ############################################################################
+ # Errors #
+ ############################################################################
+
+ def test_MissingNode
+ # TODO
+ end
+
+ ############################################################################
+ # Encoding #
+ ############################################################################
+
+ def test_encoding
+ assert_prism_eval('"però"')
+ assert_prism_eval(":però")
+ end
+
+ def test_parse_file
+ assert_nothing_raised do
+ RubyVM::InstructionSequence.compile_file_prism(__FILE__)
+ end
+
+ error = assert_raise Errno::ENOENT do
+ RubyVM::InstructionSequence.compile_file_prism("idontexist.rb")
+ end
+
+ assert_equal "No such file or directory - idontexist.rb", error.message
+
+ assert_raise TypeError do
+ RubyVM::InstructionSequence.compile_file_prism(nil)
+ end
+ end
+
+ private
+
+ def compare_eval(source, raw:, location:)
+ source = raw ? source : "class Prism::TestCompilePrism\n#{source}\nend"
+
+ ruby_eval = RubyVM::InstructionSequence.compile(source).eval
+ prism_eval = RubyVM::InstructionSequence.compile_prism(source).eval
+
+ if ruby_eval.is_a? Proc
+ assert_equal ruby_eval.class, prism_eval.class, "@#{location.path}:#{location.lineno}"
+ else
+ assert_equal ruby_eval, prism_eval, "@#{location.path}:#{location.lineno}"
+ end
+ end
+
+ def assert_prism_eval(source, raw: false)
+ location = caller_locations(1, 1).first
+ $VERBOSE, verbose_bak = nil, $VERBOSE
+
+ begin
+ compare_eval(source, raw:, location:)
+
+ # Test "popped" functionality
+ compare_eval("#{source}; 1", raw:, location:)
+ ensure
+ $VERBOSE = verbose_bak
+ end
+ end
+ end
+end
diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb
index a3a7546575..c0cfb73235 100644
--- a/test/ruby/test_complex.rb
+++ b/test/ruby/test_complex.rb
@@ -221,10 +221,16 @@ class Complex_Test < Test::Unit::TestCase
assert_equal([1,2], Complex.polar(1,2).polar)
assert_equal(Complex.polar(1.0, Math::PI * 2 / 3), Complex.polar(1, Math::PI * 2 / 3))
- assert_in_out_err([], <<-'end;', ['OK'], [])
- Complex.polar(1, Complex(1, 0))
- puts :OK
- end;
+ one = 1+0i
+ c = Complex.polar(0, one)
+ assert_equal(0, c)
+ assert_predicate(c.real, :real?)
+ c = Complex.polar(one, 0)
+ assert_equal(1, c)
+ assert_predicate(c.real, :real?)
+ c = Complex.polar(one)
+ assert_equal(1, c)
+ assert_predicate(c.real, :real?)
end
def test_uplus
@@ -520,6 +526,71 @@ class Complex_Test < Test::Unit::TestCase
r = c ** Rational(-2,3)
assert_in_delta(0.432, r.real, 0.001)
assert_in_delta(-0.393, r.imag, 0.001)
+ end
+
+ def test_expt_for_special_angle
+ c = Complex(1, 0) ** 100000000000000000000000000000000
+ assert_equal(Complex(1, 0), c)
+
+ c = Complex(-1, 0) ** 10000000000000000000000000000000
+ assert_equal(Complex(1, 0), c)
+
+ c = Complex(-1, 0) ** 10000000000000000000000000000001
+ assert_equal(Complex(-1, 0), c)
+
+ c = Complex(0, 1) ** 100000000000000000000000000000000
+ assert_equal(Complex(1, 0), c)
+
+ c = Complex(0, 1) ** 100000000000000000000000000000001
+ assert_equal(Complex(0, 1), c)
+
+ c = Complex(0, 1) ** 100000000000000000000000000000002
+ assert_equal(Complex(-1, 0), c)
+
+ c = Complex(0, 1) ** 100000000000000000000000000000003
+ assert_equal(Complex(0, -1), c)
+
+ c = Complex(0, -1) ** 100000000000000000000000000000000
+ assert_equal(Complex(1, 0), c)
+
+ c = Complex(0, -1) ** 100000000000000000000000000000001
+ assert_equal(Complex(0, -1), c)
+
+ c = Complex(0, -1) ** 100000000000000000000000000000002
+ assert_equal(Complex(-1, 0), c)
+
+ c = Complex(0, -1) ** 100000000000000000000000000000003
+ assert_equal(Complex(0, 1), c)
+
+ c = Complex(1, 1) ** 1
+ assert_equal(Complex(1, 1), c)
+
+ c = Complex(1, 1) ** 2
+ assert_equal(Complex(0, 2), c)
+
+ c = Complex(1, 1) ** 3
+ assert_equal(Complex(-2, 2), c)
+
+ c = Complex(1, 1) ** 4
+ assert_equal(Complex(-4, 0), c)
+
+ c = Complex(1, 1) ** 5
+ assert_equal(Complex(-4, -4), c)
+
+ c = Complex(1, 1) ** 6
+ assert_equal(Complex(0, -8), c)
+
+ c = Complex(1, 1) ** 7
+ assert_equal(Complex(8, -8), c)
+
+ c = Complex(-2, -2) ** 3
+ assert_equal(Complex(16, -16), c)
+
+ c = Complex(2, -2) ** 3
+ assert_equal(Complex(-16, -16), c)
+
+ c = Complex(-2, 2) ** 3
+ assert_equal(Complex(16, 16), c)
c = Complex(0.0, -888888888888888.0)**8888
assert_not_predicate(c.real, :nan?)
@@ -567,20 +638,24 @@ class Complex_Test < Test::Unit::TestCase
assert_raise_with_message(TypeError, /C\u{1f5ff}/) { Complex(1).coerce(obj) }
end
- class ObjectX
- def +(x) Rational(1) end
+ class ObjectX < Numeric
+ def initialize(real = true, n = 1) @n = n; @real = real; end
+ def +(x) Rational(@n) end
alias - +
alias * +
alias / +
alias quo +
alias ** +
- def coerce(x) [x, Complex(1)] end
+ def coerce(x) [x, Complex(@n)] end
+ def real?; @real; end
end
def test_coerce2
x = ObjectX.new
- %w(+ - * / quo **).each do |op|
- assert_kind_of(Numeric, Complex(1).__send__(op, x))
+ y = ObjectX.new(false)
+ %w(+ - * / quo ** <=>).each do |op|
+ assert_kind_of(Numeric, Complex(1).__send__(op, x), op)
+ assert_kind_of(Numeric, Complex(1).__send__(op, y), op)
end
end
@@ -843,20 +918,42 @@ class Complex_Test < Test::Unit::TestCase
assert_equal(Complex(0), '_5'.to_c)
assert_equal(Complex(5), '5_'.to_c)
assert_equal(Complex(5), '5x'.to_c)
+ assert_equal(Complex(51), '5_1'.to_c)
+ assert_equal(Complex(5), '5__1'.to_c)
assert_equal(Complex(5), '5+_3i'.to_c)
assert_equal(Complex(5), '5+3_i'.to_c)
assert_equal(Complex(5,3), '5+3i_'.to_c)
assert_equal(Complex(5,3), '5+3ix'.to_c)
+ assert_equal(Complex(5,31), '5+3_1i'.to_c)
+ assert_equal(Complex(5), '5+3__1i'.to_c)
+ assert_equal(Complex(51), Complex('5_1'))
+ assert_equal(Complex(5,31), Complex('5+3_1i'))
+ assert_equal(Complex(5,31), Complex('5+3_1I'))
+ assert_equal(Complex(5,31), Complex('5+3_1j'))
+ assert_equal(Complex(5,31), Complex('5+3_1J'))
+ assert_equal(Complex(0,31), Complex('3_1i'))
+ assert_equal(Complex(0,31), Complex('3_1I'))
+ assert_equal(Complex(0,31), Complex('3_1j'))
+ assert_equal(Complex(0,31), Complex('3_1J'))
assert_raise(ArgumentError){ Complex('')}
assert_raise(ArgumentError){ Complex('_')}
assert_raise(ArgumentError){ Complex("\f\n\r\t\v5\0")}
assert_raise(ArgumentError){ Complex('_5')}
assert_raise(ArgumentError){ Complex('5_')}
+ assert_raise(ArgumentError){ Complex('5__1')}
assert_raise(ArgumentError){ Complex('5x')}
assert_raise(ArgumentError){ Complex('5+_3i')}
assert_raise(ArgumentError){ Complex('5+3_i')}
assert_raise(ArgumentError){ Complex('5+3i_')}
assert_raise(ArgumentError){ Complex('5+3ix')}
+ assert_raise(ArgumentError){ Complex('5+3__1i')}
+ assert_raise(ArgumentError){ Complex('5+3__1I')}
+ assert_raise(ArgumentError){ Complex('5+3__1j')}
+ assert_raise(ArgumentError){ Complex('5+3__1J')}
+ assert_raise(ArgumentError){ Complex('3__1i')}
+ assert_raise(ArgumentError){ Complex('3__1I')}
+ assert_raise(ArgumentError){ Complex('3__1j')}
+ assert_raise(ArgumentError){ Complex('3__1J')}
assert_equal(Complex(Rational(1,5)), '1/5'.to_c)
assert_equal(Complex(Rational(-1,5)), '-1/5'.to_c)
@@ -883,31 +980,27 @@ class Complex_Test < Test::Unit::TestCase
}
end
- def test_Complex_without_exception
- assert_nothing_raised(ArgumentError){
- assert_equal(nil, Complex('5x', exception: false))
- }
- assert_nothing_raised(ArgumentError){
- assert_equal(nil, Complex(nil, exception: false))
- }
- assert_nothing_raised(ArgumentError){
- assert_equal(nil, Complex(Object.new, exception: false))
- }
- assert_nothing_raised(ArgumentError){
- assert_equal(nil, Complex(1, nil, exception: false))
- }
- assert_nothing_raised(ArgumentError){
- assert_equal(nil, Complex(1, Object.new, exception: false))
- }
+ def assert_complex_with_exception(error, *args, message: "")
+ assert_raise(error, message) do
+ Complex(*args, exception: true)
+ end
+ assert_nothing_raised(error, message) do
+ assert_nil(Complex(*args, exception: false))
+ assert_nil($!)
+ end
+ end
+
+ def test_Complex_with_exception
+ assert_complex_with_exception(ArgumentError, '5x')
+ assert_complex_with_exception(TypeError, nil)
+ assert_complex_with_exception(TypeError, Object.new)
+ assert_complex_with_exception(TypeError, 1, nil)
+ assert_complex_with_exception(TypeError, 1, Object.new)
o = Object.new
def o.to_c; raise; end
- assert_nothing_raised(ArgumentError){
- assert_equal(nil, Complex(o, exception: false))
- }
- assert_nothing_raised(ArgumentError){
- assert_equal(nil, Complex(1, o, exception: false))
- }
+ assert_complex_with_exception(RuntimeError, o)
+ assert_complex_with_exception(TypeError, 1, o)
end
def test_respond
@@ -961,6 +1054,29 @@ class Complex_Test < Test::Unit::TestCase
assert_raise(RangeError){Rational(Complex(3,2))}
end
+ def test_to_r_with_float
+ assert_equal(Rational(3), Complex(3, 0.0).to_r)
+ assert_raise(RangeError){Complex(3, 1.0).to_r}
+ end
+
+ def test_to_r_with_numeric_obj
+ c = Class.new(Numeric)
+
+ num = 0
+ c.define_method(:to_s) { num.to_s }
+ c.define_method(:==) { num == it }
+ c.define_method(:<) { num < it }
+
+ o = c.new
+ assert_equal(Rational(3), Complex(3, o).to_r)
+
+ num = 1
+ assert_raise(RangeError){Complex(3, o).to_r}
+
+ c.define_method(:to_r) { 0r }
+ assert_equal(Rational(3), Complex(3, o).to_r)
+ end
+
def test_to_c
c = nil.to_c
assert_equal([0,0], [c.real, c.imag])
@@ -1135,15 +1251,34 @@ class Complex_Test < Test::Unit::TestCase
end
def test_canonicalize_polar
- obj = Class.new(Numeric) do
- def initialize
- @x = 2
+ error = "not a real"
+ assert_raise_with_message(TypeError, error) do
+ Complex.polar(1i)
+ end
+ assert_raise_with_message(TypeError, error) do
+ Complex.polar(1i, 0)
+ end
+ assert_raise_with_message(TypeError, error) do
+ Complex.polar(0, 1i)
+ end
+ n = Class.new(Numeric) do
+ def initialize(x = 1)
+ @x = x
end
def real?
(@x -= 1) > 0
end
- end.new
- assert_raise(TypeError) do
+ end
+ obj = n.new
+ assert_raise_with_message(TypeError, error) do
+ Complex.polar(obj)
+ end
+ obj = n.new
+ assert_raise_with_message(TypeError, error) do
+ Complex.polar(obj, 0)
+ end
+ obj = n.new
+ assert_raise_with_message(TypeError, error) do
Complex.polar(1, obj)
end
end
diff --git a/test/ruby/test_continuation.rb b/test/ruby/test_continuation.rb
index 8c62d20840..612dbf28c9 100644
--- a/test/ruby/test_continuation.rb
+++ b/test/ruby/test_continuation.rb
@@ -4,6 +4,10 @@ EnvUtil.suppress_warning {require 'continuation'}
require 'fiber'
class TestContinuation < Test::Unit::TestCase
+ def setup
+ omit 'requires callcc support' unless respond_to?(:callcc)
+ end
+
def test_create
assert_equal(:ok, callcc{:ok})
assert_equal(:ok, callcc{|c| c.call :ok})
diff --git a/test/ruby/test_data.rb b/test/ruby/test_data.rb
new file mode 100644
index 0000000000..bb38f8ec91
--- /dev/null
+++ b/test/ruby/test_data.rb
@@ -0,0 +1,283 @@
+# -*- coding: us-ascii -*-
+# frozen_string_literal: false
+require 'test/unit'
+require 'timeout'
+
+class TestData < Test::Unit::TestCase
+ def test_define
+ klass = Data.define(:foo, :bar)
+ assert_kind_of(Class, klass)
+ assert_equal(%i[foo bar], klass.members)
+
+ assert_raise(NoMethodError) { Data.new(:foo) }
+ assert_raise(TypeError) { Data.define(0) }
+
+ # Because some code is shared with Struct, check we don't share unnecessary functionality
+ assert_raise(TypeError) { Data.define(:foo, keyword_init: true) }
+
+ assert_not_respond_to(Data.define, :define, "Cannot define from defined Data class")
+ end
+
+ def test_define_edge_cases
+ # non-ascii
+ klass = Data.define(:"r\u{e9}sum\u{e9}")
+ o = klass.new(1)
+ assert_equal(1, o.send(:"r\u{e9}sum\u{e9}"))
+
+ # junk string
+ klass = Data.define(:"a\000")
+ o = klass.new(1)
+ assert_equal(1, o.send(:"a\000"))
+
+ # special characters in attribute names
+ klass = Data.define(:a, :b?)
+ x = Object.new
+ o = klass.new("test", x)
+ assert_same(x, o.b?)
+
+ klass = Data.define(:a, :b!)
+ x = Object.new
+ o = klass.new("test", x)
+ assert_same(x, o.b!)
+
+ assert_raise(ArgumentError) { Data.define(:x=) }
+ assert_raise(ArgumentError, /duplicate member/) { Data.define(:x, :x) }
+ end
+
+ def test_define_with_block
+ klass = Data.define(:a, :b) do
+ def c
+ a + b
+ end
+ end
+
+ assert_equal(3, klass.new(1, 2).c)
+ end
+
+ def test_initialize
+ klass = Data.define(:foo, :bar)
+
+ # Regular
+ test = klass.new(1, 2)
+ assert_equal(1, test.foo)
+ assert_equal(2, test.bar)
+ assert_equal(test, klass.new(1, 2))
+ assert_predicate(test, :frozen?)
+
+ # Keywords
+ test_kw = klass.new(foo: 1, bar: 2)
+ assert_equal(1, test_kw.foo)
+ assert_equal(2, test_kw.bar)
+ assert_equal(test_kw, klass.new(foo: 1, bar: 2))
+ assert_equal(test_kw, test)
+
+ # Wrong protocol
+ assert_raise(ArgumentError) { klass.new(1) }
+ assert_raise(ArgumentError) { klass.new(1, 2, 3) }
+ assert_raise(ArgumentError) { klass.new(foo: 1) }
+ assert_raise(ArgumentError) { klass.new(foo: 1, bar: 2, baz: 3) }
+ # Could be converted to foo: 1, bar: 2, but too smart is confusing
+ assert_raise(ArgumentError) { klass.new(1, bar: 2) }
+ end
+
+ def test_initialize_redefine
+ klass = Data.define(:foo, :bar) do
+ attr_reader :passed
+
+ def initialize(*args, **kwargs)
+ @passed = [args, kwargs]
+ super(foo: 1, bar: 2) # so we can experiment with passing wrong numbers of args
+ end
+ end
+
+ assert_equal([[], {foo: 1, bar: 2}], klass.new(foo: 1, bar: 2).passed)
+
+ # Positional arguments are converted to keyword ones
+ assert_equal([[], {foo: 1, bar: 2}], klass.new(1, 2).passed)
+
+ # Missing arguments can be fixed in initialize
+ assert_equal([[], {foo: 1}], klass.new(foo: 1).passed)
+ assert_equal([[], {foo: 42}], klass.new(42).passed)
+
+ # Extra keyword arguments can be dropped in initialize
+ assert_equal([[], {foo: 1, bar: 2, baz: 3}], klass.new(foo: 1, bar: 2, baz: 3).passed)
+ end
+
+ def test_instance_behavior
+ klass = Data.define(:foo, :bar)
+
+ test = klass.new(1, 2)
+ assert_equal(1, test.foo)
+ assert_equal(2, test.bar)
+ assert_equal(%i[foo bar], test.members)
+ assert_equal(1, test.public_send(:foo))
+ assert_equal(0, test.method(:foo).arity)
+ assert_equal([], test.method(:foo).parameters)
+
+ assert_equal({foo: 1, bar: 2}, test.to_h)
+ assert_equal({"foo"=>"1", "bar"=>"2"}, test.to_h { [_1.to_s, _2.to_s] })
+
+ assert_equal([1, 2], test.deconstruct)
+ assert_equal({foo: 1, bar: 2}, test.deconstruct_keys(nil))
+ assert_equal({foo: 1}, test.deconstruct_keys(%i[foo]))
+ assert_equal({foo: 1}, test.deconstruct_keys(%i[foo baz]))
+ assert_equal({}, test.deconstruct_keys(%i[foo bar baz]))
+ assert_raise(TypeError) { test.deconstruct_keys(0) }
+
+ assert_kind_of(Integer, test.hash)
+ end
+
+ def test_hash
+ measure = Data.define(:amount, :unit)
+
+ assert_equal(measure[1, 'km'].hash, measure[1, 'km'].hash)
+ assert_not_equal(measure[1, 'km'].hash, measure[10, 'km'].hash)
+ assert_not_equal(measure[1, 'km'].hash, measure[1, 'm'].hash)
+ assert_not_equal(measure[1, 'km'].hash, measure[1.0, 'km'].hash)
+
+ # Structurally similar data class, but shouldn't be considered
+ # the same hash key
+ measurement = Data.define(:amount, :unit)
+
+ assert_not_equal(measure[1, 'km'].hash, measurement[1, 'km'].hash)
+ end
+
+ def test_inspect
+ klass = Data.define(:a)
+ o = klass.new(1)
+ assert_equal("#<data a=1>", o.inspect)
+
+ Object.const_set(:Foo, klass)
+ assert_equal("#<data Foo a=1>", o.inspect)
+ Object.instance_eval { remove_const(:Foo) }
+
+ klass = Data.define(:@a)
+ o = klass.new(1)
+ assert_equal("#<data :@a=1>", o.inspect)
+ end
+
+ def test_equal
+ klass1 = Data.define(:a)
+ klass2 = Data.define(:a)
+ o1 = klass1.new(1)
+ o2 = klass1.new(1)
+ o3 = klass2.new(1)
+ assert_equal(o1, o2)
+ assert_not_equal(o1, o3)
+ end
+
+ def test_eql
+ klass1 = Data.define(:a)
+ klass2 = Data.define(:a)
+ o1 = klass1.new(1)
+ o2 = klass1.new(1)
+ o3 = klass2.new(1)
+ assert_operator(o1, :eql?, o2)
+ assert_not_operator(o1, :eql?, o3)
+ end
+
+ def test_with
+ klass = Data.define(:foo, :bar)
+ source = klass.new(foo: 1, bar: 2)
+
+ # Simple
+ test = source.with
+ assert_equal(source.object_id, test.object_id)
+
+ # Changes
+ test = source.with(foo: 10)
+
+ assert_equal(1, source.foo)
+ assert_equal(2, source.bar)
+ assert_equal(source, klass.new(foo: 1, bar: 2))
+
+ assert_equal(10, test.foo)
+ assert_equal(2, test.bar)
+ assert_equal(test, klass.new(foo: 10, bar: 2))
+
+ test = source.with(foo: 10, bar: 20)
+
+ assert_equal(1, source.foo)
+ assert_equal(2, source.bar)
+ assert_equal(source, klass.new(foo: 1, bar: 2))
+
+ assert_equal(10, test.foo)
+ assert_equal(20, test.bar)
+ assert_equal(test, klass.new(foo: 10, bar: 20))
+
+ # Keyword splat
+ changes = { foo: 10, bar: 20 }
+ test = source.with(**changes)
+
+ assert_equal(1, source.foo)
+ assert_equal(2, source.bar)
+ assert_equal(source, klass.new(foo: 1, bar: 2))
+
+ assert_equal(10, test.foo)
+ assert_equal(20, test.bar)
+ assert_equal(test, klass.new(foo: 10, bar: 20))
+
+ # Wrong protocol
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given 1, expected 0)") do
+ source.with(10)
+ end
+ assert_raise_with_message(ArgumentError, "unknown keywords: :baz, :quux") do
+ source.with(foo: 1, bar: 2, baz: 3, quux: 4)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given 1, expected 0)") do
+ source.with(1, bar: 2)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given 2, expected 0)") do
+ source.with(1, 2)
+ end
+ assert_raise_with_message(ArgumentError, "wrong number of arguments (given 1, expected 0)") do
+ source.with({ bar: 2 })
+ end
+ end
+
+ def test_with_initialize
+ oddclass = Data.define(:odd) do
+ def initialize(odd:)
+ raise ArgumentError, "Not odd" unless odd.odd?
+ super(odd: odd)
+ end
+ end
+ assert_raise_with_message(ArgumentError, "Not odd") {
+ oddclass.new(odd: 0)
+ }
+ odd = oddclass.new(odd: 1)
+ assert_raise_with_message(ArgumentError, "Not odd") {
+ odd.with(odd: 2)
+ }
+ end
+
+ def test_memberless
+ klass = Data.define
+
+ test = klass.new
+
+ assert_equal(klass.new, test)
+ assert_not_equal(Data.define.new, test)
+
+ assert_equal('#<data >', test.inspect)
+ assert_equal([], test.members)
+ assert_equal({}, test.to_h)
+ end
+
+ def test_dup
+ klass = Data.define(:foo, :bar)
+ test = klass.new(foo: 1, bar: 2)
+ assert_equal(klass.new(foo: 1, bar: 2), test.dup)
+ assert_predicate(test.dup, :frozen?)
+ end
+
+ Klass = Data.define(:foo, :bar)
+
+ def test_marshal
+ test = Klass.new(foo: 1, bar: 2)
+ loaded = Marshal.load(Marshal.dump(test))
+ assert_equal(test, loaded)
+ assert_not_same(test, loaded)
+ assert_predicate(loaded, :frozen?)
+ end
+end
diff --git a/test/ruby/test_default_gems.rb b/test/ruby/test_default_gems.rb
index 467e5ecf83..b82e304cbd 100644
--- a/test/ruby/test_default_gems.rb
+++ b/test/ruby/test_default_gems.rb
@@ -2,15 +2,28 @@
require 'rubygems'
class TestDefaultGems < Test::Unit::TestCase
+ def self.load(file)
+ code = File.read(file, mode: "r:UTF-8:-", &:read)
+
+ # These regex patterns are from load_gemspec method of rbinstall.rb.
+ # - `git ls-files` is useless under ruby's repository
+ # - `2>/dev/null` works only on Unix-like platforms
+ code.gsub!(/(?:`git[^\`]*`|%x\[git[^\]]*\])\.split\([^\)]*\)/m, '[]')
+ code.gsub!(/IO\.popen\(.*git.*?\)/, '[] || itself')
+
+ eval(code, binding, file)
+ end
def test_validate_gemspec
- omit "git not found" unless system("git", "rev-parse", %i[out err]=>IO::NULL)
srcdir = File.expand_path('../../..', __FILE__)
- Dir.glob("#{srcdir}/{lib,ext}/**/*.gemspec").map do |src|
- assert_nothing_raised do
- raise("invalid spec in #{src}") unless Gem::Specification.load(src)
+ specs = 0
+ Dir.chdir(srcdir) do
+ all_assertions_foreach(nil, *Dir["{lib,ext}/**/*.gemspec"]) do |src|
+ specs += 1
+ assert_kind_of(Gem::Specification, self.class.load(src), "invalid spec in #{src}")
end
end
+ assert_operator specs, :>, 0, "gemspecs not found"
end
end
diff --git a/test/ruby/test_defined.rb b/test/ruby/test_defined.rb
index 3324a09afe..0505bdada6 100644
--- a/test/ruby/test_defined.rb
+++ b/test/ruby/test_defined.rb
@@ -127,6 +127,18 @@ class TestDefined < Test::Unit::TestCase
assert_equal nil, defined?($2)
end
+ def test_defined_assignment
+ assert_equal("assignment", defined?(a = 1))
+ assert_equal("assignment", defined?(a += 1))
+ assert_equal("assignment", defined?(a &&= 1))
+ assert_equal("assignment", eval('defined?(A = 1)'))
+ assert_equal("assignment", eval('defined?(A += 1)'))
+ assert_equal("assignment", eval('defined?(A &&= 1)'))
+ assert_equal("assignment", eval('defined?(A::B = 1)'))
+ assert_equal("assignment", eval('defined?(A::B += 1)'))
+ assert_equal("assignment", eval('defined?(A::B &&= 1)'))
+ end
+
def test_defined_literal
assert_equal("nil", defined?(nil))
assert_equal("true", defined?(true))
@@ -303,6 +315,20 @@ class TestDefined < Test::Unit::TestCase
assert_equal("super", o.x, bug8367)
end
+ def test_super_in_basic_object
+ BasicObject.class_eval do
+ def a
+ defined?(super)
+ end
+ end
+
+ assert_nil(a)
+ ensure
+ BasicObject.class_eval do
+ undef_method :a if defined?(a)
+ end
+ end
+
def test_super_toplevel
assert_separately([], "assert_nil(defined?(super))")
end
diff --git a/test/ruby/test_dir.rb b/test/ruby/test_dir.rb
index 514c6e5921..2cc1c3ef4a 100644
--- a/test/ruby/test_dir.rb
+++ b/test/ruby/test_dir.rb
@@ -19,11 +19,21 @@ class TestDir < Test::Unit::TestCase
@dirs << File.join(i, "")
end
end
+ @envs = nil
end
def teardown
$VERBOSE = @verbose
FileUtils.remove_entry_secure @root if File.directory?(@root)
+ ENV.update(@envs) if @envs
+ end
+
+ def setup_envs(envs = %w"HOME LOGDIR")
+ @envs ||= {}
+ envs.each do |e, v|
+ @envs[e] = ENV.delete(e)
+ ENV[e] = v if v
+ end
end
def test_seek
@@ -86,33 +96,31 @@ class TestDir < Test::Unit::TestCase
d.close
end
- def test_chdir
+ def test_class_chdir
pwd = Dir.pwd
- env_home = ENV["HOME"]
- env_logdir = ENV["LOGDIR"]
- ENV.delete("HOME")
- ENV.delete("LOGDIR")
+ setup_envs
assert_raise(Errno::ENOENT) { Dir.chdir(@nodir) }
assert_raise(ArgumentError) { Dir.chdir }
ENV["HOME"] = pwd
Dir.chdir do
- assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(pwd) }
+ conflicting = /conflicting chdir during another chdir block\n^#{Regexp.quote(__FILE__)}:#{__LINE__-1}:/
+ assert_warning(conflicting) { Dir.chdir(pwd) }
- assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(@root) }
+ assert_warning(conflicting) { Dir.chdir(@root) }
assert_equal(@root, Dir.pwd)
- assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(pwd) }
+ assert_warning(conflicting) { Dir.chdir(pwd) }
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; Dir.chdir(@root) }.join }
assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; Dir.chdir(@root) { } }.join }
- assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(pwd) }
+ assert_warning(conflicting) { Dir.chdir(pwd) }
- assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(@root) }
+ assert_warning(conflicting) { Dir.chdir(@root) }
assert_equal(@root, Dir.pwd)
- assert_warning(/conflicting chdir during another chdir block/) { Dir.chdir(pwd) }
+ assert_warning(conflicting) { Dir.chdir(pwd) }
Dir.chdir(@root) do
assert_equal(@root, Dir.pwd)
end
@@ -125,8 +133,73 @@ class TestDir < Test::Unit::TestCase
rescue
abort("cannot return the original directory: #{ pwd }")
end
- ENV["HOME"] = env_home
- ENV["LOGDIR"] = env_logdir
+ end
+
+ def test_instance_chdir
+ pwd = Dir.pwd
+ dir = Dir.new(pwd)
+ root_dir = Dir.new(@root)
+ setup_envs
+
+ ENV["HOME"] = pwd
+ ret = root_dir.chdir do |*a|
+ conflicting = /conflicting chdir during another chdir block\n^#{Regexp.quote(__FILE__)}:#{__LINE__-1}:/
+
+ assert_empty(a)
+
+ assert_warning(conflicting) { dir.chdir }
+ assert_warning(conflicting) { root_dir.chdir }
+
+ assert_equal(@root, Dir.pwd)
+
+ assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; dir.chdir }.join }
+ assert_raise(RuntimeError) { Thread.new { Thread.current.report_on_exception = false; dir.chdir{} }.join }
+
+ assert_warning(conflicting) { dir.chdir }
+ assert_equal(pwd, Dir.pwd)
+
+ assert_warning(conflicting) { root_dir.chdir }
+ assert_equal(@root, Dir.pwd)
+
+ assert_warning(conflicting) { dir.chdir }
+
+ root_dir.chdir do
+ assert_equal(@root, Dir.pwd)
+ end
+ assert_equal(pwd, Dir.pwd)
+
+ 42
+ end
+
+ assert_separately(["-", @root], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ root = ARGV.shift
+
+ $dir_warnings = []
+
+ def Warning.warn(message)
+ $dir_warnings << message
+ end
+
+ line2 = line1 = __LINE__; Dir.chdir(root) do
+ line2 = __LINE__; Dir.chdir
+ end
+
+ message = $dir_warnings.shift
+ assert_include(message, "#{__FILE__}:#{line2}:")
+ assert_include(message, "#{__FILE__}:#{line1}:")
+ assert_empty($dir_warnings)
+ end;
+
+ assert_equal(42, ret)
+ ensure
+ begin
+ assert_equal(0, dir.chdir)
+ rescue
+ abort("cannot return the original directory: #{ pwd }")
+ end
+ dir.close
+ root_dir.close
end
def test_chdir_conflict
@@ -259,6 +332,20 @@ class TestDir < Test::Unit::TestCase
end
end
+ def test_glob_recursive_with_brace
+ Dir.chdir(@root) do
+ bug19042 = '[ruby-core:110220] [Bug #19042]'
+ %w"c/dir_a c/dir_b c/dir_b/dir".each do |d|
+ Dir.mkdir(d)
+ end
+ expected = %w"c/dir_a/file c/dir_b/dir/file"
+ expected.each do |f|
+ File.write(f, "")
+ end
+ assert_equal(expected, Dir.glob("**/{dir_a,dir_b/dir}/file"), bug19042)
+ end
+ end
+
def test_glob_order
Dir.chdir(@root) do
assert_equal(["#{@root}/a", "#{@root}/b"], Dir.glob("#{@root}/[ba]"))
@@ -502,13 +589,62 @@ class TestDir < Test::Unit::TestCase
assert_include(Dir.glob(wild, File::FNM_SHORTNAME), long, bug10819)
assert_empty(entries - Dir.glob("#{wild}/Common*", File::FNM_SHORTNAME), bug10819)
end
+
+ def test_home_windows
+ setup_envs(%w[HOME USERPROFILE HOMEDRIVE HOMEPATH])
+
+ ENV['HOME'] = "C:\\ruby\\home"
+ assert_equal("C:/ruby/home", Dir.home)
+
+ ENV['USERPROFILE'] = "C:\\ruby\\userprofile"
+ assert_equal("C:/ruby/home", Dir.home)
+ ENV.delete('HOME')
+ assert_equal("C:/ruby/userprofile", Dir.home)
+
+ ENV['HOMEDRIVE'] = "C:"
+ ENV['HOMEPATH'] = "\\ruby\\homepath"
+ assert_equal("C:/ruby/userprofile", Dir.home)
+ ENV.delete('USERPROFILE')
+ assert_equal("C:/ruby/homepath", Dir.home)
+ end
+
+ def test_home_at_startup_windows
+ env = {'HOME' => "C:\\ruby\\home"}
+ args = [env]
+ assert_separately(args, "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_equal("C:/ruby/home", Dir.home)
+ end;
+
+ env['USERPROFILE'] = "C:\\ruby\\userprofile"
+ assert_separately(args, "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_equal("C:/ruby/home", Dir.home)
+ end;
+
+ env['HOME'] = nil
+ assert_separately(args, "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_equal("C:/ruby/userprofile", Dir.home)
+ end;
+
+ env['HOMEDRIVE'] = "C:"
+ env['HOMEPATH'] = "\\ruby\\homepath"
+ assert_separately(args, "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_equal("C:/ruby/userprofile", Dir.home)
+ end;
+
+ env['USERPROFILE'] = nil
+ assert_separately(args, "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_equal("C:/ruby/homepath", Dir.home)
+ end;
+ end
end
def test_home
- env_home = ENV["HOME"]
- env_logdir = ENV["LOGDIR"]
- ENV.delete("HOME")
- ENV.delete("LOGDIR")
+ setup_envs
ENV["HOME"] = @nodir
assert_nothing_raised(ArgumentError) do
@@ -526,9 +662,16 @@ class TestDir < Test::Unit::TestCase
%W[no:such:user \u{7559 5b88}:\u{756a}].each do |user|
assert_raise_with_message(ArgumentError, /#{user}/) {Dir.home(user)}
end
- ensure
- ENV["HOME"] = env_home
- ENV["LOGDIR"] = env_logdir
+ end
+
+ if Encoding.find("filesystem") == Encoding::UTF_8
+ # On Windows and macOS, file system encoding is always UTF-8.
+ def test_home_utf8
+ setup_envs
+
+ ENV["HOME"] = "/\u{e4}~\u{1f3e0}"
+ assert_equal("/\u{e4}~\u{1f3e0}", Dir.home)
+ end
end
def test_symlinks_not_resolved
@@ -559,6 +702,21 @@ class TestDir < Test::Unit::TestCase
}
end
+ def test_for_fd
+ if Dir.respond_to? :for_fd
+ begin
+ new_dir = Dir.new('..')
+ for_fd_dir = Dir.for_fd(new_dir.fileno)
+ assert_equal(new_dir.chdir{Dir.pwd}, for_fd_dir.chdir{Dir.pwd})
+ ensure
+ new_dir&.close
+ for_fd_dir&.close
+ end
+ else
+ assert_raise(NotImplementedError) { Dir.for_fd(0) }
+ end
+ end
+
def test_empty?
assert_not_send([Dir, :empty?, @root])
a = File.join(@root, "a")
diff --git a/test/ruby/test_dir_m17n.rb b/test/ruby/test_dir_m17n.rb
index 67bad8a514..cdf8b44ef2 100644
--- a/test/ruby/test_dir_m17n.rb
+++ b/test/ruby/test_dir_m17n.rb
@@ -56,7 +56,7 @@ class TestDir_M17N < Test::Unit::TestCase
return if Bug::File::Fs.fsname(Dir.tmpdir) == "apfs"
with_tmpdir {|d|
assert_separately(%w[-EASCII-8BIT], <<-'EOS', :chdir=>d)
- filename = "\xff".force_encoding("ASCII-8BIT") # invalid byte sequence as UTF-8
+ filename = "\xff".dup.force_encoding("ASCII-8BIT") # invalid byte sequence as UTF-8
File.open(filename, "w") {}
opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
ents = Dir.entries(".", **(opts||{}))
@@ -64,7 +64,7 @@ class TestDir_M17N < Test::Unit::TestCase
assert_include(ents, filename)
EOS
assert_separately(%w[-EUTF-8], <<-'EOS', :chdir=>d)
- filename = "\xff".force_encoding("UTF-8") # invalid byte sequence as UTF-8
+ filename = "\xff".dup.force_encoding("UTF-8") # invalid byte sequence as UTF-8
File.open(filename, "w") {}
opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
ents = Dir.entries(".", **(opts||{}))
@@ -77,7 +77,7 @@ class TestDir_M17N < Test::Unit::TestCase
def test_filename_as_bytes_extutf8
with_tmpdir {|d|
assert_separately(%w[-EUTF-8], <<-'EOS', :chdir=>d)
- filename = "\xc2\xa1".force_encoding("utf-8")
+ filename = "\xc2\xa1".dup.force_encoding("utf-8")
File.open(filename, "w") {}
opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
ents = Dir.entries(".", **(opts||{}))
@@ -85,9 +85,9 @@ class TestDir_M17N < Test::Unit::TestCase
EOS
assert_separately(%w[-EUTF-8], <<-'EOS', :chdir=>d)
if /mswin|mingw|darwin/ =~ RUBY_PLATFORM
- filename = "\x8f\xa2\xc2".force_encoding("euc-jp")
+ filename = "\x8f\xa2\xc2".dup.force_encoding("euc-jp")
else
- filename = "\xc2\xa1".force_encoding("euc-jp")
+ filename = "\xc2\xa1".dup.force_encoding("euc-jp")
end
assert_nothing_raised(Errno::ENOENT) do
open(filename) {}
@@ -96,8 +96,8 @@ class TestDir_M17N < Test::Unit::TestCase
# no meaning test on windows
unless /mswin|mingw|darwin/ =~ RUBY_PLATFORM
assert_separately(%W[-EUTF-8], <<-'EOS', :chdir=>d)
- filename1 = "\xc2\xa1".force_encoding("utf-8")
- filename2 = "\xc2\xa1".force_encoding("euc-jp")
+ filename1 = "\xc2\xa1".dup.force_encoding("utf-8")
+ filename2 = "\xc2\xa1".dup.force_encoding("euc-jp")
filename3 = filename1.encode("euc-jp")
filename4 = filename2.encode("utf-8")
assert_file.stat(filename1)
@@ -121,13 +121,13 @@ class TestDir_M17N < Test::Unit::TestCase
assert_include(ents, filename)
EOS
assert_separately(%w[-EUTF-8:EUC-JP], <<-'EOS', :chdir=>d)
- filename = "\xA4\xA2".force_encoding("euc-jp")
+ filename = "\xA4\xA2".dup.force_encoding("euc-jp")
opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
ents = Dir.entries(".", **(opts||{}))
assert_include(ents, filename)
EOS
assert_separately(%w[-EUTF-8:EUC-JP], <<-'EOS', :chdir=>d)
- filename = "\xA4\xA2".force_encoding("euc-jp")
+ filename = "\xA4\xA2".dup.force_encoding("euc-jp")
assert_nothing_raised(Errno::ENOENT) do
open(filename) {}
end
@@ -149,7 +149,7 @@ class TestDir_M17N < Test::Unit::TestCase
EOS
assert_separately(%w[-EUTF-8:EUC-JP], <<-'EOS', :chdir=>d)
filename1 = "\u2661" # WHITE HEART SUIT which is not representable in EUC-JP
- filename2 = "\xA4\xA2".force_encoding("euc-jp") # HIRAGANA LETTER A in EUC-JP
+ filename2 = "\xA4\xA2".dup.force_encoding("euc-jp") # HIRAGANA LETTER A in EUC-JP
opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
ents = Dir.entries(".", **(opts||{}))
assert_include(ents, filename1)
@@ -158,7 +158,7 @@ class TestDir_M17N < Test::Unit::TestCase
assert_separately(%w[-EUTF-8:EUC-JP], <<-'EOS', :chdir=>d)
filename1 = "\u2661" # WHITE HEART SUIT which is not representable in EUC-JP
filename2 = "\u3042" # HIRAGANA LETTER A which is representable in EUC-JP
- filename3 = "\xA4\xA2".force_encoding("euc-jp") # HIRAGANA LETTER A in EUC-JP
+ filename3 = "\xA4\xA2".dup.force_encoding("euc-jp") # HIRAGANA LETTER A in EUC-JP
assert_file.stat(filename1)
assert_file.stat(filename2)
assert_file.stat(filename3)
@@ -172,7 +172,7 @@ class TestDir_M17N < Test::Unit::TestCase
return if /cygwin/ =~ RUBY_PLATFORM
with_tmpdir {|d|
assert_separately(%w[-EEUC-JP], <<-'EOS', :chdir=>d)
- filename = "\xA4\xA2".force_encoding("euc-jp")
+ filename = "\xA4\xA2".dup.force_encoding("euc-jp")
File.open(filename, "w") {}
opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
ents = Dir.entries(".", **(opts||{}))
@@ -189,7 +189,7 @@ class TestDir_M17N < Test::Unit::TestCase
return if /cygwin/ =~ RUBY_PLATFORM
with_tmpdir {|d|
assert_separately(%w[-EEUC-JP], <<-'EOS', :chdir=>d)
- filename = "\xA4\xA2".force_encoding("euc-jp")
+ filename = "\xA4\xA2".dup.force_encoding("euc-jp")
File.open(filename, "w") {}
ents = Dir.entries(".")
if /darwin/ =~ RUBY_PLATFORM
@@ -200,7 +200,7 @@ class TestDir_M17N < Test::Unit::TestCase
assert_include(ents, filename)
EOS
assert_separately(%w[-EASCII-8BIT], <<-'EOS', :chdir=>d)
- filename = "\xA4\xA2".force_encoding('ASCII-8BIT')
+ filename = "\xA4\xA2".dup.force_encoding('ASCII-8BIT')
ents = Dir.entries(".")
unless ents.include?(filename)
case RUBY_PLATFORM
@@ -231,7 +231,7 @@ class TestDir_M17N < Test::Unit::TestCase
return if /cygwin/ =~ RUBY_PLATFORM
with_tmpdir {|d|
assert_separately(%w[-EEUC-JP], <<-'EOS', :chdir=>d)
- filename = "\xA4\xA2".force_encoding("euc-jp")
+ filename = "\xA4\xA2".dup.force_encoding("euc-jp")
File.open(filename, "w") {}
opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
ents = Dir.entries(".", **(opts||{}))
@@ -241,7 +241,7 @@ class TestDir_M17N < Test::Unit::TestCase
assert_include(ents, filename)
EOS
assert_separately(%w[-EEUC-JP:UTF-8], <<-'EOS', :chdir=>d)
- filename = "\u3042"
+ filename = "\u3042".dup
opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
ents = Dir.entries(".", **(opts||{}))
if /darwin/ =~ RUBY_PLATFORM
@@ -318,7 +318,7 @@ class TestDir_M17N < Test::Unit::TestCase
def test_glob_warning_opendir
with_enc_path do |dir|
- open("#{dir}/x", "w") {}
+ File.binwrite("#{dir}/x", "")
File.chmod(0300, dir)
next if File.readable?(dir)
assert_warning(/#{dir}/) do
@@ -329,7 +329,7 @@ class TestDir_M17N < Test::Unit::TestCase
def test_glob_warning_match_all
with_enc_path do |dir|
- open("#{dir}/x", "w") {}
+ File.binwrite("#{dir}/x", "")
File.chmod(0000, dir)
next if File.readable?(dir)
assert_warning(/#{dir}/) do
@@ -350,7 +350,7 @@ class TestDir_M17N < Test::Unit::TestCase
end
def test_glob_escape_multibyte
- name = "\x81\\".force_encoding(Encoding::Shift_JIS)
+ name = "\x81\\".dup.force_encoding(Encoding::Shift_JIS)
with_tmpdir do
open(name, "w") {} rescue next
match, = Dir.glob("#{name}*")
@@ -362,9 +362,9 @@ class TestDir_M17N < Test::Unit::TestCase
def test_glob_encoding
with_tmpdir do
list = %W"file_one.ext file_two.ext \u{6587 4ef6}1.txt \u{6587 4ef6}2.txt"
- list.each {|f| open(f, "w") {}}
- a = "file_one*".force_encoding Encoding::IBM437
- b = "file_two*".force_encoding Encoding::EUC_JP
+ list.each {|f| File.binwrite(f, "")}
+ a = "file_one*".dup.force_encoding Encoding::IBM437
+ b = "file_two*".dup.force_encoding Encoding::EUC_JP
assert_equal([a, b].map(&:encoding), Dir[a, b].map(&:encoding))
if Bug::File::Fs.fsname(Dir.pwd) == "apfs"
# High Sierra's APFS cannot use filenames with undefined character
@@ -375,7 +375,7 @@ class TestDir_M17N < Test::Unit::TestCase
Dir.mkdir(dir)
list << dir
bug12081 = '[ruby-core:73868] [Bug #12081]'
- a = "*".force_encoding("us-ascii")
+ a = "*".dup.force_encoding("us-ascii")
result = Dir[a].map {|n|
if n.encoding == Encoding::ASCII_8BIT ||
n.encoding == Encoding::ISO_8859_1 ||
diff --git a/test/ruby/test_econv.rb b/test/ruby/test_econv.rb
index 1aad0de347..1d0641e918 100644
--- a/test/ruby/test_econv.rb
+++ b/test/ruby/test_econv.rb
@@ -931,7 +931,7 @@ class TestEncodingConverter < Test::Unit::TestCase
def test_default_external
Encoding.list.grep(->(enc) {/\AISO-8859-\d+\z/i =~ enc.name}) do |enc|
- assert_separately(%W[--disable=gems -d - #{enc.name}], <<-EOS, ignore_stderr: true)
+ assert_separately(%W[-d - #{enc.name}], <<-EOS, ignore_stderr: true)
Encoding.default_external = ext = ARGV[0]
Encoding.default_internal = int ='utf-8'
assert_nothing_raised do
diff --git a/test/ruby/test_encoding.rb b/test/ruby/test_encoding.rb
index 4a6dd932ed..f2c609a4cd 100644
--- a/test/ruby/test_encoding.rb
+++ b/test/ruby/test_encoding.rb
@@ -55,39 +55,6 @@ class TestEncoding < Test::Unit::TestCase
assert_raise(TypeError, bug5150) {Encoding.find(1)}
end
- def test_replicate
- assert_separately([], "#{<<~'END;'}")
- assert_instance_of(Encoding, Encoding::UTF_8.replicate("UTF-8-ANOTHER#{Time.now.to_f}"))
- assert_instance_of(Encoding, Encoding::ISO_2022_JP.replicate("ISO-2022-JP-ANOTHER#{Time.now.to_f}"))
- bug3127 = '[ruby-dev:40954]'
- assert_raise(TypeError, bug3127) {Encoding::UTF_8.replicate(0)}
- assert_raise_with_message(ArgumentError, /\bNUL\b/, bug3127) {Encoding::UTF_8.replicate("\0")}
- END;
- end
-
- def test_extra_encoding
- assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- 200.times {|i|
- Encoding::UTF_8.replicate("dummy#{i}")
- }
- e = Encoding.list.last
- format = "%d".force_encoding(e)
- assert_equal("0", format % 0)
- assert_equal(e, format.dup.encoding)
- assert_equal(e, (format*1).encoding)
-
- assert_equal(e, (("x"*30).force_encoding(e)*1).encoding)
- GC.start
-
- name = "A" * 64
- Encoding.list.each do |enc|
- assert_raise(ArgumentError) {enc.replicate(name)}
- name.succ!
- end
- end;
- end
-
def test_dummy_p
assert_equal(true, Encoding::ISO_2022_JP.dummy?)
assert_equal(false, Encoding::UTF_8.dummy?)
@@ -139,7 +106,7 @@ class TestEncoding < Test::Unit::TestCase
end
def test_errinfo_after_autoload
- assert_separately(%w[--disable=gems], "#{<<~"begin;"}\n#{<<~'end;'}")
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
bug9038 = '[ruby-core:57949] [Bug #9038]'
begin;
e = assert_raise_with_message(SyntaxError, /unknown regexp option - Q/, bug9038) {
diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb
index cc217b05cc..7503e06272 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -843,6 +843,8 @@ class TestEnumerable < Test::Unit::TestCase
end
def test_callcc
+ omit 'requires callcc support' unless respond_to?(:callcc)
+
assert_raise(RuntimeError) do
c = nil
@obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }
@@ -1334,4 +1336,16 @@ class TestEnumerable < Test::Unit::TestCase
assert_equal([], @obj.filter_map { nil })
assert_instance_of(Enumerator, @obj.filter_map)
end
+
+ def test_ruby_svar
+ klass = Class.new do
+ include Enumerable
+ def each
+ %w(bar baz).each{|e| yield e}
+ end
+ end
+ svars = []
+ klass.new.grep(/(b.)/) { svars << $1 }
+ assert_equal(["ba", "ba"], svars)
+ end
end
diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb
index 3ca33126d5..7599d43463 100644
--- a/test/ruby/test_enumerator.rb
+++ b/test/ruby/test_enumerator.rb
@@ -127,6 +127,17 @@ class TestEnumerator < Test::Unit::TestCase
assert_equal([[1,5],[2,6],[3,7]], @obj.to_enum(:foo, 1, 2, 3).with_index(5).to_a)
end
+ def test_with_index_under_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ assert_equal([[1, 0], [2, 1], [3, 2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a)
+ assert_equal([[1, 5], [2, 6], [3, 7]], @obj.to_enum(:foo, 1, 2, 3).with_index(5).to_a)
+
+ s = 1 << (8 * 1.size - 2)
+ assert_equal([[1, s], [2, s + 1], [3, s + 2]], @obj.to_enum(:foo, 1, 2, 3).with_index(s).to_a)
+ end
+ end
+
def test_with_index_large_offset
bug8010 = '[ruby-dev:47131] [Bug #8010]'
s = 1 << (8*1.size-2)
@@ -244,6 +255,26 @@ class TestEnumerator < Test::Unit::TestCase
assert_equal(res, exc.result)
end
+ def test_stopiteration_rescue
+ e = [1].each
+ res = e.each {}
+ e.next
+ exc0 = assert_raise(StopIteration) { e.peek }
+ assert_include(exc0.backtrace.first, "test_enumerator.rb:#{__LINE__-1}:")
+ assert_nil(exc0.cause)
+ assert_equal(res, exc0.result)
+
+ exc1 = assert_raise(StopIteration) { e.next }
+ assert_include(exc1.backtrace.first, "test_enumerator.rb:#{__LINE__-1}:")
+ assert_same(exc0, exc1.cause)
+ assert_equal(res, exc1.result)
+
+ exc2 = assert_raise(StopIteration) { e.next }
+ assert_include(exc2.backtrace.first, "test_enumerator.rb:#{__LINE__-1}:")
+ assert_same(exc0, exc2.cause)
+ assert_equal(res, exc2.result)
+ end
+
def test_next_values
o = Object.new
def o.each
@@ -832,6 +863,21 @@ class TestEnumerator < Test::Unit::TestCase
assert_equal(33, chain.next)
end
+ def test_lazy_chain_under_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ ea = (10..).lazy.select(&:even?).take(10)
+ ed = (20..).lazy.select(&:odd?)
+ chain = (ea + ed).select{|x| x % 3 == 0}
+ assert_equal(12, chain.next)
+ assert_equal(18, chain.next)
+ assert_equal(24, chain.next)
+ assert_equal(21, chain.next)
+ assert_equal(27, chain.next)
+ assert_equal(33, chain.next)
+ end
+ end
+
def test_chain_undef_methods
chain = [1].to_enum + [2].to_enum
meths = (chain.methods & [:feed, :next, :next_values, :peek, :peek_values])
@@ -907,41 +953,94 @@ class TestEnumerator < Test::Unit::TestCase
assert_equal(true, e.is_lambda)
end
- def test_product
+ def test_product_new
+ # 0-dimensional
e = Enumerator::Product.new
assert_instance_of(Enumerator::Product, e)
assert_kind_of(Enumerator, e)
assert_equal(1, e.size)
elts = []
- e.each { |*x| elts << x }
+ e.each { |x| elts << x }
assert_equal [[]], elts
+ assert_equal elts, e.to_a
+ heads = []
+ e.each { |x,| heads << x }
+ assert_equal [nil], heads
+ # 1-dimensional
+ e = Enumerator::Product.new(1..3)
+ assert_instance_of(Enumerator::Product, e)
+ assert_kind_of(Enumerator, e)
+ assert_equal(3, e.size)
+ elts = []
+ e.each { |x| elts << x }
+ assert_equal [[1], [2], [3]], elts
+ assert_equal elts, e.to_a
+
+ # 2-dimensional
e = Enumerator::Product.new(1..3, %w[a b])
assert_instance_of(Enumerator::Product, e)
assert_kind_of(Enumerator, e)
assert_equal(3 * 2, e.size)
elts = []
- e.each { |*x| elts << x }
+ e.each { |x| elts << x }
assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"], [3, "a"], [3, "b"]], elts
+ assert_equal elts, e.to_a
+ heads = []
+ e.each { |x,| heads << x }
+ assert_equal [1, 1, 2, 2, 3, 3], heads
+
+ # Any enumerable is 0 size
+ assert_equal(0, Enumerator::Product.new([], 1..).size)
+ # Reject keyword arguments
+ assert_raise(ArgumentError) {
+ Enumerator::Product.new(1..3, foo: 1, bar: 2)
+ }
+ end
+
+ def test_s_product
+ # without a block
e = Enumerator.product(1..3, %w[a b])
assert_instance_of(Enumerator::Product, e)
+ # with a block
elts = []
- ret = Enumerator.product(1..3, %w[a b]) { |*x| elts << x }
- assert_instance_of(Enumerator::Product, ret)
- assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"], [3, "a"], [3, "b"]], elts
+ ret = Enumerator.product(1..3) { |x| elts << x }
+ assert_equal(nil, ret)
+ assert_equal [[1], [2], [3]], elts
+ assert_equal elts, Enumerator.product(1..3).to_a
+ # an infinite enumerator and a finite enumerable
e = Enumerator.product(1.., 'a'..'c')
assert_equal(Float::INFINITY, e.size)
assert_equal [[1, "a"], [1, "b"], [1, "c"], [2, "a"]], e.take(4)
+ # an infinite enumerator and an unknown enumerator
e = Enumerator.product(1.., Enumerator.new { |y| y << 'a' << 'b' })
assert_equal(Float::INFINITY, e.size)
assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"]], e.take(4)
+ # an infinite enumerator and an unknown enumerator
e = Enumerator.product(1..3, Enumerator.new { |y| y << 'a' << 'b' })
assert_equal(nil, e.size)
assert_equal [[1, "a"], [1, "b"], [2, "a"], [2, "b"]], e.take(4)
+
+ assert_equal(0, Enumerator.product([], 1..).size)
+
+ # Reject keyword arguments
+ assert_raise(ArgumentError) {
+ Enumerator.product(1..3, foo: 1, bar: 2)
+ }
+ end
+
+ def test_freeze
+ e = 3.times.freeze
+ assert_raise(FrozenError) { e.next }
+ assert_raise(FrozenError) { e.next_values }
+ assert_raise(FrozenError) { e.peek }
+ assert_raise(FrozenError) { e.peek_values }
+ assert_raise(FrozenError) { e.feed 1 }
+ assert_raise(FrozenError) { e.rewind }
end
end
diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb
index cdadeac148..4b5f18e7bb 100644
--- a/test/ruby/test_env.rb
+++ b/test/ruby/test_env.rb
@@ -612,8 +612,8 @@ class TestEnv < Test::Unit::TestCase
<<-"end;"
envvars_to_check = [
"foo\0bar",
- "#{'\xa1\xa1'}".force_encoding(Encoding::UTF_16LE),
- "foo".force_encoding(Encoding::ISO_2022_JP),
+ "#{'\xa1\xa1'}".dup.force_encoding(Encoding::UTF_16LE),
+ "foo".dup.force_encoding(Encoding::ISO_2022_JP),
]
envvars_to_check.each do |#{var_name}|
#{str_for_yielding_exception_class(code_str)}
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb
index d55977c986..082d1dc03c 100644
--- a/test/ruby/test_eval.rb
+++ b/test/ruby/test_eval.rb
@@ -488,6 +488,9 @@ class TestEval < Test::Unit::TestCase
end
end
assert_equal(feature6609, feature6609_method)
+ ensure
+ Object.undef_method(:feature6609_block) rescue nil
+ Object.undef_method(:feature6609_method) rescue nil
end
def test_eval_using_integer_as_binding
@@ -544,8 +547,8 @@ class TestEval < Test::Unit::TestCase
end
def test_eval_location_binding
- assert_equal(['(eval)', 1], eval("[__FILE__, __LINE__]", nil))
- assert_equal(['(eval)', 1], eval("[__FILE__, __LINE__]", binding))
+ assert_equal(["(eval at #{__FILE__}:#{__LINE__})", 1], eval("[__FILE__, __LINE__]", nil))
+ assert_equal(["(eval at #{__FILE__}:#{__LINE__})", 1], eval("[__FILE__, __LINE__]", binding))
assert_equal(['foo', 1], eval("[__FILE__, __LINE__]", nil, 'foo'))
assert_equal(['foo', 1], eval("[__FILE__, __LINE__]", binding, 'foo'))
assert_equal(['foo', 2], eval("[__FILE__, __LINE__]", nil, 'foo', 2))
diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb
index 0b05ff7c51..4b7d709906 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -416,7 +416,7 @@ class TestException < Test::Unit::TestCase
assert_in_out_err([], "$@ = 1", [], /\$! not set \(ArgumentError\)$/)
- assert_in_out_err([], <<-INPUT, [], /backtrace must be Array of String \(TypeError\)$/)
+ assert_in_out_err([], <<-INPUT, [], /backtrace must be an Array of String or an Array of Thread::Backtrace::Location \(TypeError\)$/)
begin
raise
rescue
@@ -478,6 +478,12 @@ end.join
def to_s; ""; end
end
assert_equal(e.inspect, e.new.inspect)
+
+ # https://bugs.ruby-lang.org/issues/18170#note-13
+ assert_equal('#<Exception:"foo\nbar">', Exception.new("foo\nbar").inspect)
+ assert_equal('#<Exception: foo bar>', Exception.new("foo bar").inspect)
+ assert_equal('#<Exception: foo\bar>', Exception.new("foo\\bar").inspect)
+ assert_equal('#<Exception: "foo\nbar">', Exception.new('"foo\nbar"').inspect)
end
def test_to_s
@@ -502,6 +508,16 @@ end.join
assert_raise(TypeError) { e.set_backtrace(1) }
assert_raise(TypeError) { e.set_backtrace([1]) }
+
+ error = assert_raise(TypeError) do
+ e.set_backtrace(caller_locations(1, 1) + ["foo"])
+ end
+ assert_include error.message, "backtrace must be an Array of String or an Array of Thread::Backtrace::Location"
+
+ error = assert_raise(TypeError) do
+ e.set_backtrace(["foo"] + caller_locations(1, 1))
+ end
+ assert_include error.message, "backtrace must be an Array of String or an Array of Thread::Backtrace::Location"
end
def test_exit_success_p
@@ -534,6 +550,14 @@ end.join
assert_equal(Encoding.find("locale"), Errno::EINVAL.new.message.encoding)
end
+ def test_errno_constants
+ assert_equal [:NOERROR], Errno.constants.grep_v(/\AE/)
+ all_assertions_foreach("should be a subclass of SystemCallError", *Errno.constants) do |c|
+ e = Errno.const_get(c)
+ assert_operator e, :<, SystemCallError, proc {e.ancestors.inspect}
+ end
+ end
+
def test_too_many_args_in_eval
bug5720 = '[ruby-core:41520]'
arg_string = (0...140000).to_a.join(", ")
@@ -679,7 +703,7 @@ end.join
def test_machine_stackoverflow
bug9109 = '[ruby-dev:47804] [Bug #9109]'
- assert_separately(%w[--disable-gem], <<-SRC)
+ assert_separately([], <<-SRC)
assert_raise(SystemStackError, #{bug9109.dump}) {
h = {a: ->{h[:a].call}}
h[:a].call
@@ -690,7 +714,7 @@ end.join
def test_machine_stackoverflow_by_define_method
bug9454 = '[ruby-core:60113] [Bug #9454]'
- assert_separately(%w[--disable-gem], <<-SRC)
+ assert_separately([], <<-SRC)
assert_raise(SystemStackError, #{bug9454.dump}) {
define_method(:foo) {self.foo}
self.foo
@@ -795,7 +819,7 @@ end.join
def test_cause_at_end
errs = [
/-: unexpected return\n/,
- /.*undefined local variable or method `n'.*\n/,
+ /.*undefined local variable or method 'n'.*\n/,
]
assert_in_out_err([], <<-'end;', [], errs)
END{n}; END{return}
@@ -1031,7 +1055,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
end
def test_message_of_name_error
- assert_raise_with_message(NameError, /\Aundefined method `foo' for module `#<Module:.*>'$/) do
+ assert_raise_with_message(NameError, /\Aundefined method 'foo' for module '#<Module:.*>'$/) do
Module.new do
module_function :foo
end
@@ -1040,8 +1064,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
def capture_warning_warn(category: false)
verbose = $VERBOSE
- deprecated = Warning[:deprecated]
- experimental = Warning[:experimental]
+ categories = Warning.categories.to_h {|cat| [cat, Warning[cat]]}
warning = []
::Warning.class_eval do
@@ -1053,22 +1076,20 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
warning << [str, category]
end
else
- define_method(:warn) do |str|
+ define_method(:warn) do |str, category: nil|
warning << str
end
end
end
$VERBOSE = true
- Warning[:deprecated] = true
- Warning[:experimental] = true
+ Warning.categories.each {|cat| Warning[cat] = true}
yield
return warning
ensure
$VERBOSE = verbose
- Warning[:deprecated] = deprecated
- Warning[:experimental] = experimental
+ categories.each {|cat, flag| Warning[cat] = flag}
::Warning.class_eval do
remove_method :warn
@@ -1079,7 +1100,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
def test_warning_warn
warning = capture_warning_warn {$asdfasdsda_test_warning_warn}
- assert_match(/global variable `\$asdfasdsda_test_warning_warn' not initialized/, warning[0])
+ assert_match(/global variable '\$asdfasdsda_test_warning_warn' not initialized/, warning[0])
assert_equal(["a\nz\n"], capture_warning_warn {warn "a\n", "z"})
assert_equal([], capture_warning_warn {warn})
@@ -1087,19 +1108,13 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
end
def test_warn_deprecated_backwards_compatibility_category
- omit "no method to test"
-
- warning = capture_warning_warn { }
-
- assert_match(/deprecated/, warning[0])
- end
-
- def test_warn_deprecated_category
- omit "no method to test"
-
- warning = capture_warning_warn(category: true) { }
+ (message, category), = capture_warning_warn(category: true) do
+ $; = "www"
+ $; = nil
+ end
- assert_equal :deprecated, warning[0][1]
+ assert_include message, 'deprecated'
+ assert_equal :deprecated, category
end
def test_kernel_warn_uplevel
@@ -1155,7 +1170,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
end
def test_warning_warn_super
- assert_in_out_err(%[-W0], "#{<<~"{#"}\n#{<<~'};'}", [], /global variable `\$asdfiasdofa_test_warning_warn_super' not initialized/)
+ assert_in_out_err(%[-W0], "#{<<~"{#"}\n#{<<~'};'}", [], /global variable '\$asdfiasdofa_test_warning_warn_super' not initialized/)
{#
module Warning
def warn(message)
@@ -1171,48 +1186,24 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
def test_warning_category
assert_raise(TypeError) {Warning[nil]}
assert_raise(ArgumentError) {Warning[:XXXX]}
- assert_include([true, false], Warning[:deprecated])
- assert_include([true, false], Warning[:experimental])
- end
- def test_warning_category_deprecated
- warning = EnvUtil.verbose_warning do
- deprecated = Warning[:deprecated]
- Warning[:deprecated] = true
- Warning.warn "deprecated feature", category: :deprecated
- ensure
- Warning[:deprecated] = deprecated
- end
- assert_equal "deprecated feature", warning
-
- warning = EnvUtil.verbose_warning do
- deprecated = Warning[:deprecated]
- Warning[:deprecated] = false
- Warning.warn "deprecated feature", category: :deprecated
- ensure
- Warning[:deprecated] = deprecated
- end
- assert_empty warning
- end
+ all_assertions_foreach("categories", *Warning.categories) do |cat|
+ value = Warning[cat]
+ assert_include([true, false], value)
- def test_warning_category_experimental
- warning = EnvUtil.verbose_warning do
- experimental = Warning[:experimental]
- Warning[:experimental] = true
- Warning.warn "experimental feature", category: :experimental
- ensure
- Warning[:experimental] = experimental
- end
- assert_equal "experimental feature", warning
-
- warning = EnvUtil.verbose_warning do
- experimental = Warning[:experimental]
- Warning[:experimental] = false
- Warning.warn "experimental feature", category: :experimental
+ enabled = EnvUtil.verbose_warning do
+ Warning[cat] = true
+ Warning.warn "#{cat} feature", category: cat
+ end
+ disabled = EnvUtil.verbose_warning do
+ Warning[cat] = false
+ Warning.warn "#{cat} feature", category: cat
+ end
ensure
- Warning[:experimental] = experimental
+ Warning[cat] = value
+ assert_equal "#{cat} feature", enabled
+ assert_empty disabled
end
- assert_empty warning
end
def test_undef_Warning_warn
@@ -1260,7 +1251,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
begin;
class Bug < RuntimeError
def backtrace
- IO.readlines(IO::NULL)
+ File.readlines(IO::NULL)
end
end
bug = Bug.new '[ruby-core:85939] [Bug #14577]'
@@ -1304,7 +1295,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
def test_backtrace_in_eval
bug = '[ruby-core:84434] [Bug #14229]'
- assert_in_out_err(['-e', 'eval("raise")'], "", [], /^\(eval\):1:/, bug)
+ assert_in_out_err(['-e', 'eval("raise")'], "", [], /^\(eval at .*\):1:/, bug)
end
def test_full_message
@@ -1406,6 +1397,14 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
end;
end
+ def test_marshal_circular_cause
+ dump = "\x04\bo:\x11RuntimeError\b:\tmesgI\"\berr\x06:\x06ET:\abt[\x00:\ncause@\x05"
+ assert_raise_with_message(ArgumentError, /circular cause/, ->{dump.inspect}) do
+ e = Marshal.load(dump)
+ assert_same(e, e.cause)
+ end
+ end
+
def test_super_in_method_missing
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
@@ -1417,7 +1416,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
end
bug14670 = '[ruby-dev:50522] [Bug #14670]'
- assert_raise_with_message(NoMethodError, /`foo'/, bug14670) do
+ assert_raise_with_message(NoMethodError, /'foo'/, bug14670) do
Object.new.foo
end
end;
@@ -1441,6 +1440,15 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
assert_equal("\e[1mRuntimeError (\e[1;4mRuntimeError\e[m\e[1m)\e[m", e.detailed_message(highlight: true))
end
+ def test_detailed_message_under_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ e = RuntimeError.new("foo\nbar\nbaz")
+ assert_equal("foo (RuntimeError)\nbar\nbaz", e.detailed_message)
+ assert_equal("\e[1mfoo (\e[1;4mRuntimeError\e[m\e[1m)\e[m\n\e[1mbar\e[m\n\e[1mbaz\e[m", e.detailed_message(highlight: true))
+ end
+ end
+
def test_full_message_with_custom_detailed_message
e = RuntimeError.new("message")
opt_ = nil
@@ -1451,4 +1459,70 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status|
assert_match("BOO!", e.full_message.lines.first)
assert_equal({ highlight: Exception.to_tty? }, opt_)
end
+
+ def test_full_message_with_encoding
+ message = "\u{dc}bersicht"
+ begin
+ begin
+ raise message
+ rescue => e
+ raise "\n#{e.message}"
+ end
+ rescue => e
+ end
+ assert_include(e.full_message, message)
+ end
+
+ def test_syntax_error_detailed_message
+ Dir.mktmpdir do |dir|
+ File.write(File.join(dir, "detail.rb"), "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class SyntaxError
+ def detailed_message(**)
+ Thread.new {}.join
+ "<#{super}>\n""<#{File.basename(__FILE__)}>"
+ rescue ThreadError => e
+ e.message
+ end
+ end
+ end;
+ pattern = /^<detail\.rb>/
+ assert_in_out_err(%W[-r#{dir}/detail -], "1+", [], pattern)
+
+ File.write(File.join(dir, "main.rb"), "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ 1 +
+ end;
+ assert_in_out_err(%W[-r#{dir}/detail #{dir}/main.rb]) do |stdout, stderr,|
+ assert_empty(stdout)
+ assert_not_empty(stderr.grep(pattern))
+ error, = stderr.grep(/unexpected end-of-input/)
+ assert_not_nil(error)
+ assert_match(/<.*unexpected end-of-input.*>/, error)
+ end
+ end
+ end
+
+ def test_syntax_error_path
+ e = assert_raise(SyntaxError) {
+ eval("1+", nil, "test_syntax_error_path.rb")
+ }
+ assert_equal("test_syntax_error_path.rb", e.path)
+
+ Dir.mktmpdir do |dir|
+ lib = File.join(dir, "syntax_error-path.rb")
+ File.write(lib, "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class SyntaxError
+ def detailed_message(**)
+ STDERR.puts "\n""path=#{path}\n"
+ super
+ end
+ end
+ end;
+ main = File.join(dir, "syntax_error.rb")
+ File.write(main, "1+\n")
+ assert_in_out_err(%W[-r#{lib} #{main}], "", [], [:*, "\n""path=#{main}\n", :*])
+ end
+ end
end
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb
index 5825aaf6cc..45e5d12092 100644
--- a/test/ruby/test_fiber.rb
+++ b/test/ruby/test_fiber.rb
@@ -34,7 +34,7 @@ class TestFiber < Test::Unit::TestCase
end
def test_many_fibers
- omit 'This is unstable on GitHub Actions --jit-wait. TODO: debug it' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ omit 'This is unstable on GitHub Actions --jit-wait. TODO: debug it' if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
max = 1000
assert_equal(max, max.times{
Fiber.new{}
@@ -82,12 +82,14 @@ class TestFiber < Test::Unit::TestCase
f.resume
f.resume
}
- assert_raise(RuntimeError){
- Fiber.new{
- @c = callcc{|c| @c = c}
- }.resume
- @c.call # cross fiber callcc
- }
+ if respond_to?(:callcc)
+ assert_raise(RuntimeError){
+ Fiber.new{
+ @c = callcc{|c| @c = c}
+ }.resume
+ @c.call # cross fiber callcc
+ }
+ end
assert_raise(RuntimeError){
Fiber.new{
raise
@@ -422,7 +424,7 @@ class TestFiber < Test::Unit::TestCase
end
def test_fatal_in_fiber
- assert_in_out_err(["-r-test-/fatal/rb_fatal", "-e", <<-EOS], "", [], /ok/)
+ assert_in_out_err(["-r-test-/fatal", "-e", <<-EOS], "", [], /ok/)
Fiber.new{
Bug.rb_fatal "ok"
}.resume
diff --git a/test/ruby/test_file.rb b/test/ruby/test_file.rb
index 905416911a..aa10566bfa 100644
--- a/test/ruby/test_file.rb
+++ b/test/ruby/test_file.rb
@@ -460,6 +460,48 @@ class TestFile < Test::Unit::TestCase
end
end
+ def test_file_open_newline_option
+ Dir.mktmpdir(__method__.to_s) do |tmpdir|
+ path = File.join(tmpdir, "foo")
+ test = lambda do |newline|
+ File.open(path, "wt", newline: newline) do |f|
+ f.write "a\n"
+ f.puts "b"
+ end
+ File.binread(path)
+ end
+ assert_equal("a\nb\n", test.(:lf))
+ assert_equal("a\nb\n", test.(:universal))
+ assert_equal("a\r\nb\r\n", test.(:crlf))
+ assert_equal("a\rb\r", test.(:cr))
+
+ test = lambda do |newline|
+ File.open(path, "rt", newline: newline) do |f|
+ f.read
+ end
+ end
+
+ File.binwrite(path, "a\nb\n")
+ assert_equal("a\nb\n", test.(:lf))
+ assert_equal("a\nb\n", test.(:universal))
+ assert_equal("a\nb\n", test.(:crlf))
+ assert_equal("a\nb\n", test.(:cr))
+
+ File.binwrite(path, "a\r\nb\r\n")
+ assert_equal("a\r\nb\r\n", test.(:lf))
+ assert_equal("a\nb\n", test.(:universal))
+ # Work on both Windows and non-Windows
+ assert_include(["a\r\nb\r\n", "a\nb\n"], test.(:crlf))
+ assert_equal("a\r\nb\r\n", test.(:cr))
+
+ File.binwrite(path, "a\rb\r")
+ assert_equal("a\rb\r", test.(:lf))
+ assert_equal("a\nb\n", test.(:universal))
+ assert_equal("a\rb\r", test.(:crlf))
+ assert_equal("a\rb\r", test.(:cr))
+ end
+ end
+
def test_open_nul
Dir.mktmpdir(__method__.to_s) do |tmpdir|
path = File.join(tmpdir, "foo")
@@ -485,7 +527,7 @@ class TestFile < Test::Unit::TestCase
io.write "foo"
io.flush
assert_equal 3, io.size
- assert_raise(IOError) { io.path }
+ assert_nil io.path
ensure
io&.close
end
@@ -512,4 +554,250 @@ class TestFile < Test::Unit::TestCase
assert_file.absolute_path?("/foo/bar\\baz")
end
end
+
+ class NewlineConvTests < Test::Unit::TestCase
+ TEST_STRING_WITH_CRLF = "line1\r\nline2\r\n".freeze
+ TEST_STRING_WITH_LF = "line1\nline2\n".freeze
+
+ def setup
+ @tmpdir = Dir.mktmpdir(self.class.name)
+ @read_path_with_crlf = File.join(@tmpdir, "read_path_with_crlf")
+ File.binwrite(@read_path_with_crlf, TEST_STRING_WITH_CRLF)
+ @read_path_with_lf = File.join(@tmpdir, "read_path_with_lf")
+ File.binwrite(@read_path_with_lf, TEST_STRING_WITH_LF)
+ @write_path = File.join(@tmpdir, "write_path")
+ File.binwrite(@write_path, '')
+ end
+
+ def teardown
+ FileUtils.rm_rf @tmpdir
+ end
+
+ def windows?
+ /cygwin|mswin|mingw/ =~ RUBY_PLATFORM
+ end
+
+ def open_file_with(method, filename, mode)
+ read_or_write = mode.include?('w') ? :write : :read
+ binary_or_text = mode.include?('b') ? :binary : :text
+
+ f = case method
+ when :ruby_file_open
+ File.open(filename, mode)
+ when :c_rb_file_open
+ Bug::File::NewlineConv.rb_file_open(filename, read_or_write, binary_or_text)
+ when :c_rb_io_fdopen
+ Bug::File::NewlineConv.rb_io_fdopen(filename, read_or_write, binary_or_text)
+ else
+ raise "Don't know how to open with #{method}"
+ end
+
+ begin
+ yield f
+ ensure
+ f.close
+ end
+ end
+
+ def assert_file_contents_has_lf(f)
+ assert_equal TEST_STRING_WITH_LF, f.read
+ end
+
+ def assert_file_contents_has_crlf(f)
+ assert_equal TEST_STRING_WITH_CRLF, f.read
+ end
+
+ def assert_file_contents_has_lf_on_windows(f)
+ if windows?
+ assert_file_contents_has_lf(f)
+ else
+ assert_file_contents_has_crlf(f)
+ end
+ end
+
+ def assert_file_contents_has_crlf_on_windows(f)
+ if windows?
+ assert_file_contents_has_crlf(f)
+ else
+ assert_file_contents_has_lf(f)
+ end
+ end
+
+ def test_ruby_file_open_text_mode_read_crlf
+ open_file_with(:ruby_file_open, @read_path_with_crlf, 'r') { |f| assert_file_contents_has_lf_on_windows(f) }
+ end
+
+ def test_ruby_file_open_bin_mode_read_crlf
+ open_file_with(:ruby_file_open, @read_path_with_crlf, 'rb') { |f| assert_file_contents_has_crlf(f) }
+ end
+
+ def test_ruby_file_open_text_mode_read_lf
+ open_file_with(:ruby_file_open, @read_path_with_lf, 'r') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_ruby_file_open_bin_mode_read_lf
+ open_file_with(:ruby_file_open, @read_path_with_lf, 'rb') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_ruby_file_open_text_mode_read_crlf_with_utf8_encoding
+ open_file_with(:ruby_file_open, @read_path_with_crlf, 'r') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf_on_windows(f)
+ end
+ end
+
+ def test_ruby_file_open_bin_mode_read_crlf_with_utf8_encoding
+ open_file_with(:ruby_file_open, @read_path_with_crlf, 'rb') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_crlf(f)
+ end
+ end
+
+ def test_ruby_file_open_text_mode_read_lf_with_utf8_encoding
+ open_file_with(:ruby_file_open, @read_path_with_lf, 'r') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf(f)
+ end
+ end
+
+ def test_ruby_file_open_bin_mode_read_lf_with_utf8_encoding
+ open_file_with(:ruby_file_open, @read_path_with_lf, 'rb') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf(f)
+ end
+ end
+
+ def test_ruby_file_open_text_mode_write_lf
+ open_file_with(:ruby_file_open, @write_path, 'w') { |f| f.write TEST_STRING_WITH_LF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf_on_windows(f) }
+ end
+
+ def test_ruby_file_open_bin_mode_write_lf
+ open_file_with(:ruby_file_open, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_LF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_ruby_file_open_bin_mode_write_crlf
+ open_file_with(:ruby_file_open, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_CRLF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf(f) }
+ end
+
+ def test_c_rb_file_open_text_mode_read_crlf
+ open_file_with(:c_rb_file_open, @read_path_with_crlf, 'r') { |f| assert_file_contents_has_lf_on_windows(f) }
+ end
+
+ def test_c_rb_file_open_bin_mode_read_crlf
+ open_file_with(:c_rb_file_open, @read_path_with_crlf, 'rb') { |f| assert_file_contents_has_crlf(f) }
+ end
+
+ def test_c_rb_file_open_text_mode_read_lf
+ open_file_with(:c_rb_file_open, @read_path_with_lf, 'r') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_c_rb_file_open_bin_mode_read_lf
+ open_file_with(:c_rb_file_open, @read_path_with_lf, 'rb') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_c_rb_file_open_text_mode_write_lf
+ open_file_with(:c_rb_file_open, @write_path, 'w') { |f| f.write TEST_STRING_WITH_LF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf_on_windows(f) }
+ end
+
+ def test_c_rb_file_open_bin_mode_write_lf
+ open_file_with(:c_rb_file_open, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_LF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_c_rb_file_open_bin_mode_write_crlf
+ open_file_with(:c_rb_file_open, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_CRLF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf(f) }
+ end
+
+ def test_c_rb_file_open_text_mode_read_crlf_with_utf8_encoding
+ open_file_with(:c_rb_file_open, @read_path_with_crlf, 'r') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf_on_windows(f)
+ end
+ end
+
+ def test_c_rb_file_open_bin_mode_read_crlf_with_utf8_encoding
+ open_file_with(:c_rb_file_open, @read_path_with_crlf, 'rb') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_crlf(f)
+ end
+ end
+
+ def test_c_rb_file_open_text_mode_read_lf_with_utf8_encoding
+ open_file_with(:c_rb_file_open, @read_path_with_lf, 'r') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf(f)
+ end
+ end
+
+ def test_c_rb_file_open_bin_mode_read_lf_with_utf8_encoding
+ open_file_with(:c_rb_file_open, @read_path_with_lf, 'rb') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf(f)
+ end
+ end
+
+ def test_c_rb_io_fdopen_text_mode_read_crlf
+ open_file_with(:c_rb_io_fdopen, @read_path_with_crlf, 'r') { |f| assert_file_contents_has_lf_on_windows(f) }
+ end
+
+ def test_c_rb_io_fdopen_bin_mode_read_crlf
+ open_file_with(:c_rb_io_fdopen, @read_path_with_crlf, 'rb') { |f| assert_file_contents_has_crlf(f) }
+ end
+
+ def test_c_rb_io_fdopen_text_mode_read_lf
+ open_file_with(:c_rb_io_fdopen, @read_path_with_lf, 'r') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_c_rb_io_fdopen_bin_mode_read_lf
+ open_file_with(:c_rb_io_fdopen, @read_path_with_lf, 'rb') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_c_rb_io_fdopen_text_mode_write_lf
+ open_file_with(:c_rb_io_fdopen, @write_path, 'w') { |f| f.write TEST_STRING_WITH_LF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf_on_windows(f) }
+ end
+
+ def test_c_rb_io_fdopen_bin_mode_write_lf
+ open_file_with(:c_rb_io_fdopen, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_LF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_lf(f) }
+ end
+
+ def test_c_rb_io_fdopen_bin_mode_write_crlf
+ open_file_with(:c_rb_io_fdopen, @write_path, 'wb') { |f| f.write TEST_STRING_WITH_CRLF }
+ File.open(@write_path, 'rb') { |f| assert_file_contents_has_crlf(f) }
+ end
+
+ def test_c_rb_io_fdopen_text_mode_read_crlf_with_utf8_encoding
+ open_file_with(:c_rb_io_fdopen, @read_path_with_crlf, 'r') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf_on_windows(f)
+ end
+ end
+
+ def test_c_rb_io_fdopen_bin_mode_read_crlf_with_utf8_encoding
+ open_file_with(:c_rb_io_fdopen, @read_path_with_crlf, 'rb') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_crlf(f)
+ end
+ end
+
+ def test_c_rb_io_fdopen_text_mode_read_lf_with_utf8_encoding
+ open_file_with(:c_rb_io_fdopen, @read_path_with_lf, 'r') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf(f)
+ end
+ end
+
+ def test_c_rb_io_fdopen_bin_mode_read_lf_with_utf8_encoding
+ open_file_with(:c_rb_io_fdopen, @read_path_with_lf, 'rb') do |f|
+ f.set_encoding Encoding::UTF_8, '-'
+ assert_file_contents_has_lf(f)
+ end
+ end
+ end
end
diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb
index 8cd020533b..fbb18f07f9 100644
--- a/test/ruby/test_file_exhaustive.rb
+++ b/test/ruby/test_file_exhaustive.rb
@@ -649,7 +649,7 @@ class TestFileExhaustive < Test::Unit::TestCase
# ignore unsupporting filesystems
rescue Errno::EPERM
# Docker prohibits statx syscall by the default.
- skip("statx(2) is prohibited by seccomp")
+ omit("statx(2) is prohibited by seccomp")
end
assert_raise(Errno::ENOENT) { File.birthtime(nofile) }
end if File.respond_to?(:birthtime)
@@ -1517,9 +1517,12 @@ class TestFileExhaustive < Test::Unit::TestCase
assert_equal(File.zero?(f), test(?z, f), f)
stat = File.stat(f)
- assert_equal(stat.atime, File.atime(f), f)
- assert_equal(stat.ctime, File.ctime(f), f)
- assert_equal(stat.mtime, File.mtime(f), f)
+ unless stat.chardev?
+ # null device may be accessed by other processes
+ assert_equal(stat.atime, File.atime(f), f)
+ assert_equal(stat.ctime, File.ctime(f), f)
+ assert_equal(stat.mtime, File.mtime(f), f)
+ end
assert_bool_equal(stat.blockdev?, File.blockdev?(f), f)
assert_bool_equal(stat.chardev?, File.chardev?(f), f)
assert_bool_equal(stat.directory?, File.directory?(f), f)
diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb
index 57a46fce92..b91b904d1e 100644
--- a/test/ruby/test_float.rb
+++ b/test/ruby/test_float.rb
@@ -141,6 +141,9 @@ class TestFloat < Test::Unit::TestCase
assert_raise(ArgumentError){Float("1__1")}
assert_raise(ArgumentError){Float("1.")}
assert_raise(ArgumentError){Float("1.e+00")}
+ assert_raise(ArgumentError){Float("0x.1")}
+ assert_raise(ArgumentError){Float("0x1.")}
+ assert_raise(ArgumentError){Float("0x1.0")}
assert_raise(ArgumentError){Float("0x1.p+0")}
# add expected behaviour here.
assert_equal(10, Float("1_0"))
@@ -224,6 +227,12 @@ class TestFloat < Test::Unit::TestCase
assert_equal(-3.5, (-11.5).remainder(-4))
assert_predicate(Float::NAN.remainder(4), :nan?)
assert_predicate(4.remainder(Float::NAN), :nan?)
+
+ ten = Object.new
+ def ten.coerce(other)
+ [other, 10]
+ end
+ assert_equal(4, 14.0.remainder(ten))
end
def test_to_s
@@ -483,6 +492,17 @@ class TestFloat < Test::Unit::TestCase
assert_equal(-1.26, -1.255.round(2))
end
+ def test_round_half_even_with_precision
+ assert_equal(767573.18759, 767573.1875850001.round(5, half: :even))
+ assert_equal(767573.18758, 767573.187585.round(5, half: :even))
+ assert_equal(767573.18758, 767573.1875849998.round(5, half: :even))
+ assert_equal(767573.18758, 767573.187575.round(5, half: :even))
+ assert_equal(-767573.18759, -767573.1875850001.round(5, half: :even))
+ assert_equal(-767573.18758, -767573.187585.round(5, half: :even))
+ assert_equal(-767573.18758, -767573.1875849998.round(5, half: :even))
+ assert_equal(-767573.18758, -767573.187575.round(5, half: :even))
+ end
+
def test_floor_with_precision
assert_equal(+0.0, +0.001.floor(1))
assert_equal(-0.1, -0.001.floor(1))
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb
index d2f1e21e33..39b001c3d0 100644
--- a/test/ruby/test_gc.rb
+++ b/test/ruby/test_gc.rb
@@ -128,6 +128,8 @@ class TestGc < Test::Unit::TestCase
omit 'stress' if GC.stress
stat = GC.stat
+ # marking_time + sweeping_time could differ from time by 1 because they're stored in nanoseconds
+ assert_in_delta stat[:time], stat[:marking_time] + stat[:sweeping_time], 1
assert_equal stat[:total_allocated_pages], stat[:heap_allocated_pages] + stat[:total_freed_pages]
assert_operator stat[:heap_sorted_length], :>=, stat[:heap_eden_pages] + stat[:heap_allocatable_pages], "stat is: " + stat.inspect
assert_equal stat[:heap_available_slots], stat[:heap_live_slots] + stat[:heap_free_slots] + stat[:heap_final_slots]
@@ -149,10 +151,15 @@ class TestGc < Test::Unit::TestCase
GC.stat(stat)
GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT].times do |i|
- GC.stat_heap(i, stat_heap)
- GC.stat(stat)
+ begin
+ reenable_gc = !GC.disable
+ GC.stat_heap(i, stat_heap)
+ GC.stat(stat)
+ ensure
+ GC.enable if reenable_gc
+ end
- assert_equal GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * (2**i), stat_heap[:slot_size]
+ assert_equal GC::INTERNAL_CONSTANTS[:RVALUE_SIZE] * (2**i), stat_heap[:slot_size]
assert_operator stat_heap[:heap_allocatable_pages], :<=, stat[:heap_allocatable_pages]
assert_operator stat_heap[:heap_eden_pages], :<=, stat[:heap_eden_pages]
assert_operator stat_heap[:heap_eden_slots], :>=, 0
@@ -161,6 +168,10 @@ class TestGc < Test::Unit::TestCase
assert_operator stat_heap[:total_allocated_pages], :>=, 0
assert_operator stat_heap[:total_freed_pages], :>=, 0
assert_operator stat_heap[:force_major_gc_count], :>=, 0
+ assert_operator stat_heap[:force_incremental_marking_finish_count], :>=, 0
+ assert_operator stat_heap[:total_allocated_objects], :>=, 0
+ assert_operator stat_heap[:total_freed_objects], :>=, 0
+ assert_operator stat_heap[:total_freed_objects], :<=, stat_heap[:total_allocated_objects]
end
GC.stat_heap(0, stat_heap)
@@ -172,6 +183,7 @@ class TestGc < Test::Unit::TestCase
end
def test_stat_heap_all
+ omit "flaky with RJIT, which allocates objects itself" if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
stat_heap_all = {}
stat_heap = {}
@@ -183,6 +195,11 @@ class TestGc < Test::Unit::TestCase
GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT].times do |i|
GC.stat_heap(i, stat_heap)
+ # Remove keys that can vary between invocations
+ %i(total_allocated_objects).each do |sym|
+ stat_heap[sym] = stat_heap_all[i][sym] = 0
+ end
+
assert_equal stat_heap, stat_heap_all[i]
end
@@ -194,8 +211,10 @@ class TestGc < Test::Unit::TestCase
stat = GC.stat
stat_heap = GC.stat_heap
- GC.stat(stat)
- GC.stat_heap(nil, stat_heap)
+ 2.times do
+ GC.stat(stat)
+ GC.stat_heap(nil, stat_heap)
+ end
stat_heap_sum = Hash.new(0)
stat_heap.values.each do |hash|
@@ -208,17 +227,36 @@ class TestGc < Test::Unit::TestCase
assert_equal stat[:heap_available_slots], stat_heap_sum[:heap_eden_slots] + stat_heap_sum[:heap_tomb_slots]
assert_equal stat[:total_allocated_pages], stat_heap_sum[:total_allocated_pages]
assert_equal stat[:total_freed_pages], stat_heap_sum[:total_freed_pages]
+ assert_equal stat[:total_allocated_objects], stat_heap_sum[:total_allocated_objects]
+ assert_equal stat[:total_freed_objects], stat_heap_sum[:total_freed_objects]
+ end
+
+ def test_measure_total_time
+ assert_separately([], __FILE__, __LINE__, <<~RUBY)
+ GC.measure_total_time = false
+
+ time_before = GC.stat(:time)
+
+ # Generate some garbage
+ Random.new.bytes(100 * 1024 * 1024)
+ GC.start
+
+ time_after = GC.stat(:time)
+
+ # If time measurement is disabled, the time stat should not change
+ assert_equal time_before, time_after
+ RUBY
end
def test_latest_gc_info
omit 'stress' if GC.stress
- assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-'eom'
- GC.start
- count = GC.stat(:heap_free_slots) + GC.stat(:heap_allocatable_pages) * GC::INTERNAL_CONSTANTS[:HEAP_PAGE_OBJ_LIMIT]
- count.times{ "a" + "b" }
- assert_equal :newobj, GC.latest_gc_info[:gc_by]
- eom
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ GC.start
+ count = GC.stat(:heap_free_slots) + GC.stat(:heap_allocatable_pages) * GC::INTERNAL_CONSTANTS[:HEAP_PAGE_OBJ_LIMIT]
+ count.times{ "a" + "b" }
+ assert_equal :newobj, GC.latest_gc_info[:gc_by]
+ RUBY
GC.latest_gc_info(h = {}) # allocate hash and rehearsal
GC.start
@@ -229,6 +267,7 @@ class TestGc < Test::Unit::TestCase
assert_equal :force, h[:major_by] if use_rgengc?
assert_equal :method, h[:gc_by]
assert_equal true, h[:immediate_sweep]
+ assert_equal true, h.key?(:need_major_by)
GC.stress = true
assert_equal :force, GC.latest_gc_info[:major_by]
@@ -246,8 +285,82 @@ class TestGc < Test::Unit::TestCase
assert_raise_with_message(ArgumentError, /\u{30eb 30d3 30fc}/) {GC.latest_gc_info(:"\u{30eb 30d3 30fc}")}
end
+ def test_latest_gc_info_need_major_by
+ return unless use_rgengc?
+ omit 'stress' if GC.stress
+
+ 3.times { GC.start }
+ assert_nil GC.latest_gc_info(:need_major_by)
+
+ # allocate objects until need_major_by is set or major GC happens
+ objects = []
+ while GC.latest_gc_info(:need_major_by).nil?
+ objects.append(100.times.map { '*' })
+ end
+
+ # We need to ensure that no GC gets ran before the call to GC.start since
+ # it would trigger a major GC. Assertions could allocate objects and
+ # trigger a GC so we don't run assertions until we perform the major GC.
+ need_major_by = GC.latest_gc_info(:need_major_by)
+ GC.start(full_mark: false) # should be upgraded to major
+ major_by = GC.latest_gc_info(:major_by)
+
+ assert_not_nil(need_major_by)
+ assert_not_nil(major_by)
+ end
+
+ def test_latest_gc_info_weak_references_count
+ assert_separately([], __FILE__, __LINE__, <<~RUBY)
+ count = 10_000
+ # Some weak references may be created, so allow some margin of error
+ error_tolerance = 100
+
+ # Run full GC to clear out weak references
+ GC.start
+ # Run full GC again to collect stats about weak references
+ GC.start
+
+ before_weak_references_count = GC.latest_gc_info(:weak_references_count)
+ before_retained_weak_references_count = GC.latest_gc_info(:retained_weak_references_count)
+
+ # Create some objects and place it in a WeakMap
+ wmap = ObjectSpace::WeakMap.new
+ ary = Array.new(count)
+ enum = count.times
+ enum.each.with_index do |i|
+ obj = Object.new
+ ary[i] = obj
+ wmap[obj] = nil
+ end
+
+ # Run full GC to collect stats about weak references
+ GC.start
+
+ assert_operator(GC.latest_gc_info(:weak_references_count), :>=, before_weak_references_count + count - error_tolerance)
+ assert_operator(GC.latest_gc_info(:retained_weak_references_count), :>=, before_retained_weak_references_count + count - error_tolerance)
+ assert_operator(GC.latest_gc_info(:retained_weak_references_count), :<=, GC.latest_gc_info(:weak_references_count))
+
+ before_weak_references_count = GC.latest_gc_info(:weak_references_count)
+ before_retained_weak_references_count = GC.latest_gc_info(:retained_weak_references_count)
+
+ ary = nil
+
+ # Free ary, which should empty out the wmap
+ GC.start
+ # Run full GC again to collect stats about weak references
+ GC.start
+
+ # Sometimes the WeakMap has one element, which might be held on by registers.
+ assert_operator(wmap.size, :<=, 1)
+
+ assert_operator(GC.latest_gc_info(:weak_references_count), :<=, before_weak_references_count - count + error_tolerance)
+ assert_operator(GC.latest_gc_info(:retained_weak_references_count), :<=, before_retained_weak_references_count - count + error_tolerance)
+ assert_operator(GC.latest_gc_info(:retained_weak_references_count), :<=, GC.latest_gc_info(:weak_references_count))
+ RUBY
+ end
+
def test_stress_compile_send
- assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "")
+ assert_in_out_err([], <<-EOS, [], [], "")
GC.stress = true
begin
eval("A::B.c(1, 1, d: 234)")
@@ -257,7 +370,7 @@ class TestGc < Test::Unit::TestCase
end
def test_singleton_method
- assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "[ruby-dev:42832]")
+ assert_in_out_err([], <<-EOS, [], [], "[ruby-dev:42832]")
GC.stress = true
10.times do
obj = Object.new
@@ -269,7 +382,7 @@ class TestGc < Test::Unit::TestCase
end
def test_singleton_method_added
- assert_in_out_err(%w[--disable-gems], <<-EOS, [], [], "[ruby-dev:44436]")
+ assert_in_out_err([], <<-EOS, [], [], "[ruby-dev:44436]")
class BasicObject
undef singleton_method_added
def singleton_method_added(mid)
@@ -285,19 +398,23 @@ class TestGc < Test::Unit::TestCase
def test_gc_parameter
env = {
- "RUBY_GC_MALLOC_LIMIT" => "60000000",
- "RUBY_GC_HEAP_INIT_SLOTS" => "100000"
+ "RUBY_GC_HEAP_INIT_SLOTS" => "100"
}
- assert_normal_exit("exit", "[ruby-core:39777]", :child_env => env)
+ assert_in_out_err([env, "-W0", "-e", "exit"], "", [], [])
+ assert_in_out_err([env, "-W:deprecated", "-e", "exit"], "", [],
+ /The environment variable RUBY_GC_HEAP_INIT_SLOTS is deprecated; use environment variables RUBY_GC_HEAP_%d_INIT_SLOTS instead/)
- env = {
- "RUBYOPT" => "",
- "RUBY_GC_HEAP_INIT_SLOTS" => "100000"
- }
- assert_in_out_err([env, "-e", "exit"], "", [], [], "[ruby-core:39795]")
- assert_in_out_err([env, "-W0", "-e", "exit"], "", [], [], "[ruby-core:39795]")
- assert_in_out_err([env, "-W1", "-e", "exit"], "", [], [], "[ruby-core:39795]")
- assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_HEAP_INIT_SLOTS=100000/, "[ruby-core:39795]")
+ env = {}
+ GC.stat_heap.keys.each do |heap|
+ env["RUBY_GC_HEAP_#{heap}_INIT_SLOTS"] = "200000"
+ end
+ assert_normal_exit("exit", "", :child_env => env)
+
+ env = {}
+ GC.stat_heap.keys.each do |heap|
+ env["RUBY_GC_HEAP_#{heap}_INIT_SLOTS"] = "0"
+ end
+ assert_normal_exit("exit", "", :child_env => env)
env = {
"RUBY_GC_HEAP_GROWTH_FACTOR" => "2.0",
@@ -307,16 +424,13 @@ class TestGc < Test::Unit::TestCase
assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_HEAP_GROWTH_FACTOR=2.0/, "")
assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_HEAP_GROWTH_MAX_SLOTS=10000/, "[ruby-core:57928]")
- env = {
- "RUBY_GC_HEAP_INIT_SLOTS" => "100000",
- "RUBY_GC_HEAP_FREE_SLOTS" => "10000",
- "RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR" => "0.9",
- }
- assert_normal_exit("exit", "", :child_env => env)
- assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=0\.9/, "")
-
- # always full GC when RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR < 1.0
- assert_in_out_err([env, "-e", "1000_000.times{Object.new}; p(GC.stat[:minor_gc_count] < GC.stat[:major_gc_count])"], "", ['true'], //, "") if use_rgengc?
+ if use_rgengc?
+ env = {
+ "RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR" => "0.4",
+ }
+ # always full GC when RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR < 1.0
+ assert_in_out_err([env, "-e", "GC.start; 1000_000.times{Object.new}; p(GC.stat[:minor_gc_count] < GC.stat[:major_gc_count])"], "", ['true'], //, "")
+ end
env = {
"RUBY_GC_MALLOC_LIMIT" => "60000000",
@@ -339,6 +453,127 @@ class TestGc < Test::Unit::TestCase
assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_OLDMALLOC_LIMIT_MAX=16000000/, "")
assert_in_out_err([env, "-w", "-e", "exit"], "", [], /RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR=2.0/, "")
end
+
+ ["0.01", "0.1", "1.0"].each do |i|
+ env = {"RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR" => "0", "RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO" => i}
+ assert_separately([env, "-W0"], __FILE__, __LINE__, <<~RUBY)
+ GC.disable
+ GC.start
+ assert_equal((GC.stat[:old_objects] * #{i}).to_i, GC.stat[:remembered_wb_unprotected_objects_limit])
+ RUBY
+ end
+ end
+
+ def test_gc_parameter_init_slots
+ assert_separately([], __FILE__, __LINE__, <<~RUBY)
+ # Constant from gc.c.
+ GC_HEAP_INIT_SLOTS = 10_000
+ GC.stat_heap.each do |_, s|
+ multiple = s[:slot_size] / (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] + GC::INTERNAL_CONSTANTS[:RVALUE_OVERHEAD])
+ # Allocatable pages are assumed to have lost 1 slot due to alignment.
+ slots_per_page = (GC::INTERNAL_CONSTANTS[:HEAP_PAGE_OBJ_LIMIT] / multiple) - 1
+
+ total_slots = s[:heap_eden_slots] + s[:heap_allocatable_pages] * slots_per_page
+ assert_operator(total_slots, :>=, GC_HEAP_INIT_SLOTS, s)
+ end
+ RUBY
+
+ env = {}
+ # Make the heap big enough to ensure the heap never needs to grow.
+ sizes = GC.stat_heap.keys.reverse.map { |i| (i + 1) * 100_000 }
+ GC.stat_heap.keys.each do |heap|
+ env["RUBY_GC_HEAP_#{heap}_INIT_SLOTS"] = sizes[heap].to_s
+ end
+ assert_separately([env, "-W0"], __FILE__, __LINE__, <<~RUBY)
+ SIZES = #{sizes}
+ GC.stat_heap.each do |i, s|
+ multiple = s[:slot_size] / (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] + GC::INTERNAL_CONSTANTS[:RVALUE_OVERHEAD])
+ # Allocatable pages are assumed to have lost 1 slot due to alignment.
+ slots_per_page = (GC::INTERNAL_CONSTANTS[:HEAP_PAGE_OBJ_LIMIT] / multiple) - 1
+
+ total_slots = s[:heap_eden_slots] + s[:heap_allocatable_pages] * slots_per_page
+
+ # The delta is calculated as follows:
+ # - For allocated pages, each page can vary by 1 slot due to alignment.
+ # - For allocatable pages, we can end up with at most 1 extra page of slots.
+ assert_in_delta(SIZES[i], total_slots, s[:heap_eden_pages] + slots_per_page, s)
+ end
+ RUBY
+
+ # Check that the configured sizes are "remembered" across GC invocations.
+ assert_separately([env, "-W0"], __FILE__, __LINE__, <<~RUBY)
+ SIZES = #{sizes}
+
+ # Fill size pool 0 with transient objects.
+ ary = []
+ while GC.stat_heap(0, :heap_allocatable_pages) != 0
+ ary << Object.new
+ end
+ ary.clear
+ ary = nil
+
+ # Clear all the objects that were allocated.
+ GC.start
+
+ # Check that we still have the same number of slots as initially configured.
+ GC.stat_heap.each do |i, s|
+ multiple = s[:slot_size] / (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] + GC::INTERNAL_CONSTANTS[:RVALUE_OVERHEAD])
+ # Allocatable pages are assumed to have lost 1 slot due to alignment.
+ slots_per_page = (GC::INTERNAL_CONSTANTS[:HEAP_PAGE_OBJ_LIMIT] / multiple) - 1
+
+ total_slots = s[:heap_eden_slots] + s[:heap_allocatable_pages] * slots_per_page
+
+ # The delta is calculated as follows:
+ # - For allocated pages, each page can vary by 1 slot due to alignment.
+ # - For allocatable pages, we can end up with at most 1 extra page of slots.
+ assert_in_delta(SIZES[i], total_slots, s[:heap_eden_pages] + slots_per_page, s)
+ end
+ RUBY
+
+ # Check that we don't grow the heap in minor GC if we have alloctable pages.
+ env["RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO"] = "0.3"
+ env["RUBY_GC_HEAP_FREE_SLOTS_GOAL_RATIO"] = "0.99"
+ env["RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO"] = "1.0"
+ env["RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR"] = "100" # Large value to disable major GC
+ assert_separately([env, "-W0"], __FILE__, __LINE__, <<~RUBY)
+ SIZES = #{sizes}
+
+ # Run a major GC to clear out dead objects.
+ GC.start
+
+ # Disable GC so we can control when GC is ran.
+ GC.disable
+
+ # Run minor GC enough times so that we don't grow the heap because we
+ # haven't yet ran RVALUE_OLD_AGE minor GC cycles.
+ GC::INTERNAL_CONSTANTS[:RVALUE_OLD_AGE].times { GC.start(full_mark: false) }
+
+ # Fill size pool 0 to over 50% full so that the number of allocatable
+ # pages that will be created will be over the number in heap_allocatable_pages
+ # (calculated using RUBY_GC_HEAP_FREE_SLOTS_MIN_RATIO).
+ # 70% was chosen here to guarantee that.
+ ary = []
+ while GC.stat_heap(0, :heap_allocatable_pages) >
+ (GC.stat_heap(0, :heap_allocatable_pages) + GC.stat_heap(0, :heap_eden_pages)) * 0.3
+ ary << Object.new
+ end
+
+ GC.start(full_mark: false)
+
+ # Check that we still have the same number of slots as initially configured.
+ GC.stat_heap.each do |i, s|
+ multiple = s[:slot_size] / (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] + GC::INTERNAL_CONSTANTS[:RVALUE_OVERHEAD])
+ # Allocatable pages are assumed to have lost 1 slot due to alignment.
+ slots_per_page = (GC::INTERNAL_CONSTANTS[:HEAP_PAGE_OBJ_LIMIT] / multiple) - 1
+
+ total_slots = s[:heap_eden_slots] + s[:heap_allocatable_pages] * slots_per_page
+
+ # The delta is calculated as follows:
+ # - For allocated pages, each page can vary by 1 slot due to alignment.
+ # - For allocatable pages, we can end up with at most 1 extra page of slots.
+ assert_in_delta(SIZES[i], total_slots, s[:heap_eden_pages] + slots_per_page, s)
+ end
+ RUBY
end
def test_profiler_enabled
@@ -352,19 +587,27 @@ class TestGc < Test::Unit::TestCase
def test_profiler_clear
omit "for now"
- assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-'eom', timeout: 30
- GC::Profiler.enable
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY', timeout: 30)
+ GC::Profiler.enable
- GC.start
- assert_equal(1, GC::Profiler.raw_data.size)
- GC::Profiler.clear
- assert_equal(0, GC::Profiler.raw_data.size)
+ GC.start
+ assert_equal(1, GC::Profiler.raw_data.size)
+ GC::Profiler.clear
+ assert_equal(0, GC::Profiler.raw_data.size)
+
+ 200.times{ GC.start }
+ assert_equal(200, GC::Profiler.raw_data.size)
+ GC::Profiler.clear
+ assert_equal(0, GC::Profiler.raw_data.size)
+ RUBY
+ end
- 200.times{ GC.start }
- assert_equal(200, GC::Profiler.raw_data.size)
- GC::Profiler.clear
- assert_equal(0, GC::Profiler.raw_data.size)
- eom
+ def test_profiler_raw_data
+ GC::Profiler.enable
+ GC.start
+ assert GC::Profiler.raw_data
+ ensure
+ GC::Profiler.disable
end
def test_profiler_total_time
@@ -378,38 +621,42 @@ class TestGc < Test::Unit::TestCase
end
def test_finalizing_main_thread
- assert_in_out_err(%w[--disable-gems], <<-EOS, ["\"finalize\""], [], "[ruby-dev:46647]")
+ assert_in_out_err([], <<-EOS, ["\"finalize\""], [], "[ruby-dev:46647]")
ObjectSpace.define_finalizer(Thread.main) { p 'finalize' }
EOS
end
def test_expand_heap
- assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-'eom'
- GC.start
- base_length = GC.stat[:heap_eden_pages]
- (base_length * 500).times{ 'a' }
- GC.start
- base_length = GC.stat[:heap_eden_pages]
- (base_length * 500).times{ 'a' }
- GC.start
- assert_in_epsilon base_length, (v = GC.stat[:heap_eden_pages]), 1/8r,
- "invalid heap expanding (base_length: #{base_length}, GC.stat[:heap_eden_pages]: #{v})"
+ assert_separately([], __FILE__, __LINE__, <<~'RUBY')
+ GC.start
+ base_length = GC.stat[:heap_eden_pages]
+ (base_length * 500).times{ 'a' }
+ GC.start
+ base_length = GC.stat[:heap_eden_pages]
+ (base_length * 500).times{ 'a' }
+ GC.start
+ assert_in_epsilon base_length, (v = GC.stat[:heap_eden_pages]), 1/8r,
+ "invalid heap expanding (base_length: #{base_length}, GC.stat[:heap_eden_pages]: #{v})"
- a = []
- (base_length * 500).times{ a << 'a'; nil }
- GC.start
- assert_operator base_length, :<, GC.stat[:heap_eden_pages] + 1
- eom
+ a = []
+ (base_length * 500).times{ a << 'a'; nil }
+ GC.start
+ assert_operator base_length, :<, GC.stat[:heap_eden_pages] + 1
+ RUBY
end
def test_thrashing_for_young_objects
# This test prevents bugs like [Bug #18929]
- assert_separately %w[--disable-gem], __FILE__, __LINE__, <<-RUBY
+ assert_separately([], __FILE__, __LINE__, <<-'RUBY')
+ # Grow the heap
+ @ary = 100_000.times.map { Object.new }
+
# Warmup to make sure heap stabilizes
1_000_000.times { Object.new }
before_stats = GC.stat
+ before_stat_heap = GC.stat_heap
1_000_000.times { Object.new }
@@ -418,13 +665,17 @@ class TestGc < Test::Unit::TestCase
GC.start(full_mark: false)
after_stats = GC.stat
+ after_stat_heap = GC.stat_heap
+
+ # Debugging output to for failures in trunk-repeat50@phosphorus-docker
+ debug_msg = "before_stats: #{before_stats}\nbefore_stat_heap: #{before_stat_heap}\nafter_stats: #{after_stats}\nafter_stat_heap: #{after_stat_heap}"
# Should not be thrashing in page creation
- assert_equal before_stats[:heap_allocated_pages], after_stats[:heap_allocated_pages]
- assert_equal 0, after_stats[:heap_tomb_pages]
- assert_equal 0, after_stats[:total_freed_pages]
+ assert_equal before_stats[:heap_allocated_pages], after_stats[:heap_allocated_pages], debug_msg
+ assert_equal 0, after_stats[:heap_tomb_pages], debug_msg
+ assert_equal 0, after_stats[:total_freed_pages], debug_msg
# Only young objects, so should not trigger major GC
- assert_equal before_stats[:major_gc_count], after_stats[:major_gc_count]
+ assert_equal before_stats[:major_gc_count], after_stats[:major_gc_count], debug_msg
RUBY
end
@@ -487,11 +738,11 @@ class TestGc < Test::Unit::TestCase
end
def test_finalizer_passed_object_id
- assert_in_out_err(%w[--disable-gems], <<-EOS, ["true"], [])
+ assert_in_out_err([], <<~RUBY, ["true"], [])
o = Object.new
obj_id = o.object_id
ObjectSpace.define_finalizer(o, ->(id){ p id == obj_id })
- EOS
+ RUBY
end
def test_verify_internal_consistency
@@ -576,6 +827,15 @@ class TestGc < Test::Unit::TestCase
obj = nil
end
end;
+
+ assert_normal_exit "#{<<~"begin;"}\n#{<<~'end;'}", '[Bug #20042]'
+ begin;
+ def (f = Object.new).call = nil # missing ID
+ o = Object.new
+ ObjectSpace.define_finalizer(o, f)
+ o = nil
+ GC.start
+ end;
end
def test_object_ids_never_repeat
@@ -591,4 +851,30 @@ class TestGc < Test::Unit::TestCase
Module.new.class_eval( (["# shareable_constant_value: literal"] +
(0..100000).map {|i| "M#{ i } = {}" }).join("\n"))
end
+
+ def test_old_to_young_reference
+ original_gc_disabled = GC.disable
+
+ require "objspace"
+
+ old_obj = Object.new
+ 4.times { GC.start }
+
+ assert_include ObjectSpace.dump(old_obj), '"old":true'
+
+ young_obj = Object.new
+ old_obj.instance_variable_set(:@test, young_obj)
+
+ # Not immediately promoted to old generation
+ 3.times do
+ assert_not_include ObjectSpace.dump(young_obj), '"old":true'
+ GC.start
+ end
+
+ # Takes 4 GC to promote to old generation
+ GC.start
+ assert_include ObjectSpace.dump(young_obj), '"old":true'
+ ensure
+ GC.enable if !original_gc_disabled
+ end
end
diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb
index 92a2be1174..f47c0b046b 100644
--- a/test/ruby/test_gc_compact.rb
+++ b/test/ruby/test_gc_compact.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
require 'test/unit'
-require 'fiddle'
-require 'etc'
if RUBY_PLATFORM =~ /s390x/
warn "Currently, it is known that the compaction does not work well on s390x; contribution is welcome https://github.com/ruby/ruby/pull/5077"
@@ -112,10 +110,6 @@ class TestGCCompact < Test::Unit::TestCase
end
end
- def os_page_size
- return true unless defined?(Etc::SC_PAGE_SIZE)
- end
-
def test_gc_compact_stats
list = []
@@ -130,10 +124,6 @@ class TestGCCompact < Test::Unit::TestCase
refute_predicate compact_stats[:moved], :empty?
end
- def memory_location(obj)
- (Fiddle.dlwrap(obj) >> 1)
- end
-
def big_list(level = 10)
if level > 0
big_list(level - 1)
@@ -146,21 +136,6 @@ class TestGCCompact < Test::Unit::TestCase
end
end
- # Find an object that's allocated in a slot that had a previous
- # tenant, and that tenant moved and is still alive
- def find_object_in_recycled_slot(addresses)
- new_object = nil
-
- 100_000.times do
- new_object = Object.new
- if addresses.index memory_location(new_object)
- break
- end
- end
-
- new_object
- end
-
def test_complex_hash_keys
list_of_objects = big_list
hash = list_of_objects.hash
@@ -209,48 +184,155 @@ class TestGCCompact < Test::Unit::TestCase
assert_equal([:call, :line], results)
end
+ def test_updating_references_for_heap_allocated_shared_arrays
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ begin;
+ ary = []
+ 50.times { |i| ary << i }
+
+ # Pointer in slice should point to buffer of ary
+ slice = ary[10..40]
+
+ # Check that slice is pointing to buffer of ary
+ assert_include(ObjectSpace.dump(slice), '"shared":true')
+
+ # Run compaction to re-embed ary
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ # Assert that slice is pointer to updated buffer in ary
+ assert_equal(10, slice[0])
+ # Check that slice is still pointing to buffer of ary
+ assert_include(ObjectSpace.dump(slice), '"shared":true')
+ end;
+ end
+
+ def test_updating_references_for_embed_shared_arrays
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ begin;
+ ary = Array.new(50)
+ 50.times { |i| ary[i] = i }
+
+ # Ensure ary is embedded
+ assert_include(ObjectSpace.dump(ary), '"embedded":true')
+
+ slice = ary[10..40]
+
+ # Check that slice is pointing to buffer of ary
+ assert_include(ObjectSpace.dump(slice), '"shared":true')
+
+ # Run compaction to re-embed ary
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ # Assert that slice is pointer to updated buffer in ary
+ assert_equal(10, slice[0])
+ # Check that slice is still pointing to buffer of ary
+ assert_include(ObjectSpace.dump(slice), '"shared":true')
+ end;
+ end
+
+ def test_updating_references_for_heap_allocated_frozen_shared_arrays
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ begin;
+ ary = []
+ 50.times { |i| ary << i }
+ # Frozen arrays can become shared root without RARRAY_SHARED_ROOT_FLAG
+ ary.freeze
+
+ slice = ary[10..40]
+
+ # Check that slice is pointing to buffer of ary
+ assert_include(ObjectSpace.dump(slice), '"shared":true')
+
+ # Run compaction to re-embed ary
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ # Assert that slice is pointer to updated buffer in ary
+ assert_equal(10, slice[0])
+ # Check that slice is still pointing to buffer of ary
+ assert_include(ObjectSpace.dump(slice), '"shared":true')
+ end;
+ end
+
+ def test_updating_references_for_embed_frozen_shared_arrays
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ begin;
+ ary = Array.new(50)
+ 50.times { |i| ary[i] = i }
+ # Frozen arrays can become shared root without RARRAY_SHARED_ROOT_FLAG
+ ary.freeze
+
+ # Ensure ary is embedded
+ assert_include(ObjectSpace.dump(ary), '"embedded":true')
+
+ slice = ary[10..40]
+
+ # Check that slice is pointing to buffer of ary
+ assert_include(ObjectSpace.dump(slice), '"shared":true')
+
+ # Run compaction to re-embed ary
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ # Assert that slice is pointer to updated buffer in ary
+ assert_equal(10, slice[0])
+ # Check that slice is still pointing to buffer of ary
+ assert_include(ObjectSpace.dump(slice), '"shared":true')
+ end;
+ end
+
def test_moving_arrays_down_size_pools
- omit if !GC.using_rvargc?
- assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
begin;
- ARY_COUNT = 500
+ ARY_COUNT = 50000
GC.verify_compaction_references(expand_heap: true, toward: :empty)
- arys = ARY_COUNT.times.map do
- ary = "abbbbbbbbbb".chars
- ary.uniq!
- end
+ Fiber.new {
+ $arys = ARY_COUNT.times.map do
+ ary = "abbbbbbbbbb".chars
+ ary.uniq!
+ end
+ }.resume
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats.dig(:moved_down, :T_ARRAY), :>=, ARY_COUNT)
- assert(arys) # warning: assigned but unused variable - arys
+ assert_operator(stats.dig(:moved_down, :T_ARRAY) || 0, :>=, ARY_COUNT - 10)
+ refute_empty($arys.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
end;
end
def test_moving_arrays_up_size_pools
- omit if !GC.using_rvargc?
- assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
begin;
- ARY_COUNT = 500
+ ARY_COUNT = 50000
GC.verify_compaction_references(expand_heap: true, toward: :empty)
- ary = "hello".chars
- arys = ARY_COUNT.times.map do
- x = []
- ary.each { |e| x << e }
- x
- end
+ Fiber.new {
+ ary = "hello".chars
+ $arys = ARY_COUNT.times.map do
+ x = []
+ ary.each { |e| x << e }
+ x
+ end
+ }.resume
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats.dig(:moved_up, :T_ARRAY), :>=, ARY_COUNT)
- assert(arys) # warning: assigned but unused variable - arys
+ assert_operator(stats.dig(:moved_up, :T_ARRAY) || 0, :>=, ARY_COUNT - 10)
+ refute_empty($arys.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
end;
end
def test_moving_objects_between_size_pools
- assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
begin;
class Foo
def add_ivars
@@ -260,51 +342,114 @@ class TestGCCompact < Test::Unit::TestCase
end
end
- OBJ_COUNT = 500
+ OBJ_COUNT = 50000
GC.verify_compaction_references(expand_heap: true, toward: :empty)
- ary = OBJ_COUNT.times.map { Foo.new }
- ary.each(&:add_ivars)
+ Fiber.new {
+ $ary = OBJ_COUNT.times.map { Foo.new }
+ $ary.each(&:add_ivars)
+
+ GC.start
+ Foo.new.add_ivars
+ }.resume
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats[:moved_up][:T_OBJECT], :>=, OBJ_COUNT)
+ assert_operator(stats.dig(:moved_up, :T_OBJECT) || 0, :>=, OBJ_COUNT - 10)
+ refute_empty($ary.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
end;
end
def test_moving_strings_up_size_pools
- omit if !GC.using_rvargc?
- assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 30, signal: :SEGV)
begin;
- STR_COUNT = 500
+ STR_COUNT = 50000
GC.verify_compaction_references(expand_heap: true, toward: :empty)
- str = "a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]
- ary = STR_COUNT.times.map { "" << str }
+ Fiber.new {
+ str = "a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 4
+ $ary = STR_COUNT.times.map { +"" << str }
+ }.resume
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats[:moved_up][:T_STRING], :>=, STR_COUNT)
- assert(ary) # warning: assigned but unused variable - ary
+ assert_operator(stats[:moved_up][:T_STRING], :>=, STR_COUNT - 10)
+ refute_empty($ary.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
end;
end
def test_moving_strings_down_size_pools
- omit if !GC.using_rvargc?
- assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 10, signal: :SEGV)
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 30, signal: :SEGV)
begin;
- STR_COUNT = 500
+ STR_COUNT = 50000
GC.verify_compaction_references(expand_heap: true, toward: :empty)
- ary = STR_COUNT.times.map { ("a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]).squeeze! }
+ Fiber.new {
+ $ary = STR_COUNT.times.map { ("a" * GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 4).squeeze! }
+ }.resume
stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
- assert_operator(stats[:moved_down][:T_STRING], :>=, STR_COUNT)
- assert(ary) # warning: assigned but unused variable - ary
+ assert_operator(stats[:moved_down][:T_STRING], :>=, STR_COUNT - 10)
+ refute_empty($ary.keep_if { |o| ObjectSpace.dump(o).include?('"embedded":true') })
+ end;
+ end
+
+ def test_moving_hashes_down_size_pools
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+ # AR and ST hashes are in the same size pool on 32 bit
+ omit unless RbConfig::SIZEOF["uint64_t"] <= RbConfig::SIZEOF["void*"]
+
+ assert_separately(%w[-robjspace], "#{<<~"begin;"}\n#{<<~"end;"}", timeout: 30, signal: :SEGV)
+ begin;
+ HASH_COUNT = 50000
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ Fiber.new {
+ base_hash = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8 }
+ $ary = HASH_COUNT.times.map { base_hash.dup }
+ $ary.each_with_index { |h, i| h[:i] = 9 }
+ }.resume
+
+ stats = GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ assert_operator(stats[:moved_down][:T_HASH], :>=, HASH_COUNT - 10)
+ end;
+ end
+
+ def test_moving_objects_between_size_pools_keeps_shape_frozen_status
+ # [Bug #19536]
+ assert_separately([], "#{<<~"begin;"}\n#{<<~"end;"}")
+ begin;
+ class A
+ def add_ivars
+ @a = @b = @c = @d = 1
+ end
+
+ def set_a
+ @a = 10
+ end
+ end
+
+ a = A.new
+ a.add_ivars
+ a.freeze
+
+ b = A.new
+ b.add_ivars
+ b.set_a # Set the inline cache in set_a
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ assert_raise(FrozenError) { a.set_a }
end;
end
end
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index 83d16d462e..f60ba0cffd 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -4,7 +4,6 @@ require 'test/unit'
EnvUtil.suppress_warning {require 'continuation'}
class TestHash < Test::Unit::TestCase
-
def test_hash
x = @cls[1=>2, 2=>4, 3=>6]
y = @cls[1=>2, 2=>4, 3=>6] # y = {1, 2, 2, 4, 3, 6} # 1.9 doesn't support
@@ -85,20 +84,9 @@ class TestHash < Test::Unit::TestCase
self => 'self', true => 'true', nil => 'nil',
'nil' => nil
]
- @verbose = $VERBOSE
end
def teardown
- $VERBOSE = @verbose
- end
-
- def test_bad_initialize_copy
- h = Class.new(Hash) {
- def initialize_copy(h)
- super(Object.new)
- end
- }.new
- assert_raise(TypeError) { h.dup }
end
def test_clear_initialize_copy
@@ -113,35 +101,6 @@ class TestHash < Test::Unit::TestCase
assert_equal(2, h[1])
end
- def test_dup_will_not_rehash
- assert_hash_does_not_rehash(&:dup)
- end
-
- def assert_hash_does_not_rehash
- obj = Object.new
- class << obj
- attr_accessor :hash_calls
- def hash
- @hash_calls += 1
- super
- end
- end
- obj.hash_calls = 0
- hash = {obj => 42}
- assert_equal(1, obj.hash_calls)
- yield hash
- assert_equal(1, obj.hash_calls)
- end
-
- def test_select_reject_will_not_rehash
- assert_hash_does_not_rehash do |hash|
- hash.select { true }
- end
- assert_hash_does_not_rehash do |hash|
- hash.reject { false }
- end
- end
-
def test_s_AREF_from_hash
h = @cls["a" => 100, "b" => 200]
assert_equal(100, h['a'])
@@ -219,6 +178,16 @@ class TestHash < Test::Unit::TestCase
assert_equal('default', h['spurious'])
end
+ def test_st_literal_memory_leak
+ assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", rss: true)
+ begin;
+ 1_000_000.times do
+ # >8 element hashes are ST allocated rather than AR allocated
+ {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9}
+ end
+ end;
+ end
+
def test_try_convert
assert_equal({1=>2}, Hash.try_convert({1=>2}))
assert_equal(nil, Hash.try_convert("1=>2"))
@@ -294,78 +263,6 @@ class TestHash < Test::Unit::TestCase
assert_equal(256, h[z])
end
- def test_AREF_fstring_key
- # warmup ObjectSpace.count_objects
- ObjectSpace.count_objects
-
- h = {"abc" => 1}
- before = ObjectSpace.count_objects[:T_STRING]
- 5.times{ h["abc"] }
- assert_equal before, ObjectSpace.count_objects[:T_STRING]
- end
-
- def test_AREF_fstring_key_default_proc
- assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- h = Hash.new do |h, k|
- k.frozen?
- end
-
- str = "foo"
- refute str.frozen? # assumes this file is frozen_string_literal: false
- refute h[str]
- refute h["foo"]
- end;
- end
-
- def test_ASET_fstring_key
- a, b = {}, {}
- assert_equal 1, a["abc"] = 1
- assert_equal 1, b["abc"] = 1
- assert_same a.keys[0], b.keys[0]
- end
-
- def test_ASET_fstring_non_literal_key
- underscore = "_"
- non_literal_strings = Proc.new{ ["abc#{underscore}def", "abc" * 5, "abc" + "def", "" << "ghi" << "jkl"] }
-
- a, b = {}, {}
- non_literal_strings.call.each do |string|
- assert_equal 1, a[string] = 1
- end
-
- non_literal_strings.call.each do |string|
- assert_equal 1, b[string] = 1
- end
-
- [a.keys, b.keys].transpose.each do |key_a, key_b|
- assert_same key_a, key_b
- end
- end
-
- def test_hash_aset_fstring_identity
- h = {}.compare_by_identity
- h['abc'] = 1
- h['abc'] = 2
- assert_equal 2, h.size, '[ruby-core:78783] [Bug #12855]'
- end
-
- def test_hash_aref_fstring_identity
- h = {}.compare_by_identity
- h['abc'] = 1
- assert_nil h['abc'], '[ruby-core:78783] [Bug #12855]'
- end
-
- def test_NEWHASH_fstring_key
- a = {"ABC" => :t}
- b = {"ABC" => :t}
- assert_same a.keys[0], b.keys[0]
- assert_same "ABC".freeze, a.keys[0]
- var = +'ABC'
- c = { var => :t }
- assert_same "ABC".freeze, c.keys[0]
- end
-
def test_EQUAL # '=='
h1 = @cls[ "a" => 1, "c" => 2 ]
h2 = @cls[ "a" => 1, "c" => 2, 7 => 35 ]
@@ -472,6 +369,10 @@ class TestHash < Test::Unit::TestCase
end
end
assert_equal(base.dup, h)
+
+ h = base.dup
+ assert_same h, h.delete_if {h.assoc(nil); true}
+ assert_empty h
end
def test_keep_if
@@ -842,14 +743,6 @@ class TestHash < Test::Unit::TestCase
assert_predicate(h, :compare_by_identity?)
end
- def test_replace_bug15358
- h1 = {}
- h2 = {a:1,b:2,c:3,d:4,e:5}
- h2.replace(h1)
- GC.start
- assert(true)
- end
-
def test_shift
h = @h.dup
@@ -965,13 +858,6 @@ class TestHash < Test::Unit::TestCase
assert_instance_of(Hash, h)
end
- def test_nil_to_h
- h = nil.to_h
- assert_equal({}, h)
- assert_nil(h.default)
- assert_nil(h.default_proc)
- end
-
def test_to_s
h = @cls[ 1 => 2, "cat" => "dog", 1.5 => :fred ]
assert_equal(h.inspect, h.to_s)
@@ -1018,12 +904,6 @@ class TestHash < Test::Unit::TestCase
assert_equal([], expected - vals)
end
- def test_initialize_wrong_arguments
- assert_raise(ArgumentError) do
- Hash.new(0) { }
- end
- end
-
def test_create
assert_equal({1=>2, 3=>4}, @cls[[[1,2],[3,4]]])
assert_raise(ArgumentError) { @cls[0, 1, 2] }
@@ -1305,15 +1185,6 @@ class TestHash < Test::Unit::TestCase
assert_raise(FrozenError) { h2.replace(42) }
end
- def test_replace_memory_leak
- assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}")
- h = ("aa".."zz").each_with_index.to_h
- 10_000.times {h.dup}
- begin;
- 500_000.times {h.dup.replace(h)}
- end;
- end
-
def test_size2
assert_equal(0, @cls[].size)
end
@@ -1397,6 +1268,15 @@ class TestHash < Test::Unit::TestCase
assert_equal(@cls[a: 10, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], h)
end
+ def test_update_on_identhash
+ key = +'a'
+ i = @cls[].compare_by_identity
+ i[key] = 0
+ h = @cls[].update(i)
+ key.upcase!
+ assert_equal(0, h.fetch('a'))
+ end
+
def test_merge
h1 = @cls[1=>2, 3=>4]
h2 = {1=>3, 5=>7}
@@ -1419,10 +1299,10 @@ class TestHash < Test::Unit::TestCase
expected[7] = 8
h2 = h.merge(7=>8)
assert_equal(expected, h2)
- assert_equal(true, h2.compare_by_identity?)
+ assert_predicate(h2, :compare_by_identity?)
h2 = h.merge({})
assert_equal(h, h2)
- assert_equal(true, h2.compare_by_identity?)
+ assert_predicate(h2, :compare_by_identity?)
h = @cls[]
h.compare_by_identity
@@ -1430,10 +1310,10 @@ class TestHash < Test::Unit::TestCase
h1.compare_by_identity
h2 = h.merge(7=>8)
assert_equal(h1, h2)
- assert_equal(true, h2.compare_by_identity?)
+ assert_predicate(h2, :compare_by_identity?)
h2 = h.merge({})
assert_equal(h, h2)
- assert_equal(true, h2.compare_by_identity?)
+ assert_predicate(h2, :compare_by_identity?)
end
def test_merge!
@@ -1488,6 +1368,8 @@ class TestHash < Test::Unit::TestCase
end
def test_callcc
+ omit 'requires callcc support' unless respond_to?(:callcc)
+
h = @cls[1=>2]
c = nil
f = false
@@ -1508,6 +1390,8 @@ class TestHash < Test::Unit::TestCase
end
def test_callcc_iter_level
+ omit 'requires callcc support' unless respond_to?(:callcc)
+
bug9105 = '[ruby-dev:47803] [Bug #9105]'
h = @cls[1=>2, 3=>4]
c = nil
@@ -1526,6 +1410,8 @@ class TestHash < Test::Unit::TestCase
end
def test_callcc_escape
+ omit 'requires callcc support' unless respond_to?(:callcc)
+
bug9105 = '[ruby-dev:47803] [Bug #9105]'
assert_nothing_raised(RuntimeError, bug9105) do
h=@cls[]
@@ -1540,6 +1426,8 @@ class TestHash < Test::Unit::TestCase
end
def test_callcc_reenter
+ omit 'requires callcc support' unless respond_to?(:callcc)
+
bug9105 = '[ruby-dev:47803] [Bug #9105]'
assert_nothing_raised(RuntimeError, bug9105) do
h = @cls[1=>2,3=>4]
@@ -1587,6 +1475,16 @@ class TestHash < Test::Unit::TestCase
assert_predicate(h.dup, :compare_by_identity?, bug8703)
end
+ def test_compare_by_identy_memory_leak
+ assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #20145]", rss: true)
+ begin;
+ h = { 1 => 2 }.compare_by_identity
+ 1_000_000.times do
+ h.select { false }
+ end
+ end;
+ end
+
def test_same_key
bug9646 = '[ruby-dev:48047] [Bug #9646] Infinite loop at Hash#each'
h = @cls[a=[], 1]
@@ -1717,115 +1615,6 @@ class TestHash < Test::Unit::TestCase
end
end
- def test_exception_in_rehash_memory_leak
- return unless @cls == Hash
-
- bug9187 = '[ruby-core:58728] [Bug #9187]'
-
- prepare = <<-EOS
- class Foo
- def initialize
- @raise = false
- end
-
- def hash
- raise if @raise
- @raise = true
- return 0
- end
- end
- h = {Foo.new => true}
- EOS
-
- code = <<-EOS
- 10_0000.times do
- h.rehash rescue nil
- end
- GC.start
- EOS
-
- assert_no_memory_leak([], prepare, code, bug9187)
- end
-
- def test_wrapper
- bug9381 = '[ruby-core:59638] [Bug #9381]'
-
- wrapper = Class.new do
- def initialize(obj)
- @obj = obj
- end
-
- def hash
- @obj.hash
- end
-
- def eql?(other)
- @obj.eql?(other)
- end
- end
-
- bad = [
- 5, true, false, nil,
- 0.0, 1.72723e-77,
- :foo, "dsym_#{self.object_id.to_s(16)}_#{Time.now.to_i.to_s(16)}".to_sym,
- "str",
- ].select do |x|
- hash = {x => bug9381}
- hash[wrapper.new(x)] != bug9381
- end
- assert_empty(bad, bug9381)
- end
-
- def assert_hash_random(obj, dump = obj.inspect)
- a = [obj.hash.to_s]
- 3.times {
- assert_in_out_err(["-e", "print (#{dump}).hash"], "") do |r, e|
- a += r
- assert_equal([], e)
- end
- }
- assert_not_equal([obj.hash.to_s], a.uniq)
- assert_operator(a.uniq.size, :>, 2, proc {a.inspect})
- end
-
- def test_string_hash_random
- assert_hash_random('abc')
- end
-
- def test_symbol_hash_random
- assert_hash_random(:-)
- assert_hash_random(:foo)
- assert_hash_random("dsym_#{self.object_id.to_s(16)}_#{Time.now.to_i.to_s(16)}".to_sym)
- end
-
- def test_integer_hash_random
- assert_hash_random(0)
- assert_hash_random(+1)
- assert_hash_random(-1)
- assert_hash_random(+(1<<100))
- assert_hash_random(-(1<<100))
- end
-
- def test_float_hash_random
- assert_hash_random(0.0)
- assert_hash_random(+1.0)
- assert_hash_random(-1.0)
- assert_hash_random(1.72723e-77)
- assert_hash_random(Float::INFINITY, "Float::INFINITY")
- end
-
- def test_label_syntax
- return unless @cls == Hash
-
- feature4935 = '[ruby-core:37553] [Feature #4935]'
- x = 'world'
- hash = assert_nothing_raised(SyntaxError, feature4935) do
- break eval(%q({foo: 1, "foo-bar": 2, "hello-#{x}": 3, 'hello-#{x}': 4, 'bar': {}}))
- end
- assert_equal({:foo => 1, :'foo-bar' => 2, :'hello-world' => 3, :'hello-#{x}' => 4, :bar => {}}, hash, feature4935)
- x = x
- end
-
def test_dig
h = @cls[a: @cls[b: [1, 2, 3]], c: 4]
assert_equal(1, h.dig(:a, :b, 0))
@@ -1845,12 +1634,12 @@ class TestHash < Test::Unit::TestCase
def o.respond_to?(*args)
super
end
- assert_raise(TypeError, bug12030) {{foo: o}.dig(:foo, :foo)}
+ assert_raise(TypeError, bug12030) {@cls[foo: o].dig(:foo, :foo)}
end
def test_cmp
- h1 = {a:1, b:2}
- h2 = {a:1, b:2, c:3}
+ h1 = @cls[a:1, b:2]
+ h2 = @cls[a:1, b:2, c:3]
assert_operator(h1, :<=, h1)
assert_operator(h1, :<=, h2)
@@ -1874,8 +1663,8 @@ class TestHash < Test::Unit::TestCase
end
def test_cmp_samekeys
- h1 = {a:1}
- h2 = {a:2}
+ h1 = @cls[a:1]
+ h2 = @cls[a:2]
assert_operator(h1, :<=, h1)
assert_not_operator(h1, :<=, h2)
@@ -1899,15 +1688,15 @@ class TestHash < Test::Unit::TestCase
end
def test_to_proc
- h = {
+ h = @cls[
1 => 10,
2 => 20,
3 => 30,
- }
+ ]
assert_equal([10, 20, 30], [1, 2, 3].map(&h))
- assert_equal(true, h.to_proc.lambda?)
+ assert_predicate(h.to_proc, :lambda?)
end
def test_transform_keys
@@ -2037,22 +1826,6 @@ class TestHash < Test::Unit::TestCase
assert_equal(@cls[a: 2, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], x)
end
- def test_broken_hash_value
- bug14218 = '[ruby-core:84395] [Bug #14218]'
-
- assert_equal(0, 1_000_000.times.count{a=Object.new.hash; b=Object.new.hash; a < 0 && b < 0 && a + b > 0}, bug14218)
- assert_equal(0, 1_000_000.times.count{a=Object.new.hash; b=Object.new.hash; 0 + a + b != 0 + b + a}, bug14218)
- end
-
- def test_reserved_hash_val
- s = Struct.new(:hash)
- h = {}
- keys = [*0..8]
- keys.each {|i| h[s.new(i)]=true}
- msg = proc {h.inspect}
- assert_equal(keys, h.keys.map(&:hash), msg)
- end
-
def hrec h, n, &b
if n > 0
h.each{hrec(h, n-1, &b)}
@@ -2082,6 +1855,27 @@ class TestHash < Test::Unit::TestCase
# ignore
end
+ # Previously this test would fail because rb_hash inside opt_aref would look
+ # at the current method name
+ def test_hash_recursion_independent_of_mid
+ o = Class.new do
+ def hash(h, k)
+ h[k]
+ end
+
+ def any_other_name(h, k)
+ h[k]
+ end
+ end.new
+
+ rec = []; rec << rec
+
+ h = @cls[]
+ h[rec] = 1
+ assert o.hash(h, rec)
+ assert o.any_other_name(h, rec)
+ end
+
class TestSubHash < TestHash
class SubHash < Hash
end
@@ -2091,6 +1885,341 @@ class TestHash < Test::Unit::TestCase
super
end
end
+end
+
+class TestHashOnly < Test::Unit::TestCase
+ def test_bad_initialize_copy
+ h = Class.new(Hash) {
+ def initialize_copy(h)
+ super(Object.new)
+ end
+ }.new
+ assert_raise(TypeError) { h.dup }
+ end
+
+ def test_dup_will_not_rehash
+ assert_hash_does_not_rehash(&:dup)
+ end
+
+ def assert_hash_does_not_rehash
+ obj = Object.new
+ class << obj
+ attr_accessor :hash_calls
+ def hash
+ @hash_calls += 1
+ super
+ end
+ end
+ obj.hash_calls = 0
+ hash = {obj => 42}
+ assert_equal(1, obj.hash_calls)
+ yield hash
+ assert_equal(1, obj.hash_calls)
+ end
+
+ def test_select_reject_will_not_rehash
+ assert_hash_does_not_rehash do |hash|
+ hash.select { true }
+ end
+ assert_hash_does_not_rehash do |hash|
+ hash.reject { false }
+ end
+ end
+
+ def test_st_literal_memory_leak
+ assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", rss: true)
+ begin;
+ 1_000_000.times do
+ # >8 element hashes are ST allocated rather than AR allocated
+ {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9}
+ end
+ end;
+ end
+
+ def test_compare_by_id_memory_leak
+ assert_no_memory_leak([], "", <<~RUBY, rss: true)
+ 1_000_000.times do
+ {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8}.compare_by_identity
+ end
+ RUBY
+ end
+
+ def test_try_convert
+ assert_equal({1=>2}, Hash.try_convert({1=>2}))
+ assert_equal(nil, Hash.try_convert("1=>2"))
+ o = Object.new
+ def o.to_hash; {3=>4} end
+ assert_equal({3=>4}, Hash.try_convert(o))
+ end
+
+ def test_AREF_fstring_key
+ # warmup ObjectSpace.count_objects
+ ObjectSpace.count_objects
+
+ h = {"abc" => 1}
+ before = ObjectSpace.count_objects[:T_STRING]
+ 5.times{ h["abc"] }
+ assert_equal before, ObjectSpace.count_objects[:T_STRING]
+ end
+
+ def test_AREF_fstring_key_default_proc
+ assert_separately(['--disable-frozen-string-literal'], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ h = Hash.new do |h, k|
+ k.frozen?
+ end
+
+ str = "foo"
+ refute str.frozen?
+ refute h[str]
+ refute h["foo"]
+ end;
+ end
+
+ def test_ASET_fstring_key
+ a, b = {}, {}
+ assert_equal 1, a["abc"] = 1
+ assert_equal 1, b["abc"] = 1
+ assert_same a.keys[0], b.keys[0]
+ end
+
+ def test_ASET_fstring_non_literal_key
+ underscore = "_"
+ non_literal_strings = Proc.new{ ["abc#{underscore}def", "abc" * 5, "abc" + "def", "" << "ghi" << "jkl"] }
+
+ a, b = {}, {}
+ non_literal_strings.call.each do |string|
+ assert_equal 1, a[string] = 1
+ end
+
+ non_literal_strings.call.each do |string|
+ assert_equal 1, b[string] = 1
+ end
+
+ [a.keys, b.keys].transpose.each do |key_a, key_b|
+ assert_same key_a, key_b
+ end
+ end
+
+ def test_hash_aset_fstring_identity
+ h = {}.compare_by_identity
+ h['abc'] = 1
+ h['abc'] = 2
+ assert_equal 2, h.size, '[ruby-core:78783] [Bug #12855]'
+ end
+
+ def test_hash_aref_fstring_identity
+ h = {}.compare_by_identity
+ h['abc'] = 1
+ assert_nil h['abc'], '[ruby-core:78783] [Bug #12855]'
+ end
+
+ def test_NEWHASH_fstring_key
+ a = {"ABC" => :t}
+ b = {"ABC" => :t}
+ assert_same a.keys[0], b.keys[0]
+ assert_same "ABC".freeze, a.keys[0]
+ var = +'ABC'
+ c = { var => :t }
+ assert_same "ABC".freeze, c.keys[0]
+ end
+
+ def test_rehash_memory_leak
+ assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
+ ar_hash = 1.times.map { |i| [i, i] }.to_h
+ st_hash = 10.times.map { |i| [i, i] }.to_h
+
+ code = proc do
+ ar_hash.rehash
+ st_hash.rehash
+ end
+ 1_000.times(&code)
+ PREP
+ 1_000_000.times(&code)
+ CODE
+ end
+
+ def test_replace_bug15358
+ h1 = {}
+ h2 = {a:1,b:2,c:3,d:4,e:5}
+ h2.replace(h1)
+ GC.start
+ assert(true)
+ end
+
+ def test_replace_st_with_ar
+ # ST hash
+ h1 = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9 }
+ # AR hash
+ h2 = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7 }
+ # Replace ST hash with AR hash
+ h1.replace(h2)
+ assert_equal(h2, h1)
+ end
+
+ def test_nil_to_h
+ h = nil.to_h
+ assert_equal({}, h)
+ assert_nil(h.default)
+ assert_nil(h.default_proc)
+ end
+
+ def test_initialize_wrong_arguments
+ assert_raise(ArgumentError) do
+ Hash.new(0) { }
+ end
+ end
+
+ def test_replace_memory_leak
+ assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true)
+ h = ("aa".."zz").each_with_index.to_h
+ 10_000.times {h.dup}
+ begin;
+ 500_000.times {h.dup.replace(h)}
+ end;
+ end
+
+ def hash_iter_recursion(h, level)
+ return if level == 0
+ h.each_key {}
+ h.each_value { hash_iter_recursion(h, level - 1) }
+ end
+
+ def test_iterlevel_in_ivar_bug19589
+ h = { a: nil }
+ hash_iter_recursion(h, 200)
+ assert true
+ end
+
+ def test_exception_in_rehash_memory_leak
+ bug9187 = '[ruby-core:58728] [Bug #9187]'
+
+ prepare = <<-EOS
+ class Foo
+ def initialize
+ @raise = false
+ end
+
+ def hash
+ raise if @raise
+ @raise = true
+ return 0
+ end
+ end
+ h = {Foo.new => true}
+ EOS
+
+ code = <<-EOS
+ 10_0000.times do
+ h.rehash rescue nil
+ end
+ GC.start
+ EOS
+
+ assert_no_memory_leak([], prepare, code, bug9187)
+ end
+
+ def test_memory_size_after_delete
+ require 'objspace'
+ h = {}
+ 1000.times {|i| h[i] = true}
+ big = ObjectSpace.memsize_of(h)
+ 1000.times {|i| h.delete(i)}
+ assert_operator ObjectSpace.memsize_of(h), :<, big/10
+ end
+
+ def test_wrapper
+ bug9381 = '[ruby-core:59638] [Bug #9381]'
+
+ wrapper = Class.new do
+ def initialize(obj)
+ @obj = obj
+ end
+
+ def hash
+ @obj.hash
+ end
+
+ def eql?(other)
+ @obj.eql?(other)
+ end
+ end
+
+ bad = [
+ 5, true, false, nil,
+ 0.0, 1.72723e-77,
+ :foo, "dsym_#{self.object_id.to_s(16)}_#{Time.now.to_i.to_s(16)}".to_sym,
+ "str",
+ ].select do |x|
+ hash = {x => bug9381}
+ hash[wrapper.new(x)] != bug9381
+ end
+ assert_empty(bad, bug9381)
+ end
+
+ def assert_hash_random(obj, dump = obj.inspect)
+ a = [obj.hash.to_s]
+ 3.times {
+ assert_in_out_err(["-e", "print (#{dump}).hash"], "") do |r, e|
+ a += r
+ assert_equal([], e)
+ end
+ }
+ assert_not_equal([obj.hash.to_s], a.uniq)
+ assert_operator(a.uniq.size, :>, 2, proc {a.inspect})
+ end
+
+ def test_string_hash_random
+ assert_hash_random('abc')
+ end
+
+ def test_symbol_hash_random
+ assert_hash_random(:-)
+ assert_hash_random(:foo)
+ assert_hash_random("dsym_#{self.object_id.to_s(16)}_#{Time.now.to_i.to_s(16)}".to_sym)
+ end
+
+ def test_integer_hash_random
+ assert_hash_random(0)
+ assert_hash_random(+1)
+ assert_hash_random(-1)
+ assert_hash_random(+(1<<100))
+ assert_hash_random(-(1<<100))
+ end
+
+ def test_float_hash_random
+ assert_hash_random(0.0)
+ assert_hash_random(+1.0)
+ assert_hash_random(-1.0)
+ assert_hash_random(1.72723e-77)
+ assert_hash_random(Float::INFINITY, "Float::INFINITY")
+ end
+
+ def test_label_syntax
+ feature4935 = '[ruby-core:37553] [Feature #4935]'
+ x = 'world'
+ hash = assert_nothing_raised(SyntaxError, feature4935) do
+ break eval(%q({foo: 1, "foo-bar": 2, "hello-#{x}": 3, 'hello-#{x}': 4, 'bar': {}}))
+ end
+ assert_equal({:foo => 1, :'foo-bar' => 2, :'hello-world' => 3, :'hello-#{x}' => 4, :bar => {}}, hash, feature4935)
+ x = x
+ end
+
+ def test_broken_hash_value
+ bug14218 = '[ruby-core:84395] [Bug #14218]'
+
+ assert_equal(0, 1_000_000.times.count{a=Object.new.hash; b=Object.new.hash; a < 0 && b < 0 && a + b > 0}, bug14218)
+ assert_equal(0, 1_000_000.times.count{a=Object.new.hash; b=Object.new.hash; 0 + a + b != 0 + b + a}, bug14218)
+ end
+
+ def test_reserved_hash_val
+ s = Struct.new(:hash)
+ h = {}
+ keys = [*0..8]
+ keys.each {|i| h[s.new(i)]=true}
+ msg = proc {h.inspect}
+ assert_equal(keys, h.keys.map(&:hash), msg)
+ end
ruby2_keywords def get_flagged_hash(*args)
args.last
@@ -2116,23 +2245,11 @@ class TestHash < Test::Unit::TestCase
assert_raise(TypeError) { Hash.ruby2_keywords_hash(1) }
end
- def test_ar2st
- # insert
- obj = Object.new
- obj.instance_variable_set(:@h, h = {})
- def obj.hash
- 10.times{|i| @h[i] = i}
- 0
- end
- def obj.inspect
- 'test'
+ def ar2st_object
+ class << (obj = Object.new)
+ attr_reader :h
end
- h[obj] = true
- assert_equal '{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, test=>true}', h.inspect
-
- # delete
- obj = Object.new
- obj.instance_variable_set(:@h, h = {})
+ obj.instance_variable_set(:@h, {})
def obj.hash
10.times{|i| @h[i] = i}
0
@@ -2143,6 +2260,21 @@ class TestHash < Test::Unit::TestCase
def obj.eql? other
other.class == Object
end
+ obj
+ end
+
+ def test_ar2st_insert
+ obj = ar2st_object
+ h = obj.h
+
+ h[obj] = true
+ assert_equal '{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, test=>true}', h.inspect
+ end
+
+ def test_ar2st_delete
+ obj = ar2st_object
+ h = obj.h
+
obj2 = Object.new
def obj2.hash
0
@@ -2151,20 +2283,12 @@ class TestHash < Test::Unit::TestCase
h[obj2] = true
h.delete obj
assert_equal '{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9}', h.inspect
+ end
+
+ def test_ar2st_lookup
+ obj = ar2st_object
+ h = obj.h
- # lookup
- obj = Object.new
- obj.instance_variable_set(:@h, h = {})
- def obj.hash
- 10.times{|i| @h[i] = i}
- 0
- end
- def obj.inspect
- 'test'
- end
- def obj.eql? other
- other.class == Object
- end
obj2 = Object.new
def obj2.hash
0
@@ -2180,27 +2304,6 @@ class TestHash < Test::Unit::TestCase
end
end
- # Previously this test would fail because rb_hash inside opt_aref would look
- # at the current method name
- def test_hash_recursion_independent_of_mid
- o = Class.new do
- def hash(h, k)
- h[k]
- end
-
- def any_other_name(h, k)
- h[k]
- end
- end.new
-
- rec = []; rec << rec
-
- h = @cls[]
- h[rec] = 1
- assert o.hash(h, rec)
- assert o.any_other_name(h, rec)
- end
-
def test_any_hash_fixable
20.times do
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
@@ -2226,4 +2329,35 @@ class TestHash < Test::Unit::TestCase
end;
end
end
+
+ def test_compare_by_identity_during_iteration
+ h = { 1 => 1 }
+ h.each do
+ assert_raise(RuntimeError, "compare_by_identity during iteration") do
+ h.compare_by_identity
+ end
+ end
+ end
+
+ def test_ar_hash_to_st_hash
+ assert_normal_exit("#{<<~"begin;"}\n#{<<~'end;'}", 'https://bugs.ruby-lang.org/issues/20050#note-5')
+ begin;
+ srand(0)
+ class Foo
+ def to_a
+ []
+ end
+
+ def hash
+ $h.delete($h.keys.sample) if rand < 0.1
+ to_a.hash
+ end
+ end
+
+ 1000.times do
+ $h = {}
+ (0..10).each {|i| $h[Foo.new] ||= {} }
+ end
+ end;
+ end
end
diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb
index c3e11498be..3349a1c493 100644
--- a/test/ruby/test_integer.rb
+++ b/test/ruby/test_integer.rb
@@ -2,16 +2,9 @@
require 'test/unit'
class TestInteger < Test::Unit::TestCase
- BDSIZE = 0x4000000000000000.coerce(0)[0].size
- def self.bdsize(x)
- ((x + 1) / 8 + BDSIZE) / BDSIZE * BDSIZE
- end
- def bdsize(x)
- self.class.bdsize(x)
- end
-
FIXNUM_MIN = RbConfig::LIMITS['FIXNUM_MIN']
FIXNUM_MAX = RbConfig::LIMITS['FIXNUM_MAX']
+ LONG_MAX = RbConfig::LIMITS['LONG_MAX']
def test_aref
@@ -96,11 +89,16 @@ class TestInteger < Test::Unit::TestCase
assert_equal(0, 1 << -0x40000001)
assert_equal(0, 1 << -0x80000000)
assert_equal(0, 1 << -0x80000001)
- # assert_equal(bdsize(0x80000000), (1 << 0x80000000).size)
+
+ char_bit = RbConfig::LIMITS["UCHAR_MAX"].bit_length
+ size_max = RbConfig::LIMITS["SIZE_MAX"]
+ size_bit_max = size_max * char_bit
+ assert_raise_with_message(RangeError, /shift width/) {
+ 1 << size_bit_max
+ }
end
def test_rshift
- # assert_equal(bdsize(0x40000001), (1 >> -0x40000001).size)
assert_predicate((1 >> 0x80000000), :zero?)
assert_predicate((1 >> 0xffffffff), :zero?)
assert_predicate((1 >> 0x100000000), :zero?)
@@ -140,20 +138,6 @@ class TestInteger < Test::Unit::TestCase
assert_equal(1234, Integer(1234))
assert_equal(1, Integer(1.234))
- # base argument
- assert_equal(1234, Integer("1234", 10))
- assert_equal(668, Integer("1234", 8))
- assert_equal(4660, Integer("1234", 16))
- assert_equal(49360, Integer("1234", 36))
- # decimal, not octal
- assert_equal(1234, Integer("01234", 10))
- assert_raise(ArgumentError) { Integer("0x123", 10) }
- assert_raise(ArgumentError) { Integer(1234, 10) }
- assert_raise(ArgumentError) { Integer(12.34, 10) }
- assert_raise(ArgumentError) { Integer(Object.new, 1) }
-
- assert_raise(ArgumentError) { Integer(1, 1, 1) }
-
assert_equal(2 ** 50, Integer(2.0 ** 50))
assert_raise(TypeError) { Integer(nil) }
@@ -247,6 +231,39 @@ class TestInteger < Test::Unit::TestCase
end;
end
+ def test_Integer_when_to_str
+ def (obj = Object.new).to_str
+ "0x10"
+ end
+ assert_equal(16, Integer(obj))
+ end
+
+ def test_Integer_with_base
+ assert_equal(1234, Integer("1234", 10))
+ assert_equal(668, Integer("1234", 8))
+ assert_equal(4660, Integer("1234", 16))
+ assert_equal(49360, Integer("1234", 36))
+ # decimal, not octal
+ assert_equal(1234, Integer("01234", 10))
+ assert_raise(ArgumentError) { Integer("0x123", 10) }
+ assert_raise(ArgumentError) { Integer(1234, 10) }
+ assert_raise(ArgumentError) { Integer(12.34, 10) }
+ assert_raise(ArgumentError) { Integer(Object.new, 1) }
+
+ assert_raise(ArgumentError) { Integer(1, 1, 1) }
+
+ def (base = Object.new).to_int
+ 8
+ end
+ assert_equal(8, Integer("10", base))
+
+ assert_raise(TypeError) { Integer("10", "8") }
+ def (base = Object.new).to_int
+ "8"
+ end
+ assert_raise(TypeError) { Integer("10", base) }
+ end
+
def test_int_p
assert_not_predicate(1.0, :integer?)
assert_predicate(1, :integer?)
@@ -304,23 +321,34 @@ class TestInteger < Test::Unit::TestCase
begin;
called = false
Integer.class_eval do
- alias old_plus +
- undef +
- define_method(:+){|x| called = true; 1}
+ alias old_succ succ
+ undef succ
+ define_method(:succ){|x| called = true; x+1}
alias old_lt <
undef <
define_method(:<){|x| called = true}
end
+
+ fix = 1
+ fix.times{break 0}
+ fix_called = called
+
+ called = false
+
big = 2**65
big.times{break 0}
+ big_called = called
+
Integer.class_eval do
- undef +
- alias + old_plus
+ undef succ
+ alias succ old_succ
undef <
alias < old_lt
end
+
+ # Asssert that Fixnum and Bignum behave consistently
bug18377 = "[ruby-core:106361]"
- assert_equal(false, called, bug18377)
+ assert_equal(fix_called, big_called, bug18377)
end;
end
@@ -676,6 +704,14 @@ class TestInteger < Test::Unit::TestCase
def test_fdiv
assert_equal(1.0, 1.fdiv(1))
assert_equal(0.5, 1.fdiv(2))
+
+ m = 50 << Float::MANT_DIG
+ prev = 1.0
+ (1..100).each do |i|
+ val = (m + i).fdiv(m)
+ assert_operator val, :>=, prev, "1+epsilon*(#{i}/100)"
+ prev = val
+ end
end
def test_obj_fdiv
@@ -720,5 +756,9 @@ class TestInteger < Test::Unit::TestCase
assert_equal(10, (10**100-11).ceildiv(10**99-1))
assert_equal(11, (10**100-9).ceildiv(10**99-1))
+
+ o = Object.new
+ def o.coerce(other); [other, 10]; end
+ assert_equal(124, 1234.ceildiv(o))
end
end
diff --git a/test/ruby/test_integer_comb.rb b/test/ruby/test_integer_comb.rb
index 1ad13dd31b..150f45cfd7 100644
--- a/test/ruby/test_integer_comb.rb
+++ b/test/ruby/test_integer_comb.rb
@@ -408,19 +408,32 @@ class TestIntegerComb < Test::Unit::TestCase
end
def test_remainder
+ coerce = EnvUtil.labeled_class("CoerceNum") do
+ def initialize(num)
+ @num = num
+ end
+ def coerce(other)
+ [other, @num]
+ end
+ def inspect
+ "#{self.class.name}(#@num)"
+ end
+ alias to_s inspect
+ end
+
VS.each {|a|
- VS.each {|b|
- if b == 0
+ (VS + VS.map {|b| [coerce.new(b), b]}).each {|b, i = b|
+ if i == 0
assert_raise(ZeroDivisionError) { a.divmod(b) }
else
- r = a.remainder(b)
+ r = assert_nothing_raised(ArgumentError, "#{a}.remainder(#{b})") {a.remainder(b)}
assert_kind_of(Integer, r)
if a < 0
- assert_operator(-b.abs, :<, r, "#{a}.remainder(#{b})")
+ assert_operator(-i.abs, :<, r, "#{a}.remainder(#{b})")
assert_operator(0, :>=, r, "#{a}.remainder(#{b})")
elsif 0 < a
assert_operator(0, :<=, r, "#{a}.remainder(#{b})")
- assert_operator(b.abs, :>, r, "#{a}.remainder(#{b})")
+ assert_operator(i.abs, :>, r, "#{a}.remainder(#{b})")
else
assert_equal(0, r, "#{a}.remainder(#{b})")
end
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 6a3d7594cf..476d9f882f 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -655,7 +655,7 @@ class TestIO < Test::Unit::TestCase
if have_nonblock?
def test_copy_stream_no_busy_wait
- omit "MJIT has busy wait on GC. This sometimes fails with --jit." if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ omit "RJIT has busy wait on GC. This sometimes fails with --jit." if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
omit "multiple threads already active" if Thread.list.size > 1
msg = 'r58534 [ruby-core:80969] [Backport #13533]'
@@ -900,6 +900,10 @@ class TestIO < Test::Unit::TestCase
end if defined? UNIXSocket
def test_copy_stream_socket4
+ if RUBY_PLATFORM =~ /mingw|mswin/
+ omit "pread(2) is not implemented."
+ end
+
with_bigsrc {|bigsrc, bigcontent|
File.open(bigsrc) {|f|
assert_equal(0, f.pos)
@@ -916,9 +920,13 @@ class TestIO < Test::Unit::TestCase
}
}
}
- end if defined? UNIXSocket
+ end
def test_copy_stream_socket5
+ if RUBY_PLATFORM =~ /mingw|mswin/
+ omit "pread(2) is not implemented."
+ end
+
with_bigsrc {|bigsrc, bigcontent|
File.open(bigsrc) {|f|
assert_equal(bigcontent[0,100], f.read(100))
@@ -936,9 +944,13 @@ class TestIO < Test::Unit::TestCase
}
}
}
- end if defined? UNIXSocket
+ end
def test_copy_stream_socket6
+ if RUBY_PLATFORM =~ /mingw|mswin/
+ omit "pread(2) is not implemented."
+ end
+
mkcdtmpdir {
megacontent = "abc" * 1234567
File.open("megasrc", "w") {|f| f << megacontent }
@@ -959,9 +971,13 @@ class TestIO < Test::Unit::TestCase
assert_equal(megacontent, result)
}
}
- end if defined? UNIXSocket
+ end
def test_copy_stream_socket7
+ if RUBY_PLATFORM =~ /mingw|mswin/
+ omit "pread(2) is not implemented."
+ end
+
GC.start
mkcdtmpdir {
megacontent = "abc" * 1234567
@@ -996,7 +1012,7 @@ class TestIO < Test::Unit::TestCase
end
}
}
- end if defined? UNIXSocket and IO.method_defined?("nonblock=")
+ end
def test_copy_stream_strio
src = StringIO.new("abcd")
@@ -1441,6 +1457,16 @@ class TestIO < Test::Unit::TestCase
End
end
+ def test_dup_timeout
+ with_pipe do |r, w|
+ r.timeout = 0.1
+ r2 = r.dup
+ assert_equal(0.1, r2.timeout)
+ ensure
+ r2&.close
+ end
+ end
+
def test_inspect
with_pipe do |r, w|
assert_match(/^#<IO:fd \d+>$/, r.inspect)
@@ -1597,6 +1623,28 @@ class TestIO < Test::Unit::TestCase
end
end
+ def test_read_nonblock_file
+ make_tempfile do |path|
+ File.open(path, 'r') do |file|
+ file.read_nonblock(4)
+ end
+ end
+ end
+
+ def test_write_nonblock_file
+ make_tempfile do |path|
+ File.open(path, 'w') do |file|
+ file.write_nonblock("Ruby")
+ end
+ end
+ end
+
+ def test_explicit_path
+ io = IO.for_fd(0, path: "Fake Path", autoclose: false)
+ assert_match %r"Fake Path", io.inspect
+ assert_equal "Fake Path", io.path
+ end
+
def test_write_nonblock_simple_no_exceptions
pipe(proc do |w|
w.write_nonblock('1', exception: false)
@@ -1631,7 +1679,7 @@ class TestIO < Test::Unit::TestCase
end if have_nonblock?
def test_read_nonblock_no_exceptions
- omit '[ruby-core:90895] MJIT worker may leave fd open in a forked child' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # TODO: consider acquiring GVL from MJIT worker.
+ omit '[ruby-core:90895] RJIT worker may leave fd open in a forked child' if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # TODO: consider acquiring GVL from RJIT worker.
with_pipe {|r, w|
assert_equal :wait_readable, r.read_nonblock(4096, exception: false)
w.puts "HI!"
@@ -1850,6 +1898,110 @@ class TestIO < Test::Unit::TestCase
end)
end
+ def test_readline_bad_param_raises
+ File.open(__FILE__) do |f|
+ assert_raise(TypeError) do
+ f.readline Object.new
+ end
+ end
+
+ File.open(__FILE__) do |f|
+ assert_raise(TypeError) do
+ f.readline 1, 2
+ end
+ end
+ end
+
+ def test_readline_raises
+ File.open(__FILE__) do |f|
+ assert_equal File.read(__FILE__), f.readline(nil)
+ assert_raise(EOFError) do
+ f.readline
+ end
+ end
+ end
+
+ def test_readline_separators
+ File.open(__FILE__) do |f|
+ line = f.readline("def")
+ assert_equal File.read(__FILE__)[/\A.*?def/m], line
+ end
+
+ File.open(__FILE__) do |f|
+ line = f.readline("def", chomp: true)
+ assert_equal File.read(__FILE__)[/\A.*?(?=def)/m], line
+ end
+ end
+
+ def test_readline_separators_limits
+ t = Tempfile.open("readline_limit")
+ str = "#" * 50
+ sep = "def"
+
+ t.write str
+ t.write sep
+ t.write str
+ t.flush
+
+ # over limit
+ File.open(t.path) do |f|
+ line = f.readline sep, str.bytesize
+ assert_equal(str, line)
+ end
+
+ # under limit
+ File.open(t.path) do |f|
+ line = f.readline(sep, str.bytesize + 5)
+ assert_equal(str + sep, line)
+ end
+
+ # under limit + chomp
+ File.open(t.path) do |f|
+ line = f.readline(sep, str.bytesize + 5, chomp: true)
+ assert_equal(str, line)
+ end
+ ensure
+ t&.close!
+ end
+
+ def test_readline_limit_without_separator
+ t = Tempfile.open("readline_limit")
+ str = "#" * 50
+ sep = "\n"
+
+ t.write str
+ t.write sep
+ t.write str
+ t.flush
+
+ # over limit
+ File.open(t.path) do |f|
+ line = f.readline str.bytesize
+ assert_equal(str, line)
+ end
+
+ # under limit
+ File.open(t.path) do |f|
+ line = f.readline(str.bytesize + 5)
+ assert_equal(str + sep, line)
+ end
+
+ # under limit + chomp
+ File.open(t.path) do |f|
+ line = f.readline(str.bytesize + 5, chomp: true)
+ assert_equal(str, line)
+ end
+ ensure
+ t&.close!
+ end
+
+ def test_readline_chomp_true
+ File.open(__FILE__) do |f|
+ line = f.readline(chomp: true)
+ assert_equal File.readlines(__FILE__).first.chomp, line
+ end
+ end
+
def test_set_lineno_readline
pipe(proc do |w|
w.puts "foo"
@@ -2213,6 +2365,14 @@ class TestIO < Test::Unit::TestCase
end)
end
+ def test_sysread_with_negative_length
+ make_tempfile {|t|
+ open(t.path) do |f|
+ assert_raise(ArgumentError) { f.sysread(-1) }
+ end
+ }
+ end
+
def test_flag
make_tempfile {|t|
assert_raise(ArgumentError) do
@@ -2291,9 +2451,9 @@ class TestIO < Test::Unit::TestCase
end
def test_autoclose_true_closed_by_finalizer
- # http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1465760
- # http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1469765
- omit 'this randomly fails with MJIT' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ # http://ci.rvm.jp/results/trunk-rjit@silicon-docker/1465760
+ # http://ci.rvm.jp/results/trunk-rjit@silicon-docker/1469765
+ omit 'this randomly fails with RJIT' if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
feature2250 = '[ruby-core:26222]'
pre = 'ft2250'
@@ -2356,15 +2516,19 @@ class TestIO < Test::Unit::TestCase
end
def test_open_pipe
- open("|" + EnvUtil.rubybin, "r+") do |f|
- f.puts "puts 'foo'"
- f.close_write
- assert_equal("foo\n", f.read)
+ assert_deprecated_warning(/Kernel#open with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630
+ open("|" + EnvUtil.rubybin, "r+") do |f|
+ f.puts "puts 'foo'"
+ f.close_write
+ assert_equal("foo\n", f.read)
+ end
end
end
def test_read_command
- assert_equal("foo\n", IO.read("|echo foo"))
+ assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630
+ assert_equal("foo\n", IO.read("|echo foo"))
+ end
assert_raise(Errno::ENOENT, Errno::EINVAL) do
File.read("|#{EnvUtil.rubybin} -e puts")
end
@@ -2378,7 +2542,9 @@ class TestIO < Test::Unit::TestCase
Class.new(IO).binread("|#{EnvUtil.rubybin} -e puts")
end
assert_raise(Errno::ESPIPE) do
- IO.read("|echo foo", 1, 1)
+ assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630
+ IO.read("|echo foo", 1, 1)
+ end
end
end
@@ -2563,11 +2729,16 @@ class TestIO < Test::Unit::TestCase
def test_foreach
a = []
- IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }
+
+ assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630
+ IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }
+ end
assert_equal(["foo\n", "bar\n", "baz\n"], a)
a = []
- IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :zot'", :open_args => ["r"]) {|x| a << x }
+ assert_deprecated_warning(/IO process creation with a leading '\|'/) do # https://bugs.ruby-lang.org/issues/19630
+ IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :zot'", :open_args => ["r"]) {|x| a << x }
+ end
assert_equal(["zot\n"], a)
make_tempfile {|t|
@@ -2602,6 +2773,8 @@ class TestIO < Test::Unit::TestCase
bug = '[ruby-dev:31525]'
assert_raise(ArgumentError, bug) {IO.foreach}
+ assert_raise(ArgumentError, "[Bug #18767] [ruby-core:108499]") {IO.foreach(__FILE__, 0){}}
+
a = nil
assert_nothing_raised(ArgumentError, bug) {a = IO.foreach(t.path).to_a}
assert_equal(["foo\n", "bar\n", "baz\n"], a, bug)
@@ -2808,6 +2981,9 @@ class TestIO < Test::Unit::TestCase
assert_equal("foo\nbar\nbaz\n", File.read(t.path))
assert_equal("foo\nba", File.read(t.path, 6))
assert_equal("bar\n", File.read(t.path, 4, 4))
+
+ assert_raise(ArgumentError) { File.read(t.path, -1) }
+ assert_raise(ArgumentError) { File.read(t.path, 1, -1) }
}
end
@@ -3753,7 +3929,7 @@ __END__
end
def test_race_gets_and_close
- opt = { signal: :ABRT, timeout: 200 }
+ opt = { signal: :ABRT, timeout: 10 }
assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}", **opt)
bug13076 = '[ruby-core:78845] [Bug #13076]'
begin;
@@ -3915,7 +4091,7 @@ __END__
assert_raise(EOFError) { f.pread(1, f.size) }
end
}
- end if IO.method_defined?(:pread)
+ end
def test_pwrite
make_tempfile { |t|
@@ -3924,7 +4100,7 @@ __END__
assert_equal("ooo", f.pread(3, 4))
end
}
- end if IO.method_defined?(:pread) and IO.method_defined?(:pwrite)
+ end
def test_select_exceptfds
if Etc.uname[:sysname] == 'SunOS'
@@ -3950,6 +4126,9 @@ __END__
noex = Thread.new do # everything right and never see exceptions :)
until sig_rd.wait_readable(0)
IO.pipe do |r, w|
+ assert_nil r.timeout
+ assert_nil w.timeout
+
th = Thread.new { r.read(1) }
w.write(dot)
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
index 0f8a9c5e80..7a58ec0c5a 100644
--- a/test/ruby/test_io_buffer.rb
+++ b/test/ruby/test_io_buffer.rb
@@ -80,7 +80,7 @@ class TestIOBuffer < Test::Unit::TestCase
end
def test_file_mapped_invalid
- assert_raise NoMethodError do
+ assert_raise TypeError do
IO::Buffer.map("foobar")
end
end
@@ -102,11 +102,6 @@ class TestIOBuffer < Test::Unit::TestCase
IO::Buffer.for(string) do |buffer|
refute buffer.readonly?
- # Cannot modify string as it's locked by the buffer:
- assert_raise RuntimeError do
- string[0] = "h"
- end
-
buffer.set_value(:U8, 0, "h".ord)
# Buffer releases it's ownership of the string:
@@ -116,6 +111,16 @@ class TestIOBuffer < Test::Unit::TestCase
end
end
+ def test_string_mapped_buffer_locked
+ string = "Hello World"
+ IO::Buffer.for(string) do |buffer|
+ # Cannot modify string as it's locked by the buffer:
+ assert_raise RuntimeError do
+ string[0] = "h"
+ end
+ end
+ end
+
def test_non_string
not_string = Object.new
@@ -124,6 +129,20 @@ class TestIOBuffer < Test::Unit::TestCase
end
end
+ def test_string
+ result = IO::Buffer.string(12) do |buffer|
+ buffer.set_string("Hello World!")
+ end
+
+ assert_equal "Hello World!", result
+ end
+
+ def test_string_negative
+ assert_raise ArgumentError do
+ IO::Buffer.string(-1)
+ end
+ end
+
def test_resize_mapped
buffer = IO::Buffer.new
@@ -142,6 +161,24 @@ class TestIOBuffer < Test::Unit::TestCase
assert_equal message, buffer.get_string(0, message.bytesize)
end
+ def test_resize_zero_internal
+ buffer = IO::Buffer.new(1)
+
+ buffer.resize(0)
+ assert_equal 0, buffer.size
+
+ buffer.resize(1)
+ assert_equal 1, buffer.size
+ end
+
+ def test_resize_zero_external
+ buffer = IO::Buffer.for('1')
+
+ assert_raise IO::Buffer::AccessError do
+ buffer.resize(0)
+ end
+ end
+
def test_compare_same_size
buffer1 = IO::Buffer.new(1)
assert_equal buffer1, buffer1
@@ -162,6 +199,14 @@ class TestIOBuffer < Test::Unit::TestCase
assert_positive buffer2 <=> buffer1
end
+ def test_compare_zero_length
+ buffer1 = IO::Buffer.new(0)
+ buffer2 = IO::Buffer.new(1)
+
+ assert_negative buffer1 <=> buffer2
+ assert_positive buffer2 <=> buffer1
+ end
+
def test_slice
buffer = IO::Buffer.new(128)
slice = buffer.slice(8, 32)
@@ -169,16 +214,26 @@ class TestIOBuffer < Test::Unit::TestCase
assert_equal("Hello World", buffer.get_string(8, 11))
end
- def test_slice_bounds
+ def test_slice_arguments
+ buffer = IO::Buffer.for("Hello World")
+
+ slice = buffer.slice
+ assert_equal "Hello World", slice.get_string
+
+ slice = buffer.slice(2)
+ assert_equal("llo World", slice.get_string)
+ end
+
+ def test_slice_bounds_error
buffer = IO::Buffer.new(128)
assert_raise ArgumentError do
buffer.slice(128, 10)
end
- # assert_raise RuntimeError do
- # pp buffer.slice(-10, 10)
- # end
+ assert_raise ArgumentError do
+ buffer.slice(-10, 10)
+ end
end
def test_locked
@@ -209,6 +264,26 @@ class TestIOBuffer < Test::Unit::TestCase
chunk = buffer.get_string(0, message.bytesize, Encoding::BINARY)
assert_equal Encoding::BINARY, chunk.encoding
+
+ assert_raise_with_message(ArgumentError, /bigger than the buffer size/) do
+ buffer.get_string(0, 129)
+ end
+
+ assert_raise_with_message(ArgumentError, /bigger than the buffer size/) do
+ buffer.get_string(129)
+ end
+
+ assert_raise_with_message(ArgumentError, /Offset can't be negative/) do
+ buffer.get_string(-1)
+ end
+ end
+
+ def test_zero_length_get_string
+ buffer = IO::Buffer.new.slice(0, 0)
+ assert_equal "", buffer.get_string
+
+ buffer = IO::Buffer.new(0)
+ assert_equal "", buffer.get_string
end
# We check that values are correctly round tripped.
@@ -235,17 +310,78 @@ class TestIOBuffer < Test::Unit::TestCase
:F64 => [-1.0, 0.0, 0.5, 1.0, 128.0],
}
- def test_get_set_primitives
+ def test_get_set_value
buffer = IO::Buffer.new(128)
- RANGES.each do |type, values|
+ RANGES.each do |data_type, values|
values.each do |value|
- buffer.set_value(type, 0, value)
- assert_equal value, buffer.get_value(type, 0), "Converting #{value} as #{type}."
+ buffer.set_value(data_type, 0, value)
+ assert_equal value, buffer.get_value(data_type, 0), "Converting #{value} as #{data_type}."
end
end
end
+ def test_get_set_values
+ buffer = IO::Buffer.new(128)
+
+ RANGES.each do |data_type, values|
+ format = [data_type] * values.size
+
+ buffer.set_values(format, 0, values)
+ assert_equal values, buffer.get_values(format, 0), "Converting #{values} as #{format}."
+ end
+ end
+
+ def test_zero_length_get_set_values
+ buffer = IO::Buffer.new(0)
+
+ assert_equal [], buffer.get_values([], 0)
+ assert_equal 0, buffer.set_values([], 0, [])
+ end
+
+ def test_values
+ buffer = IO::Buffer.new(128)
+
+ RANGES.each do |data_type, values|
+ format = [data_type] * values.size
+
+ buffer.set_values(format, 0, values)
+ assert_equal values, buffer.values(data_type, 0, values.size), "Reading #{values} as #{format}."
+ end
+ end
+
+ def test_each
+ buffer = IO::Buffer.new(128)
+
+ RANGES.each do |data_type, values|
+ format = [data_type] * values.size
+ data_type_size = IO::Buffer.size_of(data_type)
+ values_with_offsets = values.map.with_index{|value, index| [index * data_type_size, value]}
+
+ buffer.set_values(format, 0, values)
+ assert_equal values_with_offsets, buffer.each(data_type, 0, values.size).to_a, "Reading #{values} as #{data_type}."
+ end
+ end
+
+ def test_zero_length_each
+ buffer = IO::Buffer.new(0)
+
+ assert_equal [], buffer.each(:U8).to_a
+ end
+
+ def test_each_byte
+ string = "The quick brown fox jumped over the lazy dog."
+ buffer = IO::Buffer.for(string)
+
+ assert_equal string.bytes, buffer.each_byte.to_a
+ end
+
+ def test_zero_length_each_byte
+ buffer = IO::Buffer.new(0)
+
+ assert_equal [], buffer.each_byte.to_a
+ end
+
def test_clear
buffer = IO::Buffer.new(16)
buffer.set_string("Hello World!")
@@ -277,17 +413,38 @@ class TestIOBuffer < Test::Unit::TestCase
input.close
end
- def test_read
+ def hello_world_tempfile
io = Tempfile.new
io.write("Hello World")
io.seek(0)
- buffer = IO::Buffer.new(128)
- buffer.read(io, 5)
-
- assert_equal "Hello", buffer.get_string(0, 5)
+ yield io
ensure
- io.close!
+ io&.close!
+ end
+
+ def test_read
+ hello_world_tempfile do |io|
+ buffer = IO::Buffer.new(128)
+ buffer.read(io)
+ assert_equal "Hello", buffer.get_string(0, 5)
+ end
+ end
+
+ def test_read_with_with_length
+ hello_world_tempfile do |io|
+ buffer = IO::Buffer.new(128)
+ buffer.read(io, 5)
+ assert_equal "Hello", buffer.get_string(0, 5)
+ end
+ end
+
+ def test_read_with_with_offset
+ hello_world_tempfile do |io|
+ buffer = IO::Buffer.new(128)
+ buffer.read(io, nil, 6)
+ assert_equal "Hello", buffer.get_string(6, 5)
+ end
end
def test_write
@@ -295,7 +452,7 @@ class TestIOBuffer < Test::Unit::TestCase
buffer = IO::Buffer.new(128)
buffer.set_string("Hello")
- buffer.write(io, 5)
+ buffer.write(io)
io.seek(0)
assert_equal "Hello", io.read(5)
@@ -309,7 +466,7 @@ class TestIOBuffer < Test::Unit::TestCase
io.seek(0)
buffer = IO::Buffer.new(128)
- buffer.pread(io, 5, 6)
+ buffer.pread(io, 6, 5)
assert_equal "World", buffer.get_string(0, 5)
assert_equal 0, io.tell
@@ -317,12 +474,41 @@ class TestIOBuffer < Test::Unit::TestCase
io.close!
end
+ def test_pread_offset
+ io = Tempfile.new
+ io.write("Hello World")
+ io.seek(0)
+
+ buffer = IO::Buffer.new(128)
+ buffer.pread(io, 6, 5, 6)
+
+ assert_equal "World", buffer.get_string(6, 5)
+ assert_equal 0, io.tell
+ ensure
+ io.close!
+ end
+
def test_pwrite
io = Tempfile.new
buffer = IO::Buffer.new(128)
buffer.set_string("World")
- buffer.pwrite(io, 5, 6)
+ buffer.pwrite(io, 6, 5)
+
+ assert_equal 0, io.tell
+
+ io.seek(6)
+ assert_equal "World", io.read(5)
+ ensure
+ io.close!
+ end
+
+ def test_pwrite_offset
+ io = Tempfile.new
+
+ buffer = IO::Buffer.new(128)
+ buffer.set_string("Hello World")
+ buffer.pwrite(io, 6, 5, 6)
assert_equal 0, io.tell
@@ -351,4 +537,39 @@ class TestIOBuffer < Test::Unit::TestCase
assert_equal IO::Buffer.for("\x00\x01\x004\x00\x01\x004\x00\x01"), source.dup.xor!(mask)
assert_equal IO::Buffer.for("\xce\xcd\xcc\xcb\xce\xcd\xcc\xcb\xce\xcd"), source.dup.not!
end
+
+ def test_shared
+ message = "Hello World"
+ buffer = IO::Buffer.new(64, IO::Buffer::MAPPED | IO::Buffer::SHARED)
+
+ pid = fork do
+ buffer.set_string(message)
+ end
+
+ Process.wait(pid)
+ string = buffer.get_string(0, message.bytesize)
+ assert_equal message, string
+ rescue NotImplementedError
+ omit "Fork/shared memory is not supported."
+ end
+
+ def test_private
+ Tempfile.create(%w"buffer .txt") do |file|
+ file.write("Hello World")
+
+ buffer = IO::Buffer.map(file, nil, 0, IO::Buffer::PRIVATE)
+ begin
+ assert buffer.private?
+ refute buffer.readonly?
+
+ buffer.set_string("J")
+
+ # It was not changed because the mapping was private:
+ file.seek(0)
+ assert_equal "Hello World", file.read
+ ensure
+ buffer&.free
+ end
+ end
+ end
end
diff --git a/test/ruby/test_io_m17n.rb b/test/ruby/test_io_m17n.rb
index 9c14087eba..b01d627d92 100644
--- a/test/ruby/test_io_m17n.rb
+++ b/test/ruby/test_io_m17n.rb
@@ -1158,6 +1158,78 @@ EOT
end
end
+ def test_set_encoding_argument_parsing
+ File.open(File::NULL) do |f|
+ f.set_encoding('binary')
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding(Encoding.find('binary'))
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding('binary:utf-8')
+ assert_equal(nil, f.internal_encoding)
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding('binary', 'utf-8')
+ assert_equal(nil, f.internal_encoding)
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding(Encoding.find('binary'), Encoding.find('utf-8'))
+ assert_equal(nil, f.internal_encoding)
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding('binary', Encoding.find('utf-8'))
+ assert_equal(nil, f.internal_encoding)
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding(Encoding.find('binary'), 'utf-8')
+ assert_equal(nil, f.internal_encoding)
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding('iso-8859-1:utf-8')
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ assert_equal(Encoding::ISO_8859_1, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding('iso-8859-1', 'utf-8')
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ assert_equal(Encoding::ISO_8859_1, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding(Encoding.find('iso-8859-1'), Encoding.find('utf-8'))
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ assert_equal(Encoding::ISO_8859_1, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding('iso-8859-1', Encoding.find('utf-8'))
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ assert_equal(Encoding::ISO_8859_1, f.external_encoding)
+ end
+
+ File.open(File::NULL) do |f|
+ f.set_encoding(Encoding.find('iso-8859-1'), 'utf-8')
+ assert_equal(Encoding::UTF_8, f.internal_encoding)
+ assert_equal(Encoding::ISO_8859_1, f.external_encoding)
+ end
+ end
+
def test_textmode_twice
assert_raise(ArgumentError) {
open(__FILE__, "rt", textmode: true) {|f|
@@ -1324,23 +1396,27 @@ EOT
end
def test_open_pipe_r_enc
- open("|#{EnvUtil.rubybin} -e 'putc 255'", "r:ascii-8bit") {|f|
- assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
- assert_equal(nil, f.internal_encoding)
- s = f.read
- assert_equal(Encoding::ASCII_8BIT, s.encoding)
- assert_equal("\xff".force_encoding("ascii-8bit"), s)
- }
+ EnvUtil.suppress_warning do # https://bugs.ruby-lang.org/issues/19630
+ open("|#{EnvUtil.rubybin} -e 'putc 255'", "r:ascii-8bit") {|f|
+ assert_equal(Encoding::ASCII_8BIT, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::ASCII_8BIT, s.encoding)
+ assert_equal("\xff".force_encoding("ascii-8bit"), s)
+ }
+ end
end
def test_open_pipe_r_enc2
- open("|#{EnvUtil.rubybin} -e 'putc \"\\u3042\"'", "r:UTF-8") {|f|
- assert_equal(Encoding::UTF_8, f.external_encoding)
- assert_equal(nil, f.internal_encoding)
- s = f.read
- assert_equal(Encoding::UTF_8, s.encoding)
- assert_equal("\u3042", s)
- }
+ EnvUtil.suppress_warning do # https://bugs.ruby-lang.org/issues/19630
+ open("|#{EnvUtil.rubybin} -e 'putc \"\\u3042\"'", "r:UTF-8") {|f|
+ assert_equal(Encoding::UTF_8, f.external_encoding)
+ assert_equal(nil, f.internal_encoding)
+ s = f.read
+ assert_equal(Encoding::UTF_8, s.encoding)
+ assert_equal("\u3042", s)
+ }
+ end
end
def test_s_foreach_enc
diff --git a/test/ruby/test_io_timeout.rb b/test/ruby/test_io_timeout.rb
new file mode 100644
index 0000000000..e017395980
--- /dev/null
+++ b/test/ruby/test_io_timeout.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: false
+
+require 'io/nonblock'
+
+class TestIOTimeout < Test::Unit::TestCase
+ def with_pipe
+ omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
+
+ begin
+ i, o = UNIXSocket.pair
+
+ yield i, o
+ ensure
+ i.close
+ o.close
+ end
+ end
+
+ def test_timeout_attribute
+ with_pipe do |i, o|
+ assert_nil i.timeout
+
+ i.timeout = 10
+ assert_equal 10, i.timeout
+ assert_nil o.timeout
+
+ o.timeout = 20
+ assert_equal 20, o.timeout
+ assert_equal 10, i.timeout
+ end
+ end
+
+ def test_timeout_read_exception
+ with_pipe do |i, o|
+ i.timeout = 0.0001
+
+ assert_raise(IO::TimeoutError) {i.read}
+ end
+ end
+
+ def test_timeout_gets_exception
+ with_pipe do |i, o|
+ i.timeout = 0.0001
+
+ assert_raise(IO::TimeoutError) {i.gets}
+ end
+ end
+
+ def test_timeout_puts
+ with_pipe do |i, o|
+ i.timeout = 0.0001
+ o.puts("Hello World")
+ o.close
+
+ assert_equal "Hello World", i.gets.chomp
+ end
+ end
+end
diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb
index 2a18ff02e1..dc84d8bd7c 100644
--- a/test/ruby/test_iseq.rb
+++ b/test/ruby/test_iseq.rb
@@ -157,18 +157,18 @@ class TestISeq < Test::Unit::TestCase
y = nil.instance_eval do
eval("proc {#{name} = []; proc {|x| #{name}}}").call
end
- assert_raise_with_message(Ractor::IsolationError, /`#{name}'/) do
+ assert_raise_with_message(Ractor::IsolationError, /'#{name}'/) do
Ractor.make_shareable(y)
end
obj = Object.new
def obj.foo(*) nil.instance_eval{ ->{super} } end
- assert_raise_with_message(Ractor::IsolationError, /refer unshareable object \[\] from variable `\*'/) do
+ assert_raise_with_message(Ractor::IsolationError, /refer unshareable object \[\] from variable '\*'/) do
Ractor.make_shareable(obj.foo)
end
end
def test_disasm_encoding
- src = "\u{3042} = 1; \u{3042}; \u{3043}"
+ src = +"\u{3042} = 1; \u{3042}; \u{3043}"
asm = compile(src).disasm
assert_equal(src.encoding, asm.encoding)
assert_predicate(asm, :valid_encoding?)
@@ -355,12 +355,19 @@ class TestISeq < Test::Unit::TestCase
end
end
+ # [Bug #19173]
+ def test_compile_error
+ assert_raise SyntaxError do
+ RubyVM::InstructionSequence.compile 'using Module.new; yield'
+ end
+ end
+
def test_compile_file_error
Tempfile.create(%w"test_iseq .rb") do |f|
f.puts "end"
f.close
path = f.path
- assert_in_out_err(%W[- #{path}], "#{<<-"begin;"}\n#{<<-"end;"}", /unexpected `end'/, [], success: true)
+ assert_in_out_err(%W[- #{path}], "#{<<-"begin;"}\n#{<<-"end;"}", /unexpected 'end'/, [], success: true)
begin;
path = ARGV[0]
begin
@@ -490,7 +497,8 @@ class TestISeq < Test::Unit::TestCase
[7, :line],
[9, :return]]],
[["ensure in foo@2", [[7, :line]]]],
- [["rescue in foo@4", [[5, :line]]]]]],
+ [["rescue in foo@4", [[5, :line],
+ [5, :rescue]]]]]],
[["<class:D>@17", [[17, :class],
[18, :end]]]]], collect_iseq.call(sample_iseq)
end
@@ -558,6 +566,23 @@ class TestISeq < Test::Unit::TestCase
iseq2
end
+ def test_to_binary_with_hidden_local_variables
+ assert_iseq_to_binary("for foo in bar; end")
+
+ bin = RubyVM::InstructionSequence.compile(<<-RUBY).to_binary
+ Object.new.instance_eval do
+ a = []
+ def self.bar; [1] end
+ for foo in bar
+ a << (foo * 2)
+ end
+ a
+ end
+ RUBY
+ v = RubyVM::InstructionSequence.load_from_binary(bin).eval
+ assert_equal([2], v)
+ end
+
def test_to_binary_with_objects
assert_iseq_to_binary("[]"+100.times.map{|i|"<</#{i}/"}.join)
assert_iseq_to_binary("@x ||= (1..2)")
@@ -630,6 +655,8 @@ class TestISeq < Test::Unit::TestCase
}
lines
+ ensure
+ Object.send(:remove_const, :A) rescue nil
end
def test_to_binary_line_tracepoint
@@ -750,4 +777,59 @@ class TestISeq < Test::Unit::TestCase
assert_equal :new, r.take
RUBY
end
+
+ def test_ever_condition_loop
+ assert_ruby_status([], "BEGIN {exit}; while true && true; end")
+ end
+
+ def test_unreachable_syntax_error
+ mesg = /Invalid break/
+ assert_syntax_error("false and break", mesg)
+ assert_syntax_error("if false and break; end", mesg)
+ end
+
+ def test_unreachable_pattern_matching
+ assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", %w[1])
+ begin;
+ if true or {a: 0} in {a:}
+ p 1
+ else
+ p a
+ end
+ end;
+ end
+
+ def test_loading_kwargs_memory_leak
+ assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", rss: true)
+ a = RubyVM::InstructionSequence.compile("foo(bar: :baz)").to_binary
+ begin;
+ 1_000_000.times do
+ RubyVM::InstructionSequence.load_from_binary(a)
+ end
+ end;
+ end
+
+ def test_ibf_bignum
+ iseq = RubyVM::InstructionSequence.compile("0x0"+"_0123_4567_89ab_cdef"*5)
+ expected = iseq.eval
+ result = RubyVM::InstructionSequence.load_from_binary(iseq.to_binary).eval
+ assert_equal expected, result, proc {sprintf("expected: %x, result: %x", expected, result)}
+ end
+
+ def test_compile_prism_with_file
+ Tempfile.create(%w"test_iseq .rb") do |f|
+ f.puts "name = 'Prism'; puts 'hello'"
+ f.close
+
+ assert_nothing_raised(TypeError) do
+ RubyVM::InstructionSequence.compile_prism(f)
+ end
+ end
+ end
+
+ def test_compile_prism_with_invalid_object_type
+ assert_raise(TypeError) do
+ RubyVM::InstructionSequence.compile_prism(Object.new)
+ end
+ end
end
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 9978072744..34a80c3729 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -182,6 +182,52 @@ class TestKeywordArguments < Test::Unit::TestCase
[:keyrest, :kw], [:block, :b]], method(:f9).parameters)
end
+ def test_keyword_with_anonymous_keyword_splat
+ def self.a(b: 1, **) [b, **] end
+ kw = {b: 2, c: 3}
+ assert_equal([2, {c: 3}], a(**kw))
+ assert_equal({b: 2, c: 3}, kw)
+ end
+
+ def test_keyword_splat_nil
+ # cfunc call
+ assert_equal(nil, p(**nil))
+
+ def self.a0; end
+ assert_equal(nil, a0(**nil))
+ assert_equal(nil, :a0.to_proc.call(self, **nil))
+ assert_equal(nil, a0(**nil, &:block))
+
+ def self.o(x=1); x end
+ assert_equal(1, o(**nil))
+ assert_equal(2, o(2, **nil))
+ assert_equal(1, o(*nil, **nil))
+ assert_equal(1, o(**nil, **nil))
+ assert_equal({a: 1}, o(a: 1, **nil))
+ assert_equal({a: 1}, o(**nil, a: 1))
+
+ # symproc call
+ assert_equal(1, :o.to_proc.call(self, **nil))
+
+ def self.s(*a); a end
+ assert_equal([], s(**nil))
+ assert_equal([1], s(1, **nil))
+ assert_equal([], s(*nil, **nil))
+
+ def self.kws(**a); a end
+ assert_equal({}, kws(**nil))
+ assert_equal({}, kws(*nil, **nil))
+
+ def self.skws(*a, **kw); [a, kw] end
+ assert_equal([[], {}], skws(**nil))
+ assert_equal([[1], {}], skws(1, **nil))
+ assert_equal([[], {}], skws(*nil, **nil))
+
+ assert_equal({}, {**nil})
+ assert_equal({a: 1}, {a: 1, **nil})
+ assert_equal({a: 1}, {**nil, a: 1})
+ end
+
def test_lambda
f = ->(str: "foo", num: 424242) { [str, num] }
assert_equal(["foo", 424242], f[])
@@ -237,27 +283,27 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal(true, Hash.ruby2_keywords_hash?(marked))
end
+ def assert_equal_not_same(kw, res)
+ assert_instance_of(Hash, res)
+ assert_equal(kw, res)
+ assert_not_same(kw, res)
+ end
+
def test_keyword_splat_new
kw = {}
h = {a: 1}
- def self.assert_equal_not_same(kw, res)
- assert_instance_of(Hash, res)
- assert_equal(kw, res)
- assert_not_same(kw, res)
- end
-
- def self.y(**kw) kw end
- m = method(:y)
- assert_equal(false, y(**{}).frozen?)
- assert_equal_not_same(kw, y(**kw))
- assert_equal_not_same(h, y(**h))
- assert_equal(false, send(:y, **{}).frozen?)
- assert_equal_not_same(kw, send(:y, **kw))
- assert_equal_not_same(h, send(:y, **h))
- assert_equal(false, public_send(:y, **{}).frozen?)
- assert_equal_not_same(kw, public_send(:y, **kw))
- assert_equal_not_same(h, public_send(:y, **h))
+ def self.yo(**kw) kw end
+ m = method(:yo)
+ assert_equal(false, yo(**{}).frozen?)
+ assert_equal_not_same(kw, yo(**kw))
+ assert_equal_not_same(h, yo(**h))
+ assert_equal(false, send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, send(:yo, **kw))
+ assert_equal_not_same(h, send(:yo, **h))
+ assert_equal(false, public_send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, public_send(:yo, **kw))
+ assert_equal_not_same(h, public_send(:yo, **h))
assert_equal(false, m.(**{}).frozen?)
assert_equal_not_same(kw, m.(**kw))
assert_equal_not_same(h, m.(**h))
@@ -266,25 +312,25 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal_not_same(h, m.send(:call, **h))
m = method(:send)
- assert_equal(false, m.(:y, **{}).frozen?)
- assert_equal_not_same(kw, m.(:y, **kw))
- assert_equal_not_same(h, m.(:y, **h))
- assert_equal(false, m.send(:call, :y, **{}).frozen?)
- assert_equal_not_same(kw, m.send(:call, :y, **kw))
- assert_equal_not_same(h, m.send(:call, :y, **h))
-
- singleton_class.send(:remove_method, :y)
- define_singleton_method(:y) { |**kw| kw }
- m = method(:y)
- assert_equal(false, y(**{}).frozen?)
- assert_equal_not_same(kw, y(**kw))
- assert_equal_not_same(h, y(**h))
- assert_equal(false, send(:y, **{}).frozen?)
- assert_equal_not_same(kw, send(:y, **kw))
- assert_equal_not_same(h, send(:y, **h))
- assert_equal(false, public_send(:y, **{}).frozen?)
- assert_equal_not_same(kw, public_send(:y, **kw))
- assert_equal_not_same(h, public_send(:y, **h))
+ assert_equal(false, m.(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, m.(:yo, **kw))
+ assert_equal_not_same(h, m.(:yo, **h))
+ assert_equal(false, m.send(:call, :yo, **{}).frozen?)
+ assert_equal_not_same(kw, m.send(:call, :yo, **kw))
+ assert_equal_not_same(h, m.send(:call, :yo, **h))
+
+ singleton_class.send(:remove_method, :yo)
+ define_singleton_method(:yo) { |**kw| kw }
+ m = method(:yo)
+ assert_equal(false, yo(**{}).frozen?)
+ assert_equal_not_same(kw, yo(**kw))
+ assert_equal_not_same(h, yo(**h))
+ assert_equal(false, send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, send(:yo, **kw))
+ assert_equal_not_same(h, send(:yo, **h))
+ assert_equal(false, public_send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, public_send(:yo, **kw))
+ assert_equal_not_same(h, public_send(:yo, **h))
assert_equal(false, m.(**{}).frozen?)
assert_equal_not_same(kw, m.(**kw))
assert_equal_not_same(h, m.(**h))
@@ -292,17 +338,17 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal_not_same(kw, m.send(:call, **kw))
assert_equal_not_same(h, m.send(:call, **h))
- y = lambda { |**kw| kw }
- m = y.method(:call)
- assert_equal(false, y.(**{}).frozen?)
- assert_equal_not_same(kw, y.(**kw))
- assert_equal_not_same(h, y.(**h))
- assert_equal(false, y.send(:call, **{}).frozen?)
- assert_equal_not_same(kw, y.send(:call, **kw))
- assert_equal_not_same(h, y.send(:call, **h))
- assert_equal(false, y.public_send(:call, **{}).frozen?)
- assert_equal_not_same(kw, y.public_send(:call, **kw))
- assert_equal_not_same(h, y.public_send(:call, **h))
+ yo = lambda { |**kw| kw }
+ m = yo.method(:call)
+ assert_equal(false, yo.(**{}).frozen?)
+ assert_equal_not_same(kw, yo.(**kw))
+ assert_equal_not_same(h, yo.(**h))
+ assert_equal(false, yo.send(:call, **{}).frozen?)
+ assert_equal_not_same(kw, yo.send(:call, **kw))
+ assert_equal_not_same(h, yo.send(:call, **h))
+ assert_equal(false, yo.public_send(:call, **{}).frozen?)
+ assert_equal_not_same(kw, yo.public_send(:call, **kw))
+ assert_equal_not_same(h, yo.public_send(:call, **h))
assert_equal(false, m.(**{}).frozen?)
assert_equal_not_same(kw, m.(**kw))
assert_equal_not_same(h, m.(**h))
@@ -310,17 +356,17 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal_not_same(kw, m.send(:call, **kw))
assert_equal_not_same(h, m.send(:call, **h))
- y = :y.to_proc
- m = y.method(:call)
- assert_equal(false, y.(self, **{}).frozen?)
- assert_equal_not_same(kw, y.(self, **kw))
- assert_equal_not_same(h, y.(self, **h))
- assert_equal(false, y.send(:call, self, **{}).frozen?)
- assert_equal_not_same(kw, y.send(:call, self, **kw))
- assert_equal_not_same(h, y.send(:call, self, **h))
- assert_equal(false, y.public_send(:call, self, **{}).frozen?)
- assert_equal_not_same(kw, y.public_send(:call, self, **kw))
- assert_equal_not_same(h, y.public_send(:call, self, **h))
+ yo = :yo.to_proc
+ m = yo.method(:call)
+ assert_equal(false, yo.(self, **{}).frozen?)
+ assert_equal_not_same(kw, yo.(self, **kw))
+ assert_equal_not_same(h, yo.(self, **h))
+ assert_equal(false, yo.send(:call, self, **{}).frozen?)
+ assert_equal_not_same(kw, yo.send(:call, self, **kw))
+ assert_equal_not_same(h, yo.send(:call, self, **h))
+ assert_equal(false, yo.public_send(:call, self, **{}).frozen?)
+ assert_equal_not_same(kw, yo.public_send(:call, self, **kw))
+ assert_equal_not_same(h, yo.public_send(:call, self, **h))
assert_equal(false, m.(self, **{}).frozen?)
assert_equal_not_same(kw, m.(self, **kw))
assert_equal_not_same(h, m.(self, **h))
@@ -329,20 +375,20 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal_not_same(h, m.send(:call, self, **h))
c = Class.new do
- def y(**kw) kw end
+ def yo(**kw) kw end
end
o = c.new
- def o.y(**kw) super end
- m = o.method(:y)
- assert_equal(false, o.y(**{}).frozen?)
- assert_equal_not_same(kw, o.y(**kw))
- assert_equal_not_same(h, o.y(**h))
- assert_equal(false, o.send(:y, **{}).frozen?)
- assert_equal_not_same(kw, o.send(:y, **kw))
- assert_equal_not_same(h, o.send(:y, **h))
- assert_equal(false, o.public_send(:y, **{}).frozen?)
- assert_equal_not_same(kw, o.public_send(:y, **kw))
- assert_equal_not_same(h, o.public_send(:y, **h))
+ def o.yo(**kw) super end
+ m = o.method(:yo)
+ assert_equal(false, o.yo(**{}).frozen?)
+ assert_equal_not_same(kw, o.yo(**kw))
+ assert_equal_not_same(h, o.yo(**h))
+ assert_equal(false, o.send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, o.send(:yo, **kw))
+ assert_equal_not_same(h, o.send(:yo, **h))
+ assert_equal(false, o.public_send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, o.public_send(:yo, **kw))
+ assert_equal_not_same(h, o.public_send(:yo, **h))
assert_equal(false, m.(**{}).frozen?)
assert_equal_not_same(kw, m.(**kw))
assert_equal_not_same(h, m.(**h))
@@ -350,17 +396,17 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal_not_same(kw, m.send(:call, **kw))
assert_equal_not_same(h, m.send(:call, **h))
- o.singleton_class.send(:remove_method, :y)
- def o.y(**kw) super(**kw) end
- assert_equal(false, o.y(**{}).frozen?)
- assert_equal_not_same(kw, o.y(**kw))
- assert_equal_not_same(h, o.y(**h))
- assert_equal(false, o.send(:y, **{}).frozen?)
- assert_equal_not_same(kw, o.send(:y, **kw))
- assert_equal_not_same(h, o.send(:y, **h))
- assert_equal(false, o.public_send(:y, **{}).frozen?)
- assert_equal_not_same(kw, o.public_send(:y, **kw))
- assert_equal_not_same(h, o.public_send(:y, **h))
+ o.singleton_class.send(:remove_method, :yo)
+ def o.yo(**kw) super(**kw) end
+ assert_equal(false, o.yo(**{}).frozen?)
+ assert_equal_not_same(kw, o.yo(**kw))
+ assert_equal_not_same(h, o.yo(**h))
+ assert_equal(false, o.send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, o.send(:yo, **kw))
+ assert_equal_not_same(h, o.send(:yo, **h))
+ assert_equal(false, o.public_send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, o.public_send(:yo, **kw))
+ assert_equal_not_same(h, o.public_send(:yo, **h))
assert_equal(false, m.(**{}).frozen?)
assert_equal_not_same(kw, m.(**kw))
assert_equal_not_same(h, m.(**h))
@@ -372,17 +418,17 @@ class TestKeywordArguments < Test::Unit::TestCase
def method_missing(_, **kw) kw end
end
o = c.new
- def o.y(**kw) super end
- m = o.method(:y)
- assert_equal(false, o.y(**{}).frozen?)
- assert_equal_not_same(kw, o.y(**kw))
- assert_equal_not_same(h, o.y(**h))
- assert_equal(false, o.send(:y, **{}).frozen?)
- assert_equal_not_same(kw, o.send(:y, **kw))
- assert_equal_not_same(h, o.send(:y, **h))
- assert_equal(false, o.public_send(:y, **{}).frozen?)
- assert_equal_not_same(kw, o.public_send(:y, **kw))
- assert_equal_not_same(h, o.public_send(:y, **h))
+ def o.yo(**kw) super end
+ m = o.method(:yo)
+ assert_equal(false, o.yo(**{}).frozen?)
+ assert_equal_not_same(kw, o.yo(**kw))
+ assert_equal_not_same(h, o.yo(**h))
+ assert_equal(false, o.send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, o.send(:yo, **kw))
+ assert_equal_not_same(h, o.send(:yo, **h))
+ assert_equal(false, o.public_send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, o.public_send(:yo, **kw))
+ assert_equal_not_same(h, o.public_send(:yo, **h))
assert_equal(false, m.(**{}).frozen?)
assert_equal_not_same(kw, m.(**kw))
assert_equal_not_same(h, m.(**h))
@@ -390,17 +436,17 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal_not_same(kw, m.send(:call, **kw))
assert_equal_not_same(h, m.send(:call, **h))
- o.singleton_class.send(:remove_method, :y)
- def o.y(**kw) super(**kw) end
- assert_equal(false, o.y(**{}).frozen?)
- assert_equal_not_same(kw, o.y(**kw))
- assert_equal_not_same(h, o.y(**h))
- assert_equal(false, o.send(:y, **{}).frozen?)
- assert_equal_not_same(kw, o.send(:y, **kw))
- assert_equal_not_same(h, o.send(:y, **h))
- assert_equal(false, o.public_send(:y, **{}).frozen?)
- assert_equal_not_same(kw, o.public_send(:y, **kw))
- assert_equal_not_same(h, o.public_send(:y, **h))
+ o.singleton_class.send(:remove_method, :yo)
+ def o.yo(**kw) super(**kw) end
+ assert_equal(false, o.yo(**{}).frozen?)
+ assert_equal_not_same(kw, o.yo(**kw))
+ assert_equal_not_same(h, o.yo(**h))
+ assert_equal(false, o.send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, o.send(:yo, **kw))
+ assert_equal_not_same(h, o.send(:yo, **h))
+ assert_equal(false, o.public_send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, o.public_send(:yo, **kw))
+ assert_equal_not_same(h, o.public_send(:yo, **h))
assert_equal(false, m.(**{}).frozen?)
assert_equal_not_same(kw, m.(**kw))
assert_equal_not_same(h, m.(**h))
@@ -436,17 +482,41 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal_not_same(h, m.(**h))
assert_equal_not_same(h, m.send(:call, **h))
- singleton_class.send(:remove_method, :y)
+ singleton_class.send(:remove_method, :yo)
def self.method_missing(_, **kw) kw end
- assert_equal(false, y(**{}).frozen?)
- assert_equal_not_same(kw, y(**kw))
- assert_equal_not_same(h, y(**h))
- assert_equal(false, send(:y, **{}).frozen?)
- assert_equal_not_same(kw, send(:y, **kw))
- assert_equal_not_same(h, send(:y, **h))
- assert_equal(false, public_send(:y, **{}).frozen?)
- assert_equal_not_same(kw, public_send(:y, **kw))
- assert_equal_not_same(h, public_send(:y, **h))
+ assert_equal(false, yo(**{}).frozen?)
+ assert_equal_not_same(kw, yo(**kw))
+ assert_equal_not_same(h, yo(**h))
+ assert_equal(false, send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, send(:yo, **kw))
+ assert_equal_not_same(h, send(:yo, **h))
+ assert_equal(false, public_send(:yo, **{}).frozen?)
+ assert_equal_not_same(kw, public_send(:yo, **kw))
+ assert_equal_not_same(h, public_send(:yo, **h))
+
+ def self.yo(*a, **kw) = kw
+ assert_equal_not_same kw, yo(**kw)
+ assert_equal_not_same kw, yo(**kw, **kw)
+
+ singleton_class.send(:remove_method, :yo)
+ def self.yo(opts) = opts
+ assert_equal_not_same h, yo(*[], **h)
+ a = []
+ assert_equal_not_same h, yo(*a, **h)
+ end
+
+ def test_keyword_splat_to_non_keyword_method
+ h = {a: 1}.freeze
+
+ def self.yo(kw) kw end
+ assert_equal_not_same(h, yo(**h))
+ assert_equal_not_same(h, method(:yo).(**h))
+ assert_equal_not_same(h, :yo.to_proc.(self, **h))
+
+ def self.yoa(*kw) kw[0] end
+ assert_equal_not_same(h, yoa(**h))
+ assert_equal_not_same(h, method(:yoa).(**h))
+ assert_equal_not_same(h, :yoa.to_proc.(self, **h))
end
def test_regular_kwsplat
@@ -2747,6 +2817,37 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_raise(FrozenError) { c.send(:ruby2_keywords, :baz) }
end
+ def test_anon_splat_ruby2_keywords
+ singleton_class.class_exec do
+ def bar(*a, **kw)
+ [a, kw]
+ end
+
+ ruby2_keywords def bar_anon(*)
+ bar(*)
+ end
+ end
+
+ a = [1, 2]
+ kw = {a: 1}
+ assert_equal([[1, 2], {a: 1}], bar_anon(*a, **kw))
+ assert_equal([1, 2], a)
+ assert_equal({a: 1}, kw)
+ end
+
+ def test_anon_splat_ruby2_keywords_bug_20388
+ extend(Module.new{def process(action, ...) 1 end})
+ extend(Module.new do
+ def process(action, *args)
+ args.freeze
+ super
+ end
+ ruby2_keywords :process
+ end)
+
+ assert_equal(1, process(:foo, bar: :baz))
+ end
+
def test_top_ruby2_keywords
assert_in_out_err([], <<-INPUT, ["[1, 2, 3]", "{:k=>1}"], [])
def bar(*a, **kw)
@@ -3922,6 +4023,20 @@ class TestKeywordArguments < Test::Unit::TestCase
}, bug8964
end
+ def test_large_kwsplat_to_method_taking_kw_and_kwsplat
+ assert_separately(['-'], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ n = 100000
+ x = Fiber.new do
+ h = {kw: 2}
+ n.times{|i| h[i.to_s.to_sym] = i}
+ def self.f(kw: 1, **kws) kws.size end
+ f(**h)
+ end.resume
+ assert_equal(n, x)
+ end;
+ end
+
def test_dynamic_symbol_keyword
bug10266 = '[ruby-dev:48564] [Bug #10266]'
assert_separately(['-', bug10266], "#{<<~"begin;"}\n#{<<~'end;'}")
diff --git a/test/ruby/test_lambda.rb b/test/ruby/test_lambda.rb
index 9949fab8c7..7738034240 100644
--- a/test/ruby/test_lambda.rb
+++ b/test/ruby/test_lambda.rb
@@ -177,32 +177,6 @@ class TestLambdaParameters < Test::Unit::TestCase
RUBY
end
- def pass_along(&block)
- lambda(&block)
- end
-
- def pass_along2(&block)
- pass_along(&block)
- end
-
- def test_create_non_lambda_for_proc_one_level
- prev_warning, Warning[:deprecated] = Warning[:deprecated], false
- f = pass_along {}
- refute_predicate(f, :lambda?, '[Bug #15620]')
- assert_nothing_raised(ArgumentError) { f.call(:extra_arg) }
- ensure
- Warning[:deprecated] = prev_warning
- end
-
- def test_create_non_lambda_for_proc_two_levels
- prev_warning, Warning[:deprecated] = Warning[:deprecated], false
- f = pass_along2 {}
- refute_predicate(f, :lambda?, '[Bug #15620]')
- assert_nothing_raised(ArgumentError) { f.call(:extra_arg) }
- ensure
- Warning[:deprecated] = prev_warning
- end
-
def test_instance_exec
bug12568 = '[ruby-core:76300] [Bug #12568]'
assert_nothing_raised(ArgumentError, bug12568) do
diff --git a/test/ruby/test_lazy_enumerator.rb b/test/ruby/test_lazy_enumerator.rb
index 2116d0ee31..22127e903a 100644
--- a/test/ruby/test_lazy_enumerator.rb
+++ b/test/ruby/test_lazy_enumerator.rb
@@ -282,6 +282,11 @@ class TestLazyEnumerator < Test::Unit::TestCase
assert_equal(3, a.current)
end
+ def test_zip_map_lambda_bug_19569
+ ary = [1, 2, 3].to_enum.lazy.zip([:a, :b, :c]).map(&:last).to_a
+ assert_equal([:a, :b, :c], ary)
+ end
+
def test_take
a = Step.new(1..10)
assert_equal(1, a.take(5).first)
@@ -295,6 +300,26 @@ class TestLazyEnumerator < Test::Unit::TestCase
assert_equal(nil, a.current)
end
+ def test_take_0_bug_18971
+ def (bomb = Object.new.extend(Enumerable)).each
+ raise
+ end
+ [2..10, bomb].each do |e|
+ assert_equal([], e.lazy.take(0).map(&:itself).to_a)
+ assert_equal([], e.lazy.take(0).select(&:even?).to_a)
+ assert_equal([], e.lazy.take(0).select(&:odd?).to_a)
+ assert_equal([], e.lazy.take(0).reject(&:even?).to_a)
+ assert_equal([], e.lazy.take(0).reject(&:odd?).to_a)
+ assert_equal([], e.lazy.take(0).take(1).to_a)
+ assert_equal([], e.lazy.take(0).take(0).take(1).to_a)
+ assert_equal([], e.lazy.take(0).drop(0).to_a)
+ assert_equal([], e.lazy.take(0).find_all {|_| true}.to_a)
+ assert_equal([], e.lazy.take(0).zip((12..20)).to_a)
+ assert_equal([], e.lazy.take(0).uniq.to_a)
+ assert_equal([], e.lazy.take(0).sort.to_a)
+ end
+ end
+
def test_take_bad_arg
a = Step.new(1..10)
assert_raise(ArgumentError) { a.lazy.take(-1) }
diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb
index 99dd3a0c56..c6154af1f6 100644
--- a/test/ruby/test_literal.rb
+++ b/test/ruby/test_literal.rb
@@ -142,6 +142,8 @@ class TestRubyLiteral < Test::Unit::TestCase
end
def test_frozen_string
+ default = eval("'test'").frozen?
+
all_assertions do |a|
a.for("false with indicator") do
str = eval("# -*- frozen-string-literal: false -*-\n""'foo'")
@@ -161,19 +163,19 @@ class TestRubyLiteral < Test::Unit::TestCase
end
a.for("false with preceding garbage") do
str = eval("# x frozen-string-literal: false\n""'foo'")
- assert_not_predicate(str, :frozen?)
+ assert_equal(default, str.frozen?)
end
a.for("true with preceding garbage") do
str = eval("# x frozen-string-literal: true\n""'foo'")
- assert_not_predicate(str, :frozen?)
+ assert_equal(default, str.frozen?)
end
a.for("false with succeeding garbage") do
str = eval("# frozen-string-literal: false x\n""'foo'")
- assert_not_predicate(str, :frozen?)
+ assert_equal(default, str.frozen?)
end
a.for("true with succeeding garbage") do
str = eval("# frozen-string-literal: true x\n""'foo'")
- assert_not_predicate(str, :frozen?)
+ assert_equal(default, str.frozen?)
end
end
end
@@ -184,6 +186,11 @@ class TestRubyLiteral < Test::Unit::TestCase
list.each { |str| assert_predicate str, :frozen? }
end
+ def test_string_in_hash_literal
+ hash = eval("# frozen-string-literal: false\n""{foo: 'foo'}")
+ assert_not_predicate(hash[:foo], :frozen?)
+ end
+
if defined?(RubyVM::InstructionSequence.compile_option) and
RubyVM::InstructionSequence.compile_option.key?(:debug_frozen_string_literal)
def test_debug_frozen_string
@@ -496,10 +503,11 @@ class TestRubyLiteral < Test::Unit::TestCase
'1.0i',
'1.72723e-77',
'//',
+ '__LINE__',
+ '__FILE__',
+ '__ENCODING__',
) do |key|
- assert_warning(/key #{Regexp.quote(eval(key).inspect)} is duplicated/) do
- eval("{#{key} => :bar, #{key} => :foo}")
- end
+ assert_warning(/key #{Regexp.quote(eval(key).inspect)} is duplicated/) { eval("{#{key} => :bar, #{key} => :foo}") }
end
end
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb
index c00bf59e18..907360b3a6 100644
--- a/test/ruby/test_m17n.rb
+++ b/test/ruby/test_m17n.rb
@@ -226,38 +226,16 @@ class TestM17N < Test::Unit::TestCase
end
end
- STR_WITHOUT_BOM = "\u3042".freeze
- STR_WITH_BOM = "\uFEFF\u3042".freeze
- bug8940 = '[ruby-core:59757] [Bug #8940]'
- bug9415 = '[ruby-dev:47895] [Bug #9415]'
- %w/UTF-16 UTF-32/.each do |enc|
- %w/BE LE/.each do |endian|
- bom = "\uFEFF".encode("#{enc}#{endian}").force_encoding(enc)
-
- define_method("test_utf_16_32_inspect(#{enc}#{endian})") do
- s = STR_WITHOUT_BOM.encode(enc + endian)
- # When a UTF-16/32 string doesn't have a BOM,
- # inspect as a dummy encoding string.
- assert_equal(s.dup.force_encoding("ISO-2022-JP").inspect,
- s.dup.force_encoding(enc).inspect)
- assert_normal_exit("#{bom.b.dump}.force_encoding('#{enc}').inspect", bug8940)
- end
-
- define_method("test_utf_16_32_codepoints(#{enc}#{endian})") do
- assert_equal([0xFEFF], bom.codepoints, bug9415)
- end
-
- define_method("test_utf_16_32_ord(#{enc}#{endian})") do
- assert_equal(0xFEFF, bom.ord, bug9415)
- end
-
- define_method("test_utf_16_32_inspect(#{enc}#{endian}-BOM)") do
- s = STR_WITH_BOM.encode(enc + endian)
- # When a UTF-16/32 string has a BOM,
- # inspect as a particular encoding string.
- assert_equal(s.inspect,
- s.dup.force_encoding(enc).inspect)
- end
+ def test_utf_dummy_are_like_regular_dummy_encodings
+ [Encoding::UTF_16, Encoding::UTF_32].each do |enc|
+ s = "\u3042".encode("UTF-32BE")
+ assert_equal(s.dup.force_encoding("ISO-2022-JP").inspect, s.dup.force_encoding(enc).inspect)
+ s = "\x00\x00\xFE\xFF"
+ assert_equal(s.dup.force_encoding("ISO-2022-JP").inspect, s.dup.force_encoding(enc).inspect)
+
+ assert_equal [0, 0, 254, 255], "\x00\x00\xFE\xFF".force_encoding(enc).codepoints
+ assert_equal 0, "\x00\x00\xFE\xFF".force_encoding(enc).ord
+ assert_equal 255, "\xFF\xFE\x00\x00".force_encoding(enc).ord
end
end
@@ -892,10 +870,22 @@ class TestM17N < Test::Unit::TestCase
assert_raise(Encoding::CompatibilityError) {
"%s%s" % [s("\xc2\xa1"), e("\xc2\xa1")]
}
+
+ assert_equal("\u3042".encode('Windows-31J'), "%c" % "\u3042\u3044".encode('Windows-31J'))
end
def test_sprintf_p
Encoding.list.each do |e|
+ unless e.ascii_compatible?
+ format = e.dummy? ? "%p".force_encoding(e) : "%p".encode(e)
+ assert_raise(Encoding::CompatibilityError) do
+ sprintf(format, nil)
+ end
+ assert_raise(Encoding::CompatibilityError) do
+ format % nil
+ end
+ next
+ end
format = "%p".force_encoding(e)
['', 'a', "\xC2\xA1", "\x00"].each do |s|
s.force_encoding(e)
@@ -1100,7 +1090,23 @@ class TestM17N < Test::Unit::TestCase
assert_nil(e("\xa1\xa2\xa3\xa4").index(e("\xa3")))
assert_nil(e("\xa1\xa2\xa3\xa4").rindex(e("\xa3")))
s = e("\xa3\xb0\xa3\xb1\xa3\xb2\xa3\xb3\xa3\xb4")
- assert_raise(Encoding::CompatibilityError){s.rindex(a("\xb1\xa3"))}
+
+ a_with_e = /EUC-JP and ASCII-8BIT/
+ assert_raise_with_message(Encoding::CompatibilityError, a_with_e) do
+ s.index(a("\xb1\xa3"))
+ end
+ assert_raise_with_message(Encoding::CompatibilityError, a_with_e) do
+ s.rindex(a("\xb1\xa3"))
+ end
+
+ a_with_e = /ASCII-8BIT regexp with EUC-JP string/
+ assert_raise_with_message(Encoding::CompatibilityError, a_with_e) do
+ s.index(Regexp.new(a("\xb1\xa3")))
+ end
+ assert_raise_with_message(Encoding::CompatibilityError, a_with_e) do
+ s.rindex(Regexp.new(a("\xb1\xa3")))
+ end
+
bug11488 = '[ruby-core:70592] [Bug #11488]'
each_encoding("abcdef", "def") do |str, substr|
assert_equal(3, str.index(substr), bug11488)
diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb
index fc5cd9e93e..79d9577737 100644
--- a/test/ruby/test_marshal.rb
+++ b/test/ruby/test_marshal.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: false
require 'test/unit'
-require 'tempfile'
require_relative 'marshaltestlib'
class TestMarshal < Test::Unit::TestCase
@@ -92,6 +91,14 @@ class TestMarshal < Test::Unit::TestCase
TestMarshal.instance_eval { remove_const :StructInvalidMembers }
end
+ def test_load_range_as_struct
+ assert_raise(TypeError, 'GH-6832') do
+ # Can be obtained with:
+ # $ ruby -e 'Range = Struct.new(:a, :b, :c); p Marshal.dump(Range.new(nil, nil, nil))'
+ Marshal.load("\x04\bS:\nRange\b:\x06a0:\x06b0:\x06c0")
+ end
+ end
+
class C
def initialize(str)
@str = str
@@ -306,11 +313,10 @@ class TestMarshal < Test::Unit::TestCase
assert_equal(c, Marshal.load(Marshal.dump(c)), bug2109)
assert_nothing_raised(ArgumentError, '[ruby-dev:40386]') do
- re = Tempfile.create("marshal_regexp") do |f|
- f.binmode.write("\x04\bI/\x00\x00\x06:\rencoding\"\rUS-ASCII")
- f.rewind
- re2 = Marshal.load(f)
- re2
+ re = IO.pipe do |r, w|
+ w.write("\x04\bI/\x00\x00\x06:\rencoding\"\rUS-ASCII")
+ # Marshal.load would not overread and block
+ Marshal.load(r)
end
assert_equal(//, re)
end
@@ -603,6 +609,8 @@ class TestMarshal < Test::Unit::TestCase
def test_continuation
EnvUtil.suppress_warning {require "continuation"}
+ omit 'requires callcc support' unless respond_to?(:callcc)
+
c = Bug9523.new
assert_raise_with_message(RuntimeError, /Marshal\.dump reentered at marshal_dump/) do
Marshal.dump(c)
diff --git a/test/ruby/test_math.rb b/test/ruby/test_math.rb
index 73f44c6ae3..6e67099c6b 100644
--- a/test/ruby/test_math.rb
+++ b/test/ruby/test_math.rb
@@ -5,6 +5,7 @@ class TestMath < Test::Unit::TestCase
def assert_infinity(a, *rest)
rest = ["not infinity: #{a.inspect}"] if rest.empty?
assert_predicate(a, :infinite?, *rest)
+ assert_predicate(a, :positive?, *rest)
end
def assert_nan(a, *rest)
@@ -165,6 +166,9 @@ class TestMath < Test::Unit::TestCase
assert_nothing_raised { assert_nan(Math.log(0.0, 0.0)) }
assert_nothing_raised { assert_nan(Math.log(Float::NAN)) }
assert_nothing_raised { assert_nan(Math.log(1.0, Float::NAN)) }
+ assert_nothing_raised { assert_infinity(-Math.log(0)) }
+ assert_nothing_raised { assert_infinity(-Math.log(0, 2)) }
+ check(307.95368556425274, Math.log(2**1023, 10))
end
def test_log2
@@ -179,6 +183,7 @@ class TestMath < Test::Unit::TestCase
assert_raise_with_message(Math::DomainError, /\blog2\b/) { Math.log2(-1.0) }
assert_raise_with_message(Math::DomainError, /\blog2\b/) { Math.log2(-Float::EPSILON) }
assert_nothing_raised { assert_nan(Math.log2(Float::NAN)) }
+ assert_nothing_raised { assert_infinity(-Math.log2(0)) }
end
def test_log10
@@ -193,6 +198,7 @@ class TestMath < Test::Unit::TestCase
assert_raise_with_message(Math::DomainError, /\blog10\b/) { Math.log10(-1.0) }
assert_raise_with_message(Math::DomainError, /\blog10\b/) { Math.log10(-Float::EPSILON) }
assert_nothing_raised { assert_nan(Math.log10(Float::NAN)) }
+ assert_nothing_raised { assert_infinity(-Math.log10(0)) }
end
def test_sqrt
@@ -277,8 +283,7 @@ class TestMath < Test::Unit::TestCase
assert_raise_with_message(Math::DomainError, /\bgamma\b/) { Math.gamma(-1.0) }
x = Math.gamma(-0.0)
mesg = "Math.gamma(-0.0) should be -INF"
- assert_infinity(x, mesg)
- assert_predicate(x, :negative?, mesg)
+ assert_infinity(-x, mesg)
assert_nan(Math.gamma(Float::NAN))
end
@@ -299,7 +304,6 @@ class TestMath < Test::Unit::TestCase
x, sign = Math.lgamma(-0.0)
mesg = "Math.lgamma(-0.0) should be [INF, -1]"
assert_infinity(x, mesg)
- assert_predicate(x, :positive?, mesg)
assert_equal(-1, sign, mesg)
x, sign = Math.lgamma(Float::NAN)
assert_nan(x)
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 56e94493d9..a41704cf06 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -450,6 +450,18 @@ class TestMethod < Test::Unit::TestCase
assert_equal(:bar, m.clone.bar)
end
+ def test_clone_under_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ o = Object.new
+ def o.foo; :foo; end
+ m = o.method(:foo)
+ def m.bar; :bar; end
+ assert_equal(:foo, m.clone.call)
+ assert_equal(:bar, m.clone.bar)
+ end
+ end
+
def test_inspect
o = Object.new
def o.foo; end; line_no = __LINE__
@@ -771,6 +783,14 @@ class TestMethod < Test::Unit::TestCase
assert_raise(NoMethodError) { (self).mv2 }
assert_nothing_raised { self.mv3 }
+ class << (obj = Object.new)
+ private def [](x) x end
+ def mv1(x) self[x] end
+ def mv2(x) (self)[x] end
+ end
+ assert_nothing_raised { obj.mv1(0) }
+ assert_raise(NoMethodError) { obj.mv2(0) }
+
v = Visibility.new
assert_equal('method', defined?(v.mv1))
@@ -1056,7 +1076,7 @@ class TestMethod < Test::Unit::TestCase
assert_equal(sm, im.clone.bind(o).super_method)
end
- def test_super_method_removed
+ def test_super_method_removed_public
c1 = Class.new {private def foo; end}
c2 = Class.new(c1) {public :foo}
c3 = Class.new(c2) {def foo; end}
@@ -1066,20 +1086,35 @@ class TestMethod < Test::Unit::TestCase
assert_nil(m, Feature9781)
end
+ def test_super_method_removed_regular
+ c1 = Class.new { def foo; end }
+ c2 = Class.new(c1) { def foo; end }
+ assert_equal c1.instance_method(:foo), c2.instance_method(:foo).super_method
+ c1.remove_method :foo
+ assert_equal nil, c2.instance_method(:foo).super_method
+ end
+
def test_prepended_public_zsuper
- mod = EnvUtil.labeled_module("Mod") {private def foo; :ok end}
- mods = [mod]
+ mod = EnvUtil.labeled_module("Mod") {private def foo; [:ok] end}
obj = Object.new.extend(mod)
+
class << obj
public :foo
end
- 2.times do |i|
- mods.unshift(mod = EnvUtil.labeled_module("Mod#{i}") {def foo; end})
- obj.singleton_class.prepend(mod)
- end
+
+ mod1 = EnvUtil.labeled_module("Mod1") {def foo; [:mod1] + super end}
+ obj.singleton_class.prepend(mod1)
+
+ mod2 = EnvUtil.labeled_module("Mod2") {def foo; [:mod2] + super end}
+ obj.singleton_class.prepend(mod2)
+
m = obj.method(:foo)
- assert_equal(mods, mods.map {m.owner.tap {m = m.super_method}})
- assert_nil(m)
+ assert_equal mod2, m.owner
+ assert_equal mod1, m.super_method.owner
+ assert_equal obj.singleton_class, m.super_method.super_method.owner
+ assert_equal nil, m.super_method.super_method.super_method
+
+ assert_equal [:mod2, :mod1, :ok], obj.foo
end
def test_super_method_with_prepended_module
@@ -1192,6 +1227,147 @@ class TestMethod < Test::Unit::TestCase
assert_nil(super_method)
end
+ # Bug 18435
+ def test_instance_methods_owner_consistency
+ a = Module.new { def method1; end }
+
+ b = Class.new do
+ include a
+ protected :method1
+ end
+
+ assert_equal [:method1], b.instance_methods(false)
+ assert_equal b, b.instance_method(:method1).owner
+ end
+
+ def test_zsuper_method_removed
+ a = EnvUtil.labeled_class('A') do
+ private
+ def foo(arg = nil)
+ 1
+ end
+ end
+ line = __LINE__ - 4
+
+ b = EnvUtil.labeled_class('B', a) do
+ public :foo
+ end
+
+ unbound = b.instance_method(:foo)
+
+ assert_equal unbound, b.public_instance_method(:foo)
+ assert_equal "#<UnboundMethod: A#foo(arg=...) #{__FILE__}:#{line}>", unbound.inspect
+ assert_equal [[:opt, :arg]], unbound.parameters
+
+ a.remove_method(:foo)
+
+ assert_equal "#<UnboundMethod: A#foo(arg=...) #{__FILE__}:#{line}>", unbound.inspect
+ assert_equal [[:opt, :arg]], unbound.parameters
+
+ obj = b.new
+ assert_equal 1, unbound.bind_call(obj)
+
+ assert_include b.instance_methods(false), :foo
+ link = 'https://github.com/ruby/ruby/pull/6467#issuecomment-1262159088'
+ assert_raise(NameError, link) { b.instance_method(:foo) }
+ # For #test_method_list below, otherwise we get the same error as just above
+ b.remove_method(:foo)
+ end
+
+ def test_zsuper_method_removed_higher_method
+ a0 = EnvUtil.labeled_class('A0') do
+ def foo(arg1 = nil, arg2 = nil)
+ 0
+ end
+ end
+ line0 = __LINE__ - 4
+ a0_foo = a0.instance_method(:foo)
+
+ a = EnvUtil.labeled_class('A', a0) do
+ private
+ def foo(arg = nil)
+ 1
+ end
+ end
+ line = __LINE__ - 4
+
+ b = EnvUtil.labeled_class('B', a) do
+ public :foo
+ end
+
+ unbound = b.instance_method(:foo)
+
+ assert_equal a0_foo, unbound.super_method
+
+ a.remove_method(:foo)
+
+ assert_equal "#<UnboundMethod: A#foo(arg=...) #{__FILE__}:#{line}>", unbound.inspect
+ assert_equal [[:opt, :arg]], unbound.parameters
+ assert_equal a0_foo, unbound.super_method
+
+ obj = b.new
+ assert_equal 1, unbound.bind_call(obj)
+
+ assert_include b.instance_methods(false), :foo
+ assert_equal "#<UnboundMethod: A0#foo(arg1=..., arg2=...) #{__FILE__}:#{line0}>", b.instance_method(:foo).inspect
+ end
+
+ def test_zsuper_method_redefined_bind_call
+ c0 = EnvUtil.labeled_class('C0') do
+ def foo
+ [:foo]
+ end
+ end
+
+ c1 = EnvUtil.labeled_class('C1', c0) do
+ def foo
+ super + [:bar]
+ end
+ end
+ m1 = c1.instance_method(:foo)
+
+ c2 = EnvUtil.labeled_class('C2', c1) do
+ private :foo
+ end
+
+ assert_equal [:foo], c2.private_instance_methods(false)
+ m2 = c2.instance_method(:foo)
+
+ c1.class_exec do
+ remove_method :foo
+ def foo
+ [:bar2]
+ end
+ end
+
+ m3 = c2.instance_method(:foo)
+ c = c2.new
+ assert_equal [:foo, :bar], m1.bind_call(c)
+ assert_equal c1, m1.owner
+ assert_equal [:foo, :bar], m2.bind_call(c)
+ assert_equal c2, m2.owner
+ assert_equal [:bar2], m3.bind_call(c)
+ assert_equal c2, m3.owner
+ end
+
+ # Bug #18751
+ def method_equality_visbility_alias
+ c = Class.new do
+ class << self
+ alias_method :n, :new
+ private :new
+ end
+ end
+
+ assert_equal c.method(:n), c.method(:new)
+
+ assert_not_equal c.method(:n), Class.method(:new)
+ assert_equal c.method(:n) == Class.instance_method(:new).bind(c)
+
+ assert_not_equal c.method(:new), Class.method(:new)
+ assert_equal c.method(:new), Class.instance_method(:new).bind(c)
+ end
+
def rest_parameter(*rest)
rest
end
@@ -1267,25 +1443,25 @@ class TestMethod < Test::Unit::TestCase
end
def test_argument_error_location
- body = <<-'END_OF_BODY'
- eval <<-'EOS'
- $line_lambda = __LINE__; $f = lambda do
- _x = 1
- end
- $line_method = __LINE__; def foo
- _x = 1
- end
- begin
- $f.call(1)
- rescue ArgumentError => e
- assert_equal "(eval):#{$line_lambda.to_s}:in `block in <main>'", e.backtrace.first
- end
- begin
- foo(1)
- rescue ArgumentError => e
- assert_equal "(eval):#{$line_method}:in `foo'", e.backtrace.first
- end
- EOS
+ body = <<~'END_OF_BODY'
+ eval <<~'EOS', nil, "main.rb"
+ $line_lambda = __LINE__; $f = lambda do
+ _x = 1
+ end
+ $line_method = __LINE__; def foo
+ _x = 1
+ end
+ begin
+ $f.call(1)
+ rescue ArgumentError => e
+ assert_equal "main.rb:#{$line_lambda}:in 'block in <main>'", e.backtrace.first
+ end
+ begin
+ foo(1)
+ rescue ArgumentError => e
+ assert_equal "main.rb:#{$line_method}:in 'foo'", e.backtrace.first
+ end
+ EOS
END_OF_BODY
assert_separately [], body
@@ -1294,7 +1470,7 @@ class TestMethod < Test::Unit::TestCase
end
def test_zsuper_private_override_instance_method
- assert_separately(%w(--disable-gems), <<-'end;', timeout: 30)
+ assert_separately([], <<-'end;', timeout: 30)
# Bug #16942 [ruby-core:98691]
module M
def x
@@ -1310,12 +1486,12 @@ class TestMethod < Test::Unit::TestCase
::Object.prepend(M2)
m = Object.instance_method(:x)
- assert_equal M, m.owner
+ assert_equal M2, m.owner
end;
end
def test_override_optimized_method_on_class_using_prepend
- assert_separately(%w(--disable-gems), <<-'end;', timeout: 30)
+ assert_separately([], <<-'end;', timeout: 30)
# Bug #17725 [ruby-core:102884]
$VERBOSE = nil
String.prepend(Module.new)
@@ -1439,4 +1615,82 @@ class TestMethod < Test::Unit::TestCase
def test_invalidating_CC_ASAN
assert_ruby_status(['-e', 'using Module.new'])
end
+
+ def test_kwarg_eval_memory_leak
+ assert_no_memory_leak([], "", <<~RUBY, rss: true, limit: 1.2)
+ 100_000.times do
+ eval("Hash.new(foo: 123)")
+ end
+ RUBY
+ end
+
+ def test_warn_unused_block
+ assert_in_out_err '-w', <<-'RUBY' do |_out, err, _status|
+ def foo = nil
+ foo{} # warn
+ send(:foo){} # warn
+ b = Proc.new{}
+ foo(&b) # warn
+ RUBY
+ assert_equal 3, err.size
+ err = err.join
+ assert_match(/-:2: warning/, err)
+ assert_match(/-:3: warning/, err)
+ assert_match(/-:5: warning/, err)
+ end
+
+ assert_in_out_err '-w', <<-'RUBY' do |_out, err, _status|
+ def foo = nil
+ 10.times{foo{}} # warn once
+ RUBY
+ assert_equal 1, err.size
+ end
+
+ assert_in_out_err '-w', <<-'RUBY' do |_out, err, _status|
+ def foo = nil; b = nil
+ foo(&b) # no warning
+ 1.object_id{} # no warning because it is written in C
+
+ class C
+ def initialize
+ end
+ end
+ C.new{} # no warning
+
+ RUBY
+ assert_equal 0, err.size
+ end
+
+ assert_in_out_err '-w', <<-'RUBY' do |_out, err, _status|
+ class C0
+ def f1 = nil
+ def f2 = nil
+ def f3 = nil
+ def f4 = nil
+ def f5 = nil
+ def f6 = nil
+ end
+
+ class C1 < C0
+ def f1 = super # zsuper / use
+ def f2 = super() # super / use
+ def f3(&_) = super(&_) # super / use
+ def f4 = super(&nil) # super / unuse
+ def f5 = super(){} # super / unuse
+ def f6 = super{} # zsuper / unuse
+ end
+
+ C1.new.f1{} # no warning
+ C1.new.f2{} # no warning
+ C1.new.f3{} # no warning
+ C1.new.f4{} # warning
+ C1.new.f5{} # warning
+ C1.new.f6{} # warning
+ RUBY
+ assert_equal 3, err.size, err.join("\n")
+ assert_match(/-:22: warning.+f4/, err.join)
+ assert_match(/-:23: warning.+f5/, err.join)
+ assert_match(/-:24: warning.+f6/, err.join)
+ end
+ end
end
diff --git a/test/ruby/test_mjit.rb b/test/ruby/test_mjit.rb
deleted file mode 100644
index 02be88aa32..0000000000
--- a/test/ruby/test_mjit.rb
+++ /dev/null
@@ -1,1307 +0,0 @@
-# frozen_string_literal: true
-require 'test/unit'
-require 'tmpdir'
-require_relative '../lib/jit_support'
-
-# Test for --mjit option
-class TestMJIT < Test::Unit::TestCase
- include JITSupport
-
- IGNORABLE_PATTERNS = [
- /\AJIT recompile: .+\n\z/,
- /\AJIT inline: .+\n\z/,
- /\AJIT cancel: .+\n\z/,
- /\ASuccessful MJIT finish\n\z/,
- ]
- MAX_CACHE_PATTERNS = [
- /\AJIT compaction \([^)]+\): .+\n\z/,
- /\AToo many JIT code, but skipped unloading units for JIT compaction\n\z/,
- /\ANo units can be unloaded -- .+\n\z/,
- ]
-
- # trace_* insns are not compiled for now...
- TEST_PENDING_INSNS = RubyVM::INSTRUCTION_NAMES.select { |n| n.start_with?('trace_') }.map(&:to_sym) + [
- # not supported yet
- :defineclass,
-
- # to be tested
- :invokebuiltin,
-
- # never used
- :opt_invokebuiltin_delegate,
- ].each do |insn|
- if !RubyVM::INSTRUCTION_NAMES.include?(insn.to_s)
- warn "instruction #{insn.inspect} is not defined but included in TestMJIT::TEST_PENDING_INSNS"
- end
- end
-
- def self.untested_insns
- @untested_insns ||= (RubyVM::INSTRUCTION_NAMES.map(&:to_sym) - TEST_PENDING_INSNS)
- end
-
- def self.setup
- return if defined?(@setup_hooked)
- @setup_hooked = true
-
- # ci.rvm.jp caches its build environment. Clean up temporary files left by SEGV.
- if ENV['RUBY_DEBUG']&.include?('ci')
- Dir.glob("#{ENV.fetch('TMPDIR', '/tmp')}/_ruby_mjit_p*u*.*").each do |file|
- puts "test/ruby/test_mjit.rb: removing #{file}"
- File.unlink(file)
- end
- end
-
- # ruby -w -Itest/lib test/ruby/test_mjit.rb
- if $VERBOSE
- pid = $$
- at_exit do
- if pid == $$ && !TestMJIT.untested_insns.empty?
- warn "you may want to add tests for following insns, when you have a chance: #{TestMJIT.untested_insns.join(' ')}"
- end
- end
- end
- end
-
- def setup
- unless JITSupport.supported?
- omit 'JIT seems not supported on this platform'
- end
- self.class.setup
- end
-
- def test_compile_insn_nop
- assert_compile_once('nil rescue true', result_inspect: 'nil', insns: %i[nop])
- end
-
- def test_compile_insn_local
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[setlocal_WC_0 getlocal_WC_0])
- begin;
- foo = 1
- foo
- end;
-
- insns = %i[setlocal getlocal setlocal_WC_0 getlocal_WC_0 setlocal_WC_1 getlocal_WC_1]
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 3, stdout: '168', insns: insns)
- begin;
- def foo
- a = 0
- [1, 2].each do |i|
- a += i
- [3, 4].each do |j|
- a *= j
- end
- end
- a
- end
-
- print foo
- end;
- end
-
- def test_compile_insn_blockparam
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '3', success_count: 2, insns: %i[getblockparam setblockparam])
- begin;
- def foo(&b)
- a = b
- b = 2
- a.call + 2
- end
-
- print foo { 1 }
- end;
- end
-
- def test_compile_insn_getblockparamproxy
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '4', success_count: 3, insns: %i[getblockparamproxy])
- begin;
- def bar(&b)
- b.call
- end
-
- def foo(&b)
- bar(&b) * bar(&b)
- end
-
- print foo { 2 }
- end;
- end
-
- def test_compile_insn_getspecial
- assert_compile_once('$1', result_inspect: 'nil', insns: %i[getspecial])
- end
-
- def test_compile_insn_setspecial
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true', insns: %i[setspecial])
- begin;
- true if nil.nil?..nil.nil?
- end;
- end
-
- def test_compile_insn_instancevariable
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[getinstancevariable setinstancevariable])
- begin;
- @foo = 1
- @foo
- end;
-
- # optimized getinstancevariable call
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '33', success_count: 1, min_calls: 2)
- begin;
- class A
- def initialize
- @a = 1
- @b = 2
- end
-
- def three
- @a + @b
- end
- end
-
- a = A.new
- print(a.three) # set ic
- print(a.three) # inlined ic
- end;
- end
-
- def test_compile_insn_classvariable
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '1', success_count: 1, insns: %i[getclassvariable setclassvariable])
- begin;
- class Foo
- def self.foo
- @@foo = 1
- @@foo
- end
- end
-
- print Foo.foo
- end;
- end
-
- def test_compile_insn_constant
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[getconstant setconstant])
- begin;
- FOO = 1
- FOO
- end;
- end
-
- def test_compile_insn_global
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[getglobal setglobal])
- begin;
- $foo = 1
- $foo
- end;
- end
-
- def test_compile_insn_putnil
- assert_compile_once('nil', result_inspect: 'nil', insns: %i[putnil])
- end
-
- def test_compile_insn_putself
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 1, insns: %i[putself])
- begin;
- proc { print "hello" }.call
- end;
- end
-
- def test_compile_insn_putobject
- assert_compile_once('0', result_inspect: '0', insns: %i[putobject_INT2FIX_0_])
- assert_compile_once('1', result_inspect: '1', insns: %i[putobject_INT2FIX_1_])
- assert_compile_once('2', result_inspect: '2', insns: %i[putobject])
- end
-
- def test_compile_insn_definemethod_definesmethod
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'helloworld', success_count: 3, insns: %i[definemethod definesmethod])
- begin;
- print 1.times.map {
- def method_definition
- 'hello'
- end
-
- def self.smethod_definition
- 'world'
- end
-
- method_definition + smethod_definition
- }.join
- end;
- end
-
- def test_compile_insn_putspecialobject
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'a', success_count: 2, insns: %i[putspecialobject])
- begin;
- print 1.times.map {
- def a
- 'a'
- end
-
- alias :b :a
-
- b
- }.join
- end;
- end
-
- def test_compile_insn_putstring_concatstrings_objtostring
- assert_compile_once('"a#{}b" + "c"', result_inspect: '"abc"', insns: %i[putstring concatstrings objtostring])
- end
-
- def test_compile_insn_toregexp
- assert_compile_once('/#{true}/ =~ "true"', result_inspect: '0', insns: %i[toregexp])
- end
-
- def test_compile_insn_newarray
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '[1, 2, 3]', insns: %i[newarray])
- begin;
- a, b, c = 1, 2, 3
- [a, b, c]
- end;
- end
-
- def test_compile_insn_newarraykwsplat
- assert_compile_once('[**{ x: 1 }]', result_inspect: '[{:x=>1}]', insns: %i[newarraykwsplat])
- end
-
- def test_compile_insn_intern_duparray
- assert_compile_once('[:"#{0}"] + [1,2,3]', result_inspect: '[:"0", 1, 2, 3]', insns: %i[intern duparray])
- end
-
- def test_compile_insn_expandarray
- assert_compile_once('y = [ true, false, nil ]; x, = y; x', result_inspect: 'true', insns: %i[expandarray])
- end
-
- def test_compile_insn_concatarray
- assert_compile_once('["t", "r", *x = "u", "e"].join', result_inspect: '"true"', insns: %i[concatarray])
- end
-
- def test_compile_insn_splatarray
- assert_compile_once('[*(1..2)]', result_inspect: '[1, 2]', insns: %i[splatarray])
- end
-
- def test_compile_insn_newhash
- assert_compile_once('a = 1; { a: a }', result_inspect: '{:a=>1}', insns: %i[newhash])
- end
-
- def test_compile_insn_duphash
- assert_compile_once('{ a: 1 }', result_inspect: '{:a=>1}', insns: %i[duphash])
- end
-
- def test_compile_insn_newrange
- assert_compile_once('a = 1; 0..a', result_inspect: '0..1', insns: %i[newrange])
- end
-
- def test_compile_insn_pop
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[pop])
- begin;
- a = false
- b = 1
- a || b
- end;
- end
-
- def test_compile_insn_dup
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '3', insns: %i[dup])
- begin;
- a = 1
- a&.+(2)
- end;
- end
-
- def test_compile_insn_dupn
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true', insns: %i[dupn])
- begin;
- klass = Class.new
- klass::X ||= true
- end;
- end
-
- def test_compile_insn_swap_topn
- assert_compile_once('{}["true"] = true', result_inspect: 'true', insns: %i[swap topn])
- end
-
- def test_compile_insn_reput
- omit "write test"
- end
-
- def test_compile_insn_setn
- assert_compile_once('[nil][0] = 1', result_inspect: '1', insns: %i[setn])
- end
-
- def test_compile_insn_adjuststack
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'true', insns: %i[adjuststack])
- begin;
- x = [true]
- x[0] ||= nil
- x[0]
- end;
- end
-
- def test_compile_insn_defined
- assert_compile_once('defined?(a)', result_inspect: 'nil', insns: %i[defined])
- end
-
- def test_compile_insn_checkkeyword
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'true', success_count: 1, insns: %i[checkkeyword])
- begin;
- def test(x: rand)
- x
- end
- print test(x: true)
- end;
- end
-
- def test_compile_insn_tracecoverage
- omit "write test"
- end
-
- def test_compile_insn_defineclass
- omit "support this in mjit_compile (low priority)"
- end
-
- def test_compile_insn_send
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '1', success_count: 3, insns: %i[send])
- begin;
- print proc { yield_self { 1 } }.call
- end;
- end
-
- def test_compile_insn_opt_str_freeze
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"foo"', insns: %i[opt_str_freeze])
- begin;
- 'foo'.freeze
- end;
- end
-
- def test_compile_insn_opt_nil_p
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: 'false', insns: %i[opt_nil_p])
- begin;
- nil.nil?.nil?
- end;
- end
-
- def test_compile_insn_opt_str_uminus
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"bar"', insns: %i[opt_str_uminus])
- begin;
- -'bar'
- end;
- end
-
- def test_compile_insn_opt_newarray_max
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '2', insns: %i[opt_newarray_max])
- begin;
- a = 1
- b = 2
- [a, b].max
- end;
- end
-
- def test_compile_insn_opt_newarray_min
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '1', insns: %i[opt_newarray_min])
- begin;
- a = 1
- b = 2
- [a, b].min
- end;
- end
-
- def test_compile_insn_opt_send_without_block
- assert_compile_once('print', result_inspect: 'nil', insns: %i[opt_send_without_block])
- end
-
- def test_compile_insn_invokesuper
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '3', success_count: 4, insns: %i[invokesuper])
- begin;
- mod = Module.new {
- def test
- super + 2
- end
- }
- klass = Class.new {
- prepend mod
- def test
- 1
- end
- }
- print klass.new.test
- end;
- end
-
- def test_compile_insn_invokeblock_leave
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '2', success_count: 2, insns: %i[invokeblock leave])
- begin;
- def foo
- yield
- end
- print foo { 2 }
- end;
- end
-
- def test_compile_insn_throw
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '4', success_count: 2, insns: %i[throw])
- begin;
- def test
- proc do
- if 1+1 == 1
- return 3
- else
- return 4
- end
- 5
- end.call
- end
- print test
- end;
- end
-
- def test_compile_insn_jump_branchif
- assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: 'nil', insns: %i[jump branchif])
- begin;
- a = false
- 1 + 1 while a
- end;
- end
-
- def test_compile_insn_branchunless
- assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '1', insns: %i[branchunless])
- begin;
- a = true
- if a
- 1
- else
- 2
- end
- end;
- end
-
- def test_compile_insn_branchnil
- assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '3', insns: %i[branchnil])
- begin;
- a = 2
- a&.+(1)
- end;
- end
-
- def test_compile_insn_objtostring
- assert_compile_once("#{<<~"begin;"}\n#{<<~'end;'}", result_inspect: '"42"', insns: %i[objtostring])
- begin;
- a = '2'
- "4#{a}"
- end;
- end
-
- def test_compile_insn_inlinecache
- assert_compile_once('Struct', result_inspect: 'Struct', insns: %i[opt_getinlinecache opt_setinlinecache])
- end
-
- def test_compile_insn_once
- assert_compile_once('/#{true}/o =~ "true" && $~.to_a', result_inspect: '["true"]', insns: %i[once])
- end
-
- def test_compile_insn_checkmatch_opt_case_dispatch
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"world"', insns: %i[opt_case_dispatch])
- begin;
- case 'hello'
- when 'hello'
- 'world'
- end
- end;
- end
-
- def test_compile_insn_opt_calc
- assert_compile_once('4 + 2 - ((2 * 3 / 2) % 2)', result_inspect: '5', insns: %i[opt_plus opt_minus opt_mult opt_div opt_mod])
- assert_compile_once('4.0 + 2.0 - ((2.0 * 3.0 / 2.0) % 2.0)', result_inspect: '5.0', insns: %i[opt_plus opt_minus opt_mult opt_div opt_mod])
- assert_compile_once('4 + 2', result_inspect: '6')
- end
-
- def test_compile_insn_opt_cmp
- assert_compile_once('(1 == 1) && (1 != 2)', result_inspect: 'true', insns: %i[opt_eq opt_neq])
- end
-
- def test_compile_insn_opt_rel
- assert_compile_once('1 < 2 && 1 <= 1 && 2 > 1 && 1 >= 1', result_inspect: 'true', insns: %i[opt_lt opt_le opt_gt opt_ge])
- end
-
- def test_compile_insn_opt_ltlt
- assert_compile_once('[1] << 2', result_inspect: '[1, 2]', insns: %i[opt_ltlt])
- end
-
- def test_compile_insn_opt_and
- assert_compile_once('1 & 3', result_inspect: '1', insns: %i[opt_and])
- end
-
- def test_compile_insn_opt_or
- assert_compile_once('1 | 3', result_inspect: '3', insns: %i[opt_or])
- end
-
- def test_compile_insn_opt_aref
- # optimized call (optimized JIT) -> send call
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '21', success_count: 2, min_calls: 1, insns: %i[opt_aref])
- begin;
- obj = Object.new
- def obj.[](h)
- h
- end
-
- block = proc { |h| h[1] }
- print block.call({ 1 => 2 })
- print block.call(obj)
- end;
-
- # send call -> optimized call (send JIT) -> optimized call
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '122', success_count: 2, min_calls: 2)
- begin;
- obj = Object.new
- def obj.[](h)
- h
- end
-
- block = proc { |h| h[1] }
- print block.call(obj)
- print block.call({ 1 => 2 })
- print block.call({ 1 => 2 })
- end;
- end
-
- def test_compile_insn_opt_aref_with
- assert_compile_once("{ '1' => 2 }['1']", result_inspect: '2', insns: %i[opt_aref_with])
- end
-
- def test_compile_insn_opt_aset
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '5', insns: %i[opt_aset opt_aset_with])
- begin;
- hash = { '1' => 2 }
- (hash['2'] = 2) + (hash[1.to_s] = 3)
- end;
- end
-
- def test_compile_insn_opt_length_size
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '4', insns: %i[opt_length opt_size])
- begin;
- array = [1, 2]
- array.length + array.size
- end;
- end
-
- def test_compile_insn_opt_empty_p
- assert_compile_once('[].empty?', result_inspect: 'true', insns: %i[opt_empty_p])
- end
-
- def test_compile_insn_opt_succ
- assert_compile_once('1.succ', result_inspect: '2', insns: %i[opt_succ])
- end
-
- def test_compile_insn_opt_not
- assert_compile_once('!!true', result_inspect: 'true', insns: %i[opt_not])
- end
-
- def test_compile_insn_opt_regexpmatch2
- assert_compile_once("/true/ =~ 'true'", result_inspect: '0', insns: %i[opt_regexpmatch2])
- assert_compile_once("'true' =~ /true/", result_inspect: '0', insns: %i[opt_regexpmatch2])
- end
-
- def test_compile_insn_opt_invokebuiltin_delegate_leave
- iseq = eval(EnvUtil.invoke_ruby(['-e', <<~'EOS'], '', true).first)
- p RubyVM::InstructionSequence.of("\x00".method(:unpack)).to_a
- EOS
- insns = collect_insns(iseq)
- mark_tested_insn(:opt_invokebuiltin_delegate_leave, used_insns: insns)
- assert_eval_with_jit('print "\x00".unpack("c")', stdout: '[0]', success_count: 1)
- end
-
- def test_compile_insn_checkmatch
- assert_compile_once("#{<<~"begin;"}\n#{<<~"end;"}", result_inspect: '"world"', insns: %i[checkmatch])
- begin;
- ary = %w(hello good-bye)
- case 'hello'
- when *ary
- 'world'
- end
- end;
- end
-
- def test_compile_opt_pc
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 1)
- begin;
- def test(arg = 'hello')
- print arg
- end
- test
- end;
- end
-
- def test_mjit_output
- out, err = eval_with_jit('5.times { puts "MJIT" }', verbose: 1, min_calls: 5)
- assert_equal("MJIT\n" * 5, out)
- assert_match(/^#{JIT_SUCCESS_PREFIX}: block in <main>@-e:1 -> .+_ruby_mjit_p\d+u\d+\.c$/, err)
- assert_match(/^Successful MJIT finish$/, err)
- end
-
- def test_nothing_to_unload_with_jit_wait
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 11, max_cache: 10, ignorable_patterns: MAX_CACHE_PATTERNS)
- begin;
- def a1() a2() end
- def a2() a3() end
- def a3() a4() end
- def a4() a5() end
- def a5() a6() end
- def a6() a7() end
- def a7() a8() end
- def a8() a9() end
- def a9() a10() end
- def a10() a11() end
- def a11() print('hello') end
- a1
- end;
- end
-
- def test_unload_units_on_fiber
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 12, max_cache: 10, ignorable_patterns: MAX_CACHE_PATTERNS)
- begin;
- def a1() a2(false); a2(true) end
- def a2(a) a3(a) end
- def a3(a) a4(a) end
- def a4(a) a5(a) end
- def a5(a) a6(a) end
- def a6(a) a7(a) end
- def a7(a) a8(a) end
- def a8(a) a9(a) end
- def a9(a) a10(a) end
- def a10(a)
- if a
- Fiber.new { a11 }.resume
- end
- end
- def a11() print('hello') end
- a1
- end;
- end
-
- def test_unload_units_and_compaction
- Dir.mktmpdir("jit_test_unload_units_") do |dir|
- # MIN_CACHE_SIZE is 10
- out, err = eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~'end;'}", verbose: 1, min_calls: 1, max_cache: 10)
- begin;
- i = 0
- while i < 11
- eval(<<-EOS)
- def mjit#{i}
- print #{i}
- end
- mjit#{i}
- EOS
- i += 1
- end
-
- if defined?(fork)
- # test the child does not try to delete files which are deleted by parent,
- # and test possible deadlock on fork during MJIT unload and JIT compaction on child
- Process.waitpid(Process.fork {})
- end
- end;
-
- debug_info = %Q[stdout:\n"""\n#{out}\n"""\n\nstderr:\n"""\n#{err}"""\n]
- assert_equal('012345678910', out, debug_info)
- compactions, errs = err.lines.partition do |l|
- l.match?(/\AJIT compaction \(\d+\.\dms\): Compacted \d+ methods /)
- end
- 10.times do |i|
- assert_match(/\A#{JIT_SUCCESS_PREFIX}: mjit#{i}@\(eval\):/, errs[i], debug_info)
- end
-
- assert_equal("No units can be unloaded -- incremented max-cache-size to 11 for --jit-wait\n", errs[10], debug_info)
- assert_match(/\A#{JIT_SUCCESS_PREFIX}: mjit10@\(eval\):/, errs[11], debug_info)
- # On --jit-wait, when the number of JIT-ed code reaches --jit-max-cache,
- # it should trigger compaction.
- unless RUBY_PLATFORM.match?(/mswin|mingw/) # compaction is not supported on Windows yet
- assert_equal(1, compactions.size, debug_info)
- end
-
- if RUBY_PLATFORM.match?(/mswin/)
- # "Permission Denied" error is preventing to remove so file on AppVeyor/RubyCI.
- omit 'Removing so file is randomly failing on AppVeyor/RubyCI mswin due to Permission Denied.'
- end
- if RUBY_PLATFORM.match?(/darwin/)
- omit '.bundle.dSYM directory is left but removing it is not supported for now'
- end
- # verify .c files are deleted on unload_units
- assert_send([Dir, :empty?, dir], debug_info)
- end
- end
-
- def test_newarraykwsplat_on_stack
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "[nil, [{:type=>:development}]]\n", success_count: 1, insns: %i[newarraykwsplat])
- begin;
- def arr
- [nil, [:type => :development]]
- end
- p arr
- end;
- end
-
- def test_local_stack_on_exception
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '3', success_count: 2)
- begin;
- def b
- raise
- rescue
- 2
- end
-
- def a
- # Calling #b should be vm_exec, not direct mjit_exec.
- # Otherwise `1` on local variable would be purged.
- 1 + b
- end
-
- print a
- end;
- end
-
- def test_local_stack_with_sp_motion_by_blockargs
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '1', success_count: 2)
- begin;
- def b(base)
- 1
- end
-
- # This method is simple enough to have false in catch_except_p.
- # So local_stack_p would be true in JIT compiler.
- def a
- m = method(:b)
-
- # ci->flag has VM_CALL_ARGS_BLOCKARG and cfp->sp is moved in vm_caller_setup_arg_block.
- # So, for this send insn, JIT-ed code should use cfp->sp instead of local variables for stack.
- Module.module_eval(&m)
- end
-
- print a
- end;
- end
-
- def test_catching_deep_exception
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '1', success_count: 4)
- begin;
- def catch_true(paths, prefixes) # catch_except_p: TRUE
- prefixes.each do |prefix| # catch_except_p: TRUE
- paths.each do |path| # catch_except_p: FALSE
- return path
- end
- end
- end
-
- def wrapper(paths, prefixes)
- catch_true(paths, prefixes)
- end
-
- print wrapper(['1'], ['2'])
- end;
- end
-
- def test_inlined_builtin_methods
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '', success_count: 1, min_calls: 2)
- begin;
- def test
- float = 0.0
- float.abs
- float.-@
- float.zero?
- end
- test
- test
- end;
- end
-
- def test_inlined_c_method
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 2, recompile_count: 1, min_calls: 2)
- begin;
- def test(obj, recursive: nil)
- if recursive
- test(recursive)
- end
- obj.to_s
- end
-
- print(test('a')) # set #to_s cc to String#to_s (expecting C method)
- print(test('a')) # JIT with #to_s cc: String#to_s
- # update #to_s cd->cc to Symbol#to_s, then go through the Symbol#to_s cd->cc
- # after checking receiver class using inlined #to_s cc with String#to_s.
- print(test('a', recursive: :foo))
- end;
- end
-
- def test_inlined_exivar
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 3, recompile_count: 1, min_calls: 2)
- begin;
- class Foo < Hash
- def initialize
- @a = :a
- end
-
- def bar
- @a
- end
- end
-
- print(Foo.new.bar)
- print(Foo.new.bar) # compile #initialize, #bar -> recompile #bar
- print(Foo.new.bar) # compile #bar with exivar
- end;
- end
-
- def test_inlined_undefined_ivar
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "bbb", success_count: 3, min_calls: 3)
- begin;
- class Foo
- def initialize
- @a = :a
- end
-
- def bar
- if @b.nil?
- @b = :b
- end
- end
- end
-
- print(Foo.new.bar)
- print(Foo.new.bar)
- print(Foo.new.bar)
- end;
- end
-
- def test_inlined_setivar_frozen
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "FrozenError\n", success_count: 2, min_calls: 3)
- begin;
- class A
- def a
- @a = 1
- end
- end
-
- a = A.new
- a.a
- a.a
- a.a
- a.freeze
- begin
- a.a
- rescue FrozenError => e
- p e.class
- end
- end;
- end
-
- def test_inlined_getconstant
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '11', success_count: 1, min_calls: 2)
- begin;
- FOO = 1
- def const
- FOO
- end
- print const
- print const
- end;
- end
-
- def test_attr_reader
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "4nil\nnil\n6", success_count: 2, min_calls: 2)
- begin;
- class A
- attr_reader :a, :b
-
- def initialize
- @a = 2
- end
-
- def test
- a
- end
-
- def undefined
- b
- end
- end
-
- a = A.new
- print(a.test * a.test)
- p(a.undefined)
- p(a.undefined)
-
- # redefinition
- def a.test
- 3
- end
-
- print(2 * a.test)
- end;
-
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true", success_count: 1, min_calls: 2)
- begin;
- class Hoge
- attr_reader :foo
-
- def initialize
- @foo = []
- @bar = nil
- end
- end
-
- class Fuga < Hoge
- def initialize
- @bar = nil
- @foo = []
- end
- end
-
- def test(recv)
- recv.foo.empty?
- end
-
- hoge = Hoge.new
- fuga = Fuga.new
-
- test(hoge) # VM: cc set index=1
- test(hoge) # JIT: compile with index=1
- test(fuga) # JIT -> VM: cc set index=2
- print test(hoge) # JIT: should use index=1, not index=2 in cc
- end;
- end
-
- def test_heap_promotion_of_ivar_in_the_middle_of_jit
- omit if GC.using_rvargc?
-
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\n", success_count: 2, min_calls: 2)
- begin;
- class A
- def initialize
- @iv0 = nil
- @iv1 = []
- end
-
- def test(add)
- @iv0.nil?
- add_ivar if add
- @iv1.empty?
- end
-
- def add_ivar
- @iv2 = nil
- @iv3 = nil
- end
- end
-
- a = A.new
- p a.test(false)
- p a.test(true)
- end;
- end
-
- def test_jump_to_precompiled_branch
- assert_eval_with_jit("#{<<~'begin;'}\n#{<<~'end;'}", stdout: ".0", success_count: 1, min_calls: 1)
- begin;
- def test(foo)
- ".#{foo unless foo == 1}" if true
- end
- print test(0)
- end;
- end
-
- def test_clean_so
- if RUBY_PLATFORM.match?(/mswin/)
- omit 'Removing so file is randomly failing on AppVeyor/RubyCI mswin due to Permission Denied.'
- end
- if RUBY_PLATFORM.match?(/darwin/)
- omit '.bundle.dSYM directory is left but removing it is not supported for now'
- end
- Dir.mktmpdir("jit_test_clean_so_") do |dir|
- code = "x = 0; 10.times {|i|x+=i}"
- eval_with_jit({"TMPDIR"=>dir}, code)
- assert_send([Dir, :empty?, dir], "Directory #{dir} was not empty:\n#{Dir.glob("#{dir}/*").join("\n")}\n")
- eval_with_jit({"TMPDIR"=>dir}, code, save_temps: true)
- assert_not_send([Dir, :empty?, dir])
- end
- end
-
- def test_clean_objects_on_exec
- if /mswin|mingw/ =~ RUBY_PLATFORM
- # TODO: check call stack and close handle of code which is not on stack, and remove objects on best-effort basis
- omit 'Removing so file being used does not work on Windows'
- end
- if RUBY_PLATFORM.match?(/darwin/)
- omit '.bundle.dSYM directory is left but removing it is not supported for now'
- end
- Dir.mktmpdir("jit_test_clean_objects_on_exec_") do |dir|
- eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1)
- begin;
- def a; end; a
- exec "true"
- end;
- error_message = "Undeleted files:\n #{Dir.glob("#{dir}/*").join("\n ")}\n"
- assert_send([Dir, :empty?, dir], error_message)
- end
- end
-
- def test_lambda_longjmp
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '5', success_count: 1)
- begin;
- fib = lambda do |x|
- return x if x == 0 || x == 1
- fib.call(x-1) + fib.call(x-2)
- end
- print fib.call(5)
- end;
- end
-
- def test_stack_pointer_with_assignment
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "nil\nnil\n", success_count: 1)
- begin;
- 2.times do
- a, _ = nil
- p a
- end
- end;
- end
-
- def test_frame_omitted_inlining
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\ntrue\n", success_count: 1, min_calls: 2)
- begin;
- class Integer
- remove_method :zero?
- def zero?
- self == 0
- end
- end
-
- 3.times do
- p 0.zero?
- end
- end;
- end
-
- def test_block_handler_with_possible_frame_omitted_inlining
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "70.0\n70.0\n70.0\n", success_count: 2, min_calls: 2)
- begin;
- def multiply(a, b)
- a *= b
- end
-
- 3.times do
- p multiply(7.0, 10.0)
- end
- end;
- end
-
- def test_builtin_frame_omitted_inlining
- assert_eval_with_jit('0.zero?; 0.zero?; 3.times { p 0.zero? }', stdout: "true\ntrue\ntrue\n", success_count: 1, min_calls: 2)
- end
-
- def test_program_counter_with_regexpmatch
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aa", success_count: 1)
- begin;
- 2.times do
- break if /a/ =~ "ab" && !$~[0]
- print $~[0]
- end
- end;
- end
-
- def test_pushed_values_with_opt_aset_with
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "{}{}", success_count: 1)
- begin;
- 2.times do
- print(Thread.current["a"] = {})
- end
- end;
- end
-
- def test_pushed_values_with_opt_aref_with
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "nil\nnil\n", success_count: 1)
- begin;
- 2.times do
- p(Thread.current["a"])
- end
- end;
- end
-
- def test_mjit_pause_wait
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '', success_count: 0, min_calls: 1)
- begin;
- RubyVM::MJIT.pause
- proc {}.call
- end;
- end
-
- def test_not_cancel_by_tracepoint_class
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 1, min_calls: 2)
- begin;
- TracePoint.new(:class) {}.enable
- 2.times {}
- end;
- end
-
- def test_cancel_by_tracepoint
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 0, min_calls: 2)
- begin;
- TracePoint.new(:line) {}.enable
- 2.times {}
- end;
- end
-
- def test_caller_locations_without_catch_table
- out, _ = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1)
- begin;
- def b # 2
- caller_locations.first # 3
- end # 4
- # 5
- def a # 6
- print # <-- don't leave PC here # 7
- b # 8
- end
- puts a
- puts a
- end;
- lines = out.lines
- assert_equal("-e:8:in `a'\n", lines[0])
- assert_equal("-e:8:in `a'\n", lines[1])
- end
-
- def test_fork_with_mjit_worker_thread
- Dir.mktmpdir("jit_test_fork_with_mjit_worker_thread_") do |dir|
- # min_calls: 2 to skip fork block
- out, err = eval_with_jit({ "TMPDIR" => dir }, "#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 2, verbose: 1)
- begin;
- def before_fork; end
- def after_fork; end
-
- before_fork; before_fork # the child should not delete this .o file
- pid = Process.fork do # this child should not delete shared .pch file
- sleep 2.0 # to prevent mixing outputs on Solaris
- after_fork; after_fork # this child does not share JIT-ed after_fork with parent
- end
- after_fork; after_fork # this parent does not share JIT-ed after_fork with child
-
- Process.waitpid(pid)
- end;
- success_count = err.scan(/^#{JIT_SUCCESS_PREFIX}:/).size
- debug_info = "stdout:\n```\n#{out}\n```\n\nstderr:\n```\n#{err}```\n"
- assert_equal(3, success_count, debug_info)
-
- # assert no remove error
- assert_equal("Successful MJIT finish\n" * 2, err.gsub(/^#{JIT_SUCCESS_PREFIX}:[^\n]+\n/, ''), debug_info)
-
- # ensure objects are deleted
- if RUBY_PLATFORM.match?(/darwin/)
- omit '.bundle.dSYM directory is left but removing it is not supported for now'
- end
- assert_send([Dir, :empty?, dir], debug_info)
- end
- end if defined?(fork)
-
- def test_jit_failure
- _, err = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1, verbose: 1)
- begin;
- 1.times do
- class A
- end
- end
- end;
- assert_match(/^MJIT warning: .+ unsupported instruction: defineclass/, err)
- assert_match(/^JIT failure: block in <main>/, err)
- end
-
- private
-
- # The shortest way to test one proc
- def assert_compile_once(script, result_inspect:, insns: [], uplevel: 1)
- if script.match?(/\A\n.+\n\z/m)
- script = script.gsub(/^/, ' ')
- else
- script = " #{script} "
- end
- assert_eval_with_jit("p proc {#{script}}.call", stdout: "#{result_inspect}\n", success_count: 1, insns: insns, uplevel: uplevel + 1)
- end
-
- # Shorthand for normal test cases
- def assert_eval_with_jit(script, stdout: nil, success_count:, recompile_count: nil, min_calls: 1, max_cache: 1000, insns: [], uplevel: 1, ignorable_patterns: [])
- out, err = eval_with_jit(script, verbose: 1, min_calls: min_calls, max_cache: max_cache)
- success_actual = err.scan(/^#{JIT_SUCCESS_PREFIX}:/).size
- recompile_actual = err.scan(/^#{JIT_RECOMPILE_PREFIX}:/).size
- # Add --mjit-verbose=2 logs for cl.exe because compiler's error message is suppressed
- # for cl.exe with --mjit-verbose=1. See `start_process` in mjit.c.
- if RUBY_PLATFORM.match?(/mswin/) && success_count != success_actual
- out2, err2 = eval_with_jit(script, verbose: 2, min_calls: min_calls, max_cache: max_cache)
- end
-
- # Make sure that the script has insns expected to be tested
- used_insns = method_insns(script)
- insns.each do |insn|
- mark_tested_insn(insn, used_insns: used_insns, uplevel: uplevel + 3)
- end
-
- suffix = "script:\n#{code_block(script)}\nstderr:\n#{code_block(err)}#{(
- "\nstdout(verbose=2 retry):\n#{code_block(out2)}\nstderr(verbose=2 retry):\n#{code_block(err2)}" if out2 || err2
- )}"
- assert_equal(
- success_count, success_actual,
- "Expected #{success_count} times of JIT success, but succeeded #{success_actual} times.\n\n#{suffix}",
- )
- if recompile_count
- assert_equal(
- recompile_count, recompile_actual,
- "Expected #{success_count} times of JIT recompile, but recompiled #{success_actual} times.\n\n#{suffix}",
- )
- end
- if stdout
- assert_equal(stdout, out, "Expected stdout #{out.inspect} to match #{stdout.inspect} with script:\n#{code_block(script)}")
- end
- err_lines = err.lines.reject! do |l|
- l.chomp.empty? || l.match?(/\A#{JIT_SUCCESS_PREFIX}/) || (IGNORABLE_PATTERNS + ignorable_patterns).any? { |pat| pat.match?(l) }
- end
- unless err_lines.empty?
- warn err_lines.join(''), uplevel: uplevel
- end
- end
-
- def mark_tested_insn(insn, used_insns:, uplevel: 1)
- # Currently, this check emits a false-positive warning against opt_regexpmatch2,
- # so the insn is excluded explicitly. See https://bugs.ruby-lang.org/issues/18269
- if !used_insns.include?(insn) && insn != :opt_regexpmatch2
- $stderr.puts
- warn "'#{insn}' insn is not included in the script. Actual insns are: #{used_insns.join(' ')}\n", uplevel: uplevel
- end
- TestMJIT.untested_insns.delete(insn)
- end
-
- # Collect block's insns or defined method's insns, which are expected to be JIT-ed.
- # Note that this intentionally excludes insns in script's toplevel because they are not JIT-ed.
- def method_insns(script)
- insns = []
- RubyVM::InstructionSequence.compile(script).to_a.last.each do |(insn, *args)|
- case insn
- when :send
- insns += collect_insns(args.last)
- when :definemethod, :definesmethod
- insns += collect_insns(args[1])
- when :defineclass
- insns += collect_insns(args[1])
- end
- end
- insns.uniq
- end
-
- # Recursively collect insns in iseq_array
- def collect_insns(iseq_array)
- return [] if iseq_array.nil?
-
- insns = iseq_array.last.select { |x| x.is_a?(Array) }.map(&:first)
- iseq_array.last.each do |(insn, *args)|
- case insn
- when :definemethod, :definesmethod, :send
- insns += collect_insns(args.last)
- end
- end
- insns
- end
-end
diff --git a/test/ruby/test_mjit_debug.rb b/test/ruby/test_mjit_debug.rb
deleted file mode 100644
index 0b50acc68d..0000000000
--- a/test/ruby/test_mjit_debug.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-require_relative 'test_mjit'
-
-return unless defined?(TestMJIT)
-return if ENV.key?('APPVEYOR')
-return if ENV.key?('RUBYCI_NICKNAME')
-return if ENV['RUBY_DEBUG']&.include?('ci') # ci.rvm.jp
-return if /mswin/ =~ RUBY_PLATFORM
-
-class TestMJITDebug < TestMJIT
- @@test_suites.delete TestMJIT if self.respond_to? :on_parallel_worker?
-
- def setup
- super
- # let `#eval_with_jit` use --mjit-debug
- @mjit_debug = true
- end
-end
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 137da09bc3..75d8d909d7 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -253,6 +253,14 @@ class TestModule < Test::Unit::TestCase
assert_operator(Math, :const_defined?, "PI")
assert_not_operator(Math, :const_defined?, :IP)
assert_not_operator(Math, :const_defined?, "IP")
+
+ # Test invalid symbol name
+ # [Bug #20245]
+ EnvUtil.under_gc_stress do
+ assert_raise(EncodingError) do
+ Math.const_defined?("\xC3")
+ end
+ end
end
def each_bad_constants(m, &b)
@@ -1469,7 +1477,7 @@ class TestModule < Test::Unit::TestCase
end
%w(object_id __send__ initialize).each do |n|
- assert_in_out_err([], <<-INPUT, [], %r"warning: undefining `#{n}' may cause serious problems$")
+ assert_in_out_err([], <<-INPUT, [], %r"warning: undefining '#{n}' may cause serious problems$")
$VERBOSE = false
Class.new.instance_eval { undef_method(:#{n}) }
INPUT
@@ -1728,6 +1736,8 @@ class TestModule < Test::Unit::TestCase
assert_equal("TestModule::C\u{df}", c.name, '[ruby-core:24600]')
c = Module.new.module_eval("class X\u{df} < Module; self; end")
assert_match(/::X\u{df}:/, c.new.to_s)
+ ensure
+ Object.send(:remove_const, "C\u{df}")
end
@@ -2350,6 +2360,18 @@ class TestModule < Test::Unit::TestCase
assert_equal(:foo, removed)
end
+ def test_frozen_prepend_remove_method
+ [Module, Class].each do |klass|
+ mod = klass.new do
+ prepend(Module.new)
+ def foo; end
+ end
+ mod.freeze
+ assert_raise(FrozenError, '[Bug #19166]') { mod.send(:remove_method, :foo) }
+ assert_equal([:foo], mod.instance_methods(false))
+ end
+ end
+
def test_prepend_class_ancestors
bug6658 = '[ruby-core:45919]'
m = labeled_module("m")
@@ -2856,6 +2878,7 @@ class TestModule < Test::Unit::TestCase
def test_invalid_attr
%W[
+ foo=
foo?
@foo
@@foo
@@ -3160,6 +3183,7 @@ class TestModule < Test::Unit::TestCase
end
def test_redefinition_mismatch
+ omit "Investigating trunk-rjit failure on ci.rvm.jp" if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
m = Module.new
m.module_eval "A = 1", __FILE__, line = __LINE__
e = assert_raise_with_message(TypeError, /is not a module/) {
@@ -3261,6 +3285,62 @@ class TestModule < Test::Unit::TestCase
assert_match(/::Foo$/, mod.name, '[Bug #14895]')
end
+ def test_iclass_memory_leak
+ # [Bug #19550]
+ assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
+ code = proc do
+ mod = Module.new
+ Class.new do
+ include mod
+ end
+ end
+ 1_000.times(&code)
+ PREP
+ 3_000_000.times(&code)
+ CODE
+ end
+
+ def test_complemented_method_entry_memory_leak
+ # [Bug #19894] [Bug #19896]
+ assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
+ code = proc do
+ $c = Class.new do
+ def foo; end
+ end
+
+ $m = Module.new do
+ refine $c do
+ def foo; end
+ end
+ end
+
+ Class.new do
+ using $m
+
+ def initialize
+ o = $c.new
+ o.method(:foo).unbind
+ end
+ end.new
+ end
+ 1_000.times(&code)
+ PREP
+ 300_000.times(&code)
+ CODE
+ end
+
+ def test_module_clone_memory_leak
+ # [Bug #19901]
+ assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
+ code = proc do
+ Module.new.clone
+ end
+ 1_000.times(&code)
+ PREP
+ 1_000_000.times(&code)
+ CODE
+ end
+
private
def assert_top_method_is_private(method)
@@ -3268,7 +3348,7 @@ class TestModule < Test::Unit::TestCase
methods = singleton_class.private_instance_methods(false)
assert_include(methods, :#{method}, ":#{method} should be private")
- assert_raise_with_message(NoMethodError, "private method `#{method}' called for main:Object") {
+ assert_raise_with_message(NoMethodError, /^private method '#{method}' called for /) {
recv = self
recv.#{method}
}
diff --git a/test/ruby/test_nomethod_error.rb b/test/ruby/test_nomethod_error.rb
index 321b7ccab2..6d413e6391 100644
--- a/test/ruby/test_nomethod_error.rb
+++ b/test/ruby/test_nomethod_error.rb
@@ -85,7 +85,7 @@ class TestNoMethodError < Test::Unit::TestCase
bug3237 = '[ruby-core:29948]'
str = "\u2600"
id = :"\u2604"
- msg = "undefined method `#{id}' for \"#{str}\":String"
+ msg = "undefined method '#{id}' for an instance of String"
assert_raise_with_message(NoMethodError, Regexp.compile(Regexp.quote(msg)), bug3237) do
str.__send__(id)
end
diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb
index 0593cb535d..ab492743f6 100644
--- a/test/ruby/test_numeric.rb
+++ b/test/ruby/test_numeric.rb
@@ -324,6 +324,9 @@ class TestNumeric < Test::Unit::TestCase
e = 1.step(10, {by: "1"})
assert_raise(TypeError) {e.next}
assert_raise(TypeError) {e.size}
+ e = 1.step(to: "10")
+ assert_raise(ArgumentError) {e.next}
+ assert_raise(ArgumentError) {e.size}
assert_equal(bignum*2+1, (-bignum).step(bignum, 1).size)
assert_equal(bignum*2, (-bignum).step(bignum-1, 1).size)
diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb
index 83208bbcdb..37c09596a2 100644
--- a/test/ruby/test_object.rb
+++ b/test/ruby/test_object.rb
@@ -355,6 +355,41 @@ class TestObject < Test::Unit::TestCase
end
end
+ def test_remove_instance_variable_re_embed
+ require "objspace"
+
+ c = Class.new do
+ def a = @a
+
+ def b = @b
+
+ def c = @c
+ end
+
+ o1 = c.new
+ o2 = c.new
+
+ o1.instance_variable_set(:@foo, 5)
+ o1.instance_variable_set(:@a, 0)
+ o1.instance_variable_set(:@b, 1)
+ o1.instance_variable_set(:@c, 2)
+ refute_includes ObjectSpace.dump(o1), '"embedded":true'
+ o1.remove_instance_variable(:@foo)
+ assert_includes ObjectSpace.dump(o1), '"embedded":true'
+
+ o2.instance_variable_set(:@a, 0)
+ o2.instance_variable_set(:@b, 1)
+ o2.instance_variable_set(:@c, 2)
+ assert_includes ObjectSpace.dump(o2), '"embedded":true'
+
+ assert_equal(0, o1.a)
+ assert_equal(1, o1.b)
+ assert_equal(2, o1.c)
+ assert_equal(0, o2.a)
+ assert_equal(1, o2.b)
+ assert_equal(2, o2.c)
+ end
+
def test_convert_string
o = Object.new
def o.to_s; 1; end
@@ -422,6 +457,18 @@ class TestObject < Test::Unit::TestCase
assert_equal(1+3+5+7+9, n)
end
+ def test_max_shape_variation_with_performance_warnings
+ assert_in_out_err([], <<-INPUT, %w(), /The class Foo reached 8 shape variations, instance variables accesses will be slower and memory usage increased/)
+ $VERBOSE = false
+ Warning[:performance] = true
+
+ class Foo; end
+ 10.times do |i|
+ Foo.new.instance_variable_set(:"@a\#{i}", nil)
+ end
+ INPUT
+ end
+
def test_redefine_method_under_verbose
assert_in_out_err([], <<-INPUT, %w(2), /warning: method redefined; discarding old foo$/)
$VERBOSE = true
@@ -433,12 +480,12 @@ class TestObject < Test::Unit::TestCase
end
def test_redefine_method_which_may_case_serious_problem
- assert_in_out_err([], <<-INPUT, [], %r"warning: redefining `object_id' may cause serious problems$")
+ assert_in_out_err([], <<-INPUT, [], %r"warning: redefining 'object_id' may cause serious problems$")
$VERBOSE = false
def (Object.new).object_id; end
INPUT
- assert_in_out_err([], <<-INPUT, [], %r"warning: redefining `__send__' may cause serious problems$")
+ assert_in_out_err([], <<-INPUT, [], %r"warning: redefining '__send__' may cause serious problems$")
$VERBOSE = false
def (Object.new).__send__; end
INPUT
@@ -481,7 +528,7 @@ class TestObject < Test::Unit::TestCase
assert_raise(NoMethodError, bug2202) {o2.meth2}
%w(object_id __send__ initialize).each do |m|
- assert_in_out_err([], <<-INPUT, %w(:ok), %r"warning: removing `#{m}' may cause serious problems$")
+ assert_in_out_err([], <<-INPUT, %w(:ok), %r"warning: removing '#{m}' may cause serious problems$")
$VERBOSE = false
begin
Class.new.instance_eval { remove_method(:#{m}) }
@@ -853,6 +900,15 @@ class TestObject < Test::Unit::TestCase
x.instance_variable_set(:@bar, 42)
assert_match(/\A#<Object:0x\h+ (?:@foo="value", @bar=42|@bar=42, @foo="value")>\z/, x.inspect)
+ # Bug: [ruby-core:19167]
+ x = Object.new
+ x.instance_variable_set(:@foo, NilClass)
+ assert_match(/\A#<Object:0x\h+ @foo=NilClass>\z/, x.inspect)
+ x.instance_variable_set(:@foo, TrueClass)
+ assert_match(/\A#<Object:0x\h+ @foo=TrueClass>\z/, x.inspect)
+ x.instance_variable_set(:@foo, FalseClass)
+ assert_match(/\A#<Object:0x\h+ @foo=FalseClass>\z/, x.inspect)
+
# #inspect does not call #to_s anymore
feature6130 = '[ruby-core:43238]'
x = Object.new
@@ -925,6 +981,19 @@ class TestObject < Test::Unit::TestCase
end
end
+ def test_singleton_class_freeze
+ x = Object.new
+ xs = x.singleton_class
+ x.freeze
+ assert_predicate(xs, :frozen?)
+
+ y = Object.new
+ ys = y.singleton_class
+ ys.prepend(Module.new)
+ y.freeze
+ assert_predicate(ys, :frozen?, '[Bug #19169]')
+ end
+
def test_redef_method_missing
bug5473 = '[ruby-core:40287]'
['ArgumentError.new("bug5473")', 'ArgumentError, "bug5473"', '"bug5473"'].each do |code|
@@ -993,4 +1062,13 @@ class TestObject < Test::Unit::TestCase
end
EOS
end
+
+ def test_frozen_inspect
+ obj = Object.new
+ obj.instance_variable_set(:@a, "a")
+ ins = obj.inspect
+ obj.freeze
+
+ assert_equal(ins, obj.inspect)
+ end
end
diff --git a/test/ruby/test_objectspace.rb b/test/ruby/test_objectspace.rb
index 3c912fe300..1c97bd517e 100644
--- a/test/ruby/test_objectspace.rb
+++ b/test/ruby/test_objectspace.rb
@@ -66,8 +66,11 @@ End
end
def test_id2ref_invalid_symbol_id
+ # RB_STATIC_SYM_P checks for static symbols by checking that the bottom
+ # 8 bits of the object is equal to RUBY_SYMBOL_FLAG, so we need to make
+ # sure that the bottom 8 bits remain unchanged.
msg = /is not symbol id value/
- assert_raise_with_message(RangeError, msg) { ObjectSpace._id2ref(:a.object_id + 40) }
+ assert_raise_with_message(RangeError, msg) { ObjectSpace._id2ref(:a.object_id + 256) }
end
def test_count_objects
diff --git a/test/ruby/test_optimization.rb b/test/ruby/test_optimization.rb
index 80c3c3860b..a7a0582dbb 100644
--- a/test/ruby/test_optimization.rb
+++ b/test/ruby/test_optimization.rb
@@ -16,6 +16,18 @@ class TestRubyOptimization < Test::Unit::TestCase
end;
end
+ def assert_performance_warning(klass, method)
+ assert_in_out_err([], "#{<<-"begin;"}\n#{<<~"end;"}", [], ["-:4: warning: Redefining '#{klass}##{method}' disables interpreter and JIT optimizations"])
+ begin;
+ Warning[:performance] = true
+ class #{klass}
+ undef #{method}
+ def #{method}
+ end
+ end
+ end;
+ end
+
def disasm(name)
RubyVM::InstructionSequence.of(method(name)).disasm
end
@@ -23,102 +35,122 @@ class TestRubyOptimization < Test::Unit::TestCase
def test_fixnum_plus
assert_equal 21, 10 + 11
assert_redefine_method('Integer', '+', 'assert_equal 11, 10 + 11')
+ assert_performance_warning('Integer', '+')
end
def test_fixnum_minus
assert_equal 5, 8 - 3
assert_redefine_method('Integer', '-', 'assert_equal 3, 8 - 3')
+ assert_performance_warning('Integer', '-')
end
def test_fixnum_mul
assert_equal 15, 3 * 5
assert_redefine_method('Integer', '*', 'assert_equal 5, 3 * 5')
+ assert_performance_warning('Integer', '*')
end
def test_fixnum_div
assert_equal 3, 15 / 5
assert_redefine_method('Integer', '/', 'assert_equal 5, 15 / 5')
+ assert_performance_warning('Integer', '/')
end
def test_fixnum_mod
assert_equal 1, 8 % 7
assert_redefine_method('Integer', '%', 'assert_equal 7, 8 % 7')
+ assert_performance_warning('Integer', '%')
end
def test_fixnum_lt
assert_equal true, 1 < 2
assert_redefine_method('Integer', '<', 'assert_equal 2, 1 < 2')
+ assert_performance_warning('Integer', '<')
end
def test_fixnum_le
assert_equal true, 1 <= 2
assert_redefine_method('Integer', '<=', 'assert_equal 2, 1 <= 2')
+ assert_performance_warning('Integer', '<=')
end
def test_fixnum_gt
assert_equal false, 1 > 2
assert_redefine_method('Integer', '>', 'assert_equal 2, 1 > 2')
+ assert_performance_warning('Integer', '>')
end
def test_fixnum_ge
assert_equal false, 1 >= 2
assert_redefine_method('Integer', '>=', 'assert_equal 2, 1 >= 2')
+ assert_performance_warning('Integer', '>=')
end
def test_float_plus
assert_equal 4.0, 2.0 + 2.0
assert_redefine_method('Float', '+', 'assert_equal 2.0, 2.0 + 2.0')
+ assert_performance_warning('Float', '+')
end
def test_float_minus
assert_equal 4.0, 2.0 + 2.0
- assert_redefine_method('Float', '+', 'assert_equal 2.0, 2.0 + 2.0')
+ assert_redefine_method('Float', '-', 'assert_equal 2.0, 4.0 - 2.0')
+ assert_performance_warning('Float', '-')
end
def test_float_mul
assert_equal 29.25, 4.5 * 6.5
assert_redefine_method('Float', '*', 'assert_equal 6.5, 4.5 * 6.5')
+ assert_performance_warning('Float', '*')
end
def test_float_div
assert_in_delta 0.63063063063063063, 4.2 / 6.66
assert_redefine_method('Float', '/', 'assert_equal 6.66, 4.2 / 6.66', "[Bug #9238]")
+ assert_performance_warning('Float', '/')
end
def test_float_lt
assert_equal true, 1.1 < 2.2
assert_redefine_method('Float', '<', 'assert_equal 2.2, 1.1 < 2.2')
+ assert_performance_warning('Float', '<')
end
def test_float_le
assert_equal true, 1.1 <= 2.2
assert_redefine_method('Float', '<=', 'assert_equal 2.2, 1.1 <= 2.2')
+ assert_performance_warning('Float', '<=')
end
def test_float_gt
assert_equal false, 1.1 > 2.2
assert_redefine_method('Float', '>', 'assert_equal 2.2, 1.1 > 2.2')
+ assert_performance_warning('Float', '>')
end
def test_float_ge
assert_equal false, 1.1 >= 2.2
assert_redefine_method('Float', '>=', 'assert_equal 2.2, 1.1 >= 2.2')
+ assert_performance_warning('Float', '>=')
end
def test_string_length
assert_equal 6, "string".length
assert_redefine_method('String', 'length', 'assert_nil "string".length')
+ assert_performance_warning('String', 'length')
end
def test_string_size
assert_equal 6, "string".size
assert_redefine_method('String', 'size', 'assert_nil "string".size')
+ assert_performance_warning('String', 'size')
end
def test_string_empty?
assert_equal true, "".empty?
assert_equal false, "string".empty?
assert_redefine_method('String', 'empty?', 'assert_nil "string".empty?')
+ assert_performance_warning('String', 'empty?')
end
def test_string_plus
@@ -127,39 +159,50 @@ class TestRubyOptimization < Test::Unit::TestCase
assert_equal "x", "" + "x"
assert_equal "ab", "a" + "b"
assert_redefine_method('String', '+', 'assert_equal "b", "a" + "b"')
+ assert_performance_warning('String', '+')
end
def test_string_succ
assert_equal 'b', 'a'.succ
assert_equal 'B', 'A'.succ
+ assert_performance_warning('String', 'succ')
end
def test_string_format
assert_equal '2', '%d' % 2
assert_redefine_method('String', '%', 'assert_equal 2, "%d" % 2')
+ assert_performance_warning('String', '%')
end
def test_string_freeze
assert_equal "foo", "foo".freeze
assert_equal "foo".freeze.object_id, "foo".freeze.object_id
assert_redefine_method('String', 'freeze', 'assert_nil "foo".freeze')
+ assert_performance_warning('String', 'freeze')
end
def test_string_uminus
assert_same "foo".freeze, -"foo"
assert_redefine_method('String', '-@', 'assert_nil(-"foo")')
+ assert_performance_warning('String', '-@')
end
def test_array_min
assert_equal 1, [1, 2, 4].min
assert_redefine_method('Array', 'min', 'assert_nil([1, 2, 4].min)')
assert_redefine_method('Array', 'min', 'assert_nil([1 + 0, 2, 4].min)')
+ assert_performance_warning('Array', 'min')
end
def test_array_max
assert_equal 4, [1, 2, 4].max
assert_redefine_method('Array', 'max', 'assert_nil([1, 2, 4].max)')
assert_redefine_method('Array', 'max', 'assert_nil([1 + 0, 2, 4].max)')
+ assert_performance_warning('Array', 'max')
+ end
+
+ def test_array_hash
+ assert_performance_warning('Array', 'hash')
end
def test_trace_optimized_methods
@@ -235,6 +278,8 @@ class TestRubyOptimization < Test::Unit::TestCase
assert_equal :b, (b #{m} "b").to_sym
end
end
+
+ assert_performance_warning('String', '==')
end
def test_string_ltlt
@@ -243,50 +288,59 @@ class TestRubyOptimization < Test::Unit::TestCase
assert_equal "x", "" << "x"
assert_equal "ab", "a" << "b"
assert_redefine_method('String', '<<', 'assert_equal "b", "a" << "b"')
+ assert_performance_warning('String', '<<')
end
def test_fixnum_and
assert_equal 1, 1&3
assert_redefine_method('Integer', '&', 'assert_equal 3, 1&3')
+ assert_performance_warning('Integer', '&')
end
def test_fixnum_or
assert_equal 3, 1|3
assert_redefine_method('Integer', '|', 'assert_equal 1, 3|1')
+ assert_performance_warning('Integer', '|')
end
def test_array_plus
assert_equal [1,2], [1]+[2]
assert_redefine_method('Array', '+', 'assert_equal [2], [1]+[2]')
+ assert_performance_warning('Array', '+')
end
def test_array_minus
assert_equal [2], [1,2] - [1]
assert_redefine_method('Array', '-', 'assert_equal [1], [1,2]-[1]')
+ assert_performance_warning('Array', '-')
end
def test_array_length
assert_equal 0, [].length
assert_equal 3, [1,2,3].length
assert_redefine_method('Array', 'length', 'assert_nil([].length); assert_nil([1,2,3].length)')
+ assert_performance_warning('Array', 'length')
end
def test_array_empty?
assert_equal true, [].empty?
assert_equal false, [1,2,3].empty?
assert_redefine_method('Array', 'empty?', 'assert_nil([].empty?); assert_nil([1,2,3].empty?)')
+ assert_performance_warning('Array', 'empty?')
end
def test_hash_length
assert_equal 0, {}.length
assert_equal 1, {1=>1}.length
assert_redefine_method('Hash', 'length', 'assert_nil({}.length); assert_nil({1=>1}.length)')
+ assert_performance_warning('Hash', 'length')
end
def test_hash_empty?
assert_equal true, {}.empty?
assert_equal false, {1=>1}.empty?
assert_redefine_method('Hash', 'empty?', 'assert_nil({}.empty?); assert_nil({1=>1}.empty?)')
+ assert_performance_warning('Hash', 'empty?')
end
def test_hash_aref_with
@@ -297,6 +351,7 @@ class TestRubyOptimization < Test::Unit::TestCase
h = { "foo" => 1 }
assert_equal "foo", h["foo"]
end;
+ assert_performance_warning('Hash', '[]')
end
def test_hash_aset_with
@@ -308,6 +363,7 @@ class TestRubyOptimization < Test::Unit::TestCase
assert_equal 1, h["foo"] = 1, "assignment always returns value set"
assert_nil h["foo"]
end;
+ assert_performance_warning('Hash', '[]=')
end
class MyObj
@@ -437,6 +493,31 @@ class TestRubyOptimization < Test::Unit::TestCase
message(bug12565) {disasm(:add_one_and_two)})
end
+ def test_c_func_with_sp_offset_under_tailcall
+ tailcall("#{<<-"begin;"}\n#{<<~"end;"}")
+ begin;
+ def calc_one_plus_two
+ 1 + 2.abs
+ end
+
+ def one_plus_two
+ calc_one_plus_two
+ end
+ end;
+ assert_equal(3, one_plus_two)
+ end
+
+ def test_tailcall_and_post_arg
+ tailcall(<<~RUBY)
+ def ret_const = :ok
+
+ def post_arg(_a = 1, _b) = ret_const
+ RUBY
+
+ # YJIT probably uses a fallback on the call to post_arg
+ assert_equal(:ok, post_arg(0))
+ end
+
def test_tailcall_interrupted_by_sigint
bug12576 = 'ruby-core:76327'
script = "#{<<-"begin;"}\n#{<<~'end;'}"
@@ -510,7 +591,7 @@ class TestRubyOptimization < Test::Unit::TestCase
end
def test_tailcall_not_to_grow_stack
- omit 'currently JIT-ed code always creates a new stack frame' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ omit 'currently JIT-ed code always creates a new stack frame' if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
bug16161 = '[ruby-core:94881]'
tailcall("#{<<-"begin;"}\n#{<<~"end;"}")
@@ -552,7 +633,7 @@ class TestRubyOptimization < Test::Unit::TestCase
begin;
class String
undef freeze
- def freeze
+ def freeze(&)
block_given?
end
end
@@ -614,6 +695,7 @@ class TestRubyOptimization < Test::Unit::TestCase
[ nil, true, false, 0.1, :sym, 'str', 0xffffffffffffffff ].each do |v|
k = v.class.to_s
assert_redefine_method(k, '===', "assert_equal(#{v.inspect} === 0, 0)")
+ assert_performance_warning(k, '===')
end
end
diff --git a/test/ruby/test_pack.rb b/test/ruby/test_pack.rb
index 9738f82b7e..1ce46e8916 100644
--- a/test/ruby/test_pack.rb
+++ b/test/ruby/test_pack.rb
@@ -1,25 +1,44 @@
# coding: US-ASCII
# frozen_string_literal: false
require 'test/unit'
+require 'rbconfig'
+require 'rbconfig/sizeof'
class TestPack < Test::Unit::TestCase
+ # Note: the size of intptr_t and uintptr_t should be equal.
+ J_SIZE = RbConfig::SIZEOF['uintptr_t']
+
def test_pack
- $format = "c2x5CCxsdils_l_a6";
+ format = "c2x5CCxsdils_l_a6";
# Need the expression in here to force ary[5] to be numeric. This avoids
# test2 failing because ary2 goes str->numeric->str and ary does not.
ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,-32767,-123456,"abcdef"]
- $x = ary.pack($format)
- ary2 = $x.unpack($format)
+ x = ary.pack(format)
+ ary2 = x.unpack(format)
assert_equal(ary.length, ary2.length)
assert_equal(ary.join(':'), ary2.join(':'))
- assert_match(/def/, $x)
+ assert_match(/def/, x)
+
+ x = [-1073741825]
+ assert_equal(x, x.pack("q").unpack("q"))
+
+ x = [-1]
+ assert_equal(x, x.pack("l").unpack("l"))
+ end
+
+ def test_ascii_incompatible
+ assert_raise(Encoding::CompatibilityError) do
+ ["foo"].pack("u".encode("UTF-32BE"))
+ end
- $x = [-1073741825]
- assert_equal($x, $x.pack("q").unpack("q"))
+ assert_raise(Encoding::CompatibilityError) do
+ "foo".unpack("C".encode("UTF-32BE"))
+ end
- $x = [-1]
- assert_equal($x, $x.pack("l").unpack("l"))
+ assert_raise(Encoding::CompatibilityError) do
+ "foo".unpack1("C".encode("UTF-32BE"))
+ end
end
def test_pack_n
@@ -79,11 +98,11 @@ class TestPack < Test::Unit::TestCase
assert_equal("\x01\x02\x03\x04", [0x01020304].pack("L"+mod))
assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("q"+mod))
assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("Q"+mod))
- psize = [nil].pack('p').bytesize
- if psize == 4
+ case J_SIZE
+ when 4
assert_equal("\x01\x02\x03\x04", [0x01020304].pack("j"+mod))
assert_equal("\x01\x02\x03\x04", [0x01020304].pack("J"+mod))
- elsif psize == 8
+ when 8
assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("j"+mod))
assert_equal("\x01\x02\x03\x04\x05\x06\x07\x08", [0x0102030405060708].pack("J"+mod))
end
@@ -95,10 +114,11 @@ class TestPack < Test::Unit::TestCase
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("I!"+mod))
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("l!"+mod))
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("L!"+mod))
- if psize == 4
+ case J_SIZE
+ when 4
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("j!"+mod))
assert_match(/\A\x00*\x01\x02\x03\x04\z/, [0x01020304].pack("J!"+mod))
- elsif psize == 8
+ when 8
assert_match(/\A\x00*\x01\x02\x03\x04\x05\x06\x07\x08\z/, [0x0102030405060708].pack("j!"+mod))
assert_match(/\A\x00*\x01\x02\x03\x04\x05\x06\x07\x08\z/, [0x0102030405060708].pack("J!"+mod))
end
@@ -127,11 +147,11 @@ class TestPack < Test::Unit::TestCase
assert_equal("\x04\x03\x02\x01", [0x01020304].pack("L"+mod))
assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("q"+mod))
assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("Q"+mod))
- psize = [nil].pack('p').bytesize
- if psize == 4
+ case J_SIZE
+ when 4
assert_equal("\x04\x03\x02\x01", [0x01020304].pack("j"+mod))
assert_equal("\x04\x03\x02\x01", [0x01020304].pack("J"+mod))
- elsif psize == 8
+ when 8
assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("j"+mod))
assert_equal("\x08\x07\x06\x05\x04\x03\x02\x01", [0x0102030405060708].pack("J"+mod))
end
@@ -143,10 +163,11 @@ class TestPack < Test::Unit::TestCase
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("I!"+mod))
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("l!"+mod))
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("L!"+mod))
- if psize == 4
+ case J_SIZE
+ when 4
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("j!"+mod))
assert_match(/\A\x04\x03\x02\x01\x00*\z/, [0x01020304].pack("J!"+mod))
- elsif psize == 8
+ when 8
assert_match(/\A\x08\x07\x06\x05\x04\x03\x02\x01\x00*\z/, [0x0102030405060708].pack("j!"+mod))
assert_match(/\A\x08\x07\x06\x05\x04\x03\x02\x01\x00*\z/, [0x0102030405060708].pack("J!"+mod))
end
@@ -182,8 +203,8 @@ class TestPack < Test::Unit::TestCase
end
def test_integer_endian_explicit
- _integer_big_endian('>')
- _integer_little_endian('<')
+ _integer_big_endian('>')
+ _integer_little_endian('<')
end
def test_pack_U
@@ -428,7 +449,6 @@ class TestPack < Test::Unit::TestCase
assert_operator(4, :<=, [1].pack("L!").bytesize)
end
- require 'rbconfig'
def test_pack_unpack_qQ
s1 = [578437695752307201, -506097522914230529].pack("q*")
s2 = [578437695752307201, 17940646550795321087].pack("Q*")
@@ -451,10 +471,8 @@ class TestPack < Test::Unit::TestCase
end if RbConfig::CONFIG['HAVE_LONG_LONG']
def test_pack_unpack_jJ
- # Note: we assume that the size of intptr_t and uintptr_t equals to the size
- # of real pointer.
- psize = [nil].pack("p").bytesize
- if psize == 4
+ case J_SIZE
+ when 4
s1 = [67305985, -50462977].pack("j*")
s2 = [67305985, 4244504319].pack("J*")
assert_equal(s1, s2)
@@ -468,7 +486,7 @@ class TestPack < Test::Unit::TestCase
assert_equal(4, [1].pack("j").bytesize)
assert_equal(4, [1].pack("J").bytesize)
- elsif psize == 8
+ when 8
s1 = [578437695752307201, -506097522914230529].pack("j*")
s2 = [578437695752307201, 17940646550795321087].pack("J*")
assert_equal(s1, s2)
@@ -763,58 +781,32 @@ EXPECTED
end
def test_pack_garbage
- verbose = $VERBOSE
- $VERBOSE = false
-
- assert_silent do
- assert_equal "\000", [0].pack("*U")
- end
-
- $VERBOSE = true
-
- _, err = capture_output do
+ assert_raise(ArgumentError, %r%unknown pack directive '\*' in '\*U'$%) do
assert_equal "\000", [0].pack("*U")
end
-
- assert_match %r%unknown pack directive '\*' in '\*U'$%, err
- ensure
- $VERBOSE = verbose
end
def test_unpack_garbage
- verbose = $VERBOSE
- $VERBOSE = false
-
- assert_silent do
+ assert_raise(ArgumentError, %r%unknown unpack directive '\*' in '\*U'$%) do
assert_equal [0], "\000".unpack("*U")
end
-
- $VERBOSE = true
-
- _, err = capture_output do
- assert_equal [0], "\000".unpack("*U")
- end
-
- assert_match %r%unknown unpack directive '\*' in '\*U'$%, err
- ensure
- $VERBOSE = verbose
end
def test_invalid_warning
- assert_warning(/unknown pack directive ',' in ','/) {
+ assert_raise(ArgumentError, /unknown pack directive ',' in ','/) {
[].pack(",")
}
- assert_warning(/\A[ -~]+\Z/) {
+ assert_raise(ArgumentError, /\A[ -~]+\Z/) {
[].pack("\x7f")
}
- assert_warning(/\A(.* in '\u{3042}'\n)+\z/) {
+ assert_raise(ArgumentError, /\A(.* in '\u{3042}'\n)+\z/) {
[].pack("\u{3042}")
}
- assert_warning(/\A.* in '.*U'\Z/) {
+ assert_raise(ArgumentError, /\A.* in '.*U'\Z/) {
assert_equal "\000", [0].pack("\0U")
}
- assert_warning(/\A.* in '.*U'\Z/) {
+ assert_raise(ArgumentError, /\A.* in '.*U'\Z/) {
"\000".unpack("\0U")
}
end
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index 4488ea620e..fe649cddb9 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -14,6 +14,7 @@ class TestParse < Test::Unit::TestCase
def test_error_line
assert_syntax_error('------,,', /\n\z/, 'Message to pipe should end with a newline')
+ assert_syntax_error("{hello\n world}", /hello/)
end
def test_else_without_rescue
@@ -377,10 +378,10 @@ class TestParse < Test::Unit::TestCase
def assert_disallowed_variable(type, noname, invalid)
noname.each do |name|
- assert_syntax_error("proc{a = #{name} }", "`#{noname[0]}' without identifiers is not allowed as #{type} variable name")
+ assert_syntax_error("proc{a = #{name} }", "'#{noname[0]}' without identifiers is not allowed as #{type} variable name")
end
invalid.each do |name|
- assert_syntax_error("proc {a = #{name} }", "`#{name}' is not allowed as #{type} variable name")
+ assert_syntax_error("proc {a = #{name} }", "'#{name}' is not allowed as #{type} variable name")
end
end
@@ -452,10 +453,44 @@ class TestParse < Test::Unit::TestCase
end
def test_define_singleton_error
- assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /singleton method for literals/) do
- begin;
- def ("foo").foo; end
- end;
+ msg = /singleton method for literals/
+ assert_parse_error(%q[def ("foo").foo; end], msg)
+ assert_parse_error(%q[def (1).foo; end], msg)
+ assert_parse_error(%q[def ((1;1)).foo; end], msg)
+ assert_parse_error(%q[def ((;1)).foo; end], msg)
+ assert_parse_error(%q[def ((1+1;1)).foo; end], msg)
+ assert_parse_error(%q[def ((%s();1)).foo; end], msg)
+ assert_parse_error(%q[def ((%w();1)).foo; end], msg)
+ assert_parse_error(%q[def ("#{42}").foo; end], msg)
+ assert_parse_error(%q[def (:"#{42}").foo; end], msg)
+ end
+
+ def test_flip_flop
+ all_assertions_foreach(nil,
+ ['(cond1..cond2)', true],
+ ['((cond1..cond2))', true],
+
+ # '(;;;cond1..cond2)', # don't care
+
+ '(1; cond1..cond2)',
+ '(%s(); cond1..cond2)',
+ '(%w(); cond1..cond2)',
+ '(1; (2; (3; 4; cond1..cond2)))',
+ '(1+1; cond1..cond2)',
+ ) do |code, pass|
+ code = code.sub("cond1", "n==4").sub("cond2", "n==5")
+ if pass
+ assert_equal([4,5], eval("(1..9).select {|n| true if #{code}}"))
+ else
+ assert_raise_with_message(ArgumentError, /bad value for range/, code) {
+ verbose_bak, $VERBOSE = $VERBOSE, nil # disable "warning: possibly useless use of a literal in void context"
+ begin
+ eval("[4].each {|n| true if #{code}}")
+ ensure
+ $VERBOSE = verbose_bak
+ end
+ }
+ end
end
end
@@ -463,6 +498,10 @@ class TestParse < Test::Unit::TestCase
t = Object.new
a = []
blk = proc {|x| a << x }
+
+ # Prevent an "assigned but unused variable" warning
+ _ = blk
+
def t.[](_)
yield(:aref)
nil
@@ -472,16 +511,16 @@ class TestParse < Test::Unit::TestCase
end
def t.dummy(_)
end
- eval <<-END, nil, __FILE__, __LINE__+1
+
+ assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /block arg given in index/)
+ begin;
t[42, &blk] ||= 42
- END
- assert_equal([:aref, :aset], a)
- a.clear
- eval <<-END, nil, __FILE__, __LINE__+1
- t[42, &blk] ||= t.dummy 42 # command_asgn test
- END
- assert_equal([:aref, :aset], a)
- blk
+ end;
+
+ assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /block arg given in index/)
+ begin;
+ t[42, &blk] ||= t.dummy 42 # command_asgn test
+ end;
end
def test_backquote
@@ -492,7 +531,7 @@ class TestParse < Test::Unit::TestCase
def t.`(x); "foo" + x + "bar"; end
END
end
- a = b = nil
+ a = b = c = nil
assert_nothing_raised do
eval <<-END, nil, __FILE__, __LINE__+1
a = t.` "zzz"
@@ -500,10 +539,12 @@ class TestParse < Test::Unit::TestCase
END
t.instance_eval <<-END, __FILE__, __LINE__+1
b = `zzz`
+ c = %x(ccc)
END
end
assert_equal("foozzzbar", a)
assert_equal("foozzzbar", b)
+ assert_equal("foocccbar", c)
end
def test_carrige_return
@@ -577,6 +618,10 @@ class TestParse < Test::Unit::TestCase
assert_equal(' ^~~~~'"\n", e.message.lines.last)
e = assert_syntax_error('"\M-\U0000"', 'Invalid escape character syntax')
assert_equal(' ^~~~~'"\n", 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_not_include(e.message, "invalid multibyte char")
end
def test_question
@@ -607,6 +652,8 @@ class TestParse < Test::Unit::TestCase
assert_syntax_error("?\\M-\x01", 'Invalid escape character syntax')
assert_syntax_error("?\\M-\\C-\x01", 'Invalid escape character syntax')
assert_syntax_error("?\\C-\\M-\x01", 'Invalid escape character syntax')
+
+ assert_equal("\xff", eval("# encoding: ascii-8bit\n""?\\\xFF"))
end
def test_percent
@@ -640,6 +687,7 @@ class TestParse < Test::Unit::TestCase
assert_syntax_error(':@@1', /is not allowed/)
assert_syntax_error(':@', /is not allowed/)
assert_syntax_error(':@1', /is not allowed/)
+ assert_syntax_error(':$01234', /is not allowed/)
end
def test_parse_string
@@ -680,6 +728,16 @@ FOO
eval "x = <<""FOO\r\n1\r\nFOO"
end
assert_equal("1\n", x)
+
+ assert_nothing_raised do
+ x = eval "<<' FOO'\n""[Bug #19539]\n"" FOO\n"
+ end
+ assert_equal("[Bug #19539]\n", x)
+
+ assert_nothing_raised do
+ x = eval "<<-' FOO'\n""[Bug #19539]\n"" FOO\n"
+ end
+ assert_equal("[Bug #19539]\n", x)
end
def test_magic_comment
@@ -715,6 +773,54 @@ x = __ENCODING__
END
end
assert_equal(__ENCODING__, x)
+
+ assert_raise(ArgumentError) do
+ EnvUtil.with_default_external(Encoding::US_ASCII) {eval <<-END, nil, __FILE__, __LINE__+1}
+# coding = external
+x = __ENCODING__
+ END
+ end
+
+ assert_raise(ArgumentError) do
+ EnvUtil.with_default_internal(Encoding::US_ASCII) {eval <<-END, nil, __FILE__, __LINE__+1}
+# coding = internal
+x = __ENCODING__
+ END
+ end
+
+ assert_raise(ArgumentError) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+# coding = filesystem
+x = __ENCODING__
+ END
+ end
+
+ assert_raise(ArgumentError) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+# coding = locale
+x = __ENCODING__
+ END
+ end
+
+ e = assert_raise(ArgumentError) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+# coding: foo
+ END
+ end
+
+ message = e.message.gsub(/\033\[.*?m/, "")
+ assert_include(message, "# coding: foo\n")
+ assert_include(message, " ^")
+
+ e = assert_raise(ArgumentError) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+# coding = foo
+ END
+ end
+
+ message = e.message.gsub(/\033\[.*?m/, "")
+ assert_include(message, "# coding = foo\n")
+ assert_include(message, " ^")
end
def test_utf8_bom
@@ -758,7 +864,7 @@ x = __ENCODING__
def test_float
assert_predicate(assert_warning(/out of range/) {eval("1e10000")}, :infinite?)
- assert_syntax_error('1_E', /trailing `_'/)
+ assert_syntax_error('1_E', /trailing '_'/)
assert_syntax_error('1E1E1', /unexpected constant/)
end
@@ -786,7 +892,7 @@ x = __ENCODING__
def test_invalid_char
bug10117 = '[ruby-core:64243] [Bug #10117]'
- invalid_char = /Invalid char `\\x01'/
+ invalid_char = /Invalid char '\\x01'/
x = 1
assert_in_out_err(%W"-e \x01x", "", [], invalid_char, bug10117)
assert_syntax_error("\x01x", invalid_char, bug10117)
@@ -820,24 +926,9 @@ x = __ENCODING__
assert_syntax_error("$& = 1", /Can't set variable/)
end
- def test_arg_concat
- o = Object.new
- class << o; self; end.instance_eval do
- define_method(:[]=) {|*r, &b| b.call(r) }
- end
- r = nil
- assert_nothing_raised do
- eval <<-END, nil, __FILE__, __LINE__+1
- o[&proc{|x| r = x }] = 1
- END
- end
- assert_equal([1], r)
- end
-
def test_void_expr_stmts_value
x = 1
useless_use = /useless use/
- unused = /unused/
assert_nil assert_warning(useless_use) {eval("x; nil")}
assert_nil assert_warning(useless_use) {eval("1+1; nil")}
assert_nil assert_warning('') {eval("1.+(1); nil")}
@@ -845,10 +936,10 @@ x = __ENCODING__
assert_nil assert_warning(useless_use) {eval("::TestParse; nil")}
assert_nil assert_warning(useless_use) {eval("x..x; nil")}
assert_nil assert_warning(useless_use) {eval("x...x; nil")}
- assert_nil assert_warning(unused) {eval("self; nil")}
- assert_nil assert_warning(unused) {eval("nil; nil")}
- assert_nil assert_warning(unused) {eval("true; nil")}
- assert_nil assert_warning(unused) {eval("false; nil")}
+ assert_nil assert_warning(useless_use) {eval("self; nil")}
+ assert_nil assert_warning(useless_use) {eval("nil; nil")}
+ assert_nil assert_warning(useless_use) {eval("true; nil")}
+ assert_nil assert_warning(useless_use) {eval("false; nil")}
assert_nil assert_warning(useless_use) {eval("defined?(1); nil")}
assert_equal 1, x
@@ -856,13 +947,15 @@ x = __ENCODING__
end
def test_assign_in_conditional
- assert_warning(/`= literal' in conditional/) do
+ # multiple assignment
+ assert_warning(/'= literal' in conditional/) do
eval <<-END, nil, __FILE__, __LINE__+1
(x, y = 1, 2) ? 1 : 2
END
end
- assert_warning(/`= literal' in conditional/) do
+ # instance variable assignment
+ assert_warning(/'= literal' in conditional/) do
eval <<-END, nil, __FILE__, __LINE__+1
if @x = true
1
@@ -871,6 +964,71 @@ x = __ENCODING__
end
END
end
+
+ # local variable assignment
+ assert_warning(/'= literal' in conditional/) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+ def m
+ if x = true
+ 1
+ else
+ 2
+ end
+ end
+ END
+ end
+
+ # global variable assignment
+ assert_separately([], <<-RUBY)
+ assert_warning(/'= literal' in conditional/) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+ if $x = true
+ 1
+ else
+ 2
+ end
+ END
+ end
+ RUBY
+
+ # dynamic variable assignment
+ assert_warning(/'= literal' in conditional/) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+ y = 1
+
+ 1.times do
+ if y = true
+ 1
+ else
+ 2
+ end
+ end
+ END
+ end
+
+ # class variable assignment
+ assert_warning(/'= literal' in conditional/) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+ c = Class.new
+ class << c
+ if @@a = 1
+ end
+ end
+ END
+ end
+
+ # constant declaration
+ assert_separately([], <<-RUBY)
+ assert_warning(/'= literal' in conditional/) do
+ eval <<-END, nil, __FILE__, __LINE__+1
+ if Const = true
+ 1
+ else
+ 2
+ end
+ END
+ end
+ RUBY
end
def test_literal_in_conditional
@@ -947,6 +1105,20 @@ x = __ENCODING__
assert_warning('') {o.instance_eval("def marg2((a)); nil; end")}
end
+ def test_parsing_begin_statement_inside_method_definition
+ assert_equal :bug_20234, eval("def (begin;end).bug_20234; end")
+ NilClass.remove_method(:bug_20234)
+ assert_equal :bug_20234, eval("def (begin;rescue;end).bug_20234; end")
+ NilClass.remove_method(:bug_20234)
+ assert_equal :bug_20234, eval("def (begin;ensure;end).bug_20234; end")
+ NilClass.remove_method(:bug_20234)
+ assert_equal :bug_20234, eval("def (begin;rescue;else;end).bug_20234; end")
+ NilClass.remove_method(:bug_20234)
+
+ assert_raise(SyntaxError) { eval("def (begin;else;end).bug_20234; end") }
+ assert_raise(SyntaxError) { eval("def (begin;ensure;else;end).bug_20234; end") }
+ end
+
def test_named_capture_conflict
a = 1
assert_warning('') {eval("a = 1; /(?<a>)/ =~ ''")}
@@ -954,6 +1126,30 @@ x = __ENCODING__
assert_warning('') {eval("#{a} = 1; /(?<#{a}>)/ =~ ''")}
end
+ def test_named_capture_in_block
+ all_assertions_foreach(nil,
+ '(/(?<a>.*)/)',
+ '(;/(?<a>.*)/)',
+ '(%s();/(?<a>.*)/)',
+ '(%w();/(?<a>.*)/)',
+ '(1; (2; 3; (4; /(?<a>.*)/)))',
+ '(1+1; /(?<a>.*)/)',
+ '/#{""}(?<a>.*)/',
+ ) do |code, pass|
+ token = Random.bytes(4).unpack1("H*")
+ if pass
+ assert_equal(token, eval("#{code} =~ #{token.dump}; a"))
+ else
+ verbose_bak, $VERBOSE = $VERBOSE, nil # disable "warning: possibly useless use of a literal in void context"
+ begin
+ assert_nil(eval("#{code} =~ #{token.dump}; defined?(a)"), code)
+ ensure
+ $VERBOSE = verbose_bak
+ end
+ end
+ end
+ end
+
def test_rescue_in_command_assignment
bug = '[ruby-core:75621] [Bug #12402]'
all_assertions(bug) do |a|
@@ -1041,6 +1237,22 @@ x = __ENCODING__
assert_syntax_error(" 0b\n", /\^/)
end
+ def test_unclosed_unicode_escape_at_eol_bug_19750
+ assert_separately([], "#{<<-"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_syntax_error("/\\u", /too short escape sequence/)
+ assert_syntax_error("/\\u{", /unterminated regexp meets end of file/)
+ assert_syntax_error("/\\u{\\n", /invalid Unicode list/)
+ assert_syntax_error("/a#\\u{\\n/", /invalid Unicode list/)
+ re = eval("/a#\\u{\n$/x")
+ assert_match(re, 'a')
+ assert_not_match(re, 'a#')
+ re = eval("/a#\\u\n$/x")
+ assert_match(re, 'a')
+ assert_not_match(re, 'a#')
+ end;
+ end
+
def test_error_def_in_argument
assert_separately([], "#{<<-"begin;"}\n#{<<~"end;"}")
begin;
@@ -1084,31 +1296,40 @@ x = __ENCODING__
end;
end
- def test_heredoc_interpolation
- var = 1
+ def test_heredoc_interpolation
+ var = 1
- v1 = <<~HEREDOC
- something
- #{"/#{var}"}
- HEREDOC
+ v1 = <<~HEREDOC
+ something
+ #{"/#{var}"}
+ HEREDOC
- v2 = <<~HEREDOC
- something
- #{_other = "/#{var}"}
- HEREDOC
+ v2 = <<~HEREDOC
+ something
+ #{_other = "/#{var}"}
+ HEREDOC
- v3 = <<~HEREDOC
- something
- #{("/#{var}")}
- HEREDOC
+ v3 = <<~HEREDOC
+ something
+ #{("/#{var}")}
+ HEREDOC
- assert_equal "something\n/1\n", v1
- assert_equal "something\n/1\n", v2
- assert_equal "something\n/1\n", v3
- assert_equal v1, v2
- assert_equal v2, v3
- assert_equal v1, v3
- end
+ assert_equal "something\n/1\n", v1
+ assert_equal "something\n/1\n", v2
+ assert_equal "something\n/1\n", v3
+ assert_equal v1, v2
+ assert_equal v2, v3
+ assert_equal v1, v3
+ end
+
+ def test_heredoc_unterminated_interpolation
+ code = <<~'HEREDOC'
+ <<A+1
+ #{
+ HEREDOC
+
+ assert_syntax_error(code, /can't find string "A"/)
+ end
def test_unexpected_token_error
assert_syntax_error('"x"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', /unexpected/)
@@ -1118,6 +1339,8 @@ x = __ENCODING__
assert_syntax_error('0000xyz', /^ \^~~\Z/)
assert_syntax_error('1.2i1.1', /^ \^~~\Z/)
assert_syntax_error('1.2.3', /^ \^~\Z/)
+ assert_syntax_error('1.', /unexpected end-of-input/)
+ assert_syntax_error('1e', /expecting end-of-input/)
end
def test_truncated_source_line
@@ -1237,10 +1460,23 @@ x = __ENCODING__
def test_void_value_in_rhs
w = "void value expression"
- ["x = return 1", "x = return, 1", "x = 1, return", "x, y = return"].each do |code|
+ [
+ "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",
+ ].each do |code|
ex = assert_syntax_error(code, w)
assert_equal(1, ex.message.scan(w).size, ->{"same #{w.inspect} warning should be just once\n#{w.message}"})
end
+ [
+ "x = begin return; rescue; end",
+ "x = begin return; rescue; return; else end",
+ ].each do |code|
+ assert_valid_syntax(code)
+ end
end
def eval_separately(code)
@@ -1304,6 +1540,24 @@ x = __ENCODING__
assert_not_ractor_shareable(obj)
assert_equal obj, a
assert !obj.equal?(a)
+
+ bug_20339 = '[ruby-core:117186] [Bug #20339]'
+ bug_20341 = '[ruby-core:117197] [Bug #20341]'
+ a, b = eval_separately(<<~'end;')
+ # shareable_constant_value: literal
+ foo = 1
+ bar = 2
+ A = { foo => bar }
+ B = [foo, bar]
+ [A, B]
+ end;
+
+ assert_ractor_shareable(a)
+ assert_ractor_shareable(b)
+ assert_equal([1], a.keys, bug_20339)
+ assert_equal([2], a.values, bug_20339)
+ assert_equal(1, b[0], bug_20341)
+ assert_equal(2, b[1], bug_20341)
end
def test_shareable_constant_value_nested
@@ -1325,12 +1579,71 @@ x = __ENCODING__
end
def test_shareable_constant_value_unshareable_literal
- assert_raise_separately(Ractor::IsolationError, /unshareable/,
+ assert_raise_separately(Ractor::IsolationError, /unshareable object to C/,
"#{<<~"begin;"}\n#{<<~'end;'}")
begin;
# shareable_constant_value: literal
C = ["Not " + "shareable"]
end;
+
+ assert_raise_separately(Ractor::IsolationError, /unshareable object to B::C/,
+ "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ # shareable_constant_value: literal
+ B = Class.new
+ B::C = ["Not " + "shareable"]
+ end;
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_raise_with_message(Ractor::IsolationError, /unshareable object to ::C/) do
+ # shareable_constant_value: literal
+ ::C = ["Not " + "shareable"]
+ end
+ end;
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_raise_with_message(Ractor::IsolationError, /unshareable object to ::B::C/) do
+ # shareable_constant_value: literal
+ ::B = Class.new
+ ::B::C = ["Not " + "shareable"]
+ end
+ end;
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_raise_with_message(Ractor::IsolationError, /unshareable object to ::C/) do
+ # shareable_constant_value: literal
+ ::C ||= ["Not " + "shareable"]
+ end
+ end;
+
+ assert_raise_separately(Ractor::IsolationError, /unshareable object to B::C/,
+ "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ # shareable_constant_value: literal
+ B = Class.new
+ B::C ||= ["Not " + "shareable"]
+ end;
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_raise_with_message(Ractor::IsolationError, /unshareable object to ::B::C/) do
+ # shareable_constant_value: literal
+ ::B = Class.new
+ ::B::C ||= ["Not " + "shareable"]
+ end
+ end;
+
+ assert_raise_separately(Ractor::IsolationError, /unshareable object to ...::C/,
+ "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ # shareable_constant_value: literal
+ B = Class.new
+ def self.expr; B; end
+ expr::C ||= ["Not " + "shareable"]
+ end;
end
def test_shareable_constant_value_nonliteral
@@ -1405,9 +1718,29 @@ x = __ENCODING__
assert_equal(expected, obj.arg)
end
+ def test_ungettable_gvar
+ assert_syntax_error('$01234', /not allowed/)
+ assert_syntax_error('"#$01234"', /not allowed/)
+ end
+
=begin
def test_past_scope_variable
assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}}
end
=end
+
+ def assert_parse(code)
+ assert_kind_of(RubyVM::AbstractSyntaxTree::Node, RubyVM::AbstractSyntaxTree.parse(code))
+ end
+
+ def assert_parse_error(code, message)
+ assert_raise_with_message(SyntaxError, message) do
+ $VERBOSE, verbose_bak = nil, $VERBOSE
+ begin
+ RubyVM::AbstractSyntaxTree.parse(code)
+ ensure
+ $VERBOSE = verbose_bak
+ end
+ end
+ end
end
diff --git a/test/ruby/test_pattern_matching.rb b/test/ruby/test_pattern_matching.rb
index 36731e14f9..db6ad06b82 100644
--- a/test/ruby/test_pattern_matching.rb
+++ b/test/ruby/test_pattern_matching.rb
@@ -9,14 +9,14 @@ class TestPatternMatching < Test::Unit::TestCase
end
def setup
- if defined?(DidYouMean)
+ if defined?(DidYouMean.formatter=nil)
@original_formatter = DidYouMean.formatter
DidYouMean.formatter = NullFormatter.new
end
end
def teardown
- if defined?(DidYouMean)
+ if defined?(DidYouMean.formatter=nil)
DidYouMean.formatter = @original_formatter
end
end
@@ -109,16 +109,12 @@ class TestPatternMatching < Test::Unit::TestCase
end
assert_block do
- # suppress "warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!"
- experimental, Warning[:experimental] = Warning[:experimental], false
eval(%q{
case true
in a
a
end
})
- ensure
- Warning[:experimental] = experimental
end
assert_block do
@@ -358,6 +354,14 @@ END
end
assert_block do
+ a = "abc"
+ case 'abc'
+ in /#{a}/o
+ true
+ end
+ end
+
+ assert_block do
case 0
in ->(i) { i == 0 }
true
@@ -464,6 +468,8 @@ END
true
end
end
+
+ assert_valid_syntax("1 in ^(1\n)")
end
def test_array_pattern
@@ -798,6 +804,10 @@ END
true
end
end
+
+ assert_syntax_error(%q{
+ 0 => [a, *a]
+ }, /duplicated variable name/)
end
def test_find_pattern
@@ -866,6 +876,10 @@ END
false
end
end
+
+ assert_syntax_error(%q{
+ 0 => [*a, a, b, *b]
+ }, /duplicated variable name/)
end
def test_hash_pattern
@@ -1155,7 +1169,7 @@ END
end
end
- bug18890 = assert_warning(/(?:.*:[47]: warning: unused literal ignored\n){2}/) do
+ bug18890 = assert_warning(/(?:.*:[47]: warning: possibly useless use of a literal in void context\n){2}/) do
eval("#{<<~';;;'}")
proc do |i|
case i
@@ -1570,6 +1584,18 @@ END
assert_equal false, (1 in 2)
end
+ def test_bug18990
+ {a: 0} => a:
+ assert_equal 0, a
+ {a: 0} => a:
+ assert_equal 0, a
+
+ {a: 0} in a:
+ assert_equal 0, a
+ {a: 0} in a:
+ assert_equal 0, a
+ end
+
################################################################
def test_single_pattern_error_value_pattern
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index 05c6e03aac..2f91da8aa8 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -289,7 +289,6 @@ class TestProc < Test::Unit::TestCase
assert_equal(false, l.lambda?)
assert_equal(false, l.curry.lambda?, '[ruby-core:24127]')
assert_equal(false, proc(&l).lambda?)
- assert_equal(false, assert_deprecated_warning {lambda(&l)}.lambda?)
assert_equal(false, Proc.new(&l).lambda?)
l = lambda {}
assert_equal(true, l.lambda?)
@@ -299,47 +298,21 @@ class TestProc < Test::Unit::TestCase
assert_equal(true, Proc.new(&l).lambda?)
end
- def self.helper_test_warn_lamda_with_passed_block &b
+ def helper_test_warn_lambda_with_passed_block &b
lambda(&b)
end
- def self.def_lambda_warning name, warn
- define_method(name, proc do
- prev = Warning[:deprecated]
- assert_warn warn do
- Warning[:deprecated] = true
- yield
- end
- ensure
- Warning[:deprecated] = prev
- end)
- end
-
- def_lambda_warning 'test_lambda_warning_normal', '' do
- lambda{}
- end
-
- def_lambda_warning 'test_lambda_warning_pass_lambda', '' do
- b = lambda{}
- lambda(&b)
- end
-
- def_lambda_warning 'test_lambda_warning_pass_symbol_proc', '' do
- lambda(&:to_s)
- end
-
- def_lambda_warning 'test_lambda_warning_pass_proc', /deprecated/ do
- b = proc{}
- lambda(&b)
- end
-
- def_lambda_warning 'test_lambda_warning_pass_block', /deprecated/ do
- helper_test_warn_lamda_with_passed_block{}
+ def test_lambda_warning_pass_proc
+ assert_raise(ArgumentError) do
+ b = proc{}
+ lambda(&b)
+ end
end
- def_lambda_warning 'test_lambda_warning_pass_block_symbol_proc', '' do
- # Symbol#to_proc returns lambda
- helper_test_warn_lamda_with_passed_block(&:to_s)
+ def test_lambda_warning_pass_block
+ assert_raise(ArgumentError) do
+ helper_test_warn_lambda_with_passed_block{}
+ end
end
def test_curry_ski_fib
@@ -415,6 +388,15 @@ class TestProc < Test::Unit::TestCase
def test_dup_subclass
c1 = Class.new(Proc)
assert_equal c1, c1.new{}.dup.class, '[Bug #17545]'
+ c1 = Class.new(Proc) {def initialize_dup(*) throw :initialize_dup; end}
+ assert_throw(:initialize_dup) {c1.new{}.dup}
+ end
+
+ def test_clone_subclass
+ c1 = Class.new(Proc)
+ assert_equal c1, c1.new{}.clone.class, '[Bug #17545]'
+ c1 = Class.new(Proc) {def initialize_clone(*) throw :initialize_clone; end}
+ assert_throw(:initialize_clone) {c1.new{}.clone}
end
def test_binding
@@ -1321,6 +1303,32 @@ class TestProc < Test::Unit::TestCase
assert_empty(pr.parameters.map{|_,n|n}.compact)
end
+ def test_proc_autosplat_with_multiple_args_with_ruby2_keywords_splat_bug_19759
+ def self.yielder_ab(splat)
+ yield([:a, :b], *splat)
+ end
+
+ res = yielder_ab([[:aa, :bb], Hash.ruby2_keywords_hash({k: :k})]) do |a, b, k:|
+ [a, b, k]
+ end
+ assert_equal([[:a, :b], [:aa, :bb], :k], res)
+
+ def self.yielder(splat)
+ yield(*splat)
+ end
+ res = yielder([ [:a, :b] ]){|a, b, **| [a, b]}
+ assert_equal([:a, :b], res)
+
+ res = yielder([ [:a, :b], Hash.ruby2_keywords_hash({}) ]){|a, b, **| [a, b]}
+ assert_equal([[:a, :b], nil], res)
+
+ res = yielder([ [:a, :b], Hash.ruby2_keywords_hash({c: 1}) ]){|a, b, **| [a, b]}
+ assert_equal([[:a, :b], nil], res)
+
+ res = yielder([ [:a, :b], Hash.ruby2_keywords_hash({}) ]){|a, b, **nil| [a, b]}
+ assert_equal([[:a, :b], nil], res)
+ end
+
def test_parameters_lambda
assert_equal([], proc {}.parameters(lambda: true))
assert_equal([], proc {||}.parameters(lambda: true))
@@ -1838,4 +1846,3 @@ class TestProcKeywords < Test::Unit::TestCase
assert_raise(ArgumentError) { (f >> g).call(**{})[:a] }
end
end
-
diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb
index c4888598a8..7ef184d639 100644
--- a/test/ruby/test_process.rb
+++ b/test/ruby/test_process.rb
@@ -3,7 +3,6 @@
require 'test/unit'
require 'tempfile'
require 'timeout'
-require 'io/wait'
require 'rbconfig'
class TestProcess < Test::Unit::TestCase
@@ -24,12 +23,6 @@ class TestProcess < Test::Unit::TestCase
return /mswin|mingw|bccwin/ =~ RUBY_PLATFORM
end
- def write_file(filename, content)
- File.open(filename, "w") {|f|
- f << content
- }
- end
-
def with_tmpchdir
Dir.mktmpdir {|d|
d = File.realpath(d)
@@ -40,7 +33,7 @@ class TestProcess < Test::Unit::TestCase
end
def run_in_child(str) # should be called in a temporary directory
- write_file("test-script", str)
+ File.write("test-script", str)
Process.wait spawn(RUBY, "test-script")
$?
end
@@ -66,7 +59,7 @@ class TestProcess < Test::Unit::TestCase
def test_rlimit_nofile
return unless rlimit_exist?
with_tmpchdir {
- write_file 's', <<-"End"
+ File.write 's', <<-"End"
# Too small RLIMIT_NOFILE, such as zero, causes problems.
# [OpenBSD] Setting to zero freezes this test.
# [GNU/Linux] EINVAL on poll(). EINVAL on ruby's internal poll() ruby with "[ASYNC BUG] thread_timer: select".
@@ -206,58 +199,67 @@ class TestProcess < Test::Unit::TestCase
max = Process.getrlimit(:CORE).last
+ # When running under ASAN, we need to set disable_coredump=0 for this test; by default
+ # the ASAN runtime library sets RLIMIT_CORE to 0, "to avoid dumping a 16T+ core file", and
+ # that inteferes with this test.
+ asan_options = ENV['ASAN_OPTIONS'] || ''
+ asan_options << ':' unless asan_options.empty?
+ env = {
+ 'ASAN_OPTIONS' => "#{asan_options}disable_coredump=0"
+ }
+
n = max
- IO.popen([RUBY, "-e",
+ IO.popen([env, RUBY, "-e",
"puts Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
assert_equal("#{n}\n#{n}\n", io.read)
}
n = 0
- IO.popen([RUBY, "-e",
+ IO.popen([env, RUBY, "-e",
"puts Process.getrlimit(:CORE)", :rlimit_core=>n]) {|io|
assert_equal("#{n}\n#{n}\n", io.read)
}
n = max
- IO.popen([RUBY, "-e",
+ IO.popen([env, RUBY, "-e",
"puts Process.getrlimit(:CORE)", :rlimit_core=>[n]]) {|io|
assert_equal("#{n}\n#{n}\n", io.read)
}
m, n = 0, max
- IO.popen([RUBY, "-e",
+ IO.popen([env, RUBY, "-e",
"puts Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
assert_equal("#{m}\n#{n}\n", io.read)
}
m, n = 0, 0
- IO.popen([RUBY, "-e",
+ IO.popen([env, RUBY, "-e",
"puts Process.getrlimit(:CORE)", :rlimit_core=>[m,n]]) {|io|
assert_equal("#{m}\n#{n}\n", io.read)
}
n = max
- IO.popen([RUBY, "-e",
+ IO.popen([env, RUBY, "-e",
"puts Process.getrlimit(:CORE), Process.getrlimit(:CPU)",
:rlimit_core=>n, :rlimit_cpu=>3600]) {|io|
assert_equal("#{n}\n#{n}\n""3600\n3600\n", io.read)
}
assert_raise(ArgumentError) do
- system(RUBY, '-e', 'exit', 'rlimit_bogus'.to_sym => 123)
+ system(env, RUBY, '-e', 'exit', 'rlimit_bogus'.to_sym => 123)
end
- assert_separately([],"#{<<~"begin;"}\n#{<<~'end;'}", 'rlimit_cpu'.to_sym => 3600)
+ assert_separately([env],"#{<<~"begin;"}\n#{<<~'end;'}", 'rlimit_cpu'.to_sym => 3600)
BUG = "[ruby-core:82033] [Bug #13744]"
begin;
assert_equal([3600,3600], Process.getrlimit(:CPU), BUG)
end;
assert_raise_with_message(ArgumentError, /bogus/) do
- system(RUBY, '-e', 'exit', :rlimit_bogus => 123)
+ system(env, RUBY, '-e', 'exit', :rlimit_bogus => 123)
end
assert_raise_with_message(ArgumentError, /rlimit_cpu/) {
- system(RUBY, '-e', 'exit', "rlimit_cpu\0".to_sym => 3600)
+ system(env, RUBY, '-e', 'exit', "rlimit_cpu\0".to_sym => 3600)
}
end
@@ -273,7 +275,7 @@ class TestProcess < Test::Unit::TestCase
end;
end
- MANDATORY_ENVS = %w[RUBYLIB MJIT_SEARCH_BUILD_DIR]
+ MANDATORY_ENVS = %w[RUBYLIB RJIT_SEARCH_BUILD_DIR]
case RbConfig::CONFIG['target_os']
when /linux/
MANDATORY_ENVS << 'LD_PRELOAD'
@@ -362,7 +364,7 @@ class TestProcess < Test::Unit::TestCase
def test_execopt_env_path
bug8004 = '[ruby-core:53103] [Bug #8004]'
Dir.mktmpdir do |d|
- open("#{d}/tmp_script.cmd", "w") {|f| f.puts ": ;"; f.chmod(0755)}
+ File.write("#{d}/tmp_script.cmd", ": ;\n", perm: 0o755)
assert_not_nil(pid = Process.spawn({"PATH" => d}, "tmp_script.cmd"), bug8004)
wpid, st = Process.waitpid2(pid)
assert_equal([pid, true], [wpid, st.success?], bug8004)
@@ -400,7 +402,7 @@ class TestProcess < Test::Unit::TestCase
def test_execopts_env_popen_string
with_tmpchdir do |d|
- open('test-script', 'w') do |f|
+ File.open('test-script', 'w') do |f|
ENVCOMMAND.each_with_index do |cmd, i|
next if i.zero? or cmd == "-e"
f.puts cmd
@@ -412,16 +414,14 @@ class TestProcess < Test::Unit::TestCase
def test_execopts_preserve_env_on_exec_failure
with_tmpchdir {|d|
- write_file 's', <<-"End"
+ File.write 's', <<-"End"
ENV["mgg"] = nil
prog = "./nonexistent"
begin
Process.exec({"mgg" => "mggoo"}, [prog, prog])
rescue Errno::ENOENT
end
- open('out', 'w') {|f|
- f.print ENV["mgg"].inspect
- }
+ File.write('out', ENV["mgg"].inspect)
End
system(RUBY, 's')
assert_equal(nil.inspect, File.read('out'),
@@ -431,9 +431,7 @@ class TestProcess < Test::Unit::TestCase
def test_execopts_env_single_word
with_tmpchdir {|d|
- open("test_execopts_env_single_word.rb", "w") {|f|
- f.puts "print ENV['hgga']"
- }
+ File.write("test_execopts_env_single_word.rb", "print ENV['hgga']\n")
system({"hgga"=>"ugu"}, RUBY,
:in => 'test_execopts_env_single_word.rb',
:out => 'test_execopts_env_single_word.out')
@@ -555,7 +553,7 @@ class TestProcess < Test::Unit::TestCase
assert_equal("a", File.read("out").chomp)
if windows?
# currently telling to child the file modes is not supported.
- open("out", "a") {|f| f.write "0\n"}
+ File.write("out", "0\n", mode: "a")
else
Process.wait Process.spawn(*ECHO["0"], STDOUT=>["out", File::WRONLY|File::CREAT|File::APPEND, 0644])
assert_equal("a\n0\n", File.read("out"))
@@ -666,6 +664,7 @@ class TestProcess < Test::Unit::TestCase
end unless windows? # does not support fifo
def test_execopts_redirect_open_fifo_interrupt_raise
+ pid = nil
with_tmpchdir {|d|
begin
File.mkfifo("fifo")
@@ -683,15 +682,21 @@ class TestProcess < Test::Unit::TestCase
puts "ok"
end
EOS
+ pid = io.pid
assert_equal("start\n", io.gets)
sleep 0.5
Process.kill(:USR1, io.pid)
assert_equal("ok\n", io.read)
}
+ assert_equal(pid, $?.pid)
+ assert_predicate($?, :success?)
}
+ ensure
+ assert_raise(Errno::ESRCH) {Process.kill(:KILL, pid)} if pid
end unless windows? # does not support fifo
def test_execopts_redirect_open_fifo_interrupt_print
+ pid = nil
with_tmpchdir {|d|
begin
File.mkfifo("fifo")
@@ -704,14 +709,25 @@ class TestProcess < Test::Unit::TestCase
puts "start"
system("cat", :in => "fifo")
EOS
+ pid = io.pid
assert_equal("start\n", io.gets)
sleep 0.2 # wait for the child to stop at opening "fifo"
Process.kill(:USR1, io.pid)
assert_equal("trap\n", io.readpartial(8))
+ sleep 0.2 # wait for the child to return to opening "fifo".
+ # On arm64-darwin22, often deadlocks while the child is
+ # opening "fifo". Not sure to where "ok" line being written
+ # at the next has gone.
File.write("fifo", "ok\n")
assert_equal("ok\n", io.read)
}
+ assert_equal(pid, $?.pid)
+ assert_predicate($?, :success?)
}
+ ensure
+ if pid
+ assert_raise(Errno::ESRCH) {Process.kill(:KILL, pid)}
+ end
end unless windows? # does not support fifo
def test_execopts_redirect_pipe
@@ -859,7 +875,7 @@ class TestProcess < Test::Unit::TestCase
def test_execopts_exec
with_tmpchdir {|d|
- write_file("s", 'exec "echo aaa", STDOUT=>"foo"')
+ File.write("s", 'exec "echo aaa", STDOUT=>"foo"')
pid = spawn RUBY, 's'
Process.wait pid
assert_equal("aaa\n", File.read("foo"))
@@ -933,7 +949,7 @@ class TestProcess < Test::Unit::TestCase
}
with_pipe {|r, w|
with_tmpchdir {|d|
- write_file("s", <<-"End")
+ File.write("s", <<-"End")
exec(#{RUBY.dump}, '-e',
'IO.new(ARGV[0].to_i, "w").puts("bu") rescue nil',
#{w.fileno.to_s.dump}, :close_others=>false)
@@ -987,7 +1003,7 @@ class TestProcess < Test::Unit::TestCase
assert_equal("bi\n", r.read)
}
with_pipe {|r, w|
- write_file("s", <<-"End")
+ File.write("s", <<-"End")
exec(#{RUBY.dump}, '-e',
'STDERR.reopen("err", "w"); IO.new(ARGV[0].to_i, "w").puts("mu")',
#{w.fileno.to_s.dump},
@@ -1113,7 +1129,7 @@ class TestProcess < Test::Unit::TestCase
def test_exec_noshell
with_tmpchdir {|d|
- write_file("s", <<-"End")
+ File.write("s", <<-"End")
str = "echo non existing command name which contains spaces"
STDERR.reopen(STDOUT)
begin
@@ -1129,7 +1145,7 @@ class TestProcess < Test::Unit::TestCase
def test_system_wordsplit
with_tmpchdir {|d|
- write_file("script", <<-'End')
+ File.write("script", <<-'End')
File.open("result", "w") {|t| t << "haha pid=#{$$} ppid=#{Process.ppid}" }
exit 5
End
@@ -1145,7 +1161,7 @@ class TestProcess < Test::Unit::TestCase
def test_spawn_wordsplit
with_tmpchdir {|d|
- write_file("script", <<-'End')
+ File.write("script", <<-'End')
File.open("result", "w") {|t| t << "hihi pid=#{$$} ppid=#{Process.ppid}" }
exit 6
End
@@ -1162,7 +1178,7 @@ class TestProcess < Test::Unit::TestCase
def test_popen_wordsplit
with_tmpchdir {|d|
- write_file("script", <<-'End')
+ File.write("script", <<-'End')
print "fufu pid=#{$$} ppid=#{Process.ppid}"
exit 7
End
@@ -1181,7 +1197,7 @@ class TestProcess < Test::Unit::TestCase
def test_popen_wordsplit_beginning_and_trailing_spaces
with_tmpchdir {|d|
- write_file("script", <<-'End')
+ File.write("script", <<-'End')
print "fufumm pid=#{$$} ppid=#{Process.ppid}"
exit 7
End
@@ -1200,7 +1216,7 @@ class TestProcess < Test::Unit::TestCase
def test_exec_wordsplit
with_tmpchdir {|d|
- write_file("script", <<-'End')
+ File.write("script", <<-'End')
File.open("result", "w") {|t|
if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
t << "hehe ppid=#{Process.ppid}"
@@ -1210,7 +1226,7 @@ class TestProcess < Test::Unit::TestCase
}
exit 6
End
- write_file("s", <<-"End")
+ File.write("s", <<-"End")
ruby = #{RUBY.dump}
exec "\#{ruby} script"
End
@@ -1231,11 +1247,11 @@ class TestProcess < Test::Unit::TestCase
def test_system_shell
with_tmpchdir {|d|
- write_file("script1", <<-'End')
+ File.write("script1", <<-'End')
File.open("result1", "w") {|t| t << "taka pid=#{$$} ppid=#{Process.ppid}" }
exit 7
End
- write_file("script2", <<-'End')
+ File.write("script2", <<-'End')
File.open("result2", "w") {|t| t << "taki pid=#{$$} ppid=#{Process.ppid}" }
exit 8
End
@@ -1251,7 +1267,7 @@ class TestProcess < Test::Unit::TestCase
if windows?
Dir.mkdir(path = "path with space")
- write_file(bat = path + "/bat test.bat", "@echo %1>out")
+ File.write(bat = path + "/bat test.bat", "@echo %1>out")
system(bat, "foo 'bar'")
assert_equal(%["foo 'bar'"\n], File.read("out"), '[ruby-core:22960]')
system(%[#{bat.dump} "foo 'bar'"])
@@ -1262,11 +1278,11 @@ class TestProcess < Test::Unit::TestCase
def test_spawn_shell
with_tmpchdir {|d|
- write_file("script1", <<-'End')
+ File.write("script1", <<-'End')
File.open("result1", "w") {|t| t << "taku pid=#{$$} ppid=#{Process.ppid}" }
exit 7
End
- write_file("script2", <<-'End')
+ File.write("script2", <<-'End')
File.open("result2", "w") {|t| t << "take pid=#{$$} ppid=#{Process.ppid}" }
exit 8
End
@@ -1283,7 +1299,7 @@ class TestProcess < Test::Unit::TestCase
if windows?
Dir.mkdir(path = "path with space")
- write_file(bat = path + "/bat test.bat", "@echo %1>out")
+ File.write(bat = path + "/bat test.bat", "@echo %1>out")
pid = spawn(bat, "foo 'bar'")
Process.wait pid
status = $?
@@ -1302,11 +1318,11 @@ class TestProcess < Test::Unit::TestCase
def test_popen_shell
with_tmpchdir {|d|
- write_file("script1", <<-'End')
+ File.write("script1", <<-'End')
puts "tako pid=#{$$} ppid=#{Process.ppid}"
exit 7
End
- write_file("script2", <<-'End')
+ File.write("script2", <<-'End')
puts "tika pid=#{$$} ppid=#{Process.ppid}"
exit 8
End
@@ -1321,7 +1337,7 @@ class TestProcess < Test::Unit::TestCase
if windows?
Dir.mkdir(path = "path with space")
- write_file(bat = path + "/bat test.bat", "@echo %1")
+ File.write(bat = path + "/bat test.bat", "@echo %1")
r = IO.popen([bat, "foo 'bar'"]) {|f| f.read}
assert_equal(%["foo 'bar'"\n], r, '[ruby-core:22960]')
r = IO.popen(%[#{bat.dump} "foo 'bar'"]) {|f| f.read}
@@ -1332,15 +1348,15 @@ class TestProcess < Test::Unit::TestCase
def test_exec_shell
with_tmpchdir {|d|
- write_file("script1", <<-'End')
+ File.write("script1", <<-'End')
File.open("result1", "w") {|t| t << "tiki pid=#{$$} ppid=#{Process.ppid}" }
exit 7
End
- write_file("script2", <<-'End')
+ File.write("script2", <<-'End')
File.open("result2", "w") {|t| t << "tiku pid=#{$$} ppid=#{Process.ppid}" }
exit 8
End
- write_file("s", <<-"End")
+ File.write("s", <<-"End")
ruby = #{RUBY.dump}
exec("\#{ruby} script1 || \#{ruby} script2")
End
@@ -1367,7 +1383,7 @@ class TestProcess < Test::Unit::TestCase
assert_equal("1", IO.popen([[RUBY, "qwerty"], "-e", "print 1"]) {|f| f.read })
- write_file("s", <<-"End")
+ File.write("s", <<-"End")
exec([#{RUBY.dump}, "lkjh"], "-e", "exit 5")
End
pid = spawn RUBY, "s"
@@ -1377,7 +1393,7 @@ class TestProcess < Test::Unit::TestCase
end
def with_stdin(filename)
- open(filename) {|f|
+ File.open(filename) {|f|
begin
old = STDIN.dup
begin
@@ -1394,8 +1410,8 @@ class TestProcess < Test::Unit::TestCase
def test_argv0_noarg
with_tmpchdir {|d|
- open("t", "w") {|f| f.print "exit true" }
- open("f", "w") {|f| f.print "exit false" }
+ File.write("t", "exit true")
+ File.write("f", "exit false")
with_stdin("t") { assert_equal(true, system([RUBY, "qaz"])) }
with_stdin("f") { assert_equal(false, system([RUBY, "wsx"])) }
@@ -1425,6 +1441,11 @@ class TestProcess < Test::Unit::TestCase
REPRO
end
+ def test_argv0_frozen
+ assert_predicate Process.argv0, :frozen?
+ assert_predicate $0, :frozen?
+ end
+
def test_status
with_tmpchdir do
s = run_in_child("exit 1")
@@ -1433,8 +1454,15 @@ class TestProcess < Test::Unit::TestCase
assert_equal(s, s)
assert_equal(s, s.to_i)
- assert_equal(s.to_i & 0x55555555, s & 0x55555555)
- assert_equal(s.to_i >> 1, s >> 1)
+ assert_deprecated_warn(/\buse .*Process::Status/) do
+ assert_equal(s.to_i & 0x55555555, s & 0x55555555)
+ end
+ assert_deprecated_warn(/\buse .*Process::Status/) do
+ assert_equal(s.to_i >> 1, s >> 1)
+ end
+ assert_raise(ArgumentError) do
+ s >> -1
+ end
assert_equal(false, s.stopped?)
assert_equal(nil, s.stopsig)
@@ -1450,7 +1478,7 @@ class TestProcess < Test::Unit::TestCase
expected = Signal.list.include?("QUIT") ? [false, true, false, nil] : [true, false, false, true]
with_tmpchdir do
- write_file("foo", "Process.kill(:KILL, $$); exit(42)")
+ File.write("foo", "Process.kill(:KILL, $$); exit(42)")
system(RUBY, "foo")
s = $?
assert_equal(expected,
@@ -1498,7 +1526,7 @@ class TestProcess < Test::Unit::TestCase
def test_wait_without_arg
with_tmpchdir do
- write_file("foo", "sleep 0.1")
+ File.write("foo", "sleep 0.1")
pid = spawn(RUBY, "foo")
assert_equal(pid, Process.wait)
end
@@ -1506,7 +1534,7 @@ class TestProcess < Test::Unit::TestCase
def test_wait2
with_tmpchdir do
- write_file("foo", "sleep 0.1")
+ File.write("foo", "sleep 0.1")
pid = spawn(RUBY, "foo")
assert_equal([pid, 0], Process.wait2)
end
@@ -1514,7 +1542,7 @@ class TestProcess < Test::Unit::TestCase
def test_waitall
with_tmpchdir do
- write_file("foo", "sleep 0.1")
+ File.write("foo", "sleep 0.1")
ps = (0...3).map { spawn(RUBY, "foo") }.sort
ss = Process.waitall.sort
ps.zip(ss) do |p1, (p2, s)|
@@ -1547,6 +1575,8 @@ class TestProcess < Test::Unit::TestCase
assert_operator(diff, :<, sec,
->{"#{bug11340}: #{diff} seconds to interrupt Process.wait"})
f.puts
+ rescue Errno::EPIPE
+ omit "child process exited already in #{diff} seconds"
end
end
@@ -1554,7 +1584,7 @@ class TestProcess < Test::Unit::TestCase
with_tmpchdir do
s = run_in_child("abort")
assert_not_predicate(s, :success?)
- write_file("test-script", "#{<<~"begin;"}\n#{<<~'end;'}")
+ File.write("test-script", "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
STDERR.reopen(STDOUT)
begin
@@ -1695,11 +1725,6 @@ class TestProcess < Test::Unit::TestCase
end
def test_wait_and_sigchild
- if /freebsd|openbsd/ =~ RUBY_PLATFORM
- # this relates #4173
- # When ruby can use 2 cores, signal and wait4 may miss the signal.
- omit "this fails on FreeBSD and OpenBSD on multithreaded environment"
- end
signal_received = []
IO.pipe do |sig_r, sig_w|
Signal.trap(:CHLD) do
@@ -1718,7 +1743,7 @@ class TestProcess < Test::Unit::TestCase
Process.wait pid
assert_send [sig_r, :wait_readable, 5], 'self-pipe not readable'
end
- if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # checking -DMJIT_FORCE_ENABLE. It may trigger extra SIGCHLD.
+ if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # checking -DRJIT_FORCE_ENABLE. It may trigger extra SIGCHLD.
assert_equal [true], signal_received.uniq, "[ruby-core:19744]"
else
assert_equal [true], signal_received, "[ruby-core:19744]"
@@ -1752,16 +1777,16 @@ class TestProcess < Test::Unit::TestCase
def test_fallback_to_sh
feature = '[ruby-core:32745]'
with_tmpchdir do |d|
- open("tmp_script.#{$$}", "w") {|f| f.puts ": ;"; f.chmod(0755)}
+ File.write("tmp_script.#{$$}", ": ;\n", perm: 0o755)
assert_not_nil(pid = Process.spawn("./tmp_script.#{$$}"), feature)
wpid, st = Process.waitpid2(pid)
assert_equal([pid, true], [wpid, st.success?], feature)
- open("tmp_script.#{$$}", "w") {|f| f.puts "echo $#: $@"; f.chmod(0755)}
+ File.write("tmp_script.#{$$}", "echo $#: $@", perm: 0o755)
result = IO.popen(["./tmp_script.#{$$}", "a b", "c"]) {|f| f.read}
assert_equal("2: a b c\n", result, feature)
- open("tmp_script.#{$$}", "w") {|f| f.puts "echo $hghg"; f.chmod(0755)}
+ File.write("tmp_script.#{$$}", "echo $hghg", perm: 0o755)
result = IO.popen([{"hghg" => "mogomogo"}, "./tmp_script.#{$$}", "a b", "c"]) {|f| f.read}
assert_equal("mogomogo\n", result, feature)
@@ -1789,14 +1814,20 @@ class TestProcess < Test::Unit::TestCase
exs << Errno::EINVAL if windows?
exs << Errno::E2BIG if defined?(Errno::E2BIG)
opts = {[STDOUT, STDERR]=>File::NULL}
- opts[:rlimit_nproc] = 128 if defined?(Process::RLIMIT_NPROC)
+ if defined?(Process::RLIMIT_NPROC)
+ opts[:rlimit_nproc] = /openbsd/i =~ RUBY_PLATFORM ? 64 : 128
+ end
EnvUtil.suppress_warning do
assert_raise(*exs, mesg) do
begin
loop do
Process.spawn(cmds.join(sep), opts)
min = [cmds.size, min].max
- cmds *= 100
+ begin
+ cmds *= 100
+ rescue ArgumentError
+ raise NoMemoryError
+ end
end
rescue NoMemoryError
size = cmds.size
@@ -1817,7 +1848,7 @@ class TestProcess < Test::Unit::TestCase
with_tmpchdir do
assert_nothing_raised('[ruby-dev:12261]') do
- EnvUtil.timeout(3) do
+ EnvUtil.timeout(10) do
pid = spawn('yes | ls')
Process.waitpid pid
end
@@ -1876,6 +1907,28 @@ class TestProcess < Test::Unit::TestCase
assert_not_equal(cpid, dpid)
end
+ def test_daemon_detached
+ IO.popen("-", "r+") do |f|
+ if f
+ assert_equal(f.pid, Process.wait(f.pid))
+
+ dpid, ppid, dsid = 3.times.map {Integer(f.gets)}
+
+ message = "daemon #{dpid} should be detached"
+ assert_not_equal($$, ppid, message) # would be 1 almost always
+ assert_raise(Errno::ECHILD, message) {Process.wait(dpid)}
+ assert_kind_of(Integer, Process.kill(0, dpid), message)
+ assert_equal(dpid, dsid)
+
+ break # close f, and let the daemon resume and exit
+ end
+ Process.setsid rescue nil
+ Process.daemon(false, true)
+ puts $$, Process.ppid, Process.getsid
+ $stdin.gets # wait for the above assertions using signals
+ end
+ end
+
if File.directory?("/proc/self/task") && /netbsd[a-z]*[1-6]/ !~ RUBY_PLATFORM
def test_daemon_no_threads
pid, data = IO.popen("-", "r+") do |f|
@@ -2116,7 +2169,7 @@ EOS
"c\u{1EE7}a",
].each do |arg|
begin
- arg = arg.encode(Encoding.find("locale"))
+ arg = arg.encode(Encoding.local_charmap)
rescue
else
assert_in_out_err([], "#{<<-"begin;"}\n#{<<-"end;"}", [arg], [], bug12841)
@@ -2134,7 +2187,9 @@ EOS
t3 = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
assert_operator(t1, :<=, t2)
assert_operator(t2, :<=, t3)
- assert_raise(Errno::EINVAL) { Process.clock_gettime(:foo) }
+ assert_raise_with_message(Errno::EINVAL, /:foo/) do
+ Process.clock_gettime(:foo)
+ end
end
def test_clock_gettime_unit
@@ -2239,7 +2294,9 @@ EOS
rescue Errno::EINVAL
else
assert_kind_of(Integer, r)
- assert_raise(Errno::EINVAL) { Process.clock_getres(:foo) }
+ assert_raise_with_message(Errno::EINVAL, /:foo/) do
+ Process.clock_getres(:foo)
+ end
end
def test_clock_getres_constants
@@ -2326,7 +2383,7 @@ EOS
end
def test_deadlock_by_signal_at_forking
- assert_separately(%W(--disable=gems - #{RUBY}), <<-INPUT, timeout: 100)
+ assert_separately(%W(- #{RUBY}), <<-INPUT, timeout: 100)
ruby = ARGV.shift
GC.start # reduce garbage
GC.disable # avoid triggering CoW after forks
@@ -2565,6 +2622,26 @@ EOS
end
end if Process.respond_to?(:_fork)
+ def test__fork_pid_cache
+ _parent_pid = Process.pid
+ r, w = IO.pipe
+ pid = Process._fork
+ if pid == 0
+ begin
+ r.close
+ w << "ok: #{Process.pid}"
+ w.close
+ ensure
+ exit!
+ end
+ else
+ w.close
+ assert_equal("ok: #{pid}", r.read)
+ r.close
+ Process.waitpid(pid)
+ end
+ end if Process.respond_to?(:_fork)
+
def test__fork_hook
%w(fork Process.fork).each do |method|
feature17795 = '[ruby-core:103400] [Feature #17795]'
@@ -2637,4 +2714,148 @@ EOS
end
end;
end if Process.respond_to?(:_fork)
+
+ def test_warmup_promote_all_objects_to_oldgen
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ require 'objspace'
+ begin;
+ obj = Object.new
+
+ assert_not_include(ObjectSpace.dump(obj), '"old":true')
+ Process.warmup
+ assert_include(ObjectSpace.dump(obj), '"old":true')
+ end;
+ end
+
+ def test_warmup_run_major_gc_and_compact
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ # Run a GC to ensure that we are not in the middle of a GC run
+ GC.start
+
+ major_gc_count = GC.stat(:major_gc_count)
+ compact_count = GC.stat(:compact_count)
+ Process.warmup
+ assert_equal major_gc_count + 1, GC.stat(:major_gc_count)
+ assert_equal compact_count + 1, GC.stat(:compact_count)
+ end;
+ end
+
+ def test_warmup_precompute_string_coderange
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ require 'objspace'
+ begin;
+ obj = "a" * 12
+ obj.force_encoding(Encoding::UTF_16LE)
+ obj.force_encoding(Encoding::BINARY)
+ assert_include(ObjectSpace.dump(obj), '"coderange":"unknown"')
+ Process.warmup
+ assert_include(ObjectSpace.dump(obj), '"coderange":"7bit"')
+ end;
+ end
+
+ def test_warmup_frees_pages
+ assert_separately([{"RUBY_GC_HEAP_FREE_SLOTS_MAX_RATIO" => "1.0"}, "-W0"], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ GC.start
+
+ TIMES = 10_000
+ ary = Array.new(TIMES)
+ TIMES.times do |i|
+ ary[i] = Object.new
+ end
+ ary.clear
+ ary = nil
+
+ # Disable GC so we can make sure GC only runs in Process.warmup
+ GC.disable
+
+ total_pages_before = GC.stat_heap.map { |_, v| v[:heap_eden_pages] + v[:heap_allocatable_pages] }
+
+ Process.warmup
+
+ # Number of pages freed should cause equal increase in number of allocatable pages.
+ total_pages_before.each_with_index do |val, i|
+ assert_equal(val, GC.stat_heap(i, :heap_eden_pages) + GC.stat_heap(i, :heap_allocatable_pages), "size pool: #{i}")
+ end
+ assert_equal(0, GC.stat(:heap_tomb_pages))
+ assert_operator(GC.stat(:total_freed_pages), :>, 0)
+ end;
+ end
+
+ def test_concurrent_group_and_pid_wait
+ # Use a pair of pipes that will make long_pid exit when this test exits, to avoid
+ # leaking temp processes.
+ long_rpipe, long_wpipe = IO.pipe
+ short_rpipe, short_wpipe = IO.pipe
+ # This process should run forever
+ long_pid = fork do
+ [short_rpipe, short_wpipe, long_wpipe].each(&:close)
+ long_rpipe.read
+ end
+ # This process will exit
+ short_pid = fork do
+ [long_rpipe, long_wpipe, short_wpipe].each(&:close)
+ short_rpipe.read
+ end
+ t1, t2, t3 = nil
+ EnvUtil.timeout(5) do
+ t1 = Thread.new do
+ Process.waitpid long_pid
+ end
+ # Wait for us to be blocking in a call to waitpid2
+ Thread.pass until t1.stop?
+ short_wpipe.close # Make short_pid exit
+
+ # The short pid has exited, so -1 should pick that up.
+ assert_equal short_pid, Process.waitpid(-1)
+
+ # Terminate t1 for the next phase of the test.
+ t1.kill
+ t1.join
+
+ t2 = Thread.new do
+ Process.waitpid(-1)
+ rescue Errno::ECHILD
+ nil
+ end
+ Thread.pass until t2.stop?
+ t3 = Thread.new do
+ Process.waitpid long_pid
+ rescue Errno::ECHILD
+ nil
+ end
+ Thread.pass until t3.stop?
+
+ # it's actually nondeterministic which of t2 or t3 will receive the wait (this
+ # nondeterminism comes from the behaviour of the underlying system calls)
+ long_wpipe.close
+ assert_equal [long_pid], [t2, t3].map(&:value).compact
+ end
+ ensure
+ [t1, t2, t3].each { _1&.kill rescue nil }
+ [t1, t2, t3].each { _1&.join rescue nil }
+ [long_rpipe, long_wpipe, short_rpipe, short_wpipe].each { _1&.close rescue nil }
+ end if defined?(fork)
+
+ def test_handle_interrupt_with_fork
+ Thread.handle_interrupt(RuntimeError => :never) do
+ Thread.current.raise(RuntimeError, "Queued error")
+
+ assert_predicate Thread, :pending_interrupt?
+
+ pid = Process.fork do
+ if Thread.pending_interrupt?
+ exit 1
+ end
+ end
+
+ _, status = Process.waitpid2(pid)
+ assert_predicate status, :success?
+
+ assert_predicate Thread, :pending_interrupt?
+ end
+ rescue RuntimeError
+ # Ignore.
+ end if defined?(fork)
end
diff --git a/test/ruby/test_rand.rb b/test/ruby/test_rand.rb
index f066433f6a..a4beffd689 100644
--- a/test/ruby/test_rand.rb
+++ b/test/ruby/test_rand.rb
@@ -336,6 +336,14 @@ class TestRand < Test::Unit::TestCase
}
end
+ def test_seed_leading_zero_guard
+ guard = 1<<32
+ range = 0...(1<<32)
+ all_assertions_foreach(nil, 0, 1, 2) do |i|
+ assert_not_equal(Random.new(i).rand(range), Random.new(i+guard).rand(range))
+ end
+ end
+
def test_marshal
bug3656 = '[ruby-core:31622]'
assert_raise(TypeError, bug3656) {
diff --git a/test/ruby/test_random_formatter.rb b/test/ruby/test_random_formatter.rb
index a5072099e1..f927522d96 100644
--- a/test/ruby/test_random_formatter.rb
+++ b/test/ruby/test_random_formatter.rb
@@ -75,6 +75,47 @@ module Random::Formatter
assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid)
end
+ def assert_uuid_v7(**opts)
+ t1 = current_uuid7_time(**opts)
+ uuid = @it.uuid_v7(**opts)
+ t3 = current_uuid7_time(**opts)
+
+ assert_match(/\A\h{8}-\h{4}-7\h{3}-[89ab]\h{3}-\h{12}\z/, uuid)
+
+ t2 = get_uuid7_time(uuid, **opts)
+ assert_operator(t1, :<=, t2)
+ assert_operator(t2, :<=, t3)
+ end
+
+ def test_uuid_v7
+ assert_uuid_v7
+ 0.upto(12) do |extra_timestamp_bits|
+ assert_uuid_v7 extra_timestamp_bits: extra_timestamp_bits
+ end
+ end
+
+ # It would be nice to simply use Time#floor here. But that is problematic
+ # due to the difference between decimal vs binary fractions.
+ def current_uuid7_time(extra_timestamp_bits: 0)
+ denominator = (1 << extra_timestamp_bits).to_r
+ Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
+ .then {|ns| ((ns / 1_000_000r) * denominator).floor / denominator }
+ .then {|ms| Time.at(ms / 1000r, in: "+00:00") }
+ end
+
+ def get_uuid7_time(uuid, extra_timestamp_bits: 0)
+ denominator = (1 << extra_timestamp_bits) * 1000r
+ extra_chars = extra_timestamp_bits / 4
+ last_char_bits = extra_timestamp_bits % 4
+ extra_chars += 1 if last_char_bits != 0
+ timestamp_re = /\A(\h{8})-(\h{4})-7(\h{#{extra_chars}})/
+ timestamp_chars = uuid.match(timestamp_re).captures.join
+ timestamp = timestamp_chars.to_i(16)
+ timestamp >>= 4 - last_char_bits unless last_char_bits == 0
+ timestamp /= denominator
+ Time.at timestamp, in: "+00:00"
+ end
+
def test_alphanumeric
65.times do |n|
an = @it.alphanumeric(n)
@@ -83,6 +124,20 @@ module Random::Formatter
end
end
+ def test_alphanumeric_chars
+ [
+ [[*"0".."9"], /\A\d*\z/],
+ [[*"a".."t"], /\A[a-t]*\z/],
+ ["一二三四五六七八九十".chars, /\A[一二三四五六七八九十]*\z/],
+ ].each do |chars, pattern|
+ 10.times do |n|
+ an = @it.alphanumeric(n, chars: chars)
+ assert_match(pattern, an)
+ assert_equal(n, an.length)
+ end
+ end
+ end
+
def assert_in_range(range, result, mesg = nil)
assert(range.cover?(result), build_message(mesg, "Expected #{result} to be in #{range}"))
end
diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb
index 0df0a985ad..84b3b205f0 100644
--- a/test/ruby/test_range.rb
+++ b/test/ruby/test_range.rb
@@ -2,7 +2,7 @@
require 'test/unit'
require 'delegate'
require 'timeout'
-require 'bigdecimal'
+require 'date'
require 'rbconfig/sizeof'
class TestRange < Test::Unit::TestCase
@@ -392,6 +392,26 @@ class TestRange < Test::Unit::TestCase
assert_equal(4, (1.0...5.6).step(1.5).to_a.size)
end
+ def test_step_with_succ
+ c = Struct.new(:i) do
+ def succ; self.class.new(i+1); end
+ def <=>(other) i <=> other.i;end
+ end.new(0)
+
+ result = []
+ (c..c.succ).step(2) do |d|
+ result << d.i
+ end
+ assert_equal([0], result)
+
+ result = []
+ (c..).step(2) do |d|
+ result << d.i
+ break if d.i >= 4
+ end
+ assert_equal([0, 2, 4], result)
+ end
+
def test_each
a = []
(0..10).each {|x| a << x }
@@ -456,6 +476,171 @@ class TestRange < Test::Unit::TestCase
assert_equal(["a", "b", "c"], a)
end
+ def test_each_with_succ
+ c = Struct.new(:i) do
+ def succ; self.class.new(i+1); end
+ def <=>(other) i <=> other.i;end
+ end.new(0)
+
+ result = []
+ (c..c.succ).each do |d|
+ result << d.i
+ end
+ assert_equal([0, 1], result)
+
+ result = []
+ (c..).each do |d|
+ result << d.i
+ break if d.i >= 4
+ end
+ assert_equal([0, 1, 2, 3, 4], result)
+ end
+
+ def test_reverse_each
+ a = []
+ (1..3).reverse_each {|x| a << x }
+ assert_equal([3, 2, 1], a)
+
+ a = []
+ (1...3).reverse_each {|x| a << x }
+ assert_equal([2, 1], a)
+
+ fmax = RbConfig::LIMITS['FIXNUM_MAX']
+ fmin = RbConfig::LIMITS['FIXNUM_MIN']
+
+ a = []
+ (fmax+1..fmax+3).reverse_each {|x| a << x }
+ assert_equal([fmax+3, fmax+2, fmax+1], a)
+
+ a = []
+ (fmax+1...fmax+3).reverse_each {|x| a << x }
+ assert_equal([fmax+2, fmax+1], a)
+
+ a = []
+ (fmax-1..fmax+1).reverse_each {|x| a << x }
+ assert_equal([fmax+1, fmax, fmax-1], a)
+
+ a = []
+ (fmax-1...fmax+1).reverse_each {|x| a << x }
+ assert_equal([fmax, fmax-1], a)
+
+ a = []
+ (fmin-1..fmin+1).reverse_each{|x| a << x }
+ assert_equal([fmin+1, fmin, fmin-1], a)
+
+ a = []
+ (fmin-1...fmin+1).reverse_each{|x| a << x }
+ assert_equal([fmin, fmin-1], a)
+
+ a = []
+ (fmin-3..fmin-1).reverse_each{|x| a << x }
+ assert_equal([fmin-1, fmin-2, fmin-3], a)
+
+ a = []
+ (fmin-3...fmin-1).reverse_each{|x| a << x }
+ assert_equal([fmin-2, fmin-3], a)
+
+ a = []
+ ("a".."c").reverse_each {|x| a << x }
+ assert_equal(["c", "b", "a"], a)
+ end
+
+ def test_reverse_each_for_beginless_range
+ fmax = RbConfig::LIMITS['FIXNUM_MAX']
+ fmin = RbConfig::LIMITS['FIXNUM_MIN']
+
+ a = []
+ (..3).reverse_each {|x| a << x; break if x <= 0 }
+ assert_equal([3, 2, 1, 0], a)
+
+ a = []
+ (...3).reverse_each {|x| a << x; break if x <= 0 }
+ assert_equal([2, 1, 0], a)
+
+ a = []
+ (..fmax+1).reverse_each {|x| a << x; break if x <= fmax-1 }
+ assert_equal([fmax+1, fmax, fmax-1], a)
+
+ a = []
+ (...fmax+1).reverse_each {|x| a << x; break if x <= fmax-1 }
+ assert_equal([fmax, fmax-1], a)
+
+ a = []
+ (..fmin+1).reverse_each {|x| a << x; break if x <= fmin-1 }
+ assert_equal([fmin+1, fmin, fmin-1], a)
+
+ a = []
+ (...fmin+1).reverse_each {|x| a << x; break if x <= fmin-1 }
+ assert_equal([fmin, fmin-1], a)
+
+ a = []
+ (..fmin-1).reverse_each {|x| a << x; break if x <= fmin-3 }
+ assert_equal([fmin-1, fmin-2, fmin-3], a)
+
+ a = []
+ (...fmin-1).reverse_each {|x| a << x; break if x <= fmin-3 }
+ assert_equal([fmin-2, fmin-3], a)
+ end
+
+ def test_reverse_each_for_endless_range
+ assert_raise(TypeError) { (1..).reverse_each {} }
+
+ enum = nil
+ assert_nothing_raised { enum = (1..).reverse_each }
+ assert_raise(TypeError) { enum.each {} }
+ end
+
+ def test_reverse_each_for_single_point_range
+ fmin = RbConfig::LIMITS['FIXNUM_MIN']
+ fmax = RbConfig::LIMITS['FIXNUM_MAX']
+
+ values = [fmin*2, fmin-1, fmin, 0, fmax, fmax+1, fmax*2]
+
+ values.each do |b|
+ r = b..b
+ a = []
+ r.reverse_each {|x| a << x }
+ assert_equal([b], a, "failed on #{r}")
+
+ r = b...b+1
+ a = []
+ r.reverse_each {|x| a << x }
+ assert_equal([b], a, "failed on #{r}")
+ end
+ end
+
+ def test_reverse_each_for_empty_range
+ fmin = RbConfig::LIMITS['FIXNUM_MIN']
+ fmax = RbConfig::LIMITS['FIXNUM_MAX']
+
+ values = [fmin*2, fmin-1, fmin, 0, fmax, fmax+1, fmax*2]
+
+ values.each do |b|
+ r = b..b-1
+ a = []
+ r.reverse_each {|x| a << x }
+ assert_equal([], a, "failed on #{r}")
+ end
+
+ values.repeated_permutation(2).to_a.product([true, false]).each do |(b, e), excl|
+ next unless b > e || (b == e && excl)
+
+ r = Range.new(b, e, excl)
+ a = []
+ r.reverse_each {|x| a << x }
+ assert_equal([], a, "failed on #{r}")
+ end
+ end
+
+ def test_reverse_each_with_no_block
+ enum = (1..5).reverse_each
+ assert_equal 5, enum.size
+
+ a = []
+ enum.each {|x| a << x }
+ assert_equal [5, 4, 3, 2, 1], a
+ end
+
def test_begin_end
assert_equal(0, (0..1).begin)
assert_equal(1, (0..1).end)
@@ -539,6 +724,10 @@ class TestRange < Test::Unit::TestCase
assert_not_operator(0..10, :===, 11)
assert_operator(5..nil, :===, 11)
assert_not_operator(5..nil, :===, 0)
+ assert_operator(nil..10, :===, 0)
+ assert_operator(nil..nil, :===, 0)
+ assert_operator(nil..nil, :===, Object.new)
+ assert_not_operator(0..10, :===, 0..10)
end
def test_eqq_string
@@ -583,6 +772,28 @@ class TestRange < Test::Unit::TestCase
assert_operator(c.new(0)..c.new(10), :===, c.new(5), bug12003)
end
+ def test_eqq_unbounded_ruby_bug_19864
+ t1 = Date.today
+ t2 = t1 + 1
+ assert_equal(true, (..t1) === t1)
+ assert_equal(false, (..t1) === t2)
+ assert_equal(true, (..t2) === t1)
+ assert_equal(true, (..t2) === t2)
+ assert_equal(false, (...t1) === t1)
+ assert_equal(false, (...t1) === t2)
+ assert_equal(true, (...t2) === t1)
+ assert_equal(false, (...t2) === t2)
+
+ assert_equal(true, (t1..) === t1)
+ assert_equal(true, (t1..) === t2)
+ assert_equal(false, (t2..) === t1)
+ assert_equal(true, (t2..) === t2)
+ assert_equal(true, (t1...) === t1)
+ assert_equal(true, (t1...) === t2)
+ assert_equal(false, (t2...) === t1)
+ assert_equal(true, (t2...) === t2)
+ end
+
def test_eqq_non_iteratable
k = Class.new do
include Comparable
@@ -599,13 +810,14 @@ class TestRange < Test::Unit::TestCase
assert_include("a"..."z", "y")
assert_not_include("a"..."z", "z")
assert_not_include("a".."z", "cc")
- assert_include("a".., "c")
- assert_not_include("a".., "5")
+ assert_raise(TypeError) {("a"..).include?("c")}
+ assert_raise(TypeError) {("a"..).include?("5")}
+
assert_include(0...10, 5)
assert_include(5..., 10)
assert_not_include(5..., 0)
- assert_include(.."z", "z")
- assert_not_include(..."z", "z")
+ assert_raise(TypeError) {(.."z").include?("z")}
+ assert_raise(TypeError) {(..."z").include?("z")}
assert_include(..10, 10)
assert_not_include(...10, 10)
end
@@ -771,18 +983,38 @@ class TestRange < Test::Unit::TestCase
end
def test_size
- assert_equal 42, (1..42).size
- assert_equal 41, (1...42).size
- assert_equal 6, (1...6.3).size
- assert_equal 5, (1.1...6).size
- assert_equal 42, (1..42).each.size
+ Enumerator.product([:to_i, :to_f, :to_r].repeated_permutation(2), [1, 10], [5, 5.5], [true, false]) do |(m1, m2), beg, ende, exclude_end|
+ r = Range.new(beg.send(m1), ende.send(m2), exclude_end)
+ iterable = true
+ yielded = []
+ begin
+ r.each { yielded << _1 }
+ rescue TypeError
+ iterable = false
+ end
+
+ if iterable
+ assert_equal(yielded.size, r.size, "failed on #{r}")
+ assert_equal(yielded.size, r.each.size, "failed on #{r}")
+ else
+ assert_raise(TypeError, "failed on #{r}") { r.size }
+ assert_raise(TypeError, "failed on #{r}") { r.each.size }
+ end
+ end
+
assert_nil ("a"..."z").size
- assert_equal Float::INFINITY, (1...).size
- assert_equal Float::INFINITY, (1.0...).size
- assert_equal Float::INFINITY, (...1).size
- assert_equal Float::INFINITY, (...1.0).size
- assert_nil ("a"...).size
+ assert_equal Float::INFINITY, (1..).size
+ assert_raise(TypeError) { (1.0..).size }
+ assert_raise(TypeError) { (1r..).size }
+ assert_nil ("a"..).size
+
+ assert_raise(TypeError) { (..1).size }
+ assert_raise(TypeError) { (..1.0).size }
+ assert_raise(TypeError) { (..1r).size }
+ assert_raise(TypeError) { (..'z').size }
+
+ assert_raise(TypeError) { (nil...nil).size }
end
def test_bsearch_typechecks_return_values
@@ -806,9 +1038,6 @@ class TestRange < Test::Unit::TestCase
assert_raise(TypeError) {
(Rational(-1,2)..Rational(9,4)).bsearch
}
- assert_raise(TypeError) {
- (BigDecimal('0.5')..BigDecimal('2.25')).bsearch
- }
end
def test_bsearch_for_fixnum
@@ -982,7 +1211,10 @@ class TestRange < Test::Unit::TestCase
assert_equal(nil, (bignum...bignum+ary.size).bsearch {|i| ary[i - bignum] >= 100 })
assert_equal(bignum + 0, (bignum...bignum+ary.size).bsearch {|i| true })
assert_equal(nil, (bignum...bignum+ary.size).bsearch {|i| false })
+
+ assert_equal(bignum * 2 + 1, (0...).bsearch {|i| i > bignum * 2 })
assert_equal(bignum * 2 + 1, (bignum...).bsearch {|i| i > bignum * 2 })
+ assert_equal(-bignum * 2 + 1, (...0).bsearch {|i| i > -bignum * 2 })
assert_equal(-bignum * 2 + 1, (...-bignum).bsearch {|i| i > -bignum * 2 })
assert_raise(TypeError) { ("a".."z").bsearch {} }
@@ -1007,6 +1239,81 @@ class TestRange < Test::Unit::TestCase
end
def test_count
+ assert_equal 42, (1..42).count
+ assert_equal 41, (1...42).count
+ assert_equal 0, (42..1).count
+ assert_equal 0, (42...1).count
+ assert_equal 2**100, (1..2**100).count
+ assert_equal 6, (1...6.3).count
+ assert_equal 4, ('a'..'d').count
+ assert_equal 3, ('a'...'d').count
+
assert_equal(Float::INFINITY, (1..).count)
+ assert_equal(Float::INFINITY, (..1).count)
+ end
+
+ def test_overlap?
+ assert_not_operator(0..2, :overlap?, -2..-1)
+ assert_not_operator(0..2, :overlap?, -2...0)
+ assert_operator(0..2, :overlap?, -1..0)
+ assert_operator(0..2, :overlap?, 1..2)
+ assert_operator(0..2, :overlap?, 2..3)
+ assert_not_operator(0..2, :overlap?, 3..4)
+ assert_not_operator(0...2, :overlap?, 2..3)
+
+ assert_operator(..0, :overlap?, -1..0)
+ assert_operator(...0, :overlap?, -1..0)
+ assert_operator(..0, :overlap?, 0..1)
+ assert_operator(..0, :overlap?, ..1)
+ assert_not_operator(..0, :overlap?, 1..2)
+ assert_not_operator(...0, :overlap?, 0..1)
+
+ assert_not_operator(0.., :overlap?, -2..-1)
+ assert_not_operator(0.., :overlap?, ...0)
+ assert_operator(0.., :overlap?, -1..0)
+ assert_operator(0.., :overlap?, ..0)
+ assert_operator(0.., :overlap?, 0..1)
+ assert_operator(0.., :overlap?, 1..2)
+ assert_operator(0.., :overlap?, 1..)
+
+ assert_not_operator((1..3), :overlap?, ('a'..'d'))
+ assert_not_operator((1..), :overlap?, ('a'..))
+ assert_not_operator((..1), :overlap?, (..'a'))
+
+ assert_raise(TypeError) { (0..).overlap?(1) }
+ assert_raise(TypeError) { (0..).overlap?(nil) }
+
+ assert_operator((1..3), :overlap?, (2..4))
+ assert_operator((1...3), :overlap?, (2..3))
+ assert_operator((2..3), :overlap?, (1..2))
+ assert_operator((..3), :overlap?, (3..))
+ assert_operator((nil..nil), :overlap?, (3..))
+ assert_operator((nil...nil), :overlap?, (nil..))
+
+ assert_raise(TypeError) { (1..3).overlap?(1) }
+
+ assert_not_operator((1..2), :overlap?, (2...2))
+ assert_not_operator((2...2), :overlap?, (1..2))
+
+ assert_not_operator((4..1), :overlap?, (2..3))
+ assert_not_operator((4..1), :overlap?, (..3))
+ assert_not_operator((4..1), :overlap?, (2..))
+
+ assert_not_operator((1..4), :overlap?, (3..2))
+ assert_not_operator((..4), :overlap?, (3..2))
+ assert_not_operator((1..), :overlap?, (3..2))
+
+ assert_not_operator((4..5), :overlap?, (2..3))
+ assert_not_operator((4..5), :overlap?, (2...4))
+
+ assert_not_operator((1..2), :overlap?, (3..4))
+ assert_not_operator((1...3), :overlap?, (3..4))
+
+ assert_not_operator((4..5), :overlap?, (2..3))
+ assert_not_operator((4..5), :overlap?, (2...4))
+
+ assert_not_operator((1..2), :overlap?, (3..4))
+ assert_not_operator((1...3), :overlap?, (3..4))
+ assert_not_operator((...3), :overlap?, (3..))
end
end
diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb
index fe9de64c4c..a51ce3dc99 100644
--- a/test/ruby/test_rational.rb
+++ b/test/ruby/test_rational.rb
@@ -823,6 +823,8 @@ class Rational_Test < Test::Unit::TestCase
ng[5, 1, '5/_3']
ng[5, 3, '5/3_']
ng[5, 3, '5/3x']
+
+ ng[5, 1, '5/-3']
end
def test_parse_zero_denominator
diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb
index 56f33ae00a..11acf31f21 100644
--- a/test/ruby/test_refinement.rb
+++ b/test/ruby/test_refinement.rb
@@ -1044,7 +1044,7 @@ class TestRefinement < Test::Unit::TestCase
end
using Test
def t
- 'Refinements are broken!'.chop!
+ 'Refinements are broken!'.dup.chop!
end
t
module Test
@@ -1606,18 +1606,35 @@ class TestRefinement < Test::Unit::TestCase
end
using R
+ def m
+ C.new.m
+ end
+
assert_equal(:foo, C.new.m)
+ assert_equal(:foo, m)
module R
refine C do
+
+ assert_equal(:foo, C.new.m)
+ assert_equal(:foo, m)
+
alias m m
+
+ assert_equal(:foo, C.new.m)
+ assert_equal(:foo, m)
+
def m
:bar
end
+
+ assert_equal(:bar, C.new.m, "[ruby-core:71423] [Bug #11672]")
+ assert_equal(:bar, m, "[Bug #20285]")
end
end
assert_equal(:bar, C.new.m, "[ruby-core:71423] [Bug #11672]")
+ assert_equal(:bar, m, "[Bug #20285]")
end;
end
@@ -1798,7 +1815,7 @@ class TestRefinement < Test::Unit::TestCase
assert_equal([int_refinement, str_refinement], m.refinements)
end
- def test_refined_class
+ def test_target
refinements = Module.new {
refine Integer do
end
@@ -1806,8 +1823,14 @@ class TestRefinement < Test::Unit::TestCase
refine String do
end
}.refinements
- assert_equal(Integer, refinements[0].refined_class)
- assert_equal(String, refinements[1].refined_class)
+ assert_equal(Integer, refinements[0].target)
+ assert_warn(/Refinement#refined_class is deprecated and will be removed in Ruby 3.4; use Refinement#target instead/) do
+ assert_equal(Integer, refinements[0].refined_class)
+ end
+ assert_equal(String, refinements[1].target)
+ assert_warn(/Refinement#refined_class is deprecated and will be removed in Ruby 3.4; use Refinement#target instead/) do
+ assert_equal(String, refinements[1].refined_class)
+ end
end
def test_warn_setconst_in_refinmenet
@@ -2626,6 +2649,75 @@ class TestRefinement < Test::Unit::TestCase
assert_equal([], Refinement.used_modules)
end
+ def test_inlinecache
+ assert_separately([], <<-"end;")
+ module R
+ refine String do
+ def to_s = :R
+ end
+ end
+
+ 2.times{|i|
+ s = ''.to_s
+ assert_equal '', s if i == 0
+ assert_equal :R, s if i == 1
+ using R if i == 0
+ assert_equal :R, ''.to_s
+ }
+ end;
+ end
+
+ def test_inline_cache_invalidation
+ klass = Class.new do
+ def cached_foo_callsite = foo
+
+ def foo = :v1
+
+ host = self
+ @refinement = Module.new do
+ refine(host) do
+ def foo = :unused
+ end
+ end
+ end
+
+ obj = klass.new
+ obj.cached_foo_callsite # prime cache
+ klass.class_eval do
+ def foo = :v2 # invalidate
+ end
+ assert_equal(:v2, obj.cached_foo_callsite)
+ end
+
+ # [Bug #20302]
+ def test_multiple_refinements_for_same_module
+ assert_in_out_err([], <<-INPUT, %w(:f2 :f1), [])
+ module M1
+ refine(Kernel) do
+ def f1 = :f1
+ end
+ end
+
+ module M2
+ refine(Kernel) do
+ def f2 = :f2
+ end
+ end
+
+ class Foo
+ using M1
+ using M2
+
+ def test
+ p f2
+ p f1
+ end
+ end
+
+ Foo.new.test
+ INPUT
+ end
+
private
def eval_using(mod, s)
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index 1d93d1a5b1..c996b1785a 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -40,19 +40,6 @@ class TestRegexp < Test::Unit::TestCase
assert_equal("a".gsub(/a\Z/, ""), "")
end
- def test_yoshidam_net_20041111_1
- s = "[\xC2\xA0-\xC3\xBE]"
- r = assert_deprecated_warning(/ignored/) {Regexp.new(s, nil, "u")}
- assert_match(r, "\xC3\xBE")
- end
-
- def test_yoshidam_net_20041111_2
- assert_raise(RegexpError) do
- s = "[\xFF-\xFF]".force_encoding("utf-8")
- assert_warning(/ignored/) {Regexp.new(s, nil, "u")}
- end
- end
-
def test_ruby_dev_31309
assert_equal('Ruby', 'Ruby'.sub(/[^a-z]/i, '-'))
end
@@ -85,6 +72,19 @@ class TestRegexp < Test::Unit::TestCase
end
end
+ def test_to_s_under_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ str = "abcd\u3042"
+ [:UTF_16BE, :UTF_16LE, :UTF_32BE, :UTF_32LE].each do |es|
+ enc = Encoding.const_get(es)
+ rs = Regexp.new(str.encode(enc)).to_s
+ assert_equal("(?-mix:abcd\u3042)".encode(enc), rs)
+ assert_equal(enc, rs.encoding)
+ end
+ end
+ end
+
def test_to_s_extended_subexp
re = /#\g#{"\n"}/x
re = /#{re}/
@@ -144,6 +144,69 @@ class TestRegexp < Test::Unit::TestCase
assert_raise(SyntaxError) {eval "/# \\users/"}
end
+ def test_nonextended_section_of_extended_regexp_bug_19379
+ assert_separately([], <<-'RUBY')
+ re = /(?-x:#)/x
+ assert_match(re, '#')
+ assert_not_match(re, '-')
+
+ re = /(?xi:#
+ y)/
+ assert_match(re, 'Y')
+ assert_not_match(re, '-')
+
+ re = /(?mix:#
+ y)/
+ assert_match(re, 'Y')
+ assert_not_match(re, '-')
+
+ re = /(?x-im:#
+ y)/i
+ assert_match(re, 'y')
+ assert_not_match(re, 'Y')
+
+ re = /(?-imx:(?xim:#
+ y))/x
+ assert_match(re, 'y')
+ assert_not_match(re, '-')
+
+ re = /(?x)#
+ y/
+ assert_match(re, 'y')
+ assert_not_match(re, 'Y')
+
+ re = /(?mx-i)#
+ y/i
+ assert_match(re, 'y')
+ assert_not_match(re, 'Y')
+
+ re = /(?-imx:(?xim:#
+ (?-x)y#))/x
+ assert_match(re, 'Y#')
+ assert_not_match(re, '-#')
+
+ re = /(?imx:#
+ (?-xim:#(?im)#(?x)#
+ )#
+ (?x)#
+ y)/
+ assert_match(re, '###Y')
+ assert_not_match(re, '###-')
+
+ re = %r{#c-\w+/comment/[\w-]+}
+ re = %r{https?://[^/]+#{re}}x
+ assert_match(re, 'http://foo#c-x/comment/bar')
+ assert_not_match(re, 'http://foo#cx/comment/bar')
+ RUBY
+ end
+
+ def test_utf8_comment_in_usascii_extended_regexp_bug_19455
+ assert_separately([], <<-RUBY)
+ assert_equal(Encoding::UTF_8, /(?#\u1000)/x.encoding)
+ assert_equal(Encoding::UTF_8, /#\u1000/x.encoding)
+ RUBY
+ end
+
def test_union
assert_equal :ok, begin
Regexp.union(
@@ -261,6 +324,9 @@ class TestRegexp < Test::Unit::TestCase
assert_equal({'a' => '1', 'b' => '2', 'c' => '3'}, /^(?<a>.)(?<b>.)(?<c>.)?/.match('123').named_captures)
assert_equal({'a' => '1', 'b' => '2', 'c' => ''}, /^(?<a>.)(?<b>.)(?<c>.?)/.match('12').named_captures)
+ assert_equal({a: '1', b: '2', c: ''}, /^(?<a>.)(?<b>.)(?<c>.?)/.match('12').named_captures(symbolize_names: true))
+ assert_equal({'a' => '1', 'b' => '2', 'c' => ''}, /^(?<a>.)(?<b>.)(?<c>.?)/.match('12').named_captures(symbolize_names: false))
+
assert_equal({'a' => 'x'}, /(?<a>x)|(?<a>y)/.match('x').named_captures)
assert_equal({'a' => 'y'}, /(?<a>x)|(?<a>y)/.match('y').named_captures)
@@ -404,6 +470,13 @@ class TestRegexp < Test::Unit::TestCase
assert_equal('/\/\xF1\xF2\xF3/i', /\/#{s}/i.inspect)
end
+ def test_inspect_under_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ assert_equal('/(?-mix:\\/)|/', Regexp.union(/\//, "").inspect)
+ end
+ end
+
def test_char_to_option
assert_equal("BAR", "FOOBARBAZ"[/b../i])
assert_equal("bar", "foobarbaz"[/ b . . /x])
@@ -608,19 +681,73 @@ class TestRegexp < Test::Unit::TestCase
assert_equal('#<MatchData "foobarbaz" 1:"foo" 2:"bar" 3:"baz" 4:nil>', m.inspect)
end
+ def test_match_data_deconstruct
+ m = /foo.+/.match("foobarbaz")
+ assert_equal([], m.deconstruct)
+
+ m = /(foo).+(baz)/.match("foobarbaz")
+ assert_equal(["foo", "baz"], m.deconstruct)
+
+ m = /(...)(...)(...)(...)?/.match("foobarbaz")
+ assert_equal(["foo", "bar", "baz", nil], m.deconstruct)
+ end
+
+ def test_match_data_deconstruct_keys
+ m = /foo.+/.match("foobarbaz")
+ assert_equal({}, m.deconstruct_keys([:a]))
+
+ m = /(?<a>foo).+(?<b>baz)/.match("foobarbaz")
+ assert_equal({a: "foo", b: "baz"}, m.deconstruct_keys(nil))
+ assert_equal({a: "foo", b: "baz"}, m.deconstruct_keys([:a, :b]))
+ assert_equal({b: "baz"}, m.deconstruct_keys([:b]))
+ assert_equal({}, m.deconstruct_keys([:c, :a]))
+ assert_equal({a: "foo"}, m.deconstruct_keys([:a, :c]))
+ assert_equal({}, m.deconstruct_keys([:a, :b, :c]))
+
+ assert_raise(TypeError) {
+ m.deconstruct_keys(0)
+ }
+
+ assert_raise(TypeError) {
+ m.deconstruct_keys(["a", "b"])
+ }
+ end
+
+ def test_match_no_match_no_matchdata
+ EnvUtil.without_gc do
+ h = {}
+ ObjectSpace.count_objects(h)
+ prev_matches = h[:T_MATCH] || 0
+ _md = /[A-Z]/.match('1') # no match
+ ObjectSpace.count_objects(h)
+ new_matches = h[:T_MATCH] || 0
+ assert_equal prev_matches, new_matches, "Bug [#20104]"
+ end
+ end
+
def test_initialize
assert_raise(ArgumentError) { Regexp.new }
assert_equal(/foo/, assert_warning(/ignored/) {Regexp.new(/foo/, Regexp::IGNORECASE)})
assert_equal(/foo/, assert_no_warning(/ignored/) {Regexp.new(/foo/)})
assert_equal(/foo/, assert_no_warning(/ignored/) {Regexp.new(/foo/, timeout: nil)})
- assert_equal(Encoding.find("US-ASCII"), Regexp.new("b..", nil, "n").encoding)
- assert_equal("bar", "foobarbaz"[Regexp.new("b..", nil, "n")])
- assert_equal(//n, Regexp.new("", nil, "n"))
+ arg_encoding_none = //n.options # ARG_ENCODING_NONE is implementation defined value
+
+ assert_deprecated_warning('') do
+ assert_equal(Encoding.find("US-ASCII"), Regexp.new("b..", Regexp::NOENCODING).encoding)
+ assert_equal("bar", "foobarbaz"[Regexp.new("b..", Regexp::NOENCODING)])
+ assert_equal(//, Regexp.new(""))
+ assert_equal(//, Regexp.new("", timeout: 1))
+ assert_equal(//n, Regexp.new("", Regexp::NOENCODING))
+ assert_equal(//n, Regexp.new("", Regexp::NOENCODING, timeout: 1))
- arg_encoding_none = 32 # ARG_ENCODING_NONE is implementation defined value
- assert_equal(arg_encoding_none, Regexp.new("", nil, "n").options)
- assert_equal(arg_encoding_none, Regexp.new("", nil, "N").options)
+ assert_equal(arg_encoding_none, Regexp.new("", Regexp::NOENCODING).options)
+
+ assert_nil(Regexp.new("").timeout)
+ assert_equal(1.0, Regexp.new("", timeout: 1.0).timeout)
+ assert_nil(Regexp.compile("").timeout)
+ assert_equal(1.0, Regexp.compile("", timeout: 1.0).timeout)
+ end
assert_raise(RegexpError) { Regexp.new(")(") }
assert_raise(RegexpError) { Regexp.new('[\\40000000000') }
@@ -628,6 +755,12 @@ class TestRegexp < Test::Unit::TestCase
assert_raise(RegexpError) { Regexp.new("((?<v>))\\g<0>") }
end
+ def test_initialize_from_regex_memory_corruption
+ assert_ruby_status([], <<-'end;')
+ 10_000.times { Regexp.new(Regexp.new("(?<name>)")) }
+ end;
+ end
+
def test_initialize_bool_warning
assert_warning(/expected true or false as ignorecase/) do
Regexp.new("foo", :i)
@@ -759,6 +892,14 @@ class TestRegexp < Test::Unit::TestCase
$_ = nil; assert_nil(~/./)
end
+ def test_match_under_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ m = /(?<foo>.)(?<n>[^aeiou])?(?<bar>.+)/.match("hoge\u3042")
+ assert_equal("h", m.match(:foo))
+ end
+ end
+
def test_match_p
/backref/ =~ 'backref'
# must match here, but not in a separate method, e.g., assert_send,
@@ -1265,30 +1406,109 @@ class TestRegexp < Test::Unit::TestCase
end
def test_unicode_age
- assert_match(/^\p{Age=6.0}$/u, "\u261c")
- assert_match(/^\p{Age=1.1}$/u, "\u261c")
- assert_no_match(/^\P{age=6.0}$/u, "\u261c")
-
- assert_match(/^\p{age=6.0}$/u, "\u31f6")
- assert_match(/^\p{age=3.2}$/u, "\u31f6")
- assert_no_match(/^\p{age=3.1}$/u, "\u31f6")
- assert_no_match(/^\p{age=3.0}$/u, "\u31f6")
- assert_no_match(/^\p{age=1.1}$/u, "\u31f6")
-
- assert_match(/^\p{age=6.0}$/u, "\u2754")
- assert_no_match(/^\p{age=5.0}$/u, "\u2754")
- assert_no_match(/^\p{age=4.0}$/u, "\u2754")
- assert_no_match(/^\p{age=3.0}$/u, "\u2754")
- assert_no_match(/^\p{age=2.0}$/u, "\u2754")
- assert_no_match(/^\p{age=1.1}$/u, "\u2754")
-
- assert_no_match(/^\p{age=12.0}$/u, "\u32FF")
- assert_match(/^\p{age=12.1}$/u, "\u32FF")
- assert_no_match(/^\p{age=13.0}$/u, "\u{10570}")
- assert_match(/^\p{age=14.0}$/u, "\u{10570}")
- assert_match(/^\p{age=14.0}$/u, "\u9FFF")
- assert_match(/^\p{age=14.0}$/u, "\u{2A6DF}")
- assert_match(/^\p{age=14.0}$/u, "\u{2B738}")
+ assert_unicode_age("\u261c", matches: %w"6.0 1.1", unmatches: [])
+
+ assert_unicode_age("\u31f6", matches: %w"6.0 3.2", unmatches: %w"3.1 3.0 1.1")
+ assert_unicode_age("\u2754", matches: %w"6.0", unmatches: %w"5.0 4.0 3.0 2.0 1.1")
+
+ assert_unicode_age("\u32FF", matches: %w"12.1", unmatches: %w"12.0")
+ end
+
+ def test_unicode_age_14_0
+ @matches = %w"14.0"
+ @unmatches = %w"13.0"
+
+ assert_unicode_age("\u{10570}")
+ assert_unicode_age("\u9FFF")
+ assert_unicode_age("\u{2A6DF}")
+ assert_unicode_age("\u{2B738}")
+ end
+
+ def test_unicode_age_15_0
+ @matches = %w"15.0"
+ @unmatches = %w"14.0"
+
+ assert_unicode_age("\u{0CF3}",
+ "KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT")
+ assert_unicode_age("\u{0ECE}", "LAO YAMAKKAN")
+ assert_unicode_age("\u{10EFD}".."\u{10EFF}",
+ "ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA")
+ assert_unicode_age("\u{1123F}".."\u{11241}",
+ "KHOJKI LETTER QA..KHOJKI VOWEL SIGN VOCALIC R")
+ assert_unicode_age("\u{11B00}".."\u{11B09}",
+ "DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU")
+ assert_unicode_age("\u{11F00}".."\u{11F10}",
+ "KAWI SIGN CANDRABINDU..KAWI LETTER O")
+ assert_unicode_age("\u{11F12}".."\u{11F3A}",
+ "KAWI LETTER KA..KAWI VOWEL SIGN VOCALIC R")
+ assert_unicode_age("\u{11F3E}".."\u{11F59}",
+ "KAWI VOWEL SIGN E..KAWI DIGIT NINE")
+ assert_unicode_age("\u{1342F}",
+ "EGYPTIAN HIEROGLYPH V011D")
+ assert_unicode_age("\u{13439}".."\u{1343F}",
+ "EGYPTIAN HIEROGLYPH INSERT AT MIDDLE..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE")
+ assert_unicode_age("\u{13440}".."\u{13455}",
+ "EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED")
+ assert_unicode_age("\u{1B132}", "HIRAGANA LETTER SMALL KO")
+ assert_unicode_age("\u{1B155}", "KATAKANA LETTER SMALL KO")
+ assert_unicode_age("\u{1D2C0}".."\u{1D2D3}",
+ "KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN")
+ assert_unicode_age("\u{1DF25}".."\u{1DF2A}",
+ "LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK")
+ assert_unicode_age("\u{1E030}".."\u{1E06D}",
+ "MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE")
+ assert_unicode_age("\u{1E08F}",
+ "COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I")
+ assert_unicode_age("\u{1E4D0}".."\u{1E4F9}",
+ "NAG MUNDARI LETTER O..NAG MUNDARI DIGIT NINE")
+ assert_unicode_age("\u{1F6DC}", "WIRELESS")
+ assert_unicode_age("\u{1F774}".."\u{1F776}",
+ "LOT OF FORTUNE..LUNAR ECLIPSE")
+ assert_unicode_age("\u{1F77B}".."\u{1F77F}",
+ "HAUMEA..ORCUS")
+ assert_unicode_age("\u{1F7D9}", "NINE POINTED WHITE STAR")
+ assert_unicode_age("\u{1FA75}".."\u{1FA77}",
+ "LIGHT BLUE HEART..PINK HEART")
+ assert_unicode_age("\u{1FA87}".."\u{1FA88}",
+ "MARACAS..FLUTE")
+ assert_unicode_age("\u{1FAAD}".."\u{1FAAF}",
+ "FOLDING HAND FAN..KHANDA")
+ assert_unicode_age("\u{1FABB}".."\u{1FABD}",
+ "HYACINTH..WING")
+ assert_unicode_age("\u{1FABF}", "GOOSE")
+ assert_unicode_age("\u{1FACE}".."\u{1FACF}",
+ "MOOSE..DONKEY")
+ assert_unicode_age("\u{1FADA}".."\u{1FADB}",
+ "GINGER ROOT..PEA POD")
+ assert_unicode_age("\u{1FAE8}", "SHAKING FACE")
+ assert_unicode_age("\u{1FAF7}".."\u{1FAF8}",
+ "LEFTWARDS PUSHING HAND..RIGHTWARDS PUSHING HAND")
+ assert_unicode_age("\u{2B739}",
+ "CJK UNIFIED IDEOGRAPH-2B739")
+ assert_unicode_age("\u{31350}".."\u{323AF}",
+ "CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF")
+ end
+
+ UnicodeAgeRegexps = Hash.new do |h, age|
+ h[age] = [/\A\p{age=#{age}}+\z/u, /\A\P{age=#{age}}+\z/u].freeze
+ end
+
+ def assert_unicode_age(char, mesg = nil, matches: @matches, unmatches: @unmatches)
+ if Range === char
+ char = char.to_a.join("")
+ end
+
+ matches.each do |age|
+ pos, neg = UnicodeAgeRegexps[age]
+ assert_match(pos, char, mesg)
+ assert_not_match(neg, char, mesg)
+ end
+
+ unmatches.each do |age|
+ pos, neg = UnicodeAgeRegexps[age]
+ assert_not_match(pos, char, mesg)
+ assert_match(neg, char, mesg)
+ end
end
MatchData_A = eval("class MatchData_\u{3042} < MatchData; self; end")
@@ -1493,6 +1713,9 @@ class TestRegexp < Test::Unit::TestCase
assert_equal(0, /(?~(a)c)/ =~ "abb")
assert_nil($1)
+
+ assert_equal(0, /(?~(a))/ =~ "")
+ assert_nil($1)
end
def test_backref_overrun
@@ -1547,17 +1770,16 @@ class TestRegexp < Test::Unit::TestCase
end
def test_s_timeout
- assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(0.2).inspect }
begin;
- timeout = EnvUtil.apply_timeout_scale(0.2)
-
Regexp.timeout = timeout
- assert_equal(timeout, Regexp.timeout)
+ assert_in_delta(timeout, Regexp.timeout, timeout * 2 * Float::EPSILON)
t = Time.now
assert_raise_with_message(Regexp::TimeoutError, "regexp match timeout") do
# A typical ReDoS case
- /^(a*)*$/ =~ "a" * 1000000 + "x"
+ /^(a*)*\1$/ =~ "a" * 1000000 + "x"
end
t = Time.now - t
@@ -1565,15 +1787,60 @@ class TestRegexp < Test::Unit::TestCase
end;
end
- def test_timeout
- assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
+ def test_s_timeout_corner_cases
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
- dummy_timeout = EnvUtil.apply_timeout_scale(10)
- timeout = EnvUtil.apply_timeout_scale(0.2)
+ assert_nil(Regexp.timeout)
+
+ # This is just an implementation detail that users should not depend on:
+ # If Regexp.timeout is set to a value greater than the value that can be
+ # represented in the internal representation of timeout, it uses the
+ # maximum value that can be represented.
+ Regexp.timeout = Float::INFINITY
+ assert_equal(((1<<64)-1) / 1000000000.0, Regexp.timeout)
+
+ Regexp.timeout = 1e300
+ assert_equal(((1<<64)-1) / 1000000000.0, Regexp.timeout)
+
+ assert_raise(ArgumentError) { Regexp.timeout = 0 }
+ assert_raise(ArgumentError) { Regexp.timeout = -1 }
- Regexp.timeout = dummy_timeout # This should be ignored
+ Regexp.timeout = nil
+ assert_nil(Regexp.timeout)
+ end;
+ end
+
+ def test_s_timeout_memory_leak
+ assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~"end;"}", "[Bug #20228]", rss: true)
+ Regexp.timeout = 0.001
+ regex = /^(a*)*$/
+ str = "a" * 1000000 + "x"
+
+ code = proc do
+ regex =~ str
+ rescue
+ end
+
+ 10.times(&code)
+ begin;
+ 1_000.times(&code)
+ end;
+ end
+
+ def per_instance_redos_test(global_timeout, per_instance_timeout, expected_timeout)
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ global_timeout = #{ EnvUtil.apply_timeout_scale(global_timeout).inspect }
+ per_instance_timeout = #{ (per_instance_timeout ? EnvUtil.apply_timeout_scale(per_instance_timeout) : nil).inspect }
+ expected_timeout = #{ EnvUtil.apply_timeout_scale(expected_timeout).inspect }
+ begin;
+ Regexp.timeout = global_timeout
- re = Regexp.new("^a*b?a*$", timeout: timeout)
+ re = Regexp.new("^(a*)\\1b?a*$", timeout: per_instance_timeout)
+ if per_instance_timeout
+ assert_in_delta(per_instance_timeout, re.timeout, per_instance_timeout * 2 * Float::EPSILON)
+ else
+ assert_nil(re.timeout)
+ end
t = Time.now
assert_raise_with_message(Regexp::TimeoutError, "regexp match timeout") do
@@ -1581,7 +1848,229 @@ class TestRegexp < Test::Unit::TestCase
end
t = Time.now - t
- assert_in_delta(timeout, t, timeout / 2)
+ assert_in_delta(expected_timeout, t, expected_timeout * 3 / 4)
end;
end
+
+ def test_timeout_shorter_than_global
+ omit "timeout test is too unstable on s390x" if RUBY_PLATFORM =~ /s390x/
+ per_instance_redos_test(10, 0.2, 0.2)
+ end
+
+ def test_timeout_longer_than_global
+ omit "timeout test is too unstable on s390x" if RUBY_PLATFORM =~ /s390x/
+ per_instance_redos_test(0.01, 0.5, 0.5)
+ end
+
+ def test_timeout_nil
+ per_instance_redos_test(0.5, nil, 0.5)
+ end
+
+ def test_timeout_corner_cases
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ assert_nil(//.timeout)
+
+ # This is just an implementation detail that users should not depend on:
+ # If Regexp.timeout is set to a value greater than the value that can be
+ # represented in the internal representation of timeout, it uses the
+ # maximum value that can be represented.
+ assert_equal(((1<<64)-1) / 1000000000.0, Regexp.new("foo", timeout: Float::INFINITY).timeout)
+
+ assert_equal(((1<<64)-1) / 1000000000.0, Regexp.new("foo", timeout: 1e300).timeout)
+
+ assert_raise(ArgumentError) { Regexp.new("foo", timeout: 0) }
+ assert_raise(ArgumentError) { Regexp.new("foo", timeout: -1) }
+ end;
+ end
+
+ def test_match_cache_exponential
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/^(a*)*$/ =~ "a" * 1000000 + "x")
+ end;
+ end
+
+ def test_match_cache_square
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/^a*b?a*$/ =~ "a" * 1000000 + "x")
+ end;
+ end
+
+ def test_match_cache_atomic
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/^a*?(?>a*a*)$/ =~ "a" * 1000000 + "x")
+ end;
+ end
+
+ def test_match_cache_atomic_complex
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/a*(?>a*)ab/ =~ "a" * 1000000 + "b")
+ end;
+ end
+
+ def test_match_cache_positive_look_ahead
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/^a*?(?=a*a*)$/ =~ "a" * 1000000 + "x")
+ end;
+ end
+
+ def test_match_cache_positive_look_ahead_complex
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_equal(/(?:(?=a*)a)*/ =~ "a" * 1000000, 0)
+ end;
+ end
+
+ def test_match_cache_negative_look_ahead
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/^a*?(?!a*a*)$/ =~ "a" * 1000000 + "x")
+ end;
+ end
+
+ def test_match_cache_positive_look_behind
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/(?<=abc|def)(a|a)*$/ =~ "abc" + "a" * 1000000 + "x")
+ end;
+ end
+
+ def test_match_cache_negative_look_behind
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/(?<!x)(a|a)*$/ =~ "a" * 1000000 + "x")
+ end;
+ end
+
+ def test_match_cache_with_peek_optimization
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+ assert_nil(/a+z/ =~ "a" * 1000000 + "xz")
+ end;
+ end
+
+ def test_cache_opcodes_initialize
+ str = 'test1-test2-test3-test4-test_5'
+ re = '^([0-9a-zA-Z\-/]*){1,256}$'
+ 100.times do
+ assert !Regexp.new(re).match?(str)
+ end
+ end
+
+ def test_bug_19273 # [Bug #19273]
+ pattern = /(?:(?:-?b)|(?:-?(?:1_?(?:0_?)*)?0))(?::(?:(?:-?b)|(?:-?(?:1_?(?:0_?)*)?0))){0,3}/
+ assert_equal("10:0:0".match(pattern)[0], "10:0:0")
+ end
+
+ def test_bug_19467 # [Bug #19467]
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ timeout = #{ EnvUtil.apply_timeout_scale(10).inspect }
+ begin;
+ Regexp.timeout = timeout
+
+ assert_nil(/\A.*a.*z\z/ =~ "a" * 1000000 + "y")
+ end;
+ end
+
+ def test_bug_19476 # [Bug #19476]
+ assert_equal("123456789".match(/(?:x?\dx?){2,10}/)[0], "123456789")
+ assert_equal("123456789".match(/(?:x?\dx?){2,}/)[0], "123456789")
+ end
+
+ def test_encoding_flags_are_preserved_when_initialized_with_another_regexp
+ re = Regexp.new("\u2018hello\u2019".encode("UTF-8"))
+ str = "".encode("US-ASCII")
+
+ assert_nothing_raised do
+ str.match?(re)
+ str.match?(Regexp.new(re))
+ end
+ end
+
+ def test_bug_19537 # [Bug #19537]
+ str = 'aac'
+ re = '^([ab]{1,3})(a?)*$'
+ 100.times do
+ assert !Regexp.new(re).match?(str)
+ end
+ end
+
+ def test_bug_20083 # [Bug #20083]
+ re = /([\s]*ABC)$/i
+ (1..100).each do |n|
+ text = "#{"0" * n}ABC"
+ assert text.match?(re)
+ end
+ end
+
+ def test_bug_20098 # [Bug #20098]
+ assert(/a((.|.)|bc){,4}z/.match? 'abcbcbcbcz')
+ assert(/a(b+?c*){4,5}z/.match? 'abbbccbbbccbcbcz')
+ assert(/a(b+?(.|.)){2,3}z/.match? 'abbbcbbbcbbbcz')
+ assert(/a(b*?(.|.)[bc]){2,5}z/.match? 'abcbbbcbcccbcz')
+ assert(/^(?:.+){2,4}?b|b/.match? "aaaabaa")
+ end
+
+ def test_bug_20207 # [Bug #20207]
+ assert(!'clan'.match?(/(?=.*a)(?!.*n)/))
+ end
+
+ def test_bug_20212 # [Bug #20212]
+ regex = Regexp.new(
+ /\A((?=.*?[a-z])(?!.*--)[a-z\d]+[a-z\d-]*[a-z\d]+).((?=.*?[a-z])(?!.*--)[a-z\d]+[a-z\d-]*[a-z\d]+).((?=.*?[a-z])(?!.*--)[a-z]+[a-z-]*[a-z]+).((?=.*?[a-z])(?!.*--)[a-z]+[a-z-]*[a-z]+)\Z/x
+ )
+ string = "www.google.com"
+ 100.times.each { assert(regex.match?(string)) }
+ end
+
+ def test_bug_20246 # [Bug #20246]
+ assert_equal '1.2.3', '1.2.3'[/(\d+)(\.\g<1>){2}/]
+ assert_equal '1.2.3', '1.2.3'[/((?:\d|foo|bar)+)(\.\g<1>){2}/]
+ end
+
+ def test_linear_time_p
+ assert_send [Regexp, :linear_time?, /a/]
+ assert_send [Regexp, :linear_time?, 'a']
+ assert_send [Regexp, :linear_time?, 'a', Regexp::IGNORECASE]
+ assert_not_send [Regexp, :linear_time?, /(a)\1/]
+ assert_not_send [Regexp, :linear_time?, "(a)\\1"]
+
+ assert_not_send [Regexp, :linear_time?, /(?=(a))/]
+ assert_not_send [Regexp, :linear_time?, /(?!(a))/]
+
+ assert_raise(TypeError) {Regexp.linear_time?(nil)}
+ assert_raise(TypeError) {Regexp.linear_time?(Regexp.allocate)}
+ end
+
+ def test_linear_performance
+ pre = ->(n) {[Regexp.new("a?" * n + "a" * n), "a" * n]}
+ assert_linear_performance([10, 29], pre: pre) do |re, s|
+ re =~ s
+ end
+ end
end
diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb
index 604ddf09d8..ef33928376 100644
--- a/test/ruby/test_require.rb
+++ b/test/ruby/test_require.rb
@@ -6,11 +6,27 @@ require 'tmpdir'
class TestRequire < Test::Unit::TestCase
def test_load_error_path
- filename = "should_not_exist"
- error = assert_raise(LoadError) do
- require filename
- end
- assert_equal filename, error.path
+ Tempfile.create(["should_not_exist", ".rb"]) {|t|
+ filename = t.path
+ t.close
+ File.unlink(filename)
+
+ error = assert_raise(LoadError) do
+ require filename
+ end
+ assert_equal filename, error.path
+
+ # with --disable=gems
+ assert_separately(["-", filename], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ filename = ARGV[0]
+ path = Struct.new(:to_path).new(filename)
+ error = assert_raise(LoadError) do
+ require path
+ end
+ assert_equal filename, error.path
+ end;
+ }
end
def test_require_invalid_shared_object
@@ -52,7 +68,8 @@ class TestRequire < Test::Unit::TestCase
def test_require_nonascii
bug3758 = '[ruby-core:31915]'
["\u{221e}", "\x82\xa0".force_encoding("cp932")].each do |path|
- assert_raise_with_message(LoadError, /#{path}\z/, bug3758) {require path}
+ e = assert_raise(LoadError, bug3758) {require path}
+ assert_operator(e.message, :end_with?, path, bug3758)
end
end
@@ -192,7 +209,7 @@ class TestRequire < Test::Unit::TestCase
File.write(req, "p :ok\n")
assert_file.exist?(req)
req[/.rb$/i] = ""
- assert_in_out_err(['--disable-gems'], <<-INPUT, %w(:ok), [])
+ assert_in_out_err([], <<-INPUT, %w(:ok), [])
require "#{req}"
require "#{req}"
INPUT
@@ -210,6 +227,7 @@ class TestRequire < Test::Unit::TestCase
assert_not_nil(bt = e.backtrace, "no backtrace")
assert_not_empty(bt.find_all {|b| b.start_with? __FILE__}, proc {bt.inspect})
end
+ ensure
$LOADED_FEATURES.replace loaded_features
end
@@ -352,6 +370,26 @@ class TestRequire < Test::Unit::TestCase
end
end
+ def test_public_in_wrapped_load
+ Tempfile.create(["test_public_in_wrapped_load", ".rb"]) do |t|
+ t.puts "def foo; end", "public :foo"
+ t.close
+ assert_warning(/main\.public/) do
+ assert load(t.path, true)
+ end
+ end
+ end
+
+ def test_private_in_wrapped_load
+ Tempfile.create(["test_private_in_wrapped_load", ".rb"]) do |t|
+ t.puts "def foo; end", "private :foo"
+ t.close
+ assert_warning(/main\.private/) do
+ assert load(t.path, true)
+ end
+ end
+ end
+
def test_load_scope
bug1982 = '[ruby-core:25039] [Bug #1982]'
Tempfile.create(["test_ruby_test_require", ".rb"]) {|t|
@@ -562,9 +600,6 @@ class TestRequire < Test::Unit::TestCase
assert_equal(true, (t1_res ^ t2_res), bug5754 + " t1:#{t1_res} t2:#{t2_res}")
assert_equal([:pre, :post], scratch, bug5754)
-
- assert_match(/circular require/, output)
- assert_match(/in #{__method__}'$/o, output)
}
ensure
$VERBOSE = verbose
@@ -682,7 +717,7 @@ class TestRequire < Test::Unit::TestCase
Dir.mktmpdir {|tmp|
Dir.chdir(tmp) {
open("foo.rb", "w") {}
- assert_in_out_err([{"RUBYOPT"=>nil}, '--disable-gems'], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7158)
+ assert_in_out_err([{"RUBYOPT"=>nil}], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7158)
begin;
$:.replace([IO::NULL])
a = Object.new
@@ -710,7 +745,7 @@ class TestRequire < Test::Unit::TestCase
Dir.mktmpdir {|tmp|
Dir.chdir(tmp) {
open("foo.rb", "w") {}
- assert_in_out_err([{"RUBYOPT"=>nil}, '--disable-gems'], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7158)
+ assert_in_out_err([{"RUBYOPT"=>nil}], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7158)
begin;
$:.replace([IO::NULL])
a = Object.new
@@ -740,7 +775,7 @@ class TestRequire < Test::Unit::TestCase
open("foo.rb", "w") {}
Dir.mkdir("a")
open(File.join("a", "bar.rb"), "w") {}
- assert_in_out_err(['--disable-gems'], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7383)
+ assert_in_out_err([], "#{<<~"begin;"}\n#{<<~"end;"}", %w(:ok), [], bug7383)
begin;
$:.replace([IO::NULL])
$:.#{add} "#{tmp}"
@@ -961,4 +996,19 @@ class TestRequire < Test::Unit::TestCase
assert_nil($LOAD_PATH.resolve_feature_path("superkalifragilisticoespialidoso"))
end
end
+
+ def test_require_with_public_method_missing
+ # [Bug #19793]
+ assert_separately(["-W0", "-rtempfile"], __FILE__, __LINE__, <<~RUBY, timeout: 60)
+ GC.stress = true
+
+ class Object
+ public :method_missing
+ end
+
+ Tempfile.create(["empty", ".rb"]) do |file|
+ require file.path
+ end
+ RUBY
+ end
end
diff --git a/test/ruby/test_require_lib.rb b/test/ruby/test_require_lib.rb
index 95fa3f29e1..a88279727e 100644
--- a/test/ruby/test_require_lib.rb
+++ b/test/ruby/test_require_lib.rb
@@ -1,25 +1,26 @@
-# frozen_string_literal: false
+# frozen_string_literal: true
require 'test/unit'
class TestRequireLib < Test::Unit::TestCase
- TEST_RATIO = ENV["TEST_REQUIRE_THREAD_RATIO"]&.tap {|s|break s.to_f} || 0.05 # testing all files needs too long time...
+ libdir = __dir__ + '/../../lib'
- Dir.glob(File.expand_path('../../lib/**/*.rb', __dir__)).each do |lib|
- # skip some problems
- next if %r!/lib/(?:bundler|rubygems)\b! =~ lib
- next if %r!/lib/(?:debug|mkmf)\.rb\z! =~ lib
- next if %r!/lib/irb/ext/tracer\.rb\z! =~ lib
- # skip many files that almost use no threads
- next if TEST_RATIO < rand(0.0..1.0)
+ # .rb files at lib
+ scripts = Dir.glob('*.rb', base: libdir).map {|f| f.chomp('.rb')}
+
+ # .rb files in subdirectories of lib without same name script
+ dirs = Dir.glob('*/', base: libdir).map {|d| d.chomp('/')}
+ dirs -= scripts
+ scripts.concat(Dir.glob(dirs.map {|d| d + '/*.rb'}, base: libdir).map {|f| f.chomp('.rb')})
+
+ # skip some problems
+ scripts -= %w[bundler bundled_gems rubygems mkmf]
+
+ scripts.each do |lib|
define_method "test_thread_size:#{lib}" do
- assert_separately(['--disable-gems', '-W0'], "#{<<~"begin;"}\n#{<<~"end;"}")
+ assert_separately(['-W0'], "#{<<~"begin;"}\n#{<<~"end;"}")
begin;
n = Thread.list.size
- begin
- require #{lib.dump}
- rescue Exception
- omit $!
- end
+ require #{lib.dump}
assert_equal n, Thread.list.size
end;
end
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index ed2bc3538c..76be9152a7 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -7,14 +7,19 @@ require 'tempfile'
require_relative '../lib/jit_support'
class TestRubyOptions < Test::Unit::TestCase
- def self.mjit_enabled? = defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
- def self.yjit_enabled? = defined?(RubyVM::YJIT.enabled?) && RubyVM::YJIT.enabled?
+ def self.rjit_enabled? = defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ def self.yjit_enabled? = defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
+
+ # Here we're defining our own RUBY_DESCRIPTION without "+PRISM". We do this
+ # here so that the various tests that reference RUBY_DESCRIPTION don't have to
+ # worry about it. The flag itself is tested in its own test.
+ RUBY_DESCRIPTION = ::RUBY_DESCRIPTION.sub(/\+PRISM /, '')
NO_JIT_DESCRIPTION =
- if mjit_enabled?
- RUBY_DESCRIPTION.sub(/\+MJIT /, '')
+ if rjit_enabled?
+ RUBY_DESCRIPTION.sub(/\+RJIT /, '')
elsif yjit_enabled?
- RUBY_DESCRIPTION.sub(/\+YJIT /, '')
+ RUBY_DESCRIPTION.sub(/\+YJIT( (dev|dev_nodebug|stats))? /, '')
else
RUBY_DESCRIPTION
end
@@ -41,7 +46,7 @@ class TestRubyOptions < Test::Unit::TestCase
def test_usage
assert_in_out_err(%w(-h)) do |r, e|
assert_operator(r.size, :<=, 25)
- longer = r[1..-1].select {|x| x.size > 80}
+ longer = r[1..-1].select {|x| x.size >= 80}
assert_equal([], longer)
assert_equal([], e)
end
@@ -74,7 +79,7 @@ class TestRubyOptions < Test::Unit::TestCase
def test_backtrace_limit
assert_in_out_err(%w(--backtrace-limit), "", [], /missing argument for --backtrace-limit/)
assert_in_out_err(%w(--backtrace-limit= 1), "", [], /missing argument for --backtrace-limit/)
- assert_in_out_err(%w(--backtrace-limit=-1), "", [], /wrong limit for backtrace length/)
+ assert_in_out_err(%w(--backtrace-limit=-2), "", [], /wrong limit for backtrace length/)
code = 'def f(n);n > 0 ? f(n-1) : raise;end;f(5)'
assert_in_out_err(%w(--backtrace-limit=1), code, [],
[/.*unhandled exception\n/, /^\tfrom .*\n/,
@@ -84,46 +89,71 @@ class TestRubyOptions < Test::Unit::TestCase
/^\t \.{3} \d+ levels\.{3}\n/])
assert_kind_of(Integer, Thread::Backtrace.limit)
assert_in_out_err(%w(--backtrace-limit=1), "p Thread::Backtrace.limit", ['1'], [])
+ assert_in_out_err(%w(--backtrace-limit 1), "p Thread::Backtrace.limit", ['1'], [])
+ env = {"RUBYOPT" => "--backtrace-limit=5"}
+ assert_in_out_err([env], "p Thread::Backtrace.limit", ['5'], [])
+ assert_in_out_err([env, "--backtrace-limit=1"], "p Thread::Backtrace.limit", ['1'], [])
+ assert_in_out_err([env, "--backtrace-limit=-1"], "p Thread::Backtrace.limit", ['-1'], [])
+ assert_in_out_err([env, "--backtrace-limit=3", "--backtrace-limit=1"],
+ "p Thread::Backtrace.limit", ['1'], [])
+ assert_in_out_err([{"RUBYOPT" => "--backtrace-limit=5 --backtrace-limit=3"}],
+ "p Thread::Backtrace.limit", ['3'], [])
+ long_max = RbConfig::LIMITS["LONG_MAX"]
+ assert_in_out_err(%W(--backtrace-limit=#{long_max}), "p Thread::Backtrace.limit",
+ ["#{long_max}"], [])
end
def test_warning
- save_rubyopt = ENV['RUBYOPT']
- ENV['RUBYOPT'] = nil
+ save_rubyopt = ENV.delete('RUBYOPT')
assert_in_out_err(%w(-W0 -e) + ['p $-W'], "", %w(0), [])
assert_in_out_err(%w(-W1 -e) + ['p $-W'], "", %w(1), [])
assert_in_out_err(%w(-Wx -e) + ['p $-W'], "", %w(2), [])
assert_in_out_err(%w(-W -e) + ['p $-W'], "", %w(2), [])
assert_in_out_err(%w(-We) + ['p $-W'], "", %w(2), [])
assert_in_out_err(%w(-w -W0 -e) + ['p $-W'], "", %w(0), [])
- assert_in_out_err(%w(-W:deprecated -e) + ['p Warning[:deprecated]'], "", %w(true), [])
- assert_in_out_err(%w(-W:no-deprecated -e) + ['p Warning[:deprecated]'], "", %w(false), [])
- assert_in_out_err(%w(-W:experimental -e) + ['p Warning[:experimental]'], "", %w(true), [])
- assert_in_out_err(%w(-W:no-experimental -e) + ['p Warning[:experimental]'], "", %w(false), [])
- assert_in_out_err(%w(-W:qux), "", [], /unknown warning category: `qux'/)
- assert_in_out_err(%w(-w -e) + ['p Warning[:deprecated]'], "", %w(true), [])
- assert_in_out_err(%w(-W -e) + ['p Warning[:deprecated]'], "", %w(true), [])
- assert_in_out_err(%w(-We) + ['p Warning[:deprecated]'], "", %w(true), [])
- assert_in_out_err(%w(-e) + ['p Warning[:deprecated]'], "", %w(false), [])
- code = 'puts "#{$VERBOSE}:#{Warning[:deprecated]}:#{Warning[:experimental]}"'
+
+ categories = {deprecated: 1, experimental: 0, performance: 2}
+ assert_equal categories.keys.sort, Warning.categories.sort
+
+ categories.each do |category, level|
+ assert_in_out_err(["-W:#{category}", "-e", "p Warning[:#{category}]"], "", %w(true), [])
+ assert_in_out_err(["-W:no-#{category}", "-e", "p Warning[:#{category}]"], "", %w(false), [])
+ assert_in_out_err(["-e", "p Warning[:#{category}]"], "", level > 0 ? %w(false) : %w(true), [])
+ assert_in_out_err(["-w", "-e", "p Warning[:#{category}]"], "", level > 1 ? %w(false) : %w(true), [])
+ assert_in_out_err(["-W", "-e", "p Warning[:#{category}]"], "", level > 1 ? %w(false) : %w(true), [])
+ assert_in_out_err(["-We", "p Warning[:#{category}]"], "", level > 1 ? %w(false) : %w(true), [])
+ end
+ assert_in_out_err(%w(-W:qux), "", [], /unknown warning category: 'qux'/)
+
+ def categories.expected(lev = 1, **warnings)
+ [
+ (lev > 1).to_s,
+ *map {|category, level| warnings.fetch(category, lev > level).to_s}
+ ].join(':')
+ end
+ code = ['#{$VERBOSE}', *categories.map {|category, | "\#{Warning[:#{category}]}"}].join(':')
+ code = %[puts "#{code}"]
Tempfile.create(["test_ruby_test_rubyoption", ".rb"]) do |t|
t.puts code
t.close
- assert_in_out_err(["-r#{t.path}", '-e', code], "", %w(false:false:true false:false:true), [])
- assert_in_out_err(["-r#{t.path}", '-w', '-e', code], "", %w(true:true:true true:true:true), [])
- assert_in_out_err(["-r#{t.path}", '-W:deprecated', '-e', code], "", %w(false:true:true false:true:true), [])
- assert_in_out_err(["-r#{t.path}", '-W:no-experimental', '-e', code], "", %w(false:false:false false:false:false), [])
+ assert_in_out_err(["-r#{t.path}", '-e', code], "", [categories.expected(1)]*2, [])
+ assert_in_out_err(["-r#{t.path}", '-w', '-e', code], "", [categories.expected(2)]*2, [])
+ categories.each do |category, |
+ assert_in_out_err(["-r#{t.path}", "-W:#{category}", '-e', code], "", [categories.expected(category => 'true')]*2, [])
+ assert_in_out_err(["-r#{t.path}", "-W:no-#{category}", '-e', code], "", [categories.expected(category => 'false')]*2, [])
+ end
end
ensure
ENV['RUBYOPT'] = save_rubyopt
end
def test_debug
- assert_in_out_err(["--disable-gems", "-de", "p $DEBUG"], "", %w(true), [])
+ assert_in_out_err(["-de", "p $DEBUG"], "", %w(true), [])
- assert_in_out_err(["--disable-gems", "--debug", "-e", "p $DEBUG"],
+ assert_in_out_err(["--debug", "-e", "p $DEBUG"],
"", %w(true), [])
- assert_in_out_err(["--disable-gems", "--debug-", "-e", "p $DEBUG"], "", %w(), /invalid option --debug-/)
+ assert_in_out_err(["--debug-", "-e", "p $DEBUG"], "", %w(), /invalid option --debug-/)
end
q = Regexp.method(:quote)
@@ -137,21 +167,21 @@ class TestRubyOptions < Test::Unit::TestCase
end
private_constant :VERSION_PATTERN
- VERSION_PATTERN_WITH_JIT =
+ VERSION_PATTERN_WITH_RJIT =
case RUBY_ENGINE
when 'ruby'
- /^ruby #{q[RUBY_VERSION]}(?:[p ]|dev|rc).*? \+MJIT \[#{q[RUBY_PLATFORM]}\]$/
+ /^ruby #{q[RUBY_VERSION]}(?:[p ]|dev|rc).*? \+RJIT (\+MN )?\[#{q[RUBY_PLATFORM]}\]$/
else
VERSION_PATTERN
end
- private_constant :VERSION_PATTERN_WITH_JIT
+ private_constant :VERSION_PATTERN_WITH_RJIT
def test_verbose
assert_in_out_err([{'RUBY_YJIT_ENABLE' => nil}, "-vve", ""]) do |r, e|
assert_match(VERSION_PATTERN, r[0])
- if self.class.mjit_enabled? && !JITSupport.mjit_force_enabled?
+ if self.class.rjit_enabled? && !JITSupport.rjit_force_enabled?
assert_equal(NO_JIT_DESCRIPTION, r[0])
- elsif self.class.yjit_enabled? && !yjit_force_enabled? # checking -DYJIT_FORCE_ENABLE
+ elsif self.class.yjit_enabled? && !JITSupport.yjit_force_enabled?
assert_equal(NO_JIT_DESCRIPTION, r[0])
else
assert_equal(RUBY_DESCRIPTION, r[0])
@@ -172,13 +202,18 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_enable
- if JITSupport.supported?
+ if JITSupport.yjit_supported?
assert_in_out_err(%w(--enable all -e) + [""], "", [], [])
assert_in_out_err(%w(--enable-all -e) + [""], "", [], [])
assert_in_out_err(%w(--enable=all -e) + [""], "", [], [])
+ elsif JITSupport.rjit_supported?
+ # Avoid failing tests by RJIT warnings
+ assert_in_out_err(%w(--enable all --disable rjit -e) + [""], "", [], [])
+ assert_in_out_err(%w(--enable-all --disable-rjit -e) + [""], "", [], [])
+ assert_in_out_err(%w(--enable=all --disable=rjit -e) + [""], "", [], [])
end
assert_in_out_err(%w(--enable foobarbazqux -e) + [""], "", [],
- /unknown argument for --enable: `foobarbazqux'/)
+ /unknown argument for --enable: 'foobarbazqux'/)
assert_in_out_err(%w(--enable), "", [], /missing argument for --enable/)
end
@@ -187,11 +222,11 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err(%w(--disable-all -e) + [""], "", [], [])
assert_in_out_err(%w(--disable=all -e) + [""], "", [], [])
assert_in_out_err(%w(--disable foobarbazqux -e) + [""], "", [],
- /unknown argument for --disable: `foobarbazqux'/)
+ /unknown argument for --disable: 'foobarbazqux'/)
assert_in_out_err(%w(--disable), "", [], /missing argument for --disable/)
- assert_in_out_err(%w(--disable-gems -e) + ['p defined? Gem'], "", ["nil"], [])
+ assert_in_out_err(%w(-e) + ['p defined? Gem'], "", ["nil"], [])
assert_in_out_err(%w(--disable-did_you_mean -e) + ['p defined? DidYouMean'], "", ["nil"], [])
- assert_in_out_err(%w(--disable-gems -e) + ['p defined? DidYouMean'], "", ["nil"], [])
+ assert_in_out_err(%w(-e) + ['p defined? DidYouMean'], "", ["nil"], [])
end
def test_kanji
@@ -212,31 +247,29 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_version
- env = {'RUBY_YJIT_ENABLE' => nil} # unset in children
+ env = { 'RUBY_YJIT_ENABLE' => nil } # unset in children
assert_in_out_err([env, '--version']) do |r, e|
assert_match(VERSION_PATTERN, r[0])
if ENV['RUBY_YJIT_ENABLE'] == '1'
assert_equal(NO_JIT_DESCRIPTION, r[0])
- elsif self.class.mjit_enabled? || self.class.yjit_enabled? # checking -D(M|Y)JIT_FORCE_ENABLE
+ elsif self.class.rjit_enabled? || self.class.yjit_enabled? # checking -D(M|Y)JIT_FORCE_ENABLE
assert_equal(EnvUtil.invoke_ruby(['-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
else
assert_equal(RUBY_DESCRIPTION, r[0])
end
assert_equal([], e)
end
+ end
- return if RbConfig::CONFIG["MJIT_SUPPORT"] == 'no'
- return if yjit_force_enabled?
+ def test_rjit_disabled_version
+ return unless JITSupport.rjit_supported?
+ return if JITSupport.yjit_force_enabled?
+ env = { 'RUBY_YJIT_ENABLE' => nil } # unset in children
[
- %w(--version --mjit --disable=mjit),
- %w(--version --enable=mjit --disable=mjit),
- %w(--version --enable-mjit --disable-mjit),
- *([
- %w(--version --jit --disable=jit),
- %w(--version --enable=jit --disable=jit),
- %w(--version --enable-jit --disable-jit),
- ] unless JITSupport.yjit_supported?),
+ %w(--version --rjit --disable=rjit),
+ %w(--version --enable=rjit --disable=rjit),
+ %w(--version --enable-rjit --disable-rjit),
].each do |args|
assert_in_out_err([env] + args) do |r, e|
assert_match(VERSION_PATTERN, r[0])
@@ -244,31 +277,45 @@ class TestRubyOptions < Test::Unit::TestCase
assert_equal([], e)
end
end
+ end
- if JITSupport.supported?
- [
- %w(--version --mjit),
- %w(--version --enable=mjit),
- %w(--version --enable-mjit),
- *([
- %w(--version --jit),
- %w(--version --enable=jit),
- %w(--version --enable-jit),
- ] unless JITSupport.yjit_supported?),
- ].each do |args|
- assert_in_out_err([env] + args) do |r, e|
- assert_match(VERSION_PATTERN_WITH_JIT, r[0])
- if JITSupport.mjit_force_enabled?
- assert_equal(RUBY_DESCRIPTION, r[0])
- else
- assert_equal(EnvUtil.invoke_ruby([env, '--mjit', '-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
- end
- assert_equal([], e)
+ def test_rjit_version
+ return unless JITSupport.rjit_supported?
+ return if JITSupport.yjit_force_enabled?
+
+ env = { 'RUBY_YJIT_ENABLE' => nil } # unset in children
+ [
+ %w(--version --rjit),
+ %w(--version --enable=rjit),
+ %w(--version --enable-rjit),
+ ].each do |args|
+ assert_in_out_err([env] + args) do |r, e|
+ assert_match(VERSION_PATTERN_WITH_RJIT, r[0])
+ if JITSupport.rjit_force_enabled?
+ assert_equal(RUBY_DESCRIPTION, r[0])
+ else
+ assert_equal(EnvUtil.invoke_ruby([env, '--rjit', '-e', 'print RUBY_DESCRIPTION'], '', true).first, r[0])
end
+ assert_equal([], e)
end
end
end
+ def test_parser_flag
+ warning = /compiler based on the Prism parser is currently experimental/
+
+ assert_in_out_err(%w(--parser=prism -e) + ["puts :hi"], "", %w(hi), warning)
+ assert_in_out_err(%w(--parser=prism -W:no-experimental -e) + ["puts :hi"], "", %w(hi), [])
+ assert_in_out_err(%w(--parser=prism -W:no-experimental --dump=parsetree -e _=:hi), "", /"hi"/, [])
+
+ assert_in_out_err(%w(--parser=parse.y -e) + ["puts :hi"], "", %w(hi), [])
+ assert_norun_with_rflag('--parser=parse.y', '--version', "")
+
+ assert_in_out_err(%w(--parser=notreal -e) + ["puts :hi"], "", [], /unknown parser notreal/)
+
+ assert_in_out_err(%w(--parser=prism --version), "", /\+PRISM/, [])
+ end
+
def test_eval
assert_in_out_err(%w(-e), "", [], /no code specified for -e \(RuntimeError\)/)
end
@@ -335,22 +382,32 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err(%w(--encoding test_ruby_test_rubyoptions_foobarbazqux), "", [],
/unknown encoding name - test_ruby_test_rubyoptions_foobarbazqux \(RuntimeError\)/)
- if /mswin|mingw|aix|android/ =~ RUBY_PLATFORM &&
- (str = "\u3042".force_encoding(Encoding.find("external"))).valid_encoding?
- # This result depends on locale because LANG=C doesn't affect locale
- # on Windows.
- # On AIX, the source encoding of stdin with LANG=C is ISO-8859-1,
- # which allows \u3042.
- out, err = [str], []
- else
- out, err = [], /invalid multibyte char/
- end
- assert_in_out_err(%w(-Eutf-8), "puts '\u3042'", out, err)
- assert_in_out_err(%w(--encoding utf-8), "puts '\u3042'", out, err)
+ assert_in_out_err(%w(-Eutf-8), 'puts Encoding::default_external', ["UTF-8"])
+ assert_in_out_err(%w(-Ecesu-8), 'puts Encoding::default_external', ["CESU-8"])
+ assert_in_out_err(%w(--encoding utf-8), 'puts Encoding::default_external', ["UTF-8"])
+ assert_in_out_err(%w(--encoding cesu-8), 'puts Encoding::default_external', ["CESU-8"])
end
def test_syntax_check
- assert_in_out_err(%w(-c -e a=1+1 -e !a), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-cw -e a=1+1 -e !a), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-cw -e break), "", [], ["-e:1: Invalid break", :*])
+ assert_in_out_err(%w(-cw -e next), "", [], ["-e:1: Invalid next", :*])
+ assert_in_out_err(%w(-cw -e redo), "", [], ["-e:1: Invalid redo", :*])
+ assert_in_out_err(%w(-cw -e retry), "", [], ["-e:1: Invalid retry", :*])
+ assert_in_out_err(%w(-cw -e yield), "", [], ["-e:1: Invalid yield", :*])
+ assert_in_out_err(%w(-cw -e begin -e break -e end), "", [], ["-e:2: Invalid break", :*])
+ assert_in_out_err(%w(-cw -e begin -e next -e end), "", [], ["-e:2: Invalid next", :*])
+ assert_in_out_err(%w(-cw -e begin -e redo -e end), "", [], ["-e:2: Invalid redo", :*])
+ assert_in_out_err(%w(-cw -e begin -e retry -e end), "", [], ["-e:2: Invalid retry", :*])
+ assert_in_out_err(%w(-cw -e begin -e yield -e end), "", [], ["-e:2: Invalid yield", :*])
+ assert_in_out_err(%w(-cw -e !defined?(break)), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-cw -e !defined?(next)), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-cw -e !defined?(redo)), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-cw -e !defined?(retry)), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-cw -e !defined?(yield)), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-n -cw -e break), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-n -cw -e next), "", ["Syntax OK"], [])
+ assert_in_out_err(%w(-n -cw -e redo), "", ["Syntax OK"], [])
end
def test_invalid_option
@@ -397,13 +454,12 @@ class TestRubyOptions < Test::Unit::TestCase
ENV['RUBYOPT'] = '-W:no-experimental'
assert_in_out_err(%w(), "p Warning[:experimental]", ["false"])
ENV['RUBYOPT'] = '-W:qux'
- assert_in_out_err(%w(), "", [], /unknown warning category: `qux'/)
+ assert_in_out_err(%w(), "", [], /unknown warning category: 'qux'/)
+
+ ENV['RUBYOPT'] = 'w'
+ assert_in_out_err(%w(), "p $VERBOSE", ["true"])
ensure
- if rubyopt_orig
- ENV['RUBYOPT'] = rubyopt_orig
- else
- ENV.delete('RUBYOPT')
- end
+ ENV['RUBYOPT'] = rubyopt_orig
end
def test_search
@@ -493,6 +549,16 @@ class TestRubyOptions < Test::Unit::TestCase
/invalid name for global variable - -# \(NameError\)/)
end
+ def test_option_missing_argument
+ assert_in_out_err(%w(-0 --enable), "", [], /missing argument for --enable/)
+ assert_in_out_err(%w(-0 --disable), "", [], /missing argument for --disable/)
+ assert_in_out_err(%w(-0 --dump), "", [], /missing argument for --dump/)
+ assert_in_out_err(%w(-0 --encoding), "", [], /missing argument for --encoding/)
+ assert_in_out_err(%w(-0 --external-encoding), "", [], /missing argument for --external-encoding/)
+ assert_in_out_err(%w(-0 --internal-encoding), "", [], /missing argument for --internal-encoding/)
+ assert_in_out_err(%w(-0 --backtrace-limit), "", [], /missing argument for --backtrace-limit/)
+ end
+
def test_assignment_in_conditional
Tempfile.create(["test_ruby_test_rubyoption", ".rb"]) {|t|
t.puts "if a = 1"
@@ -503,7 +569,7 @@ class TestRubyOptions < Test::Unit::TestCase
t.puts " end"
t.puts "end"
t.flush
- warning = ' warning: found `= literal\' in conditional, should be =='
+ warning = ' warning: found \'= literal\' in conditional, should be =='
err = ["#{t.path}:1:#{warning}",
"#{t.path}:4:#{warning}",
]
@@ -520,16 +586,29 @@ class TestRubyOptions < Test::Unit::TestCase
t.puts "if a = {}; end"
t.puts "if a = {1=>2}; end"
t.puts "if a = {3=>a}; end"
+ t.puts "if a = :sym; end"
t.flush
err = ["#{t.path}:1:#{warning}",
"#{t.path}:2:#{warning}",
"#{t.path}:3:#{warning}",
"#{t.path}:5:#{warning}",
"#{t.path}:6:#{warning}",
+ "#{t.path}:8:#{warning}",
]
feature4299 = '[ruby-dev:43083]'
assert_in_out_err(["-w", t.path], "", [], err, feature4299)
assert_in_out_err(["-wr", t.path, "-e", ""], "", [], err, feature4299)
+
+ t.rewind
+ t.truncate(0)
+ t.puts "if a = __LINE__; end"
+ t.puts "if a = __FILE__; end"
+ t.flush
+ err = ["#{t.path}:1:#{warning}",
+ "#{t.path}:2:#{warning}",
+ ]
+ assert_in_out_err(["-w", t.path], "", [], err)
+ assert_in_out_err(["-wr", t.path, "-e", ""], "", [], err)
}
end
@@ -741,7 +820,7 @@ class TestRubyOptions < Test::Unit::TestCase
-e:(?:1:)?\s\[BUG\]\sSegmentation\sfault.*\n
)x,
%r(
- #{ Regexp.quote((TestRubyOptions.mjit_enabled? && !JITSupport.mjit_force_enabled?) ? NO_JIT_DESCRIPTION : RUBY_DESCRIPTION) }\n\n
+ #{ Regexp.quote((TestRubyOptions.rjit_enabled? && !JITSupport.rjit_force_enabled?) ? NO_JIT_DESCRIPTION : RUBY_DESCRIPTION) }\n\n
)x,
%r(
(?:--\s(?:.+\n)*\n)?
@@ -752,12 +831,15 @@ class TestRubyOptions < Test::Unit::TestCase
%r(
(?:
--\sRuby\slevel\sbacktrace\sinformation\s----------------------------------------\n
- (?:-e:1:in\s\`(?:block\sin\s)?<main>\'\n)*
- -e:1:in\s\`kill\'\n
+ (?:-e:1:in\s\'(?:block\sin\s)?<main>\'\n)*
+ -e:1:in\s\'kill\'\n
\n
)?
)x,
%r(
+ (?:--\sThreading(?:.+\n)*\n)?
+ )x,
+ %r(
(?:--\sMachine(?:.+\n)*\n)?
)x,
%r(
@@ -773,30 +855,36 @@ class TestRubyOptions < Test::Unit::TestCase
)?
)x,
]
- end
- def assert_segv(args, message=nil)
- omit if ENV['RUBY_ON_BUG']
+ KILL_SELF = "Process.kill :SEGV, $$"
+ end
+ def assert_segv(args, message=nil, list: SEGVTest::ExpectedStderrList, **opt, &block)
# We want YJIT to be enabled in the subprocess if it's enabled for us
# so that the Ruby description matches.
+ env = Hash === args.first ? args.shift : {}
args.unshift("--yjit") if self.class.yjit_enabled?
+ env.update({'RUBY_ON_BUG' => nil})
+ # ASAN registers a segv handler which prints out "AddressSanitizer: DEADLYSIGNAL" when
+ # catching sigsegv; we don't expect that output, so suppress it.
+ env.update({'ASAN_OPTIONS' => 'handle_segv=0'})
+ args.unshift(env)
test_stdin = ""
- opt = SEGVTest::ExecOptions.dup
- list = SEGVTest::ExpectedStderrList
+ tests = [//, list] unless block
- assert_in_out_err(args, test_stdin, //, list, encoding: "ASCII-8BIT", **opt)
+ assert_in_out_err(args, test_stdin, *tests, encoding: "ASCII-8BIT",
+ **SEGVTest::ExecOptions, **opt, &block)
end
def test_segv_test
- assert_segv(["--disable-gems", "-e", "Process.kill :SEGV, $$"])
+ assert_segv(["--disable-gems", "-e", SEGVTest::KILL_SELF])
end
def test_segv_loaded_features
bug7402 = '[ruby-core:49573]'
- status = assert_segv(['-e', 'END {Process.kill :SEGV, $$}',
+ status = assert_segv(['-e', "END {#{SEGVTest::KILL_SELF}}",
'-e', 'class Bogus; def to_str; exit true; end; end',
'-e', '$".clear',
'-e', '$".unshift Bogus.new',
@@ -810,10 +898,64 @@ class TestRubyOptions < Test::Unit::TestCase
Tempfile.create(["test_ruby_test_bug7597", ".rb"]) {|t|
t.write "f" * 100
t.flush
- assert_segv(["--disable-gems", "-e", "$0=ARGV[0]; Process.kill :SEGV, $$", t.path], bug7597)
+ assert_segv(["--disable-gems", "-e", "$0=ARGV[0]; #{SEGVTest::KILL_SELF}", t.path], bug7597)
}
end
+ def assert_crash_report(path, cmd = nil, &block)
+ Dir.mktmpdir("ruby_crash_report") do |dir|
+ list = SEGVTest::ExpectedStderrList
+ if cmd
+ FileUtils.mkpath(File.join(dir, File.dirname(cmd)))
+ File.write(File.join(dir, cmd), SEGVTest::KILL_SELF+"\n")
+ c = Regexp.quote(cmd)
+ list = list.map {|re| Regexp.new(re.source.gsub(/^\s*(\(\?:)?\K-e(?=:)/) {c}, re.options)}
+ else
+ cmd = ['-e', SEGVTest::KILL_SELF]
+ end
+ status = assert_segv([{"RUBY_CRASH_REPORT"=>path}, *cmd], list: [], chdir: dir, &block)
+ next if block
+ reports = Dir.glob("*.log", File::FNM_DOTMATCH, base: dir)
+ assert_equal(1, reports.size)
+ assert_pattern_list(list, File.read(File.join(dir, reports.first)))
+ break status, reports.first
+ end
+ end
+
+ def test_crash_report
+ status, report = assert_crash_report("%e.%f.%p.log")
+ assert_equal("#{File.basename(EnvUtil.rubybin)}.-e.#{status.pid}.log", report)
+ end
+
+ def test_crash_report_script
+ status, report = assert_crash_report("%e.%f.%p.log", "bug.rb")
+ assert_equal("#{File.basename(EnvUtil.rubybin)}.bug.rb.#{status.pid}.log", report)
+ end
+
+ def test_crash_report_executable_path
+ omit if EnvUtil.rubybin.size > 245
+ status, report = assert_crash_report("%E.%p.log")
+ path = EnvUtil.rubybin.sub(/\A\w\K:[\/\\]/, '!').tr_s('/', '!')
+ assert_equal("#{path}.#{status.pid}.log", report)
+ end
+
+ def test_crash_report_script_path
+ status, report = assert_crash_report("%F.%p.log", "test/bug.rb")
+ assert_equal("test!bug.rb.#{status.pid}.log", report)
+ end
+
+ def test_crash_report_pipe
+ if File.executable?(echo = "/bin/echo")
+ elsif /mswin|ming/ =~ RUBY_PLATFORM
+ echo = "echo"
+ else
+ omit "/bin/echo not found"
+ end
+ assert_crash_report("| #{echo} %e:%f:%p") do |stdin, stdout, status|
+ assert_equal(["#{File.basename(EnvUtil.rubybin)}:-e:#{status.pid}"], stdin)
+ end
+ end
+
def test_DATA
Tempfile.create(["test_ruby_test_rubyoption", ".rb"]) {|t|
t.puts "puts DATA.read.inspect"
@@ -996,18 +1138,17 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err(['-p', '-e', 'sub(/t.*/){"TEST"}'], %[test], %w[TEST], [], bug7157)
end
- def assert_norun_with_rflag(*opt)
+ def assert_norun_with_rflag(*opt, test_stderr: [])
bug10435 = "[ruby-dev:48712] [Bug #10435]: should not run with #{opt} option"
stderr = []
Tempfile.create(%w"bug10435- .rb") do |script|
dir, base = File.split(script.path)
- script.puts "abort ':run'"
- script.close
+ File.write(script, "abort ':run'\n")
opts = ['-C', dir, '-r', "./#{base}", *opt]
- _, e = assert_in_out_err([*opts, '-ep'], "", //)
+ _, e = assert_in_out_err([*opts, '-ep'], "", //, test_stderr)
stderr.concat(e) if e
stderr << "---"
- _, e = assert_in_out_err([*opts, base], "", //)
+ _, e = assert_in_out_err([*opts, base], "", //, test_stderr)
stderr.concat(e) if e
end
assert_not_include(stderr, ":run", bug10435)
@@ -1026,6 +1167,17 @@ class TestRubyOptions < Test::Unit::TestCase
def test_dump_parsetree_with_rflag
assert_norun_with_rflag('--dump=parsetree')
assert_norun_with_rflag('--dump=parsetree', '-e', '#frozen-string-literal: true')
+ assert_norun_with_rflag('--dump=parsetree+error_tolerant')
+ assert_norun_with_rflag('--dump=parse+error_tolerant')
+ end
+
+ def test_dump_parsetree_error_tolerant
+ assert_in_out_err(['--dump=parse', '-e', 'begin'],
+ "", [], /unexpected end-of-input/, success: false)
+ assert_in_out_err(['--dump=parse', '--dump=+error_tolerant', '-e', 'begin'],
+ "", /^# @/, /unexpected end-of-input/, success: true)
+ assert_in_out_err(['--dump=+error_tolerant', '-e', 'begin p :run'],
+ "", [], /unexpected end-of-input/, success: false)
end
def test_dump_insns_with_rflag
@@ -1056,13 +1208,16 @@ 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],
- [nil, false],
]
+ frozen << [nil, false] unless default_frozen
+
debugs = [
["--debug-frozen-string-literal", true],
["--debug=frozen-string-literal", true],
@@ -1127,17 +1282,9 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err([IO::NULL], success: true)
end
- def test_mjit_debug
- # mswin uses prebuilt precompiled header. Thus it does not show a pch compilation log to check "-O0 -O1".
- if JITSupport.supported? && !RUBY_PLATFORM.match?(/mswin/)
- env = { 'MJIT_SEARCH_BUILD_DIR' => 'true' }
- assert_in_out_err([env, "--disable-yjit", "--mjit-debug=-O0 -O1", "--mjit-verbose=2", "" ], "", [], /-O0 -O1/)
- end
- end
-
- private
-
- def yjit_force_enabled?
- "#{RbConfig::CONFIG['CFLAGS']} #{RbConfig::CONFIG['CPPFLAGS']}".match?(/(\A|\s)-D ?YJIT_FORCE_ENABLE\b/)
+ def test_free_at_exit_env_var
+ env = {"RUBY_FREE_AT_EXIT"=>"1"}
+ assert_ruby_status([env, "-e;"])
+ assert_in_out_err([env, "-W"], "", [], /Free at exit is experimental and may be unstable/)
end
end
diff --git a/test/ruby/test_rubyvm.rb b/test/ruby/test_rubyvm.rb
index d0b7cba341..d729aa5af8 100644
--- a/test/ruby/test_rubyvm.rb
+++ b/test/ruby/test_rubyvm.rb
@@ -4,11 +4,9 @@ require 'test/unit'
class TestRubyVM < Test::Unit::TestCase
def test_stat
assert_kind_of Hash, RubyVM.stat
- assert_kind_of Integer, RubyVM.stat[:class_serial]
RubyVM.stat(stat = {})
assert_not_empty stat
- assert_equal stat[:class_serial], RubyVM.stat(:class_serial)
end
def test_stat_unknown
diff --git a/test/ruby/test_rubyvm_mjit.rb b/test/ruby/test_rubyvm_mjit.rb
deleted file mode 100644
index 8ca0fb9ef2..0000000000
--- a/test/ruby/test_rubyvm_mjit.rb
+++ /dev/null
@@ -1,108 +0,0 @@
-# frozen_string_literal: true
-require 'test/unit'
-require_relative '../lib/jit_support'
-
-return if RbConfig::CONFIG["MJIT_SUPPORT"] == 'no'
-
-class TestRubyVMMJIT < Test::Unit::TestCase
- include JITSupport
-
- def setup
- unless JITSupport.supported?
- omit 'JIT seems not supported on this platform'
- end
- end
-
- def test_pause
- out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
- i = 0
- while i < 5
- eval("def mjit#{i}; end; mjit#{i}")
- i += 1
- end
- print RubyVM::MJIT.pause
- print RubyVM::MJIT.pause
- while i < 10
- eval("def mjit#{i}; end; mjit#{i}")
- i += 1
- end
- print RubyVM::MJIT.pause # no JIT here
- EOS
- assert_equal('truefalsefalse', out)
- assert_equal(
- 5, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size,
- "unexpected stdout:\n```\n#{out}```\n\nstderr:\n```\n#{err}```",
- )
- end
-
- def test_pause_waits_until_compaction
- out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
- def a() end; a
- def b() end; b
- RubyVM::MJIT.pause
- EOS
- assert_equal(
- 2, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size,
- "unexpected stdout:\n```\n#{out}```\n\nstderr:\n```\n#{err}```",
- )
- assert_equal(
- 1, err.scan(/#{JITSupport::JIT_COMPACTION_PREFIX}/).size,
- "unexpected stdout:\n```\n#{out}```\n\nstderr:\n```\n#{err}```",
- ) unless RUBY_PLATFORM.match?(/mswin|mingw/) # compaction is not supported on Windows yet
- end
-
- def test_pause_after_waitall
- out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
- def test() = nil
- test
- Process.waitall
- print RubyVM::MJIT.pause
- EOS
- assert_equal(
- 1, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size,
- "unexpected stdout:\n```\n#{out}```\n\nstderr:\n```\n#{err}```",
- )
- end
-
- def test_pause_does_not_hang_on_full_units
- out, _ = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, max_cache: 10, wait: false)
- i = 0
- while i < 11
- eval("def mjit#{i}; end; mjit#{i}")
- i += 1
- end
- print RubyVM::MJIT.pause
- EOS
- assert_equal('true', out)
- end
-
- def test_pause_wait_false
- out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
- i = 0
- while i < 10
- eval("def mjit#{i}; end; mjit#{i}")
- i += 1
- end
- print RubyVM::MJIT.pause(wait: false)
- print RubyVM::MJIT.pause(wait: false)
- EOS
- assert_equal('truefalse', out)
- if RUBY_PLATFORM.match?(/mswin|mingw/) # MJIT synchronously compiles methods on Windows
- assert_equal(10, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size)
- else
- assert_equal(true, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size < 10)
- end
- end
-
- def test_resume
- out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
- print RubyVM::MJIT.resume
- print RubyVM::MJIT.pause
- print RubyVM::MJIT.resume
- print RubyVM::MJIT.resume
- print RubyVM::MJIT.pause
- EOS
- assert_equal('falsetruetruefalsetrue', out)
- assert_equal(0, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size)
- end
-end
diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb
index 31946c8b71..1251f8879f 100644
--- a/test/ruby/test_settracefunc.rb
+++ b/test/ruby/test_settracefunc.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: false
require 'test/unit'
+EnvUtil.suppress_warning {require 'continuation'}
class TestSetTraceFunc < Test::Unit::TestCase
def setup
@@ -50,6 +51,49 @@ class TestSetTraceFunc < Test::Unit::TestCase
assert_equal([], events)
end
+ def test_c_return_no_binding
+ binding = :none
+ TracePoint.new(:c_return){|tp|
+ binding = tp.binding
+ }.enable{
+ 1.object_id
+ }
+ assert_nil(binding)
+ end
+
+ def test_c_call_no_binding
+ binding = :none
+ TracePoint.new(:c_call){|tp|
+ binding = tp.binding
+ }.enable{
+ 1.object_id
+ }
+ assert_nil(binding)
+ end
+
+ def test_c_call_removed_method
+ # [Bug #19305]
+ klass = Class.new do
+ attr_writer :bar
+ alias_method :set_bar, :bar=
+ remove_method :bar=
+ end
+
+ obj = klass.new
+ method_id = nil
+ parameters = nil
+
+ TracePoint.new(:c_call) { |tp|
+ method_id = tp.method_id
+ parameters = tp.parameters
+ }.enable {
+ obj.set_bar(1)
+ }
+
+ assert_equal(:bar=, method_id)
+ assert_equal([[:req]], parameters)
+ end
+
def test_call
events = []
name = "#{self.class}\##{__method__}"
@@ -315,18 +359,18 @@ class TestSetTraceFunc < Test::Unit::TestCase
def test_thread_trace
events = {:set => [], :add => []}
+ name = "#{self.class}\##{__method__}"
prc = Proc.new { |event, file, lineno, mid, binding, klass|
- events[:set] << [event, lineno, mid, klass, :set]
+ events[:set] << [event, lineno, mid, klass, :set] if file == name
}
prc = prc # suppress warning
prc2 = Proc.new { |event, file, lineno, mid, binding, klass|
- events[:add] << [event, lineno, mid, klass, :add]
+ events[:add] << [event, lineno, mid, klass, :add] if file == name
}
prc2 = prc2 # suppress warning
th = Thread.new do
th = Thread.current
- name = "#{self.class}\##{__method__}"
eval <<-EOF.gsub(/^.*?: /, ""), nil, name
1: th.set_trace_func(prc)
2: th.add_trace_func(prc2)
@@ -459,9 +503,9 @@ class TestSetTraceFunc < Test::Unit::TestCase
begin
eval <<-EOF.gsub(/^.*?: /, ""), nil, 'xyzzy'
1: trace = TracePoint.trace(*trace_events){|tp| next if !target_thread?
- 2: events << [tp.event, tp.lineno, tp.path, _defined_class.(tp), tp.method_id, tp.self, tp.binding.eval("_local_var"), _get_data.(tp)] if tp.path == 'xyzzy'
+ 2: events << [tp.event, tp.lineno, tp.path, _defined_class.(tp), tp.method_id, tp.self, tp.binding&.eval("_local_var"), _get_data.(tp)] if tp.path == 'xyzzy'
3: }
- 4: 1.times{|;_local_var| _local_var = :inner
+ 4: [1].reverse_each{|;_local_var| _local_var = :inner
5: tap{}
6: }
7: class XYZZY
@@ -488,29 +532,29 @@ class TestSetTraceFunc < Test::Unit::TestCase
answer_events = [
#
[:line, 4, 'xyzzy', self.class, method, self, :outer, :nothing],
- [:c_call, 4, 'xyzzy', Integer, :times, 1, :outer, :nothing],
+ [:c_call, 4, 'xyzzy', Array, :reverse_each, [1], nil, :nothing],
[:line, 4, 'xyzzy', self.class, method, self, nil, :nothing],
[:line, 5, 'xyzzy', self.class, method, self, :inner, :nothing],
- [:c_return, 4, "xyzzy", Integer, :times, 1, :outer, 1],
+ [:c_return, 4, "xyzzy", Array, :reverse_each, [1], nil, [1]],
[:line, 7, 'xyzzy', self.class, method, self, :outer, :nothing],
- [:c_call, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, :outer, :nothing],
- [:c_return, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, :outer, nil],
- [:c_call, 7, "xyzzy", Class, :inherited, Object, :outer, :nothing],
- [:c_return, 7, "xyzzy", Class, :inherited, Object, :outer, nil],
+ [:c_call, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, nil, :nothing],
+ [:c_return, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, nil, nil],
+ [:c_call, 7, "xyzzy", Class, :inherited, Object, nil, :nothing],
+ [:c_return, 7, "xyzzy", Class, :inherited, Object, nil, nil],
[:class, 7, "xyzzy", nil, nil, xyzzy.class, nil, :nothing],
[:line, 8, "xyzzy", nil, nil, xyzzy.class, nil, :nothing],
[:line, 9, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer, :nothing],
- [:c_call, 9, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer, :nothing],
- [:c_return, 9, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer, nil],
+ [:c_call, 9, "xyzzy", Module, :method_added, xyzzy.class, nil, :nothing],
+ [:c_return, 9, "xyzzy", Module, :method_added, xyzzy.class, nil, nil],
[:line, 13, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer, :nothing],
- [:c_call, 13, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer, :nothing],
- [:c_return,13, "xyzzy", Module, :method_added, xyzzy.class, :XYZZY_outer, nil],
+ [:c_call, 13, "xyzzy", Module, :method_added, xyzzy.class, nil, :nothing],
+ [:c_return,13, "xyzzy", Module, :method_added, xyzzy.class, nil, nil],
[:end, 17, "xyzzy", nil, nil, xyzzy.class, :XYZZY_outer, :nothing],
[:line, 18, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
- [:c_call, 18, "xyzzy", Class, :new, xyzzy.class, :outer, :nothing],
- [:c_call, 18, "xyzzy", BasicObject, :initialize, xyzzy, :outer, :nothing],
- [:c_return,18, "xyzzy", BasicObject, :initialize, xyzzy, :outer, nil],
- [:c_return,18, "xyzzy", Class, :new, xyzzy.class, :outer, xyzzy],
+ [:c_call, 18, "xyzzy", Class, :new, xyzzy.class, nil, :nothing],
+ [:c_call, 18, "xyzzy", BasicObject, :initialize, xyzzy, nil, :nothing],
+ [:c_return,18, "xyzzy", BasicObject, :initialize, xyzzy, nil, nil],
+ [:c_return,18, "xyzzy", Class, :new, xyzzy.class, nil, xyzzy],
[:line, 19, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
[:call, 9, "xyzzy", xyzzy.class, :foo, xyzzy, nil, :nothing],
[:line, 10, "xyzzy", xyzzy.class, :foo, xyzzy, nil, :nothing],
@@ -521,17 +565,17 @@ class TestSetTraceFunc < Test::Unit::TestCase
[:return, 16, "xyzzy", xyzzy.class, :bar, xyzzy, :XYZZY_bar, xyzzy],
[:return, 12, "xyzzy", xyzzy.class, :foo, xyzzy, :XYZZY_foo, xyzzy],
[:line, 20, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
- [:c_call, 20, "xyzzy", Kernel, :raise, self, :outer, :nothing],
- [:c_call, 20, "xyzzy", Exception, :exception, RuntimeError, :outer, :nothing],
- [:c_call, 20, "xyzzy", Exception, :initialize, raised_exc, :outer, :nothing],
- [:c_return,20, "xyzzy", Exception, :initialize, raised_exc, :outer, raised_exc],
- [:c_return,20, "xyzzy", Exception, :exception, RuntimeError, :outer, raised_exc],
- [:c_return,20, "xyzzy", Kernel, :raise, self, :outer, nil],
- [:c_call, 20, "xyzzy", Exception, :backtrace, raised_exc, :outer, :nothing],
- [:c_return,20, "xyzzy", Exception, :backtrace, raised_exc, :outer, nil],
+ [:c_call, 20, "xyzzy", Kernel, :raise, self, nil, :nothing],
+ [:c_call, 20, "xyzzy", Exception, :exception, RuntimeError, nil, :nothing],
+ [:c_call, 20, "xyzzy", Exception, :initialize, raised_exc, nil, :nothing],
+ [:c_return,20, "xyzzy", Exception, :initialize, raised_exc, nil, raised_exc],
+ [:c_return,20, "xyzzy", Exception, :exception, RuntimeError, nil, raised_exc],
+ [:c_return,20, "xyzzy", Kernel, :raise, self, nil, nil],
+ [:c_call, 20, "xyzzy", Exception, :backtrace, raised_exc, nil, :nothing],
+ [:c_return,20, "xyzzy", Exception, :backtrace, raised_exc, nil, nil],
[:raise, 20, "xyzzy", TestSetTraceFunc, :trace_by_tracepoint, self, :outer, raised_exc],
- [:c_call, 20, "xyzzy", Module, :===, RuntimeError,:outer, :nothing],
- [:c_return,20, "xyzzy", Module, :===, RuntimeError,:outer, true],
+ [:c_call, 20, "xyzzy", Module, :===, RuntimeError, nil, :nothing],
+ [:c_return,20, "xyzzy", Module, :===, RuntimeError, nil, true],
[:line, 21, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
]
@@ -582,6 +626,19 @@ PREP
CODE
end
+ def test_tracepoint_bmethod_memory_leak
+ assert_no_memory_leak([], '', "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #20194]", rss: true)
+ obj = Object.new
+ obj.define_singleton_method(:foo) {}
+ bmethod = obj.method(:foo)
+ tp = TracePoint.new(:return) {}
+ begin;
+ 1_000_000.times do
+ tp.enable(target: bmethod) {}
+ end
+ end;
+ end
+
def trace_by_set_trace_func
events = []
trace = nil
@@ -596,7 +653,7 @@ CODE
1: set_trace_func(lambda{|event, file, line, id, binding, klass|
2: events << [event, line, file, klass, id, binding&.eval('self'), binding&.eval("_local_var")] if file == 'xyzzy'
3: })
- 4: 1.times{|;_local_var| _local_var = :inner
+ 4: [1].map{|;_local_var| _local_var = :inner
5: tap{}
6: }
7: class XYZZY
@@ -912,6 +969,55 @@ CODE
assert_equal(expected*2, events)
end
+ def test_tracepoint_struct
+ c = Struct.new(:x) do
+ alias y x
+ alias y= x=
+ end
+ obj = c.new
+
+ ar_meth = obj.method(:x)
+ aw_meth = obj.method(:x=)
+ aar_meth = obj.method(:y)
+ aaw_meth = obj.method(:y=)
+ events = []
+ trace = TracePoint.new(:c_call, :c_return){|tp|
+ next if !target_thread?
+ next if tp.path != __FILE__
+ next if tp.method_id == :call
+ case tp.event
+ when :c_call
+ assert_raise(RuntimeError) {tp.return_value}
+ events << [tp.event, tp.method_id, tp.callee_id]
+ when :c_return
+ events << [tp.event, tp.method_id, tp.callee_id, tp.return_value]
+ end
+ }
+ test_proc = proc do
+ obj.x = 1
+ obj.x
+ obj.y = 2
+ obj.y
+ aw_meth.call(1)
+ ar_meth.call
+ aaw_meth.call(2)
+ aar_meth.call
+ end
+ test_proc.call # populate call caches
+ trace.enable(&test_proc)
+ expected = [
+ [:c_call, :x=, :x=],
+ [:c_return, :x=, :x=, 1],
+ [:c_call, :x, :x],
+ [:c_return, :x, :x, 1],
+ [:c_call, :x=, :y=],
+ [:c_return, :x=, :y=, 2],
+ [:c_call, :x, :y],
+ [:c_return, :x, :y, 2],
+ ]
+ assert_equal(expected*2, events)
+ end
+
class XYZZYException < Exception; end
def method_test_tracepoint_raised_exception err
raise err
@@ -951,7 +1057,7 @@ CODE
/return/ =~ tp.event ? tp.return_value : nil
]
}.enable{
- 1.times{
+ [1].map{
3
}
method_for_test_tracepoint_block{
@@ -961,10 +1067,10 @@ CODE
# pp events
# expected_events =
[[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
- [:c_call, :times, Integer, Integer, nil],
+ [:c_call, :map, Array, Array, nil],
[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
[:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 3],
- [:c_return, :times, Integer, Integer, 1],
+ [:c_return, :map, Array, Array, [3]],
[:call, :method_for_test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil],
[:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 4],
@@ -1018,9 +1124,9 @@ CODE
when :line
assert_match(/ in /, str)
when :call, :c_call
- assert_match(/call \`/, str) # #<TracePoint:c_call `inherited' ../trunk/test.rb:11>
+ assert_match(/call \'/, str) # #<TracePoint:c_call 'inherited' ../trunk/test.rb:11>
when :return, :c_return
- assert_match(/return \`/, str) # #<TracePoint:return `m' ../trunk/test.rb:3>
+ assert_match(/return \'/, str) # #<TracePoint:return 'm' ../trunk/test.rb:3>
when /thread/
assert_match(/\#<Thread:/, str) # #<TracePoint:thread_end of #<Thread:0x87076c0>>
else
@@ -1153,15 +1259,17 @@ CODE
end
}
assert_normal_exit src % %q{obj.zip({}) {}}, bug7774
- assert_normal_exit src % %q{
- require 'continuation'
- begin
- c = nil
- obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }
- c.call
- rescue RuntimeError
- end
- }, bug7774
+ if respond_to?(:callcc)
+ assert_normal_exit src % %q{
+ require 'continuation'
+ begin
+ c = nil
+ obj.sort_by {|x| callcc {|c2| c ||= c2 }; x }
+ c.call
+ rescue RuntimeError
+ end
+ }, bug7774
+ end
# TracePoint
tp_b = nil
@@ -1267,7 +1375,7 @@ CODE
next if !target_thread?
events << tp.event
}.enable{
- 1.times{
+ [1].map{
3
}
method_for_test_tracepoint_block{
@@ -1289,7 +1397,7 @@ CODE
next if !target_thread?
events << tp.event
}.enable{
- 1.times{
+ [1].map{
3
}
method_for_test_tracepoint_block{
@@ -1648,7 +1756,7 @@ CODE
Bug10724.new
}
- assert_equal([:call, :return], evs)
+ assert_equal([:call, :call, :return, :return], evs)
end
require 'fiber'
@@ -1880,7 +1988,11 @@ CODE
def tp_return_value mid
ary = []
- TracePoint.new(:return, :b_return){|tp| next if !target_thread?; ary << [tp.event, tp.method_id, tp.return_value]}.enable{
+ TracePoint.new(:return, :b_return){|tp|
+ next if !target_thread?
+ next if tp.path != __FILE__
+ ary << [tp.event, tp.method_id, tp.return_value]
+ }.enable{
send mid
}
ary.pop # last b_return event is not required.
@@ -2089,7 +2201,7 @@ CODE
q = Thread::Queue.new
t = Thread.new{
Thread.current.add_trace_func proc{|ev, file, line, *args|
- events << [ev, line]
+ events << [ev, line] if file == __FILE__
} # do not stop trace. They will be stopped at Thread termination.
q.push 1
_x = 1
@@ -2125,9 +2237,9 @@ CODE
}
# it is dirty hack. usually we shouldn't use such technique
Thread.pass until t.status == 'sleep'
- # When MJIT thread exists, t.status becomes 'sleep' even if it does not reach m2t_q.pop.
+ # When RJIT thread exists, t.status becomes 'sleep' even if it does not reach m2t_q.pop.
# This sleep forces it to reach m2t_q.pop for --jit-wait.
- sleep 1 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ sleep 1 if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
t.add_trace_func proc{|ev, file, line, *args|
if file == __FILE__
@@ -2363,6 +2475,18 @@ CODE
assert_equal [:tp1, 1, 2, :tp2, 3], events
end
+ def test_multiple_enable
+ ary = []
+ trace = TracePoint.new(:call) do |tp|
+ ary << tp.method_id
+ end
+ trace.enable
+ trace.enable
+ foo
+ trace.disable
+ assert_equal(1, ary.count(:foo), '[Bug #19114]')
+ end
+
def test_multiple_tracepoints_same_bmethod
events = []
tp1 = TracePoint.new(:return) do |tp|
@@ -2682,4 +2806,123 @@ CODE
Foo.foo
RUBY
end
+
+ def helper_cant_rescue
+ begin
+ raise SyntaxError
+ rescue
+ cant_rescue
+ end
+ end
+
+ def test_tp_rescue
+ lines = []
+ TracePoint.new(:line){|tp|
+ next unless target_thread?
+ lines << tp.lineno
+ }.enable{
+ begin
+ helper_cant_rescue
+ rescue SyntaxError
+ end
+ }
+ _call_line = lines.shift
+ _raise_line = lines.shift
+ assert_equal [], lines
+ end
+
+ def helper_can_rescue
+ begin
+ raise __LINE__.to_s
+ rescue SyntaxError
+ :ng
+ rescue
+ :ok
+ end
+ end
+
+ def helper_can_rescue_empty_body
+ begin
+ raise __LINE__.to_s
+ rescue SyntaxError
+ :ng
+ rescue
+ end
+ end
+
+ def test_tp_rescue_event
+ lines = []
+ TracePoint.new(:rescue){|tp|
+ next unless target_thread?
+ lines << [tp.lineno, tp.raised_exception]
+ }.enable{
+ helper_can_rescue
+ }
+
+ line, err, = lines.pop
+ assert_equal [], lines
+ assert err.kind_of?(RuntimeError)
+ assert_equal err.message.to_i + 4, line
+
+ lines = []
+ TracePoint.new(:rescue){|tp|
+ next unless target_thread?
+ lines << [tp.lineno, tp.raised_exception]
+ }.enable{
+ helper_can_rescue_empty_body
+ }
+
+ line, err, = lines.pop
+ assert_equal [], lines
+ assert err.kind_of?(RuntimeError)
+ assert_equal err.message.to_i + 3, line
+ end
+
+ def test_tracepoint_thread_begin
+ target_thread = nil
+
+ trace = TracePoint.new(:thread_begin) do |tp|
+ target_thread = tp.self
+ end
+
+ trace.enable(target_thread: nil) do
+ Thread.new{}.join
+ end
+
+ assert_kind_of(Thread, target_thread)
+ end
+
+ def test_tracepoint_thread_end
+ target_thread = nil
+
+ trace = TracePoint.new(:thread_end) do |tp|
+ target_thread = tp.self
+ end
+
+ trace.enable(target_thread: nil) do
+ Thread.new{}.join
+ end
+
+ assert_kind_of(Thread, target_thread)
+ end
+
+ def test_tracepoint_thread_end_with_exception
+ target_thread = nil
+
+ trace = TracePoint.new(:thread_end) do |tp|
+ target_thread = tp.self
+ end
+
+ trace.enable(target_thread: nil) do
+ thread = Thread.new do
+ Thread.current.report_on_exception = false
+ raise
+ end
+
+ # Ignore the exception raised by the thread:
+ thread.join rescue nil
+ end
+
+ assert_kind_of(Thread, target_thread)
+ end
end
diff --git a/test/ruby/test_shapes.rb b/test/ruby/test_shapes.rb
new file mode 100644
index 0000000000..9b02504384
--- /dev/null
+++ b/test/ruby/test_shapes.rb
@@ -0,0 +1,1040 @@
+# frozen_string_literal: false
+require 'test/unit'
+require 'objspace'
+require 'json'
+
+# These test the functionality of object shapes
+class TestShapes < Test::Unit::TestCase
+ MANY_IVS = 80
+
+ class IVOrder
+ def expected_ivs
+ %w{ @a @b @c @d @e @f @g @h @i @j @k }
+ end
+
+ def set_ivs
+ expected_ivs.each { instance_variable_set(_1, 1) }
+ self
+ end
+ end
+
+ class ShapeOrder
+ def initialize
+ @b = :b # 5 => 6
+ end
+
+ def set_b
+ @b = :b # 5 => 6
+ end
+
+ def set_c
+ @c = :c # 5 => 7
+ end
+ end
+
+ class OrderedAlloc
+ def add_ivars
+ 10.times do |i|
+ instance_variable_set("@foo" + i.to_s, 0)
+ end
+ end
+ end
+
+ class Example
+ def initialize
+ @a = 1
+ end
+ end
+
+ class RemoveAndAdd
+ def add_foo
+ @foo = 1
+ end
+
+ def remove_foo
+ remove_instance_variable(:@foo)
+ end
+
+ def add_bar
+ @bar = 1
+ end
+ end
+
+ class TooComplex
+ attr_reader :hopefully_unique_name, :b
+
+ def initialize
+ @hopefully_unique_name = "a"
+ @b = "b"
+ end
+
+ # Make enough lazily defined accessors to allow us to force
+ # polymorphism
+ class_eval (RubyVM::Shape::SHAPE_MAX_VARIATIONS + 1).times.map {
+ "def a#{_1}_m; @a#{_1} ||= #{_1}; end"
+ }.join(" ; ")
+
+ class_eval "attr_accessor " + (RubyVM::Shape::SHAPE_MAX_VARIATIONS + 1).times.map {
+ ":a#{_1}"
+ }.join(", ")
+
+ def iv_not_defined; @not_defined; end
+
+ def write_iv_method
+ self.a3 = 12345
+ end
+
+ def write_iv
+ @a3 = 12345
+ end
+ end
+
+ # RubyVM::Shape.of returns new instances of shape objects for
+ # each call. This helper method allows us to define equality for
+ # shapes
+ def assert_shape_equal(shape1, shape2)
+ assert_equal(shape1.id, shape2.id)
+ assert_equal(shape1.parent_id, shape2.parent_id)
+ assert_equal(shape1.depth, shape2.depth)
+ assert_equal(shape1.type, shape2.type)
+ end
+
+ def refute_shape_equal(shape1, shape2)
+ refute_equal(shape1.id, shape2.id)
+ end
+
+ def test_iv_order_correct_on_complex_objects
+ (RubyVM::Shape::SHAPE_MAX_VARIATIONS + 1).times {
+ IVOrder.new.instance_variable_set("@a#{_1}", 1)
+ }
+
+ obj = IVOrder.new
+ iv_list = obj.set_ivs.instance_variables
+ assert_equal obj.expected_ivs, iv_list.map(&:to_s)
+ end
+
+ def test_too_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ end
+
+ def test_ordered_alloc_is_not_complex
+ 5.times { OrderedAlloc.new.add_ivars }
+ obj = JSON.parse(ObjectSpace.dump(OrderedAlloc))
+ assert_operator obj["variation_count"], :<, RubyVM::Shape::SHAPE_MAX_VARIATIONS
+ end
+
+ def test_too_many_ivs_on_obj
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class Hi; end
+
+ RubyVM::Shape.exhaust_shapes(2)
+
+ obj = Hi.new
+ obj.instance_variable_set(:@b, 1)
+ obj.instance_variable_set(:@c, 1)
+ obj.instance_variable_set(:@d, 1)
+
+ assert_predicate RubyVM::Shape.of(obj), :too_complex?
+ end;
+ end
+
+ def test_too_many_ivs_on_class
+ obj = Class.new
+
+ (MANY_IVS + 1).times do
+ obj.instance_variable_set(:"@a#{_1}", 1)
+ end
+
+ assert_false RubyVM::Shape.of(obj).too_complex?
+ end
+
+ def test_removing_when_too_many_ivs_on_class
+ obj = Class.new
+
+ (MANY_IVS + 2).times do
+ obj.instance_variable_set(:"@a#{_1}", 1)
+ end
+ (MANY_IVS + 2).times do
+ obj.remove_instance_variable(:"@a#{_1}")
+ end
+
+ assert_empty obj.instance_variables
+ end
+
+ def test_removing_when_too_many_ivs_on_module
+ obj = Module.new
+
+ (MANY_IVS + 2).times do
+ obj.instance_variable_set(:"@a#{_1}", 1)
+ end
+ (MANY_IVS + 2).times do
+ obj.remove_instance_variable(:"@a#{_1}")
+ end
+
+ assert_empty obj.instance_variables
+ end
+
+ def test_too_complex_geniv
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class TooComplex < Hash
+ attr_reader :very_unique
+ end
+
+ RubyVM::Shape.exhaust_shapes
+
+ (RubyVM::Shape::SHAPE_MAX_VARIATIONS * 2).times do
+ TooComplex.new.instance_variable_set(:"@unique_#{_1}", 1)
+ end
+
+ tc = TooComplex.new
+ tc.instance_variable_set(:@very_unique, 3)
+ tc.instance_variable_set(:@very_unique2, 4)
+ assert_equal 3, tc.instance_variable_get(:@very_unique)
+ assert_equal 4, tc.instance_variable_get(:@very_unique2)
+
+ assert_equal [:@very_unique, :@very_unique2], tc.instance_variables
+ end;
+ end
+
+ def test_use_all_shapes_then_freeze
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class Hi; end
+ RubyVM::Shape.exhaust_shapes(3)
+
+ obj = Hi.new
+ i = 0
+ while RubyVM::Shape.shapes_available > 0
+ obj.instance_variable_set(:"@b#{i}", 1)
+ i += 1
+ end
+ obj.freeze
+
+ assert obj.frozen?
+ end;
+ end
+
+ def test_run_out_of_shape_for_object
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class A
+ def initialize
+ @a = 1
+ end
+ end
+ RubyVM::Shape.exhaust_shapes
+
+ A.new
+ end;
+ end
+
+ def test_run_out_of_shape_for_class_ivar
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ RubyVM::Shape.exhaust_shapes
+
+ c = Class.new
+ c.instance_variable_set(:@a, 1)
+ assert_equal(1, c.instance_variable_get(:@a))
+
+ c.remove_instance_variable(:@a)
+ assert_nil(c.instance_variable_get(:@a))
+
+ assert_raise(NameError) do
+ c.remove_instance_variable(:@a)
+ end
+ end;
+ end
+
+ def test_evacuate_class_ivar_and_compaction
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ count = 20
+
+ c = Class.new
+ count.times do |ivar|
+ c.instance_variable_set("@i#{ivar}", "ivar-#{ivar}")
+ end
+
+ RubyVM::Shape.exhaust_shapes
+
+ GC.auto_compact = true
+ GC.stress = true
+ # Cause evacuation
+ c.instance_variable_set(:@a, o = Object.new)
+ assert_equal(o, c.instance_variable_get(:@a))
+ GC.stress = false
+
+ count.times do |ivar|
+ assert_equal "ivar-#{ivar}", c.instance_variable_get("@i#{ivar}")
+ end
+ end;
+ end
+
+ def test_evacuate_generic_ivar_and_compaction
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ count = 20
+
+ c = Hash.new
+ count.times do |ivar|
+ c.instance_variable_set("@i#{ivar}", "ivar-#{ivar}")
+ end
+
+ RubyVM::Shape.exhaust_shapes
+
+ GC.auto_compact = true
+ GC.stress = true
+
+ # Cause evacuation
+ c.instance_variable_set(:@a, o = Object.new)
+ assert_equal(o, c.instance_variable_get(:@a))
+
+ GC.stress = false
+
+ count.times do |ivar|
+ assert_equal "ivar-#{ivar}", c.instance_variable_get("@i#{ivar}")
+ end
+ end;
+ end
+
+ def test_evacuate_object_ivar_and_compaction
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ count = 20
+
+ c = Object.new
+ count.times do |ivar|
+ c.instance_variable_set("@i#{ivar}", "ivar-#{ivar}")
+ end
+
+ RubyVM::Shape.exhaust_shapes
+
+ GC.auto_compact = true
+ GC.stress = true
+
+ # Cause evacuation
+ c.instance_variable_set(:@a, o = Object.new)
+ assert_equal(o, c.instance_variable_get(:@a))
+
+ GC.stress = false
+
+ count.times do |ivar|
+ assert_equal "ivar-#{ivar}", c.instance_variable_get("@i#{ivar}")
+ end
+ end;
+ end
+
+ def test_gc_stress_during_evacuate_generic_ivar
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ [].instance_variable_set(:@a, 1)
+
+ RubyVM::Shape.exhaust_shapes
+
+ ary = 10.times.map { [] }
+
+ GC.stress = true
+ ary.each do |o|
+ o.instance_variable_set(:@a, 1)
+ o.instance_variable_set(:@b, 1)
+ end
+ end;
+ end
+
+ def test_run_out_of_shape_for_module_ivar
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ RubyVM::Shape.exhaust_shapes
+
+ module Foo
+ @a = 1
+ @b = 2
+ assert_equal 1, @a
+ assert_equal 2, @b
+ end
+ end;
+ end
+
+ def test_run_out_of_shape_for_class_cvar
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ RubyVM::Shape.exhaust_shapes
+
+ c = Class.new
+
+ c.class_variable_set(:@@a, 1)
+ assert_equal(1, c.class_variable_get(:@@a))
+
+ c.class_eval { remove_class_variable(:@@a) }
+ assert_false(c.class_variable_defined?(:@@a))
+
+ assert_raise(NameError) do
+ c.class_eval { remove_class_variable(:@@a) }
+ end
+ end;
+ end
+
+ def test_run_out_of_shape_generic_instance_variable_set
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class TooComplex < Hash
+ end
+
+ RubyVM::Shape.exhaust_shapes
+
+ tc = TooComplex.new
+ tc.instance_variable_set(:@a, 1)
+ tc.instance_variable_set(:@b, 2)
+
+ tc.remove_instance_variable(:@a)
+ assert_nil(tc.instance_variable_get(:@a))
+
+ assert_raise(NameError) do
+ tc.remove_instance_variable(:@a)
+ end
+ end;
+ end
+
+ def test_run_out_of_shape_generic_ivar_set
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class Hi < String
+ def initialize
+ 8.times do |i|
+ instance_variable_set("@ivar_#{i}", i)
+ end
+ end
+
+ def transition
+ @hi_transition ||= 1
+ end
+ end
+
+ a = Hi.new
+
+ # Try to run out of shapes
+ RubyVM::Shape.exhaust_shapes
+
+ assert_equal 1, a.transition
+ assert_equal 1, a.transition
+ end;
+ end
+
+ def test_run_out_of_shape_instance_variable_defined
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class A
+ attr_reader :a, :b, :c, :d
+ def initialize
+ @a = @b = @c = @d = 1
+ end
+ end
+
+ RubyVM::Shape.exhaust_shapes
+
+ a = A.new
+ assert_equal true, a.instance_variable_defined?(:@a)
+ end;
+ end
+
+ def test_run_out_of_shape_instance_variable_defined_on_module
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ RubyVM::Shape.exhaust_shapes
+
+ module A
+ @a = @b = @c = @d = 1
+ end
+
+ assert_equal true, A.instance_variable_defined?(:@a)
+ end;
+ end
+
+ def test_run_out_of_shape_during_remove_instance_variable
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ o = Object.new
+ 10.times { |i| o.instance_variable_set(:"@a#{i}", i) }
+
+ RubyVM::Shape.exhaust_shapes
+
+ o.remove_instance_variable(:@a0)
+ (1...10).each do |i|
+ assert_equal(i, o.instance_variable_get(:"@a#{i}"))
+ end
+ end;
+ end
+
+ def test_run_out_of_shape_remove_instance_variable
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class A
+ attr_reader :a, :b, :c, :d
+ def initialize
+ @a = @b = @c = @d = 1
+ end
+ end
+
+ a = A.new
+
+ RubyVM::Shape.exhaust_shapes
+
+ a.remove_instance_variable(:@b)
+ assert_nil a.b
+
+ a.remove_instance_variable(:@a)
+ assert_nil a.a
+
+ a.remove_instance_variable(:@c)
+ assert_nil a.c
+
+ assert_equal 1, a.d
+ end;
+ end
+
+ def test_run_out_of_shape_rb_obj_copy_ivar
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class A
+ def initialize
+ init # Avoid right sizing
+ end
+
+ def init
+ @a = @b = @c = @d = @e = @f = 1
+ end
+ end
+
+ a = A.new
+
+ RubyVM::Shape.exhaust_shapes
+
+ a.dup
+ end;
+ end
+
+ def test_evacuate_generic_ivar_memory_leak
+ assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
+ o = []
+ o.instance_variable_set(:@a, 1)
+
+ RubyVM::Shape.exhaust_shapes
+
+ ary = 1_000_000.times.map { [] }
+ begin;
+ ary.each do |o|
+ o.instance_variable_set(:@a, 1)
+ o.instance_variable_set(:@b, 1)
+ end
+ ary.clear
+ ary = nil
+ GC.start
+ end;
+ end
+
+ def test_use_all_shapes_module
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class Hi; end
+
+ RubyVM::Shape.exhaust_shapes(2)
+
+ obj = Module.new
+ 3.times do
+ obj.instance_variable_set(:"@a#{_1}", _1)
+ end
+
+ ivs = 3.times.map do
+ obj.instance_variable_get(:"@a#{_1}")
+ end
+
+ assert_equal [0, 1, 2], ivs
+ end;
+ end
+
+ def test_complex_freeze_after_clone
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class Hi; end
+
+ RubyVM::Shape.exhaust_shapes(2)
+
+ obj = Object.new
+ i = 0
+ while RubyVM::Shape.shapes_available > 0
+ obj.instance_variable_set(:"@b#{i}", i)
+ i += 1
+ end
+
+ v = obj.clone(freeze: true)
+ assert_predicate v, :frozen?
+ assert_equal 0, v.instance_variable_get(:@b0)
+ end;
+ end
+
+ def test_too_complex_ractor
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ $VERBOSE = nil
+ class TooComplex
+ attr_reader :very_unique
+ end
+
+ RubyVM::Shape::SHAPE_MAX_VARIATIONS.times do
+ TooComplex.new.instance_variable_set(:"@unique_#{_1}", Object.new)
+ end
+
+ tc = TooComplex.new
+ tc.instance_variable_set(:"@very_unique", 3)
+
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ assert_equal 3, tc.very_unique
+ assert_equal 3, Ractor.new(tc) { |x| Ractor.yield(x.very_unique) }.take
+ assert_equal tc.instance_variables.sort, Ractor.new(tc) { |x| Ractor.yield(x.instance_variables) }.take.sort
+ end;
+ end
+
+ def test_too_complex_ractor_shareable
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ $VERBOSE = nil
+ class TooComplex
+ attr_reader :very_unique
+ end
+
+ RubyVM::Shape::SHAPE_MAX_VARIATIONS.times do
+ TooComplex.new.instance_variable_set(:"@unique_#{_1}", Object.new)
+ end
+
+ tc = TooComplex.new
+ tc.instance_variable_set(:"@very_unique", 3)
+
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ assert_equal 3, tc.very_unique
+ assert_equal 3, Ractor.make_shareable(tc).very_unique
+ end;
+ end
+
+ def test_too_complex_obj_ivar_ractor_share
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ $VERBOSE = nil
+
+ RubyVM::Shape.exhaust_shapes
+
+ r = Ractor.new do
+ o = Object.new
+ o.instance_variable_set(:@a, "hello")
+ Ractor.yield(o)
+ end
+
+ o = r.take
+ assert_equal "hello", o.instance_variable_get(:@a)
+ end;
+ end
+
+ def test_too_complex_generic_ivar_ractor_share
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ $VERBOSE = nil
+
+ RubyVM::Shape.exhaust_shapes
+
+ r = Ractor.new do
+ o = []
+ o.instance_variable_set(:@a, "hello")
+ Ractor.yield(o)
+ end
+
+ o = r.take
+ assert_equal "hello", o.instance_variable_get(:@a)
+ end;
+ end
+
+ def test_read_iv_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ assert_equal 3, tc.a3_m
+ end
+
+ def test_read_method_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ assert_equal 3, tc.a3_m
+ assert_equal 3, tc.a3
+ end
+
+ def test_write_method_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ tc.write_iv_method
+ tc.write_iv_method
+ assert_equal 12345, tc.a3_m
+ assert_equal 12345, tc.a3
+ end
+
+ def test_write_iv_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ tc.write_iv
+ tc.write_iv
+ assert_equal 12345, tc.a3_m
+ assert_equal 12345, tc.a3
+ end
+
+ def test_iv_read_via_method_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ assert_equal 3, tc.a3_m
+ assert_equal 3, tc.instance_variable_get(:@a3)
+ end
+
+ def test_delete_iv_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+
+ assert_equal 3, tc.a3_m # make sure IV is initialized
+ assert tc.instance_variable_defined?(:@a3)
+ tc.remove_instance_variable(:@a3)
+ assert_nil tc.a3
+ end
+
+ def test_delete_undefined_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+
+ refute tc.instance_variable_defined?(:@a3)
+ assert_raise(NameError) do
+ tc.remove_instance_variable(:@a3)
+ end
+ assert_nil tc.a3
+ end
+
+ def test_remove_instance_variable
+ ivars_count = 5
+ object = Object.new
+ ivars_count.times do |i|
+ object.instance_variable_set("@ivar_#{i}", i)
+ end
+
+ ivars = ivars_count.times.map do |i|
+ object.instance_variable_get("@ivar_#{i}")
+ end
+ assert_equal [0, 1, 2, 3, 4], ivars
+
+ object.remove_instance_variable(:@ivar_2)
+
+ ivars = ivars_count.times.map do |i|
+ object.instance_variable_get("@ivar_#{i}")
+ end
+ assert_equal [0, 1, nil, 3, 4], ivars
+ end
+
+ def test_remove_instance_variable_when_out_of_shapes
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ ivars_count = 5
+ object = Object.new
+ ivars_count.times do |i|
+ object.instance_variable_set("@ivar_#{i}", i)
+ end
+
+ ivars = ivars_count.times.map do |i|
+ object.instance_variable_get("@ivar_#{i}")
+ end
+ assert_equal [0, 1, 2, 3, 4], ivars
+
+ RubyVM::Shape.exhaust_shapes
+
+ object.remove_instance_variable(:@ivar_2)
+
+ ivars = ivars_count.times.map do |i|
+ object.instance_variable_get("@ivar_#{i}")
+ end
+ assert_equal [0, 1, nil, 3, 4], ivars
+ end;
+ end
+
+ def test_remove_instance_variable_capacity_transition
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ t_object_shape = RubyVM::Shape.find_by_id(RubyVM::Shape::FIRST_T_OBJECT_SHAPE_ID)
+ assert_equal(RubyVM::Shape::SHAPE_T_OBJECT, t_object_shape.type)
+
+ initial_capacity = t_object_shape.capacity
+
+ # a does not transition in capacity
+ a = Class.new.new
+ initial_capacity.times do |i|
+ a.instance_variable_set(:"@ivar#{i + 1}", i)
+ end
+
+ # b transitions in capacity
+ b = Class.new.new
+ (initial_capacity + 1).times do |i|
+ b.instance_variable_set(:"@ivar#{i}", i)
+ end
+
+ assert_operator(RubyVM::Shape.of(a).capacity, :<, RubyVM::Shape.of(b).capacity)
+
+ # b will now have the same tree as a
+ b.remove_instance_variable(:@ivar0)
+
+ a.instance_variable_set(:@foo, 1)
+ a.instance_variable_set(:@bar, 1)
+
+ # Check that there is no heap corruption
+ GC.verify_internal_consistency
+ end;
+ end
+
+ def test_freeze_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ tc.freeze
+ assert_raise(FrozenError) { tc.a3_m }
+ # doesn't transition to frozen shape in this case
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ end
+
+ def test_read_undefined_iv_after_complex
+ ensure_complex
+
+ tc = TooComplex.new
+ tc.send("a#{RubyVM::Shape::SHAPE_MAX_VARIATIONS}_m")
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ assert_equal nil, tc.iv_not_defined
+ assert_predicate RubyVM::Shape.of(tc), :too_complex?
+ end
+
+ def test_shape_order
+ bar = ShapeOrder.new # 0 => 1
+ bar.set_c # 1 => 2
+ bar.set_b # 2 => 2
+
+ foo = ShapeOrder.new # 0 => 1
+ shape_id = RubyVM::Shape.of(foo).id
+ foo.set_b # should not transition
+ assert_equal shape_id, RubyVM::Shape.of(foo).id
+ end
+
+ def test_iv_index
+ example = RemoveAndAdd.new
+ initial_shape = RubyVM::Shape.of(example)
+ assert_equal 0, initial_shape.next_iv_index
+
+ example.add_foo # makes a transition
+ add_foo_shape = RubyVM::Shape.of(example)
+ assert_equal([:@foo], example.instance_variables)
+ assert_equal(initial_shape.id, add_foo_shape.parent.id)
+ assert_equal(1, add_foo_shape.next_iv_index)
+
+ example.remove_foo # makes a transition
+ remove_foo_shape = RubyVM::Shape.of(example)
+ assert_equal([], example.instance_variables)
+ assert_shape_equal(initial_shape, remove_foo_shape)
+
+ example.add_bar # makes a transition
+ bar_shape = RubyVM::Shape.of(example)
+ assert_equal([:@bar], example.instance_variables)
+ assert_equal(initial_shape.id, bar_shape.parent_id)
+ assert_equal(1, bar_shape.next_iv_index)
+ end
+
+ def test_remove_then_add_again
+ example = RemoveAndAdd.new
+ _initial_shape = RubyVM::Shape.of(example)
+
+ example.add_foo # makes a transition
+ add_foo_shape = RubyVM::Shape.of(example)
+ example.remove_foo # makes a transition
+ example.add_foo # makes a transition
+ assert_shape_equal(add_foo_shape, RubyVM::Shape.of(example))
+ end
+
+ class TestObject; end
+
+ def test_new_obj_has_t_object_shape
+ obj = TestObject.new
+ shape = RubyVM::Shape.of(obj)
+ assert_equal RubyVM::Shape::SHAPE_T_OBJECT, shape.type
+ assert_nil shape.parent
+ end
+
+ def test_str_has_root_shape
+ assert_shape_equal(RubyVM::Shape.root_shape, RubyVM::Shape.of(""))
+ end
+
+ def test_array_has_root_shape
+ assert_shape_equal(RubyVM::Shape.root_shape, RubyVM::Shape.of([]))
+ end
+
+ def test_true_has_special_const_shape_id
+ assert_equal(RubyVM::Shape::SPECIAL_CONST_SHAPE_ID, RubyVM::Shape.of(true).id)
+ end
+
+ def test_nil_has_special_const_shape_id
+ assert_equal(RubyVM::Shape::SPECIAL_CONST_SHAPE_ID, RubyVM::Shape.of(nil).id)
+ end
+
+ def test_root_shape_transition_to_special_const_on_frozen
+ assert_equal(RubyVM::Shape::SPECIAL_CONST_SHAPE_ID, RubyVM::Shape.of([].freeze).id)
+ end
+
+ def test_basic_shape_transition
+ omit "Failing with RJIT for some reason" if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ obj = Example.new
+ shape = RubyVM::Shape.of(obj)
+ refute_equal(RubyVM::Shape.root_shape, shape)
+ assert_equal :@a, shape.edge_name
+ assert_equal RubyVM::Shape::SHAPE_IVAR, shape.type
+
+ shape = shape.parent
+ assert_equal RubyVM::Shape::SHAPE_T_OBJECT, shape.type
+ assert_nil shape.parent
+
+ assert_equal(1, obj.instance_variable_get(:@a))
+ end
+
+ def test_different_objects_make_same_transition
+ obj = []
+ obj2 = ""
+ obj.instance_variable_set(:@a, 1)
+ obj2.instance_variable_set(:@a, 1)
+ assert_shape_equal(RubyVM::Shape.of(obj), RubyVM::Shape.of(obj2))
+ end
+
+ def test_duplicating_objects
+ obj = Example.new
+ obj2 = obj.dup
+ assert_shape_equal(RubyVM::Shape.of(obj), RubyVM::Shape.of(obj2))
+ end
+
+ def test_duplicating_too_complex_objects_memory_leak
+ assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", "[Bug #20162]", rss: true)
+ RubyVM::Shape.exhaust_shapes
+
+ o = Object.new
+ o.instance_variable_set(:@a, 0)
+ begin;
+ 1_000_000.times do
+ o.dup
+ end
+ end;
+ end
+
+ def test_freezing_and_duplicating_object
+ obj = Object.new.freeze
+ obj2 = obj.dup
+ refute_predicate(obj2, :frozen?)
+ # dup'd objects shouldn't be frozen, and the shape should be the
+ # parent shape of the copied object
+ assert_equal(RubyVM::Shape.of(obj).parent.id, RubyVM::Shape.of(obj2).id)
+ end
+
+ def test_freezing_and_duplicating_object_with_ivars
+ obj = Example.new.freeze
+ obj2 = obj.dup
+ refute_predicate(obj2, :frozen?)
+ refute_shape_equal(RubyVM::Shape.of(obj), RubyVM::Shape.of(obj2))
+ assert_equal(obj2.instance_variable_get(:@a), 1)
+ end
+
+ def test_freezing_and_duplicating_string_with_ivars
+ str = "str"
+ str.instance_variable_set(:@a, 1)
+ str.freeze
+ str2 = str.dup
+ refute_predicate(str2, :frozen?)
+ refute_equal(RubyVM::Shape.of(str).id, RubyVM::Shape.of(str2).id)
+ assert_equal(str2.instance_variable_get(:@a), 1)
+ end
+
+ def test_freezing_and_cloning_objects
+ obj = Object.new.freeze
+ obj2 = obj.clone(freeze: true)
+ assert_predicate(obj2, :frozen?)
+ assert_shape_equal(RubyVM::Shape.of(obj), RubyVM::Shape.of(obj2))
+ end
+
+ def test_cloning_with_freeze_option
+ obj = Object.new
+ obj2 = obj.clone(freeze: true)
+ assert_predicate(obj2, :frozen?)
+ refute_shape_equal(RubyVM::Shape.of(obj), RubyVM::Shape.of(obj2))
+ assert_equal(RubyVM::Shape::SHAPE_FROZEN, RubyVM::Shape.of(obj2).type)
+ assert_shape_equal(RubyVM::Shape.of(obj), RubyVM::Shape.of(obj2).parent)
+ end
+
+ def test_freezing_and_cloning_object_with_ivars
+ obj = Example.new.freeze
+ obj2 = obj.clone(freeze: true)
+ assert_predicate(obj2, :frozen?)
+ assert_shape_equal(RubyVM::Shape.of(obj), RubyVM::Shape.of(obj2))
+ assert_equal(obj2.instance_variable_get(:@a), 1)
+ end
+
+ def test_freezing_and_cloning_string
+ str = ("str" + "str").freeze
+ str2 = str.clone(freeze: true)
+ assert_predicate(str2, :frozen?)
+ assert_shape_equal(RubyVM::Shape.of(str), RubyVM::Shape.of(str2))
+ end
+
+ def test_freezing_and_cloning_string_with_ivars
+ str = "str"
+ str.instance_variable_set(:@a, 1)
+ str.freeze
+ str2 = str.clone(freeze: true)
+ assert_predicate(str2, :frozen?)
+ assert_shape_equal(RubyVM::Shape.of(str), RubyVM::Shape.of(str2))
+ assert_equal(str2.instance_variable_get(:@a), 1)
+ end
+
+ def test_out_of_bounds_shape
+ assert_raise ArgumentError do
+ RubyVM::Shape.find_by_id(RubyVM.stat[:next_shape_id])
+ end
+ assert_raise ArgumentError do
+ RubyVM::Shape.find_by_id(-1)
+ end
+ end
+
+ def ensure_complex
+ RubyVM::Shape::SHAPE_MAX_VARIATIONS.times do
+ tc = TooComplex.new
+ tc.send("a#{_1}_m")
+ end
+ end
+end if defined?(RubyVM::Shape)
diff --git a/test/ruby/test_signal.rb b/test/ruby/test_signal.rb
index c5043eea59..7877a35129 100644
--- a/test/ruby/test_signal.rb
+++ b/test/ruby/test_signal.rb
@@ -323,49 +323,6 @@ class TestSignal < Test::Unit::TestCase
end;
end
- def test_sigchld_ignore
- omit 'no SIGCHLD' unless Signal.list['CHLD']
- old = trap(:CHLD, 'IGNORE')
- cmd = [ EnvUtil.rubybin, '--disable=gems', '-e' ]
- assert(system(*cmd, 'exit!(0)'), 'no ECHILD')
- IO.pipe do |r, w|
- pid = spawn(*cmd, "STDIN.read", in: r)
- nb = Process.wait(pid, Process::WNOHANG)
- th = Thread.new(Thread.current) do |parent|
- Thread.pass until parent.stop? # wait for parent to Process.wait
- w.close
- end
- assert_raise(Errno::ECHILD) { Process.wait(pid) }
- th.join
- assert_nil nb
- end
-
- IO.pipe do |r, w|
- pids = 3.times.map { spawn(*cmd, 'exit!', out: w) }
- w.close
- zombies = pids.dup
- assert_nil r.read(1), 'children dead'
-
- Timeout.timeout(10) do
- zombies.delete_if do |pid|
- begin
- Process.kill(0, pid)
- false
- rescue Errno::ESRCH
- true
- end
- end while zombies[0]
- end
- assert_predicate zombies, :empty?, 'zombies leftover'
-
- pids.each do |pid|
- assert_raise(Errno::ECHILD) { Process.waitpid(pid) }
- end
- end
- ensure
- trap(:CHLD, old) if Signal.list['CHLD']
- end
-
def test_sigwait_fd_unused
t = EnvUtil.apply_timeout_scale(0.1)
assert_separately([], <<-End)
diff --git a/test/ruby/test_sprintf.rb b/test/ruby/test_sprintf.rb
index f2e73eb58d..c453ecd350 100644
--- a/test/ruby/test_sprintf.rb
+++ b/test/ruby/test_sprintf.rb
@@ -362,11 +362,16 @@ class TestSprintf < Test::Unit::TestCase
def test_char
assert_equal("a", sprintf("%c", 97))
assert_equal("a", sprintf("%c", ?a))
- assert_raise(ArgumentError) { sprintf("%c", sprintf("%c%c", ?a, ?a)) }
+ assert_equal("a", sprintf("%c", "a"))
+ assert_equal("a", sprintf("%c", sprintf("%c%c", ?a, ?a)))
assert_equal(" " * (BSIZ - 1) + "a", sprintf(" " * (BSIZ - 1) + "%c", ?a))
assert_equal(" " * (BSIZ - 1) + "a", sprintf(" " * (BSIZ - 1) + "%-1c", ?a))
assert_equal(" " * BSIZ + "a", sprintf("%#{ BSIZ + 1 }c", ?a))
assert_equal("a" + " " * BSIZ, sprintf("%-#{ BSIZ + 1 }c", ?a))
+ assert_raise(ArgumentError) { sprintf("%c", -1) }
+ s = sprintf("%c".encode(Encoding::US_ASCII), 0x80)
+ assert_equal("\x80".b, s)
+ assert_predicate(s, :valid_encoding?)
end
def test_string
@@ -507,6 +512,16 @@ class TestSprintf < Test::Unit::TestCase
end
end
+ def test_coderange
+ format_str = "wrong constant name %s"
+ interpolated_str = "\u3042"
+ assert_predicate format_str, :ascii_only?
+ refute_predicate interpolated_str, :ascii_only?
+
+ str = format_str % interpolated_str
+ refute_predicate str, :ascii_only?
+ end
+
def test_named_default
h = Hash.new('world')
assert_equal("hello world", "hello %{location}" % h)
diff --git a/test/ruby/test_stack.rb b/test/ruby/test_stack.rb
index 763aeb6bc2..8a78848322 100644
--- a/test/ruby/test_stack.rb
+++ b/test/ruby/test_stack.rb
@@ -18,7 +18,6 @@ class TestStack < Test::Unit::TestCase
env = {}
env['RUBY_FIBER_VM_STACK_SIZE'] = vm_stack_size.to_s if vm_stack_size
env['RUBY_FIBER_MACHINE_STACK_SIZE'] = machine_stack_size.to_s if machine_stack_size
- env['ASAN_OPTIONS'] = ENV['ASAN_OPTIONS'] if ENV['ASAN_OPTIONS']
stdout, stderr, status = EnvUtil.invoke_ruby([env, '-e', script], '', true, true, timeout: 30)
assert(!status.signaled?, FailDesc[status, nil, stderr])
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index ab14a3c17b..13261eacdd 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -9,9 +9,6 @@ class TestString < Test::Unit::TestCase
def initialize(*args)
@cls = String
- @aref_re_nth = true
- @aref_re_silent = false
- @aref_slicebang_silent = true
super
end
@@ -80,6 +77,13 @@ class TestString < Test::Unit::TestCase
assert_equal("mystring", str.__send__(:initialize, "mystring", capacity: 1000))
str = S("mystring")
assert_equal("mystring", str.__send__(:initialize, str, capacity: 1000))
+
+ if @cls == String
+ 100.times {
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".
+ __send__(:initialize, capacity: -1)
+ }
+ end
end
def test_initialize_shared
@@ -100,7 +104,7 @@ class TestString < Test::Unit::TestCase
return unless @cls == String
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
-code = proc {('x'*100000).__send__(:initialize, '')}
+code = proc {('x'*100_000).__send__(:initialize, '')}
1_000.times(&code)
PREP
100_000.times(&code)
@@ -112,7 +116,7 @@ CODE
return unless @cls == String
assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
-code = proc {0.to_s.__send__(:initialize, capacity: 10000)}
+code = proc {0.to_s.__send__(:initialize, capacity: 100_000)}
1_000.times(&code)
PREP
100_000.times(&code)
@@ -146,14 +150,12 @@ CODE
assert_equal(nil, S("FooBar")[S("xyzzy")])
assert_equal(nil, S("FooBar")[S("plugh")])
- if @aref_re_nth
- assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/, 1])
- assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/, 2])
- assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/, 3])
- assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/, -1])
- assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/, -2])
- assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/, -3])
- end
+ assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/, 1])
+ assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/, 2])
+ assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/, 3])
+ assert_equal(S("Bar"), S("FooBar")[/([A-Z]..)([A-Z]..)/, -1])
+ assert_equal(S("Foo"), S("FooBar")[/([A-Z]..)([A-Z]..)/, -2])
+ assert_equal(nil, S("FooBar")[/([A-Z]..)([A-Z]..)/, -3])
o = Object.new
def o.to_int; 2; end
@@ -199,24 +201,18 @@ CODE
assert_equal(S("BarBar"), s)
s[/..r$/] = S("Foo")
assert_equal(S("BarFoo"), s)
- if @aref_re_silent
- s[/xyzzy/] = S("None")
- assert_equal(S("BarFoo"), s)
- else
- assert_raise(IndexError) { s[/xyzzy/] = S("None") }
- end
- if @aref_re_nth
- s[/([A-Z]..)([A-Z]..)/, 1] = S("Foo")
- assert_equal(S("FooFoo"), s)
- s[/([A-Z]..)([A-Z]..)/, 2] = S("Bar")
- assert_equal(S("FooBar"), s)
- assert_raise(IndexError) { s[/([A-Z]..)([A-Z]..)/, 3] = "None" }
- s[/([A-Z]..)([A-Z]..)/, -1] = S("Foo")
- assert_equal(S("FooFoo"), s)
- s[/([A-Z]..)([A-Z]..)/, -2] = S("Bar")
- assert_equal(S("BarFoo"), s)
- assert_raise(IndexError) { s[/([A-Z]..)([A-Z]..)/, -3] = "None" }
- end
+ assert_raise(IndexError) { s[/xyzzy/] = S("None") }
+
+ s[/([A-Z]..)([A-Z]..)/, 1] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ s[/([A-Z]..)([A-Z]..)/, 2] = S("Bar")
+ assert_equal(S("FooBar"), s)
+ assert_raise(IndexError) { s[/([A-Z]..)([A-Z]..)/, 3] = "None" }
+ s[/([A-Z]..)([A-Z]..)/, -1] = S("Foo")
+ assert_equal(S("FooFoo"), s)
+ s[/([A-Z]..)([A-Z]..)/, -2] = S("Bar")
+ assert_equal(S("BarFoo"), s)
+ assert_raise(IndexError) { s[/([A-Z]..)([A-Z]..)/, -3] = "None" }
s = S("FooBar")
s[S("Foo")] = S("Bar")
@@ -301,6 +297,9 @@ CODE
assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << -1}
assert_raise(RangeError, bug) {S("a".force_encoding(Encoding::UTF_8)) << 0x81308130}
assert_nothing_raised {S("a".force_encoding(Encoding::GB18030)) << 0x81308130}
+
+ s = "\x95".force_encoding(Encoding::SJIS).tap(&:valid_encoding?)
+ assert_predicate(s << 0x5c, :valid_encoding?)
end
def test_MATCH # '=~'
@@ -587,6 +586,8 @@ CODE
assert_equal("foo", s.chomp!("\n"))
s = "foo\r"
assert_equal("foo", s.chomp!("\n"))
+
+ assert_raise(ArgumentError) {String.new.chomp!("", "")}
ensure
$/ = save
$VERBOSE = verbose
@@ -661,6 +662,27 @@ CODE
assert_equal(Encoding::UTF_8, "#{s}x".encoding)
end
+ def test_string_interpolations_across_size_pools_get_embedded
+ omit if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+
+ require 'objspace'
+ base_slot_size = GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE]
+ small_obj_size = (base_slot_size / 2)
+ large_obj_size = base_slot_size * 2
+
+ a = "a" * small_obj_size
+ b = "a" * large_obj_size
+
+ res = "#{a}, #{b}"
+ dump_res = ObjectSpace.dump(res)
+ dump_orig = ObjectSpace.dump(a)
+ new_slot_size = Integer(dump_res.match(/"slot_size":(\d+)/)[1])
+ orig_slot_size = Integer(dump_orig.match(/"slot_size":(\d+)/)[1])
+
+ assert_match(/"embedded":true/, dump_res)
+ assert_operator(new_slot_size, :>, orig_slot_size)
+ end
+
def test_count
a = S("hello world")
assert_equal(5, a.count(S("lo")))
@@ -875,6 +897,18 @@ CODE
}
end
+ def test_undump_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ a = S("Test") << 1 << 2 << 3 << 9 << 13 << 10
+ EnvUtil.under_gc_compact_stress do
+ assert_equal(a, S('"Test\\x01\\x02\\x03\\t\\r\\n"').undump)
+ end
+
+ EnvUtil.under_gc_compact_stress do
+ assert_equal(S("\u{ABCDE 10ABCD}"), S('"\\u{ABCDE 10ABCD}"').undump)
+ end
+ end
+
def test_dup
for frozen in [ false, true ]
a = S("hello")
@@ -887,6 +921,18 @@ CODE
end
end
+ class StringWithIVSet < String
+ def set_iv
+ @foo = 1
+ end
+ end
+
+ def test_ivar_set_after_frozen_dup
+ str = StringWithIVSet.new.freeze
+ str.dup.set_iv
+ assert_raise(FrozenError) { str.set_iv }
+ end
+
def test_each
verbose, $VERBOSE = $VERBOSE, nil
@@ -1062,6 +1108,22 @@ CODE
assert_equal("C", res[2])
end
+ def test_grapheme_clusters_memory_leak
+ assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #todo]", rss: true)
+ begin;
+ str = "hello world".encode(Encoding::UTF_32LE)
+
+ 10_000.times do
+ str.grapheme_clusters
+ end
+ end;
+ end
+
+ def test_byteslice_grapheme_clusters
+ string = "안녕"
+ assert_equal(["안"], string.byteslice(0,4).grapheme_clusters)
+ end
+
def test_each_line
verbose, $VERBOSE = $VERBOSE, nil
@@ -1216,6 +1278,11 @@ CODE
assert_raise(ArgumentError) { S("foo").gsub }
end
+ def test_gsub_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress { assert_equal(S("h<e>ll<o>"), S("hello").gsub(/([aeiou])/, S('<\1>'))) }
+ end
+
def test_gsub_encoding
a = S("hello world")
a.force_encoding Encoding::UTF_8
@@ -1259,6 +1326,15 @@ CODE
assert_nil(a.sub!(S('X'), S('Y')))
end
+ def test_gsub_bang_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ a = S("hello")
+ a.gsub!(/([aeiou])/, S('<\1>'))
+ assert_equal(S("h<e>ll<o>"), a)
+ end
+ end
+
def test_sub_hash
assert_equal('azc', S('abc').sub(/b/, "b" => "z"))
assert_equal('ac', S('abc').sub(/b/, {}))
@@ -1286,6 +1362,9 @@ CODE
assert_not_equal(S("a").hash, S("a\0").hash, bug4104)
bug9172 = '[ruby-core:58658] [Bug #9172]'
assert_not_equal(S("sub-setter").hash, S("discover").hash, bug9172)
+ assert_equal(S("").hash, S("".encode(Encoding::UTF_32BE)).hash)
+ h1, h2 = ["\x80", "\x81"].map {|c| c.b.hash ^ c.hash}
+ assert_not_equal(h1, h2)
end
def test_hex
@@ -1306,54 +1385,54 @@ CODE
end
def test_index
- assert_equal(0, S("hello").index(?h))
- assert_equal(1, S("hello").index(S("ell")))
- assert_equal(2, S("hello").index(/ll./))
+ assert_index(0, S("hello"), ?h)
+ assert_index(1, S("hello"), S("ell"))
+ assert_index(2, S("hello"), /ll./)
- assert_equal(3, S("hello").index(?l, 3))
- assert_equal(3, S("hello").index(S("l"), 3))
- assert_equal(3, S("hello").index(/l./, 3))
+ assert_index(3, S("hello"), ?l, 3)
+ assert_index(3, S("hello"), S("l"), 3)
+ assert_index(3, S("hello"), /l./, 3)
- assert_nil(S("hello").index(?z, 3))
- assert_nil(S("hello").index(S("z"), 3))
- assert_nil(S("hello").index(/z./, 3))
+ assert_index(nil, S("hello"), ?z, 3)
+ assert_index(nil, S("hello"), S("z"), 3)
+ assert_index(nil, S("hello"), /z./, 3)
- assert_nil(S("hello").index(?z))
- assert_nil(S("hello").index(S("z")))
- assert_nil(S("hello").index(/z./))
+ assert_index(nil, S("hello"), ?z)
+ assert_index(nil, S("hello"), S("z"))
+ assert_index(nil, S("hello"), /z./)
- assert_equal(0, S("").index(S("")))
- assert_equal(0, S("").index(//))
- assert_nil(S("").index(S("hello")))
- assert_nil(S("").index(/hello/))
- assert_equal(0, S("hello").index(S("")))
- assert_equal(0, S("hello").index(//))
+ assert_index(0, S(""), S(""))
+ assert_index(0, S(""), //)
+ assert_index(nil, S(""), S("hello"))
+ assert_index(nil, S(""), /hello/)
+ assert_index(0, S("hello"), S(""))
+ assert_index(0, S("hello"), //)
s = S("long") * 1000 << "x"
- assert_nil(s.index(S("y")))
- assert_equal(4 * 1000, s.index(S("x")))
+ assert_index(nil, s, S("y"))
+ assert_index(4 * 1000, s, S("x"))
s << "yx"
- assert_equal(4 * 1000, s.index(S("x")))
- assert_equal(4 * 1000, s.index(S("xyx")))
+ assert_index(4 * 1000, s, S("x"))
+ assert_index(4 * 1000, s, S("xyx"))
o = Object.new
def o.to_str; "bar"; end
- assert_equal(3, S("foobarbarbaz").index(o))
+ assert_index(3, S("foobarbarbaz"), o)
assert_raise(TypeError) { S("foo").index(Object.new) }
- assert_nil(S("foo").index(//, -100))
- assert_nil($~)
+ assert_index(nil, S("foo"), //, -100)
+ assert_index(nil, S("foo"), //, 4)
- assert_equal(2, S("abcdbce").index(/b\Kc/))
+ assert_index(2, S("abcdbce"), /b\Kc/)
- assert_equal(0, S("こんにちは").index(?こ))
- assert_equal(1, S("こんにちは").index(S("んにち")))
- assert_equal(2, S("こんにちは").index(/にち./))
+ assert_index(0, S("こんにちは"), ?こ)
+ assert_index(1, S("こんにちは"), S("んにち"))
+ assert_index(2, S("こんにちは"), /にち./)
- assert_equal(0, S("にんにちは").index(?に, 0))
- assert_equal(2, S("にんにちは").index(?に, 1))
- assert_equal(2, S("にんにちは").index(?に, 2))
- assert_nil(S("にんにちは").index(?に, 3))
+ assert_index(0, S("にんにちは"), ?に, 0)
+ assert_index(2, S("にんにちは"), ?に, 1)
+ assert_index(2, S("にんにちは"), ?に, 2)
+ assert_index(nil, S("にんにちは"), ?に, 3)
end
def test_insert
@@ -1500,57 +1579,57 @@ CODE
end
def test_rindex
- assert_equal(3, S("hello").rindex(?l))
- assert_equal(6, S("ell, hello").rindex(S("ell")))
- assert_equal(7, S("ell, hello").rindex(/ll./))
+ assert_rindex(3, S("hello"), ?l)
+ assert_rindex(6, S("ell, hello"), S("ell"))
+ assert_rindex(7, S("ell, hello"), /ll./)
- assert_equal(3, S("hello,lo").rindex(?l, 3))
- assert_equal(3, S("hello,lo").rindex(S("l"), 3))
- assert_equal(3, S("hello,lo").rindex(/l./, 3))
+ assert_rindex(3, S("hello,lo"), ?l, 3)
+ assert_rindex(3, S("hello,lo"), S("l"), 3)
+ assert_rindex(3, S("hello,lo"), /l./, 3)
- assert_nil(S("hello").rindex(?z, 3))
- assert_nil(S("hello").rindex(S("z"), 3))
- assert_nil(S("hello").rindex(/z./, 3))
+ assert_rindex(nil, S("hello"), ?z, 3)
+ assert_rindex(nil, S("hello"), S("z"), 3)
+ assert_rindex(nil, S("hello"), /z./, 3)
- assert_nil(S("hello").rindex(?z))
- assert_nil(S("hello").rindex(S("z")))
- assert_nil(S("hello").rindex(/z./))
+ assert_rindex(nil, S("hello"), ?z)
+ assert_rindex(nil, S("hello"), S("z"))
+ assert_rindex(nil, S("hello"), /z./)
- assert_equal(5, S("hello").rindex(S("")))
- assert_equal(5, S("hello").rindex(S(""), 5))
- assert_equal(4, S("hello").rindex(S(""), 4))
- assert_equal(0, S("hello").rindex(S(""), 0))
+ assert_rindex(5, S("hello"), S(""))
+ assert_rindex(5, S("hello"), S(""), 5)
+ assert_rindex(4, S("hello"), S(""), 4)
+ assert_rindex(0, S("hello"), S(""), 0)
o = Object.new
def o.to_str; "bar"; end
- assert_equal(6, S("foobarbarbaz").rindex(o))
+ assert_rindex(6, S("foobarbarbaz"), o)
assert_raise(TypeError) { S("foo").rindex(Object.new) }
- assert_nil(S("foo").rindex(//, -100))
- assert_nil($~)
+ assert_rindex(nil, S("foo"), //, -100)
- assert_equal(3, S("foo").rindex(//))
- assert_equal([3, 3], $~.offset(0))
+ m = assert_rindex(3, S("foo"), //)
+ assert_equal([3, 3], m.offset(0))
+ assert_rindex(3, S("foo"), //, 4)
- assert_equal(5, S("abcdbce").rindex(/b\Kc/))
+ assert_rindex(5, S("abcdbce"), /b\Kc/)
- assert_equal(2, S("こんにちは").rindex(?に))
- assert_equal(6, S("にちは、こんにちは").rindex(S("にちは")))
- assert_equal(6, S("にちは、こんにちは").rindex(/にち./))
+ assert_rindex(2, S("こんにちは"), ?に)
+ assert_rindex(6, S("にちは、こんにちは"), S("にちは"))
+ assert_rindex(6, S("にちは、こんにちは"), /にち./)
- assert_equal(6, S("にちは、こんにちは").rindex(S("にちは"), 7))
- assert_equal(6, S("にちは、こんにちは").rindex(S("にちは"), -2))
- assert_equal(6, S("にちは、こんにちは").rindex(S("にちは"), 6))
- assert_equal(6, S("にちは、こんにちは").rindex(S("にちは"), -3))
- assert_equal(0, S("にちは、こんにちは").rindex(S("にちは"), 5))
- assert_equal(0, S("にちは、こんにちは").rindex(S("にちは"), -4))
- assert_equal(0, S("にちは、こんにちは").rindex(S("にちは"), 1))
- assert_equal(0, S("にちは、こんにちは").rindex(S("にちは"), 0))
+ assert_rindex(6, S("にちは、こんにちは"), S("にちは"), 7)
+ assert_rindex(6, S("にちは、こんにちは"), S("にちは"), -2)
+ assert_rindex(6, S("にちは、こんにちは"), S("にちは"), 6)
+ assert_rindex(6, S("にちは、こんにちは"), S("にちは"), -3)
+ assert_rindex(0, S("にちは、こんにちは"), S("にちは"), 5)
+ assert_rindex(0, S("にちは、こんにちは"), S("にちは"), -4)
+ assert_rindex(0, S("にちは、こんにちは"), S("にちは"), 1)
+ assert_rindex(0, S("にちは、こんにちは"), S("にちは"), 0)
- assert_equal(0, S("こんにちは").rindex(S("こんにちは")))
- assert_nil(S("こんにち").rindex(S("こんにちは")))
- assert_nil(S("こ").rindex(S("こんにちは")))
- assert_nil(S("").rindex(S("こんにちは")))
+ assert_rindex(0, S("こんにちは"), S("こんにちは"))
+ assert_rindex(nil, S("こんにち"), S("こんにちは"))
+ assert_rindex(nil, S("こ"), S("こんにちは"))
+ assert_rindex(nil, S(""), S("こんにちは"))
end
def test_rjust
@@ -1589,6 +1668,20 @@ CODE
assert_equal(%w[1 2 3], S("a1 a2 a3").scan(/a\K./))
end
+ def test_scan_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress { assert_equal([["1a"], ["2b"], ["3c"]], S("1a2b3c").scan(/(\d.)/)) }
+ end
+
+ def test_scan_segv
+ bug19159 = '[Bug #19159]'
+ assert_nothing_raised(Exception, bug19159) do
+ ObjectSpace.each_object(MatchData).to_a
+ "".scan(//)
+ ObjectSpace.each_object(MatchData).to_a.inspect
+ end
+ end
+
def test_size
assert_equal(0, S("").size)
assert_equal(4, S("1234").size)
@@ -1640,20 +1733,11 @@ CODE
assert_equal(S("FooBa"), a)
a = S("FooBar")
- if @aref_slicebang_silent
- assert_nil( a.slice!(6) )
- assert_nil( a.slice!(6r) )
- else
- assert_raise(IndexError) { a.slice!(6) }
- assert_raise(IndexError) { a.slice!(6r) }
- end
+ assert_nil( a.slice!(6) )
+ assert_nil( a.slice!(6r) )
assert_equal(S("FooBar"), a)
- if @aref_slicebang_silent
- assert_nil( a.slice!(-7) )
- else
- assert_raise(IndexError) { a.slice!(-7) }
- end
+ assert_nil( a.slice!(-7) )
assert_equal(S("FooBar"), a)
a = S("FooBar")
@@ -1665,17 +1749,9 @@ CODE
assert_equal(S("Foo"), a)
a=S("FooBar")
- if @aref_slicebang_silent
assert_nil(a.slice!(7,2)) # Maybe should be six?
- else
- assert_raise(IndexError) {a.slice!(7,2)} # Maybe should be six?
- end
assert_equal(S("FooBar"), a)
- if @aref_slicebang_silent
assert_nil(a.slice!(-7,10))
- else
- assert_raise(IndexError) {a.slice!(-7,10)}
- end
assert_equal(S("FooBar"), a)
a=S("FooBar")
@@ -1687,17 +1763,9 @@ CODE
assert_equal(S("Foo"), a)
a=S("FooBar")
- if @aref_slicebang_silent
assert_equal(S(""), a.slice!(6..2))
- else
- assert_raise(RangeError) {a.slice!(6..2)}
- end
assert_equal(S("FooBar"), a)
- if @aref_slicebang_silent
assert_nil(a.slice!(-10..-7))
- else
- assert_raise(RangeError) {a.slice!(-10..-7)}
- end
assert_equal(S("FooBar"), a)
a=S("FooBar")
@@ -1709,17 +1777,9 @@ CODE
assert_equal(S("Foo"), a)
a=S("FooBar")
- if @aref_slicebang_silent
- assert_nil(a.slice!(/xyzzy/))
- else
- assert_raise(IndexError) {a.slice!(/xyzzy/)}
- end
+ assert_nil(a.slice!(/xyzzy/))
assert_equal(S("FooBar"), a)
- if @aref_slicebang_silent
- assert_nil(a.slice!(/plugh/))
- else
- assert_raise(IndexError) {a.slice!(/plugh/)}
- end
+ assert_nil(a.slice!(/plugh/))
assert_equal(S("FooBar"), a)
a=S("FooBar")
@@ -1896,10 +1956,15 @@ CODE
assert_send([S("hello"), :start_with?, S("hel")])
assert_not_send([S("hello"), :start_with?, S("el")])
assert_send([S("hello"), :start_with?, S("el"), S("he")])
+ assert_send([S("\xFF\xFE"), :start_with?, S("\xFF")])
+ assert_send([S("hello\xBE"), :start_with?, S("hello")])
+ assert_not_send([S("\u{c4}"), :start_with?, S("\xC3")])
bug5536 = '[ruby-core:40623]'
assert_raise(TypeError, bug5536) {S("str").start_with? :not_convertible_to_string}
+ end
+ def test_start_with_regexp
assert_equal(true, S("hello").start_with?(/hel/))
assert_equal("hel", $&)
assert_equal(false, S("hello").start_with?(/el/))
@@ -2002,6 +2067,16 @@ CODE
}
end
+ def test_sub_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress do
+ m = /&(?<foo>.*?);/.match(S("aaa &amp; yyy"))
+ assert_equal("amp", m["foo"])
+
+ assert_equal("aaa [amp] yyy", S("aaa &amp; yyy").sub(/&(?<foo>.*?);/, S('[\k<foo>]')))
+ end
+ end
+
def test_sub!
a = S("hello")
b = a.dup
@@ -2259,6 +2334,8 @@ CODE
assert_not_predicate(str, :ascii_only?)
assert_not_predicate(star, :ascii_only?)
assert_not_predicate(result, :ascii_only?, bug13950)
+
+ assert_equal(S("XYC"), S("ABC").tr("A-AB", "XY"))
end
def test_tr!
@@ -2283,6 +2360,8 @@ CODE
a = S("abc".force_encoding(Encoding::US_ASCII))
assert_nil(a.tr!(S("z"), S("\u0101")), '[ruby-core:22326]')
assert_equal(Encoding::US_ASCII, a.encoding, '[ruby-core:22326]')
+
+ assert_equal(S("XYC"), S("ABC").tr!("A-AB", "XY"))
end
def test_tr_s
@@ -2290,6 +2369,8 @@ CODE
assert_equal(S("h*o"), S("hello").tr_s(S("el"), S("*")))
assert_equal("a".hash, S("\u0101\u0101").tr_s("\u0101", "a").hash)
assert_equal(true, S("\u3041\u3041").tr("\u3041", "a").ascii_only?)
+
+ assert_equal(S("XYC"), S("ABC").tr_s("A-AB", "XY"))
end
def test_tr_s!
@@ -2302,6 +2383,8 @@ CODE
a = S("hello")
assert_equal(S("h*o"), a.tr_s!(S("el"), S("*")))
assert_equal(S("h*o"), a)
+
+ assert_equal(S("XYC"), S("ABC").tr_s!("A-AB", "XY"))
end
def test_unpack
@@ -2805,6 +2888,11 @@ CODE
assert_equal("\u3042", s5)
assert_raise(Encoding::CompatibilityError) { S("\u3042".encode("ISO-2022-JP")).rstrip! }
+ assert_raise(Encoding::CompatibilityError) { S("abc \x80 ".force_encoding('UTF-8')).rstrip! }
+ assert_raise(Encoding::CompatibilityError) { S("abc\x80 ".force_encoding('UTF-8')).rstrip! }
+ assert_raise(Encoding::CompatibilityError) { S("abc \x80".force_encoding('UTF-8')).rstrip! }
+ assert_raise(Encoding::CompatibilityError) { S("\x80".force_encoding('UTF-8')).rstrip! }
+ assert_raise(Encoding::CompatibilityError) { S(" \x80 ".force_encoding('UTF-8')).rstrip! }
end
def test_lstrip
@@ -2836,11 +2924,13 @@ CODE
end
- def test_delete_prefix
+ def test_delete_prefix_type_error
assert_raise(TypeError) { S('hello').delete_prefix(nil) }
assert_raise(TypeError) { S('hello').delete_prefix(1) }
assert_raise(TypeError) { S('hello').delete_prefix(/hel/) }
+ end
+ def test_delete_prefix
s = S("hello")
assert_equal("lo", s.delete_prefix('hel'))
assert_equal("hello", s)
@@ -2860,8 +2950,9 @@ CODE
s = S("hello")
assert_equal("hello", s.delete_prefix("\u{3053 3093}"))
assert_equal("hello", s)
+ end
- # skip if argument is a broken string
+ def test_delete_prefix_broken_encoding
s = S("\xe3\x81\x82")
assert_equal("\xe3\x81\x82", s.delete_prefix("\xe3"))
assert_equal("\xe3\x81\x82", s)
@@ -2870,23 +2961,31 @@ CODE
assert_equal("\x95\x5c".force_encoding("Shift_JIS"), s.delete_prefix("\x95"))
assert_equal("\x95\x5c".force_encoding("Shift_JIS"), s)
- # clear coderange
+ assert_equal("\xFE", S("\xFF\xFE").delete_prefix("\xFF"))
+ assert_equal("\xBE", S("hello\xBE").delete_prefix("hello"))
+ assert_equal("\xBE", S("\xFFhello\xBE").delete_prefix("\xFFhello"))
+ end
+
+ def test_delete_prefix_clear_coderange
s = S("\u{3053 3093}hello")
assert_not_predicate(s, :ascii_only?)
assert_predicate(s.delete_prefix("\u{3053 3093}"), :ascii_only?)
+ end
- # argument should be converted to String
+ def test_delete_prefix_argument_conversion
klass = Class.new { def to_str; 'a'; end }
s = S("abba")
assert_equal("bba", s.delete_prefix(klass.new))
assert_equal("abba", s)
end
- def test_delete_prefix_bang
+ def test_delete_prefix_bang_type_error
assert_raise(TypeError) { S('hello').delete_prefix!(nil) }
assert_raise(TypeError) { S('hello').delete_prefix!(1) }
assert_raise(TypeError) { S('hello').delete_prefix!(/hel/) }
+ end
+ def test_delete_prefix_bang
s = S("hello")
assert_equal("lo", s.delete_prefix!('hel'))
assert_equal("lo", s)
@@ -2906,23 +3005,32 @@ CODE
s = S("hello")
assert_equal(nil, s.delete_prefix!("\u{3053 3093}"))
assert_equal("hello", s)
+ end
- # skip if argument is a broken string
+ def test_delete_prefix_bang_broken_encoding
s = S("\xe3\x81\x82")
assert_equal(nil, s.delete_prefix!("\xe3"))
assert_equal("\xe3\x81\x82", s)
- # clear coderange
+ s = S("\xFF\xFE")
+ assert_equal("\xFE", s.delete_prefix!("\xFF"))
+ assert_equal("\xFE", s)
+ end
+
+ def test_delete_prefix_bang_clear_coderange
s = S("\u{3053 3093}hello")
assert_not_predicate(s, :ascii_only?)
assert_predicate(s.delete_prefix!("\u{3053 3093}"), :ascii_only?)
+ end
- # argument should be converted to String
+ def test_delete_prefix_bang_argument_conversion
klass = Class.new { def to_str; 'a'; end }
s = S("abba")
assert_equal("bba", s.delete_prefix!(klass.new))
assert_equal("bba", s)
+ end
+ def test_delete_prefix_bang_frozen_error
s = S("ax").freeze
assert_raise_with_message(FrozenError, /frozen/) {s.delete_prefix!("a")}
@@ -2935,11 +3043,13 @@ CODE
assert_raise_with_message(FrozenError, /frozen/) {s.delete_prefix!(o)}
end
- def test_delete_suffix
+ def test_delete_suffix_type_error
assert_raise(TypeError) { S('hello').delete_suffix(nil) }
assert_raise(TypeError) { S('hello').delete_suffix(1) }
assert_raise(TypeError) { S('hello').delete_suffix(/hel/) }
+ end
+ def test_delete_suffix
s = S("hello")
assert_equal("hel", s.delete_suffix('lo'))
assert_equal("hello", s)
@@ -2959,23 +3069,28 @@ CODE
s = S("hello")
assert_equal("hello", s.delete_suffix("\u{3061 306f}"))
assert_equal("hello", s)
+ end
- # skip if argument is a broken string
+ def test_delete_suffix_broken_encoding
s = S("\xe3\x81\x82")
assert_equal("\xe3\x81\x82", s.delete_suffix("\x82"))
assert_equal("\xe3\x81\x82", s)
+ end
- # clear coderange
+ def test_delete_suffix_clear_coderange
s = S("hello\u{3053 3093}")
assert_not_predicate(s, :ascii_only?)
assert_predicate(s.delete_suffix("\u{3053 3093}"), :ascii_only?)
+ end
- # argument should be converted to String
+ def test_delete_suffix_argument_conversion
klass = Class.new { def to_str; 'a'; end }
s = S("abba")
assert_equal("abb", s.delete_suffix(klass.new))
assert_equal("abba", s)
+ end
+ def test_delete_suffix_newline
# chomp removes any of "\n", "\r\n", "\r" when "\n" is specified,
# but delete_suffix does not
s = "foo\n"
@@ -2986,11 +3101,13 @@ CODE
assert_equal("foo\r", s.delete_suffix("\n"))
end
- def test_delete_suffix_bang
+ def test_delete_suffix_bang_type_error
assert_raise(TypeError) { S('hello').delete_suffix!(nil) }
assert_raise(TypeError) { S('hello').delete_suffix!(1) }
assert_raise(TypeError) { S('hello').delete_suffix!(/hel/) }
+ end
+ def test_delete_suffix_bang_frozen_error
s = S("hello").freeze
assert_raise_with_message(FrozenError, /frozen/) {s.delete_suffix!('lo')}
@@ -3001,7 +3118,9 @@ CODE
"x"
end
assert_raise_with_message(FrozenError, /frozen/) {s.delete_suffix!(o)}
+ end
+ def test_delete_suffix_bang
s = S("hello")
assert_equal("hel", s.delete_suffix!('lo'))
assert_equal("hel", s)
@@ -3021,8 +3140,9 @@ CODE
s = S("hello")
assert_equal(nil, s.delete_suffix!("\u{3061 306f}"))
assert_equal("hello", s)
+ end
- # skip if argument is a broken string
+ def test_delete_suffix_bang_broken_encoding
s = S("\xe3\x81\x82")
assert_equal(nil, s.delete_suffix!("\x82"))
assert_equal("\xe3\x81\x82", s)
@@ -3030,18 +3150,22 @@ CODE
s = S("\x95\x5c").force_encoding("Shift_JIS")
assert_equal(nil, s.delete_suffix!("\x5c"))
assert_equal("\x95\x5c".force_encoding("Shift_JIS"), s)
+ end
- # clear coderange
+ def test_delete_suffix_bang_clear_coderange
s = S("hello\u{3053 3093}")
assert_not_predicate(s, :ascii_only?)
assert_predicate(s.delete_suffix!("\u{3053 3093}"), :ascii_only?)
+ end
- # argument should be converted to String
+ def test_delete_suffix_bang_argument_conversion
klass = Class.new { def to_str; 'a'; end }
s = S("abba")
assert_equal("abb", s.delete_suffix!(klass.new))
assert_equal("abb", s)
+ end
+ def test_delete_suffix_bang_newline
# chomp removes any of "\n", "\r\n", "\r" when "\n" is specified,
# but delete_suffix does not
s = "foo\n"
@@ -3232,7 +3356,11 @@ CODE
assert_same(str, +str)
assert_not_same(str, -str)
+ require 'objspace'
+
str = "bar".freeze
+ assert_includes ObjectSpace.dump(str), '"fstring":true'
+
assert_predicate(str, :frozen?)
assert_not_predicate(+str, :frozen?)
assert_predicate(-str, :frozen?)
@@ -3240,8 +3368,8 @@ CODE
assert_not_same(str, +str)
assert_same(str, -str)
- bar = %w(b a r).join('')
- assert_same(str, -bar, "uminus deduplicates [Feature #13077]")
+ bar = -%w(b a r).join('')
+ assert_same(str, bar, "uminus deduplicates [Feature #13077] str: #{ObjectSpace.dump(str)} bar: #{ObjectSpace.dump(bar)}")
end
def test_uminus_frozen
@@ -3299,156 +3427,289 @@ CODE
end
def test_byteindex
- assert_equal(0, S("hello").byteindex(?h))
- assert_equal(1, S("hello").byteindex(S("ell")))
- assert_equal(2, S("hello").byteindex(/ll./))
+ assert_byteindex(0, S("hello"), ?h)
+ assert_byteindex(1, S("hello"), S("ell"))
+ assert_byteindex(2, S("hello"), /ll./)
- assert_equal(3, S("hello").byteindex(?l, 3))
- assert_equal(3, S("hello").byteindex(S("l"), 3))
- assert_equal(3, S("hello").byteindex(/l./, 3))
+ assert_byteindex(3, S("hello"), ?l, 3)
+ assert_byteindex(3, S("hello"), S("l"), 3)
+ assert_byteindex(3, S("hello"), /l./, 3)
- assert_nil(S("hello").byteindex(?z, 3))
- assert_nil(S("hello").byteindex(S("z"), 3))
- assert_nil(S("hello").byteindex(/z./, 3))
+ assert_byteindex(nil, S("hello"), ?z, 3)
+ assert_byteindex(nil, S("hello"), S("z"), 3)
+ assert_byteindex(nil, S("hello"), /z./, 3)
- assert_nil(S("hello").byteindex(?z))
- assert_nil(S("hello").byteindex(S("z")))
- assert_nil(S("hello").byteindex(/z./))
+ assert_byteindex(nil, S("hello"), ?z)
+ assert_byteindex(nil, S("hello"), S("z"))
+ assert_byteindex(nil, S("hello"), /z./)
- assert_equal(0, S("").byteindex(S("")))
- assert_equal(0, S("").byteindex(//))
- assert_nil(S("").byteindex(S("hello")))
- assert_nil(S("").byteindex(/hello/))
- assert_equal(0, S("hello").byteindex(S("")))
- assert_equal(0, S("hello").byteindex(//))
+ assert_byteindex(0, S(""), S(""))
+ assert_byteindex(0, S(""), //)
+ assert_byteindex(nil, S(""), S("hello"))
+ assert_byteindex(nil, S(""), /hello/)
+ assert_byteindex(0, S("hello"), S(""))
+ assert_byteindex(0, S("hello"), //)
s = S("long") * 1000 << "x"
- assert_nil(s.byteindex(S("y")))
- assert_equal(4 * 1000, s.byteindex(S("x")))
+ assert_byteindex(nil, s, S("y"))
+ assert_byteindex(4 * 1000, s, S("x"))
s << "yx"
- assert_equal(4 * 1000, s.byteindex(S("x")))
- assert_equal(4 * 1000, s.byteindex(S("xyx")))
+ assert_byteindex(4 * 1000, s, S("x"))
+ assert_byteindex(4 * 1000, s, S("xyx"))
o = Object.new
def o.to_str; "bar"; end
- assert_equal(3, S("foobarbarbaz").byteindex(o))
+ assert_byteindex(3, S("foobarbarbaz"), o)
assert_raise(TypeError) { S("foo").byteindex(Object.new) }
- assert_nil(S("foo").byteindex(//, -100))
- assert_nil($~)
+ assert_byteindex(nil, S("foo"), //, -100)
+ assert_byteindex(nil, S("foo"), //, -4)
- assert_equal(2, S("abcdbce").byteindex(/b\Kc/))
+ assert_byteindex(2, S("abcdbce"), /b\Kc/)
- assert_equal(0, S("こんにちは").byteindex(?こ))
- assert_equal(3, S("こんにちは").byteindex(S("んにち")))
- assert_equal(6, S("こんにちは").byteindex(/にち./))
+ assert_byteindex(0, S("こんにちは"), ?こ)
+ assert_byteindex(3, S("こんにちは"), S("んにち"))
+ assert_byteindex(6, S("こんにちは"), /にち./)
- assert_equal(0, S("にんにちは").byteindex(?に, 0))
+ assert_byteindex(0, S("にんにちは"), ?に, 0)
assert_raise(IndexError) { S("にんにちは").byteindex(?に, 1) }
assert_raise(IndexError) { S("にんにちは").byteindex(?に, 5) }
- assert_equal(6, S("にんにちは").byteindex(?に, 6))
- assert_equal(6, S("にんにちは").byteindex(S("に"), 6))
- assert_equal(6, S("にんにちは").byteindex(/に./, 6))
+ assert_byteindex(6, S("にんにちは"), ?に, 6)
+ assert_byteindex(6, S("にんにちは"), S("に"), 6)
+ assert_byteindex(6, S("にんにちは"), /に./, 6)
assert_raise(IndexError) { S("にんにちは").byteindex(?に, 7) }
+
+ s = S("foobarbarbaz")
+ assert !1000.times.any? {s.byteindex("", 100_000_000)}
end
def test_byterindex
- assert_equal(3, S("hello").byterindex(?l))
- assert_equal(6, S("ell, hello").byterindex(S("ell")))
- assert_equal(7, S("ell, hello").byterindex(/ll./))
+ assert_byterindex(3, S("hello"), ?l)
+ assert_byterindex(6, S("ell, hello"), S("ell"))
+ assert_byterindex(7, S("ell, hello"), /ll./)
- assert_equal(3, S("hello,lo").byterindex(?l, 3))
- assert_equal(3, S("hello,lo").byterindex(S("l"), 3))
- assert_equal(3, S("hello,lo").byterindex(/l./, 3))
+ assert_byterindex(3, S("hello,lo"), ?l, 3)
+ assert_byterindex(3, S("hello,lo"), S("l"), 3)
+ assert_byterindex(3, S("hello,lo"), /l./, 3)
- assert_nil(S("hello").byterindex(?z, 3))
- assert_nil(S("hello").byterindex(S("z"), 3))
- assert_nil(S("hello").byterindex(/z./, 3))
+ assert_byterindex(nil, S("hello"), ?z, 3)
+ assert_byterindex(nil, S("hello"), S("z"), 3)
+ assert_byterindex(nil, S("hello"), /z./, 3)
- assert_nil(S("hello").byterindex(?z))
- assert_nil(S("hello").byterindex(S("z")))
- assert_nil(S("hello").byterindex(/z./))
+ assert_byterindex(nil, S("hello"), ?z)
+ assert_byterindex(nil, S("hello"), S("z"))
+ assert_byterindex(nil, S("hello"), /z./)
- assert_equal(5, S("hello").byterindex(S("")))
- assert_equal(5, S("hello").byterindex(S(""), 5))
- assert_equal(4, S("hello").byterindex(S(""), 4))
- assert_equal(0, S("hello").byterindex(S(""), 0))
+ assert_byterindex(5, S("hello"), S(""))
+ assert_byterindex(5, S("hello"), S(""), 5)
+ assert_byterindex(4, S("hello"), S(""), 4)
+ assert_byterindex(0, S("hello"), S(""), 0)
o = Object.new
def o.to_str; "bar"; end
- assert_equal(6, S("foobarbarbaz").byterindex(o))
+ assert_byterindex(6, S("foobarbarbaz"), o)
assert_raise(TypeError) { S("foo").byterindex(Object.new) }
- assert_nil(S("foo").byterindex(//, -100))
- assert_nil($~)
+ assert_byterindex(nil, S("foo"), //, -100)
- assert_equal(3, S("foo").byterindex(//))
- assert_equal([3, 3], $~.offset(0))
+ m = assert_byterindex(3, S("foo"), //)
+ assert_equal([3, 3], m.offset(0))
+ assert_byterindex(3, S("foo"), //, 4)
- assert_equal(5, S("abcdbce").byterindex(/b\Kc/))
+ assert_byterindex(5, S("abcdbce"), /b\Kc/)
- assert_equal(6, S("こんにちは").byterindex(?に))
- assert_equal(18, S("にちは、こんにちは").byterindex(S("にちは")))
- assert_equal(18, S("にちは、こんにちは").byterindex(/にち./))
+ assert_byterindex(6, S("こんにちは"), ?に)
+ assert_byterindex(18, S("にちは、こんにちは"), S("にちは"))
+ assert_byterindex(18, S("にちは、こんにちは"), /にち./)
assert_raise(IndexError) { S("にちは、こんにちは").byterindex(S("にちは"), 19) }
assert_raise(IndexError) { S("にちは、こんにちは").byterindex(S("にちは"), -2) }
- assert_equal(18, S("にちは、こんにちは").byterindex(S("にちは"), 18))
- assert_equal(18, S("にちは、こんにちは").byterindex(S("にちは"), -3))
+ assert_byterindex(18, S("にちは、こんにちは"), S("にちは"), 18)
+ assert_byterindex(18, S("にちは、こんにちは"), S("にちは"), -3)
assert_raise(IndexError) { S("にちは、こんにちは").byterindex(S("にちは"), 17) }
assert_raise(IndexError) { S("にちは、こんにちは").byterindex(S("にちは"), -4) }
assert_raise(IndexError) { S("にちは、こんにちは").byterindex(S("にちは"), 1) }
- assert_equal(0, S("にちは、こんにちは").byterindex(S("にちは"), 0))
+ assert_byterindex(0, S("にちは、こんにちは"), S("にちは"), 0)
- assert_equal(0, S("こんにちは").byterindex(S("こんにちは")))
- assert_nil(S("こんにち").byterindex(S("こんにちは")))
- assert_nil(S("こ").byterindex(S("こんにちは")))
- assert_nil(S("").byterindex(S("こんにちは")))
+ assert_byterindex(0, S("こんにちは"), S("こんにちは"))
+ assert_byterindex(nil, S("こんにち"), S("こんにちは"))
+ assert_byterindex(nil, S("こ"), S("こんにちは"))
+ assert_byterindex(nil, S(""), S("こんにちは"))
end
def test_bytesplice
- assert_bytesplice_raise(IndexError, S("hello"), -6, 0, "xxx")
- assert_bytesplice_result("xxxhello", S("hello"), -5, 0, "xxx")
- assert_bytesplice_result("xxxhello", S("hello"), 0, 0, "xxx")
- assert_bytesplice_result("xxxello", S("hello"), 0, 1, "xxx")
- assert_bytesplice_result("xxx", S("hello"), 0, 5, "xxx")
- assert_bytesplice_result("xxx", S("hello"), 0, 6, "xxx")
-
- assert_bytesplice_raise(RangeError, S("hello"), -6...-6, "xxx")
- assert_bytesplice_result("xxxhello", S("hello"), -5...-5, "xxx")
- assert_bytesplice_result("xxxhello", S("hello"), 0...0, "xxx")
- assert_bytesplice_result("xxxello", S("hello"), 0..0, "xxx")
- assert_bytesplice_result("xxxello", S("hello"), 0...1, "xxx")
- assert_bytesplice_result("xxxllo", S("hello"), 0..1, "xxx")
- assert_bytesplice_result("xxx", S("hello"), 0..-1, "xxx")
- assert_bytesplice_result("xxx", S("hello"), 0...5, "xxx")
- assert_bytesplice_result("xxx", S("hello"), 0...6, "xxx")
-
- assert_bytesplice_raise(TypeError, S("hello"), 0, "xxx")
-
- assert_bytesplice_raise(IndexError, S("こんにちは"), -16, 0, "xxx")
- assert_bytesplice_result("xxxこんにちは", S("こんにちは"), -15, 0, "xxx")
- assert_bytesplice_result("xxxこんにちは", S("こんにちは"), 0, 0, "xxx")
- assert_bytesplice_raise(IndexError, S("こんにちは"), 1, 0, "xxx")
- assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 1, "xxx")
- assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 2, "xxx")
- assert_bytesplice_result("xxxんにちは", S("こんにちは"), 0, 3, "xxx")
- assert_bytesplice_result("こんにちはxxx", S("こんにちは"), 15, 0, "xxx")
+ assert_bytesplice_raise(IndexError, S("hello"), -6, 0, "bye")
+ assert_bytesplice_result("byehello", S("hello"), -5, 0, "bye")
+ assert_bytesplice_result("byehello", S("hello"), 0, 0, "bye")
+ assert_bytesplice_result("byeello", S("hello"), 0, 1, "bye")
+ assert_bytesplice_result("bye", S("hello"), 0, 5, "bye")
+ assert_bytesplice_result("bye", S("hello"), 0, 6, "bye")
+
+ assert_bytesplice_raise(IndexError, S("hello"), -5, 0, "bye", -4, 0)
+ assert_bytesplice_result("byehello", S("hello"), 0, 0, "bye", 0, 3)
+ assert_bytesplice_result("yehello", S("hello"), 0, 0, "bye", 1, 3)
+ assert_bytesplice_result("yehello", S("hello"), 0, 0, "bye", 1, 2)
+ assert_bytesplice_result("ehello", S("hello"), 0, 0, "bye", 2, 1)
+ assert_bytesplice_result("hello", S("hello"), 0, 0, "bye", 3, 0)
+ assert_bytesplice_result("hello", s = S("hello"), 0, 5, s, 0, 5)
+ assert_bytesplice_result("elloo", s = S("hello"), 0, 4, s, 1, 4)
+ assert_bytesplice_result("llolo", s = S("hello"), 0, 3, s, 2, 3)
+ assert_bytesplice_result("lollo", s = S("hello"), 0, 2, s, 3, 2)
+ assert_bytesplice_result("oello", s = S("hello"), 0, 1, s, 4, 1)
+ assert_bytesplice_result("hhell", s = S("hello"), 1, 4, s, 0, 4)
+ assert_bytesplice_result("hehel", s = S("hello"), 2, 3, s, 0, 3)
+ assert_bytesplice_result("helhe", s = S("hello"), 3, 2, s, 0, 2)
+ assert_bytesplice_result("hellh", s = S("hello"), 4, 1, s, 0, 1)
+
+ assert_bytesplice_raise(RangeError, S("hello"), -6...-6, "bye")
+ assert_bytesplice_result("byehello", S("hello"), -5...-5, "bye")
+ assert_bytesplice_result("byehello", S("hello"), 0...0, "bye")
+ assert_bytesplice_result("byeello", S("hello"), 0..0, "bye")
+ assert_bytesplice_result("byeello", S("hello"), 0...1, "bye")
+ assert_bytesplice_result("byello", S("hello"), 0..1, "bye")
+ assert_bytesplice_result("bye", S("hello"), 0..-1, "bye")
+ assert_bytesplice_result("bye", S("hello"), 0...5, "bye")
+ assert_bytesplice_result("bye", S("hello"), 0...6, "bye")
+ assert_bytesplice_result("llolo", s = S("hello"), 0..2, s, 2..4)
+
+ assert_bytesplice_raise(RangeError, S("hello"), -5...-5, "bye", -6...-6)
+ assert_bytesplice_result("byehello", S("hello"), -5...-5, "bye", 0..-1)
+ assert_bytesplice_result("byehello", S("hello"), 0...0, "bye", 0..-1)
+ assert_bytesplice_result("bhello", S("hello"), 0...0, "bye", 0..0)
+ assert_bytesplice_result("byhello", S("hello"), 0...0, "bye", 0..1)
+ assert_bytesplice_result("byehello", S("hello"), 0...0, "bye", 0..2)
+ assert_bytesplice_result("yehello", S("hello"), 0...0, "bye", 1..2)
+
+ assert_bytesplice_raise(TypeError, S("hello"), 0, "bye")
+
+ assert_bytesplice_raise(IndexError, S("こんにちは"), -16, 0, "bye")
+ assert_bytesplice_result("byeこんにちは", S("こんにちは"), -15, 0, "bye")
+ assert_bytesplice_result("byeこんにちは", S("こんにちは"), 0, 0, "bye")
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 1, 0, "bye")
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 1, "bye")
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 2, "bye")
+ assert_bytesplice_result("byeんにちは", S("こんにちは"), 0, 3, "bye")
+ assert_bytesplice_result("こんにちはbye", S("こんにちは"), 15, 0, "bye")
+
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 0, "さようなら", -16, 0)
+ assert_bytesplice_result("こんにちはさようなら", S("こんにちは"), 15, 0, "さようなら", 0, 15)
+ assert_bytesplice_result("さようなら", S("こんにちは"), 0, 15, "さようなら", 0, 15)
+ assert_bytesplice_result("さんにちは", S("こんにちは"), 0, 3, "さようなら", 0, 3)
+ assert_bytesplice_result("さようちは", S("こんにちは"), 0, 9, "さようなら", 0, 9)
+ assert_bytesplice_result("ようなちは", S("こんにちは"), 0, 9, "さようなら", 3, 9)
+ assert_bytesplice_result("ようちは", S("こんにちは"), 0, 9, "さようなら", 3, 6)
+ assert_bytesplice_result("ようならちは", S("こんにちは"), 0, 9, "さようなら", 3, 12)
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", -16, 0)
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", 1, 0)
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", 2, 0)
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", 0, 1)
+ assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", 0, 2)
+ assert_bytesplice_result("にちはちは", s = S("こんにちは"), 0, 9, s, 6, 9)
assert_bytesplice_result("", S(""), 0, 0, "")
assert_bytesplice_result("xxx", S(""), 0, 0, "xxx")
+
+ assert_bytesplice_raise(ArgumentError, S("hello"), 0, 5, "bye", 0)
+ assert_bytesplice_raise(ArgumentError, S("hello"), 0, 5, "bye", 0..-1)
+ assert_bytesplice_raise(ArgumentError, S("hello"), 0..-1, "bye", 0, 3)
+ end
+
+ def test_chilled_string
+ chilled_string = eval('"chilled"')
+
+ # Chilled strings pretend to be frozen
+ assert_predicate chilled_string, :frozen?
+
+ assert_not_predicate chilled_string.dup, :frozen?
+ assert_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
+ assert_predicate(-chilled_string, :frozen?)
+ assert_not_same chilled_string, -chilled_string
+ end
+
+ def test_chilled_string_setivar
+ deprecated = Warning[:deprecated]
+ Warning[:deprecated] = false
+
+ String.class_eval <<~RUBY, __FILE__, __LINE__ + 1
+ def setivar!
+ @ivar = 42
+ @ivar
+ end
+ RUBY
+ chilled_string = eval('"chilled"')
+ begin
+ assert_equal 42, chilled_string.setivar!
+ ensure
+ String.undef_method(:setivar!)
+ end
+ ensure
+ Warning[:deprecated] = deprecated
+ end
+
+ def test_chilled_string_substring
+ deprecated = Warning[:deprecated]
+ Warning[:deprecated] = false
+ chilled_string = eval('"a chilled string."')
+ substring = chilled_string[0..-1]
+ assert_equal("a chilled string.", substring)
+ chilled_string[0..-1] = "This string is defrosted."
+ assert_equal("a chilled string.", substring)
+ ensure
+ Warning[:deprecated] = deprecated
end
private
def assert_bytesplice_result(expected, s, *args)
- assert_equal(args.last, s.send(:bytesplice, *args))
+ assert_equal(expected, s.send(:bytesplice, *args))
assert_equal(expected, s)
end
def assert_bytesplice_raise(e, s, *args)
assert_raise(e) { s.send(:bytesplice, *args) }
end
+
+ def assert_index_like(method, expected, string, match, *rest)
+ message = "#{method} with string does not affect $~"
+ /.*/ =~ message
+ md_before = $~
+ assert_equal(expected, string.__send__(method, match, *rest))
+ md_after = $~
+ case match
+ when Regexp
+ if expected
+ assert_not_nil(md_after)
+ assert_not_same(md_before, md_after)
+ else
+ assert_nil(md_after)
+ end
+ else
+ assert_same(md_before, md_after)
+ end
+ md_after
+ end
+
+ def assert_index(expected, string, match, *rest)
+ assert_index_like(:index, expected, string, match, *rest)
+ end
+
+ def assert_rindex(expected, string, match, *rest)
+ assert_index_like(:rindex, expected, string, match, *rest)
+ end
+
+ def assert_byteindex(expected, string, match, *rest)
+ assert_index_like(:byteindex, expected, string, match, *rest)
+ end
+
+ def assert_byterindex(expected, string, match, *rest)
+ assert_index_like(:byterindex, expected, string, match, *rest)
+ end
end
class TestString2 < TestString
diff --git a/test/ruby/test_string_memory.rb b/test/ruby/test_string_memory.rb
new file mode 100644
index 0000000000..3b4694f36f
--- /dev/null
+++ b/test/ruby/test_string_memory.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: false
+require 'test/unit'
+require 'objspace'
+
+class TestStringMemory < Test::Unit::TestCase
+ def capture_allocations(klass)
+ allocations = []
+
+ GC.start
+ GC.disable
+ generation = GC.count
+
+ ObjectSpace.trace_object_allocations do
+ yield
+
+ ObjectSpace.each_object(klass) do |instance|
+ allocations << instance if ObjectSpace.allocation_generation(instance) == generation
+ end
+ end
+
+ return allocations
+ ensure
+ GC.enable
+ end
+
+ def test_byteslice_prefix
+ string = ("a" * 100_000).freeze
+
+ allocations = capture_allocations(String) do
+ string.byteslice(0, 50_000)
+ end
+
+ assert_equal 1, allocations.size
+ end
+
+ def test_byteslice_postfix
+ string = ("a" * 100_000).freeze
+
+ allocations = capture_allocations(String) do
+ string.byteslice(50_000, 100_000)
+ end
+
+ assert_equal 1, allocations.size
+ end
+
+ def test_byteslice_postfix_twice
+ string = ("a" * 100_000).freeze
+
+ allocations = capture_allocations(String) do
+ string.byteslice(50_000, 100_000).byteslice(25_000, 50_000)
+ end
+
+ assert_equal 2, allocations.size
+ end
+end
diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb
index 78a81c5200..3d727adf04 100644
--- a/test/ruby/test_struct.rb
+++ b/test/ruby/test_struct.rb
@@ -41,6 +41,14 @@ module TestStruct
end
end
+ def test_larger_than_largest_pool
+ count = (GC::INTERNAL_CONSTANTS[:RVARGC_MAX_ALLOCATE_SIZE] / RbConfig::SIZEOF["void*"]) + 1
+ list = Array(0..count)
+ klass = @Struct.new(*list.map { |i| :"a_#{i}"})
+ struct = klass.new(*list)
+ assert_equal 0, struct.a_0
+ end
+
def test_small_structs
names = [:a, :b, :c, :d]
1.upto(4) {|n|
@@ -526,6 +534,20 @@ module TestStruct
assert_equal [[:req, :_]], klass.instance_method(:c=).parameters
end
+ def test_named_structs_are_not_rooted
+ # [Bug #20311]
+ assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true)
+ code = proc do
+ Struct.new("A")
+ Struct.send(:remove_const, :A)
+ end
+
+ 1_000.times(&code)
+ PREP
+ 50_000.times(&code)
+ CODE
+ end
+
class TopStruct < Test::Unit::TestCase
include TestStruct
diff --git a/test/ruby/test_super.rb b/test/ruby/test_super.rb
index 6a575b88c5..ce78e66c52 100644
--- a/test/ruby/test_super.rb
+++ b/test/ruby/test_super.rb
@@ -558,6 +558,18 @@ class TestSuper < Test::Unit::TestCase
end
end
+ def test_zsuper_kw_splat_not_mutable
+ extend(Module.new{def a(**k) k[:a] = 1 end})
+ extend(Module.new do
+ def a(**k)
+ before = k.dup
+ super
+ [before, k]
+ end
+ end)
+ assert_equal(*a)
+ end
+
def test_from_eval
bug10263 = '[ruby-core:65122] [Bug #10263a]'
a = Class.new do
diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb
index 1d2a18d734..4170f62899 100644
--- a/test/ruby/test_symbol.rb
+++ b/test/ruby/test_symbol.rb
@@ -118,6 +118,14 @@ class TestSymbol < Test::Unit::TestCase
end
end
+ def test_inspect_under_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ omit "very flaky on many platforms, more so with YJIT enabled" if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
+ EnvUtil.under_gc_compact_stress do
+ assert_inspect_evaled(':testing')
+ end
+ end
+
def test_name
assert_equal("foo", :foo.name)
assert_same(:foo.name, :foo.name)
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index b0ad012131..44162f06cb 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -13,8 +13,7 @@ class TestSyntax < Test::Unit::TestCase
def assert_syntax_files(test)
srcdir = File.expand_path("../../..", __FILE__)
srcdir = File.join(srcdir, test)
- assert_separately(%W[--disable-gem - #{srcdir}],
- __FILE__, __LINE__, <<-'eom', timeout: Float::INFINITY)
+ assert_separately(%W[- #{srcdir}], __FILE__, __LINE__, <<-'eom', timeout: Float::INFINITY)
dir = ARGV.shift
for script in Dir["#{dir}/**/*.rb"].sort
assert_valid_syntax(IO::read(script), script)
@@ -77,98 +76,123 @@ class TestSyntax < Test::Unit::TestCase
def test_anonymous_block_forwarding
assert_syntax_error("def b; c(&); end", /no anonymous block parameter/)
+ assert_syntax_error("def b(&) ->(&) {c(&)} end", /anonymous block parameter is also used/)
+ assert_valid_syntax("def b(&) ->() {c(&)} end")
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
- def b(&); c(&) end
- def c(&); yield 1 end
- a = nil
- b{|c| a = c}
- assert_equal(1, a)
-
- def inner
- yield
- end
+ def b(&); c(&) end
+ def c(&); yield 1 end
+ a = nil
+ b{|c| a = c}
+ assert_equal(1, a)
+
+ def inner
+ yield
+ end
- def block_only(&)
- inner(&)
- end
- assert_equal(1, block_only{1})
+ def block_only(&)
+ inner(&)
+ end
+ assert_equal(1, block_only{1})
- def pos(arg1, &)
- inner(&)
- end
- assert_equal(2, pos(nil){2})
+ def pos(arg1, &)
+ inner(&)
+ end
+ assert_equal(2, pos(nil){2})
- def pos_kwrest(arg1, **kw, &)
- inner(&)
- end
- assert_equal(3, pos_kwrest(nil){3})
+ def pos_kwrest(arg1, **kw, &)
+ inner(&)
+ end
+ assert_equal(3, pos_kwrest(nil){3})
- def no_kw(arg1, **nil, &)
- inner(&)
- end
- assert_equal(4, no_kw(nil){4})
+ def no_kw(arg1, **nil, &)
+ inner(&)
+ end
+ assert_equal(4, no_kw(nil){4})
- def rest_kw(*a, kwarg: 1, &)
- inner(&)
- end
- assert_equal(5, rest_kw{5})
+ def rest_kw(*a, kwarg: 1, &)
+ inner(&)
+ end
+ assert_equal(5, rest_kw{5})
- def kw(kwarg:1, &)
- inner(&)
- end
- assert_equal(6, kw{6})
+ def kw(kwarg:1, &)
+ inner(&)
+ end
+ assert_equal(6, kw{6})
- def pos_kw_kwrest(arg1, kwarg:1, **kw, &)
- inner(&)
- end
- assert_equal(7, pos_kw_kwrest(nil){7})
+ def pos_kw_kwrest(arg1, kwarg:1, **kw, &)
+ inner(&)
+ end
+ assert_equal(7, pos_kw_kwrest(nil){7})
- def pos_rkw(arg1, kwarg1:, &)
- inner(&)
- end
- assert_equal(8, pos_rkw(nil, kwarg1: nil){8})
+ def pos_rkw(arg1, kwarg1:, &)
+ inner(&)
+ end
+ assert_equal(8, pos_rkw(nil, kwarg1: nil){8})
- def all(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, &)
- inner(&)
- end
- assert_equal(9, all(nil, nil, nil, nil, okw1: nil, okw2: nil){9})
+ def all(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, &)
+ inner(&)
+ end
+ assert_equal(9, all(nil, nil, nil, nil, okw1: nil, okw2: nil){9})
- def all_kwrest(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, **kw, &)
- inner(&)
- end
- assert_equal(10, all_kwrest(nil, nil, nil, nil, okw1: nil, okw2: nil){10})
+ def all_kwrest(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, **kw, &)
+ inner(&)
+ end
+ assert_equal(10, all_kwrest(nil, nil, nil, nil, okw1: nil, okw2: nil){10})
end;
end
def test_anonymous_rest_forwarding
assert_syntax_error("def b; c(*); end", /no anonymous rest parameter/)
assert_syntax_error("def b; c(1, *); end", /no anonymous rest parameter/)
+ assert_syntax_error("def b(*) ->(*) {c(*)} end", /anonymous rest parameter is also used/)
+ assert_syntax_error("def b(a, *) ->(*) {c(1, *)} end", /anonymous rest parameter is also used/)
+ assert_syntax_error("def b(*) ->(a, *) {c(*)} end", /anonymous rest parameter is also used/)
+ assert_valid_syntax("def b(*) ->() {c(*)} end")
+ assert_valid_syntax("def b(a, *) ->() {c(1, *)} end")
+ assert_valid_syntax("def b(*) ->(a) {c(*)} end")
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
- def b(*); c(*) end
- def c(*a); a end
- def d(*); b(*, *) end
- assert_equal([1, 2], b(1, 2))
- assert_equal([1, 2, 1, 2], d(1, 2))
+ def b(*); c(*) end
+ def c(*a); a end
+ def d(*); b(*, *) end
+ assert_equal([1, 2], b(1, 2))
+ assert_equal([1, 2, 1, 2], d(1, 2))
end;
end
def test_anonymous_keyword_rest_forwarding
assert_syntax_error("def b; c(**); end", /no anonymous keyword rest parameter/)
assert_syntax_error("def b; c(k: 1, **); end", /no anonymous keyword rest parameter/)
+ assert_syntax_error("def b(**) ->(**) {c(**)} end", /anonymous keyword rest parameter is also used/)
+ assert_syntax_error("def b(k:, **) ->(**) {c(k: 1, **)} end", /anonymous keyword rest parameter is also used/)
+ assert_syntax_error("def b(**) ->(k:, **) {c(**)} end", /anonymous keyword rest parameter is also used/)
+ assert_valid_syntax("def b(**) ->() {c(**)} end")
+ assert_valid_syntax("def b(k:, **) ->() {c(k: 1, **)} end")
+ assert_valid_syntax("def b(**) ->(k:) {c(**)} end")
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
- def b(**); c(**) end
- def c(**kw); kw end
- def d(**); b(k: 1, **) end
- def e(**); b(**, k: 1) end
- assert_equal({a: 1, k: 3}, b(a: 1, k: 3))
- assert_equal({a: 1, k: 3}, d(a: 1, k: 3))
- assert_equal({a: 1, k: 1}, e(a: 1, k: 3))
+ def b(**); c(**) end
+ def c(**kw); kw end
+ def d(**); b(k: 1, **) end
+ def e(**); b(**, k: 1) end
+ def f(a: nil, **); b(**) end
+ assert_equal({a: 1, k: 3}, b(a: 1, k: 3))
+ assert_equal({a: 1, k: 3}, d(a: 1, k: 3))
+ assert_equal({a: 1, k: 1}, e(a: 1, k: 3))
+ assert_equal({k: 3}, f(a: 1, k: 3))
end;
end
+ def test_argument_forwarding_with_anon_rest_kwrest_and_block
+ assert_syntax_error("def f(*, **, &); g(...); end", /unexpected \.\.\./)
+ assert_syntax_error("def f(...); g(*); end", /no anonymous rest parameter/)
+ assert_syntax_error("def f(...); g(0, *); end", /no anonymous rest parameter/)
+ assert_syntax_error("def f(...); g(**); end", /no anonymous keyword rest parameter/)
+ assert_syntax_error("def f(...); g(x: 1, **); end", /no anonymous keyword rest parameter/)
+ assert_syntax_error("def f(...); g(&); end", /no anonymous block parameter/)
+ end
+
def test_newline_in_block_parameters
bug = '[ruby-dev:45292]'
["", "a", "a, b"].product(["", ";x", [";", "x"]]) do |params|
@@ -210,6 +234,7 @@ class TestSyntax < Test::Unit::TestCase
def test_array_kwsplat_hash
kw = {}
h = {a: 1}
+ a = []
assert_equal([], [**{}])
assert_equal([], [**kw])
assert_equal([h], [**h])
@@ -224,6 +249,20 @@ class TestSyntax < Test::Unit::TestCase
assert_equal([1, kw], [1, kw])
assert_equal([1, h], [1, h])
+ assert_equal([], [*a, **{}])
+ assert_equal([], [*a, **kw])
+ assert_equal([h], [*a, **h])
+ assert_equal([{}], [*a, {}])
+ assert_equal([kw], [*a, kw])
+ assert_equal([h], [*a, h])
+
+ assert_equal([1], [1, *a, **{}])
+ assert_equal([1], [1, *a, **kw])
+ assert_equal([1, h], [1, *a, **h])
+ assert_equal([1, {}], [1, *a, {}])
+ assert_equal([1, kw], [1, *a, kw])
+ assert_equal([1, h], [1, *a, h])
+
assert_equal([], [**kw, **kw])
assert_equal([], [**kw, **{}, **kw])
assert_equal([1], [1, **kw, **{}, **kw])
@@ -326,6 +365,12 @@ class TestSyntax < Test::Unit::TestCase
assert_warn(/duplicated/) {r = eval("a.f(**{k: a.add(1), j: a.add(2), k: a.add(3), k: a.add(4)})")}
assert_equal(4, r)
assert_equal([1, 2, 3, 4], a)
+ a.clear
+ r = nil
+ _z = {}
+ assert_warn(/duplicated/) {r = eval("a.f(k: a.add(1), **_z, k: a.add(2))")}
+ assert_equal(2, r)
+ assert_equal([1, 2], a)
end
def test_keyword_empty_splat
@@ -352,6 +397,7 @@ class TestSyntax < Test::Unit::TestCase
assert_syntax_error("def foo(var: var) var end", message)
assert_syntax_error("def foo(var: bar(var)) var end", message)
assert_syntax_error("def foo(var: bar {var}) var end", message)
+ assert_syntax_error("def foo(var: (1 in ^var)); end", message)
o = Object.new
assert_warn("") do
@@ -417,6 +463,7 @@ class TestSyntax < Test::Unit::TestCase
assert_syntax_error("def foo(var = bar {var}) var end", message)
assert_syntax_error("def foo(var = (def bar;end; var)) var end", message)
assert_syntax_error("def foo(var = (def self.bar;end; var)) var end", message)
+ assert_syntax_error("def foo(var = (1 in ^var)); end", message)
o = Object.new
assert_warn("") do
@@ -460,7 +507,7 @@ class TestSyntax < Test::Unit::TestCase
def test_warn_balanced
warning = <<WARN
-test:1: warning: `%s' after local variable or literal is interpreted as binary operator
+test:1: warning: '%s' after local variable or literal is interpreted as binary operator
test:1: warning: even though it seems like %s
WARN
[
@@ -627,6 +674,8 @@ WARN
assert_equal(42, obj.foo(42))
assert_equal(42, obj.foo(2, _: 0))
assert_equal(2, obj.foo(x: 2, _: 0))
+ ensure
+ self.class.remove_method(:foo)
end
def test_duplicated_opt_kw
@@ -666,7 +715,7 @@ WARN
end
def test_duplicated_when
- w = 'warning: duplicated `when\' clause with line 3 is ignored'
+ w = 'warning: duplicated \'when\' clause with line 3 is ignored'
assert_warning(/3: #{w}.+4: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m) {
eval %q{
case 1
@@ -686,10 +735,28 @@ WARN
end
}
}
+ assert_warning(/3: #{w}/m) {
+ eval %q{
+ case 1
+ when __LINE__, __LINE__
+ when 3, 3
+ when 3, 3
+ end
+ }
+ }
+ assert_warning(/3: #{w}/m) {
+ eval %q{
+ case 1
+ when __FILE__, __FILE__
+ when "filename", "filename"
+ when "filename", "filename"
+ end
+ }, binding, "filename"
+ }
end
def test_duplicated_when_check_option
- w = /duplicated `when\' clause with line 3 is ignored/
+ w = /duplicated \'when\' clause with line 3 is ignored/
assert_in_out_err(%[-wc], "#{<<~"begin;"}\n#{<<~'end;'}", ["Syntax OK"], w)
begin;
case 1
@@ -968,6 +1035,14 @@ eom
assert_not_match(/end-of-input/, e.message)
end
+ def test_invalid_regexp
+ bug20295 = '[ruby-core:116913] [Bug #20295]'
+
+ assert_syntax_error("/[/=~s", /premature end of char-class/, bug20295)
+ assert_syntax_error("/(?<>)/=~s", /group name is empty/, bug20295)
+ assert_syntax_error("/(?<a>[)/=~s", /premature end of char-class/, bug20295)
+ end
+
def test_lineno_operation_brace_block
expected = __LINE__ + 1
actual = caller_lineno\
@@ -980,7 +1055,7 @@ eom
["p ", ""], # no-pop
["", "p Foo::Bar"], # pop
].each do |p1, p2|
- src = <<-EOM.gsub(/^\s*\n/, '')
+ src = <<~EOM
class Foo
#{"Bar = " + preset if preset}
end
@@ -1012,7 +1087,7 @@ eom
["p ", ""], # no-pop
["", "p ::Bar"], # pop
].each do |p1, p2|
- src = <<-EOM.gsub(/^\s*\n/, '')
+ src = <<~EOM
#{"Bar = " + preset if preset}
class Foo
#{p1}::Bar #{op}= 42
@@ -1179,12 +1254,18 @@ eom
assert_warn(/string literal in condition/) do
eval('1 if ""')
end
+ assert_warning(/string literal in condition/) do
+ eval('1 if __FILE__')
+ end
assert_warn(/regex literal in condition/) do
eval('1 if //')
end
assert_warning(/literal in condition/) do
eval('1 if 1')
end
+ assert_warning(/literal in condition/) do
+ eval('1 if __LINE__')
+ end
assert_warning(/symbol literal in condition/) do
eval('1 if :foo')
end
@@ -1258,7 +1339,7 @@ eom
end
def test_parenthesised_statement_argument
- assert_syntax_error("foo(bar rescue nil)", /unexpected `rescue' modifier/)
+ assert_syntax_error("foo(bar rescue nil)", /unexpected 'rescue' modifier/)
assert_valid_syntax("foo (bar rescue nil)")
end
@@ -1308,6 +1389,25 @@ eom
assert_valid_syntax 'p :foo, {proc do end => proc do end, b: proc do end}', bug13073
end
+ def test_invalid_encoding_symbol
+ assert_syntax_error('{"\xC3": 1}', "invalid symbol")
+ end
+
+ def test_invalid_symbol_in_hash_memory_leak
+ assert_no_memory_leak([], "#{<<-'begin;'}", "#{<<-'end;'}", rss: true)
+ str = '{"\xC3": 1}'.force_encoding("UTF-8")
+ code = proc do
+ eval(str)
+ raise "unreachable"
+ rescue SyntaxError
+ end
+
+ 1_000.times(&code)
+ begin;
+ 1_000_000.times(&code)
+ end;
+ end
+
def test_do_after_local_variable
obj = Object.new
def obj.m; yield; end
@@ -1356,9 +1456,10 @@ eom
"#{return}"
raise((return; "should not raise"))
begin raise; ensure return; end; self
- begin raise; ensure return; end and self
nil&defined?0--begin e=no_method_error(); return; 0;end
return puts('ignored') #=> ignored
+ BEGIN {return}
+ END {return if false}
end;
.split(/\n/).map {|s|[(line+=1), *s.split(/#=> /, 2)]}
failed = proc do |n, s|
@@ -1388,6 +1489,54 @@ eom
end
end
+ def test_eval_return_toplevel
+ feature4840 = '[ruby-core:36785] [Feature #4840]'
+ line = __LINE__+2
+ code = "#{<<~"begin;"}#{<<~'end;'}"
+ begin;
+ eval "return"; raise
+ begin eval "return"; rescue SystemExit; exit false; end
+ begin eval "return"; ensure puts "ensured"; end #=> ensured
+ begin ensure eval "return"; end
+ begin raise; ensure; eval "return"; end
+ begin raise; rescue; eval "return"; end
+ eval "return false"; raise
+ eval "return 1"; raise
+ "#{eval "return"}"
+ raise((eval "return"; "should not raise"))
+ begin raise; ensure eval "return"; end; self
+ begin raise; ensure eval "return"; end and self
+ eval "return puts('ignored')" #=> ignored
+ BEGIN {eval "return"}
+ end;
+ .split(/\n/).map {|s|[(line+=1), *s.split(/#=> /, 2)]}
+ failed = proc do |n, s|
+ RubyVM::InstructionSequence.compile(s, __FILE__, nil, n).disasm
+ end
+ Tempfile.create(%w"test_return_ .rb") do |lib|
+ lib.close
+ args = %W[-W0 -r#{lib.path}]
+ all_assertions_foreach(feature4840, *[:main, :lib].product([:class, :top], code)) do |main, klass, (n, s, *ex)|
+ if klass == :class
+ s = "class X; #{s}; end"
+ if main == :main
+ assert_in_out_err(%[-W0], s, ex, /return/, proc {failed[n, s]}, success: false)
+ else
+ File.write(lib, s)
+ assert_in_out_err(args, "", ex, /return/, proc {failed[n, s]}, success: false)
+ end
+ else
+ if main == :main
+ assert_in_out_err(%[-W0], s, ex, [], proc {failed[n, s]}, success: true)
+ else
+ File.write(lib, s)
+ assert_in_out_err(args, "", ex, [], proc {failed[n, s]}, success: true)
+ end
+ end
+ end
+ end
+ end
+
def test_return_toplevel_with_argument
assert_warn(/argument of top-level return is ignored/) {eval("return 1")}
end
@@ -1396,6 +1545,20 @@ eom
assert_in_out_err(['-e', 'class TestSyntax; proc{ return }.call; end'], "", [], /^-e:1:.*unexpected return \(LocalJumpError\)/)
end
+ def test_return_in_END
+ assert_normal_exit('END {return}')
+ end
+
+ def test_return_in_BEGIN_in_eval
+ # `BEGIN` in `eval` is allowed, even inside a method, and `return`
+ # from that block exits from that method without `LocalJumpError`.
+ obj = Object.new
+ def obj.ok
+ eval("BEGIN {return :ok}")
+ end
+ assert_equal :ok, assert_nothing_raised(LocalJumpError) {obj.ok}
+ end
+
def test_syntax_error_in_rescue
bug12613 = '[ruby-core:76531] [Bug #12613]'
assert_syntax_error("#{<<-"begin;"}\n#{<<-"end;"}", /Invalid retry/, bug12613)
@@ -1615,6 +1778,29 @@ eom
def test_command_with_cmd_brace_block
assert_valid_syntax('obj.foo (1) {}')
assert_valid_syntax('obj::foo (1) {}')
+ assert_valid_syntax('bar {}')
+ assert_valid_syntax('Bar {}')
+ assert_valid_syntax('bar() {}')
+ assert_valid_syntax('Bar() {}')
+ assert_valid_syntax('Foo::bar {}')
+ assert_valid_syntax('Foo::Bar {}')
+ assert_valid_syntax('Foo::bar() {}')
+ assert_valid_syntax('Foo::Bar() {}')
+ end
+
+ def test_command_newline_in_tlparen_args
+ assert_valid_syntax("p (1\n2\n),(3),(4)")
+ assert_valid_syntax("p (\n),(),()")
+ assert_valid_syntax("a.b (1\n2\n),(3),(4)")
+ assert_valid_syntax("a.b (\n),(),()")
+ end
+
+ def test_command_semicolon_in_tlparen_at_the_first_arg
+ bug19281 = '[ruby-core:111499] [Bug #19281]'
+ assert_valid_syntax('p (1;2),(3),(4)', bug19281)
+ assert_valid_syntax('p (;),(),()', bug19281)
+ assert_valid_syntax('a.b (1;2),(3),(4)', bug19281)
+ assert_valid_syntax('a.b (;),(),()', bug19281)
end
def test_numbered_parameter
@@ -1645,7 +1831,7 @@ eom
assert_syntax_error('def x(_4) end', /_4 is reserved for numbered parameter/)
assert_syntax_error('def _5; end', /_5 is reserved for numbered parameter/)
assert_syntax_error('def self._6; end', /_6 is reserved for numbered parameter/)
- assert_raise_with_message(NameError, /undefined local variable or method `_1'/) {
+ assert_raise_with_message(NameError, /undefined local variable or method '_1'/) {
eval('_1')
}
['class C', 'class << C', 'module M', 'def m', 'def o.m'].each do |c|
@@ -1660,6 +1846,61 @@ eom
assert_raise(NameError) {eval("_1")},
]
}
+
+ assert_valid_syntax("proc {def foo(_);end;_1}")
+ assert_valid_syntax("p { [_1 **2] }")
+ assert_valid_syntax("proc {_1;def foo();end;_1}")
+ end
+
+ def test_it
+ assert_valid_syntax('proc {it}')
+ assert_syntax_error('[1,2].then {it+_2}', /'it' is already used/)
+ assert_syntax_error('[1,2].then {_2+it}', /numbered parameter is already used/)
+ assert_equal([1, 2], eval('[1,2].then {it}'))
+ assert_syntax_error('[1,2].then {"#{it}#{_2}"}', /'it' is already used/)
+ assert_syntax_error('[1,2].then {"#{_2}#{it}"}', /numbered parameter is already used/)
+ assert_syntax_error('->{it+_2}.call(1,2)', /'it' is already used/)
+ assert_syntax_error('->{_2+it}.call(1,2)', /numbered parameter is already used/)
+ assert_equal(4, eval('->(a=->{it}){a}.call.call(4)'))
+ assert_equal(5, eval('-> a: ->{it} {a}.call.call(5)'))
+ assert_syntax_error('proc {|| it}', /ordinary parameter is defined/)
+ assert_syntax_error('proc {|;a| it}', /ordinary parameter is defined/)
+ assert_syntax_error("proc {|\n| it}", /ordinary parameter is defined/)
+ assert_syntax_error('proc {|x| it}', /ordinary parameter is defined/)
+ assert_equal([1, 2], eval('1.then {[it, 2.then {_1}]}'))
+ assert_equal([2, 1], eval('1.then {[2.then {_1}, it]}'))
+ assert_syntax_error('->(){it}', /ordinary parameter is defined/)
+ assert_syntax_error('->(x){it}', /ordinary parameter is defined/)
+ assert_syntax_error('->x{it}', /ordinary parameter is defined/)
+ assert_syntax_error('->x:_1{}', /ordinary parameter is defined/)
+ assert_syntax_error('->x=it{}', /ordinary parameter is defined/)
+ assert_valid_syntax('-> {it; -> {_2}}')
+ assert_valid_syntax('-> {-> {it}; _2}')
+ assert_equal([1, nil], eval('proc {that=it; it=nil; [that, it]}.call(1)'))
+ assert_equal(1, eval('proc {it = 1}.call'))
+ assert_warning(/1: warning: assigned but unused variable - it/) {
+ assert_equal(2, eval('a=Object.new; def a.foo; it = 2; end; a.foo'))
+ }
+ assert_equal(3, eval('proc {|it| it}.call(3)'))
+ assert_equal(4, eval('a=Object.new; def a.foo(it); it; end; a.foo(4)'))
+ assert_equal(5, eval('a=Object.new; def a.it; 5; end; a.it'))
+ assert_equal(6, eval('a=Class.new; a.class_eval{ def it; 6; end }; a.new.it'))
+ assert_raise_with_message(NameError, /undefined local variable or method 'it'/) do
+ eval('it')
+ end
+ ['class C', 'class << C', 'module M', 'def m', 'def o.m'].each do |c|
+ assert_valid_syntax("->{#{c};->{it};end;it}\n")
+ assert_valid_syntax("->{it;#{c};->{it};end}\n")
+ end
+ 1.times do
+ [
+ assert_equal(0, it),
+ assert_equal([:a], eval('[:a].map{it}')),
+ assert_raise(NameError) {eval('it')},
+ ]
+ end
+ assert_valid_syntax('proc {def foo(_);end;it}')
+ assert_syntax_error('p { [it **2] }', /unexpected \*\*arg/)
end
def test_value_expr_in_condition
@@ -1670,6 +1911,11 @@ eom
assert_valid_syntax("tap {a = (break unless true)}")
end
+ def test_value_expr_in_singleton
+ mesg = /void value expression/
+ assert_syntax_error("class << (return); end", mesg)
+ end
+
def test_tautological_condition
assert_valid_syntax("def f() return if false and invalid; nil end")
assert_valid_syntax("def f() return unless true or invalid; nil end")
@@ -1707,6 +1953,8 @@ eom
assert_syntax_error('def foo(...) foo[...] = x; end', /unexpected/)
assert_syntax_error('def foo(...) foo(...) { }; end', /both block arg and actual block given/)
assert_syntax_error('def foo(...) defined?(...); end', /unexpected/)
+ assert_syntax_error('def foo(*rest, ...) end', '... after rest argument')
+ assert_syntax_error('def foo(*, ...) end', '... after rest argument')
obj1 = Object.new
def obj1.bar(*args, **kws, &block)
@@ -1907,6 +2155,13 @@ eom
assert_equal 0...1, exp.call(a: 0)
end
+ def test_argument_forwarding_with_super
+ assert_valid_syntax('def foo(...) super {}; end')
+ assert_valid_syntax('def foo(...) super() {}; end')
+ assert_syntax_error('def foo(...) super(...) {}; end', /both block arg and actual block/)
+ assert_syntax_error('def foo(...) super(1, ...) {}; end', /both block arg and actual block/)
+ end
+
def test_class_module_Object_ancestors
assert_separately([], <<-RUBY)
m = Module.new
diff --git a/test/ruby/test_system.rb b/test/ruby/test_system.rb
index 31c9cd7654..3fcdaa6aad 100644
--- a/test/ruby/test_system.rb
+++ b/test/ruby/test_system.rb
@@ -146,6 +146,19 @@ class TestSystem < Test::Unit::TestCase
end
end
+ def test_system_closed
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ ios = []
+ ObjectSpace.each_object(IO) {|io| ios << io}
+ `echo`
+ ObjectSpace.each_object(IO) do |io|
+ next if ios.include?(io)
+ assert_nothing_raised {io.close}
+ end
+ end;
+ end
+
def test_empty_evstr
assert_equal("", eval('"#{}"', nil, __FILE__, __LINE__), "[ruby-dev:25113]")
end
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb
index f6156a16fd..da14c429e6 100644
--- a/test/ruby/test_thread.rb
+++ b/test/ruby/test_thread.rb
@@ -3,6 +3,7 @@
require 'test/unit'
require "rbconfig/sizeof"
require "timeout"
+require "fiddle"
class TestThread < Test::Unit::TestCase
class Thread < ::Thread
@@ -323,7 +324,7 @@ class TestThread < Test::Unit::TestCase
s += 1
end
Thread.pass until t.stop?
- sleep 1 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # t.stop? behaves unexpectedly with --jit-wait
+ sleep 1 if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # t.stop? behaves unexpectedly with --jit-wait
assert_equal(1, s)
t.wakeup
Thread.pass while t.alive?
@@ -395,7 +396,7 @@ class TestThread < Test::Unit::TestCase
end
INPUT
- assert_in_out_err(%w(--disable-gems -d), <<-INPUT, %w(false 2), %r".+")
+ assert_in_out_err(%w(-d), <<-INPUT, %w(false 2), %r".+")
p Thread.abort_on_exception
begin
t = Thread.new { raise }
@@ -1263,6 +1264,7 @@ q.pop
assert_predicate(status, :success?, bug18902)
ensure
th.kill
+ th.join
end
end if Process.respond_to?(:fork)
@@ -1433,7 +1435,8 @@ q.pop
Thread.pass until th1.stop?
# After a thread starts (and execute `sleep`), it returns native_thread_id
- assert_instance_of Integer, th1.native_thread_id
+ native_tid = th1.native_thread_id
+ assert_instance_of Integer, native_tid if native_tid # it can be nil
th1.wakeup
Thread.pass while th1.alive?
@@ -1442,11 +1445,40 @@ q.pop
assert_nil th1.native_thread_id
end
+ def test_thread_native_thread_id_across_fork_on_linux
+ rtld_default = Fiddle.dlopen(nil)
+ omit "this test is only for Linux" unless rtld_default.sym_defined?('gettid')
+
+ gettid = Fiddle::Function.new(rtld_default['gettid'], [], Fiddle::TYPE_INT)
+
+ parent_thread_id = Thread.main.native_thread_id
+ real_parent_thread_id = gettid.call
+
+ assert_equal real_parent_thread_id, parent_thread_id
+
+ child_lines = nil
+ IO.popen('-') do |pipe|
+ if pipe
+ # parent
+ child_lines = pipe.read.lines
+ else
+ # child
+ puts Thread.main.native_thread_id
+ puts gettid.call
+ end
+ end
+ child_thread_id = child_lines[0].chomp.to_i
+ real_child_thread_id = child_lines[1].chomp.to_i
+
+ assert_equal real_child_thread_id, child_thread_id
+ refute_equal parent_thread_id, child_thread_id
+ end
+
def test_thread_interrupt_for_killed_thread
opts = { timeout: 5, timeout_error: nil }
- # prevent SIGABRT from slow shutdown with MJIT
- opts[:reprieve] = 3 if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
+ # prevent SIGABRT from slow shutdown with RJIT
+ opts[:reprieve] = 3 if defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
assert_normal_exit(<<-_end, '[Bug #8996]', **opts)
Thread.report_on_exception = false
@@ -1515,4 +1547,12 @@ q.pop
end
};
end
+
+ def test_pending_interrupt?
+ t = Thread.handle_interrupt(Exception => :never) { Thread.new { Thread.stop } }
+ t.raise(StandardError)
+ assert_equal(true, t.pending_interrupt?)
+ assert_equal(true, t.pending_interrupt?(Exception))
+ assert_equal(false, t.pending_interrupt?(ArgumentError))
+ end
end
diff --git a/test/ruby/test_thread_cv.rb b/test/ruby/test_thread_cv.rb
index 88733419da..eb88b9606c 100644
--- a/test/ruby/test_thread_cv.rb
+++ b/test/ruby/test_thread_cv.rb
@@ -6,12 +6,6 @@ class TestThreadConditionVariable < Test::Unit::TestCase
ConditionVariable = Thread::ConditionVariable
Mutex = Thread::Mutex
- def test_initialized
- assert_raise(TypeError) {
- ConditionVariable.allocate.wait(nil)
- }
- end
-
def test_condvar_signal_and_wait
mutex = Thread::Mutex.new
condvar = Thread::ConditionVariable.new
diff --git a/test/ruby/test_thread_queue.rb b/test/ruby/test_thread_queue.rb
index 1c852474b4..545bf98888 100644
--- a/test/ruby/test_thread_queue.rb
+++ b/test/ruby/test_thread_queue.rb
@@ -8,17 +8,26 @@ class TestThreadQueue < Test::Unit::TestCase
SizedQueue = Thread::SizedQueue
def test_queue_initialized
- assert_raise(TypeError) {
+ assert_raise_with_message(TypeError, /\bQueue.* not initialized/) {
Queue.allocate.push(nil)
}
end
def test_sized_queue_initialized
- assert_raise(TypeError) {
+ assert_raise_with_message(TypeError, /\bSizedQueue.* not initialized/) {
SizedQueue.allocate.push(nil)
}
end
+ def test_freeze
+ assert_raise(TypeError) {
+ Queue.new.freeze
+ }
+ assert_raise(TypeError) {
+ SizedQueue.new(5).freeze
+ }
+ end
+
def test_queue
grind(5, 1000, 15, Queue)
end
@@ -168,6 +177,24 @@ class TestThreadQueue < Test::Unit::TestCase
end
end
+ def test_sized_queue_push_timeout
+ q = Thread::SizedQueue.new(1)
+
+ q << 1
+ assert_equal 1, q.size
+
+ t1 = Thread.new { q.push(2, timeout: 1) }
+ assert_equal t1, t1.join(2)
+ assert_nil t1.value
+
+ t2 = Thread.new { q.push(2, timeout: 0.1) }
+ assert_equal t2, t2.join(1)
+ assert_nil t2.value
+ ensure
+ t1&.kill&.join
+ t2&.kill&.join
+ end
+
def test_sized_queue_push_interrupt
q = Thread::SizedQueue.new(1)
q.push(1)
@@ -190,14 +217,14 @@ class TestThreadQueue < Test::Unit::TestCase
bug5343 = '[ruby-core:39634]'
Dir.mktmpdir {|d|
- timeout = EnvUtil.apply_timeout_scale(60)
+ timeout = 60
total_count = 250
begin
- assert_normal_exit(<<-"_eom", bug5343, **{:timeout => timeout, :chdir=>d})
+ assert_normal_exit(<<-"_eom", bug5343, timeout: timeout, chdir: d)
+ r, w = IO.pipe
#{total_count}.times do |i|
- open("test_thr_kill_count", "w") {|f| f.puts i }
+ File.open("test_thr_kill_count", "w") {|f| f.puts i }
queue = Thread::Queue.new
- r, w = IO.pipe
th = Thread.start {
queue.push(nil)
r.read 1
@@ -567,9 +594,14 @@ class TestThreadQueue < Test::Unit::TestCase
count_items = rand(3000..5000)
count_producers = rand(10..20)
+ # ensure threads do not start running too soon and complete before we check status
+ mutex = Mutex.new
+ mutex.lock
+
producers = count_producers.times.map do
Thread.new do
- sleep(rand / 100)
+ mutex.lock
+ mutex.unlock
count_items.times{|i| q << [i,"#{i} for #{Thread.current.inspect}"]}
end
end
@@ -587,9 +619,11 @@ class TestThreadQueue < Test::Unit::TestCase
# No dead or finished threads, give up to 10 seconds to start running
t = Time.now
- Thread.pass until Time.now - t > 10 || (consumers + producers).all?{|thr| thr.status =~ /\A(?:run|sleep)\z/}
+ Thread.pass until Time.now - t > 10 || (consumers + producers).all?{|thr| thr.status.to_s =~ /\A(?:run|sleep)\z/}
+
+ assert (consumers + producers).all?{|thr| thr.status.to_s =~ /\A(?:run|sleep)\z/}, 'no threads running'
- assert (consumers + producers).all?{|thr| thr.status =~ /\A(?:run|sleep)\z/}, 'no threads running'
+ mutex.unlock
# just exercising the concurrency of the support methods.
counter = Thread.new do
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index 4af4cf5474..2a541bbe8c 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -54,7 +54,104 @@ class TestTime < Test::Unit::TestCase
assert_raise_with_message(ArgumentError, msg) { Time.new(2021, 1, "+09:99") }
assert_raise_with_message(ArgumentError, msg) { Time.new(2021, "+09:99") }
- assert_equal([0, 0, 0, 2, 1, 2000], Time.new(2000, 1, 1, 24, 0, 0, "-00:00").to_a[0, 6])
+ assert_equal([0, 0, 0, 1, 1, 2000, 6, 1, false, "UTC"], Time.new(2000, 1, 1, 0, 0, 0, "-00:00").to_a)
+ assert_equal([0, 0, 0, 2, 1, 2000, 0, 2, false, "UTC"], Time.new(2000, 1, 1, 24, 0, 0, "-00:00").to_a)
+ end
+
+ def test_new_from_string
+ assert_raise(ArgumentError) { Time.new(2021, 1, 1, "+09:99") }
+
+ t = Time.utc(2020, 12, 24, 15, 56, 17)
+ assert_equal(t, Time.new("2020-12-24T15:56:17Z"))
+ assert_equal(t, Time.new("2020-12-25 00:56:17 +09:00"))
+ assert_equal(t, Time.new("2020-12-25 00:57:47 +09:01:30"))
+ assert_equal(t, Time.new("2020-12-25 00:56:17 +0900"))
+ assert_equal(t, Time.new("2020-12-25 00:57:47 +090130"))
+ assert_equal(t, Time.new("2020-12-25T00:56:17+09:00"))
+ assert_raise_with_message(ArgumentError, /missing sec part/) {
+ Time.new("2020-12-25 00:56 +09:00")
+ }
+ assert_raise_with_message(ArgumentError, /missing min part/) {
+ Time.new("2020-12-25 00 +09:00")
+ }
+
+ assert_equal(Time.new(2021), Time.new("2021"))
+ assert_equal(Time.new(2021, 12, 25, in: "+09:00"), Time.new("2021-12-25+09:00"))
+ assert_equal(Time.new(2021, 12, 25, in: "+09:00"), Time.new("2021-12-25+09:00", in: "-01:00"))
+
+ assert_equal(0.123456r, Time.new("2021-12-25 00:00:00.123456 +09:00").subsec)
+ assert_equal(0.123456789r, Time.new("2021-12-25 00:00:00.123456789876 +09:00").subsec)
+ assert_equal(0.123r, Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: 3).subsec)
+ assert_equal(0.123456789876r, Time.new("2021-12-25 00:00:00.123456789876 +09:00", precision: nil).subsec)
+ assert_raise_with_message(ArgumentError, "subsecond expected after dot: 00:56:17. ") {
+ Time.new("2020-12-25 00:56:17. +0900")
+ }
+ assert_raise_with_message(ArgumentError, /year must be 4 or more/) {
+ Time.new("021-12-25 00:00:00.123456 +09:00")
+ }
+ assert_raise_with_message(ArgumentError, /fraction min is.*56\./) {
+ Time.new("2020-12-25 00:56. +0900")
+ }
+ assert_raise_with_message(ArgumentError, /fraction hour is.*00\./) {
+ Time.new("2020-12-25 00. +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits sec.*:017\b/) {
+ Time.new("2020-12-25 00:56:017 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits sec.*:9\b/) {
+ Time.new("2020-12-25 00:56:9 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /sec out of range/) {
+ Time.new("2020-12-25 00:56:64 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits min.*:056\b/) {
+ Time.new("2020-12-25 00:056:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits min.*:5\b/) {
+ Time.new("2020-12-25 00:5:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /min out of range/) {
+ Time.new("2020-12-25 00:64:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits hour.*\b000\b/) {
+ Time.new("2020-12-25 000:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits hour.*\b0\b/) {
+ Time.new("2020-12-25 0:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /hour out of range/) {
+ Time.new("2020-12-25 33:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits mday.*\b025\b/) {
+ Time.new("2020-12-025 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits mday.*\b5\b/) {
+ Time.new("2020-12-5 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /mday out of range/) {
+ Time.new("2020-12-33 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits mon.*\b012\b/) {
+ Time.new("2020-012-25 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /two digits mon.*\b1\b/) {
+ Time.new("2020-1-25 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /mon out of range/) {
+ Time.new("2020-17-25 00:56:17 +0900")
+ }
+ assert_raise_with_message(ArgumentError, /no time information/) {
+ Time.new("2020-12")
+ }
+ assert_raise_with_message(ArgumentError, /no time information/) {
+ Time.new("2020-12-02")
+ }
+ assert_raise_with_message(ArgumentError, /can't parse/) {
+ Time.new(" 2020-12-02 00:00:00")
+ }
+ assert_raise_with_message(ArgumentError, /can't parse/) {
+ Time.new("2020-12-02 00:00:00 ")
+ }
end
def test_time_add()
@@ -342,7 +439,7 @@ class TestTime < Test::Unit::TestCase
end
def test_marshal_zone_gc
- assert_separately(%w(--disable-gems), <<-'end;', timeout: 30)
+ assert_separately([], <<-'end;', timeout: 30)
ENV["TZ"] = "JST-9"
s = Marshal.dump(Time.now)
t = Marshal.load(s)
@@ -1311,7 +1408,10 @@ class TestTime < Test::Unit::TestCase
def test_memsize
# Time objects are common in some code, try to keep them small
omit "Time object size test" if /^(?:i.?86|x86_64)-linux/ !~ RUBY_PLATFORM
- omit "GC is in debug" if GC::INTERNAL_CONSTANTS[:DEBUG]
+ omit "GC is in debug" if GC::INTERNAL_CONSTANTS[:RVALUE_OVERHEAD] > 0
+ omit "memsize is not accurate due to using malloc_usable_size" if GC::INTERNAL_CONSTANTS[:SIZE_POOL_COUNT] == 1
+ omit "Only run this test on 64-bit" if RbConfig::SIZEOF["void*"] != 8
+
require 'objspace'
t = Time.at(0)
sizeof_timew =
@@ -1320,13 +1420,28 @@ class TestTime < Test::Unit::TestCase
else
RbConfig::SIZEOF["void*"] # Same size as VALUE
end
- expect =
- GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] +
- sizeof_timew +
- RbConfig::SIZEOF["void*"] * 4 + 5 + # vtm
- 1 # tzmode, tm_got
- assert_equal expect, ObjectSpace.memsize_of(t)
+ sizeof_vtm = RbConfig::SIZEOF["void*"] * 4 + 8
+ expect = GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] + sizeof_timew + sizeof_vtm
+ assert_operator ObjectSpace.memsize_of(t), :<=, expect
rescue LoadError => e
omit "failed to load objspace: #{e.message}"
end
+
+ def test_deconstruct_keys
+ t = in_timezone('JST-9') { Time.local(2022, 10, 16, 14, 1, 30, 500) }
+ assert_equal(
+ {year: 2022, month: 10, day: 16, wday: 0, yday: 289,
+ hour: 14, min: 1, sec: 30, subsec: 1/2000r, dst: false, zone: 'JST'},
+ t.deconstruct_keys(nil)
+ )
+
+ assert_equal(
+ {year: 2022, month: 10, sec: 30},
+ t.deconstruct_keys(%i[year month sec nonexistent])
+ )
+ end
+
+ def test_parse_zero_bigint
+ assert_equal 0, Time.new("2020-10-28T16:48:07.000Z").nsec, '[Bug #19390]'
+ end
end
diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb
index 6ae12dea5d..f66cd9bec2 100644
--- a/test/ruby/test_time_tz.rb
+++ b/test/ruby/test_time_tz.rb
@@ -7,9 +7,9 @@ class TestTimeTZ < Test::Unit::TestCase
has_lisbon_tz = true
force_tz_test = ENV["RUBY_FORCE_TIME_TZ_TEST"] == "yes"
case RUBY_PLATFORM
- when /linux/
+ when /darwin|linux/
force_tz_test = true
- when /darwin|freebsd|openbsd/
+ when /freebsd|openbsd/
has_lisbon_tz = false
force_tz_test = true
end
@@ -95,6 +95,9 @@ class TestTimeTZ < Test::Unit::TestCase
CORRECT_KIRITIMATI_SKIP_1994 = with_tz("Pacific/Kiritimati") {
Time.local(1994, 12, 31, 0, 0, 0).year == 1995
}
+ CORRECT_SINGAPORE_1982 = with_tz("Asia/Singapore") {
+ "2022g" if Time.local(1981, 12, 31, 23, 59, 59).utc_offset == 8*3600
+ }
def time_to_s(t)
t.to_s
@@ -140,9 +143,12 @@ class TestTimeTZ < Test::Unit::TestCase
def test_asia_singapore
with_tz(tz="Asia/Singapore") {
- assert_time_constructor(tz, "1981-12-31 23:59:59 +0730", :local, [1981,12,31,23,59,59])
- assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,0,0])
- assert_time_constructor(tz, "1982-01-01 00:59:59 +0800", :local, [1982,1,1,0,29,59])
+ assert_time_constructor(tz, "1981-12-31 23:29:59 +0730", :local, [1981,12,31,23,29,59])
+ if CORRECT_SINGAPORE_1982
+ assert_time_constructor(tz, "1982-01-01 00:00:00 +0800", :local, [1981,12,31,23,30,00])
+ assert_time_constructor(tz, "1982-01-01 00:00:00 +0800", :local, [1982,1,1,0,0,0])
+ assert_time_constructor(tz, "1982-01-01 00:29:59 +0800", :local, [1982,1,1,0,29,59])
+ end
assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,30,0])
}
end
@@ -196,7 +202,7 @@ class TestTimeTZ < Test::Unit::TestCase
def test_europe_lisbon
with_tz("Europe/Lisbon") {
- assert_equal("LMT", Time.new(-0x1_0000_0000_0000_0000).zone)
+ assert_include(%w"LMT CET", Time.new(-0x1_0000_0000_0000_0000).zone)
}
end if has_lisbon_tz
@@ -450,9 +456,12 @@ America/Managua Fri Jan 1 06:00:00 1993 UTC = Fri Jan 1 01:00:00 1993 EST isd
America/Managua Wed Jan 1 04:59:59 1997 UTC = Tue Dec 31 23:59:59 1996 EST isdst=0 gmtoff=-18000
America/Managua Wed Jan 1 05:00:00 1997 UTC = Tue Dec 31 23:00:00 1996 CST isdst=0 gmtoff=-21600
Asia/Singapore Sun Aug 8 16:30:00 1965 UTC = Mon Aug 9 00:00:00 1965 SGT isdst=0 gmtoff=27000
-Asia/Singapore Thu Dec 31 16:29:59 1981 UTC = Thu Dec 31 23:59:59 1981 SGT isdst=0 gmtoff=27000
+Asia/Singapore Thu Dec 31 15:59:59 1981 UTC = Thu Dec 31 23:29:59 1981 SGT isdst=0 gmtoff=27000
Asia/Singapore Thu Dec 31 16:30:00 1981 UTC = Fri Jan 1 00:30:00 1982 SGT isdst=0 gmtoff=28800
End
+ gen_zdump_test <<'End' if CORRECT_SINGAPORE_1982
+Asia/Singapore Thu Dec 31 16:00:00 1981 UTC = Fri Jan 1 00:00:00 1982 SGT isdst=0 gmtoff=28800
+End
gen_zdump_test CORRECT_TOKYO_DST_1951 ? <<'End' + (CORRECT_TOKYO_DST_1951 < "2018f" ? <<'2018e' : <<'2018f') : <<'End'
Asia/Tokyo Sat May 5 14:59:59 1951 UTC = Sat May 5 23:59:59 1951 JST isdst=0 gmtoff=32400
Asia/Tokyo Sat May 5 15:00:00 1951 UTC = Sun May 6 01:00:00 1951 JDT isdst=1 gmtoff=36000
@@ -612,6 +621,11 @@ module TestTimeTZ::WithTZ
assert_raise(ArgumentError) {time_class.new(2018, 9, 1, 12, 0, 0, tzarg, in: tzarg)}
end
+ def subtest_hour24(time_class, tz, tzarg, tzname, abbr, utc_offset)
+ t = time_class.new(2000, 1, 1, 24, 0, 0, tzarg)
+ assert_equal([0, 0, 0, 2, 1, 2000], [t.sec, t.min, t.hour, t.mday, t.mon, t.year])
+ end
+
def subtest_now(time_class, tz, tzarg, tzname, abbr, utc_offset)
t = time_class.now(in: tzarg)
assert_equal(tz, t.zone)
@@ -681,6 +695,13 @@ module TestTimeTZ::WithTZ
assert_equal(t.dst?, t2.dst?)
end
+ def subtest_fractional_second(time_class, tz, tzarg, tzname, abbr, utc_offset)
+ t = time_class.new(2024, 1, 1, 23, 59, 59.9r, tzarg)
+ assert_equal(utc_offset[t.dst? ? 1 : 0], t.utc_offset)
+ t = time_class.new(2024, 7, 1, 23, 59, 59.9r, tzarg)
+ assert_equal(utc_offset[t.dst? ? 1 : 0], t.utc_offset)
+ end
+
def test_invalid_zone
make_timezone("INVALID", "INV", 0)
rescue => e
@@ -705,6 +726,7 @@ module TestTimeTZ::WithTZ
"Asia/Tokyo" => ["JST", +9*3600],
"America/Los_Angeles" => ["PST", -8*3600, "PDT", -7*3600],
"Africa/Ndjamena" => ["WAT", +1*3600],
+ "Etc/UTC" => ["UTC", 0],
}
def make_timezone(tzname, abbr, utc_offset, abbr2 = nil, utc_offset2 = nil)
diff --git a/test/ruby/test_transcode.rb b/test/ruby/test_transcode.rb
index c8b0034e06..ceef19e7ea 100644
--- a/test/ruby/test_transcode.rb
+++ b/test/ruby/test_transcode.rb
@@ -10,9 +10,9 @@ class TestTranscode < Test::Unit::TestCase
assert_raise(Encoding::ConverterNotFoundError) { 'abc'.encode!('foo', 'bar') }
assert_raise(Encoding::ConverterNotFoundError) { 'abc'.force_encoding('utf-8').encode('foo') }
assert_raise(Encoding::ConverterNotFoundError) { 'abc'.force_encoding('utf-8').encode!('foo') }
- assert_raise(Encoding::UndefinedConversionError) { "\x80".encode('utf-8','ASCII-8BIT') }
- assert_raise(Encoding::InvalidByteSequenceError) { "\x80".encode('utf-8','US-ASCII') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA5".encode('utf-8','iso-8859-3') }
+ assert_undefined_in("\x80", 'ASCII-8BIT')
+ assert_invalid_in("\x80", 'US-ASCII')
+ assert_undefined_in("\xA5", 'iso-8859-3')
assert_raise(FrozenError) { 'hello'.freeze.encode!('iso-8859-1') }
assert_raise(FrozenError) { '\u3053\u3093\u306b\u3061\u306f'.freeze.encode!('iso-8859-1') } # こんにちは
end
@@ -52,16 +52,6 @@ class TestTranscode < Test::Unit::TestCase
assert_equal("\u20AC"*200000, ("\xA4"*200000).encode!('utf-8', 'iso-8859-15'))
end
- def check_both_ways(utf8, raw, encoding)
- assert_equal(utf8.force_encoding('utf-8'), raw.encode('utf-8', encoding),utf8.dump+raw.dump)
- assert_equal(raw.force_encoding(encoding), utf8.encode(encoding, 'utf-8'))
- end
-
- def check_both_ways2(str1, enc1, str2, enc2)
- assert_equal(str1.force_encoding(enc1), str2.encode(enc1, enc2))
- assert_equal(str2.force_encoding(enc2), str1.encode(enc2, enc1))
- end
-
def test_encoding_of_ascii_originating_from_binary
binary_string = [0x82, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
0x61, 0x20, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x6f,
@@ -188,16 +178,16 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_874
check_both_ways("\u20AC", "\x80", 'windows-874') # €
- assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-874') }
- assert_raise(Encoding::UndefinedConversionError) { "\x84".encode("utf-8", 'windows-874') }
+ assert_undefined_in("\x81", 'windows-874')
+ assert_undefined_in("\x84", 'windows-874')
check_both_ways("\u2026", "\x85", 'windows-874') # …
- assert_raise(Encoding::UndefinedConversionError) { "\x86".encode("utf-8", 'windows-874') }
- assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-874') }
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-874') }
+ assert_undefined_in("\x86", 'windows-874')
+ assert_undefined_in("\x8F", 'windows-874')
+ assert_undefined_in("\x90", 'windows-874')
check_both_ways("\u2018", "\x91", 'windows-874') # ‘
check_both_ways("\u2014", "\x97", 'windows-874') # —
- assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-874') }
- assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-874') }
+ assert_undefined_in("\x98", 'windows-874')
+ assert_undefined_in("\x9F", 'windows-874')
check_both_ways("\u00A0", "\xA0", 'windows-874') # non-breaking space
check_both_ways("\u0E0F", "\xAF", 'windows-874') # ฏ
check_both_ways("\u0E10", "\xB0", 'windows-874') # ฐ
@@ -206,31 +196,31 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u0E2F", "\xCF", 'windows-874') # ฯ
check_both_ways("\u0E30", "\xD0", 'windows-874') # ะ
check_both_ways("\u0E3A", "\xDA", 'windows-874') # ฺ
- assert_raise(Encoding::UndefinedConversionError) { "\xDB".encode("utf-8", 'windows-874') }
- assert_raise(Encoding::UndefinedConversionError) { "\xDE".encode("utf-8", 'windows-874') }
+ assert_undefined_in("\xDB", 'windows-874')
+ assert_undefined_in("\xDE", 'windows-874')
check_both_ways("\u0E3F", "\xDF", 'windows-874') # ฿
check_both_ways("\u0E40", "\xE0", 'windows-874') # เ
check_both_ways("\u0E4F", "\xEF", 'windows-874') # ๏
check_both_ways("\u0E50", "\xF0", 'windows-874') # ๐
check_both_ways("\u0E5B", "\xFB", 'windows-874') # ๛
- assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", 'windows-874') }
- assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-874') }
+ assert_undefined_in("\xFC", 'windows-874')
+ assert_undefined_in("\xFF", 'windows-874')
end
def test_windows_1250
check_both_ways("\u20AC", "\x80", 'windows-1250') # €
- assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1250') }
+ assert_undefined_in("\x81", 'windows-1250')
check_both_ways("\u201A", "\x82", 'windows-1250') # ‚
- assert_raise(Encoding::UndefinedConversionError) { "\x83".encode("utf-8", 'windows-1250') }
+ assert_undefined_in("\x83", 'windows-1250')
check_both_ways("\u201E", "\x84", 'windows-1250') # „
check_both_ways("\u2021", "\x87", 'windows-1250') # ‡
- assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1250') }
+ assert_undefined_in("\x88", 'windows-1250')
check_both_ways("\u2030", "\x89", 'windows-1250') # ‰
check_both_ways("\u0179", "\x8F", 'windows-1250') # Ź
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1250') }
+ assert_undefined_in("\x90", 'windows-1250')
check_both_ways("\u2018", "\x91", 'windows-1250') # ‘
check_both_ways("\u2014", "\x97", 'windows-1250') # —
- assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1250') }
+ assert_undefined_in("\x98", 'windows-1250')
check_both_ways("\u2122", "\x99", 'windows-1250') # ™
check_both_ways("\u00A0", "\xA0", 'windows-1250') # non-breaking space
check_both_ways("\u017B", "\xAF", 'windows-1250') # Ż
@@ -251,7 +241,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u20AC", "\x88", 'windows-1251') # €
check_both_ways("\u040F", "\x8F", 'windows-1251') # Џ
check_both_ways("\u0452", "\x90", 'windows-1251') # ђ
- assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1251') }
+ assert_undefined_in("\x98", 'windows-1251')
check_both_ways("\u045F", "\x9F", 'windows-1251') # џ
check_both_ways("\u00A0", "\xA0", 'windows-1251') # non-breaking space
check_both_ways("\u0407", "\xAF", 'windows-1251') # Ї
@@ -269,16 +259,16 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_1252
check_both_ways("\u20AC", "\x80", 'windows-1252') # €
- assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1252') }
+ assert_undefined_in("\x81", 'windows-1252')
check_both_ways("\u201A", "\x82", 'windows-1252') # ‚
check_both_ways("\u0152", "\x8C", 'windows-1252') # >Œ
- assert_raise(Encoding::UndefinedConversionError) { "\x8D".encode("utf-8", 'windows-1252') }
+ assert_undefined_in("\x8D", 'windows-1252')
check_both_ways("\u017D", "\x8E", 'windows-1252') # Ž
- assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1252') }
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1252') }
+ assert_undefined_in("\x8F", 'windows-1252')
+ assert_undefined_in("\x90", 'windows-1252')
check_both_ways("\u2018", "\x91", 'windows-1252') #‘
check_both_ways("\u0153", "\x9C", 'windows-1252') # œ
- assert_raise(Encoding::UndefinedConversionError) { "\x9D".encode("utf-8", 'windows-1252') }
+ assert_undefined_in("\x9D", 'windows-1252')
check_both_ways("\u017E", "\x9E", 'windows-1252') # ž
check_both_ways("\u00A0", "\xA0", 'windows-1252') # non-breaking space
check_both_ways("\u00AF", "\xAF", 'windows-1252') # ¯
@@ -296,24 +286,24 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_1253
check_both_ways("\u20AC", "\x80", 'windows-1253') # €
- assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\x81", 'windows-1253')
check_both_ways("\u201A", "\x82", 'windows-1253') # ‚
check_both_ways("\u2021", "\x87", 'windows-1253') # ‡
- assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\x88", 'windows-1253')
check_both_ways("\u2030", "\x89", 'windows-1253') # ‰
- assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\x8A", 'windows-1253')
check_both_ways("\u2039", "\x8B", 'windows-1253') # ‹
- assert_raise(Encoding::UndefinedConversionError) { "\x8C".encode("utf-8", 'windows-1253') }
- assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1253') }
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\x8C", 'windows-1253')
+ assert_undefined_in("\x8F", 'windows-1253')
+ assert_undefined_in("\x90", 'windows-1253')
check_both_ways("\u2018", "\x91", 'windows-1253') # ‘
check_both_ways("\u2014", "\x97", 'windows-1253') # —
- assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\x98", 'windows-1253')
check_both_ways("\u2122", "\x99", 'windows-1253') # ™
- assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\x9A", 'windows-1253')
check_both_ways("\u203A", "\x9B", 'windows-1253') # ›
- assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1253') }
- assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\x9C", 'windows-1253')
+ assert_undefined_in("\x9F", 'windows-1253')
check_both_ways("\u00A0", "\xA0", 'windows-1253') # non-breaking space
check_both_ways("\u2015", "\xAF", 'windows-1253') # ―
check_both_ways("\u00B0", "\xB0", 'windows-1253') # °
@@ -322,28 +312,28 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u039F", "\xCF", 'windows-1253') # Ο
check_both_ways("\u03A0", "\xD0", 'windows-1253') # Π
check_both_ways("\u03A1", "\xD1", 'windows-1253') # Ρ
- assert_raise(Encoding::UndefinedConversionError) { "\xD2".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\xD2", 'windows-1253')
check_both_ways("\u03A3", "\xD3", 'windows-1253') # Σ
check_both_ways("\u03AF", "\xDF", 'windows-1253') # ί
check_both_ways("\u03B0", "\xE0", 'windows-1253') # ΰ
check_both_ways("\u03BF", "\xEF", 'windows-1253') # ο
check_both_ways("\u03C0", "\xF0", 'windows-1253') # π
check_both_ways("\u03CE", "\xFE", 'windows-1253') # ώ
- assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-1253') }
+ assert_undefined_in("\xFF", 'windows-1253')
end
def test_windows_1254
check_both_ways("\u20AC", "\x80", 'windows-1254') # €
- assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1254') }
+ assert_undefined_in("\x81", 'windows-1254')
check_both_ways("\u201A", "\x82", 'windows-1254') # ‚
check_both_ways("\u0152", "\x8C", 'windows-1254') # Œ
- assert_raise(Encoding::UndefinedConversionError) { "\x8D".encode("utf-8", 'windows-1254') }
- assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1254') }
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1254') }
+ assert_undefined_in("\x8D", 'windows-1254')
+ assert_undefined_in("\x8F", 'windows-1254')
+ assert_undefined_in("\x90", 'windows-1254')
check_both_ways("\u2018", "\x91", 'windows-1254') # ‘
check_both_ways("\u0153", "\x9C", 'windows-1254') # œ
- assert_raise(Encoding::UndefinedConversionError) { "\x9D".encode("utf-8", 'windows-1254') }
- assert_raise(Encoding::UndefinedConversionError) { "\x9E".encode("utf-8", 'windows-1254') }
+ assert_undefined_in("\x9D", 'windows-1254')
+ assert_undefined_in("\x9E", 'windows-1254')
check_both_ways("\u0178", "\x9F", 'windows-1254') # Ÿ
check_both_ways("\u00A0", "\xA0", 'windows-1254') # non-breaking space
check_both_ways("\u00AF", "\xAF", 'windows-1254') # ¯
@@ -361,20 +351,20 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_1255
check_both_ways("\u20AC", "\x80", 'windows-1255') # €
- assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1255') }
+ assert_undefined_in("\x81", 'windows-1255')
check_both_ways("\u201A", "\x82", 'windows-1255') # ‚
check_both_ways("\u2030", "\x89", 'windows-1255') # ‰
- assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1255') }
+ assert_undefined_in("\x8A", 'windows-1255')
check_both_ways("\u2039", "\x8B", 'windows-1255') # ‹
- assert_raise(Encoding::UndefinedConversionError) { "\x8C".encode("utf-8", 'windows-1255') }
- assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'windows-1255') }
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1255') }
+ assert_undefined_in("\x8C", 'windows-1255')
+ assert_undefined_in("\x8F", 'windows-1255')
+ assert_undefined_in("\x90", 'windows-1255')
check_both_ways("\u2018", "\x91", 'windows-1255') # ‘
check_both_ways("\u2122", "\x99", 'windows-1255') # ™
- assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1255') }
+ assert_undefined_in("\x9A", 'windows-1255')
check_both_ways("\u203A", "\x9B", 'windows-1255') # ›
- assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1255') }
- assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-1255') }
+ assert_undefined_in("\x9C", 'windows-1255')
+ assert_undefined_in("\x9F", 'windows-1255')
check_both_ways("\u00A0", "\xA0", 'windows-1255') # non-breaking space
check_both_ways("\u00A1", "\xA1", 'windows-1255') # ¡
check_both_ways("\u00D7", "\xAA", 'windows-1255') # ×
@@ -391,17 +381,17 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u05C0", "\xD0", 'windows-1255') # ׀
check_both_ways("\u05F3", "\xD7", 'windows-1255') # ׳
check_both_ways("\u05F4", "\xD8", 'windows-1255') # ״
- assert_raise(Encoding::UndefinedConversionError) { "\xD9".encode("utf-8", 'windows-1255') }
- assert_raise(Encoding::UndefinedConversionError) { "\xDF".encode("utf-8", 'windows-1255') }
+ assert_undefined_in("\xD9", 'windows-1255')
+ assert_undefined_in("\xDF", 'windows-1255')
check_both_ways("\u05D0", "\xE0", 'windows-1255') # א
check_both_ways("\u05DF", "\xEF", 'windows-1255') # ן
check_both_ways("\u05E0", "\xF0", 'windows-1255') # נ
check_both_ways("\u05EA", "\xFA", 'windows-1255') # ת
- assert_raise(Encoding::UndefinedConversionError) { "\xFB".encode("utf-8", 'windows-1255') }
- assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", 'windows-1255') }
+ assert_undefined_in("\xFB", 'windows-1255')
+ assert_undefined_in("\xFC", 'windows-1255')
check_both_ways("\u200E", "\xFD", 'windows-1255') # left-to-right mark
check_both_ways("\u200F", "\xFE", 'windows-1255') # right-to-left mark
- assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'windows-1255') }
+ assert_undefined_in("\xFF", 'windows-1255')
end
def test_windows_1256
@@ -429,35 +419,35 @@ class TestTranscode < Test::Unit::TestCase
def test_windows_1257
check_both_ways("\u20AC", "\x80", 'windows-1257') # €
- assert_raise(Encoding::UndefinedConversionError) { "\x81".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x81", 'windows-1257')
check_both_ways("\u201A", "\x82", 'windows-1257') # ‚
- assert_raise(Encoding::UndefinedConversionError) { "\x83".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x83", 'windows-1257')
check_both_ways("\u201E", "\x84", 'windows-1257') # „
check_both_ways("\u2021", "\x87", 'windows-1257') # ‡
- assert_raise(Encoding::UndefinedConversionError) { "\x88".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x88", 'windows-1257')
check_both_ways("\u2030", "\x89", 'windows-1257') # ‰
- assert_raise(Encoding::UndefinedConversionError) { "\x8A".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x8A", 'windows-1257')
check_both_ways("\u2039", "\x8B", 'windows-1257') # ‹
- assert_raise(Encoding::UndefinedConversionError) { "\x8C".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x8C", 'windows-1257')
check_both_ways("\u00A8", "\x8D", 'windows-1257') # ¨
check_both_ways("\u02C7", "\x8E", 'windows-1257') # ˇ
check_both_ways("\u00B8", "\x8F", 'windows-1257') # ¸
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x90", 'windows-1257')
check_both_ways("\u2018", "\x91", 'windows-1257') # ‘
check_both_ways("\u2014", "\x97", 'windows-1257') # —
- assert_raise(Encoding::UndefinedConversionError) { "\x98".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x98", 'windows-1257')
check_both_ways("\u2122", "\x99", 'windows-1257') # ™
- assert_raise(Encoding::UndefinedConversionError) { "\x9A".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x9A", 'windows-1257')
check_both_ways("\u203A", "\x9B", 'windows-1257') # ›
- assert_raise(Encoding::UndefinedConversionError) { "\x9C".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x9C", 'windows-1257')
check_both_ways("\u00AF", "\x9D", 'windows-1257') # ¯
check_both_ways("\u02DB", "\x9E", 'windows-1257') # ˛
- assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\x9F", 'windows-1257')
check_both_ways("\u00A0", "\xA0", 'windows-1257') # non-breaking space
- assert_raise(Encoding::UndefinedConversionError) { "\xA1".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\xA1", 'windows-1257')
check_both_ways("\u00A2", "\xA2", 'windows-1257') # ¢
check_both_ways("\u00A4", "\xA4", 'windows-1257') # ¤
- assert_raise(Encoding::UndefinedConversionError) { "\xA5".encode("utf-8", 'windows-1257') }
+ assert_undefined_in("\xA5", 'windows-1257')
check_both_ways("\u00A6", "\xA6", 'windows-1257') # ¦
check_both_ways("\u00C6", "\xAF", 'windows-1257') # Æ
check_both_ways("\u00B0", "\xB0", 'windows-1257') # °
@@ -492,9 +482,9 @@ class TestTranscode < Test::Unit::TestCase
end
def test_IBM720
- assert_raise(Encoding::UndefinedConversionError) { "\x80".encode("utf-8", 'IBM720') }
- assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'IBM720') }
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'IBM720') }
+ assert_undefined_in("\x80", 'IBM720')
+ assert_undefined_in("\x8F", 'IBM720')
+ assert_undefined_in("\x90", 'IBM720')
check_both_ways("\u0627", "\x9F", 'IBM720') # ا
check_both_ways("\u0628", "\xA0", 'IBM720') # ب
check_both_ways("\u00BB", "\xAF", 'IBM720') # »
@@ -580,17 +570,17 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u00A4", "\xCF", 'IBM857') # ¤
check_both_ways("\u00BA", "\xD0", 'IBM857') # º
check_both_ways("\u00C8", "\xD4", 'IBM857') # È
- assert_raise(Encoding::UndefinedConversionError) { "\xD5".encode("utf-8", 'IBM857') }
+ assert_undefined_in("\xD5", 'IBM857')
check_both_ways("\u00CD", "\xD6", 'IBM857') # Í
check_both_ways("\u2580", "\xDF", 'IBM857') # ▀
check_both_ways("\u00D3", "\xE0", 'IBM857') # Ó
check_both_ways("\u00B5", "\xE6", 'IBM857') # µ
- assert_raise(Encoding::UndefinedConversionError) { "\xE7".encode("utf-8", 'IBM857') }
+ assert_undefined_in("\xE7", 'IBM857')
check_both_ways("\u00D7", "\xE8", 'IBM857') # ×
check_both_ways("\u00B4", "\xEF", 'IBM857') # ´
check_both_ways("\u00AD", "\xF0", 'IBM857') # soft hyphen
check_both_ways("\u00B1", "\xF1", 'IBM857') # ±
- assert_raise(Encoding::UndefinedConversionError) { "\xF2".encode("utf-8", 'IBM857') }
+ assert_undefined_in("\xF2", 'IBM857')
check_both_ways("\u00BE", "\xF3", 'IBM857') # ¾
check_both_ways("\u00A0", "\xFF", 'IBM857') # non-breaking space
end
@@ -710,16 +700,16 @@ class TestTranscode < Test::Unit::TestCase
end
def test_IBM869
- assert_raise(Encoding::UndefinedConversionError) { "\x80".encode("utf-8", 'IBM869') }
- assert_raise(Encoding::UndefinedConversionError) { "\x85".encode("utf-8", 'IBM869') }
+ assert_undefined_in("\x80", 'IBM869')
+ assert_undefined_in("\x85", 'IBM869')
check_both_ways("\u0386", "\x86", 'IBM869') # Ά
- assert_raise(Encoding::UndefinedConversionError) { "\x87".encode("utf-8", 'IBM869') }
+ assert_undefined_in("\x87", 'IBM869')
check_both_ways("\u00B7", "\x88", 'IBM869') # ·
check_both_ways("\u0389", "\x8F", 'IBM869') # Ή
check_both_ways("\u038A", "\x90", 'IBM869') # Ί
check_both_ways("\u038C", "\x92", 'IBM869') # Ό
- assert_raise(Encoding::UndefinedConversionError) { "\x93".encode("utf-8", 'IBM869') }
- assert_raise(Encoding::UndefinedConversionError) { "\x94".encode("utf-8", 'IBM869') }
+ assert_undefined_in("\x93", 'IBM869')
+ assert_undefined_in("\x94", 'IBM869')
check_both_ways("\u038E", "\x95", 'IBM869') # Ύ
check_both_ways("\u03AF", "\x9F", 'IBM869') # ί
check_both_ways("\u03CA", "\xA0", 'IBM869') # ϊ
@@ -808,7 +798,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u03BF", "\xEF", 'macGreek') # ο
check_both_ways("\u03C0", "\xF0", 'macGreek') # π
check_both_ways("\u03B0", "\xFE", 'macGreek') # ΰ
- assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'macGreek') }
+ assert_undefined_in("\xFF", 'macGreek')
end
def test_macIceland
@@ -887,7 +877,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u00D4", "\xEF", 'macTurkish') # Ô
#check_both_ways("\uF8FF", "\xF0", 'macTurkish') # Apple logo
check_both_ways("\u00D9", "\xF4", 'macTurkish') # Ù
- assert_raise(Encoding::UndefinedConversionError) { "\xF5".encode("utf-8", 'macTurkish') }
+ assert_undefined_in("\xF5", 'macTurkish')
check_both_ways("\u02C6", "\xF6", 'macTurkish') # ˆ
check_both_ways("\u02C7", "\xFF", 'macTurkish') # ˇ
end
@@ -958,11 +948,11 @@ class TestTranscode < Test::Unit::TestCase
end
def test_TIS_620
- assert_raise(Encoding::UndefinedConversionError) { "\x80".encode("utf-8", 'TIS-620') }
- assert_raise(Encoding::UndefinedConversionError) { "\x8F".encode("utf-8", 'TIS-620') }
- assert_raise(Encoding::UndefinedConversionError) { "\x90".encode("utf-8", 'TIS-620') }
- assert_raise(Encoding::UndefinedConversionError) { "\x9F".encode("utf-8", 'TIS-620') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA0".encode("utf-8", 'TIS-620') }
+ assert_undefined_in("\x80", 'TIS-620')
+ assert_undefined_in("\x8F", 'TIS-620')
+ assert_undefined_in("\x90", 'TIS-620')
+ assert_undefined_in("\x9F", 'TIS-620')
+ assert_undefined_in("\xA0", 'TIS-620')
check_both_ways("\u0E01", "\xA1", 'TIS-620') # ก
check_both_ways("\u0E0F", "\xAF", 'TIS-620') # ฏ
check_both_ways("\u0E10", "\xB0", 'TIS-620') # ฐ
@@ -971,15 +961,15 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u0E2F", "\xCF", 'TIS-620') # ฯ
check_both_ways("\u0E30", "\xD0", 'TIS-620') # ะ
check_both_ways("\u0E3A", "\xDA", 'TIS-620') # ฺ
- assert_raise(Encoding::UndefinedConversionError) { "\xDB".encode("utf-8", 'TIS-620') }
- assert_raise(Encoding::UndefinedConversionError) { "\xDE".encode("utf-8", 'TIS-620') }
+ assert_undefined_in("\xDB", 'TIS-620')
+ assert_undefined_in("\xDE", 'TIS-620')
check_both_ways("\u0E3F", "\xDF", 'TIS-620') # ฿
check_both_ways("\u0E40", "\xE0", 'TIS-620') # เ
check_both_ways("\u0E4F", "\xEF", 'TIS-620') # ๏
check_both_ways("\u0E50", "\xF0", 'TIS-620') # ๐
check_both_ways("\u0E5B", "\xFB", 'TIS-620') # ๛
- assert_raise(Encoding::UndefinedConversionError) { "\xFC".encode("utf-8", 'TIS-620') }
- assert_raise(Encoding::UndefinedConversionError) { "\xFF".encode("utf-8", 'TIS-620') }
+ assert_undefined_in("\xFC", 'TIS-620')
+ assert_undefined_in("\xFF", 'TIS-620')
end
def test_CP850
@@ -1182,15 +1172,15 @@ class TestTranscode < Test::Unit::TestCase
expected = "\u{3042}\u{3044}\u{20bb7}"
assert_equal(expected, %w/fffe4230443042d8b7df/.pack("H*").encode("UTF-8","UTF-16"))
check_both_ways(expected, %w/feff30423044d842dfb7/.pack("H*"), "UTF-16")
- assert_raise(Encoding::InvalidByteSequenceError){%w/feffdfb7/.pack("H*").encode("UTF-8","UTF-16")}
- assert_raise(Encoding::InvalidByteSequenceError){%w/fffeb7df/.pack("H*").encode("UTF-8","UTF-16")}
+ assert_invalid_in(%w/feffdfb7/.pack("H*"), "UTF-16")
+ assert_invalid_in(%w/fffeb7df/.pack("H*"), "UTF-16")
end
def test_utf_32_bom
expected = "\u{3042}\u{3044}\u{20bb7}"
assert_equal(expected, %w/fffe00004230000044300000b70b0200/.pack("H*").encode("UTF-8","UTF-32"))
check_both_ways(expected, %w/0000feff000030420000304400020bb7/.pack("H*"), "UTF-32")
- assert_raise(Encoding::InvalidByteSequenceError){%w/0000feff00110000/.pack("H*").encode("UTF-8","UTF-32")}
+ assert_invalid_in(%w/0000feff00110000/.pack("H*"), "UTF-32")
end
def check_utf_32_both_ways(utf8, raw)
@@ -1372,24 +1362,24 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u71FC", "\xE0\x9E", 'shift_jis') # 燼
check_both_ways("\u71F9", "\xE0\x9F", 'shift_jis') # 燹
check_both_ways("\u73F1", "\xE0\xFC", 'shift_jis') # 珱
- assert_raise(Encoding::UndefinedConversionError) { "\xEF\x40".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xEF\x7E".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xEF\x80".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xEF\x9E".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xEF\x9F".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xEF\xFC".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xF0\x40".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xF0\x7E".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xF0\x80".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xF0\x9E".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xF0\x9F".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xF0\xFC".encode("utf-8", 'shift_jis') }
+ assert_undefined_in("\xEF\x40", 'shift_jis')
+ assert_undefined_in("\xEF\x7E", 'shift_jis')
+ assert_undefined_in("\xEF\x80", 'shift_jis')
+ assert_undefined_in("\xEF\x9E", 'shift_jis')
+ assert_undefined_in("\xEF\x9F", 'shift_jis')
+ assert_undefined_in("\xEF\xFC", 'shift_jis')
+ assert_undefined_in("\xF0\x40", 'shift_jis')
+ assert_undefined_in("\xF0\x7E", 'shift_jis')
+ assert_undefined_in("\xF0\x80", 'shift_jis')
+ assert_undefined_in("\xF0\x9E", 'shift_jis')
+ assert_undefined_in("\xF0\x9F", 'shift_jis')
+ assert_undefined_in("\xF0\xFC", 'shift_jis')
#check_both_ways("\u9ADC", "\xFC\x40", 'shift_jis') # 髜 (IBM extended)
- assert_raise(Encoding::UndefinedConversionError) { "\xFC\x7E".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xFC\x80".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xFC\x9E".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xFC\x9F".encode("utf-8", 'shift_jis') }
- assert_raise(Encoding::UndefinedConversionError) { "\xFC\xFC".encode("utf-8", 'shift_jis') }
+ assert_undefined_in("\xFC\x7E", 'shift_jis')
+ assert_undefined_in("\xFC\x80", 'shift_jis')
+ assert_undefined_in("\xFC\x9E", 'shift_jis')
+ assert_undefined_in("\xFC\x9F", 'shift_jis')
+ assert_undefined_in("\xFC\xFC", 'shift_jis')
check_both_ways("\u677E\u672C\u884C\u5F18", "\x8f\xbc\x96\x7b\x8d\x73\x8d\x4f", 'shift_jis') # 松本行弘
check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\x90\xC2\x8E\x52\x8A\x77\x89\x40\x91\xE5\x8A\x77", 'shift_jis') # 青山学院大学
check_both_ways("\u795E\u6797\u7FA9\u535A", "\x90\x5F\x97\xD1\x8B\x60\x94\x8E", 'shift_jis') # 神林義博
@@ -1409,34 +1399,34 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u00F7", "\xA1\xE0", 'euc-jp') # ÷
check_both_ways("\u25C7", "\xA1\xFE", 'euc-jp') # ◇
check_both_ways("\u25C6", "\xA2\xA1", 'euc-jp') # ◆
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xAF".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB9".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xC2".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xC9".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xD1".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xDB".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xEB".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF1".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xFA".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xFD".encode("utf-8", 'euc-jp') }
+ assert_undefined_in("\xA2\xAF", 'euc-jp')
+ assert_undefined_in("\xA2\xB9", 'euc-jp')
+ assert_undefined_in("\xA2\xC2", 'euc-jp')
+ assert_undefined_in("\xA2\xC9", 'euc-jp')
+ assert_undefined_in("\xA2\xD1", 'euc-jp')
+ assert_undefined_in("\xA2\xDB", 'euc-jp')
+ assert_undefined_in("\xA2\xEB", 'euc-jp')
+ assert_undefined_in("\xA2\xF1", 'euc-jp')
+ assert_undefined_in("\xA2\xFA", 'euc-jp')
+ assert_undefined_in("\xA2\xFD", 'euc-jp')
check_both_ways("\u25EF", "\xA2\xFE", 'euc-jp') # ◯
- assert_raise(Encoding::UndefinedConversionError) { "\xA3\xAF".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA3\xBA".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA3\xC0".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA3\xDB".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA3\xE0".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA3\xFB".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA4\xF4".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA5\xF7".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA6\xB9".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA6\xC0".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA6\xD9".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA7\xC2".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA7\xD0".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA7\xF2".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC1".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xCF\xD4".encode("utf-8", 'euc-jp') }
- assert_raise(Encoding::UndefinedConversionError) { "\xCF\xFE".encode("utf-8", 'euc-jp') }
+ assert_undefined_in("\xA3\xAF", 'euc-jp')
+ assert_undefined_in("\xA3\xBA", 'euc-jp')
+ assert_undefined_in("\xA3\xC0", 'euc-jp')
+ assert_undefined_in("\xA3\xDB", 'euc-jp')
+ assert_undefined_in("\xA3\xE0", 'euc-jp')
+ assert_undefined_in("\xA3\xFB", 'euc-jp')
+ assert_undefined_in("\xA4\xF4", 'euc-jp')
+ assert_undefined_in("\xA5\xF7", 'euc-jp')
+ assert_undefined_in("\xA6\xB9", 'euc-jp')
+ assert_undefined_in("\xA6\xC0", 'euc-jp')
+ assert_undefined_in("\xA6\xD9", 'euc-jp')
+ assert_undefined_in("\xA7\xC2", 'euc-jp')
+ assert_undefined_in("\xA7\xD0", 'euc-jp')
+ assert_undefined_in("\xA7\xF2", 'euc-jp')
+ assert_undefined_in("\xA8\xC1", 'euc-jp')
+ assert_undefined_in("\xCF\xD4", 'euc-jp')
+ assert_undefined_in("\xCF\xFE", 'euc-jp')
check_both_ways("\u6A97", "\xDD\xA1", 'euc-jp') # 檗
check_both_ways("\u6BEF", "\xDD\xDF", 'euc-jp') # 毯
check_both_ways("\u9EBE", "\xDD\xE0", 'euc-jp') # 麾
@@ -1449,7 +1439,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u71FC", "\xDF\xFE", 'euc-jp') # 燼
check_both_ways("\u71F9", "\xE0\xA1", 'euc-jp') # 燹
check_both_ways("\u73F1", "\xE0\xFE", 'euc-jp') # 珱
- assert_raise(Encoding::UndefinedConversionError) { "\xF4\xA7".encode("utf-8", 'euc-jp') }
+ assert_undefined_in("\xF4\xA7", 'euc-jp')
#check_both_ways("\u9ADC", "\xFC\xE3", 'euc-jp') # 髜 (IBM extended)
check_both_ways("\u677E\u672C\u884C\u5F18", "\xBE\xBE\xCB\xDC\xB9\xD4\xB9\xB0", 'euc-jp') # 松本行弘
@@ -1481,7 +1471,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u2127", "\xA3\xE0", 'euc-jis-2004') # ℧
check_both_ways("\u30A0", "\xA3\xFB", 'euc-jis-2004') # ゠
check_both_ways("\uFF54", "\xA3\xF4", 'euc-jis-2004') # t
- assert_raise(Encoding::UndefinedConversionError) { "\xA5\xF7".encode("utf-8", 'euc-jis-2004') }
+ assert_undefined_in("\xA5\xF7", 'euc-jis-2004')
check_both_ways("\u2664", "\xA6\xB9", 'euc-jis-2004') # ♤
check_both_ways("\u2663", "\xA6\xC0", 'euc-jis-2004') # ♣
check_both_ways("\u03C2", "\xA6\xD9", 'euc-jis-2004') # ς
@@ -1566,33 +1556,33 @@ class TestTranscode < Test::Unit::TestCase
end
def test_eucjp_sjis_undef
- assert_raise(Encoding::UndefinedConversionError) { "\x8e\xe0".encode("Shift_JIS", "EUC-JP") }
- assert_raise(Encoding::UndefinedConversionError) { "\x8e\xfe".encode("Shift_JIS", "EUC-JP") }
- assert_raise(Encoding::UndefinedConversionError) { "\x8f\xa1\xa1".encode("Shift_JIS", "EUC-JP") }
- assert_raise(Encoding::UndefinedConversionError) { "\x8f\xa1\xfe".encode("Shift_JIS", "EUC-JP") }
- assert_raise(Encoding::UndefinedConversionError) { "\x8f\xfe\xa1".encode("Shift_JIS", "EUC-JP") }
- assert_raise(Encoding::UndefinedConversionError) { "\x8f\xfe\xfe".encode("Shift_JIS", "EUC-JP") }
-
- assert_raise(Encoding::UndefinedConversionError) { "\xf0\x40".encode("EUC-JP", "Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\xf0\x7e".encode("EUC-JP", "Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\xf0\x80".encode("EUC-JP", "Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\xf0\xfc".encode("EUC-JP", "Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\xfc\x40".encode("EUC-JP", "Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\xfc\x7e".encode("EUC-JP", "Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\xfc\x80".encode("EUC-JP", "Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\xfc\xfc".encode("EUC-JP", "Shift_JIS") }
+ assert_undefined_conversion("\x8e\xe0", "Shift_JIS", "EUC-JP")
+ assert_undefined_conversion("\x8e\xfe", "Shift_JIS", "EUC-JP")
+ assert_undefined_conversion("\x8f\xa1\xa1", "Shift_JIS", "EUC-JP")
+ assert_undefined_conversion("\x8f\xa1\xfe", "Shift_JIS", "EUC-JP")
+ assert_undefined_conversion("\x8f\xfe\xa1", "Shift_JIS", "EUC-JP")
+ assert_undefined_conversion("\x8f\xfe\xfe", "Shift_JIS", "EUC-JP")
+
+ assert_undefined_conversion("\xf0\x40", "EUC-JP", "Shift_JIS")
+ assert_undefined_conversion("\xf0\x7e", "EUC-JP", "Shift_JIS")
+ assert_undefined_conversion("\xf0\x80", "EUC-JP", "Shift_JIS")
+ assert_undefined_conversion("\xf0\xfc", "EUC-JP", "Shift_JIS")
+ assert_undefined_conversion("\xfc\x40", "EUC-JP", "Shift_JIS")
+ assert_undefined_conversion("\xfc\x7e", "EUC-JP", "Shift_JIS")
+ assert_undefined_conversion("\xfc\x80", "EUC-JP", "Shift_JIS")
+ assert_undefined_conversion("\xfc\xfc", "EUC-JP", "Shift_JIS")
end
def test_iso_2022_jp
- assert_raise(Encoding::InvalidByteSequenceError) { "\x1b(A".encode("utf-8", "iso-2022-jp") }
- assert_raise(Encoding::InvalidByteSequenceError) { "\x1b$(A".encode("utf-8", "iso-2022-jp") }
- assert_raise(Encoding::InvalidByteSequenceError) { "\x1b$C".encode("utf-8", "iso-2022-jp") }
- assert_raise(Encoding::InvalidByteSequenceError) { "\x0e".encode("utf-8", "iso-2022-jp") }
- assert_raise(Encoding::InvalidByteSequenceError) { "\x80".encode("utf-8", "iso-2022-jp") }
- assert_raise(Encoding::InvalidByteSequenceError) { "\x1b$(Dd!\x1b(B".encode("utf-8", "iso-2022-jp") }
- assert_raise(Encoding::UndefinedConversionError) { "\u9299".encode("iso-2022-jp") }
- assert_raise(Encoding::UndefinedConversionError) { "\uff71\uff72\uff73\uff74\uff75".encode("iso-2022-jp") }
- assert_raise(Encoding::InvalidByteSequenceError) { "\x1b(I12345\x1b(B".encode("utf-8", "iso-2022-jp") }
+ assert_invalid_in("\x1b(A", "iso-2022-jp")
+ assert_invalid_in("\x1b$(A", "iso-2022-jp")
+ assert_invalid_in("\x1b$C", "iso-2022-jp")
+ assert_invalid_in("\x0e", "iso-2022-jp")
+ assert_invalid_in("\x80", "iso-2022-jp")
+ assert_invalid_in("\x1b$(Dd!\x1b(B", "iso-2022-jp")
+ assert_undefined_conversion("\u9299", "iso-2022-jp")
+ assert_undefined_conversion("\uff71\uff72\uff73\uff74\uff75", "iso-2022-jp")
+ assert_invalid_in("\x1b(I12345\x1b(B", "iso-2022-jp")
assert_equal("\xA1\xA1".force_encoding("euc-jp"),
"\e$B!!\e(B".encode("EUC-JP", "ISO-2022-JP"))
assert_equal("\e$B!!\e(B".force_encoding("ISO-2022-JP"),
@@ -1655,11 +1645,11 @@ class TestTranscode < Test::Unit::TestCase
assert_equal("\u005C", "\e(J\x5C\e(B".encode("UTF-8", "ISO-2022-JP"))
assert_equal("\u005C", "\x5C".encode("stateless-ISO-2022-JP", "ISO-2022-JP"))
assert_equal("\u005C", "\e(J\x5C\e(B".encode("stateless-ISO-2022-JP", "ISO-2022-JP"))
- assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("Windows-31J") }
- assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("EUC-JP") }
- assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("eucJP-ms") }
- assert_raise(Encoding::UndefinedConversionError) { "\u00A5".encode("CP51932") }
+ assert_undefined_conversion("\u00A5", "Shift_JIS")
+ assert_undefined_conversion("\u00A5", "Windows-31J")
+ assert_undefined_conversion("\u00A5", "EUC-JP")
+ assert_undefined_conversion("\u00A5", "eucJP-ms")
+ assert_undefined_conversion("\u00A5", "CP51932")
# FULLWIDTH REVERSE SOLIDUS
check_both_ways("\uFF3C", "\x81\x5F", "Shift_JIS")
@@ -1680,21 +1670,21 @@ class TestTranscode < Test::Unit::TestCase
assert_equal("\u007E", "\e(J\x7E\e(B".encode("UTF-8", "ISO-2022-JP"))
assert_equal("\u007E", "\x7E".encode("stateless-ISO-2022-JP", "ISO-2022-JP"))
assert_equal("\u007E", "\e(J\x7E\e(B".encode("stateless-ISO-2022-JP", "ISO-2022-JP"))
- assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("Shift_JIS") }
- assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("Windows-31J") }
- assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("EUC-JP") }
- assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("eucJP-ms") }
- assert_raise(Encoding::UndefinedConversionError) { "\u203E".encode("CP51932") }
+ assert_undefined_conversion("\u203E", "Shift_JIS")
+ assert_undefined_conversion("\u203E", "Windows-31J")
+ assert_undefined_conversion("\u203E", "EUC-JP")
+ assert_undefined_conversion("\u203E", "eucJP-ms")
+ assert_undefined_conversion("\u203E", "CP51932")
end
def test_gb2312
check_both_ways("\u3000", "\xA1\xA1", 'GB2312') # full-width space
check_both_ways("\u3013", "\xA1\xFE", 'GB2312') # 〓
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GB2312') }
+ assert_undefined_in("\xA2\xB0", 'GB2312')
check_both_ways("\u2488", "\xA2\xB1", 'GB2312') # ⒈
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GB2312') }
+ assert_undefined_in("\xA2\xE4", 'GB2312')
check_both_ways("\u3220", "\xA2\xE5", 'GB2312') # ㈠
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GB2312') }
+ assert_undefined_in("\xA2\xF0", 'GB2312')
check_both_ways("\u2160", "\xA2\xF1", 'GB2312') # Ⅰ
check_both_ways("\uFF01", "\xA3\xA1", 'GB2312') # !
check_both_ways("\uFFE3", "\xA3\xFE", 'GB2312') #  ̄
@@ -1705,9 +1695,9 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u0410", "\xA7\xA1", 'GB2312') # А
check_both_ways("\u0430", "\xA7\xD1", 'GB2312') # а
check_both_ways("\u0101", "\xA8\xA1", 'GB2312') # ā
- assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC4".encode("utf-8", 'GB2312') }
+ assert_undefined_in("\xA8\xC4", 'GB2312')
check_both_ways("\u3105", "\xA8\xC5", 'GB2312') # ㄅ
- assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GB2312') }
+ assert_undefined_in("\xA9\xA3", 'GB2312')
check_both_ways("\u2500", "\xA9\xA4", 'GB2312') # ─
check_both_ways("\u554A", "\xB0\xA1", 'GB2312') # 啊
check_both_ways("\u5265", "\xB0\xFE", 'GB2312') # 剥
@@ -1721,7 +1711,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u7384", "\xD0\xFE", 'GB2312') # 玄
check_both_ways("\u4F4F", "\xD7\xA1", 'GB2312') # 住
check_both_ways("\u5EA7", "\xD7\xF9", 'GB2312') # 座
- assert_raise(Encoding::UndefinedConversionError) { "\xD7\xFA".encode("utf-8", 'GB2312') }
+ assert_undefined_in("\xD7\xFA", 'GB2312')
check_both_ways("\u647A", "\xDF\xA1", 'GB2312') # 摺
check_both_ways("\u553C", "\xDF\xFE", 'GB2312') # 唼
check_both_ways("\u5537", "\xE0\xA1", 'GB2312') # 唷
@@ -1759,48 +1749,48 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u3000", "\xA1\xA1", 'GBK') # full-width space
check_both_ways("\u3001", "\xA1\xA2", 'GBK') # 、
check_both_ways("\u3013", "\xA1\xFE", 'GBK') # 〓
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xA0".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA2\xA0", 'GBK')
check_both_ways("\u2170", "\xA2\xA1", 'GBK') # ⅰ
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA2\xB0", 'GBK')
check_both_ways("\u2488", "\xA2\xB1", 'GBK') # ⒈
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA2\xE4", 'GBK')
check_both_ways("\u3220", "\xA2\xE5", 'GBK') # ㈠
- assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA2\xF0", 'GBK')
check_both_ways("\u2160", "\xA2\xF1", 'GBK') # Ⅰ
- assert_raise(Encoding::UndefinedConversionError) { "\xA3\xA0".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA3\xA0", 'GBK')
check_both_ways("\uFF01", "\xA3\xA1", 'GBK') # !
check_both_ways("\uFFE3", "\xA3\xFE", 'GBK') #  ̄
- assert_raise(Encoding::UndefinedConversionError) { "\xA4\xA0".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA4\xA0", 'GBK')
check_both_ways("\u3041", "\xA4\xA1", 'GBK') # ぁ
- assert_raise(Encoding::UndefinedConversionError) { "\xA5\xA0".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA5\xA0", 'GBK')
check_both_ways("\u30A1", "\xA5\xA1", 'GBK') # ァ
check_both_ways("\u0391", "\xA6\xA1", 'GBK') # Α
check_both_ways("\u03B1", "\xA6\xC1", 'GBK') # α
- assert_raise(Encoding::UndefinedConversionError) { "\xA6\xED".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA6\xED", 'GBK')
check_both_ways("\uFE3B", "\xA6\xEE", 'GBK') # ︻
check_both_ways("\u0410", "\xA7\xA1", 'GBK') # А
check_both_ways("\u0430", "\xA7\xD1", 'GBK') # а
check_both_ways("\u02CA", "\xA8\x40", 'GBK') # ˊ
check_both_ways("\u2587", "\xA8\x7E", 'GBK') # ▇
- assert_raise(Encoding::UndefinedConversionError) { "\xA8\x96".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA8\x96", 'GBK')
check_both_ways("\u0101", "\xA8\xA1", 'GBK') # ā
- assert_raise(Encoding::UndefinedConversionError) { "\xA8\xBC".encode("utf-8", 'GBK') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA8\xBF".encode("utf-8", 'GBK') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC4".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA8\xBC", 'GBK')
+ assert_undefined_in("\xA8\xBF", 'GBK')
+ assert_undefined_in("\xA8\xC4", 'GBK')
check_both_ways("\u3105", "\xA8\xC5", 'GBK') # ㄅ
check_both_ways("\u3021", "\xA9\x40", 'GBK') # 〡
- assert_raise(Encoding::UndefinedConversionError) { "\xA9\x58".encode("utf-8", 'GBK') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA9\x5B".encode("utf-8", 'GBK') }
- assert_raise(Encoding::UndefinedConversionError) { "\xA9\x5D".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA9\x58", 'GBK')
+ assert_undefined_in("\xA9\x5B", 'GBK')
+ assert_undefined_in("\xA9\x5D", 'GBK')
check_both_ways("\u3007", "\xA9\x96", 'GBK') # 〇
- assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA9\xA3", 'GBK')
check_both_ways("\u2500", "\xA9\xA4", 'GBK') # ─
- assert_raise(Encoding::UndefinedConversionError) { "\xA9\xF0".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xA9\xF0", 'GBK')
check_both_ways("\u7588", "\xAF\x40", 'GBK') # 疈
check_both_ways("\u7607", "\xAF\x7E", 'GBK') # 瘇
check_both_ways("\u7608", "\xAF\x80", 'GBK') # 瘈
check_both_ways("\u7644", "\xAF\xA0", 'GBK') # 癄
- assert_raise(Encoding::UndefinedConversionError) { "\xAF\xA1".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xAF\xA1", 'GBK')
check_both_ways("\u7645", "\xB0\x40", 'GBK') # 癅
check_both_ways("\u769B", "\xB0\x7E", 'GBK') # 皛
check_both_ways("\u769C", "\xB0\x80", 'GBK') # 皜
@@ -1841,10 +1831,10 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u9F78", "\xFD\x7E", 'GBK') # 齸
check_both_ways("\u9F79", "\xFD\x80", 'GBK') # 齹
check_both_ways("\uF9F1", "\xFD\xA0", 'GBK') # 隣
- assert_raise(Encoding::UndefinedConversionError) { "\xFD\xA1".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xFD\xA1", 'GBK')
check_both_ways("\uFA0C", "\xFE\x40", 'GBK') # 兀
check_both_ways("\uFA29", "\xFE\x4F", 'GBK') # 﨩
- assert_raise(Encoding::UndefinedConversionError) { "\xFE\x50".encode("utf-8", 'GBK') }
+ assert_undefined_in("\xFE\x50", 'GBK')
check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\xC7\xE0\xC9\xBD\xD1\xA7\xD4\xBA\xB4\xF3\xD1\xA7", 'GBK') # 青山学院大学
check_both_ways("\u795E\u6797\u7FA9\u535A", "\xC9\xF1\xC1\xD6\xC1\x78\xB2\xA9", 'GBK') # 神林義博
end
@@ -1880,48 +1870,48 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u3000", "\xA1\xA1", 'GB18030') # full-width space
check_both_ways("\u3001", "\xA1\xA2", 'GB18030') #
check_both_ways("\u3013", "\xA1\xFE", 'GB18030') #
- #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xA0".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA2\xA0", 'GB18030')
check_both_ways("\u2170", "\xA2\xA1", 'GB18030') # ⅰ
- #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xB0".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA2\xB0", 'GB18030')
check_both_ways("\u2488", "\xA2\xB1", 'GB18030') #
- #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xE4".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA2\xE4", 'GB18030')
check_both_ways("\u3220", "\xA2\xE5", 'GB18030') # ㈠
- #assert_raise(Encoding::UndefinedConversionError) { "\xA2\xF0".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA2\xF0", 'GB18030')
check_both_ways("\u2160", "\xA2\xF1", 'GB18030') # Ⅰ
- #assert_raise(Encoding::UndefinedConversionError) { "\xA3\xA0".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA3\xA0", 'GB18030')
check_both_ways("\uFF01", "\xA3\xA1", 'GB18030') # E
check_both_ways("\uFFE3", "\xA3\xFE", 'GB18030') # E
- #assert_raise(Encoding::UndefinedConversionError) { "\xA4\xA0".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA4\xA0", 'GB18030')
check_both_ways("\u3041", "\xA4\xA1", 'GB18030') #
- #assert_raise(Encoding::UndefinedConversionError) { "\xA5\xA0".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA5\xA0", 'GB18030')
check_both_ways("\u30A1", "\xA5\xA1", 'GB18030') # ァ
check_both_ways("\u0391", "\xA6\xA1", 'GB18030') #
check_both_ways("\u03B1", "\xA6\xC1", 'GB18030') # α
- #assert_raise(Encoding::UndefinedConversionError) { "\xA6\xED".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA6\xED", 'GB18030')
check_both_ways("\uFE3B", "\xA6\xEE", 'GB18030') # E
check_both_ways("\u0410", "\xA7\xA1", 'GB18030') #
check_both_ways("\u0430", "\xA7\xD1", 'GB18030') # а
check_both_ways("\u02CA", "\xA8\x40", 'GB18030') #
check_both_ways("\u2587", "\xA8\x7E", 'GB18030') #
- #assert_raise(Encoding::UndefinedConversionError) { "\xA8\x96".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA8\x96", 'GB18030')
check_both_ways("\u0101", "\xA8\xA1", 'GB18030') #
- #assert_raise(Encoding::UndefinedConversionError) { "\xA8\xBC".encode("utf-8", 'GB18030') }
- #assert_raise(Encoding::UndefinedConversionError) { "\xA8\xBF".encode("utf-8", 'GB18030') }
- #assert_raise(Encoding::UndefinedConversionError) { "\xA8\xC4".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA8\xBC", 'GB18030')
+ #assert_undefined_in("\xA8\xBF", 'GB18030')
+ #assert_undefined_in("\xA8\xC4", 'GB18030')
check_both_ways("\u3105", "\xA8\xC5", 'GB18030') #
check_both_ways("\u3021", "\xA9\x40", 'GB18030') # 〡
- #assert_raise(Encoding::UndefinedConversionError) { "\xA9\x58".encode("utf-8", 'GB18030') }
- #assert_raise(Encoding::UndefinedConversionError) { "\xA9\x5B".encode("utf-8", 'GB18030') }
- #assert_raise(Encoding::UndefinedConversionError) { "\xA9\x5D".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA9\x58", 'GB18030')
+ #assert_undefined_in("\xA9\x5B", 'GB18030')
+ #assert_undefined_in("\xA9\x5D", 'GB18030')
check_both_ways("\u3007", "\xA9\x96", 'GB18030') #
- #assert_raise(Encoding::UndefinedConversionError) { "\xA9\xA3".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA9\xA3", 'GB18030')
check_both_ways("\u2500", "\xA9\xA4", 'GB18030') # ─
- #assert_raise(Encoding::UndefinedConversionError) { "\xA9\xF0".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xA9\xF0", 'GB18030')
check_both_ways("\u7588", "\xAF\x40", 'GB18030') #
check_both_ways("\u7607", "\xAF\x7E", 'GB18030') #
check_both_ways("\u7608", "\xAF\x80", 'GB18030') #
check_both_ways("\u7644", "\xAF\xA0", 'GB18030') #
- #assert_raise(Encoding::UndefinedConversionError) { "\xAF\xA1".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xAF\xA1", 'GB18030')
check_both_ways("\u7645", "\xB0\x40", 'GB18030') #
check_both_ways("\u769B", "\xB0\x7E", 'GB18030') #
check_both_ways("\u769C", "\xB0\x80", 'GB18030') #
@@ -1962,10 +1952,10 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u9F78", "\xFD\x7E", 'GB18030') # 齸
check_both_ways("\u9F79", "\xFD\x80", 'GB18030') # 齹
check_both_ways("\uF9F1", "\xFD\xA0", 'GB18030') # E
- #assert_raise(Encoding::UndefinedConversionError) { "\xFD\xA1".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xFD\xA1", 'GB18030')
check_both_ways("\uFA0C", "\xFE\x40", 'GB18030') # E
check_both_ways("\uFA29", "\xFE\x4F", 'GB18030') # E
- #assert_raise(Encoding::UndefinedConversionError) { "\xFE\x50".encode("utf-8", 'GB18030') }
+ #assert_undefined_in("\xFE\x50", 'GB18030')
check_both_ways("\u9752\u5C71\u5B66\u9662\u5927\u5B66", "\xC7\xE0\xC9\xBD\xD1\xA7\xD4\xBA\xB4\xF3\xD1\xA7", 'GB18030') # 青山学院大学
check_both_ways("\u795E\u6797\u7FA9\u535A", "\xC9\xF1\xC1\xD6\xC1\x78\xB2\xA9", 'GB18030') # 神林義
@@ -2020,7 +2010,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u310F", "\xA3\x7E", 'Big5') # ㄏ
check_both_ways("\u3110", "\xA3\xA1", 'Big5') # ㄐ
check_both_ways("\u02CB", "\xA3\xBF", 'Big5') # ˋ
- assert_raise(Encoding::UndefinedConversionError) { "\xA3\xC0".encode("utf-8", 'Big5') }
+ assert_undefined_in("\xA3\xC0", 'Big5')
check_both_ways("\u6D6C", "\xAF\x40", 'Big5') # 浬
check_both_ways("\u7837", "\xAF\x7E", 'Big5') # 砷
check_both_ways("\u7825", "\xAF\xA1", 'Big5') # 砥
@@ -2039,9 +2029,9 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u77AC", "\xC0\xFE", 'Big5') # 瞬
check_both_ways("\u8B96", "\xC6\x40", 'Big5') # 讖
check_both_ways("\u7C72", "\xC6\x7E", 'Big5') # 籲
- #assert_raise(Encoding::UndefinedConversionError) { "\xC6\xA1".encode("utf-8", 'Big5') }
- #assert_raise(Encoding::UndefinedConversionError) { "\xC7\x40".encode("utf-8", 'Big5') }
- #assert_raise(Encoding::UndefinedConversionError) { "\xC8\x40".encode("utf-8", 'Big5') }
+ #assert_undefined_in("\xC6\xA1", 'Big5')
+ #assert_undefined_in("\xC7\x40", 'Big5')
+ #assert_undefined_in("\xC8\x40", 'Big5')
check_both_ways("\u4E42", "\xC9\x40", 'Big5') # 乂
check_both_ways("\u6C15", "\xC9\x7E", 'Big5') # 氕
check_both_ways("\u6C36", "\xC9\xA1", 'Big5') # 氶
@@ -2074,7 +2064,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u9F0A", "\xF9\x7E", 'Big5') # 鼊
check_both_ways("\u9FA4", "\xF9\xA1", 'Big5') # 龤
check_both_ways("\u9F98", "\xF9\xD5", 'Big5') # 龘
- #assert_raise(Encoding::UndefinedConversionError) { "\xF9\xD6".encode("utf-8", 'Big5') }
+ #assert_undefined_in("\xF9\xD6", 'Big5')
check_both_ways("\u795E\u6797\u7FA9\u535A", "\xAF\xAB\xAA\x4C\xB8\x71\xB3\xD5", 'Big5') # 神林義博
end
@@ -2087,7 +2077,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u310F", "\xA3\x7E", 'Big5-HKSCS') # ㄏ
check_both_ways("\u3110", "\xA3\xA1", 'Big5-HKSCS') # ㄐ
check_both_ways("\u02CB", "\xA3\xBF", 'Big5-HKSCS') # ˋ
- #assert_raise(Encoding::UndefinedConversionError) { "\xA3\xC0".encode("utf-8", 'Big5-HKSCS') }
+ #assert_undefined_in("\xA3\xC0", 'Big5-HKSCS')
check_both_ways("\u6D6C", "\xAF\x40", 'Big5-HKSCS') # 浬
check_both_ways("\u7837", "\xAF\x7E", 'Big5-HKSCS') # 砷
check_both_ways("\u7825", "\xAF\xA1", 'Big5-HKSCS') # 砥
@@ -2106,9 +2096,9 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u77AC", "\xC0\xFE", 'Big5-HKSCS') # 瞬
check_both_ways("\u8B96", "\xC6\x40", 'Big5-HKSCS') # 讖
check_both_ways("\u7C72", "\xC6\x7E", 'Big5-HKSCS') # 籲
- #assert_raise(Encoding::UndefinedConversionError) { "\xC6\xA1".encode("utf-8", 'Big5-HKSCS') }
- #assert_raise(Encoding::UndefinedConversionError) { "\xC7\x40".encode("utf-8", 'Big5-HKSCS') }
- #assert_raise(Encoding::UndefinedConversionError) { "\xC8\x40".encode("utf-8", 'Big5-HKSCS') }
+ #assert_undefined_in("\xC6\xA1", 'Big5-HKSCS')
+ #assert_undefined_in("\xC7\x40", 'Big5-HKSCS')
+ #assert_undefined_in("\xC8\x40", 'Big5-HKSCS')
check_both_ways("\u4E42", "\xC9\x40", 'Big5-HKSCS') # 乂
check_both_ways("\u6C15", "\xC9\x7E", 'Big5-HKSCS') # 氕
check_both_ways("\u6C36", "\xC9\xA1", 'Big5-HKSCS') # 氶
@@ -2142,7 +2132,7 @@ class TestTranscode < Test::Unit::TestCase
check_both_ways("\u9FA4", "\xF9\xA1", 'Big5-HKSCS') # 龤
check_both_ways("\u9F98", "\xF9\xD5", 'Big5-HKSCS') # 龘
#check_both_ways("\u{23ED7}", "\x8E\x40", 'Big5-HKSCS') # 𣻗
- #assert_raise(Encoding::UndefinedConversionError) { "\xF9\xD6".encode("utf-8", 'Big5-HKSCS') }
+ #assert_undefined_in("\xF9\xD6", 'Big5-HKSCS')
check_both_ways("\u795E\u6797\u7FA9\u535A", "\xAF\xAB\xAA\x4C\xB8\x71\xB3\xD5", 'Big5-HKSCS') # 神林義博
end
@@ -2232,12 +2222,12 @@ class TestTranscode < Test::Unit::TestCase
assert_equal("U+3042", "\u{3042}".encode("US-ASCII", fallback: fallback))
end
- bug8940 = '[ruby-core:57318] [Bug #8940]'
- %w[UTF-32 UTF-16].each do |enc|
- define_method("test_pseudo_encoding_inspect(#{enc})") do
- assert_normal_exit("'aaa'.encode('#{enc}').inspect", bug8940)
- assert_equal(4, 'aaa'.encode(enc).length, "should count in #{enc} with BOM")
- end
+ def test_pseudo_encoding_inspect
+ s = 'aaa'.encode "UTF-16"
+ assert_equal '"\xFE\xFF\x00\x61\x00\x61\x00\x61"', s.inspect
+
+ s = 'aaa'.encode "UTF-32"
+ assert_equal '"\x00\x00\xFE\xFF\x00\x00\x00\x61\x00\x00\x00\x61\x00\x00\x00\x61"', s.inspect
end
def test_encode_with_invalid_chars
@@ -2275,7 +2265,7 @@ class TestTranscode < Test::Unit::TestCase
result = th.map(&:value)
end
end
- expected = "\xa4\xa2".force_encoding(Encoding::EUC_JP)
+ expected = "\xa4\xa2".dup.force_encoding(Encoding::EUC_JP)
assert_equal([expected]*num, result, bug11277)
end;
end
@@ -2305,5 +2295,37 @@ class TestTranscode < Test::Unit::TestCase
assert_equal("A\rB\r\rC", s.encode(usascii, newline: :cr))
assert_equal("A\r\nB\r\r\nC", s.encode(usascii, crlf_newline: true))
assert_equal("A\r\nB\r\r\nC", s.encode(usascii, newline: :crlf))
+ assert_equal("A\nB\nC", s.encode(usascii, lf_newline: true))
+ assert_equal("A\nB\nC", s.encode(usascii, newline: :lf))
+ end
+
+ private
+
+ def assert_conversion_both_ways_utf8(utf8, raw, encoding)
+ assert_conversion_both_ways(utf8, 'utf-8', raw, encoding)
+ end
+ alias check_both_ways assert_conversion_both_ways_utf8
+
+ def assert_conversion_both_ways(str1, enc1, str2, enc2)
+ message = str1.dump+str2.dump
+ assert_equal(str1.force_encoding(enc1), str2.encode(enc1, enc2), message)
+ assert_equal(str2.force_encoding(enc2), str1.encode(enc2, enc1), message)
+ end
+ alias check_both_ways2 assert_conversion_both_ways
+
+ def assert_undefined_conversion(str, to, from = nil)
+ assert_raise(Encoding::UndefinedConversionError) { str.encode(to, from) }
+ end
+
+ def assert_undefined_in(str, encoding)
+ assert_undefined_conversion(str, 'utf-8', encoding)
+ end
+
+ def assert_invalid_byte_sequence(str, to, from = nil)
+ assert_raise(Encoding::InvalidByteSequenceError) { str.encode(to, from) }
+ end
+
+ def assert_invalid_in(str, encoding)
+ assert_invalid_byte_sequence(str, 'utf-8', encoding)
end
end
diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb
index f8a7c68fd3..86f2e4bb84 100644
--- a/test/ruby/test_variable.rb
+++ b/test/ruby/test_variable.rb
@@ -33,6 +33,12 @@ class TestVariable < Test::Unit::TestCase
end
end
+ Athena = Gods.clone
+
+ def test_cloned_classes_copy_cvar_cache
+ assert_equal "Cronus", Athena.new.ruler0
+ end
+
def test_setting_class_variable_on_module_through_inheritance
mod = Module.new
mod.class_variable_set(:@@foo, 1)
@@ -43,6 +49,19 @@ class TestVariable < Test::Unit::TestCase
assert_equal(1, c.class_variable_get(:@@foo))
end
+ Zeus = Gods.clone
+
+ def test_cloned_allows_setting_cvar
+ Zeus.class_variable_set(:@@rule, "Athena")
+
+ god = Gods.new.ruler0
+ zeus = Zeus.new.ruler0
+
+ assert_equal "Cronus", god
+ assert_equal "Athena", zeus
+ assert_not_equal god.object_id, zeus.object_id
+ end
+
def test_singleton_class_included_class_variable
c = Class.new
c.extend(Olympians)
@@ -155,6 +174,21 @@ class TestVariable < Test::Unit::TestCase
end
end
+ def test_set_class_variable_on_frozen_object
+ set_cvar = EnvUtil.labeled_class("SetCVar")
+ set_cvar.class_eval "#{<<~"begin;"}\n#{<<~'end;'}"
+ begin;
+ def self.set(val)
+ @@a = val # inline cache
+ end
+ end;
+ set_cvar.set(1) # fill write cache
+ set_cvar.freeze
+ assert_raise(FrozenError, "[Bug #19341]") do
+ set_cvar.set(2) # hit write cache, but should check frozen status
+ end
+ end
+
def test_variable
assert_instance_of(Integer, $$)
@@ -232,6 +266,84 @@ class TestVariable < Test::Unit::TestCase
assert_include(gv, :$12)
end
+ def prepare_klass_for_test_svar_with_ifunc
+ Class.new do
+ include Enumerable
+ def each(&b)
+ @b = b
+ end
+
+ def check1
+ check2.merge({check1: $1})
+ end
+
+ def check2
+ @b.call('foo')
+ {check2: $1}
+ end
+ end
+ end
+
+ def test_svar_with_ifunc
+ c = prepare_klass_for_test_svar_with_ifunc
+
+ expected_check1_result = {
+ check1: nil, check2: nil
+ }.freeze
+
+ obj = c.new
+ result = nil
+ obj.grep(/(f..)/){
+ result = $1
+ }
+ assert_equal nil, result
+ assert_equal nil, $1
+ assert_equal expected_check1_result, obj.check1
+ assert_equal 'foo', result
+ assert_equal 'foo', $1
+
+ # this frame was escaped so try it again
+ $~ = nil
+ obj = c.new
+ result = nil
+ obj.grep(/(f..)/){
+ result = $1
+ }
+ assert_equal nil, result
+ assert_equal nil, $1
+ assert_equal expected_check1_result, obj.check1
+ assert_equal 'foo', result
+ assert_equal 'foo', $1
+
+ # different context
+ result = nil
+ Fiber.new{
+ obj = c.new
+ obj.grep(/(f..)/){
+ result = $1
+ }
+ }.resume # obj is created in antoher Fiber
+ assert_equal nil, result
+ assert_equal expected_check1_result, obj.check1
+ assert_equal 'foo', result
+ assert_equal 'foo', $1
+
+ # different thread context
+ result = nil
+ Thread.new{
+ obj = c.new
+ obj.grep(/(f..)/){
+ result = $1
+ }
+ }.join # obj is created in another Thread
+
+ assert_equal nil, result
+ assert_equal expected_check1_result, obj.check1
+ assert_equal 'foo', result
+ assert_equal 'foo', $1
+ end
+
+
def test_global_variable_0
assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, [])
end
@@ -261,6 +373,12 @@ class TestVariable < Test::Unit::TestCase
v.instance_variable_set(:@foo, :bar)
end
+ assert_raise_with_message(FrozenError, msg, "[Bug #19339]") do
+ v.instance_eval do
+ @a = 1
+ end
+ end
+
assert_nil EnvUtil.suppress_warning {v.instance_variable_get(:@foo)}
assert_not_send([v, :instance_variable_defined?, :@foo])
@@ -295,6 +413,18 @@ class TestVariable < Test::Unit::TestCase
assert_equal(%i(v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11), v, bug11674)
end
+ def test_many_instance_variables
+ objects = [Object.new, Hash.new, Module.new]
+ objects.each do |obj|
+ 1000.times do |i|
+ obj.instance_variable_set("@var#{i}", i)
+ end
+ 1000.times do |i|
+ assert_equal(i, obj.instance_variable_get("@var#{i}"))
+ end
+ end
+ end
+
private
def with_kwargs_11(v1:, v2:, v3:, v4:, v5:, v6:, v7:, v8:, v9:, v10:, v11:)
local_variables
diff --git a/test/ruby/test_vm_dump.rb b/test/ruby/test_vm_dump.rb
index 9c06ec14fb..c718f69316 100644
--- a/test/ruby/test_vm_dump.rb
+++ b/test/ruby/test_vm_dump.rb
@@ -1,14 +1,15 @@
# frozen_string_literal: true
require 'test/unit'
+return unless /darwin/ =~ RUBY_PLATFORM
+
class TestVMDump < Test::Unit::TestCase
def assert_darwin_vm_dump_works(args)
- omit if RUBY_PLATFORM !~ /darwin/
assert_in_out_err(args, "", [], /^\[IMPORTANT\]/)
end
def test_darwin_invalid_call
- assert_darwin_vm_dump_works(['-rfiddle', '-eFiddle::Function.new(Fiddle::Pointer.new(1), [], Fiddle::TYPE_VOID).call'])
+ assert_darwin_vm_dump_works(['-r-test-/fatal', '-eBug.invalid_call(1)'])
end
def test_darwin_segv_in_syscall
@@ -16,6 +17,6 @@ class TestVMDump < Test::Unit::TestCase
end
def test_darwin_invalid_access
- assert_darwin_vm_dump_works(['-rfiddle', '-eFiddle.dlunwrap(100).inspect'])
+ assert_darwin_vm_dump_works(['-r-test-/fatal', '-eBug.invalid_access(100)'])
end
end
diff --git a/test/ruby/test_weakkeymap.rb b/test/ruby/test_weakkeymap.rb
new file mode 100644
index 0000000000..6b3ffbb81f
--- /dev/null
+++ b/test/ruby/test_weakkeymap.rb
@@ -0,0 +1,145 @@
+# frozen_string_literal: false
+require 'test/unit'
+
+class TestWeakKeyMap < Test::Unit::TestCase
+ def setup
+ @wm = ObjectSpace::WeakKeyMap.new
+ end
+
+ def test_map
+ x = Object.new
+ k = "foo"
+ @wm[k] = x
+ assert_same(x, @wm[k])
+ assert_same(x, @wm["FOO".downcase])
+ end
+
+ def test_aset_const
+ x = Object.new
+ assert_raise(ArgumentError) { @wm[true] = x }
+ assert_raise(ArgumentError) { @wm[false] = x }
+ assert_raise(ArgumentError) { @wm[nil] = x }
+ assert_raise(ArgumentError) { @wm[42] = x }
+ assert_raise(ArgumentError) { @wm[2**128] = x }
+ assert_raise(ArgumentError) { @wm[1.23] = x }
+ assert_raise(ArgumentError) { @wm[:foo] = x }
+ assert_raise(ArgumentError) { @wm["foo#{rand}".to_sym] = x }
+ end
+
+ def test_getkey
+ k = "foo"
+ @wm[k] = true
+ assert_same(k, @wm.getkey("FOO".downcase))
+ end
+
+ def test_key?
+ assert_weak_include(:key?, "foo")
+ assert_not_send([@wm, :key?, "bar"])
+ end
+
+ def test_delete
+ k1 = "foo"
+ x1 = Object.new
+ @wm[k1] = x1
+ assert_equal x1, @wm[k1]
+ assert_equal x1, @wm.delete(k1)
+ assert_nil @wm[k1]
+ assert_nil @wm.delete(k1)
+
+ fallback = @wm.delete(k1) do |key|
+ assert_equal k1, key
+ 42
+ end
+ assert_equal 42, fallback
+ end
+
+ def test_clear
+ k = "foo"
+ @wm[k] = true
+ assert @wm[k]
+ assert_same @wm, @wm.clear
+ refute @wm[k]
+ end
+
+ def test_inspect
+ x = Object.new
+ k = Object.new
+ @wm[k] = x
+ assert_match(/\A\#<#{@wm.class.name}:[\dxa-f]+ size=\d+>\z/, @wm.inspect)
+
+ 1000.times do |i|
+ @wm[i.to_s] = Object.new
+ @wm.inspect
+ end
+ assert_match(/\A\#<#{@wm.class.name}:[\dxa-f]+ size=\d+>\z/, @wm.inspect)
+ end
+
+ def test_no_hash_method
+ k = BasicObject.new
+ assert_raise NoMethodError do
+ @wm[k] = 42
+ end
+ end
+
+ def test_frozen_object
+ o = Object.new.freeze
+ assert_nothing_raised(FrozenError) {@wm[o] = 'foo'}
+ assert_nothing_raised(FrozenError) {@wm['foo'] = o}
+ end
+
+ def test_inconsistent_hash_key_memory_leak
+ assert_no_memory_leak [], '', <<~RUBY
+ class BadHash
+ def initialize
+ @hash = 0
+ end
+
+ def hash
+ @hash += 1
+ end
+ end
+
+ k = BadHash.new
+ wm = ObjectSpace::WeakKeyMap.new
+
+ 100_000.times do |i|
+ wm[k] = i
+ end
+ RUBY
+ end
+
+ def test_compaction
+ omit "compaction is not supported on this platform" unless GC.respond_to?(:compact)
+
+ assert_separately(%w(-robjspace), <<-'end;')
+ wm = ObjectSpace::WeakKeyMap.new
+ key = Object.new
+ val = Object.new
+ wm[key] = val
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ assert_equal(val, wm[key])
+ end;
+ end
+
+ def test_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress { ObjectSpace::WeakKeyMap.new }
+ end
+
+ private
+
+ def assert_weak_include(m, k, n = 100)
+ if n > 0
+ return assert_weak_include(m, k, n-1)
+ end
+ 1.times do
+ x = Object.new
+ @wm[k] = x
+ assert_send([@wm, m, k])
+ assert_send([@wm, m, "FOO".downcase])
+ x = Object.new
+ end
+ end
+end
diff --git a/test/ruby/test_weakmap.rb b/test/ruby/test_weakmap.rb
index 4c91661f86..97d7197dbb 100644
--- a/test/ruby/test_weakmap.rb
+++ b/test/ruby/test_weakmap.rb
@@ -82,6 +82,22 @@ class TestWeakMap < Test::Unit::TestCase
@wm.inspect)
end
+ def test_delete
+ k1 = "foo"
+ x1 = Object.new
+ @wm[k1] = x1
+ assert_equal x1, @wm[k1]
+ assert_equal x1, @wm.delete(k1)
+ assert_nil @wm[k1]
+ assert_nil @wm.delete(k1)
+
+ fallback = @wm.delete(k1) do |key|
+ assert_equal k1, key
+ 42
+ end
+ assert_equal 42, fallback
+ end
+
def test_each
m = __callee__[/test_(.*)/, 1]
x1 = Object.new
@@ -167,4 +183,79 @@ class TestWeakMap < Test::Unit::TestCase
assert_nothing_raised(FrozenError) {@wm[o] = 'foo'}
assert_nothing_raised(FrozenError) {@wm['foo'] = o}
end
+
+ def test_no_memory_leak
+ assert_no_memory_leak([], '', "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #19398]", rss: true, limit: 1.5, timeout: 60)
+ begin;
+ 1_000_000.times do
+ ObjectSpace::WeakMap.new
+ end
+ end;
+ end
+
+ def test_compaction
+ omit "compaction is not supported on this platform" unless GC.respond_to?(:compact)
+
+ # [Bug #19529]
+ obj = Object.new
+ 100.times do |i|
+ GC.compact
+ @wm[i] = obj
+ end
+
+ assert_separately([], <<-'end;')
+ wm = ObjectSpace::WeakMap.new
+ obj = Object.new
+ 100.times do
+ wm[Object.new] = obj
+ GC.start
+ end
+ GC.compact
+ end;
+
+ assert_separately(%w(-robjspace), <<-'end;')
+ wm = ObjectSpace::WeakMap.new
+ key = Object.new
+ val = Object.new
+ wm[key] = val
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+
+ assert_equal(val, wm[key])
+ end;
+
+ assert_separately(["-W0"], <<-'end;')
+ wm = ObjectSpace::WeakMap.new
+
+ ary = 10_000.times.map do
+ o = Object.new
+ wm[o] = 1
+ o
+ end
+
+ GC.verify_compaction_references(expand_heap: true, toward: :empty)
+ end;
+ end
+
+ def test_gc_compact_stress
+ omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077
+ EnvUtil.under_gc_compact_stress { ObjectSpace::WeakMap.new }
+ end
+
+ def test_replaced_values_bug_19531
+ a = "A".dup
+ b = "B".dup
+
+ @wm[1] = a
+ @wm[1] = a
+ @wm[1] = a
+
+ @wm[1] = b
+ assert_equal b, @wm[1]
+
+ a = nil
+ GC.start
+
+ assert_equal b, @wm[1]
+ end
end
diff --git a/test/ruby/test_whileuntil.rb b/test/ruby/test_whileuntil.rb
index 121c44817d..ff6d29ac4a 100644
--- a/test/ruby/test_whileuntil.rb
+++ b/test/ruby/test_whileuntil.rb
@@ -73,6 +73,24 @@ class TestWhileuntil < Test::Unit::TestCase
}
end
+ def test_begin_while
+ i = 0
+ sum = 0
+ begin
+ i += 1
+ sum += i
+ end while i < 10
+ assert_equal([10, 55], [i, sum])
+
+ i = 0
+ sum = 0
+ (
+ i += 1
+ sum += i
+ ) while false
+ assert_equal([0, 0], [i, sum])
+ end
+
def test_until
i = 0
until i>4
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index 37e72dcafa..df71dbffc0 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -1,21 +1,25 @@
# frozen_string_literal: true
#
# This set of tests can be run with:
-# make test-all TESTS='test/ruby/test_yjit.rb' RUN_OPTS="--yjit-call-threshold=1"
+# make test-all TESTS='test/ruby/test_yjit.rb'
require 'test/unit'
require 'envutil'
require 'tmpdir'
require_relative '../lib/jit_support'
-return unless defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
+return unless JITSupport.yjit_supported?
+
+require 'stringio'
# Tests for YJIT with assertions on compilation and side exits
-# insipired by the MJIT tests in test/ruby/test_mjit.rb
+# insipired by the RJIT tests in test/ruby/test_rjit.rb
class TestYJIT < Test::Unit::TestCase
+ running_with_yjit = defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
+
def test_yjit_in_ruby_description
assert_includes(RUBY_DESCRIPTION, '+YJIT')
- end
+ end if running_with_yjit
# Check that YJIT is in the version string
def test_yjit_in_version
@@ -27,22 +31,20 @@ class TestYJIT < Test::Unit::TestCase
%w(--version --disable=yjit --yjit),
%w(--version --disable=yjit --enable-yjit),
%w(--version --disable=yjit --enable=yjit),
- *([
- %w(--version --jit),
- %w(--version --disable-jit --jit),
- %w(--version --disable-jit --enable-jit),
- %w(--version --disable-jit --enable=jit),
- %w(--version --disable=jit --yjit),
- %w(--version --disable=jit --enable-jit),
- %w(--version --disable=jit --enable=jit),
- ] if JITSupport.yjit_supported?),
+ %w(--version --jit),
+ %w(--version --disable-jit --jit),
+ %w(--version --disable-jit --enable-jit),
+ %w(--version --disable-jit --enable=jit),
+ %w(--version --disable=jit --yjit),
+ %w(--version --disable=jit --enable-jit),
+ %w(--version --disable=jit --enable=jit),
].each do |version_args|
assert_in_out_err(version_args) do |stdout, stderr|
assert_equal(RUBY_DESCRIPTION, stdout.first)
assert_equal([], stderr)
end
end
- end
+ end if running_with_yjit
def test_command_line_switches
assert_in_out_err('--yjit-', '', [], /invalid option --yjit-/)
@@ -51,8 +53,85 @@ class TestYJIT < Test::Unit::TestCase
#assert_in_out_err('--yjit-call-threshold=', '', [], /--yjit-call-threshold needs an argument/)
end
+ def test_yjit_enable
+ args = []
+ args << "--disable=yjit" if RubyVM::YJIT.enabled?
+ assert_separately(args, <<~RUBY)
+ assert_false RubyVM::YJIT.enabled?
+ assert_false RUBY_DESCRIPTION.include?("+YJIT")
+
+ RubyVM::YJIT.enable
+
+ assert_true RubyVM::YJIT.enabled?
+ assert_true RUBY_DESCRIPTION.include?("+YJIT")
+ RUBY
+ end
+
+ def test_yjit_enable_stats_false
+ assert_separately(["--yjit-disable", "--yjit-stats"], <<~RUBY, ignore_stderr: true)
+ assert_false RubyVM::YJIT.enabled?
+ assert_nil RubyVM::YJIT.runtime_stats
+
+ RubyVM::YJIT.enable
+
+ assert_true RubyVM::YJIT.enabled?
+ assert_true RubyVM::YJIT.runtime_stats[:all_stats]
+ RUBY
+ end
+
+ def test_yjit_enable_stats_true
+ args = []
+ args << "--disable=yjit" if RubyVM::YJIT.enabled?
+ assert_separately(args, <<~RUBY, ignore_stderr: true)
+ assert_false RubyVM::YJIT.enabled?
+ assert_nil RubyVM::YJIT.runtime_stats
+
+ RubyVM::YJIT.enable(stats: true)
+
+ assert_true RubyVM::YJIT.enabled?
+ assert_true RubyVM::YJIT.runtime_stats[:all_stats]
+ RUBY
+ end
+
+ def test_yjit_enable_stats_quiet
+ assert_in_out_err(['--yjit-disable', '-e', 'RubyVM::YJIT.enable(stats: true)']) do |_stdout, stderr, _status|
+ assert_not_empty stderr
+ end
+ assert_in_out_err(['--yjit-disable', '-e', 'RubyVM::YJIT.enable(stats: :quiet)']) do |_stdout, stderr, _status|
+ assert_empty stderr
+ end
+ end
+
+ def test_yjit_enable_with_call_threshold
+ assert_separately(%w[--yjit-disable --yjit-call-threshold=1], <<~RUBY)
+ def not_compiled = nil
+ def will_compile = nil
+ def compiled_counts = RubyVM::YJIT.runtime_stats&.dig(:compiled_iseq_count)
+
+ not_compiled
+ assert_nil compiled_counts
+ assert_false RubyVM::YJIT.enabled?
+
+ RubyVM::YJIT.enable
+
+ will_compile
+ assert compiled_counts > 0
+ assert_true RubyVM::YJIT.enabled?
+ RUBY
+ end
+
+ def test_yjit_enable_with_monkey_patch
+ assert_separately(%w[--yjit-disable], <<~RUBY)
+ # This lets rb_method_entry_at(rb_mKernel, ...) return NULL
+ Kernel.prepend(Module.new)
+
+ # This must not crash with "undefined optimized method!"
+ RubyVM::YJIT.enable
+ RUBY
+ end
+
def test_yjit_stats_and_v_no_error
- _stdout, stderr, _status = EnvUtil.invoke_ruby(%w(-v --yjit-stats), '', true, true)
+ _stdout, stderr, _status = invoke_ruby(%w(-v --yjit-stats), '', true, true)
refute_includes(stderr, "NoMethodError")
end
@@ -64,7 +143,7 @@ class TestYJIT < Test::Unit::TestCase
end
assert_in_out_err([yjit_child_env, '-e puts RUBY_DESCRIPTION'], '', [RUBY_DESCRIPTION])
assert_in_out_err([yjit_child_env, '-e p RubyVM::YJIT.enabled?'], '', ['true'])
- end
+ end if running_with_yjit
def test_compile_setclassvariable
script = 'class Foo; def self.foo; @@foo = 1; end; end; Foo.foo'
@@ -241,10 +320,10 @@ class TestYJIT < Test::Unit::TestCase
end
def test_compile_opt_aset
- assert_compiles('[1,2,3][2] = 4', insns: %i[opt_aset])
- assert_compiles('{}[:foo] = :bar', insns: %i[opt_aset])
- assert_compiles('[1,2,3][0..-1] = []', insns: %i[opt_aset])
- assert_compiles('"foo"[3] = "d"', insns: %i[opt_aset])
+ assert_compiles('[1,2,3][2] = 4', insns: %i[opt_aset], frozen_string_literal: false)
+ assert_compiles('{}[:foo] = :bar', insns: %i[opt_aset], frozen_string_literal: false)
+ assert_compiles('[1,2,3][0..-1] = []', insns: %i[opt_aset], frozen_string_literal: false)
+ assert_compiles('"foo"[3] = "d"', insns: %i[opt_aset], frozen_string_literal: false)
end
def test_compile_attr_set
@@ -389,8 +468,31 @@ class TestYJIT < Test::Unit::TestCase
assert_compiles("'foo' =~ /(o)./; $2", insns: %i[getspecial], result: nil)
end
- def test_compile_opt_getinlinecache
- assert_compiles(<<~RUBY, insns: %i[opt_getinlinecache], result: 123, call_threshold: 2)
+ def test_compile_getconstant
+ assert_compiles(<<~RUBY, insns: %i[getconstant], result: [], call_threshold: 1)
+ def get_argv(klass)
+ klass::ARGV
+ end
+
+ get_argv(Object)
+ RUBY
+ end
+
+ def test_compile_getconstant_with_sp_offset
+ assert_compiles(<<~RUBY, insns: %i[getconstant], result: 2, call_threshold: 1)
+ class Foo
+ Bar = 1
+ end
+
+ 2.times do
+ s = Foo # this opt_getconstant_path needs warmup, so 2.times is needed
+ Class.new(Foo).const_set(:Bar, s::Bar)
+ end
+ RUBY
+ end
+
+ def test_compile_opt_getconstant_path
+ assert_compiles(<<~RUBY, insns: %i[opt_getconstant_path], result: 123, call_threshold: 2)
def get_foo
FOO
end
@@ -402,8 +504,8 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
- def test_opt_getinlinecache_slowpath
- assert_compiles(<<~RUBY, exits: { opt_getinlinecache: 1 }, result: [42, 42, 1, 1], call_threshold: 2)
+ def test_opt_getconstant_path_slowpath
+ assert_compiles(<<~RUBY, exits: { opt_getconstant_path: 1 }, result: [42, 42, 1, 1], call_threshold: 2)
class A
FOO = 42
class << self
@@ -430,6 +532,32 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
+ def test_opt_getconstant_path_general
+ assert_compiles(<<~RUBY, result: [1, 1])
+ module Base
+ Const = 1
+ end
+
+ class Sub
+ def const
+ _const = nil # make a non-entry block for opt_getconstant_path
+ Const
+ end
+
+ def self.const_missing(n)
+ Base.const_get(n)
+ end
+ end
+
+
+ sub = Sub.new
+ result = []
+ result << sub.const # generate the general case
+ result << sub.const # const_missing does not invalidate the block
+ result
+ RUBY
+ end
+
def test_string_interpolation
assert_compiles(<<~'RUBY', insns: %i[objtostring anytostring concatstrings], result: "foobar", call_threshold: 2)
def make_str(foo, bar)
@@ -501,8 +629,7 @@ class TestYJIT < Test::Unit::TestCase
end
def test_getblockparamproxy
- # Currently two side exits as OPTIMIZED_METHOD_TYPE_CALL is unimplemented
- assert_compiles(<<~'RUBY', insns: [:getblockparamproxy], exits: { opt_send_without_block: 2 })
+ assert_compiles(<<~'RUBY', insns: [:getblockparamproxy], exits: {})
def foo &blk
p blk.call
p blk.call
@@ -513,9 +640,26 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
- def test_getblockparamproxy_with_no_block
- # Currently side exits on the send
- assert_compiles(<<~'RUBY', insns: [:getblockparamproxy], exits: { send: 2 })
+ def test_ifunc_getblockparamproxy
+ assert_compiles(<<~'RUBY', insns: [:getblockparamproxy], exits: {})
+ class Foo
+ include Enumerable
+
+ def each(&block)
+ block.call 1
+ block.call 2
+ block.call 3
+ end
+ end
+
+ foo = Foo.new
+ foo.map { _1 * 2 }
+ foo.map { _1 * 2 }
+ RUBY
+ end
+
+ def test_send_blockarg
+ assert_compiles(<<~'RUBY', insns: [:getblockparamproxy, :send], exits: {})
def bar
end
@@ -526,6 +670,9 @@ class TestYJIT < Test::Unit::TestCase
foo
foo
+
+ foo { }
+ foo { }
RUBY
end
@@ -559,7 +706,7 @@ class TestYJIT < Test::Unit::TestCase
def test_send_kwargs
# For now, this side-exits when calls include keyword args
- assert_compiles(<<~'RUBY', result: "2#a:1,b:2/A", exits: {opt_send_without_block: 1})
+ assert_compiles(<<~'RUBY', result: "2#a:1,b:2/A")
def internal_method(**kw)
"#{kw.size}##{kw.keys.map { |k| "#{k}:#{kw[k]}" }.join(",")}"
end
@@ -599,7 +746,7 @@ class TestYJIT < Test::Unit::TestCase
def test_send_kwargs_splat
# For now, this side-exits when calling with a splat
- assert_compiles(<<~'RUBY', result: "2#a:1,b:2/B", exits: {opt_send_without_block: 1})
+ assert_compiles(<<~'RUBY', result: "2#a:1,b:2/B")
def internal_method(**kw)
"#{kw.size}##{kw.keys.map { |k| "#{k}:#{kw[k]}" }.join(",")}"
end
@@ -613,7 +760,7 @@ class TestYJIT < Test::Unit::TestCase
def test_send_block
# Setlocal_wc_0 sometimes side-exits on write barrier
- assert_compiles(<<~'RUBY', result: "b:n/b:y/b:y/b:n", exits: { :setlocal_WC_0 => 0..1 })
+ assert_compiles(<<~'RUBY', result: "b:n/b:y/b:y/b:n")
def internal_method(&b)
"b:#{block_given? ? "y" : "n"}"
end
@@ -729,6 +876,25 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
+ def test_super_with_alias
+ assert_compiles(<<~'RUBY', insns: %i[invokesuper opt_plus opt_mult], result: 15)
+ class A
+ def foo = 1 + 2
+ end
+
+ module M
+ def foo = super() * 5
+ alias bar foo
+
+ def foo = :bad
+ end
+
+ A.prepend M
+
+ A.new.bar
+ RUBY
+ end
+
def test_super_cfunc
assert_compiles(<<~'RUBY', insns: %i[invokesuper], result: "Hello")
class Gnirts < String
@@ -825,12 +991,662 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
+ def test_int_equal
+ assert_compiles(<<~'RUBY', exits: :any, result: [true, false, true, false, true, false, true, false])
+ def eq(a, b)
+ a == b
+ end
+
+ def eqq(a, b)
+ a === b
+ end
+
+ big1 = 2 ** 65
+ big2 = big1 + 1
+ [eq(1, 1), eq(1, 2), eq(big1, big1), eq(big1, big2), eqq(1, 1), eqq(1, 2), eqq(big1, big1), eqq(big1, big2)]
+ RUBY
+ end
+
+ def test_opt_case_dispatch
+ assert_compiles(<<~'RUBY', exits: :any, result: [:"1", "2", 3])
+ def case_dispatch(val)
+ case val
+ when 1
+ :"#{val}"
+ when 2
+ "#{val}"
+ else
+ val
+ end
+ end
+
+ [case_dispatch(1), case_dispatch(2), case_dispatch(3)]
+ RUBY
+ end
+
+ def test_code_gc
+ assert_compiles(code_gc_helpers + <<~'RUBY', exits: :any, result: :ok)
+ return :not_paged unless add_pages(100) # prepare freeable pages
+ RubyVM::YJIT.code_gc # first code GC
+ return :not_compiled1 unless compiles { nil } # should be JITable again
+
+ RubyVM::YJIT.code_gc # second code GC
+ return :not_compiled2 unless compiles { nil } # should be JITable again
+
+ code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count]
+ return :"code_gc_#{code_gc_count}" if code_gc_count != 2
+
+ :ok
+ RUBY
+ end
+
+ def test_on_stack_code_gc_call
+ assert_compiles(code_gc_helpers + <<~'RUBY', exits: :any, result: :ok)
+ fiber = Fiber.new {
+ # Loop to call the same basic block again after Fiber.yield
+ while true
+ Fiber.yield(nil.to_i)
+ end
+ }
+
+ return :not_paged1 unless add_pages(400) # go to a page without initial ocb code
+ return :broken_resume1 if fiber.resume != 0 # JIT the fiber
+ RubyVM::YJIT.code_gc # first code GC, which should not free the fiber page
+ return :broken_resume2 if fiber.resume != 0 # The code should be still callable
+
+ code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count]
+ return :"code_gc_#{code_gc_count}" if code_gc_count != 1
+
+ :ok
+ RUBY
+ end
+
+ def test_on_stack_code_gc_twice
+ assert_compiles(code_gc_helpers + <<~'RUBY', exits: :any, result: :ok)
+ fiber = Fiber.new {
+ # Loop to call the same basic block again after Fiber.yield
+ while Fiber.yield(nil.to_i); end
+ }
+
+ return :not_paged1 unless add_pages(400) # go to a page without initial ocb code
+ return :broken_resume1 if fiber.resume(true) != 0 # JIT the fiber
+ RubyVM::YJIT.code_gc # first code GC, which should not free the fiber page
+
+ return :not_paged2 unless add_pages(300) # add some stuff to be freed
+ # Not calling fiber.resume here to test the case that the YJIT payload loses some
+ # information at the previous code GC. The payload should still be there, and
+ # thus we could know the fiber ISEQ is still on stack on this second code GC.
+ RubyVM::YJIT.code_gc # second code GC, which should still not free the fiber page
+
+ return :not_paged3 unless add_pages(200) # attempt to overwrite the fiber page (it shouldn't)
+ return :broken_resume2 if fiber.resume(true) != 0 # The fiber code should be still fine
+
+ return :broken_resume3 if fiber.resume(false) != nil # terminate the fiber
+ RubyVM::YJIT.code_gc # third code GC, freeing a page that used to be on stack
+
+ return :not_paged4 unless add_pages(100) # check everything still works
+
+ code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count]
+ return :"code_gc_#{code_gc_count}" if code_gc_count != 3
+
+ :ok
+ RUBY
+ end
+
+ def test_disable_code_gc_with_many_iseqs
+ assert_compiles(code_gc_helpers + <<~'RUBY', exits: :any, result: :ok, mem_size: 1, code_gc: false)
+ fiber = Fiber.new {
+ # Loop to call the same basic block again after Fiber.yield
+ while true
+ Fiber.yield(nil.to_i)
+ end
+ }
+
+ return :not_paged1 unless add_pages(250) # use some pages
+ return :broken_resume1 if fiber.resume != 0 # leave an on-stack code as well
+
+ add_pages(2000) # use a whole lot of pages to run out of 1MiB
+ return :broken_resume2 if fiber.resume != 0 # on-stack code should be callable
+
+ code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count]
+ return :"code_gc_#{code_gc_count}" if code_gc_count != 0
+
+ :ok
+ RUBY
+ end
+
+ def test_code_gc_with_many_iseqs
+ assert_compiles(code_gc_helpers + <<~'RUBY', exits: :any, result: :ok, mem_size: 1, code_gc: true)
+ fiber = Fiber.new {
+ # Loop to call the same basic block again after Fiber.yield
+ while true
+ Fiber.yield(nil.to_i)
+ end
+ }
+
+ return :not_paged1 unless add_pages(250) # use some pages
+ return :broken_resume1 if fiber.resume != 0 # leave an on-stack code as well
+
+ add_pages(2000) # use a whole lot of pages to run out of 1MiB
+ return :broken_resume2 if fiber.resume != 0 # on-stack code should be callable
+
+ code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count]
+ return :"code_gc_#{code_gc_count}" if code_gc_count == 0
+
+ :ok
+ RUBY
+ end
+
+ def test_code_gc_with_auto_compact
+ assert_compiles((code_gc_helpers + <<~'RUBY'), exits: :any, result: :ok, mem_size: 1, code_gc: true)
+ # Test ISEQ moves in the middle of code GC
+ GC.auto_compact = true
+
+ fiber = Fiber.new {
+ # Loop to call the same basic block again after Fiber.yield
+ while true
+ Fiber.yield(nil.to_i)
+ end
+ }
+
+ return :not_paged1 unless add_pages(250) # use some pages
+ return :broken_resume1 if fiber.resume != 0 # leave an on-stack code as well
+
+ add_pages(2000) # use a whole lot of pages to run out of 1MiB
+ return :broken_resume2 if fiber.resume != 0 # on-stack code should be callable
+
+ code_gc_count = RubyVM::YJIT.runtime_stats[:code_gc_count]
+ return :"code_gc_#{code_gc_count}" if code_gc_count == 0
+
+ :ok
+ RUBY
+ end
+
+ def test_code_gc_partial_last_page
+ # call_threshold: 2 to avoid JIT-ing code_gc itself. If code_gc were JITed right before
+ # code_gc is called, the last page would be on stack.
+ assert_compiles(<<~'RUBY', exits: :any, result: :ok, call_threshold: 2)
+ # Leave a bunch of off-stack pages
+ i = 0
+ while i < 1000
+ eval("x = proc { 1.to_s }; x.call; x.call")
+ i += 1
+ end
+
+ # On Linux, memory page size != code page size. So the last code page could be partially
+ # mapped. This call tests that assertions and other things work fine under the situation.
+ RubyVM::YJIT.code_gc
+
+ :ok
+ RUBY
+ end
+
+ def test_trace_script_compiled # not ISEQ_TRACE_EVENTS
+ assert_compiles(<<~'RUBY', exits: :any, result: :ok)
+ @eval_counter = 0
+ def eval_script
+ eval('@eval_counter += 1')
+ end
+
+ @trace_counter = 0
+ trace = TracePoint.new(:script_compiled) do |t|
+ @trace_counter += 1
+ end
+
+ eval_script # JIT without TracePoint
+ trace.enable
+ eval_script # call with TracePoint
+ trace.disable
+
+ return :"eval_#{@eval_counter}" if @eval_counter != 2
+ return :"trace_#{@trace_counter}" if @trace_counter != 1
+
+ :ok
+ RUBY
+ end
+
+ def test_trace_b_call # ISEQ_TRACE_EVENTS
+ assert_compiles(<<~'RUBY', exits: :any, result: :ok)
+ @call_counter = 0
+ def block_call
+ 1.times { @call_counter += 1 }
+ end
+
+ @trace_counter = 0
+ trace = TracePoint.new(:b_call) do |t|
+ @trace_counter += 1
+ end
+
+ block_call # JIT without TracePoint
+ trace.enable
+ block_call # call with TracePoint
+ trace.disable
+
+ return :"call_#{@call_counter}" if @call_counter != 2
+ return :"trace_#{@trace_counter}" if @trace_counter != 1
+
+ :ok
+ RUBY
+ end
+
+ def test_send_to_call
+ assert_compiles(<<~'RUBY', result: :ok)
+ ->{ :ok }.send(:call)
+ RUBY
+ end
+
+ def test_invokeblock_many_locals
+ # [Bug #19299]
+ assert_compiles(<<~'RUBY', result: :ok)
+ def foo
+ yield
+ end
+
+ foo do
+ a1=a2=a3=a4=a5=a6=a7=a8=a9=a10=a11=a12=a13=a14=a15=a16=a17=a18=a19=a20=a21=a22=a23=a24=a25=a26=a27=a28=a29=a30 = :ok
+ a30
+ end
+ RUBY
+ end
+
+ def test_bug_19316
+ n = 2 ** 64
+ # foo's extra param and the splats are relevant
+ assert_compiles(<<~'RUBY', result: [[n, -n], [n, -n]], exits: :any)
+ def foo(_, a, b, c)
+ [a & b, ~c]
+ end
+
+ n = 2 ** 64
+ args = [0, -n, n, n-1]
+
+ GC.stress = true
+ [foo(*args), foo(*args)]
+ RUBY
+ end
+
+ def test_gc_compact_cyclic_branch
+ assert_compiles(<<~'RUBY', result: 2)
+ def foo
+ i = 0
+ while i < 2
+ i += 1
+ end
+ i
+ end
+
+ foo
+ GC.compact
+ foo
+ RUBY
+ end
+
+ def test_invalidate_cyclic_branch
+ assert_compiles(<<~'RUBY', result: 2, exits: { opt_plus: 1 })
+ def foo
+ i = 0
+ while i < 2
+ i += 1
+ end
+ i
+ end
+
+ foo
+ class Integer
+ def +(x) = self - -x
+ end
+ foo
+ RUBY
+ end
+
+ def test_tracing_str_uplus
+ assert_compiles(<<~RUBY, frozen_string_literal: true, result: :ok, exits: { putspecialobject: 1, definemethod: 1 })
+ def str_uplus
+ _ = 1
+ _ = 2
+ ret = [+"frfr", __LINE__]
+ _ = 3
+ _ = 4
+
+ ret
+ end
+
+ str_uplus
+ require 'objspace'
+ ObjectSpace.trace_object_allocations_start
+
+ str, expected_line = str_uplus
+ alloc_line = ObjectSpace.allocation_sourceline(str)
+
+ if expected_line == alloc_line
+ :ok
+ else
+ [expected_line, alloc_line]
+ end
+ RUBY
+ end
+
+ def test_str_uplus_subclass
+ assert_compiles(<<~RUBY, frozen_string_literal: true, result: :subclass)
+ class S < String
+ def encoding
+ :subclass
+ end
+ end
+
+ def test(str)
+ (+str).encoding
+ end
+
+ test ""
+ test S.new
+ RUBY
+ end
+
+ def test_return_to_invalidated_block
+ # [Bug #19463]
+ assert_compiles(<<~RUBY, result: [1, 1, :ugokanai], exits: { definesmethod: 1, getlocal_WC_0: 1 })
+ klass = Class.new do
+ def self.lookup(hash, key) = hash[key]
+
+ def self.foo(a, b) = []
+
+ def self.test(hash, key)
+ [lookup(hash, key), key, "".freeze]
+ # 05 opt_send_without_block :lookup
+ # 07 getlocal_WC_0 :hash
+ # 09 opt_str_freeze ""
+ # 12 newarray 3
+ # 14 leave
+ #
+ # YJIT will put instructions (07..14) into a block.
+ # When String#freeze is redefined from within lookup(),
+ # the return address to the block is still on-stack. We rely
+ # on invalidation patching the code at the return address
+ # to service this situation correctly.
+ end
+ end
+
+ # get YJIT to compile test()
+ hash = { 1 => [] }
+ 31.times { klass.test(hash, 1) }
+
+ # inject invalidation into lookup()
+ evil_hash = Hash.new do |_, key|
+ class String
+ undef :freeze
+ def freeze = :ugokanai
+ end
+
+ key
+ end
+ klass.test(evil_hash, 1)
+ RUBY
+ end
+
+ def test_return_to_invalidated_frame
+ assert_compiles(code_gc_helpers + <<~RUBY, exits: :any, result: :ok)
+ def jump
+ [] # something not inlined
+ end
+
+ def entry(code_gc)
+ jit_exception(code_gc)
+ jump # faulty jump after code GC. #jit_exception should not come back.
+ end
+
+ def jit_exception(code_gc)
+ if code_gc
+ tap do
+ RubyVM::YJIT.code_gc
+ break # jit_exec_exception catches TAG_BREAK and re-enters JIT code
+ end
+ end
+ end
+
+ add_pages(100)
+ jump # Compile #jump in a non-first page
+ add_pages(100)
+ entry(false) # Compile #entry and its call to #jump in another page
+ entry(true) # Free #jump but not #entry
+
+ :ok
+ RUBY
+ end
+
+ def test_setivar_on_class
+ # Bug in https://github.com/ruby/ruby/pull/8152
+ assert_compiles(<<~RUBY, result: :ok)
+ class Base
+ def self.or_equal
+ @or_equal ||= Object.new
+ end
+ end
+
+ Base.or_equal # ensure compiled
+
+ class Child < Base
+ end
+
+ 200.times do |iv| # Need to be more than MAX_IVAR
+ Child.instance_variable_set("@_iv_\#{iv}", Object.new)
+ end
+
+ Child.or_equal
+ :ok
+ RUBY
+ end
+
+ def test_nested_send
+ #[Bug #19464]
+ assert_compiles(<<~RUBY, result: [:ok, :ok], exits: { defineclass: 1 })
+ klass = Class.new do
+ class << self
+ alias_method :my_send, :send
+
+ def bar = :ok
+
+ def foo = bar
+ end
+ end
+
+ with_break = -> { break klass.send(:my_send, :foo) }
+ wo_break = -> { klass.send(:my_send, :foo) }
+
+ [with_break[], wo_break[]]
+ RUBY
+ end
+
+ def test_str_concat_encoding_mismatch
+ assert_compiles(<<~'RUBY', result: "incompatible character encodings: ASCII-8BIT and EUC-JP")
+ def bar(a, b)
+ a << b
+ rescue => e
+ e.message
+ end
+
+ def foo(a, b, h)
+ h[nil]
+ bar(a, b) # Ruby call, not set cfp->pc
+ end
+
+ h = Hash.new { nil }
+ foo("\x80".b, "\xA1A1".dup.force_encoding("EUC-JP"), h)
+ foo("\x80".b, "\xA1A1".dup.force_encoding("EUC-JP"), h)
+ RUBY
+ end
+
+ def test_io_reopen_clobbering_singleton_class
+ assert_compiles(<<~RUBY, result: [:ok, :ok], exits: { definesmethod: 1, opt_eq: 2 })
+ def $stderr.to_i = :i
+
+ def test = $stderr.to_i
+
+ [test, test]
+ $stderr.reopen($stderr.dup)
+ [test, test].map { :ok unless _1 == :i }
+ RUBY
+ end
+
+ def test_opt_aref_with
+ assert_compiles(<<~RUBY, insns: %i[opt_aref_with], result: "bar", frozen_string_literal: false)
+ h = {"foo" => "bar"}
+
+ h["foo"]
+ RUBY
+ end
+
+ def test_proc_block_arg
+ assert_compiles(<<~RUBY, result: [:proc, :no_block])
+ def yield_if_given = block_given? ? yield : :no_block
+
+ def call(block_arg = nil) = yield_if_given(&block_arg)
+
+ [call(-> { :proc }), call]
+ RUBY
+ end
+
+ def test_opt_mult_overflow
+ assert_no_exits('0xfff_ffff_ffff_ffff * 0x10')
+ end
+
+ def test_disable_stats
+ assert_in_out_err(%w[--yjit-stats --yjit-disable])
+ end
+
+ def test_odd_calls_to_attr_reader
+ # Use of delegate from ActiveSupport use these kind of calls to getter methods.
+ assert_compiles(<<~RUBY, result: [1, 1, 1], no_send_fallbacks: true)
+ class One
+ attr_reader :one
+ def initialize
+ @one = 1
+ end
+ end
+
+ def calls(obj, empty, &)
+ [obj.one(*empty), obj.one(&), obj.one(*empty, &)]
+ end
+
+ calls(One.new, [])
+ RUBY
+ end
+
+ def test_kwrest
+ assert_compiles(<<~RUBY, result: true, no_send_fallbacks: true)
+ def req_rest(r1:, **kwrest) = [r1, kwrest]
+ def opt_rest(r1: 1.succ, **kwrest) = [r1, kwrest]
+ def kwrest(**kwrest) = kwrest
+
+ def calls
+ [
+ [1, {}] == req_rest(r1: 1),
+ [1, {:r2=>2, :r3=>3}] == req_rest(r1: 1, r2: 2, r3: 3),
+ [1, {:r2=>2, :r3=>3}] == req_rest(r2: 2, r1:1, r3: 3),
+ [1, {:r2=>2, :r3=>3}] == req_rest(r2: 2, r3: 3, r1: 1),
+
+ [2, {}] == opt_rest,
+ [2, { r2: 2, r3: 3 }] == opt_rest(r2: 2, r3: 3),
+ [0, { r2: 2, r3: 3 }] == opt_rest(r1: 0, r3: 3, r2: 2),
+ [0, { r2: 2, r3: 3 }] == opt_rest(r2: 2, r1: 0, r3: 3),
+ [1, { r2: 2, r3: 3 }] == opt_rest(r2: 2, r3: 3, r1: 1),
+
+ {} == kwrest,
+ { r0: 88, r1: 99 } == kwrest(r0: 88, r1: 99),
+ ]
+ end
+
+ calls.all?
+ RUBY
+ end
+
+ def test_send_polymorphic_method_name
+ assert_compiles(<<~'RUBY', result: %i[ok ok], no_send_fallbacks: true)
+ mid = "dynamic_mid_#{rand(100..200)}"
+ mid_dsym = mid.to_sym
+
+ define_method(mid) { :ok }
+
+ define_method(:send_site) { send(_1) }
+
+ [send_site(mid), send_site(mid_dsym)]
+ RUBY
+ end
+
+ def test_kw_splat_nil
+ assert_compiles(<<~'RUBY', result: %i[ok ok ok], no_send_fallbacks: true)
+ def id(x) = x
+ def kw_fw(arg, **) = id(arg, **)
+ def fw(...) = id(...)
+ def use = [fw(:ok), kw_fw(:ok), :ok.itself(**nil)]
+
+ use
+ RUBY
+ end
+
+ def test_empty_splat
+ assert_compiles(<<~'RUBY', result: %i[ok ok], no_send_fallbacks: true)
+ def foo = :ok
+ def fw(...) = foo(...)
+ def use(empty) = [foo(*empty), fw]
+
+ use([])
+ RUBY
+ end
+
+ def test_byteslice_sp_invalidation
+ assert_compiles(<<~'RUBY', result: 'ok', no_send_fallbacks: true)
+ "okng".itself.byteslice(0, 2)
+ RUBY
+ end
+
+ def test_leaf_builtin
+ assert_compiles(code_gc_helpers + <<~'RUBY', exits: :any, result: 1)
+ before = RubyVM::YJIT.runtime_stats[:num_send_iseq_leaf]
+ return 1 if before.nil?
+
+ def entry = self.class
+ entry
+
+ after = RubyVM::YJIT.runtime_stats[:num_send_iseq_leaf]
+ after - before
+ RUBY
+ end
+
+ private
+
+ def code_gc_helpers
+ <<~'RUBY'
+ def compiles(&block)
+ failures = RubyVM::YJIT.runtime_stats[:compilation_failure]
+ block.call
+ failures == RubyVM::YJIT.runtime_stats[:compilation_failure]
+ end
+
+ def add_pages(num_jits)
+ pages = RubyVM::YJIT.runtime_stats[:live_page_count]
+ num_jits.times { return false unless eval('compiles { nil.to_i }') }
+ pages.nil? || pages < RubyVM::YJIT.runtime_stats[:live_page_count]
+ end
+ RUBY
+ end
+
def assert_no_exits(script)
assert_compiles(script)
end
ANY = Object.new
- def assert_compiles(test_script, insns: [], call_threshold: 1, stdout: nil, exits: {}, result: ANY, frozen_string_literal: nil)
+ def assert_compiles(
+ test_script, insns: [],
+ call_threshold: 1,
+ stdout: nil,
+ exits: {},
+ result: ANY,
+ frozen_string_literal: nil,
+ mem_size: nil,
+ code_gc: false,
+ no_send_fallbacks: false
+ )
reset_stats = <<~RUBY
RubyVM::YJIT.runtime_stats
RubyVM::YJIT.reset_stats!
@@ -855,7 +1671,7 @@ class TestYJIT < Test::Unit::TestCase
RUBY
script = <<~RUBY
- #{"# frozen_string_literal: true" if frozen_string_literal}
+ #{"# frozen_string_literal: " + frozen_string_literal.to_s unless frozen_string_literal.nil?}
_test_proc = -> {
#{test_script}
}
@@ -864,7 +1680,7 @@ class TestYJIT < Test::Unit::TestCase
#{write_results}
RUBY
- status, out, err, stats = eval_with_jit(script, call_threshold: call_threshold)
+ status, out, err, stats = eval_with_jit(script, call_threshold:, mem_size:, code_gc:)
assert status.success?, "exited with status #{status.to_i}, stderr:\n#{err}"
@@ -890,12 +1706,23 @@ class TestYJIT < Test::Unit::TestCase
# barriers, cache misses.)
if exits != :any &&
exits != recorded_exits &&
- !exits.all? { |k, v| v === recorded_exits[k] } # triple-equal checks range membership or integer equality
- flunk "Expected #{exits.empty? ? "no" : exits.inspect} exits" \
- ", but got\n#{recorded_exits.inspect}"
+ (exits.keys != recorded_exits.keys || !exits.all? { |k, v| v === recorded_exits[k] }) # triple-equal checks range membership or integer equality
+ stats_reasons = StringIO.new
+ ::RubyVM::YJIT.send(:_print_stats_reasons, runtime_stats, stats_reasons)
+ stats_reasons = stats_reasons.string
+ flunk <<~EOM
+ Expected #{exits.empty? ? "no" : exits.inspect} exits, but got:
+ #{recorded_exits.inspect}
+ Reasons:
+ #{stats_reasons}
+ EOM
end
end
+ if no_send_fallbacks
+ assert_equal(0, runtime_stats[:num_send_dynamic], "Expected no use of fallback implementation")
+ end
+
# Only available when --enable-yjit=dev
if runtime_stats[:all_stats]
missed_insns = insns.dup
@@ -918,21 +1745,38 @@ class TestYJIT < Test::Unit::TestCase
s.chars.map { |c| c.ascii_only? ? c : "\\u%x" % c.codepoints[0] }.join
end
- def eval_with_jit(script, call_threshold: 1, timeout: 1000)
+ def eval_with_jit(script, call_threshold: 1, timeout: 1000, mem_size: nil, code_gc: false)
args = [
"--disable-gems",
"--yjit-call-threshold=#{call_threshold}",
- "--yjit-stats"
+ "--yjit-stats=quiet"
]
+ args << "--yjit-exec-mem-size=#{mem_size}" if mem_size
+ args << "--yjit-code-gc" if code_gc
args << "-e" << script_shell_encode(script)
stats_r, stats_w = IO.pipe
- out, err, status = EnvUtil.invoke_ruby(args,
- '', true, true, timeout: timeout, ios: {3 => stats_w}
- )
+ # Separate thread so we don't deadlock when
+ # the child ruby blocks writing the stats to fd 3
+ stats = ''
+ stats_reader = Thread.new do
+ stats = stats_r.read
+ stats_r.close
+ end
+ out, err, status = invoke_ruby(args, '', true, true, timeout: timeout, ios: { 3 => stats_w })
stats_w.close
- stats = stats_r.read
+ stats_reader.join(timeout)
stats = Marshal.load(stats) if !stats.empty?
- stats_r.close
[status, out, err, stats]
+ ensure
+ stats_reader&.kill
+ stats_reader&.join(timeout)
+ stats_r&.close
+ stats_w&.close
+ end
+
+ # A wrapper of EnvUtil.invoke_ruby that uses RbConfig.ruby instead of EnvUtil.ruby
+ # that might use a wrong Ruby depending on your environment.
+ def invoke_ruby(*args, **kwargs)
+ EnvUtil.invoke_ruby(*args, rubybin: RbConfig.ruby, **kwargs)
end
end
diff --git a/test/ruby/test_yjit_exit_locations.rb b/test/ruby/test_yjit_exit_locations.rb
index 9bafe392d5..816ab457ce 100644
--- a/test/ruby/test_yjit_exit_locations.rb
+++ b/test/ruby/test_yjit_exit_locations.rb
@@ -1,39 +1,25 @@
# frozen_string_literal: true
#
# This set of tests can be run with:
-# make test-all TESTS='test/ruby/test_yjit_exit_locations.rb' RUN_OPTS="--yjit-call-threshold=1"
+# make test-all TESTS='test/ruby/test_yjit_exit_locations.rb'
require 'test/unit'
require 'envutil'
require 'tmpdir'
require_relative '../lib/jit_support'
-return unless defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
+return unless JITSupport.yjit_supported?
# Tests for YJIT with assertions on tracing exits
-# insipired by the MJIT tests in test/ruby/test_yjit.rb
+# insipired by the RJIT tests in test/ruby/test_yjit.rb
class TestYJITExitLocations < Test::Unit::TestCase
def test_yjit_trace_exits_and_v_no_error
_stdout, stderr, _status = EnvUtil.invoke_ruby(%w(-v --yjit-trace-exits), '', true, true)
refute_includes(stderr, "NoMethodError")
end
- def test_trace_exits_setclassvariable
- script = 'class Foo; def self.foo; @@foo = 1; end; end; Foo.foo'
- assert_exit_locations(script)
- end
-
- def test_trace_exits_putobject
- assert_exit_locations('true')
- assert_exit_locations('123')
- assert_exit_locations(':foo')
- end
-
- def test_trace_exits_opt_not
- assert_exit_locations('!false')
- assert_exit_locations('!nil')
- assert_exit_locations('!true')
- assert_exit_locations('![]')
+ def test_trace_exits_expandarray_splat
+ assert_exit_locations('*arr = []')
end
private
diff --git a/test/rubygems/alternate_cert.pem b/test/rubygems/alternate_cert.pem
index 54a34441b1..55303190f5 100644
--- a/test/rubygems/alternate_cert.pem
+++ b/test/rubygems/alternate_cert.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDFjCCAf6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQDDAlhbHRl
+MIIDFjCCAf6gAwIBAgIBBDANBgkqhkiG9w0BAQsFADAtMRIwEAYDVQQDDAlhbHRl
cm5hdGUxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoY
Dzk5OTkxMjMxMjM1OTU5WjAtMRIwEAYDVQQDDAlhbHRlcm5hdGUxFzAVBgoJkiaJ
k/IsZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
-vZQipBa1xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu2ERWNnblm85upqBf
-jyZEnKer7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0B6SiWFYz3dYPS92b
-BK7Vks2/kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsjrZmXfIZrh7lkHhgC
-IrzPefjE3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PEOW80AD5w0THxDutG
-G0zPNCDyDEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISWTSpCp0Ww1QB55PON
-iCCn+o6vcIy46jI71dATAQIDAQABoz8wPTAcBgNVHREEFTATgRFhbHRlcm5hdGVA
-ZXhhbXBsZTAdBgNVHQ4EFgQUyvn/FwcZnA7AkzPjmoooB4/tKgcwDQYJKoZIhvcN
-AQEFBQADggEBAHilxCg0dmOn3hxPjWMf/tAvG/S25iAIZZPuWo71DSSsn/zPRWDZ
-OkDNL7syJ7S2jjrWWCIyLxhj89ZI7Oyd3elOB2zd4RsDij1y9Gv0ZPqNoTp0Repk
-aPtRRLEwk9j2C37Tv+qA2PnTLp8MA0DVkb1/yuSd03b2K/AZEHT8Jtf3WC3RqGSK
-A1+M8CvPSSgPY7oveFFerpqAzfC4tlgyPZjSqBjZucEIlxBD2lA/3JQ8Ys8+0705
-j2jGMl5r1Y22nl0A0+cHGtPX3irtR8bcEAO+rpEfpHNF2APaYsCT7Frk1CtuAHYB
-mEwqWPQKU5ZJOV4uu69Hw5Po2bfgyjKV+N8=
+pebGm7NOnx+DtWG1xQsJBfTfwNlZvfzY61nlZccrhU6vx0AnYNiDZAG3J/gFQmYZ
+9gJ98rzEwfLMCGq9R/TZM+lAEaLhzYZCu3X4QdhKxr1xZ/SFC+1f8KVuH4tLXORW
+30DwayPhNxnrOvup4pWLiYuXUSZpV9CGMvPSUCW2odhMkBMKqaTTPjxoXJIcgacy
+prkNgIq48cSvqWG/e/HrMRtkqvFbD5ta00uO1mlpajYYw1RRftEwktFo8vQgDBo9
+NT/EqoE72tffaDnLq6rQrVtw4Kr9fy775DjNAWXyiCBjnJgOQSXCGPsM/AEdFrh/
+LKQQv2M/M7WNevnEUgsEIwIDAQABoz8wPTAcBgNVHREEFTATgRFhbHRlcm5hdGVA
+ZXhhbXBsZTAdBgNVHQ4EFgQUYPwS8g98+4Tq/8gcEK1iilkGXH4wDQYJKoZIhvcN
+AQELBQADggEBABSKUFmTk53+yrVFT3TvX5iGgXudNdACQqcnknAg66Q8+wMA8WT1
+M2oZJIH4SWSKUGMYubpYuc53tTtMnR594LPidyNbxo8KXMYoNfEkZCk6hh0eKVdx
+zPJSZ4fOQ4mKFCd7HrycOr4bxuGPTVQERYJ45vZnhvVJDIRMgshnQuivP3VBwXkQ
+gKLTCh2ew2ZJgPi1dfqdNMMSw7k4OQtQVhwbAkHgwL1TUShAO9lHzxFHlQgssfR0
+f6c89eB035Vn9s21StjerTOlC9+v4hOO7QhvbsCcUs2wWiE1BWo1QqnVBCjGKyVE
+fISkJd1Sn5j+Vx/NJ7EfZcOGGQMdxHC+c90=
-----END CERTIFICATE-----
diff --git a/test/rubygems/alternate_cert_32.pem b/test/rubygems/alternate_cert_32.pem
index adeffda24a..e727189470 100644
--- a/test/rubygems/alternate_cert_32.pem
+++ b/test/rubygems/alternate_cert_32.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDFDCCAfygAwIBAgIBBTANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQDDAlhbHRl
+MIIDFDCCAfygAwIBAgIBBTANBgkqhkiG9w0BAQsFADAtMRIwEAYDVQQDDAlhbHRl
cm5hdGUxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoX
DTM4MDExOTAzMTQwN1owLTESMBAGA1UEAwwJYWx0ZXJuYXRlMRcwFQYKCZImiZPy
-LGQBGRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2U
-IqQWtcR9zPTqJ5K1GIRmXl/VBwHCYXuoyW1K/7h15IdU7thEVjZ25ZvObqagX48m
-RJynq+7gXMMJJL5orFYAvLgRAsprAcbhCMNK34imBJy7tAekolhWM93WD0vdmwSu
-1ZLNv5Dcl1JiyxqGd4nditHiuQvwCdI/qfODqj51YcpbI62Zl3yGa4e5ZB4YAiK8
-z3n4xN6TpaIv7c+n4dpLW9BWCkDH8Hk9wWtkzHn5RtdzxDlvNAA+cNEx8Q7rRhtM
-zzQg8gxKE+1FNWtwd0TB2LlMRJNRlBGFqvS+mukjKWSElk0qQqdFsNUAeeTzjYgg
-p/qOr3CMuOoyO9XQEwECAwEAAaM/MD0wHAYDVR0RBBUwE4ERYWx0ZXJuYXRlQGV4
-YW1wbGUwHQYDVR0OBBYEFMr5/xcHGZwOwJMz45qKKAeP7SoHMA0GCSqGSIb3DQEB
-BQUAA4IBAQA1Vs3lcPpqnbsdtFDgrzApZuNgtyCRbbSrshq37dem9wSI4aFjAPLx
-QGgf3c+XZczK9FkR3VUHcK8yZFrCKpv9giZDvzCUOMB/HSBAzNiNbhgUC1S0THir
-xFriDITPoY7mrdJlX41Ssqk6tIKZsYP63UVghy7f9wxqXJvyfJZSB9UeM+0baQVL
-tGTKXmvzLw1Pc/LHTrt7jcZT9UbBsxNNy0Wk9FPPePCUUlegRjInd/sNevywzL/T
-1DL0BefqF6iyWcu86Udo+eli1JDzeUsfHOL7oqJGlWhlZHRDJ1M89n5KwPg8SCx5
-TpemV2Wy0nRTzITnmggexlMibSJ0iOvC
+LGQBGRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKXm
+xpuzTp8fg7VhtcULCQX038DZWb382OtZ5WXHK4VOr8dAJ2DYg2QBtyf4BUJmGfYC
+ffK8xMHyzAhqvUf02TPpQBGi4c2GQrt1+EHYSsa9cWf0hQvtX/Clbh+LS1zkVt9A
+8Gsj4TcZ6zr7qeKVi4mLl1EmaVfQhjLz0lAltqHYTJATCqmk0z48aFySHIGnMqa5
+DYCKuPHEr6lhv3vx6zEbZKrxWw+bWtNLjtZpaWo2GMNUUX7RMJLRaPL0IAwaPTU/
+xKqBO9rX32g5y6uq0K1bcOCq/X8u++Q4zQFl8oggY5yYDkElwhj7DPwBHRa4fyyk
+EL9jPzO1jXr5xFILBCMCAwEAAaM/MD0wHAYDVR0RBBUwE4ERYWx0ZXJuYXRlQGV4
+YW1wbGUwHQYDVR0OBBYEFGD8EvIPfPuE6v/IHBCtYopZBlx+MA0GCSqGSIb3DQEB
+CwUAA4IBAQBJeq9kniAdddOY2r9MhRYb8/rzWL1mcCgbIzkwXCTeOyVt0nWZZwAy
+arEy8ofkXt1O3Bm+59+dPORnG5WJeBGVmGDHo9HxDjm4dgTramYqgtxbthmB/pu+
+QhJ5DQg59odomoRRG7dkqacd8GMdcJVYcb3OzV3Fe5v2gtvnVPZ711APtjZ7sZUR
+4XBA+ok95QFeSUYo4WIOCHh16pPtZ9ium5SZ7ChVVNj5rthr+sS+rQKjEdjG510w
+UOkg8rUjEvXPGjM80/DnOvzyRJvbcCWBWWHquft3wqbjTomnQtqHne2SwRFEyfpd
+JLEuY9QtEUCUy7obccN39+nT9jUOyg3B
-----END CERTIFICATE-----
diff --git a/test/rubygems/alternate_key.pem b/test/rubygems/alternate_key.pem
index 14ca734aba..ae587b3425 100644
--- a/test/rubygems/alternate_key.pem
+++ b/test/rubygems/alternate_key.pem
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAvZQipBa1xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu
-2ERWNnblm85upqBfjyZEnKer7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0
-B6SiWFYz3dYPS92bBK7Vks2/kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsj
-rZmXfIZrh7lkHhgCIrzPefjE3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PE
-OW80AD5w0THxDutGG0zPNCDyDEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISW
-TSpCp0Ww1QB55PONiCCn+o6vcIy46jI71dATAQIDAQABAoIBAArXgfOoaNTH7QTE
-r2awfKp1wEfywufS2ghcasiZVW6TL3Kd5NrxbYzH1/HFKIbW/SAOrDXZUPfkVOnC
-iBtrmQ+CE0jjkClLXVqmW/3vNkF2XSUphu44+B/dLjItn8pS7h6icQxoP+Bk/TJ0
-+/CUaBm2Vc4TDUolfCpOAcYvbXkM3BL+N/XN2JHX52D2ljXtryrNm/sFnabUVo96
-ghWqln8TqpYTagcs/JkEQ5YxwqFuBLofz3SgzCnf8ub8WTIpYhWzWZ4yHjZSL7AS
-54mkJarKWMUYcL/Qeuy1U9vxLrbC9V7cPzSkzYxPZF7XlYaJcAbItX182ufZ1uNX
-3JlQS5ECgYEA+6fbg+WKy5AazEs8YokPjq1X1P01o95KUWFg+68ALowQXEYcExew
-PG0BKW11WrR6Bnn41++13k8Qsrq7Tl8ynCO6ANhoWAxUksdJDAuEgQqpFuRXwa/D
-d++8WlWD4XYqLwiE+h72alE/Ce/SdfPPsyBeHtXo7fih378WyZn7K9cCgYEAwNnw
-zjndLtj9bxd4awHHWgQ7QpKCmtLMGlg7Teo9aODMO80G3h8NEEG6Ou6LHn88tqgH
-yu0WcjJmhINAzNzmABdw+WuV4C94glwtXctQ0w4byuLOaKSh3ggWUnKf56A2KyPh
-JHPe/+A1DTKAgBvU/i5Vx0kZBkUMiiEVcIOgHOcCgYBNkt6998IjIdbA5uhET4+2
-IYUTqMIiM2GhWG026CkcMBzS9OGumPzAg7F5/b3RKhT7bhnhJolfb+vrzFf0vq+x
-JeouXIc9rP9dB4Vi6yH7TTf2UIkksXOFwybCid3PYEd8nBmxqF25RDY0b/LmXTPH
-OdEJnFLjGGN9vz/dAVRFnQKBgQC8hE8hSO8uHG+haRANim+VTw2exhllvypFlnpi
-b9gX7ae3zXQpLbFXcujZMtZLuZVf+GGlvJ10hFAyuRtfJ5CuBjwplUGtJLpotDKk
-vVsE9YW1joC3SjfxE3a+oc4uXi6VfT1YpOwYtNMnU3bJxGsxDZpMdOhBeL4JSM3s
-br7VgQKBgBDdJHRQOkP41Iq7CjcheTJMeXsQJt+HLHSIpEkxi8v/9bLKPbRVRo7e
-8mmEr9mvjrNLVZMrQpgngRGbFzcdi9iDv+4m0OKU7BGZyWy1gtlUV77FqsL7EEl3
-gdM670c2kkrni5DdpTLpNgF6zRKK7ArZ6kSgmuEYJCGHHlpbkg3f
+MIIEpQIBAAKCAQEApebGm7NOnx+DtWG1xQsJBfTfwNlZvfzY61nlZccrhU6vx0An
+YNiDZAG3J/gFQmYZ9gJ98rzEwfLMCGq9R/TZM+lAEaLhzYZCu3X4QdhKxr1xZ/SF
+C+1f8KVuH4tLXORW30DwayPhNxnrOvup4pWLiYuXUSZpV9CGMvPSUCW2odhMkBMK
+qaTTPjxoXJIcgacyprkNgIq48cSvqWG/e/HrMRtkqvFbD5ta00uO1mlpajYYw1RR
+ftEwktFo8vQgDBo9NT/EqoE72tffaDnLq6rQrVtw4Kr9fy775DjNAWXyiCBjnJgO
+QSXCGPsM/AEdFrh/LKQQv2M/M7WNevnEUgsEIwIDAQABAoIBABB/S16uTPIr2xgN
+WFr4xvPtrtZphrAK1bNJpDMjxCMkePxSV9gcj6xBM2ppEnTQ3GIHS2j49oPm1f08
+SAhAw9ySpElcriGW6Unk6EP78yuiKQXSXeyatUCj4riGTH83QaA/v+iXj8y/6hFa
+d0FN56tM00ZBkJYn6UBl2JMZvPiI9cdRO1KhhK4+NZrKg8jdRwjJe9fxo31xefpr
+jNqyx7O06hzaVfMt5jUi5qSc+/1EWJtXlvCyuJJCjpEay6ePUP5eTi/hQpwfaO82
+nIRXolwg7TPxg8rea6WQM/x6Ec3MWYUflJUdZbKDQQv1pyZR62T7WHNA1p5jHMzq
+MW3kctkCgYEAxhnT8+TZG9sF/fQro0JZnKxnZXjQ9ob7vmvbyBgHf2HzrY716UkX
+vLAHrykgqzZmIlWATayCryr+CzkaXu/xLrS0IMmjF//VlFjlob6OL9n40qrOW221
+ryqNNaKkMmm4c4N9D1rhsNH+vVQoeEDkHet9Pll9ilB2o3ERapMfBzcCgYEA1mO+
+iJLf7y1chmpwMWLFrK4hjPK6670K4UvDCfX6517xHtykZ05lZQ9OQLjjDsyG8Uub
+H6k7KxCTV+zxLQDcUUEh/UbTb6eMhh2HAU+Bym8+lWCIdl8qPouPKz1dc+rImRwC
+JE7LtxbyHXv67sPL5/7GhmdCxThXQvjH7fP1CHUCgYEArbj4pmmJ+2OXXZ1Cp2kI
+LN0Dz3ijx42YNuVfV5m6+Xpst0cnX+05Y776/iCTBZIu/uz8FyGxeOu63Ry2g4rn
+do4BaL9qxyETq4RJ3A2/ozcDfbtMO+F58qLeMqruU0di+enVQiHwyZ9eRaoH020U
+nyhkLMlNzn3BjJMbMtrR2wECgYEAm54tSI9sUv2XQs5x/7cVi6GeIuRyP/mpsx2+
+RjWx2U52MZOxFne2a+PvRlWuIyjc7ruVrya1Fy5h9Zm8+pC8W5KurF1DzrFM9HDs
+dUwUBzA2ulEm3N15GYtN8fIKKsEKuPC2sUos3wqd1j8PR08CbLTnv9mmgufBl5Bj
+91p0y50CgYEAsD/KO1/BTJWVFAXoPgde4Fmt3vQyF7OYkOI0EEIGSVPydo8ebNib
+cozGB1H0vhuvdrysi1Oc+uZ2pL8gpZfdYXbmD9cScXL+pP+GUmKKHTKKGAeQCWpv
+2M3MZEjqOGQrqY50khXUDi77H1sAHMIBQ8yF6mdb+YU+OayRwBZmHiI=
-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/bad_rake.rb b/test/rubygems/bad_rake.rb
index a08aa7dacc..e15a7d4156 100644
--- a/test/rubygems/bad_rake.rb
+++ b/test/rubygems/bad_rake.rb
@@ -1,2 +1,3 @@
# frozen_string_literal: true
+
exit 1
diff --git a/test/rubygems/bundler_test_gem.rb b/test/rubygems/bundler_test_gem.rb
new file mode 100644
index 0000000000..ca2980e04b
--- /dev/null
+++ b/test/rubygems/bundler_test_gem.rb
@@ -0,0 +1,424 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+
+class TestBundlerGem < Gem::TestCase
+ PROJECT_DIR = File.expand_path("../..", __dir__)
+
+ def test_self_use_gemdeps
+ with_local_bundler_at(Gem.dir) do
+ with_rubygems_gemdeps("-") do
+ FileUtils.mkdir_p "detect/a/b"
+ FileUtils.mkdir_p "detect/a/Isolate"
+
+ FileUtils.touch "detect/Isolate"
+
+ begin
+ Dir.chdir "detect/a/b"
+
+ Gem.use_gemdeps
+
+ assert_equal add_bundler_full_name([]), loaded_spec_names
+ ensure
+ Dir.chdir @tempdir
+ end
+ end
+ end
+ end
+
+ def test_self_find_files_with_gemfile
+ with_local_bundler_at(Gem.dir) do
+ cwd = File.expand_path("test/rubygems", PROJECT_DIR)
+ actual_load_path = $LOAD_PATH.unshift(cwd).dup
+
+ discover_path = File.join "lib", "sff", "discover.rb"
+
+ foo1, _ = %w[1 2].map do |version|
+ spec = quick_gem "sff", version do |s|
+ s.files << discover_path
+ end
+
+ write_file(File.join("gems", spec.full_name, discover_path)) do |fp|
+ fp.puts "# #{spec.full_name}"
+ end
+
+ spec
+ end
+ Gem.refresh
+
+ write_file(File.join(Dir.pwd, "Gemfile")) do |fp|
+ fp.puts "source 'https://rubygems.org'"
+ fp.puts "gem '#{foo1.name}', '#{foo1.version}'"
+ end
+ Gem.use_gemdeps(File.join(Dir.pwd, "Gemfile"))
+
+ expected = [
+ File.expand_path("test/rubygems/sff/discover.rb", PROJECT_DIR),
+ File.join(foo1.full_gem_path, discover_path),
+ ].sort
+
+ assert_equal expected, Gem.find_files("sff/discover").sort
+ assert_equal expected, Gem.find_files("sff/**.rb").sort, "[ruby-core:31730]"
+ assert_equal cwd, actual_load_path.shift
+ end
+ end
+
+ def test_auto_activation_of_specific_gemdeps_file
+ with_local_bundler_at(Gem.dir) do
+ a = util_spec "a", "1", nil, "lib/a.rb"
+ b = util_spec "b", "1", nil, "lib/b.rb"
+ c = util_spec "c", "1", nil, "lib/c.rb"
+
+ install_specs a, b, c
+
+ path = File.join @tempdir, "gem.deps.rb"
+
+ File.open path, "w" do |f|
+ f.puts "gem 'a'"
+ f.puts "gem 'b'"
+ f.puts "gem 'c'"
+ end
+
+ with_rubygems_gemdeps(path) do
+ Gem.use_gemdeps
+
+ assert_equal add_bundler_full_name(%W[a-1 b-1 c-1]), loaded_spec_names
+ end
+ end
+ end
+
+ def test_auto_activation_of_used_gemdeps_file
+ with_local_bundler_at(Gem.dir) do
+ a = util_spec "a", "1", nil, "lib/a.rb"
+ b = util_spec "b", "1", nil, "lib/b.rb"
+ c = util_spec "c", "1", nil, "lib/c.rb"
+
+ install_specs a, b, c
+
+ path = File.join @tempdir, "gem.deps.rb"
+
+ File.open path, "w" do |f|
+ f.puts "gem 'a'"
+ f.puts "gem 'b'"
+ f.puts "gem 'c'"
+ end
+
+ with_rubygems_gemdeps("-") do
+ expected_specs = [a, b, util_spec("bundler", Bundler::VERSION), c].compact.map(&:full_name)
+
+ Gem.use_gemdeps
+
+ assert_equal expected_specs, loaded_spec_names
+ end
+ end
+ end
+
+ def test_looks_for_gemdeps_files_automatically_from_binstubs
+ path = File.join(@tempdir, "gd-tmp")
+
+ with_local_bundler_at(path) do
+ a = util_spec "a", "1" do |s|
+ s.executables = %w[foo]
+ s.bindir = "exe"
+ end
+
+ write_file File.join(@tempdir, "exe", "foo") do |fp|
+ fp.puts "puts Gem.loaded_specs.values.map(&:full_name).sort"
+ end
+
+ b = util_spec "b", "1", nil, "lib/b.rb"
+ c = util_spec "c", "1", nil, "lib/c.rb"
+
+ install_specs a, b, c
+
+ install_gem a, install_dir: path
+ install_gem b, install_dir: path
+ install_gem c, install_dir: path
+
+ ENV["GEM_PATH"] = path
+
+ with_rubygems_gemdeps("-") do
+ new_path = [File.join(path, "bin"), ENV["PATH"]].join(File::PATH_SEPARATOR)
+ new_rubyopt = "-I#{rubygems_path} -I#{bundler_path}"
+
+ path = File.join @tempdir, "gem.deps.rb"
+
+ File.open path, "w" do |f|
+ f.puts "gem 'a'"
+ end
+ out0 = with_path_and_rubyopt(new_path, new_rubyopt) do
+ IO.popen("foo", &:read).split(/\n/)
+ end
+
+ File.open path, "a" do |f|
+ f.puts "gem 'b'"
+ f.puts "gem 'c'"
+ end
+ out = with_path_and_rubyopt(new_path, new_rubyopt) do
+ IO.popen("foo", &:read).split(/\n/)
+ end
+
+ assert_equal ["b-1", "c-1"], out - out0
+ end
+ end
+ end
+
+ def test_looks_for_gemdeps_files_automatically_from_binstubs_in_parent_dir
+ path = File.join(@tempdir, "gd-tmp")
+
+ with_local_bundler_at(path) do
+ pend "IO.popen has issues on JRuby when passed :chdir" if Gem.java_platform?
+
+ a = util_spec "a", "1" do |s|
+ s.executables = %w[foo]
+ s.bindir = "exe"
+ end
+
+ write_file File.join(@tempdir, "exe", "foo") do |fp|
+ fp.puts "puts Gem.loaded_specs.values.map(&:full_name).sort"
+ end
+
+ b = util_spec "b", "1", nil, "lib/b.rb"
+ c = util_spec "c", "1", nil, "lib/c.rb"
+
+ install_specs a, b, c
+
+ install_gem a, install_dir: path
+ install_gem b, install_dir: path
+ install_gem c, install_dir: path
+
+ ENV["GEM_PATH"] = path
+
+ with_rubygems_gemdeps("-") do
+ Dir.mkdir "sub1"
+
+ new_path = [File.join(path, "bin"), ENV["PATH"]].join(File::PATH_SEPARATOR)
+ new_rubyopt = "-I#{rubygems_path} -I#{bundler_path}"
+
+ path = File.join @tempdir, "gem.deps.rb"
+
+ File.open path, "w" do |f|
+ f.puts "gem 'a'"
+ end
+ out0 = with_path_and_rubyopt(new_path, new_rubyopt) do
+ IO.popen("foo", chdir: "sub1", &:read).split(/\n/)
+ end
+
+ File.open path, "a" do |f|
+ f.puts "gem 'b'"
+ f.puts "gem 'c'"
+ end
+ out = with_path_and_rubyopt(new_path, new_rubyopt) do
+ IO.popen("foo", chdir: "sub1", &:read).split(/\n/)
+ end
+
+ Dir.rmdir "sub1"
+
+ assert_equal ["b-1", "c-1"], out - out0
+ end
+ end
+ end
+
+ def test_use_gemdeps
+ with_local_bundler_at(Gem.dir) do
+ gem_deps_file = "gem.deps.rb"
+ spec = util_spec "a", 1
+ install_specs spec
+
+ spec = Gem::Specification.find {|s| s == spec }
+ refute spec.activated?
+
+ File.open gem_deps_file, "w" do |io|
+ io.write 'gem "a"'
+ end
+
+ assert_nil Gem.gemdeps
+
+ Gem.use_gemdeps gem_deps_file
+
+ assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names
+ refute_nil Gem.gemdeps
+ end
+ end
+
+ def test_use_gemdeps_ENV
+ with_local_bundler_at(Gem.dir) do
+ with_rubygems_gemdeps(nil) do
+ spec = util_spec "a", 1
+
+ refute spec.activated?
+
+ File.open "gem.deps.rb", "w" do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps
+
+ refute spec.activated?
+ end
+ end
+ end
+
+ def test_use_gemdeps_argument_missing
+ with_local_bundler_at(Gem.dir) do
+ e = assert_raise ArgumentError do
+ Gem.use_gemdeps "gem.deps.rb"
+ end
+
+ assert_equal "Unable to find gem dependencies file at gem.deps.rb",
+ e.message
+ end
+ end
+
+ def test_use_gemdeps_argument_missing_match_ENV
+ with_local_bundler_at(Gem.dir) do
+ with_rubygems_gemdeps("gem.deps.rb") do
+ e = assert_raise ArgumentError do
+ Gem.use_gemdeps "gem.deps.rb"
+ end
+
+ assert_equal "Unable to find gem dependencies file at gem.deps.rb",
+ e.message
+ end
+ end
+ end
+
+ def test_use_gemdeps_automatic
+ with_local_bundler_at(Gem.dir) do
+ with_rubygems_gemdeps("-") do
+ spec = util_spec "a", 1
+ install_specs spec
+ spec = Gem::Specification.find {|s| s == spec }
+
+ refute spec.activated?
+
+ File.open "Gemfile", "w" do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps
+
+ assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names
+ end
+ end
+ end
+
+ def test_use_gemdeps_automatic_missing
+ with_local_bundler_at(Gem.dir) do
+ with_rubygems_gemdeps("-") do
+ Gem.use_gemdeps
+
+ assert true # count
+ end
+ end
+ end
+
+ def test_use_gemdeps_disabled
+ with_local_bundler_at(Gem.dir) do
+ with_rubygems_gemdeps("") do
+ spec = util_spec "a", 1
+
+ refute spec.activated?
+
+ File.open "gem.deps.rb", "w" do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps
+
+ refute spec.activated?
+ end
+ end
+ end
+
+ def test_use_gemdeps_missing_gem
+ with_local_bundler_at(Gem.dir) do
+ with_rubygems_gemdeps("x") do
+ File.open "x", "w" do |io|
+ io.write 'gem "a"'
+ end
+
+ expected = <<-EXPECTED
+Could not find gem 'a' in locally installed gems.
+You may need to `bundle install` to install missing gems
+
+ EXPECTED
+
+ Gem::Deprecate.skip_during do
+ actual_stdout, actual_stderr = capture_output do
+ Gem.use_gemdeps
+ end
+ assert_empty actual_stdout
+ assert_equal(expected, actual_stderr)
+ end
+ end
+ end
+ end
+
+ def test_use_gemdeps_specific
+ with_local_bundler_at(Gem.dir) do
+ with_rubygems_gemdeps("x") do
+ spec = util_spec "a", 1
+ install_specs spec
+
+ spec = Gem::Specification.find {|s| s == spec }
+ refute spec.activated?
+
+ File.open "x", "w" do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps
+
+ assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names
+ end
+ end
+ end
+
+ private
+
+ def add_bundler_full_name(names)
+ names << "bundler-#{Bundler::VERSION}"
+ names.sort!
+ names
+ end
+
+ def with_path_and_rubyopt(path_value, rubyopt_value)
+ path = ENV["PATH"]
+ ENV["PATH"] = path_value
+ rubyopt = ENV["RUBYOPT"]
+ ENV["RUBYOPT"] = rubyopt_value
+
+ yield
+ ensure
+ ENV["PATH"] = path
+ ENV["RUBYOPT"] = rubyopt
+ end
+
+ def with_rubygems_gemdeps(value)
+ rubygems_gemdeps = ENV["RUBYGEMS_GEMDEPS"]
+ ENV["RUBYGEMS_GEMDEPS"] = value
+
+ yield
+ ensure
+ ENV["RUBYGEMS_GEMDEPS"] = rubygems_gemdeps
+ end
+
+ def with_local_bundler_at(path)
+ require "bundler"
+
+ # If bundler gemspec exists, pretend it's installed
+ bundler_gemspec = File.expand_path("../../bundler/bundler.gemspec", __dir__)
+ if File.exist?(bundler_gemspec)
+ target_gemspec_location = "#{path}/specifications/bundler-#{Bundler::VERSION}.gemspec"
+
+ FileUtils.mkdir_p File.dirname(target_gemspec_location)
+
+ File.write target_gemspec_location, Gem::Specification.load(bundler_gemspec).to_ruby_for_cache
+ end
+
+ yield
+ ensure
+ Bundler.reset!
+ end
+end
diff --git a/test/rubygems/child_cert.pem b/test/rubygems/child_cert.pem
index 9293cfc966..26c916cf96 100644
--- a/test/rubygems/child_cert.pem
+++ b/test/rubygems/child_cert.pem
@@ -1,20 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDTTCCAjWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDLDCCAhSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoYDzk5
OTkxMjMxMjM1OTU5WjApMQ4wDAYDVQQDDAVjaGlsZDEXMBUGCgmSJomT8ixkARkW
-B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKf7+1q0cR
-MhC/RM6Whpon/5IxuSve3CCxxdN0LcSbUisFMlf28Zj+S545SKFc6gHFcnYLZZsy
-Gm4FWEd4DhNpg/kgoDPuPGwQp2DEOvKnnneB/Shj8V+6oLrjXaZFAu8Q916c5/BL
-z+PlHIIsO/Q865XOK+5z1sZi0xval8QT7u4Usrcy86gevflCbpBAWkNPa/DZDqA9
-nk0vB2XDSHvhavcrYLfDrYAnFz3wiZ70LYQrmdeOqkPpaiw//Qpzqp+vtuF2br6U
-iYWpN+dhdFsIxAwIE5kWZ1kk6OBJ4kHvr+Sh8Oqbf6WFBhW/lQa9wldA0xhNwhGr
-1FDEfC+0g/BvAgMBAAGjfTB7MBgGA1UdEQQRMA+BDWNoaWxkQGV4YW1wbGUwHQYD
-VR0OBBYEFHzVU9N7sklKBPrHElxoZ32Fg64IMB8GA1UdIwQYMBaAFF9DbvaajkUl
-6SLjfTdepNU2AoUbMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMA0G
-CSqGSIb3DQEBBQUAA4IBAQAKRUboW7dwIHuzOp+7Nbx+ltWLUgwMkDLjjXjJE1Tv
-L+NNmAx2iv0WghyoKaUBYW+SgIcenQoMfIA+K8Z6a4dUruJ0TKsUgLW8sx3wx9h8
-NwjjybsUh8mN+7EtQ5HtkLKp4F1eOqb+eTIPpCPYP8GyzUGDcFG0pdzhcHvqOKOd
-sRYzkxyf/f8DE+6P01F1EPTql8pZLLirOfZjUtboUY3gZr2JQ03RzTk3dcjEr4pI
-wvQV8rAkj3GE638iBEByzQb/HHN+c9fLAM7f1IDcHS49jZj1gCiuCAVlf52zUmwd
-NnBgKyVrEVhf02sDgXRpoTmoRfwmcMd2cWGvDmRiijHo
+B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCHyxiIjR9Z
+m3tznMc8OqAvm5h14DAUin+2eq1HzjQZ1fxkTtP4i05ieppHLTxfJrM9mH5H6sb3
+NSNtX/L7p229tM3on8UPUZRp7qDmFNTpgdRbf03ZJFDp3MTprA85wq++gc7GMI6q
+QHhLuc3gshuy4iFzVfrWE0MRF/aVkEiH91iNUCZ3vZTahDG/jTafyMYnADE+26mj
+fK8yCoTA6qYnYQrMPy3jcr0g3aak5+z5Gn55qIJklaAXV7vAyoNgYIq6MjXs9J0f
+kedZWwJTEfAarZDo2s9wEQi7McPzv4HmNB3H6JfJsAVgaD0WtQcAVr7Ngr24lIx4
+AMY7koGayD+VAgMBAAGjXDBaMBgGA1UdEQQRMA+BDWNoaWxkQGV4YW1wbGUwHQYD
+VR0OBBYEFEVZPH+Sg200JF29GN4RJ13XfpIWMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4IBAQABo0B3iS7ykcIBRflUTQtd
+ji60ZVsX+pseEvpFvlurdKR4vrhBu/5LImQxk3wMepEhyzXZbKBanWJjgZcfJBKA
+XqWFAPu80WPunonxUpNdgKMouRBCmzmKwXojzafpZUKTZKEm7q8cbE7u1Eye8Ipv
+uj41TMlIpGvJnjfGKugJh2Gu+5Sfl7P6h8nLvM5dkJW8WsRRMGc7vFEXKCvsZbth
+wclhJXWciI4wsGUENTPpqxWhO2uj80/ob3rUNgIwROKeyBWXPUVKCme4AII5Cqk7
+qwQzNIRwWofBIb7TV2aICnFUHb3NHZEjMacviaMI+Nl5ND+gDAdc8YQmXrSHg1fW
-----END CERTIFICATE-----
diff --git a/test/rubygems/child_cert_32.pem b/test/rubygems/child_cert_32.pem
index 3484803a20..4e2fcf10df 100644
--- a/test/rubygems/child_cert_32.pem
+++ b/test/rubygems/child_cert_32.pem
@@ -1,20 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDSzCCAjOgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDKjCCAhKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoXDTM4
MDExOTAzMTQwN1owKTEOMAwGA1UEAwwFY2hpbGQxFzAVBgoJkiaJk/IsZAEZFgdl
-eGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyn+/tatHETIQ
-v0TOloaaJ/+SMbkr3twgscXTdC3Em1IrBTJX9vGY/kueOUihXOoBxXJ2C2WbMhpu
-BVhHeA4TaYP5IKAz7jxsEKdgxDryp553gf0oY/FfuqC6412mRQLvEPdenOfwS8/j
-5RyCLDv0POuVzivuc9bGYtMb2pfEE+7uFLK3MvOoHr35Qm6QQFpDT2vw2Q6gPZ5N
-Lwdlw0h74Wr3K2C3w62AJxc98Ime9C2EK5nXjqpD6WosP/0Kc6qfr7bhdm6+lImF
-qTfnYXRbCMQMCBOZFmdZJOjgSeJB76/kofDqm3+lhQYVv5UGvcJXQNMYTcIRq9RQ
-xHwvtIPwbwIDAQABo30wezAYBgNVHREEETAPgQ1jaGlsZEBleGFtcGxlMB0GA1Ud
-DgQWBBR81VPTe7JJSgT6xxJcaGd9hYOuCDAfBgNVHSMEGDAWgBRfQ272mo5FJeki
-4303XqTVNgKFGzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICBDANBgkq
-hkiG9w0BAQUFAAOCAQEAhHnhcklUtCnLXVr4aCgdNgeuBMqT/v7cJFWGjy0s0isu
-zsAHZ59caMGonykuZWwxQE2ytzMhz1fC1mRH5kfYy2h2uFHGzaexrK4n2BX0HIE+
-XFyZxDW5kwKrpmXrEeo6JVWftCoINrw3eY3iuQc3pKpLtGdir4MKByM90CcjHxzQ
-RFvI9JzRY5TmY3nXdP3JNi4rNGZULEl+Hdm79LS6yrXthZQ4dqeMqJqXLggdVPf5
-5302z//0QKi+nK3UnTi5hbEOC9xUW2n5Yj2dJnSkD/aQFapobMaww8SbbOJ3IMK0
-hsI7EPoqOCw4egbv9SlvlVOQTPDqpZfSfT4Id0AnpA==
+eGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh8sYiI0fWZt7
+c5zHPDqgL5uYdeAwFIp/tnqtR840GdX8ZE7T+ItOYnqaRy08XyazPZh+R+rG9zUj
+bV/y+6dtvbTN6J/FD1GUae6g5hTU6YHUW39N2SRQ6dzE6awPOcKvvoHOxjCOqkB4
+S7nN4LIbsuIhc1X61hNDERf2lZBIh/dYjVAmd72U2oQxv402n8jGJwAxPtupo3yv
+MgqEwOqmJ2EKzD8t43K9IN2mpOfs+Rp+eaiCZJWgF1e7wMqDYGCKujI17PSdH5Hn
+WVsCUxHwGq2Q6NrPcBEIuzHD87+B5jQdx+iXybAFYGg9FrUHAFa+zYK9uJSMeADG
+O5KBmsg/lQIDAQABo1wwWjAYBgNVHREEETAPgQ1jaGlsZEBleGFtcGxlMB0GA1Ud
+DgQWBBRFWTx/koNtNCRdvRjeESdd136SFjAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAR53288aEhg6x3zMHv0Y8ZSqB
++xPTrKzouqmHdaFBvEowIkfK6V29A2LAoIBi5DfsnkbKMGCD4mOlX3ipGoi7x2CZ
+UspOfXQ93CdiG9laS4sr4f5ZUJR1sc083UT1PBwqtnajjVUPxYz9I8g2ZxxawmA/
+bybbft/l4xHDv7RUP56uzm/BoCyiUdEC9gvq+5NYS95+M7v2J/CsvV34d5xnb8cl
+49zOoboN1JoZErPZ2dGnxpHvExOcQhz6CVUIEPri5eqRae+zln3RRd8RJ4gPe1FG
+H2aDHUwX7NKxY5Xq2NT2vUmnhTmNzFT5HC9gjG8Zu+2dPw0tTZNxyuctSAhAgw==
-----END CERTIFICATE-----
diff --git a/test/rubygems/child_key.pem b/test/rubygems/child_key.pem
index c56d0699c8..61fdfb628e 100644
--- a/test/rubygems/child_key.pem
+++ b/test/rubygems/child_key.pem
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAyn+/tatHETIQv0TOloaaJ/+SMbkr3twgscXTdC3Em1IrBTJX
-9vGY/kueOUihXOoBxXJ2C2WbMhpuBVhHeA4TaYP5IKAz7jxsEKdgxDryp553gf0o
-Y/FfuqC6412mRQLvEPdenOfwS8/j5RyCLDv0POuVzivuc9bGYtMb2pfEE+7uFLK3
-MvOoHr35Qm6QQFpDT2vw2Q6gPZ5NLwdlw0h74Wr3K2C3w62AJxc98Ime9C2EK5nX
-jqpD6WosP/0Kc6qfr7bhdm6+lImFqTfnYXRbCMQMCBOZFmdZJOjgSeJB76/kofDq
-m3+lhQYVv5UGvcJXQNMYTcIRq9RQxHwvtIPwbwIDAQABAoIBAEJkNgerG0bRAlqj
-hZQml35LtbPlwTN1OqbudFCf/NjrzL0Mb3jAZ2fghQTFAlrDQkdpKri73HFF5xKL
-igsbmlO6+EAxJjWSy9998SUFKq+4LfiJduelqLw4nG2VM8Fmn9kRMY0CIm/IvjBM
-84TrNz2OA/SvxKNoJG0cSAKYRao+00s+xNIu8lr6CqvXqnFO6gzbxQvJ0J0TnKVf
-AezArZZI3VaPXmC8yo2U6v9r7/2txr12QnDPDk9YMwJ7OR+7qzujAPvtHy44t4en
-AsTetle9AXveIBC7zpl0pp27wN8tKIdh8n+jxPfES9ecn4FjfreWiwzzZSSCitqQ
-p7cQdTkCgYEA9U/y38KUjV05FO7AeeMJYmy/o3WxjcZF8lUtuCsGzogD0JbnNj7R
-BF9TwlNnkeSJsPYKMG17dnoZhgY3J96mWhQbEH9CyXNdgQladE9/qH9gCCW9BXyo
-z3urNc77F/44J+1OoegpWGS8Hdm7OGsESLF1wLet+5cRbVHtU2brqQMCgYEA01JK
-AnATj+vACcAtr1Gu9eGE/6EqAM+H/bfQzGtqkxEmY8QihW//XWH/vOZDVZZYLUoc
-9MkSUHNGwZ7ESAgoZWc1D5xxp3sT2+vV192TS+QBe3TT5AXhAGH9uL+qz7Gz4ihH
-ebt4p49u5SJVY+3vv+nck/YgEiBw4PrfwSdugSUCgYB86U/XpoH0FaMKSKRTrErM
-BmnytuxJL8vQIJVeMPKPWezvWtey5HuUCWJiEgwr2r5OEIqRrD3wzy2N9D5Dm/kC
-5zf8x4BfidHz8apQjWaIiwuAOo8saxSeSe+dP57V0coQcqLWiJv8+ZZccNEHYl7V
-ER/PmPgLoxnpm40IKeEXtwKBgCwUEAfuJMZyYD4obd8R5LK49ar0jPRaVX1gqBbb
-mQFQJHfO43x93gA2fseCKC1kDMR1nxCYGE/bm7irSznTKcns+y5kbXiHvZ6z1IkQ
-WLcNuhlsRv5bE5Gm3ut4X0KvSFw2FqKXrhUVYAY/YRxU9xtKxo2+WvYs+h6TdbSu
-auhZAoGAThhKJW0Rf+LX1zlVaq+GXrj2rkYVSBwChMHbmmp49q6crldfLi15KbI/
-LRoUwjnQLQVNT0j090/rlNVv+pcQLqZ/pDHXQOMwrYuhbbLsda/FqTo3Qb/XnwHX
-qRrjdgGk5OC3gJt8EaHHdq+ty/eF4xQ0fUPMvIj8fwowxGyextI=
+MIIEowIBAAKCAQEAh8sYiI0fWZt7c5zHPDqgL5uYdeAwFIp/tnqtR840GdX8ZE7T
++ItOYnqaRy08XyazPZh+R+rG9zUjbV/y+6dtvbTN6J/FD1GUae6g5hTU6YHUW39N
+2SRQ6dzE6awPOcKvvoHOxjCOqkB4S7nN4LIbsuIhc1X61hNDERf2lZBIh/dYjVAm
+d72U2oQxv402n8jGJwAxPtupo3yvMgqEwOqmJ2EKzD8t43K9IN2mpOfs+Rp+eaiC
+ZJWgF1e7wMqDYGCKujI17PSdH5HnWVsCUxHwGq2Q6NrPcBEIuzHD87+B5jQdx+iX
+ybAFYGg9FrUHAFa+zYK9uJSMeADGO5KBmsg/lQIDAQABAoIBAA9dClPKuakK9xLr
+wjvdeymfvkZZ3L66M7xa0VeOLCVfKTzVEVTtt+ra6bETXGD8kStvIRx0YtntvGof
+wK85sGgV+HTw/Jvg1DyO98vIQBWCL5tBgjaGzhPDe1Dfu2JC1VzltVYFgOKgxCt3
+JGSfahRZUsUIjYZibARXVHnz9szRJFYg3lzBcVeCMWDGlPVydGaV3ttrhs4cFgPk
+1TinEH80K9GfpZvkH5/4O1E2uVFetSLONRQiTs+WXpx9flEXP+mNwdrjECI6xvIP
+x7pMfIo9kI9XniXXTvbGdEIeVrOL5OpW/nBCA3+EsL9S72TBVaMuiPTqUPlxA8up
+v/oS2qkCgYEAu7Kj1t2M+NJtR50wQ2g3efY1qO3dQ41SCnoGEWJd/17riNV3u7Xw
+FwPpnpcQAceoctK095JTtRTFGRN6FPl0VWuEsCS9lnwLzS7mQXiBg5EO7474v2Ki
+JPgncJefmCbtjJwaB78l+ybk9iUkdRv80QCHqdeHA5CegbsnDGkcJSkCgYEAuTUx
+Tfd3zpIEz0qhUf1D4PpgtoTj1zbXIUEFWl1SkLqklTF7k4LXZoWj7i3LraFk+jC2
+769qkLzF0CTHRFr5d00v9tCDOT5Sv2lqJw5UAmouKSuLF7XBp5tAkICkFX7Lo61v
+4iS2HtpK9wzri+L2XnDD3bxcHFHsEaxuD0V6iI0CgYEAp6Nsa4pizxT53z1IDtw0
+uCwrTt5rgVrlzE+hvcMSWvPG/+ZQUwmzDotDC462EDDnhO4mDPvW4WNUign4PmVx
+/pzR3JRj89SEodRieFUNr5lOMq2KAz0vvj8Y0pnJQ5Z5Ed2V7hdN79uUITeZMTM3
+AOAtSochohB3UTz7Kj1ykskCgYBPXZAHTSi2CLSu79g5fkJ8Qk73Z/MK4qFFyss0
+chFTm+ezV0URbVxIvrQE+PLzMNpIrF94Tr9nzr0l+Ny7WhDVIuqO5cOV4DMte0rV
++bneXwnw8ovkWSrnXAxK4BVwcKlrNoNfcUPp7Ll7LLozc8sHpWMJvhHqwOBcont3
+Z9qecQKBgAiiWHPgMKChKDg/JVQGEqILF67c7ZuzBMtUHmGNVn8NNr++NXZ4YIRB
+/TgYNXySTgEuD7tUE6B/iO9Mp1CpJbzRtdk8oqJlgJ4rza50N07k/SGIIWl7hAr8
+No1ibENOfw7aeMKRz3udLT50TFoluykWc/m1nJEaqtSEJLkBRM5c
-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/encrypted_private_key.pem b/test/rubygems/encrypted_private_key.pem
index d9667689a6..2d0022a6c0 100644
--- a/test/rubygems/encrypted_private_key.pem
+++ b/test/rubygems/encrypted_private_key.pem
@@ -1,30 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
-DEK-Info: AES-256-CBC,CB6FD0B173EF450C6EE21A01DD785C1D
+DEK-Info: AES-256-CBC,4851D8D265711252BA5EAD983C957412
-KqHn2Df8hSuwNE+W+60MnGtc6xpoXmF3iN25iVwcN67krYn+N6cBhjFeXwXccYwJ
-2gHSu4iEK9Qe32vK0yuv8N9h/fmsabZl0TotnEem/pqO5T8W4LxyK+Rw0s6RB30S
-C+mUisRADTanAxyBxsNU8xR8OAUNMAAxV1me6It0W2lfNE3t5jg/Kr0NWMoRUNRx
-dkE6WlD5D8jBeC3QdZ6OuE7QXOCEAWAjcFMc0d1WJq2t2r3TrLVfTH7EOoRyvL1H
-rrFRx/dEW1UJfM6P11wB5R0nhg3rDXF7oDFszjwO/3tzARke0NZuN37l301lYRl1
-aolO6sShJLa0Ml/TgNcJw0S6rc6a1Z52gTfQKztKcL1UX4HLZg75zKmn6qfatMBC
-iXn+pQRYNsOPQ5h4r7lBBqvuV+gBw+rN768tYpZ2/YVDaygxETHcZAFCdAw/JNbP
-d0XPIbP79NRrCgzSo58LKQGuOQf3Hh0vp1YS+MilMtm/eogoj1enSPM+ymStHRwG
-i+D00xCQ6blSOZ2eUUBJXt11YzP22GYnv+XTR/5kGKkTIvoRMfd+39bQyR32IEv2
-Z+yweAGQInD94eifT9ObbIayJ47y01KP0+Vj6hz4RCFsmJKsYiai5JiKlmf7lV9w
-7zH3TtCOx/xSyomesXVRkqvFkdyeguU72kXc5tiMPaDXGCOeV0GWyR1GU1DUX9/K
-60E7ym0Wx77WGMKk2fkirZzBdOeliyCRUXd7ccN2rBCjTwtjAUIk27lwzdUaTUv7
-EmjauDvSMFtir58c+zjlLmBaSQOzKcj0KXMp0Oucls9bD85WGGbGyzGhTa0AZ+/+
-cCEJt7RAwW0kTEO/uO+BAZe/zBoi9ek+QBn54FK3E7CXfS4Oi9Qbc3fwlVyTlVmz
-ZGrCncO0TIVGErFWK24Z7lX8rBnk8enfnamrPfKtwn4LG9aDfhSj8DtisjlRUVT5
-chDQ+CCi9rh3wXh28lyS+nXJ3yFidCzRgcsc3PpN/c4DNRggZc+C/KDw+J2FW+8Y
-p65OliBQHQcG0PnCa2xRyCGevytPG0rfNDgyaY33dPEo90mBLVcwLbzGiSGBHgFl
-pr8A/rqbnFpRO39NYbACeRFCqPpzyzfARCCcjcDoFrENdIaJui0fjlBkoV3B/KiK
-EVjDcgwt1HAtz8bV2YJ+OpQbhD7E90e2vTRMuXAH21Ygo32VOS0LRlCRc9ZyZW4z
-PTyO/6a+FbXZ1zhVJxu/0bmBERZ14WVmWq56oxQav8knpxYeYPgpEmIZnrHnJ1Ko
-UoXcc8Hy4NKtaBmDcaF8TCobNsRZTxO/htqpdyNsOrBSsnX2kP5D/O1l1vuVYi1/
-RYfUqL9dvGzvfsFuuDDjDlQ/fIA6pFzJV3fy4KJHlF1r33qaE/lNMdpKljBwvUII
-Vog4cGmzxssqK5q9kuogcuyeOuFODjBNW4qt0WylSi9bwwy3ZwaZLRqhngz6+tCV
-Jp45Gk881XiVe3aVU0l+4DmJJ9/5vwqjH5Vo/GJqFU6gzB+Zv/0plYeNkuE0Xo2z
-ecdxnGKVPl42q44lvczjDw2KX0ahxQrfrbcl48//zR295u9POzCL97d6zpioI2NR
+0CH43Il/Lamd5AIkeYFRdCLJUUiUAEuAlE+DDYJ+Schulv9Lp+Au00VvAH/VVdqP
+jFzEJ7FIwcPac2y4SVSa8uMGdzezVhduMz3yrwWNSUPFAJCLazh4FhGMmK2kYRfx
+IReEBebwr1x+e3VqoREfTuwxQqpA5Ho7dgnrzSf2UeIQrnXfDh1rIn3SCqb/xYDI
+qqQ9bPlDs9iY/W24KM/ZfWOB/Dr6SQXXVDu1JS8EAxB9TK4PRMHZIBlIN+OVzju5
+v7FDysTu7g2BTH9BeHs4lWFpsUdJmrj0GjGoM9DCH/6xdPHQSWKpDptFu+06htBB
+zyr2chX5RMjlPxApqtz59YJaHLNhI/nABIAJdEvAgG3CAiYHB4G+X5kQwIYryJIt
+IeD8oerxNtNOVzunGL/QvYyiLB9EcDEBfPUIlriPCpTFz7r/GCLO2wX3y0u6m631
+rh/tVRPMzWTSd4HjJiBQZU/d2bVvdOKKY12b1ieai/QiaO7HjgrcVAgWLwJB8XKr
+QkXIo6W4uZv+W0YVTVQ5lPfwdNY6eQ1ZWPnqIOoczAZtFbs3zdBobgoIjyQ6cEgq
+fgRsIjJmLVYq39F2oDX7bLdUK5UaPgHWGbNi07cOIn0hqo6YNCw1YaQikUw4qfBb
+golYKoSV73/M6IVWlTjuzP6CRDRHY80epQjA3FR9P7ToT2VgcsG+pKxoYjZxotGm
+/E4PEEl+9lxNN9IXR4XuEzWSGTOiNUZ+iVOJIyNQN5tC8k6yYr08s12b9LVzvG+q
+Ro/bD/3UNaDwfujoSNgwKelZPBZmSkJIUECNDXE2i4hr6WqoJu7ZhpO5f/iU5d+i
+Ea0bbSne50zlYoIMIa7YG01zgI5Y+sV8BWSwwK+FaH5dORjpRUVat/yIw/Qx8VZ+
+f9RIfMnOShf5zvXIX8pF+Cayf8nPk4X8rhwrd+gL2cthHlYa58DkfKpJ4FxxRItJ
+mQ01K29PuQPYBdTXN0A8jurxQgETdM2R0JrLCnDOEleshUJqdsqC69Le5Sn5ucui
+ZWqxHjm+ycF4OAO99oq1T9QDyUCtIkMXPpf982KYVyzEbNw9hEr5/0CZdCaMEL4M
+gecBM9rpYeWy0ndmZ/Y9rBdTT6+en2WnONKQj3nCgL8e59y9S1VG+sgQ2LwQ2nxJ
+Mj2CeFi4B4D+2JdqyDKRFXfGKmzLIWW5Xw7/rrnMc7NtWZjRmUkvAOk3ILC81AmY
+QPCEuqju5q9hasKfIDBnB7/eNscAvf23Aa/P3A0NBTPcTko+M+Pkpc82m4eXx1Aw
+MfpfaIcfgPI4LEo+d8IfT0zcPNDuH9ACCcYa8/4q+PnKCmOsxgZ9wGpRHOQ2QfLR
+qTus6c0l9zab8EWJZBnQvuacUecU64OAryP3QAWZl/NerHsKZ/i9ZIDXtDIscCHl
+Yylu68l+vBZmfD455QN3iPVqSm4valJTGZnk40STtf8qLAuXdVhbyI921yGIz63n
+dcRx9+wd9M3VQqmvbrri8FuavTn9/uMMpKeOeR3AIhci8EJdLxhvz2A3+w9cxIO+
+Imj0syk5TWH0c3menzkYe2cO4P8jqBsb+QRdNcA2+YSTpEsvS7Tqvogl/RWnv7r4
-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/expired_cert.pem b/test/rubygems/expired_cert.pem
index c76fe4c58f..12b8836607 100644
--- a/test/rubygems/expired_cert.pem
+++ b/test/rubygems/expired_cert.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDCzCCAfOgAwIBAgIBBjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDCzCCAfOgAwIBAgIBBjANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTcwMDEwMTAwMDAwMFoXDTcw
MDEwMTAwMDAwMFowKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH
-ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x
-gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq
-WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+
-sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc
-pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE
-g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd
-w8d/F+D5bocCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD
-VR0OBBYEFF9DbvaajkUl6SLjfTdepNU2AoUbMA0GCSqGSIb3DQEBBQUAA4IBAQAP
-Z8vKQ1OjQCHx8MJ0gy6WN2CIjh0Uqf3fSfza3nd+K8jlJPkF7znEBZ345iCSmNwn
-EPrz/OrqiId2OHW2OCJv3c9NEb7hgaTswGfdq9LmqMRVeQy57FWh2lRdjVZbquWy
-IvM72hjVLqnMVisWbDxf32YghnmT37SzZKsHSXU0xUx7rVSIShnoMjLWQtIQDoqI
-3isMAeKals2NNJOy0TGKJ9SspIDl/IYm9sEO1HKiuxubrdN9q+wEQdizt59sXkol
-4AYga+5TN+KtsSRclAGjfKYfuRrQ85IbVsRhQIYX1ZOJtMseEhBRnIeySKV4xWsi
-kXAaxX5wIyoM+S1vaKcu
+ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFC3H6Q26GO
+bllXTiJBeALUbouzzxaGinwZeYYhhXKWEcfA0D8k+22w/JyndeEYc29JxwjFNwxM
+/DyyQplptzbM1Q5BCcLNQaQhmpOryosjWuYWW1JUDGTG3nEg0qRCrtjwVoAU++Ko
+NkQboM0wFQJxkBns0J1sr+O5Ml73YzKKtdVWWvg89osxyb4wRxkEoa9a/b9/aiK7
+WoeQhF00cRKoa/eoIN8usTjzKsYudHUtEQWibD7IxWdY3nMntGf1jyLYi40lVUbL
+FFytWtlZGMVKpMVIOMMCQ+ex+ExGQaJrQF5QEqPq1L/BvXgTZkv5P6CS3YjBdVC2
+/ntfos3gMhsCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD
+VR0OBBYEFLEaVAlnRWACAtfO9B1gSonf51jZMA0GCSqGSIb3DQEBCwUAA4IBAQDI
+x70p19RI73Y9AEfBd0Wmk7KsZQyP55kjTAdaM37crhmClkUQRrk/Y2a0pXOhsrNI
+0YO7t44fJKwMu++1dxh/bllKbuOkca6ApxTb2IfhOejx3IXXWzp+C1F9pmG9q5QW
+0FDt//0SFZJIqDq9N+zFiA2z0MM1L7X/r29uUgAqkU7rsytKavHXru9EGQrrkxwh
+5dM5VI+pnJgk9HYpBDPwiFVd0yFelebqdlv/nnW11tVBMTkMloVYyhei5yZbWKFk
+f0Aj5g94+S107oRMyzq5e6lxQcJBhmKfOXqGaz2wue3/IHnwio9dMArayug9GLEr
+ycy6PubJImhM/dboDIdO
-----END CERTIFICATE-----
diff --git a/test/rubygems/fake_certlib/openssl.rb b/test/rubygems/fake_certlib/openssl.rb
index c7f85140a1..928672c7e5 100644
--- a/test/rubygems/fake_certlib/openssl.rb
+++ b/test/rubygems/fake_certlib/openssl.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
diff --git a/test/rubygems/future_cert.pem b/test/rubygems/future_cert.pem
index 05d3f9ebe3..06e08bb4c6 100644
--- a/test/rubygems/future_cert.pem
+++ b/test/rubygems/future_cert.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDDzCCAfegAwIBAgIBCDANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDDzCCAfegAwIBAgIBCDANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCIYDzk5OTkxMjMxMjM1OTU5WhgP
OTk5OTEyMzEyMzU5NTlaMCoxDzANBgNVBAMMBm5vYm9keTEXMBUGCgmSJomT8ixk
-ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnZTWH
-LxQesYKU/EHJzMm1XpRi1CskC/4UD0yvSeRcqgfIRAy7dq7jMCrB1On7v5oBvrC7
-xxdZ6loWQA4Z+q8AnzT9N9Nub5LTmeoiX1OtL8rWP394JIhjZD9tZdIc9PjLNeX/
-udoJPrBV6sBgWw7XiNMee1LB4vigDeu0Ljw57YWA7cIVyAOaXHcdsB/jVvBfNhxG
-b5tYXKQO+QQ1ZOLz8Z6Q37zzikmJ/XVoIZlLWj5qslb7PF5A8Rw32OePw984j3oT
-/s0MxIPAtO0qv8+ry0jkN7mmJ9JwQ7jROlz94oyeGb7NniRHTjMktR9wrJ5Fonjw
-qy7SncPHfxfg+W6HAgMBAAGjPDA6MBkGA1UdEQQSMBCBDm5vYm9keUBleGFtcGxl
-MB0GA1UdDgQWBBRfQ272mo5FJeki4303XqTVNgKFGzANBgkqhkiG9w0BAQUFAAOC
-AQEAM/0YoOjHEs1zdE6oG10XKdDcYn192AYhkMaITrfJUJiVUYehmcC+fa7aV5Hp
-CYasFm5SawiyHwcI92GROaM97gJy7Tjpg8zcpkXg/vUA/8ItzD0UYphs5efZ9B3R
-zOfxQDasTZJgg0uCxw23Bil7Anf5/KipuiU92Cc3fjpI6jWOuezGWqSqC2KGJLM+
-S59/oLqQNR67j7WBH3lHe3qbUehpNPkSrTdcLEbvspZM2udrRN9QYUUwBxD9dMlB
-eC4hADgWEh5uPZO5sM2+qUdyIRa+fDUpcbTEhLQy6NceHuCNLK230DdC2xszrtNY
-yNFy3B5BHgxfZeycaC4pMED0gA==
+ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRQtx+
+kNuhjm5ZV04iQXgC1G6Ls88Whop8GXmGIYVylhHHwNA/JPttsPycp3XhGHNvSccI
+xTcMTPw8skKZabc2zNUOQQnCzUGkIZqTq8qLI1rmFltSVAxkxt5xINKkQq7Y8FaA
+FPviqDZEG6DNMBUCcZAZ7NCdbK/juTJe92MyirXVVlr4PPaLMcm+MEcZBKGvWv2/
+f2oiu1qHkIRdNHESqGv3qCDfLrE48yrGLnR1LREFomw+yMVnWN5zJ7Rn9Y8i2IuN
+JVVGyxRcrVrZWRjFSqTFSDjDAkPnsfhMRkGia0BeUBKj6tS/wb14E2ZL+T+gkt2I
+wXVQtv57X6LN4DIbAgMBAAGjPDA6MBkGA1UdEQQSMBCBDm5vYm9keUBleGFtcGxl
+MB0GA1UdDgQWBBSxGlQJZ0VgAgLXzvQdYEqJ3+dY2TANBgkqhkiG9w0BAQsFAAOC
+AQEAATJNbSaVk8fM1uhqQnlBiQ/0TzchHADy+WmsbIbOiUAc8c29sjpCC4x0o5Gk
+Zn18+BsXUjfyF6zyY4wPABZp9SCDIxvLxP2QVmbCtY2TJeKV95c4mWEnrFcCqYZ/
+je13m5iLnAu1WqVjSbFn1KamTf25pfBd9mqgQVwrdJMGoviJC18LyKJTZs7aV+Bu
+tsF9fVMIP8p1Xu0Es/hBXFRwths41seqT0dYFszhwTCBC9tt85TTixWmEXpdyrov
+vLFULJg4ijn9YZeKMViC6V3zgHUl9ZnMlWdFpVZ6cf7kA/1acW1ESEZnARLQhvMF
+a1gof1D2Mj5k3AtQJ2TtPXytxw==
-----END CERTIFICATE-----
diff --git a/test/rubygems/future_cert_32.pem b/test/rubygems/future_cert_32.pem
index aa74bdffbc..c023110141 100644
--- a/test/rubygems/future_cert_32.pem
+++ b/test/rubygems/future_cert_32.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDCzCCAfOgAwIBAgIBCTANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDCzCCAfOgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTM4MDExOTAzMTQwN1oXDTM4
MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH
-ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x
-gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq
-WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+
-sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc
-pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE
-g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd
-w8d/F+D5bocCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD
-VR0OBBYEFF9DbvaajkUl6SLjfTdepNU2AoUbMA0GCSqGSIb3DQEBBQUAA4IBAQA6
-lip2nqmXyhz1uBDAxlNAv9nN2JPicWpRIvQ4KLNwmZKnagPWfleZ4TbLqsn723w8
-lD2VqFNX/Vj1XNuEJg8pXME+qxbMgtWxGsXC0z6k2Q3rT81QTdhXJ7nqdoe2i8y1
-423Fft2L6Dcgmx2USJwZsNy53pK9smxI9NipuRtL4W34PHHpaFsC2646daxZ2F8M
-No3R9C4CtSFJDrM0XZoFiAnarbqoGCJs2q0NtcdV8D5m6xGeNShWJMLNbVx4DgsT
-E90gVxVqPaqm5ytAIfdPWVUsyJBoD15jDVH5AZtkBmFRNoz60KPt3HpiRPspKWCd
-tVabH2JRC0wDYRwEEMKB
+ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFC3H6Q26GO
+bllXTiJBeALUbouzzxaGinwZeYYhhXKWEcfA0D8k+22w/JyndeEYc29JxwjFNwxM
+/DyyQplptzbM1Q5BCcLNQaQhmpOryosjWuYWW1JUDGTG3nEg0qRCrtjwVoAU++Ko
+NkQboM0wFQJxkBns0J1sr+O5Ml73YzKKtdVWWvg89osxyb4wRxkEoa9a/b9/aiK7
+WoeQhF00cRKoa/eoIN8usTjzKsYudHUtEQWibD7IxWdY3nMntGf1jyLYi40lVUbL
+FFytWtlZGMVKpMVIOMMCQ+ex+ExGQaJrQF5QEqPq1L/BvXgTZkv5P6CS3YjBdVC2
+/ntfos3gMhsCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD
+VR0OBBYEFLEaVAlnRWACAtfO9B1gSonf51jZMA0GCSqGSIb3DQEBCwUAA4IBAQB2
+EjAxPVbDwoYehhEJEiMnMWk8GL6oo1uVwGJgCM76Yml69FVyWrre2GcSYiv+9f7K
+AzE9S2uREeJuGcSV0VR0MeXoHXwQpQyBV12gCL1eQH15oxFfTi9XbVLhh5CyTKc1
+J6lYtQVpZPlLRoJN3oBq3J8PN8hWBWuhb2VIrpHXNBXAMOZ+hJM2B+EYifH6tcI5
+YK/Bw5Tes81QU4stQTLKybJzQkct02Rm7bYIM3GX/FGMMEPZE4jhnQ5btSNYVBlY
+HXh6qfZVhZ8qpAy50yrlxROLa5zJSuTQ28QWh95XLzzHiHJ4Q4qZQzhcRGUQLfM3
+X6P8rtGWzXtB++CKKQIG
-----END CERTIFICATE-----
diff --git a/test/rubygems/good_rake.rb b/test/rubygems/good_rake.rb
index 4a05ae4a13..bb0ed9fa80 100644
--- a/test/rubygems/good_rake.rb
+++ b/test/rubygems/good_rake.rb
@@ -1,2 +1,3 @@
# frozen_string_literal: true
+
exit 0
diff --git a/test/rubygems/grandchild_cert.pem b/test/rubygems/grandchild_cert.pem
index dbd14bce80..c1d9887b60 100644
--- a/test/rubygems/grandchild_cert.pem
+++ b/test/rubygems/grandchild_cert.pem
@@ -1,20 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDNTCCAh2gAwIBAgIBDDANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls
+MIIDFDCCAfygAwIBAgIBDDANBgkqhkiG9w0BAQsFADApMQ4wDAYDVQQDDAVjaGls
ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTAxMDAwMDAwWhgPOTk5
OTEyMzEyMzU5NTlaMC4xEzARBgNVBAMMCmdyYW5kY2hpbGQxFzAVBgoJkiaJk/Is
-ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkfgy
-EbzcRpXvpNA0s75R8gOVk7ENEPX5uXUElbzHbVEmHkC/NFsWZXV0vxGFfZrrnEkT
-Y2kDaMMkfZX9rriRIvsZpxyqrdX87QfQTZ1ktDoytVnd+gw9A6AXB6PR7uoPymso
-f/lZYJ8BWP9fIU39nogiptFqsgkpOtKSFjJfMILkcMAeBPs2B5HV5l4oLrpJ7Ns/
-0vazCXGakTByAXNKBagJWR43gh+RUQWF6Uh04VQTQ7ENGWI83088SKAPtCCcgKxr
-ROHI025S7o7vEfDEqEn+gtu+4ndaLuRp+2AmF3YK8dEDiLXrrvEvG1r4+gIB/6tS
-MUfkkJtBleZrDoIAgQIDAQABo2EwXzAdBgNVHREEFjAUgRJncmFuZGNoaWxkQGV4
-YW1wbGUwHQYDVR0OBBYEFAnex9R5fpiHNpHxq91rMog/PZA6MB8GA1UdIwQYMBaA
-FHzVU9N7sklKBPrHElxoZ32Fg64IMA0GCSqGSIb3DQEBBQUAA4IBAQCYT10tUm9O
-2xSGVmsbYv5YVrMr1Ucuq6Y+mXuTqqXuidILXZZl3LDwaYj64AhmMUqfITybGbR3
-sbWZrz2TWI2qWo+wcYDq+k0K+ys2PBavXdbjw4nVMf/9xYb2bCHK4bxxIG6rkmCw
-zxYRTx+UivRf7Hw+6ZRtkHDxX/qPfMQK1PbmvK9c2VYXGN3+fRRIJqPnknN26Hv1
-gangMI7oqcaNwCvL16E/CpN8uwdJNB1LcCgjFJP7Ora+LIEJVe4eZvmuOYkYaYH2
-7u6CglItKwNjVZ5jULUfBuJqFkRiOxkVMVjChe9QvNXz/fkhW2sH05CR+TDyh4rD
-ZeON5sdo9TV8
+ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyh7u
+lK+O7leQKBQzSSvhEur49Xu4sQJllkVbrVvkv2jSo68woESgljSS8jCSX0I9IJ5T
+0kHzNRpiuOpfWKZx7E4cKeqW6nmV7D/B+Iy1QnJbMzUdnxp1Y+CMCK0JrLIsFBnx
+ndVmiS/S817W3coqkmZqce4e33/O0qmCChGxGJZuAVQFGYI25SiYWPbysVEjwXoW
+6zO0D1m8QZLYYCeDSRpxKgItBoJK+Up+bm/nsrkFvUf4kAZNLgik5zvflM3/Mjyx
+zxgY2MO07YaULOlr0vZN6Wxnq2F3jkuZY8JbEOpQSDGSgU2wJ1iFH+GLvj7LsBuR
+ScjL0FJ4s1EjqjjP8QIDAQABo0AwPjAdBgNVHREEFjAUgRJncmFuZGNoaWxkQGV4
+YW1wbGUwHQYDVR0OBBYEFEuKocg9sisZIWu12gxzse+7/sHfMA0GCSqGSIb3DQEB
+CwUAA4IBAQAFaz3FUNzDYt/Cb++6U1PXsucAy3pKDj8bUW7slJFleNsSooIA9A5b
+axpnHst1Lt6i/bmvbi8F8q/0iq4PtsZvusmwVhJkCinEUZ9inddSJdxpWSyzOww5
+at8ragidzREd9Fx62flRr3GflzqIufkKN8TDjYrB+n45ijnSxDcwZhu7m/tmP/e2
+FxqODaIO9sVrPAU7YbXb0m3p3Em7RK22d0tqy1dHhcRIR5/yMQB4MSEvQ7ytRD2x
+aHAP7A4rDbkRwG+LQ/4L57RJ1kU3InqpOEQnCgpwu3xw/6Alti9TXS7sGhXL4Aav
+OLsFS/1BLSJx/DSSK58Vg6JFxFh6X2NK
-----END CERTIFICATE-----
diff --git a/test/rubygems/grandchild_cert_32.pem b/test/rubygems/grandchild_cert_32.pem
index 5077a43452..5d1ad45cb7 100644
--- a/test/rubygems/grandchild_cert_32.pem
+++ b/test/rubygems/grandchild_cert_32.pem
@@ -1,20 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDMzCCAhugAwIBAgIBDTANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls
+MIIDEjCCAfqgAwIBAgIBDTANBgkqhkiG9w0BAQsFADApMQ4wDAYDVQQDDAVjaGls
ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMTIwMTAxMDAwMDAwWhcNMzgw
MTE5MDMxNDA3WjAuMRMwEQYDVQQDDApncmFuZGNoaWxkMRcwFQYKCZImiZPyLGQB
-GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJH4MhG8
-3EaV76TQNLO+UfIDlZOxDRD1+bl1BJW8x21RJh5AvzRbFmV1dL8RhX2a65xJE2Np
-A2jDJH2V/a64kSL7Gaccqq3V/O0H0E2dZLQ6MrVZ3foMPQOgFwej0e7qD8prKH/5
-WWCfAVj/XyFN/Z6IIqbRarIJKTrSkhYyXzCC5HDAHgT7NgeR1eZeKC66SezbP9L2
-swlxmpEwcgFzSgWoCVkeN4IfkVEFhelIdOFUE0OxDRliPN9PPEigD7QgnICsa0Th
-yNNuUu6O7xHwxKhJ/oLbvuJ3Wi7kaftgJhd2CvHRA4i1667xLxta+PoCAf+rUjFH
-5JCbQZXmaw6CAIECAwEAAaNhMF8wHQYDVR0RBBYwFIESZ3JhbmRjaGlsZEBleGFt
-cGxlMB0GA1UdDgQWBBQJ3sfUeX6YhzaR8avdazKIPz2QOjAfBgNVHSMEGDAWgBR8
-1VPTe7JJSgT6xxJcaGd9hYOuCDANBgkqhkiG9w0BAQUFAAOCAQEAnIlgmwVS3BGk
-cT9LxE3bbQt1WGeLLxAF5ScqkNgFm3OvIxrKPX94WRa6tjWPEeJ9rl64QMKwJ8h1
-GzNbf0DUH8nMcSJLL1J5HUqdzwysQ96HNz54RuZ3ZF8w7QD4Kv3Vvh4IIsANchSj
-unVYjcDVH9lSsbqTwC+bnUxYZ1Xu530fKZ440BG1ju9vLLZu5JaSOoJWRuHNOlQF
-FbYj5AIjPwMNUidzoE9sUWdRzvARwecismWkPjfM0x1AmxVMs8hA5tS2QoCEvOxt
-Hl3q6k7BaC8BRENkA/XRRIqgTMoTv86OOZIMFVaTiuHyU1XUxNHKv+ybAeAlP+H7
-hM/Hqka4bQ==
+GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMoe7pSv
+ju5XkCgUM0kr4RLq+PV7uLECZZZFW61b5L9o0qOvMKBEoJY0kvIwkl9CPSCeU9JB
+8zUaYrjqX1imcexOHCnqlup5lew/wfiMtUJyWzM1HZ8adWPgjAitCayyLBQZ8Z3V
+Zokv0vNe1t3KKpJmanHuHt9/ztKpggoRsRiWbgFUBRmCNuUomFj28rFRI8F6Fusz
+tA9ZvEGS2GAng0kacSoCLQaCSvlKfm5v57K5Bb1H+JAGTS4IpOc735TN/zI8sc8Y
+GNjDtO2GlCzpa9L2TelsZ6thd45LmWPCWxDqUEgxkoFNsCdYhR/hi74+y7AbkUnI
+y9BSeLNRI6o4z/ECAwEAAaNAMD4wHQYDVR0RBBYwFIESZ3JhbmRjaGlsZEBleGFt
+cGxlMB0GA1UdDgQWBBRLiqHIPbIrGSFrtdoMc7Hvu/7B3zANBgkqhkiG9w0BAQsF
+AAOCAQEAFW6StPxdeONHUmWXUAKXNncP66aaHPAk+rQ84IvuyJKqR3UrrKdCbQLQ
+LpL/lQZDkjGJSXdNHUhoB4MQsDJ8TQs2BdwDqOIvQLsZxTKZaXPfc1diFP+z/5f0
+9wbWezUateJwShDpp1RltCBmFCdibPZQUCpsgAsfqsgIWNpzhqy9dI/Upg3vECVc
+c4g+EsEtiNXSbjd0kWUXCGBAeTMu4paBLVtt81fuffKJfnAKRhzrfFy0PoL3Kt2T
+DkMr4MWfkMOyVlrSkvjPtW1oHVnxfZgqaE91J0Ht9qiHvekti3JDqxqcKaYuIgAL
+w9HK9z5uQA2KrMvqn/jiuD8lBFsnuA==
-----END CERTIFICATE-----
diff --git a/test/rubygems/grandchild_key.pem b/test/rubygems/grandchild_key.pem
index a9b9aef624..63635844b0 100644
--- a/test/rubygems/grandchild_key.pem
+++ b/test/rubygems/grandchild_key.pem
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIEpgIBAAKCAQEAkfgyEbzcRpXvpNA0s75R8gOVk7ENEPX5uXUElbzHbVEmHkC/
-NFsWZXV0vxGFfZrrnEkTY2kDaMMkfZX9rriRIvsZpxyqrdX87QfQTZ1ktDoytVnd
-+gw9A6AXB6PR7uoPymsof/lZYJ8BWP9fIU39nogiptFqsgkpOtKSFjJfMILkcMAe
-BPs2B5HV5l4oLrpJ7Ns/0vazCXGakTByAXNKBagJWR43gh+RUQWF6Uh04VQTQ7EN
-GWI83088SKAPtCCcgKxrROHI025S7o7vEfDEqEn+gtu+4ndaLuRp+2AmF3YK8dED
-iLXrrvEvG1r4+gIB/6tSMUfkkJtBleZrDoIAgQIDAQABAoIBAQCFbg4+vpfQghBM
-ZPI399oqUvJwziA2h9Kdn4TwZ18Y41vnvaHKdxUS63orihWvSmTjOL1bWsv+AJuj
-nO8GvroU8tlxM7glLX2FImZb/GrogGaH9bz+bB995+IFXs9xCE4k5y1fRgxYUSDH
-PLC13ffe6WxbdwSD9/HTTlaxqZvv1+UWxyYD0CSwopww5YdqISkVHq2UsmszK49X
-hn6zzK+DT4YA04Tbv2Go9kCYLmsgrL2/dPJulDtJhX3AckbdkodSlBAmxe7XsKEO
-TEzNDGgPZyZ+MXttBnLt1vk8ZrSJWcFG+E6DMbGUZ7rz6g98bUS1LI6PiqIp5BfS
-sr0cGQl9AoGBAMGj7SCp1GMo8wOJpzzSGJ4PCc/fpG9NcTBqtmoUTuvMk4frkGXJ
-dSS68KB0t0EGStbUFIZuylchC7RSzXs0uOZxkgaGcJT5qXXFP0Djy3/qoQMnJ2Yl
-uhD6UsetPXbozK6MPs3mh9VqSDNbf2AM034nTod3I9sV471HZLwAhQk7AoGBAMD6
-Mmvy8DEa62VDTW6P1f4b6Pi6dOiZhGbNz5Xlh5jHplSMYReQGBVmr9szrV7qytGP
-ZcBhEqTc53u2mEhSmRXQflRxJ7U2m8Xl3DClhxELHNGCJ9jEY52M4ZDJkvGj5v3t
-pbTbE/g3zxmAaYZCOKIzYv5bSSStNpauxdomxuFzAoGBAJFohH97qEZSELJ+YrwU
-VHIUfty/Zt5BvBaMe7CK0XzWIY72gHc+4Z2UV29WVeoZTIenuEX+2ii1YvGlIDI9
-s/8wF2SY/d+Q3wTV+prCtCS5TvFsLHTTLbbkEtdoqvgo9tK3881wKF5FMjSGp867
-svFPmPO2rpEtDdgrzWQzy7LTAoGBAK077Sea3qQ2VjqBQHGQDbofs/QU7f4gUgs3
-lrIpaqBsGZSssDxGzlfn5tYQfgJHI+sbn2wjuGjnJaaZM/s4qtQ6Zi3Hpq22aAAv
-aIsDDUzvfN9WyA5/vi0g2xzu10q0qBgrziWcxUB+WRu7ev9bUxvIpYVQzUhvdiGu
-o05CoSahAoGBAKoCGMGKkub+LnWazPkN2BAS6LblV+JIYWRI+DSGpz0UBk4Br546
-ozZq2GsLCQYWJabJ5RE9Are6rl9AvFQXMaWywOBe3TUz7SmLIxMjWpXKiX5YIFkS
-tOiEEmET4ZYS87flEmldnmeDFLHHbMLOw5S0dJa4PyFRn6j9su8d8mWw
+MIIEpAIBAAKCAQEAyh7ulK+O7leQKBQzSSvhEur49Xu4sQJllkVbrVvkv2jSo68w
+oESgljSS8jCSX0I9IJ5T0kHzNRpiuOpfWKZx7E4cKeqW6nmV7D/B+Iy1QnJbMzUd
+nxp1Y+CMCK0JrLIsFBnxndVmiS/S817W3coqkmZqce4e33/O0qmCChGxGJZuAVQF
+GYI25SiYWPbysVEjwXoW6zO0D1m8QZLYYCeDSRpxKgItBoJK+Up+bm/nsrkFvUf4
+kAZNLgik5zvflM3/MjyxzxgY2MO07YaULOlr0vZN6Wxnq2F3jkuZY8JbEOpQSDGS
+gU2wJ1iFH+GLvj7LsBuRScjL0FJ4s1EjqjjP8QIDAQABAoIBACI/cwQxKiojHqtX
+3ufNXlYfB//Kjr05j36SsonRqhUv3Q88umPRtRc2gda1Wbv35JUwFrpoD96F4cf8
++Jp0G5YjlxyYIinJX9i35fVoXDdN2ru2ypXgvRbnH7tBnMPNLfBbBAiPNhBVUOyJ
+e6V5odSMM4mqBEOxK5mg/MaZgFVOrNf/DEI5oFSny7duEEQAuGJadJHUJOh7al0b
+lByNVNAYNkdZMgvOdoAoyEzg5tvY9ykIwXUKdMwBgSlldolLYXyAjluXOVEj32m4
+p3rEV/vs+RQFTLLWXfyVyWoMIPYaK6nNaYpB8fMHnIjga8MzBgC6Hso3HqymRdg2
+Gttp4PUCgYEA2LQL72tzhUb+a0wo7dWJ4MY0ekyA7JxrqZRTWSNuqKMoAb6IxaXe
+quZcpht/430szpOOz52pEwEEKUsCMuqwHiqmO2ZiZqYJpDQet466GFnhYhmAqV/x
+bOaZLVbhGjiMQCD5YbpAmXjxF8SFbkqSKlSnpjxJKD2tGNX5FFWpN4UCgYEA7sXt
+Xsf0XaPbISe2gYdXMO3exHplayt7C/wqjcxMePwtSwAJD+/JrFvFSiPBKT6Ajl+M
+dcJIb9+WHhjk5GJI7KU4AVpf4feu5o1QnpnSAzCUlXpldYwSUS/7LZALvABm68Iy
+2gHU1Aj5DYB/4nesWVhExKrMZDAICVojS5jCJH0CgYEA10SsIo9cN4ZZ0J7cfb7F
+88sRcHg1DlcowFG/JmqDT/ScFnd/CNCITL8ARGZG+eZsL1333RiiT2WQC7EeoxPu
+FlmJvrIriAriwwKfjPq0tOH8eeYZoKfVfbfpbFfEz7Zi5IWdFk7eQ1cYMOMhJXng
+jzp/PCzhA5+ZJ3XPtDqQGb0CgYEA1AuwPuECUfqHSw1yldt0gj5s/D3aPW+SydT6
+kYziSPti2d1BLwb7Kfch4TKZgyA/mLCgE6AjJj8AmN/wviXOr2IWt5Tj29BTYeoT
+s5XVHQISoiDdY6OuTK14ukDXOvF8dVi0QkkoEdmaG/SHHb67r2ilQaaQ91R0fqGv
+AJ67ox0CgYBxkRfXPCnljxrJN7Fb1fS/DE1yVNWNkLiANOlUnPwzaD+jV0miCwEG
+mR1PoRBG0j4sYTp9RyVCwR1RASNPStDTF/VcSllDqI45IHToKqgfeIlApmnCu291
+km1gAveM0Ayg5mLsIfIHyOlPZRL0iuewDDkwFNtwOiR87o9BurhRow==
-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb
index cb0177adb2..f97306717d 100644
--- a/test/rubygems/helper.rb
+++ b/test/rubygems/helper.rb
@@ -2,45 +2,27 @@
require "rubygems"
-# If bundler gemspec exists, add to stubs
-bundler_gemspec = File.expand_path("../../bundler/bundler.gemspec", __dir__)
-if File.exist?(bundler_gemspec)
- Gem::Specification.dirs.unshift File.dirname(bundler_gemspec)
- Gem::Specification.class_variable_set :@@stubs, nil
- Gem::Specification.stubs
- Gem::Specification.dirs.shift
-end
-
begin
gem "test-unit", "~> 3.0"
rescue Gem::LoadError
end
-if File.exist?(bundler_gemspec)
- require_relative "../../bundler/lib/bundler"
-else
- require "bundler"
-end
-
require "test/unit"
ENV["JARS_SKIP"] = "true" if Gem.java_platform? # avoid unnecessary and noisy `jar-dependencies` post install hook
-require "rubygems/deprecate"
-
require "fileutils"
require "pathname"
require "pp"
require "rubygems/package"
require "shellwords"
require "tmpdir"
-require "uri"
+require "rubygems/vendor/uri/lib/uri"
require "zlib"
require "benchmark" # stdlib
-require "rubygems/mock_gem_ui"
+require_relative "mock_gem_ui"
module Gem
-
##
# Allows setting the gem path searcher.
@@ -88,14 +70,14 @@ end
# your normal set of gems is not affected.
class Gem::TestCase < Test::Unit::TestCase
- extend Gem::Deprecate
-
attr_accessor :fetcher # :nodoc:
attr_accessor :gem_repo # :nodoc:
attr_accessor :uri # :nodoc:
+ @@tempdirs = []
+
def assert_activate(expected, *specs)
specs.each do |spec|
case spec
@@ -125,39 +107,32 @@ class Gem::TestCase < Test::Unit::TestCase
refute File.directory?(path), msg
end
- # https://github.com/seattlerb/minitest/blob/21d9e804b63c619f602f3f4ece6c71b48974707a/lib/minitest/assertions.rb#L188
- def _synchronize
- yield
- end
-
- # https://github.com/seattlerb/minitest/blob/21d9e804b63c619f602f3f4ece6c71b48974707a/lib/minitest/assertions.rb#L546
+ # Originally copied from minitest/assertions.rb
def capture_subprocess_io
- _synchronize do
- begin
- require "tempfile"
+ require "tempfile"
- captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err")
+ captured_stdout = Tempfile.new("out")
+ captured_stderr = Tempfile.new("err")
- orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
- $stdout.reopen captured_stdout
- $stderr.reopen captured_stderr
+ orig_stdout = $stdout.dup
+ orig_stderr = $stderr.dup
+ $stdout.reopen captured_stdout
+ $stderr.reopen captured_stderr
- yield
+ yield
- $stdout.rewind
- $stderr.rewind
+ $stdout.rewind
+ $stderr.rewind
- return captured_stdout.read, captured_stderr.read
- ensure
- $stdout.reopen orig_stdout
- $stderr.reopen orig_stderr
+ [captured_stdout.read, captured_stderr.read]
+ ensure
+ $stdout.reopen orig_stdout
+ $stderr.reopen orig_stderr
- orig_stdout.close
- orig_stderr.close
- captured_stdout.close!
- captured_stderr.close!
- end
- end
+ orig_stdout.close
+ orig_stderr.close
+ captured_stdout.close!
+ captured_stderr.close!
end
##
@@ -178,6 +153,14 @@ class Gem::TestCase < Test::Unit::TestCase
end
##
+ # Overrides the Gem.install_extension_in_lib function and restores the
+ # original when the block ends
+ #
+ def extension_in_lib(value = true) # :nodoc:
+ Gem.stub(:install_extension_in_lib, value) { yield }
+ end
+
+ ##
# Sets the vendordir entry in RbConfig::CONFIG to +value+ and restores the
# original value when the block ends
#
@@ -272,18 +255,10 @@ class Gem::TestCase < Test::Unit::TestCase
def assert_contains_make_command(target, output, msg = nil)
if output.include?("\n")
msg = build_message(msg,
- "Expected output containing make command \"%s\", but was \n\nBEGIN_OF_OUTPUT\n%sEND_OF_OUTPUT" % [
- ("%s %s" % [make_command, target]).rstrip,
- output,
- ]
- )
+ format("Expected output containing make command \"%s\", but was \n\nBEGIN_OF_OUTPUT\n%sEND_OF_OUTPUT", format("%s %s", make_command, target).rstrip, output))
else
msg = build_message(msg,
- 'Expected make command "%s", but was "%s"' % [
- ("%s %s" % [make_command, target]).rstrip,
- output,
- ]
- )
+ format('Expected make command "%s", but was "%s"', format("%s %s", make_command, target).rstrip, output))
end
assert scan_make_command_lines(output).any? {|line|
@@ -310,20 +285,24 @@ class Gem::TestCase < Test::Unit::TestCase
def setup
@orig_hooks = {}
@orig_env = ENV.to_hash
- @tmp = File.expand_path("tmp")
- FileUtils.mkdir_p @tmp
+ top_srcdir = __dir__ + "/../.."
+ @tmp = File.expand_path(ENV.fetch("GEM_TEST_TMPDIR", "tmp"), top_srcdir)
+
+ FileUtils.mkdir_p(@tmp, mode: 0o700) # =rwx
+ @tmp = File.realpath(@tmp)
@tempdir = Dir.mktmpdir("test_rubygems_", @tmp)
- @tempdir.tap(&Gem::UNTAINT)
ENV["GEM_VENDOR"] = nil
ENV["GEMRC"] = nil
ENV["XDG_CACHE_HOME"] = nil
ENV["XDG_CONFIG_HOME"] = nil
ENV["XDG_DATA_HOME"] = nil
+ ENV["XDG_STATE_HOME"] = nil
ENV["SOURCE_DATE_EPOCH"] = nil
ENV["BUNDLER_VERSION"] = nil
+ ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = "true"
@current_dir = Dir.pwd
@fetcher = nil
@@ -334,15 +313,14 @@ class Gem::TestCase < Test::Unit::TestCase
# capture output
Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new
- ENV["TMPDIR"] = @tempdir
-
- @orig_SYSTEM_WIDE_CONFIG_FILE = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE
+ @orig_system_wide_config_file = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
File.join(@tempdir, "system-gemrc")
@gemhome = File.join @tempdir, "gemhome"
@userhome = File.join @tempdir, "userhome"
+ @statehome = File.join @tempdir, "statehome"
ENV["GEM_SPEC_CACHE"] = File.join @tempdir, "spec_cache"
@orig_ruby = if ENV["RUBY"]
@@ -351,16 +329,19 @@ class Gem::TestCase < Test::Unit::TestCase
ruby
end
- @git = ENV["GIT"] || (win_platform? ? "git.exe" : "git")
+ @git = ENV["GIT"] || "git#{RbConfig::CONFIG["EXEEXT"]}"
Gem.ensure_gem_subdirectories @gemhome
Gem.ensure_default_gem_subdirectories @gemhome
- @orig_LOAD_PATH = $LOAD_PATH.dup
+ @orig_load_path = $LOAD_PATH.dup
$LOAD_PATH.map! do |s|
- expand_path = File.realpath(s) rescue File.expand_path(s)
+ expand_path = begin
+ File.realpath(s)
+ rescue StandardError
+ File.expand_path(s)
+ end
if expand_path != s
- expand_path.tap(&Gem::UNTAINT)
if s.instance_variable_defined?(:@gem_prelude_index)
expand_path.instance_variable_set(:@gem_prelude_index, expand_path)
end
@@ -373,10 +354,16 @@ class Gem::TestCase < Test::Unit::TestCase
Dir.chdir @tempdir
ENV["HOME"] = @userhome
+ # Remove "RUBY_CODESIGN", which is used by mkmf-generated Makefile to
+ # sign extension bundles on macOS, to avoid trying to find the specified key
+ # from the fake $HOME/Library/Keychains directory.
+ ENV.delete "RUBY_CODESIGN"
Gem.instance_variable_set :@config_file, nil
Gem.instance_variable_set :@user_home, nil
Gem.instance_variable_set :@config_home, nil
Gem.instance_variable_set :@data_home, nil
+ Gem.instance_variable_set :@state_home, @statehome
+ Gem.instance_variable_set :@state_file, nil
Gem.instance_variable_set :@gemdeps, nil
Gem.instance_variable_set :@env_requirements_by_name, nil
Gem.send :remove_instance_variable, :@ruby_version if
@@ -386,7 +373,7 @@ class Gem::TestCase < Test::Unit::TestCase
ENV["GEM_PRIVATE_KEY_PASSPHRASE"] = PRIVATE_KEY_PASSPHRASE
- Gem.instance_variable_set(:@default_specifications_dir, nil)
+ Gem.instance_variable_set(:@default_specifications_dir, File.join(@gemhome, "specifications", "default"))
if Gem.java_platform?
@orig_default_gem_home = RbConfig::CONFIG["default_gem_home"]
RbConfig::CONFIG["default_gem_home"] = @gemhome
@@ -411,7 +398,6 @@ class Gem::TestCase < Test::Unit::TestCase
Gem.loaded_specs.clear
Gem.instance_variable_set(:@activated_gem_paths, 0)
Gem.clear_default_specs
- Bundler.reset!
Gem.configuration.verbose = true
Gem.configuration.update_sources = true
@@ -419,7 +405,7 @@ class Gem::TestCase < Test::Unit::TestCase
Gem::RemoteFetcher.fetcher = Gem::FakeFetcher.new
@gem_repo = "http://gems.example.com/"
- @uri = URI.parse @gem_repo
+ @uri = Gem::URI.parse @gem_repo
Gem.sources.replace [@gem_repo]
Gem.searcher = nil
@@ -427,7 +413,7 @@ class Gem::TestCase < Test::Unit::TestCase
@orig_arch = RbConfig::CONFIG["arch"]
- if win_platform?
+ if Gem.win_platform?
util_set_arch "i386-mswin32"
else
util_set_arch "i686-darwin8.10.1"
@@ -438,7 +424,7 @@ class Gem::TestCase < Test::Unit::TestCase
end
@marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
- @orig_LOADED_FEATURES = $LOADED_FEATURES.dup
+ @orig_loaded_features = $LOADED_FEATURES.dup
end
##
@@ -446,14 +432,14 @@ class Gem::TestCase < Test::Unit::TestCase
# tempdir
def teardown
- $LOAD_PATH.replace @orig_LOAD_PATH if @orig_LOAD_PATH
- if @orig_LOADED_FEATURES
- if @orig_LOAD_PATH
- ($LOADED_FEATURES - @orig_LOADED_FEATURES).each do |feat|
+ $LOAD_PATH.replace @orig_load_path if @orig_load_path
+ if @orig_loaded_features
+ if @orig_load_path
+ ($LOADED_FEATURES - @orig_loaded_features).each do |feat|
$LOADED_FEATURES.delete(feat) if feat.start_with?(@tmp)
end
else
- $LOADED_FEATURES.replace @orig_LOADED_FEATURES
+ $LOADED_FEATURES.replace @orig_loaded_features
end
end
@@ -467,11 +453,11 @@ class Gem::TestCase < Test::Unit::TestCase
FileUtils.rm_rf @tempdir
- ENV.replace(@orig_env)
+ restore_env
Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
- @orig_SYSTEM_WIDE_CONFIG_FILE
+ @orig_system_wide_config_file
Gem.ruby = @orig_ruby if @orig_ruby
@@ -487,20 +473,27 @@ class Gem::TestCase < Test::Unit::TestCase
end
Gem::Specification.unresolved_deps.clear
- Gem::refresh
+ Gem.refresh
@orig_hooks.each do |name, hooks|
Gem.send(name).replace hooks
end
@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
end
def credential_setup
@temp_cred = File.join(@userhome, ".gem", "credentials")
FileUtils.mkdir_p File.dirname(@temp_cred)
File.write @temp_cred, ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
- File.chmod 0600, @temp_cred
+ File.chmod 0o600, @temp_cred
end
def credential_teardown
@@ -583,10 +576,10 @@ class Gem::TestCase < Test::Unit::TestCase
system @git, "add", gemspec
system @git, "commit", "-a", "-m", "a non-empty commit message", "--quiet"
- head = Gem::Util.popen(@git, "rev-parse", "master").strip
+ head = Gem::Util.popen(@git, "rev-parse", "HEAD").strip
end
- return name, git_spec.version, directory, head
+ [name, git_spec.version, directory, head]
end
##
@@ -599,7 +592,7 @@ class Gem::TestCase < Test::Unit::TestCase
end
def in_path?(executable) # :nodoc:
- return true if %r{\A([A-Z]:|/)} =~ executable && File.exist?(executable)
+ return true if %r{\A([A-Z]:|/)}.match?(executable) && File.exist?(executable)
ENV["PATH"].split(File::PATH_SEPARATOR).any? do |directory|
File.exist? File.join directory, executable
@@ -621,17 +614,17 @@ class Gem::TestCase < Test::Unit::TestCase
end
end
- gem = File.join(@tempdir, File.basename(gem)).tap(&Gem::UNTAINT)
+ gem = File.join(@tempdir, File.basename(gem))
end
- Gem::Installer.at(gem, options.merge({ :wrappers => true })).install
+ Gem::Installer.at(gem, options.merge({ wrappers: true })).install
end
##
# Builds and installs the Gem::Specification +spec+ into the user dir
def install_gem_user(spec)
- install_gem spec, :user_install => true
+ install_gem spec, user_install: true
end
##
@@ -643,7 +636,7 @@ class Gem::TestCase < Test::Unit::TestCase
def ask_if_ok(spec)
true
end
- end.new(spec.name, :executables => true, :user_install => true).uninstall
+ end.new(spec.name, executables: true, user_install: true).uninstall
end
##
@@ -660,7 +653,7 @@ class Gem::TestCase < Test::Unit::TestCase
# Reads a Marshal file at +path+
def read_cache(path)
- File.open path.dup.tap(&Gem::UNTAINT), "rb" do |io|
+ File.open path.dup, "rb" do |io|
Marshal.load io.read
end
end
@@ -702,11 +695,8 @@ class Gem::TestCase < Test::Unit::TestCase
# Load a YAML file, the psych 3 way
def load_yaml_file(file)
- if Psych.respond_to?(:unsafe_load_file)
- Psych.unsafe_load_file(file)
- else
- Psych.load_file(file)
- end
+ require "rubygems/config_file"
+ Gem::ConfigFile.load_with_rubygems_config_hash(File.read(file))
end
def all_spec_names
@@ -747,7 +737,7 @@ class Gem::TestCase < Test::Unit::TestCase
Gem::Specification.reset
- return spec
+ spec
end
##
@@ -798,7 +788,7 @@ class Gem::TestCase < Test::Unit::TestCase
def install_specs(*specs)
specs.each do |spec|
- Gem::Installer.for_spec(spec, :force => true).install
+ Gem::Installer.for_spec(spec, force: true).install
end
Gem.searcher = nil
@@ -809,7 +799,7 @@ class Gem::TestCase < Test::Unit::TestCase
def install_default_gems(*specs)
specs.each do |spec|
- installer = Gem::Installer.for_spec(spec, :install_as_default => true)
+ installer = Gem::Installer.for_spec(spec, install_as_default: true)
installer.install
Gem.register_default_spec(spec)
end
@@ -882,7 +872,7 @@ class Gem::TestCase < Test::Unit::TestCase
FileUtils.rm spec.spec_file
end
- return spec
+ spec
end
##
@@ -949,7 +939,7 @@ class Gem::TestCase < Test::Unit::TestCase
@a1 = quick_gem "a", "1" do |s|
s.files = %w[lib/code.rb]
s.require_paths = %w[lib]
- s.date = Gem::Specification::TODAY - 86400
+ s.date = Gem::Specification::TODAY - 86_400
s.homepage = "http://a.example.com"
s.email = %w[example@example.com example2@example.com]
s.authors = %w[Example Example2]
@@ -992,15 +982,15 @@ Also, a list:
util_build_gem @a2_pre
end
- write_file File.join(*%W[gems #{@a1.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@a2.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@a3a.original_name} lib code.rb])
+ write_file File.join(*%W[gems #{@a1.original_name} lib code.rb])
+ write_file File.join(*%W[gems #{@a2.original_name} lib code.rb])
+ write_file File.join(*%W[gems #{@a3a.original_name} lib code.rb])
write_file File.join(*%W[gems #{@a_evil9.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@b2.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@x.original_name} lib code.rb])
- write_file File.join(*%W[gems #{@dep_x.original_name} lib code.rb])
+ write_file File.join(*%W[gems #{@b2.original_name} lib code.rb])
+ write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb])
+ write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb])
+ write_file File.join(*%W[gems #{@x.original_name} lib code.rb])
+ write_file File.join(*%W[gems #{@dep_x.original_name} lib code.rb])
[@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1, @x, @dep_x].each do |spec|
util_build_gem spec
@@ -1060,20 +1050,18 @@ Also, a list:
spec_fetcher.prerelease_specs[@uri] << spec.name_tuple
end
- # HACK for test_download_to_cache
+ # HACK: for test_download_to_cache
unless Gem::RemoteFetcher === @fetcher
v = Gem.marshal_version
- specs = all.map {|spec| spec.name_tuple }
+ specs = all.map(&:name_tuple)
s_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic specs
- latest_specs = latest.map do |spec|
- spec.name_tuple
- end
+ latest_specs = latest.map(&:name_tuple)
l_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic latest_specs
- prerelease_specs = prerelease.map {|spec| spec.name_tuple }
+ prerelease_specs = prerelease.map(&:name_tuple)
p_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic prerelease_specs
@fetcher.data["#{@gem_repo}specs.#{v}.gz"] = s_zip
@@ -1109,12 +1097,12 @@ Also, a list:
Gem.send :remove_instance_variable, :@ruby_version
end
- @RUBY_VERSION = RUBY_VERSION
- @RUBY_PATCHLEVEL = RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
- @RUBY_REVISION = RUBY_REVISION if defined?(RUBY_REVISION)
- @RUBY_DESCRIPTION = RUBY_DESCRIPTION
- @RUBY_ENGINE = RUBY_ENGINE
- @RUBY_ENGINE_VERSION = RUBY_ENGINE_VERSION if defined?(RUBY_ENGINE_VERSION)
+ @ruby_version = RUBY_VERSION
+ @ruby_patchlevel = RUBY_PATCHLEVEL
+ @ruby_revision = RUBY_REVISION
+ @ruby_description = RUBY_DESCRIPTION
+ @ruby_engine = RUBY_ENGINE
+ @ruby_engine_version = RUBY_ENGINE_VERSION
util_clear_RUBY_VERSION
@@ -1123,58 +1111,27 @@ Also, a list:
Object.const_set :RUBY_REVISION, revision
Object.const_set :RUBY_DESCRIPTION, description
Object.const_set :RUBY_ENGINE, engine
- Object.const_set :RUBY_ENGINE_VERSION, engine_version if engine_version
+ Object.const_set :RUBY_ENGINE_VERSION, engine_version
end
def util_restore_RUBY_VERSION
util_clear_RUBY_VERSION
- Object.const_set :RUBY_VERSION, @RUBY_VERSION
- Object.const_set :RUBY_PATCHLEVEL, @RUBY_PATCHLEVEL if
- defined?(@RUBY_PATCHLEVEL)
- Object.const_set :RUBY_REVISION, @RUBY_REVISION if
- defined?(@RUBY_REVISION)
- Object.const_set :RUBY_DESCRIPTION, @RUBY_DESCRIPTION
- Object.const_set :RUBY_ENGINE, @RUBY_ENGINE
- Object.const_set :RUBY_ENGINE_VERSION, @RUBY_ENGINE_VERSION if
- defined?(@RUBY_ENGINE_VERSION)
+ Object.const_set :RUBY_VERSION, @ruby_version
+ Object.const_set :RUBY_PATCHLEVEL, @ruby_patchlevel
+ Object.const_set :RUBY_REVISION, @ruby_revision
+ Object.const_set :RUBY_DESCRIPTION, @ruby_description
+ Object.const_set :RUBY_ENGINE, @ruby_engine
+ Object.const_set :RUBY_ENGINE_VERSION, @ruby_engine_version
end
def util_clear_RUBY_VERSION
Object.send :remove_const, :RUBY_VERSION
- Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
- Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
- Object.send :remove_const, :RUBY_DESCRIPTION if defined?(RUBY_DESCRIPTION)
+ Object.send :remove_const, :RUBY_PATCHLEVEL
+ Object.send :remove_const, :RUBY_REVISION
+ Object.send :remove_const, :RUBY_DESCRIPTION
Object.send :remove_const, :RUBY_ENGINE
- Object.send :remove_const, :RUBY_ENGINE_VERSION if defined?(RUBY_ENGINE_VERSION)
- end
-
- ##
- # Is this test being run on a Windows platform?
-
- def self.win_platform?
- Gem.win_platform?
- end
-
- ##
- # Is this test being run on a Windows platform?
-
- def win_platform?
- Gem.win_platform?
- end
-
- ##
- # Is this test being run on a Java platform?
-
- def self.java_platform?
- Gem.java_platform?
- end
-
- ##
- # Is this test being run on a Java platform?
-
- def java_platform?
- Gem.java_platform?
+ Object.send :remove_const, :RUBY_ENGINE_VERSION
end
##
@@ -1186,28 +1143,25 @@ Also, a list:
end
##
- # Returns whether or not we're on a version of Ruby built with VC++ (or
- # Borland) versus Cygwin, Mingw, etc.
+ # see ::vc_windows?
def vc_windows?
- RUBY_PLATFORM.match("mswin")
+ self.class.vc_windows?
end
##
- # Is this test being run on a ruby/ruby repository?
- #
+ # Is this test being run on a version of Ruby built with mingw?
- def ruby_repo?
- !ENV["GEM_COMMAND"].nil?
+ def mingw_windows?
+ RUBY_PLATFORM.match("mingw")
end
##
- # Returns the make command for the current platform. For versions of Ruby
- # built on MS Windows with VC++ or Borland it will return 'nmake'. On all
- # other platforms, including Cygwin, it will return 'make'.
+ # Is this test being run on a ruby/ruby repository?
+ #
- def self.make_command
- ENV["make"] || ENV["MAKE"] || (vc_windows? ? "nmake" : "make")
+ def ruby_repo?
+ !ENV["GEM_COMMAND"].nil?
end
##
@@ -1235,22 +1189,6 @@ Also, a list:
end
##
- # Allows tests to use a random (but controlled) port number instead of
- # a hardcoded one. This helps CI tools when running parallels builds on
- # the same builder slave.
-
- def self.process_based_port
- @@process_based_port ||= 8000 + $$ % 1000
- end
-
- ##
- # See ::process_based_port
-
- def process_based_port
- self.class.process_based_port
- end
-
- ##
# Allows the proper version of +rake+ to be used for the test.
def build_rake_in(good=true)
@@ -1276,7 +1214,7 @@ Also, a list:
ruby = ENV["RUBY"]
return ruby if ruby
ruby = "ruby"
- rubyexe = "#{ruby}.exe"
+ rubyexe = "#{ruby}#{RbConfig::CONFIG["EXEEXT"]}"
3.times do
if File.exist?(ruby) && File.executable?(ruby) && !File.directory?(ruby)
@@ -1303,6 +1241,10 @@ Also, a list:
$LOAD_PATH.find {|p| p == File.dirname($LOADED_FEATURES.find {|f| f.end_with?("/rubygems.rb") }) }
end
+ def bundler_path
+ $LOAD_PATH.find {|p| p == File.dirname($LOADED_FEATURES.find {|f| f.end_with?("/bundler.rb") }) }
+ end
+
def with_clean_path_to_ruby
orig_ruby = Gem.ruby
@@ -1323,32 +1265,29 @@ Also, a list:
end
def silence_warnings
- old_verbose, $VERBOSE = $VERBOSE, false
+ old_verbose = $VERBOSE
+ $VERBOSE = false
yield
ensure
$VERBOSE = old_verbose
end
- class << self
- # :nodoc:
- ##
- # Return the join path, with escaping backticks, dollars, and
- # double-quotes. Unlike `shellescape`, equal-sign is not escaped.
-
- private
+ # :nodoc:
+ ##
+ # Return the join path, with escaping backticks, dollars, and
+ # double-quotes. Unlike `shellescape`, equal-sign is not escaped.
- def escape_path(*path)
- path = File.join(*path)
- if %r{\A[-+:/=@,.\w]+\z} =~ path
- path
- else
- "\"#{path.gsub(/[`$"]/, '\\&')}\""
- end
+ def self.escape_path(*path)
+ path = File.join(*path)
+ if %r{\A[-+:/=@,.\w]+\z}.match?(path)
+ path
+ else
+ "\"#{path.gsub(/[`$"]/, '\\&')}\""
end
end
- @@good_rake = "#{rubybin} #{escape_path(__dir__, 'good_rake.rb')}"
- @@bad_rake = "#{rubybin} #{escape_path(__dir__, 'bad_rake.rb')}"
+ @@good_rake = "#{rubybin} #{escape_path(__dir__, "good_rake.rb")}"
+ @@bad_rake = "#{rubybin} #{escape_path(__dir__, "bad_rake.rb")}"
##
# Construct a new Gem::Dependency.
@@ -1431,12 +1370,12 @@ Also, a list:
#
# Yields the +specification+ to the block, if given
- def vendor_gem(name = "a", version = 1)
+ def vendor_gem(name = "a", version = 1, &block)
directory = File.join "vendor", name
FileUtils.mkdir_p directory
- save_gemspec name, version, directory
+ save_gemspec name, version, directory, &block
end
##
@@ -1454,7 +1393,7 @@ Also, a list:
io.write vendor_spec.to_ruby
end
- return name, vendor_spec.version, directory
+ [name, vendor_spec.version, directory]
end
##
@@ -1534,7 +1473,11 @@ Also, a list:
# <tt>test/rubygems/</tt>.
def self.cert_path(cert_name)
- if 32 == (Time.at(2**32) rescue 32)
+ if begin
+ Time.at(2**32)
+ rescue StandardError
+ 32
+ end == 32
cert_file = "#{__dir__}/#{cert_name}_cert_32.pem"
return cert_file if File.exist? cert_file
@@ -1564,7 +1507,7 @@ Also, a list:
# :stopdoc:
# only available in RubyGems tests
- PRIVATE_KEY_PASSPHRASE = "Foo bar".freeze
+ PRIVATE_KEY_PASSPHRASE = "Foo bar"
begin
PRIVATE_KEY = load_key "private"
@@ -1583,6 +1526,23 @@ 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
@@ -1604,7 +1564,7 @@ class Object
if val_or_callable.respond_to? :call
val_or_callable.call(*args, &blk)
else
- blk.call(*block_args) if blk
+ blk&.call(*block_args)
val_or_callable
end
end
diff --git a/test/rubygems/installer_test_case.rb b/test/rubygems/installer_test_case.rb
index 6211cfff16..abddcbe848 100644
--- a/test/rubygems/installer_test_case.rb
+++ b/test/rubygems/installer_test_case.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/installer"
@@ -110,7 +111,7 @@ class Gem::InstallerTestCase < Gem::TestCase
def setup_base_installer(force = true)
@gem = setup_base_gem
- util_installer @spec, @gemhome, false, force
+ util_installer @spec, @gemhome, force
end
##
@@ -162,7 +163,7 @@ class Gem::InstallerTestCase < Gem::TestCase
@user_gem = @user_spec.cache_file
- util_installer @user_spec, Gem.user_dir, :user
+ Gem::Installer.at @user_gem, user_install: true
end
##
@@ -214,18 +215,16 @@ class Gem::InstallerTestCase < Gem::TestCase
end
end
- Gem::Installer.at @gem, :force => force
+ Gem::Installer.at @gem, force: force
end
##
- # Creates an installer for +spec+ that will install into +gem_home+. If
- # +user+ is true a user-install will be performed.
+ # Creates an installer for +spec+ that will install into +gem_home+.
- def util_installer(spec, gem_home, user=false, force=true)
+ def util_installer(spec, gem_home, force=true)
Gem::Installer.at(spec.cache_file,
- :install_dir => gem_home,
- :user_install => user,
- :force => force)
+ install_dir: gem_home,
+ force: force)
end
@@symlink_supported = nil
diff --git a/test/rubygems/invalid_issuer_cert.pem b/test/rubygems/invalid_issuer_cert.pem
index ea11756bb0..5cb9d22a87 100644
--- a/test/rubygems/invalid_issuer_cert.pem
+++ b/test/rubygems/invalid_issuer_cert.pem
@@ -1,20 +1,20 @@
-----BEGIN CERTIFICATE-----
-MIIDUTCCAjmgAwIBAgIBCjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDMDCCAhigAwIBAgIBCjANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoYDzk5
OTkxMjMxMjM1OTU5WjArMRAwDgYDVQQDDAdpbnZhbGlkMRcwFQYKCZImiZPyLGQB
-GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM0ycOSh
-SOKDGhDlPZ3+JAWwp7KB2ps/VlLhIsZl0uAHzCAGPNI1I46gmla1g7Gh429fYeJ0
-VgeRTxI/rRWNJ0HX2I9jhaJqAkiOqV5Rk6RkJv/0lU1VSu1IBjKRmV6qXiNeBWA8
-duEPNdd6zKX7UoKcYgmG3BMDuEy67AqWUgZOjc9WUnd6i+mwWciMuNqul69vMvB5
-go4c/rgtp1Y3PhLDIrheYP9s+Bza1MNp0FUFlrPnL5gzZTsP/IX2u7kF3CEhKCZX
-ZPX0oZc/pbqIS2OuQ9T6ft6StSwA+9IhAyCeJ9bGyBYK78SyiSfELKyGKbk74SmR
-AqjpN2PJX3o/gk8CAwEAAaN/MH0wGgYDVR0RBBMwEYEPaW52YWxpZEBleGFtcGxl
-MB0GA1UdDgQWBBST34uxqPfsv8w/+cc9gEChWnnZTjAfBgNVHSMEGDAWgBRfQ272
-mo5FJeki4303XqTVNgKFGzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIC
-BDANBgkqhkiG9w0BAQUFAAOCAQEAArzlvf6q7By19O1hSabH9jmnMwxJ7rZT8lr9
-G7gt18nQxgpeY6JczRmZ9wCWpoIE+ohHJ56XVUFsWilVIZ9o7+ASpZlxIErq3pzY
-b8SYoOZtGzz6IpucdnaZixOvqXpQQtAsat1/Y+OLaMiyGwzT2VvDkPHsqBphU2qo
-n/WwaYPTQF/yqMVM63HLm34+UwzHISChoo1ZT22S3jdWSso2KrLuRN+mfYwgGm26
-h0zRmr3SmfP8yCJhfkTcAUSR/XGLN8KOTXpjzMgsFLqTIeIbTd0e7APIh/6nBqpr
-GAudXuQMlPdcYQIT8CBZJ6b36ahb+n+1oc5C9ULaeEwEZtYyLQ==
+GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPEZZzId
+y0m1jSbcHBwUc0MLpq/+JJdwLpGrjD35CuI7DNP0MiH+mNHblyTqMadB3font26k
+QFIjDZtc1es1Zvt4mNo1lScQsvbVGRFDQK2/xdZ0O0GbK31C7IJ2Boa93F+74f7N
+eD6LKn++SWCxHNCKV83RumQ6diG/WdUZQu8k9xjpRywI2u2EwNDETkbhGamj5zNj
+7a8pcPyifBxzTiZ9FZvWVaCEODvdIrF4NdIteXyYEQwDRLWD/nQ9Z9wbw4KQCtA/
+UUd+rObocjveau1wLiZryumhZRwwIKZU4+aaANYTFb3tbmUKnoR9aLavKvxEnlF0
+5kHo9xcHoS5ftw8CAwEAAaNeMFwwGgYDVR0RBBMwEYEPaW52YWxpZEBleGFtcGxl
+MB0GA1UdDgQWBBR17dM2zZQQPor/k6N4/JXerWXhSDAPBgNVHRMBAf8EBTADAQH/
+MA4GA1UdDwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEALrT6pmN79vdBA80a
+f8C1DnWAYNyXskmskWPVMnTtgrDGQkqz0Uqq7nBdWK75FiBjk3XAOiDonZegvho+
+NZUnotUFyTpkkn95q1qpkMwgTufamQlxsBxkDZLPiWqvZS4guSucVgZeEtEOy0R0
+AKXA1SZmhC7472z+pwXprGj86K4SX7w15LxsQ0wDP5qduKFItNo/CnBEP5w87/Eq
+nxSbUN3dt7Glqt0iIp/I4mZlA4OnvtKfqTitATKOnBvHxIzvm9/6BVItjET8DRXv
+2ZEVvEcnkNNRKwNbqtI3V7AzB3lf3E4nb86gFh/GLI2XRN4LlWZQ4PmyE22B8IaZ
+vpqxaQ==
-----END CERTIFICATE-----
diff --git a/test/rubygems/invalid_issuer_cert_32.pem b/test/rubygems/invalid_issuer_cert_32.pem
index bb73772735..2b71179270 100644
--- a/test/rubygems/invalid_issuer_cert_32.pem
+++ b/test/rubygems/invalid_issuer_cert_32.pem
@@ -1,20 +1,20 @@
-----BEGIN CERTIFICATE-----
-MIIDTzCCAjegAwIBAgIBCzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDLjCCAhagAwIBAgIBCzANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoXDTM4
MDExOTAzMTQwN1owKzEQMA4GA1UEAwwHaW52YWxpZDEXMBUGCgmSJomT8ixkARkW
-B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNMnDkoUji
-gxoQ5T2d/iQFsKeygdqbP1ZS4SLGZdLgB8wgBjzSNSOOoJpWtYOxoeNvX2HidFYH
-kU8SP60VjSdB19iPY4WiagJIjqleUZOkZCb/9JVNVUrtSAYykZleql4jXgVgPHbh
-DzXXesyl+1KCnGIJhtwTA7hMuuwKllIGTo3PVlJ3eovpsFnIjLjarpevbzLweYKO
-HP64LadWNz4SwyK4XmD/bPgc2tTDadBVBZaz5y+YM2U7D/yF9ru5BdwhISgmV2T1
-9KGXP6W6iEtjrkPU+n7ekrUsAPvSIQMgnifWxsgWCu/EsoknxCyshim5O+EpkQKo
-6TdjyV96P4JPAgMBAAGjfzB9MBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBsZTAd
-BgNVHQ4EFgQUk9+Lsaj37L/MP/nHPYBAoVp52U4wHwYDVR0jBBgwFoAUX0Nu9pqO
-RSXpIuN9N16k1TYChRswDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQw
-DQYJKoZIhvcNAQEFBQADggEBAMXxi62wMgtxERL3Snu9wB+qPBY0oaZn0gxcqH8x
-IKbBa+ib63l3UX0vVqzHZlDYxBLTJicU3Cwr7Tm+GHPg/oMkqufxeFZPl/n4uvwY
-iogyY5RMsx6C3WqdhA3x+tg04xMxDnAptRWMT4n19myPEadasLBwOqHeXtpc/v2N
-XnNFlX3q8NB3AQya+Sp4fxL1fp9sCYlyJolS4dNZGOW4qC5I2GQGlduFom5oOyTB
-QyWPs+McRfanWrZgmoViu5x+N7l/xRTJ7WEa9DDqZbPxjCaXrKIyteSIJgqsdqwy
-0N+4pygu9VOdQNfQvI2jkxyDZI6rZ/YEr8sxhOKmzvaW0kc=
+B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDxGWcyHctJ
+tY0m3BwcFHNDC6av/iSXcC6Rq4w9+QriOwzT9DIh/pjR25ck6jGnQd36J7dupEBS
+Iw2bXNXrNWb7eJjaNZUnELL21RkRQ0Ctv8XWdDtBmyt9QuyCdgaGvdxfu+H+zXg+
+iyp/vklgsRzQilfN0bpkOnYhv1nVGULvJPcY6UcsCNrthMDQxE5G4Rmpo+czY+2v
+KXD8onwcc04mfRWb1lWghDg73SKxeDXSLXl8mBEMA0S1g/50PWfcG8OCkArQP1FH
+fqzm6HI73mrtcC4ma8rpoWUcMCCmVOPmmgDWExW97W5lCp6EfWi2ryr8RJ5RdOZB
+6PcXB6EuX7cPAgMBAAGjXjBcMBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBsZTAd
+BgNVHQ4EFgQUde3TNs2UED6K/5OjePyV3q1l4UgwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADggEBAGolEDY9meTGpP7j3Meb
+pxtLX/JYPiTMqQR+FOOdGJlXg4V9syMBYUMmUj3yEPnpBFmDgDtBaH+OQcFuvf43
+mQYOQoTJD6OpC08fkPdVw56Em+cuUCXtDDYY4gc+nVRKk4+tJqkizHNAazqKkZoQ
+PaHaCfXsrMGPLXxh/kbk14ESU9pL0LShh/bNn68hlAKwN2ctTSlfm81QgbNX83d1
+6kLSckj/9B1ksi6ks/eHkHWeMaiJe8H3vAU6PE6NeU3WRZY1ulSGOPleYfJA99fq
+z9yks8IxwMzubJStq2sQ0n6gu3XS4Qu0sn3ih0TwRyUOSQkWa2Bf5SwUZ3/YJ25S
+Wkw=
-----END CERTIFICATE-----
diff --git a/test/rubygems/invalid_key.pem b/test/rubygems/invalid_key.pem
index 74bedabcda..bc02147403 100644
--- a/test/rubygems/invalid_key.pem
+++ b/test/rubygems/invalid_key.pem
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAzTJw5KFI4oMaEOU9nf4kBbCnsoHamz9WUuEixmXS4AfMIAY8
-0jUjjqCaVrWDsaHjb19h4nRWB5FPEj+tFY0nQdfYj2OFomoCSI6pXlGTpGQm//SV
-TVVK7UgGMpGZXqpeI14FYDx24Q8113rMpftSgpxiCYbcEwO4TLrsCpZSBk6Nz1ZS
-d3qL6bBZyIy42q6Xr28y8HmCjhz+uC2nVjc+EsMiuF5g/2z4HNrUw2nQVQWWs+cv
-mDNlOw/8hfa7uQXcISEoJldk9fShlz+luohLY65D1Pp+3pK1LAD70iEDIJ4n1sbI
-FgrvxLKJJ8QsrIYpuTvhKZECqOk3Y8lfej+CTwIDAQABAoIBAFo5I4pjoDh4jK2B
-HmapqA0Yb6P9lLFOWBZ5B2FUxDPdOdOa6oNC+i9sTnBxv0YLeIUv20pG/My3B51u
-ghxHxEsfLQlfKRMQqZBdqfrew5w0rTE9yagHKLrMQG1bt6P4JQxH+vUloN+0YGgu
-hm005EKpoDGwKnPx3sdeKQs+rTI37fGLw40ZPSod2B7UkSna4/u/uXa1yFbONlqq
-P4ozsDd1xoCaBJfwie2h93KneSPwyHHumlVgbFAJcQycuD5qproYbea9PppppQ+4
-17M9ccuQpS2j9rZWgk7+KqwLrYqzajmtHoQH4zkBYd0JQ4ywGKg307xDhppMZpq3
-uMqnXgECgYEA9iYB7vX91Q3HsRtUAd0aZ91lDIv9RXBP+PuK3OUrtChdtZx7Mih3
-uTgtfVEnP7bxgnPpwecnF4Ncginuu7TBtxjoztFjuFNzk/8Fz/J3i/H3oB0SdjhL
-uqVa6P4hPak7FnWynZHivuuIe+eKYLvK0TCMbYaz6G81xi0Whtbm498CgYEA1Wja
-PgscP/9YykCC6eRP+ixo6chGzSNJR+WRW9CJYpXEicPlaT5AI3nSZVXXSLvXIbq9
-NoExPu47pDzr9Gd02qYmFWUOolUa21W4s/x4d7lU+wJzS6ZNTFoC8woZagL2kZ5G
-+we5ifbUz7eG+ahZODGMGA9BJVT3PI6zPdKtr5ECgYEAy0ORnypGBXUOrUMa+TsD
-fjfGJTlI2dmoQLw/7K/Wijw3PizNUxs12p74eZ7VYXkKMKbVpwjiMDmK3/YOrbTT
-rwaD4Z3p0iIftFwJCbJ5Y/hZez/mqfdNGgFIdFS/UHL6V060RAhfjTdlCqSmkcEh
-9+M2Y4+z60JCzrcW/hxiqFMCgYEAj9ntwoSatkjZAPwbQq2ze18UGQH3N6/hZaVJ
-JiqbcOijYnm52gcsFL25JLWIOG7lxMarZGIRX+oWKc8m/cf+7KOyaBmGk8XqJI7T
-wf8c9RboQYqVTRj8YcsK0eis2NjGe8HE9tFuL6FCMgHz6bWg7k/3rwAZWaC8RwWp
-rLKmgQECgYBXGjEvogVeYMgnpzjoaa99wvfp6FtbRx1jZ+FOSBoH5uCRDalD5Q16
-0UVnoPcnj0Hi7Hvvl6jTLesRW/LDra5Hqyxs4yuSBagEUFv/PvY0eYGZ5egGZgaa
-PlVmxgk33xYXar8wGHLkstwqZY/OqT89cKvJqeLKMb0G2Re13oPVww==
+MIIEowIBAAKCAQEA8RlnMh3LSbWNJtwcHBRzQwumr/4kl3AukauMPfkK4jsM0/Qy
+If6Y0duXJOoxp0Hd+ie3bqRAUiMNm1zV6zVm+3iY2jWVJxCy9tUZEUNArb/F1nQ7
+QZsrfULsgnYGhr3cX7vh/s14Posqf75JYLEc0IpXzdG6ZDp2Ib9Z1RlC7yT3GOlH
+LAja7YTA0MRORuEZqaPnM2Ptrylw/KJ8HHNOJn0Vm9ZVoIQ4O90isXg10i15fJgR
+DANEtYP+dD1n3BvDgpAK0D9RR36s5uhyO95q7XAuJmvK6aFlHDAgplTj5poA1hMV
+ve1uZQqehH1otq8q/ESeUXTmQej3FwehLl+3DwIDAQABAoIBAAQ1PSEES8XZESzH
+nwakcBCQValGW8LNi+/cmSGEb7qxbNC5jIhzBkgfYjIcPkqc3TAeXQFlhNPfgGog
+7YDh7o60Ck2WAtOVjdy+AmZ+kH9Cf271719+mFHi3E2N8XY3k8Q9+2dJlHAvA0pg
+eq0L2k9kzWcuYmeZF50Q1xNfkf9U0qkb6tbx15NOGFhQMUZ/mMcbYifW/bQnU2YO
+2vgxWFDItk0c82gpi/uo22gu0TjhcBp/ByKMgXV8xrLCW7Lsh1DvJ3LtigD0Zp5s
+XtdXcF4KOo81VeUijDbByIQQJTxBlfmgdcyarAb7kV107wvDh55Xd8m68lZUrkj5
+tc3dRf0CgYEA+crRUXgtdeiHqN5gZRg6MF6S5yxFiAaKgeeKm/x/2xpMmoiyWhFv
+tK1DLxRHEGiFuWc9IGgrWu2udEg8VE4j2EExvtFi/w3lSHxBArjeq7oCabnDk261
+lRCNzYb0HU5UZL3vBsHW8pCdnDfaOxlrT2+cDVN7LHd20DsIZROG7T0CgYEA9xdH
+wSNsHqxcB44A7iNNvHxhU3Vi6QCIpzp8sfjc/fd7Ghe/MIn67gs5XPtT+DvQME0N
+4hNEy2GmbHjVJQXqlf4VSWdFJ1RnKwL+4rnOiWq5sNrxmlXuTvOTRLimpjOsLKCR
+G3dgKXiH7/qU9zjLljKOWgo7gqv3cPrPIL8H0jsCgYEAp99SRTpK8w7O/QJWLhrW
+IGOuvoXWRNCAjUUatjI/ivRlvwVXN4i4VeiLWjx6deCI3k0vm3PmjzllIOjbAp1x
+IYjO8bqumVKxYMGAv1+W5jogHQWnFpI0nnV9lz63GGrn9Lxgw13KI0JlafNvSoCO
+ydfsPFh6UywGQXMq9SLmbtECgYAHWC3N09u23bCumM32Rh5dZ+UMsgSKoHVvYxGp
+yJfpBJ4oHGSWcMOAp9zAosfQLRb3GJM9EQ2ObgygVMchHpfmdXL0h5lKnfujD6e7
+3YICG6YBV8CusbcvqZXLCSIK9qY7fVpS0q2NDgQcYfpjjtCeWkpY6szyCWKFfS8C
+7iqxWQKBgBIwdnksccXP01svXJ0tMhiAKx1jKY/aJBPIpcSqxTFNe2WpgzynRpUg
++MKAO2Ed6Rec3TTefGRNKDPb5OUsYZUMHeNbIJ1Y1S2pORRffrE3TFWBUM0LkOTj
+r4Dl5bcnDRL93Phbx7MAmjMO3TZWbQGfEgDuqk3sS1QzKMJnBLAO
-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/invalid_signer_cert.pem b/test/rubygems/invalid_signer_cert.pem
index 7f8b5cc727..59364ee51b 100644
--- a/test/rubygems/invalid_signer_cert.pem
+++ b/test/rubygems/invalid_signer_cert.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDEDCCAfigAwIBAgIBDjANBgkqhkiG9w0BAQUFADArMRAwDgYDVQQDDAdpbnZh
+MIIDEDCCAfigAwIBAgIBDjANBgkqhkiG9w0BAQsFADArMRAwDgYDVQQDDAdpbnZh
bGlkMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAgFw0xMjAxMDEwMDAwMDBaGA85
OTk5MTIzMTIzNTk1OVowKzEQMA4GA1UEAwwHaW52YWxpZDEXMBUGCgmSJomT8ixk
-ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNMnDk
-oUjigxoQ5T2d/iQFsKeygdqbP1ZS4SLGZdLgB8wgBjzSNSOOoJpWtYOxoeNvX2Hi
-dFYHkU8SP60VjSdB19iPY4WiagJIjqleUZOkZCb/9JVNVUrtSAYykZleql4jXgVg
-PHbhDzXXesyl+1KCnGIJhtwTA7hMuuwKllIGTo3PVlJ3eovpsFnIjLjarpevbzLw
-eYKOHP64LadWNz4SwyK4XmD/bPgc2tTDadBVBZaz5y+YM2U7D/yF9ru5BdwhISgm
-V2T19KGXP6W6iEtjrkPU+n7ekrUsAPvSIQMgnifWxsgWCu/EsoknxCyshim5O+Ep
-kQKo6TdjyV96P4JPAgMBAAGjPTA7MBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBs
-ZTAdBgNVHQ4EFgQUk9+Lsaj37L/MP/nHPYBAoVp52U4wDQYJKoZIhvcNAQEFBQAD
-ggEBAGJurQiRw3Vb2LPUhoL9BHyPy8TY+ZXz7eZyzf72saiATkHTuainb9jvLTzf
-9ZNYNnjxGNwR4QnDhlh8Vb8vHaYfQGGwiLhd5ZbKjkid/41Y9XmNh+oHCrmwGcS6
-vX4QmTTmPQRBZ2Ilckr+wb1fdpLYk0wW/JFMFdAzp1OO3kP23hYElqia6qeJGw4k
-4fe9d56huHHptSJrlMTjHwaqXq6QRjfjF5Za1unCjxQMO2vNQC/dUYRaq/M0kwFN
-6A2xHKukkgA9cyjVpFVpxhE3/iFz8OE1GZg7VVcT+Jzhhxaajubpe+ZtDN5rbln/
-NI4WP/ZM3cnxVrHG84G3AYRpkhc=
+ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDxGWcy
+HctJtY0m3BwcFHNDC6av/iSXcC6Rq4w9+QriOwzT9DIh/pjR25ck6jGnQd36J7du
+pEBSIw2bXNXrNWb7eJjaNZUnELL21RkRQ0Ctv8XWdDtBmyt9QuyCdgaGvdxfu+H+
+zXg+iyp/vklgsRzQilfN0bpkOnYhv1nVGULvJPcY6UcsCNrthMDQxE5G4Rmpo+cz
+Y+2vKXD8onwcc04mfRWb1lWghDg73SKxeDXSLXl8mBEMA0S1g/50PWfcG8OCkArQ
+P1FHfqzm6HI73mrtcC4ma8rpoWUcMCCmVOPmmgDWExW97W5lCp6EfWi2ryr8RJ5R
+dOZB6PcXB6EuX7cPAgMBAAGjPTA7MBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBs
+ZTAdBgNVHQ4EFgQUde3TNs2UED6K/5OjePyV3q1l4UgwDQYJKoZIhvcNAQELBQAD
+ggEBACbQA7m+zqdAE1/GrJKcXnC/Ujr1tu6rGpe0uExTwySptgVieUGAOvzlLLrY
+r2b/nGmK4bgHkeDPSVuC3F8NhgESvPTuXFSw+DU+1m+mhHxdpW30uSbbebgqV5Ea
+GpckCZj1SEdsn/1SDauXCmkrs/MBuK49mYXv3jejX0Rp0STu1NxnU13yrKF0MtrL
+fzZ/QF8bOZdg5DwtqMwhDPp72x58KpqAPN9GgdlsTiwOMGy4avds1g5KMGmkK8pK
+6I58NEMCOuN4CxFK4oWD9xuD4j+wtHy/UYxqor4rn+UKYHfr5fWtAyRJ3gD8vMUu
+C+Nl2vB8t4OVwS5FCcn0ZK18bPU=
-----END CERTIFICATE-----
diff --git a/test/rubygems/invalid_signer_cert_32.pem b/test/rubygems/invalid_signer_cert_32.pem
index 657608e503..97feb8fd0a 100644
--- a/test/rubygems/invalid_signer_cert_32.pem
+++ b/test/rubygems/invalid_signer_cert_32.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDDjCCAfagAwIBAgIBDzANBgkqhkiG9w0BAQUFADArMRAwDgYDVQQDDAdpbnZh
+MIIDDjCCAfagAwIBAgIBDzANBgkqhkiG9w0BAQsFADArMRAwDgYDVQQDDAdpbnZh
bGlkMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAeFw0xMjAxMDEwMDAwMDBaFw0z
ODAxMTkwMzE0MDdaMCsxEDAOBgNVBAMMB2ludmFsaWQxFzAVBgoJkiaJk/IsZAEZ
-FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzTJw5KFI
-4oMaEOU9nf4kBbCnsoHamz9WUuEixmXS4AfMIAY80jUjjqCaVrWDsaHjb19h4nRW
-B5FPEj+tFY0nQdfYj2OFomoCSI6pXlGTpGQm//SVTVVK7UgGMpGZXqpeI14FYDx2
-4Q8113rMpftSgpxiCYbcEwO4TLrsCpZSBk6Nz1ZSd3qL6bBZyIy42q6Xr28y8HmC
-jhz+uC2nVjc+EsMiuF5g/2z4HNrUw2nQVQWWs+cvmDNlOw/8hfa7uQXcISEoJldk
-9fShlz+luohLY65D1Pp+3pK1LAD70iEDIJ4n1sbIFgrvxLKJJ8QsrIYpuTvhKZEC
-qOk3Y8lfej+CTwIDAQABoz0wOzAaBgNVHREEEzARgQ9pbnZhbGlkQGV4YW1wbGUw
-HQYDVR0OBBYEFJPfi7Go9+y/zD/5xz2AQKFaedlOMA0GCSqGSIb3DQEBBQUAA4IB
-AQA6WW6YyykIJmVFW8Og1R3d8fbFtQarDMGN+oZrCN3Eb9Twoy36Yr/h0bZgkCEe
-arB+VCD1DfEii5luZowUDr/BlIjIR2cNIMFpmQ8ZLIpVWQz/BYHrbw7CHO5df3mg
-HYTKlEoUMimOEWvCYnSgzKWCgSWU/jBQQ0bcUBk2HHpdT4BnLPe/7rs+TZmwd/Dz
-r80sNXQ6vqTkQS+te2hqyh62r+WeaFx7aqnFjGtwiOqMmYPr80uYOy/rX26mmfwm
-vyf8JlA4uTt795Krsc4Brc+BO0bOPfDDGhRs/2tvyHhOOqBbUxQeeV5ogiAZmA31
-ZrzbFysajMrWZ+1GV8QXOcBi
+FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8RlnMh3L
+SbWNJtwcHBRzQwumr/4kl3AukauMPfkK4jsM0/QyIf6Y0duXJOoxp0Hd+ie3bqRA
+UiMNm1zV6zVm+3iY2jWVJxCy9tUZEUNArb/F1nQ7QZsrfULsgnYGhr3cX7vh/s14
+Posqf75JYLEc0IpXzdG6ZDp2Ib9Z1RlC7yT3GOlHLAja7YTA0MRORuEZqaPnM2Pt
+rylw/KJ8HHNOJn0Vm9ZVoIQ4O90isXg10i15fJgRDANEtYP+dD1n3BvDgpAK0D9R
+R36s5uhyO95q7XAuJmvK6aFlHDAgplTj5poA1hMVve1uZQqehH1otq8q/ESeUXTm
+Qej3FwehLl+3DwIDAQABoz0wOzAaBgNVHREEEzARgQ9pbnZhbGlkQGV4YW1wbGUw
+HQYDVR0OBBYEFHXt0zbNlBA+iv+To3j8ld6tZeFIMA0GCSqGSIb3DQEBCwUAA4IB
+AQBM/EjV791vKu2KQQAhd03eUXfMlvObwEj9nGtEEnSFH5i16V1m8Y5ZY7Aw+VR5
+/xJ9J2AvFG6EXclDVmkDQpo1fUVhWM/SPKD6HJWuB/eyjA30xSj+UeLmBYjdKzHt
+kK+HeEaGVQaT5j8OPOW6meGriucdBWtwbhTdyZgqvwpuZwbtPpElYXwGgSijKqHI
+GG6RWzeANdG/4AIChrp8CIgFfW4sbmlIZK3BAXuSvZ9A/deYqC2DAadJIoTJ9H6w
+0TgYlyTidaWtCkqRBXc3qrwpc/r3wJwpgan0kJAQ2kGc5W7gYUylpoS56sFq23YX
+Fmm0pRq5UZj9jKZUIwcqAoGo
-----END CERTIFICATE-----
diff --git a/test/rubygems/invalidchild_cert.pem b/test/rubygems/invalidchild_cert.pem
index 936dc650c9..281dcce655 100644
--- a/test/rubygems/invalidchild_cert.pem
+++ b/test/rubygems/invalidchild_cert.pem
@@ -1,20 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDOTCCAiGgAwIBAgIBEDANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls
+MIIDGDCCAgCgAwIBAgIBEDANBgkqhkiG9w0BAQsFADApMQ4wDAYDVQQDDAVjaGls
ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTAxMDAwMDAwWhgPOTk5
OTEyMzEyMzU5NTlaMDAxFTATBgNVBAMMDGludmFsaWRjaGlsZDEXMBUGCgmSJomT
-8ixkARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDl
-rDAlDZwmP6Zxc4sSaOdSRRXJBmbQubxmWpqU8bXrTKCkvg1l/2U6weJIS52zW6Te
-Zok7Uus5jywyeNSJ/MBHb7X5ytAPQsvLu/3WFwaVfHJzimQI4vtmx9+CDgZzipYp
-ett7IF18He8DPiFur1xCn8pp0qOOV8mXL/8TpUgJfmaOJosqgFqorj5niqF52IwJ
-vtur/gwpq2xpCtYaCUB/dFzzefLV37kt58S6jTmZnYf4kIdFKhhyTeGmDRf/wOz+
-kK/H/aKtpsYgzI//bo+bsuWNFceIdWrdCBr63cVs4ql7VN7p2xfn9ckEfwH6wFut
-QLquA/6fRkgUFF8fxUiHAgMBAAGjYzBhMB8GA1UdEQQYMBaBFGludmFsaWRjaGls
-ZEBleGFtcGxlMB0GA1UdDgQWBBSwAwFqdxjicsovAzZ1ZeSAWlnKcDAfBgNVHSME
-GDAWgBR81VPTe7JJSgT6xxJcaGd9hYOuCDANBgkqhkiG9w0BAQUFAAOCAQEAYxom
-7nHgbfqLiMtVwx8D6LM6P3sk3p5HwoHJU0zzFVfPA0iuhhC2vWyPoHJroq6d31DG
-DpPpOeVQxTYyQ6CtD6jGUpE+0MjmRoavFnvqFH5lf4OKO0dQ8xUa9fALo7fmK0v0
-ueDlgsHw3mwoVNX2Xu/+jCTuiK2KGG3J+pxr6JNA1++gQEghFFJjM8rw1/mYrDW0
-CSCyx/LeNyYbt9xzeVgo83XNO5TCfwwh8+df52I6Hj5BDFhhkP8KOai4ejq2CmZ8
-by9ylCUXc/aiz9mzX/NzIAYLuRzkmrI+lxDbUJpG/hV7MCS/TZegjD+SUSu9EI1O
-RVerg89R7kQUWZyJqg==
+8ixkARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDs
+dqLesclj2/6HnJLw4al4swiDFBA4W0KeOS3DXOa2k5+rNfGacKOQ/AkciUnzqLiC
+9D49x/YLlnlJYeSMG57C7gixhLHHDviCneQwy8TlCpuhUXnfcpmHQO+X/c+lrVB7
+wHTPjl5yZYzLFtPa8QAEtJa83E2GrUd+JEOwTRErOcBucIRP5HbeR2aD7BVP1V+F
+gaUhOZb/n2e53diQF7BZurB45DTWQ2L1R/m8VldQiWoTZluWqnCGeEwtpZJXt9kU
+8y5rQcxI3p8Qx4q0ilLKsE7c/sw2wzEFWoZ4BeURnjxdvPgYeOPk4K3a34pFg7lZ
+u1s9XvjChJVsD8HRnbQtAgMBAAGjQjBAMB8GA1UdEQQYMBaBFGludmFsaWRjaGls
+ZEBleGFtcGxlMB0GA1UdDgQWBBS3tDKiI1oVuEkKtGux8TsEy/8iuDANBgkqhkiG
+9w0BAQsFAAOCAQEAQsgdq4NZBnQRk+eNbwS4go3S+m5cPPWY7kG94kpQ3aC3nwR4
+wnICb/hd+kRCB2azTTBY8PA0SkHxIXWgRFjdEpIAekm3Xtag+lCC1q7jtDTNoHw4
+KOdfeBEF621FHL5vBvJmnRMH8f4sCjVZZE8RJcaWAK7uJJXi6gzUm3xz0UnylZNr
+vA+Z+cM5pFnCfxxqXUyT0MRb47O/wqH4f5SybKpOxO3+vnzpSeN++zgdMVjA/Pl0
+0SB8VKNKXGLQrvY2S3GuRoh7OD1DhRPzUTQ8gwwBAlhw2i3i5t9ib0ujw9MUO3GR
+dqn4Yco98R0+wFpY8feGhr5uJNDuIC10l5LHLQ==
-----END CERTIFICATE-----
diff --git a/test/rubygems/invalidchild_cert_32.pem b/test/rubygems/invalidchild_cert_32.pem
index 07687eb156..87885157f8 100644
--- a/test/rubygems/invalidchild_cert_32.pem
+++ b/test/rubygems/invalidchild_cert_32.pem
@@ -1,20 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDNzCCAh+gAwIBAgIBETANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls
+MIIDFjCCAf6gAwIBAgIBETANBgkqhkiG9w0BAQsFADApMQ4wDAYDVQQDDAVjaGls
ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMTIwMTAxMDAwMDAwWhcNMzgw
MTE5MDMxNDA3WjAwMRUwEwYDVQQDDAxpbnZhbGlkY2hpbGQxFzAVBgoJkiaJk/Is
-ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5aww
-JQ2cJj+mcXOLEmjnUkUVyQZm0Lm8ZlqalPG160ygpL4NZf9lOsHiSEuds1uk3maJ
-O1LrOY8sMnjUifzAR2+1+crQD0LLy7v91hcGlXxyc4pkCOL7Zsffgg4Gc4qWKXrb
-eyBdfB3vAz4hbq9cQp/KadKjjlfJly//E6VICX5mjiaLKoBaqK4+Z4qhediMCb7b
-q/4MKatsaQrWGglAf3Rc83ny1d+5LefEuo05mZ2H+JCHRSoYck3hpg0X/8Ds/pCv
-x/2irabGIMyP/26Pm7LljRXHiHVq3Qga+t3FbOKpe1Te6dsX5/XJBH8B+sBbrUC6
-rgP+n0ZIFBRfH8VIhwIDAQABo2MwYTAfBgNVHREEGDAWgRRpbnZhbGlkY2hpbGRA
-ZXhhbXBsZTAdBgNVHQ4EFgQUsAMBancY4nLKLwM2dWXkgFpZynAwHwYDVR0jBBgw
-FoAUfNVT03uySUoE+scSXGhnfYWDrggwDQYJKoZIhvcNAQEFBQADggEBAGK07MzH
-/TJftVEgrghvEHIna0gadQUbWfrpMWxt/Vj7jsd4LvRaZEOWObMRxhtjMvMA2q3A
-qKXoP1KddPkFGfAVdUsNKTKLsaMvDceZ7aN3SGEWv5IYGXtfjUEVhWj7CmpS05li
-Phw9uPQVUwkkY20G2UGInRzxCYqyeW5KZIaep49KebaXCrjrV5Xy13UxgtpbmNMj
-yKPvyA5u0J8TK4gQmx1Az0gujpT1KSwfMyEDrsbIqYDVMp4kF2yLlsrdmNT9Jhwj
-R+M6AMhNqpLrjsklqE6TX2pCQGo+JFxCDOKQmvv5B7AhH0od46Jlwk//aIAheQQK
-4rhDHEHYLCxGhrw=
+ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Hai
+3rHJY9v+h5yS8OGpeLMIgxQQOFtCnjktw1zmtpOfqzXxmnCjkPwJHIlJ86i4gvQ+
+Pcf2C5Z5SWHkjBuewu4IsYSxxw74gp3kMMvE5QqboVF533KZh0Dvl/3Ppa1Qe8B0
+z45ecmWMyxbT2vEABLSWvNxNhq1HfiRDsE0RKznAbnCET+R23kdmg+wVT9VfhYGl
+ITmW/59nud3YkBewWbqweOQ01kNi9Uf5vFZXUIlqE2ZblqpwhnhMLaWSV7fZFPMu
+a0HMSN6fEMeKtIpSyrBO3P7MNsMxBVqGeAXlEZ48Xbz4GHjj5OCt2t+KRYO5Wbtb
+PV74woSVbA/B0Z20LQIDAQABo0IwQDAfBgNVHREEGDAWgRRpbnZhbGlkY2hpbGRA
+ZXhhbXBsZTAdBgNVHQ4EFgQUt7QyoiNaFbhJCrRrsfE7BMv/IrgwDQYJKoZIhvcN
+AQELBQADggEBAFPyjOoghY6Iba9+psCWC//rwLtDfZPQ3kO9hFtd4CGvalPtR103
+Oc1Dk5pxHSWDTdeQfOb75mqWuqs4ET7IUyw8yY+bKkOOhY1ldwaJhTyP/fkElnrL
+prsLSpB3AdQceS1Ob2wpMaaGIPDzJlW0LG8cQNeU3SRTTdBjX5zjG6imHKG2yuJd
+76PM0tl8ooslPABlYSPSLpd1PAARqxG2ekfrxZioCLknyhBtcRsl1aMWWBiG4BH9
+xZoJvEHwpOMTxMaAFXSkyMjZAoOzAn9qP6eLbwwzeuckIrZXxYBfGcC29VOPPAN4
+IPX0IUZ7/LlzzOE5iuVS/RIBRcD+qpEzSXs=
-----END CERTIFICATE-----
diff --git a/test/rubygems/invalidchild_key.pem b/test/rubygems/invalidchild_key.pem
index 9706c9566e..1c9997150d 100644
--- a/test/rubygems/invalidchild_key.pem
+++ b/test/rubygems/invalidchild_key.pem
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIEpgIBAAKCAQEA5awwJQ2cJj+mcXOLEmjnUkUVyQZm0Lm8ZlqalPG160ygpL4N
-Zf9lOsHiSEuds1uk3maJO1LrOY8sMnjUifzAR2+1+crQD0LLy7v91hcGlXxyc4pk
-COL7Zsffgg4Gc4qWKXrbeyBdfB3vAz4hbq9cQp/KadKjjlfJly//E6VICX5mjiaL
-KoBaqK4+Z4qhediMCb7bq/4MKatsaQrWGglAf3Rc83ny1d+5LefEuo05mZ2H+JCH
-RSoYck3hpg0X/8Ds/pCvx/2irabGIMyP/26Pm7LljRXHiHVq3Qga+t3FbOKpe1Te
-6dsX5/XJBH8B+sBbrUC6rgP+n0ZIFBRfH8VIhwIDAQABAoIBAQC59hllZwev0Ims
-AqnwVhA2hMmG4zAMgNcS6PmQ78Ukp/7KZTfkBk6orKPTdaZSuzla+hrTdegPyuU2
-WK9+qq/lJ4ZootakBKmOZMC6wBoMn57r/nnQ2DhGmD9YxpJiqyu6mkdsAmCvRm1o
-ar4XKNXC/C6gUHUto9cOG0alWYZiZ/VMe/nhPTChr2Dhd+bavO1yx7/CxB+VQMfQ
-l6ihbv//3KgPJAElbaI7jfOGzX6KlwXSGf70REmZQnPGN4/n46/dLFFuA1HzcA5Z
-37NU1zgN2nIrXld8rsR1mSy6EwU46sW3AkEwv6SUajCjz7PCmmWxRaQErGJjZrUq
-sujNj5RBAoGBAPgdiY+6B7WvmLlCBCwI4PXjgRQ/6A1Ycgvi1LdSQzccSHddogNI
-tWKa0pIrYyH7y7jB/UzstFSnsOXAf4H6Xt70VUrFPq1/dRRw1CtSLA1sFspBAD8v
-aGl9R0XqWOk1t60mfgES9b4LJu46cTm7UMfyC7EbWkqHYWqf15umRgwrAoGBAOz4
-nZGqBVBW/ERDs+Imf9NcwDeuwllQ0S9ZBPHF///SQ4Rscz2Bl8GhjhTHldLNJg9k
-HjP8W2BOPas66K3WM+WC3AiGrdJfs6Ju3r27X4wA0hnNc6bcoRaoSNRaqThSkgCH
-l34l7yrB1gwpa5HlIfYXjHfJ7coX7WRMQK7wmVsVAoGBAJ/Y97z/DuSAgpYn7+Qm
-vDfuIETZfzjJ2H/L3VtVxjQFJrKwQiZ3e1RRhoPhK/bC79bSM8yRWwSHHLKIOB2X
-HfPp2eFX/i9sxBMtNaPLRtJG5s/a3LvYYR5FNdvXRPzKPNFy0Q8EFgofyS8Fu9iD
-02FdkSbDBoKpgZtd61w93TcNAoGBAKtM4SKeRC8aYku6oTtW10pkHvNhmk5UVJMk
-h6V6mx9D0NjWSMvqdVhcv8eXq19yOxQfLJIp16gbhwrTj8WyNVuwp/xl1xtfYQyH
-lu6Sl3QuV7KdSQATN0OYrOUNEIyNa8uEOOfQ5j4DVwb9niwd9dnelgU17HYNq+a4
-FH4hoMotAoGBAJk/9+RPAdxqJsr/oVp9E4wU9ffpZ2Lr0faN7/WqBFPPhhFOMWu2
-zj8fcRaP/9Wv9g2xK/GfCKhrX8FMfq/NMkZsNx6V3W0M8Zbarp9ZvA4Sj0OvsZAO
-J1NQjkvFjMCE0A29jtjY1zRmLzoC+Ds7Ola8IOKvAN8SM1X/CC6bOgGz
+MIIEowIBAAKCAQEA7Hai3rHJY9v+h5yS8OGpeLMIgxQQOFtCnjktw1zmtpOfqzXx
+mnCjkPwJHIlJ86i4gvQ+Pcf2C5Z5SWHkjBuewu4IsYSxxw74gp3kMMvE5QqboVF5
+33KZh0Dvl/3Ppa1Qe8B0z45ecmWMyxbT2vEABLSWvNxNhq1HfiRDsE0RKznAbnCE
+T+R23kdmg+wVT9VfhYGlITmW/59nud3YkBewWbqweOQ01kNi9Uf5vFZXUIlqE2Zb
+lqpwhnhMLaWSV7fZFPMua0HMSN6fEMeKtIpSyrBO3P7MNsMxBVqGeAXlEZ48Xbz4
+GHjj5OCt2t+KRYO5WbtbPV74woSVbA/B0Z20LQIDAQABAoIBAF/yuZ60NDwVWb/s
+LAGbB3mm58bMPtKnUS5DlEqn6SPfXdQKhPj+SJh9dDMEkCHS7d+RPKoz96X3DkrU
+8nhZgr+k95kUd1CGxha1+5BDNqcbeU/pcBLXfO2RT0b0oauf2j8EtkE8Cx3PD+Se
+ZCN8U94U6u9CUyDZMd/A1kh01Qkc08mCJQ0UtPbt5iRFp9nGQaN3ZOXG6taPQVOB
+M91DUUPKny74ptMrqlyRRBylTpUlSjsjo3T5LRNSVXMNubfNG2+sf1Vn/Os/3KAL
+PTqc9LLNaHpR/z/oFC/wUiMdJzHB1vBFUcwHvTmahVfqwaffqLj/zJa12ztMcZ/W
+efRFBb8CgYEA9c6JvqB0gR14Q6Shj7Yg6JM/dO3e8yllvGRsJm0S6IHHlblWeUEA
+OeY099wD0y0oK56XvgfZyd2k+hK/FKf5/otgCyzr1i64sx+hpHE6MZ/s08VLYZvt
++N9fdk7Z5crZImo8vne+7AfBhY1UNk6QjwSUMe8U/zQ6BBGbNhKtgCcCgYEA9kTo
+6xyt836PGSXFSnup3wdjlbpMlXMnvZG2V0Aw3ILdTg2iGGf37UUBzDjnZFxVRPqm
+PqHJwzjd8PZesDFvaZQ1Sn4nRLKZj0aLLOGuaUOoTAP04fQkYltWR+j8w+d4JxX6
+CDNbNtf4EYRVhfNO02WCNyE4xHya7s6u4tnySYsCgYBNlRPay/AZtIB58SNhJZ37
+akZUFKQS4ZUPwi50bmbSZevlsOq/OKnmnGdJd/LpG06bfeHtA7NUyJVCrNoMnfwE
+wF7fCB2jq3l2Z9xv96DjetOX/6SMOVgB/ha2U6rooX6pIxjrEQZ8nvIQwgu7XE66
+JTrVC933srdBA4GWrox+bwKBgQCRZLWuuUvpyfpp+ma0RrZPumkM6OR2B3qa7QAe
+GwO97HUDtADTL+6r4mXhUGcsVWbyRpkHuTUJUPWXYZ0doNIKHzonNLuyT09hy2A3
+qzXxZ8RgvKVDEYS5nPsfkWpJrsq9KLhpRwi/JFqM3PgxESiknfV23uJI/tfpzZRq
+0gm9aQKBgBuxr0xIXZpUuXwOnLIyp0qTPltXPentl71qV3tQvkqlBU+nCKnaa0ur
+7PuEGuFC0jiPiBuRbcO81kq9QTPX6poEYSEFhHphuj9o5/G8MqnC9GzHqVwjc+fI
+JPiixH1Dx9YWsCbnCw72lEdpnxMgk1efnzbV00tl63JgMjkyHBJz
-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/mock_gem_ui.rb b/test/rubygems/mock_gem_ui.rb
new file mode 100644
index 0000000000..1ece78fde7
--- /dev/null
+++ b/test/rubygems/mock_gem_ui.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require "rubygems/user_interaction"
+
+##
+# This Gem::StreamUI subclass records input and output to StringIO for
+# retrieval during tests.
+
+class Gem::MockGemUi < Gem::StreamUI
+ ##
+ # Raised when you haven't provided enough input to your MockGemUi
+
+ class InputEOFError < RuntimeError
+ def initialize(question)
+ super "Out of input for MockGemUi on #{question.inspect}"
+ end
+ end
+
+ class TermError < RuntimeError
+ attr_reader :exit_code
+
+ def initialize(exit_code)
+ super
+ @exit_code = exit_code
+ end
+ end
+
+ class SystemExitException < RuntimeError; end
+
+ module TTY
+ attr_accessor :tty
+
+ def tty?
+ @tty = true unless defined?(@tty)
+ @tty
+ end
+
+ def noecho
+ yield self
+ end
+ end
+
+ def initialize(input = "")
+ require "stringio"
+ ins = StringIO.new input
+ outs = StringIO.new
+ errs = StringIO.new
+
+ ins.extend TTY
+ outs.extend TTY
+ errs.extend TTY
+
+ super ins, outs, errs, true
+
+ @terminated = false
+ end
+
+ def ask(question)
+ raise InputEOFError, question if @ins.eof?
+
+ super
+ end
+
+ def input
+ @ins.string
+ end
+
+ def output
+ @outs.string
+ end
+
+ def error
+ @errs.string
+ end
+
+ def terminated?
+ @terminated
+ end
+
+ def terminate_interaction(status=0)
+ @terminated = true
+
+ raise TermError, status if status != 0
+ raise SystemExitException
+ end
+end
diff --git a/test/rubygems/multifactor_auth_utilities.rb b/test/rubygems/multifactor_auth_utilities.rb
new file mode 100644
index 0000000000..1133131a76
--- /dev/null
+++ b/test/rubygems/multifactor_auth_utilities.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+##
+# A MultifactorAuthFetcher is a FakeFetcher that adds paths to data for requests related to
+# multi-factor authentication.
+#
+
+require_relative "utilities"
+require "json"
+
+class Gem::MultifactorAuthFetcher < Gem::FakeFetcher
+ attr_reader :host, :webauthn_url
+
+ # GET /api/v1/webauthn_verification defaults to user does not have any security devices
+ def initialize(host: nil)
+ super()
+ @host = host || Gem.host
+ @path_token = "odow34b93t6aPCdY"
+ @webauthn_url = "#{@host}/webauthn_verification/#{@path_token}"
+ @data["#{@host}/api/v1/webauthn_verification"] = Gem::HTTPResponseFactory.create(
+ body: "You don't have any security devices",
+ code: 422,
+ msg: "Unprocessable Entity"
+ )
+ end
+
+ # given a url, return a response that requires multifactor authentication
+ def respond_with_require_otp(url, success_body)
+ response_fail = "You have enabled multifactor authentication"
+
+ @data[url] = proc do
+ @call_count ||= 0
+ if (@call_count += 1).odd?
+ Gem::HTTPResponseFactory.create(body: response_fail, code: 401, msg: "Unauthorized")
+ else
+ Gem::HTTPResponseFactory.create(body: success_body, code: 200, msg: "OK")
+ end
+ end
+ end
+
+ # GET /api/v1/webauthn_verification returns a webauthn url
+ # GET /api/v1/webauthn_verification/:token/status.json (polling url) returns pending status
+ def respond_with_webauthn_url
+ @data["#{@host}/api/v1/webauthn_verification"] = Gem::HTTPResponseFactory.create(body: @webauthn_url, code: 200, msg: "OK")
+ @data["#{@host}/api/v1/webauthn_verification/#{@path_token}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: { status: "pending", message: "Security device authentication is still pending." }.to_json,
+ code: 200,
+ msg: "OK"
+ )
+ end
+
+ # GET /api/v1/webauthn_verification/:token/status.json returns success status with OTP code
+ def respond_with_webauthn_polling(code)
+ @data["#{@host}/api/v1/webauthn_verification/#{@path_token}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: { status: "success", code: code }.to_json,
+ code: 200,
+ msg: "OK"
+ )
+ end
+
+ # GET /api/v1/webauthn_verification/:token/status.json returns expired status
+ def respond_with_webauthn_polling_failure
+ @data["#{@host}/api/v1/webauthn_verification/#{@path_token}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: {
+ status: "expired",
+ message: "The token in the link you used has either expired or been used already.",
+ }.to_json,
+ code: 200,
+ msg: "OK"
+ )
+ end
+
+ def webauthn_url_with_port(port)
+ "#{@webauthn_url}?port=#{port}"
+ end
+end
+
+##
+# The MockTCPServer for use in tests or to avoid real TCPServer instances to be created
+# when testing code related to the WebAuthn listener.
+#
+# Example:
+#
+# server = Gem::MockTCPServer
+# port = server.addr[1].to_s
+#
+# # this mocks waiting for a request by calling sleep
+# server.accept
+#
+# # this mocks the server closing
+# server.close
+
+class Gem::MockTCPServer
+ attr_reader :port
+
+ def initialize(port = 5678)
+ @port = port
+ end
+
+ def close
+ true
+ end
+
+ def addr
+ ["AF_INET6", @port, "::", "::"]
+ end
+
+ def accept
+ sleep
+ end
+end
diff --git a/test/rubygems/package/tar_test_case.rb b/test/rubygems/package/tar_test_case.rb
index 6cee7f86dc..e3d812bf3f 100644
--- a/test/rubygems/package/tar_test_case.rb
+++ b/test/rubygems/package/tar_test_case.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "../helper"
require "rubygems/package"
@@ -67,7 +68,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
end
def calc_checksum(header)
- sum = header.unpack("C*").inject {|s,a| s + a }
+ sum = header.sum(0)
SP(Z(to_oct(sum, 6)))
end
@@ -90,43 +91,52 @@ class Gem::Package::TarTestCase < Gem::TestCase
ASCIIZ("wheel", 32), # char gname[32]; ASCIIZ
Z(to_oct(0, 7)), # char devmajor[8]; 0 padded, octal, null
Z(to_oct(0, 7)), # char devminor[8]; 0 padded, octal, null
- ASCIIZ(dname, 155), # char prefix[155]; ASCII + (Z unless filled)
+ ASCIIZ(dname, 155), # char prefix[155]; ASCII + (Z unless filled)
]
h = arr.join
- ret = h + "\0" * (512 - h.size)
+ ret = ASCIIZ(h, 512)
assert_equal(512, ret.size)
ret
end
- def tar_dir_header(name, prefix, mode, mtime)
- h = header("5", name, prefix, 0, mode, mtime)
+ def header_with_checksum(type, fname, dname, length, mode, mtime, linkname = "")
+ h = header(type, fname, dname, length, mode, mtime, nil, linkname)
checksum = calc_checksum(h)
- header("5", name, prefix, 0, mode, mtime, checksum)
+ header(type, fname, dname, length, mode, mtime, checksum, linkname)
+ end
+
+ def tar_dir_header(name, prefix, mode, mtime)
+ header_with_checksum("5", name, prefix, 0, mode, mtime)
end
def tar_file_header(fname, dname, mode, length, mtime)
- h = header("0", fname, dname, length, mode, mtime)
- checksum = calc_checksum(h)
- header("0", fname, dname, length, mode, mtime, checksum)
+ header_with_checksum("0", fname, dname, length, mode, mtime)
end
- def tar_symlink_header(fname, prefix, mode, mtime, linkname)
- h = header("2", fname, prefix, 0, mode, mtime, nil, linkname)
- checksum = calc_checksum(h)
- header("2", fname, prefix, 0, mode, mtime, checksum, linkname)
+ def tar_symlink_header(fname, dname, mode, mtime, linkname)
+ header_with_checksum("2", fname, dname, 0, mode, mtime, linkname)
+ end
+
+ def tar_file_contents(content)
+ pad = (512 - (content.size % 512)) % 512
+ content + "\0" * pad
end
def to_oct(n, pad_size)
- "%0#{pad_size}o" % n
+ format("%0#{pad_size}o", n)
end
def util_entry(tar)
- io = TempIO.new tar
+ io = tar.respond_to?(:read) ? tar : TempIO.new(tar)
header = Gem::Package::TarHeader.from io
- Gem::Package::TarReader::Entry.new header, io
+ Gem::Package::TarReader::Entry.open header, io
+ end
+
+ def close_util_entry(entry)
+ entry.instance_variable_get(:@io).close!
end
def util_dir_entry
@@ -136,4 +146,30 @@ class Gem::Package::TarTestCase < Gem::TestCase
def util_symlink_entry
util_entry tar_symlink_header("foo", "bar", 0, Time.now, "link")
end
+
+ def util_tar(&block)
+ tar_io = StringIO.new
+ Gem::Package::TarWriter.new(tar_io, &block)
+ tar_io.rewind
+ tar_io
+ end
+
+ def util_tar_gz(&block)
+ tar_io = util_tar(&block)
+ StringIO.new util_gzip(tar_io.string)
+ end
+
+ def util_gem_data_tar(spec = nil, &block)
+ data_tgz = util_tar_gz(&block)
+ util_tar do |tar|
+ if spec
+ tar.add_file "metadata.gz", 0o444 do |io|
+ io.write util_gzip(spec.to_yaml)
+ end
+ end
+ tar.add_file "data.tar.gz", 0o644 do |io|
+ io.write data_tgz.string
+ end
+ end
+ end
end
diff --git a/test/rubygems/packages/Bluebie-legs-0.6.2.gem b/test/rubygems/packages/Bluebie-legs-0.6.2.gem
new file mode 100644
index 0000000000..60918f3bc5
--- /dev/null
+++ b/test/rubygems/packages/Bluebie-legs-0.6.2.gem
Binary files differ
diff --git a/test/rubygems/plugin/exception/rubygems_plugin.rb b/test/rubygems/plugin/exception/rubygems_plugin.rb
deleted file mode 100644
index f54e689d87..0000000000
--- a/test/rubygems/plugin/exception/rubygems_plugin.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# frozen_string_literal: true
-TestGem::TEST_PLUGIN_EXCEPTION = :loaded
-raise Exception.new("boom")
diff --git a/test/rubygems/plugin/load/rubygems_plugin.rb b/test/rubygems/plugin/load/rubygems_plugin.rb
index 7cc6bef90b..21fef10bb1 100644
--- a/test/rubygems/plugin/load/rubygems_plugin.rb
+++ b/test/rubygems/plugin/load/rubygems_plugin.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
class TestGem
TEST_PLUGIN_LOAD = :loaded
end
diff --git a/test/rubygems/plugin/scripterror/rubygems_plugin.rb b/test/rubygems/plugin/scripterror/rubygems_plugin.rb
new file mode 100644
index 0000000000..0acd55be12
--- /dev/null
+++ b/test/rubygems/plugin/scripterror/rubygems_plugin.rb
@@ -0,0 +1,4 @@
+# frozen_string_literal: true
+
+TestGem::TEST_PLUGIN_EXCEPTION = :loaded
+raise ScriptError.new("boom")
diff --git a/test/rubygems/plugin/standarderror/rubygems_plugin.rb b/test/rubygems/plugin/standarderror/rubygems_plugin.rb
index 0fcca28728..58e4080f05 100644
--- a/test/rubygems/plugin/standarderror/rubygems_plugin.rb
+++ b/test/rubygems/plugin/standarderror/rubygems_plugin.rb
@@ -1,3 +1,4 @@
# frozen_string_literal: true
+
TestGem::TEST_PLUGIN_STANDARDERROR = :loaded
raise StandardError.new("boom")
diff --git a/test/rubygems/private_key.pem b/test/rubygems/private_key.pem
index c6ed3fc24e..4e6ce13e65 100644
--- a/test/rubygems/private_key.pem
+++ b/test/rubygems/private_key.pem
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEAp2U1hy8UHrGClPxByczJtV6UYtQrJAv+FA9Mr0nkXKoHyEQM
-u3au4zAqwdTp+7+aAb6wu8cXWepaFkAOGfqvAJ80/TfTbm+S05nqIl9TrS/K1j9/
-eCSIY2Q/bWXSHPT4yzXl/7naCT6wVerAYFsO14jTHntSweL4oA3rtC48Oe2FgO3C
-FcgDmlx3HbAf41bwXzYcRm+bWFykDvkENWTi8/GekN+884pJif11aCGZS1o+arJW
-+zxeQPEcN9jnj8PfOI96E/7NDMSDwLTtKr/Pq8tI5De5pifScEO40Tpc/eKMnhm+
-zZ4kR04zJLUfcKyeRaJ48Ksu0p3Dx38X4PluhwIDAQABAoIBAAx09qfJtBiYoxwN
-LaQjzjrl/+re2RsEnXLGtLEysYDH0m5vyfbFXTxg4D2uZ38pgf9xPluq9CznyK5x
-M9txEUbdkibp2Z0VRnrisE7Ag0yXCuQos4awSUoEMsgkVJ99B2qv5x7BqN0ZQiwS
-nSBOhms5rmRNTxpIlrHqd0jgS/EPggnqVzNcM4/K8PJFthwEBKDmzOyiRByvz54Y
-shzOnTjGtV2oGNgwpzmCXce1yO7dh2IdKnSnmeFwyU88GxEYnGh5MIFuTiyErP72
-k6iEUfiXy0hxk/iXmKs8UyD1lVnwTNWcZcpV8yw4a06Z6nkSnwQm0SSOVIo/w35V
-jdVdUkECgYEA3GhZ70MD/Q47GFvz6BovwQvxhjFN+nIEbBfi7OTkuXprKdhVhjaR
-nERPZpZjHWrcfgbFcvPY7/GJLTPN/VF1nhOsOZpzfAmCgBujRXrzlAGpU877ZNJA
-QKPgzo+iv/RsQCIdrzF1gwHkqD2v1HRLaqb2+dVumiG4Qp3NXgasT2cCgYEAwm1U
-uRDXgQKGODeLK8eSVpfMjD5umBVu7m4D3ZmipbN6sMBxGMAlsU40eQ7DBFH0AFft
-s2D88JdjlwoOrbXYYpOc6iWD/QkygJfPpA9VQx92hv8KBd82gLHuXYMd0T0G3yZO
-gPPioeRgl2TvgVCfjn6AYr3Ubt3rB5aBlSplE+ECgYEAiXhcf6rg1fkGSs8vddi/
-aDy2y+f8pvRuZa0QUIkDT9xW8qaH0Uo/z6ObknTCJRr9o209wdDtwdp4oMTq+dDQ
-92N1zAfVd8vGpXiXgUKKognXPvqeOegZQzfzg2J7NBaTXfzpXtgOX0PTBkxTWsOe
-NkslR/YjIedeMc6SxM6MsokCgYA3mTYyGevWe5dQOin1IgPp+UzICg5sNSzcx98Z
-HpcRVWrPYqi00DW3J0sAF0WTVbA17O8PbbvHPTOAfKLH8Alp3xZvKr08vcWQWllJ
-bA0Qvc2SOxptpXAbi0ZDvXvoWtA9PeITJCr56qnogTewPhLyl6A1HF3EOne8WsDB
-nDb9YQKBgEyUDWhDBGXUfQN0fWy5ksqCCeHXQzvt6aEUstWvkkbnnarUfLAhBIqC
-2B6omokICmWzvAfDt3UsRbb3QJUBxbbVsZVM7Vr+kY2cQ1Ma093I/2mXDoq3bV+j
-LZM5+Uc7xSfiCi1hbVhGm96DXofudddo86W5mhXp3xhcQP1Fl4JZ
+MIIEpAIBAAKCAQEA0ULcfpDboY5uWVdOIkF4AtRui7PPFoaKfBl5hiGFcpYRx8DQ
+PyT7bbD8nKd14Rhzb0nHCMU3DEz8PLJCmWm3NszVDkEJws1BpCGak6vKiyNa5hZb
+UlQMZMbecSDSpEKu2PBWgBT74qg2RBugzTAVAnGQGezQnWyv47kyXvdjMoq11VZa
++Dz2izHJvjBHGQShr1r9v39qIrtah5CEXTRxEqhr96gg3y6xOPMqxi50dS0RBaJs
+PsjFZ1jecye0Z/WPItiLjSVVRssUXK1a2VkYxUqkxUg4wwJD57H4TEZBomtAXlAS
+o+rUv8G9eBNmS/k/oJLdiMF1ULb+e1+izeAyGwIDAQABAoIBABS+vR8q+ysD9LqU
+piFNPjmBl8fvtmr0QYxV9i8u6YzXhcG4wqxP3UEdl51sGIqNIvx4YuviqTdl9meK
+AII28bvUCJcWKYKPWJ+N2UYkdLrgcWV39+use2IOOQUcDOXN2omVIe4mpmXs6RxN
+ZN6SkrKgUXnQeUnx+Wno9S5m9gWPfrAMTr8iwBquo5JMFqJmAlfq1cIActU7SE6M
+7LJZ8rbVGuGmZAyqJw/I5xvxts6NlTFBm2AyGq74wtbUD4OlFDtOTA57LmtRswmr
+MK+JG5LIJIyc6qKQwmHU8vLstJEcVUyCJDbpjDkApd6GQ2FwXXode+S9C40DZKvi
+hnaGfKECgYEA1ArI5tt3GdNR4CbY4e4yDHEuSdSkMVsRa9a7gdtrrjyNitBMbZNE
+HZNqswijBCPZnXPtBxeytMUmlU7uFc7xx3QQvuBSJ6HOb9j0qtWVL+jl8R9XLogH
+sE/m0yMPs2IowevJoQ95KRZIirLywZ8QgTsySEv9U4hx2CdKpn7IeRECgYEA/KR9
+WI1n6pxDbxcjWMaOdziIcgDBk7v05Qssb1OePiz+y+zfrBVqDjsvsokRLoElSAkR
+TAV+/9hRgAu4cZJpP0FMdFe+sVkr1UfcDqvJdgumBL+xUNxRV/QFvuprLa6XbiQO
+jUclJR6BPdXeVQPDUHuQBgnwXrJdRtMl9Fj8GGsCgYAhZKVo/e0OyyHczCFhy1Jk
+dTqV8//7qdzff8y90aFuqiicUNuIciXLBplKIrURhNfTnRsZ/9hr8ZR29Rw3oQSg
+pZ2xgcBOb4QER0WY1dQN3H7B726abF/Rm3O9kor5dB75EzoIvFgXaWP5O99RMMy3
+nWv4yMbXbeiH4wA1okfOEQKBgQDkaAnyrxUN5GyK2M5aCljurCufddOMrtb+5BUu
+KNjduWw6DVNCjrGtYBEFRipEcvmzoI8EvctNntJAA1ijRQzl5TEr1dBPIiEg17C5
+itG+aVWU4YF7a1QXQkSXj/OJ/1hkeTC2xWVto6CQuPQixB4mey+AZifsVTFDQM4F
+lRWFNQKBgQDQWRXaJgc4Jeur1/I1iMAcihN/o4Lra4baM07FdpFWrePJ4IimXHG+
+buws6BuytnQP56hqIQYLQSWCF192dcnHNbodXz48Ug6rKLSBalxH3pvThYLpkBSk
+7OrfHzO4TTVaCH1mcPjzj9vmRog2tvrF/m6/8UAZQIBGDv2+cHk4rA==
-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/public_cert.pem b/test/rubygems/public_cert.pem
index 4517de53c6..7481c26b79 100644
--- a/test/rubygems/public_cert.pem
+++ b/test/rubygems/public_cert.pem
@@ -1,20 +1,20 @@
-----BEGIN CERTIFICATE-----
-MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoYDzk5
OTkxMjMxMjM1OTU5WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ
-FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2U1hy8U
-HrGClPxByczJtV6UYtQrJAv+FA9Mr0nkXKoHyEQMu3au4zAqwdTp+7+aAb6wu8cX
-WepaFkAOGfqvAJ80/TfTbm+S05nqIl9TrS/K1j9/eCSIY2Q/bWXSHPT4yzXl/7na
-CT6wVerAYFsO14jTHntSweL4oA3rtC48Oe2FgO3CFcgDmlx3HbAf41bwXzYcRm+b
-WFykDvkENWTi8/GekN+884pJif11aCGZS1o+arJW+zxeQPEcN9jnj8PfOI96E/7N
-DMSDwLTtKr/Pq8tI5De5pifScEO40Tpc/eKMnhm+zZ4kR04zJLUfcKyeRaJ48Ksu
-0p3Dx38X4PluhwIDAQABo10wWzAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAd
-BgNVHQ4EFgQUX0Nu9pqORSXpIuN9N16k1TYChRswDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQEFBQADggEBAJasznHQK7el5CY19uRM
-QZSP2moi65jbESKA5CaSOK0erWfLL7k0W69Rr4RG8CQDXmtlVLzdQlEGkvJEfMLs
-GumlIGDEsLZU/3tQ8lML2fMUKipv/fsyWoe6wUHyfsywYYT4WAxyKUtY6AepwN6Y
-sJ6+qDWUFziSVgDnU2bBdqzIOw+ww1NtRGE3PEam+a/VL7l/a2DYcot5cvcc8RYR
-6gyBXp4fvSGasM3iQp7sWdNV04H8m8+lYBLtsfuucgLDu45uEuvKL1tRcRXvtomp
-rKB5y3B5qT/bcc+3b0tbOU6s7CBIdyzIflJI7GuIbZk6lZ+V8Yem+tWt1ArL3Hqf
-Myk=
+FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ULcfpDb
+oY5uWVdOIkF4AtRui7PPFoaKfBl5hiGFcpYRx8DQPyT7bbD8nKd14Rhzb0nHCMU3
+DEz8PLJCmWm3NszVDkEJws1BpCGak6vKiyNa5hZbUlQMZMbecSDSpEKu2PBWgBT7
+4qg2RBugzTAVAnGQGezQnWyv47kyXvdjMoq11VZa+Dz2izHJvjBHGQShr1r9v39q
+Irtah5CEXTRxEqhr96gg3y6xOPMqxi50dS0RBaJsPsjFZ1jecye0Z/WPItiLjSVV
+RssUXK1a2VkYxUqkxUg4wwJD57H4TEZBomtAXlASo+rUv8G9eBNmS/k/oJLdiMF1
+ULb+e1+izeAyGwIDAQABo10wWzAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAd
+BgNVHQ4EFgQUsRpUCWdFYAIC1870HWBKid/nWNkwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADggEBAAYrbeZLQujvqrzAa6NN
+QsiGLSVoF+ZcySQH+rpoqcvbd8zLKz/vH+SoMM6db4OUgD8BKaeBb8dGhzz/lE8m
+YUqW/La4xvf/ffW5yze51Rtr1bPw1Tjrk92nE630Unjf0ZZO0h8shTmq/WlXiEqg
+cXxfbZiPP0KZkhn4ulf+RBbKKQGrLYvaVrCZcowSjLWzcfredYxElOpcgHCrL2pl
+2ZAjCySqAUpYo8HTZwgY/DeeGS3V4fZ06ZDoG20cxi7t8R+AcNbEfaTMzG3oe5qN
+A8+a3Qcf5M4yiJtXRNusMKeoRwLDkYRX9u76iOI5LfKTSqnUyhrUQcSYCTFO4y/V
+P48=
-----END CERTIFICATE-----
diff --git a/test/rubygems/public_cert_32.pem b/test/rubygems/public_cert_32.pem
index 0431b8ba1a..efcf7c0ed7 100644
--- a/test/rubygems/public_cert_32.pem
+++ b/test/rubygems/public_cert_32.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDLDCCAhSgAwIBAgIBATANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDLDCCAhSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoXDTM4
MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH
-ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x
-gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq
-WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+
-sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc
-pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE
-g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd
-w8d/F+D5bocCAwEAAaNdMFswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD
-VR0OBBYEFF9DbvaajkUl6SLjfTdepNU2AoUbMA8GA1UdEwEB/wQFMAMBAf8wDgYD
-VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBBQUAA4IBAQA2+XpC520DwKfqlv5Fn2N5
-sGOgr2Kop7Id2wVWiGDnjDEoTf2Fj+nmmLPltemoCumgY/AacUBAdK1kg47x+7NR
-QMq1pOXR5dZbopw1vs9isQQx2P7jKEH7AgIkqo/6XMQGE3tQtJyNIi1LTGCOKNok
-Fpv8ZVS8aBmXgC0zwtlrtTxCXpkFaNB99nEqo46Fy+D7dkEXE4Oc3JjTON83sHYD
-VsV3DFYzZtR9qe/gCOdgnDHYnf5vU+LGA1gX+8d4Iu/B5ZZtaAowgrsA14oJDuO3
-4g491pjaEYDFZG6mUpvf79uZaBjJdDZeyfwtJ6cN3gTv98DO4DKh/qxnbM/46LM1
+ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFC3H6Q26GO
+bllXTiJBeALUbouzzxaGinwZeYYhhXKWEcfA0D8k+22w/JyndeEYc29JxwjFNwxM
+/DyyQplptzbM1Q5BCcLNQaQhmpOryosjWuYWW1JUDGTG3nEg0qRCrtjwVoAU++Ko
+NkQboM0wFQJxkBns0J1sr+O5Ml73YzKKtdVWWvg89osxyb4wRxkEoa9a/b9/aiK7
+WoeQhF00cRKoa/eoIN8usTjzKsYudHUtEQWibD7IxWdY3nMntGf1jyLYi40lVUbL
+FFytWtlZGMVKpMVIOMMCQ+ex+ExGQaJrQF5QEqPq1L/BvXgTZkv5P6CS3YjBdVC2
+/ntfos3gMhsCAwEAAaNdMFswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD
+VR0OBBYEFLEaVAlnRWACAtfO9B1gSonf51jZMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4IBAQBqjR8ioUTAmRjZNvRPMGXc
+mx0nklEODMfG5k+X4QI2Hux/4CWuSZKh+LoIxOsqQJdm2rG1FkPr6JYQOj5HCFA7
+3gO/MoSOtqBBOY9uMnGJQUq0NrWvleO3giUhfHRzUh7utXy2u3umuwJLqF54vbuT
+a1yufGSzwBO2BP7iURt9SyVrDWFmHSX976ZFWIandPXgMCJTgO6tONOC6/sABctb
+YQKo2scrAiSsk+kgIMnebavL6gKgQud6xdjJzvUq3DV4s93ent9rpRzYRgnTM8Eo
+UcgFbpFsWR21+gEt6UKv1rO9ZaWBf6RUVdh/sJKa/7vK/shQmnWw0A/LewxKQWV3
-----END CERTIFICATE-----
diff --git a/test/rubygems/public_key.pem b/test/rubygems/public_key.pem
index 7c29dcd614..c233b35e7c 100644
--- a/test/rubygems/public_key.pem
+++ b/test/rubygems/public_key.pem
@@ -1,9 +1,9 @@
-----BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2U1hy8UHrGClPxByczJ
-tV6UYtQrJAv+FA9Mr0nkXKoHyEQMu3au4zAqwdTp+7+aAb6wu8cXWepaFkAOGfqv
-AJ80/TfTbm+S05nqIl9TrS/K1j9/eCSIY2Q/bWXSHPT4yzXl/7naCT6wVerAYFsO
-14jTHntSweL4oA3rtC48Oe2FgO3CFcgDmlx3HbAf41bwXzYcRm+bWFykDvkENWTi
-8/GekN+884pJif11aCGZS1o+arJW+zxeQPEcN9jnj8PfOI96E/7NDMSDwLTtKr/P
-q8tI5De5pifScEO40Tpc/eKMnhm+zZ4kR04zJLUfcKyeRaJ48Ksu0p3Dx38X4Plu
-hwIDAQAB
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ULcfpDboY5uWVdOIkF4
+AtRui7PPFoaKfBl5hiGFcpYRx8DQPyT7bbD8nKd14Rhzb0nHCMU3DEz8PLJCmWm3
+NszVDkEJws1BpCGak6vKiyNa5hZbUlQMZMbecSDSpEKu2PBWgBT74qg2RBugzTAV
+AnGQGezQnWyv47kyXvdjMoq11VZa+Dz2izHJvjBHGQShr1r9v39qIrtah5CEXTRx
+Eqhr96gg3y6xOPMqxi50dS0RBaJsPsjFZ1jecye0Z/WPItiLjSVVRssUXK1a2VkY
+xUqkxUg4wwJD57H4TEZBomtAXlASo+rUv8G9eBNmS/k/oJLdiMF1ULb+e1+izeAy
+GwIDAQAB
-----END PUBLIC KEY-----
diff --git a/test/rubygems/rubygems/commands/crash_command.rb b/test/rubygems/rubygems/commands/crash_command.rb
index 9155360e76..55df274603 100644
--- a/test/rubygems/rubygems/commands/crash_command.rb
+++ b/test/rubygems/rubygems/commands/crash_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
class Gem::Commands::CrashCommand < Gem::Command
raise "crash"
end
diff --git a/test/rubygems/rubygems_plugin.rb b/test/rubygems/rubygems_plugin.rb
index b538487bbf..949580f904 100644
--- a/test/rubygems/rubygems_plugin.rb
+++ b/test/rubygems/rubygems_plugin.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "rubygems/command_manager"
##
diff --git a/test/rubygems/simple_gem.rb b/test/rubygems/simple_gem.rb
index 0f2ea48198..3d30bade84 100644
--- a/test/rubygems/simple_gem.rb
+++ b/test/rubygems/simple_gem.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-SIMPLE_GEM = <<-GEMDATA.freeze
+
+SIMPLE_GEM = <<-GEMDATA
MD5SUM = "989bf34a1cbecd52e0ea66b662b3a405"
if $0 == __FILE__
require 'optparse'
diff --git a/test/rubygems/specifications/bar-0.0.2.gemspec b/test/rubygems/specifications/bar-0.0.2.gemspec
index 37b6ea45da..1f3d0161d2 100644
--- a/test/rubygems/specifications/bar-0.0.2.gemspec
+++ b/test/rubygems/specifications/bar-0.0.2.gemspec
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
Gem::Specification.new do |s|
s.name = "bar"
s.version = "0.0.2"
diff --git a/test/rubygems/specifications/rubyforge-0.0.1.gemspec b/test/rubygems/specifications/rubyforge-0.0.1.gemspec
index e8d5030326..0421b675a0 100644
--- a/test/rubygems/specifications/rubyforge-0.0.1.gemspec
+++ b/test/rubygems/specifications/rubyforge-0.0.1.gemspec
@@ -1,12 +1,15 @@
+# frozen_string_literal: true
+
Gem::Specification.new do |s|
- s.name = "rubyforge"
- s.version = "0.0.1"
- s.platform = "ruby"
- s.require_paths = ["lib"]
- s.summary = "A very bar gem"
- s.authors = ["unknown"]
- s.license = "MIT"
- s.homepage = "http://example.com"
- s.files = ["README.md"]
- s.rubyforge_project = "abc"
+ s.name = "rubyforge"
+ s.version = "0.0.1"
+ s.platform = "ruby"
+ s.require_paths = ["lib"]
+ s.summary = "A very bar gem"
+ s.authors = ["unknown"]
+ s.license = "MIT"
+ s.homepage = "http://example.com"
+ s.files = ["README.md"]
+ s.rubyforge_project = "abc"
+ s.required_ruby_version = ">= 1.9.3"
end
diff --git a/test/rubygems/test_bundled_ca.rb b/test/rubygems/test_bundled_ca.rb
index 3d7f616519..50e621f22b 100644
--- a/test/rubygems/test_bundled_ca.rb
+++ b/test/rubygems/test_bundled_ca.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
+
require_relative "helper"
-require "net/http"
+require "rubygems/vendored_net_http"
require "rubygems/openssl"
unless Gem::HAVE_OPENSSL
@@ -14,7 +15,7 @@ require "rubygems/request"
# The tested hosts are explained in detail here: https://github.com/rubygems/rubygems/commit/5e16a5428f973667cabfa07e94ff939e7a83ebd9
#
-class TestBundledCA < Gem::TestCase
+class TestGemBundledCA < Gem::TestCase
def bundled_certificate_store
store = OpenSSL::X509::Store.new
@@ -27,12 +28,12 @@ class TestBundledCA < Gem::TestCase
def assert_https(host)
assert true
- http = Net::HTTP.new(host, 443)
+ http = Gem::Net::HTTP.new(host, 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.cert_store = bundled_certificate_store
http.get("/")
- rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError
+ rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError, 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_config.rb b/test/rubygems/test_config.rb
index d9e0f4dd9d..657624d526 100644
--- a/test/rubygems/test_config.rb
+++ b/test/rubygems/test_config.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems"
require "shellwords"
-class TestConfig < Gem::TestCase
+class TestGemConfig < Gem::TestCase
def test_datadir
util_make_gems
spec = Gem::Specification.find_by_name("a")
@@ -15,13 +16,13 @@ class TestConfig < Gem::TestCase
path = Gem::TestCase.class_variable_get(:@@good_rake)
ruby, rake = path.shellsplit
assert_equal(Gem.ruby, ruby)
- assert_match(/\/good_rake.rb\z/, rake)
+ assert_match(%r{/good_rake.rb\z}, rake)
end
def test_bad_rake_path_is_escaped
path = Gem::TestCase.class_variable_get(:@@bad_rake)
ruby, rake = path.shellsplit
assert_equal(Gem.ruby, ruby)
- assert_match(/\/bad_rake.rb\z/, rake)
+ assert_match(%r{/bad_rake.rb\z}, rake)
end
end
diff --git a/test/rubygems/test_deprecate.rb b/test/rubygems/test_deprecate.rb
index dfcf8dea11..d15de646a4 100644
--- a/test/rubygems/test_deprecate.rb
+++ b/test/rubygems/test_deprecate.rb
@@ -1,8 +1,9 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/deprecate"
-class TestDeprecate < Gem::TestCase
+class TestGemDeprecate < Gem::TestCase
def setup
super
@@ -28,7 +29,7 @@ class TestDeprecate < Gem::TestCase
assert_equal true, Gem::Deprecate.skip
Gem::Deprecate.skip = nil
- assert([true,false].include? Gem::Deprecate.skip)
+ assert([true,false].include?(Gem::Deprecate.skip))
end
def test_skip
@@ -45,6 +46,7 @@ class TestDeprecate < Gem::TestCase
def foo
@message = "foo"
end
+
def bar
@message = "bar"
end
@@ -53,6 +55,7 @@ class TestDeprecate < Gem::TestCase
def foo_arg(msg)
@message = "foo" + msg
end
+
def bar_arg(msg)
@message = "bar" + msg
end
@@ -61,6 +64,7 @@ class TestDeprecate < Gem::TestCase
def foo_kwarg(message:)
@message = "foo" + message
end
+
def bar_kwarg(message:)
@message = "bar" + message
end
@@ -73,6 +77,7 @@ class TestDeprecate < Gem::TestCase
def foo
@message = "foo"
end
+
def bar
@message = "bar"
end
@@ -81,6 +86,7 @@ class TestDeprecate < Gem::TestCase
def foo_arg(msg)
@message = "foo" + msg
end
+
def bar_arg(msg)
@message = "bar" + msg
end
@@ -89,6 +95,7 @@ class TestDeprecate < Gem::TestCase
def foo_kwarg(message:)
@message = "foo" + message
end
+
def bar_kwarg(message:)
@message = "bar" + message
end
diff --git a/test/rubygems/test_exit.rb b/test/rubygems/test_exit.rb
index 707150efaa..396837edad 100644
--- a/test/rubygems/test_exit.rb
+++ b/test/rubygems/test_exit.rb
@@ -3,7 +3,7 @@
require_relative "helper"
require "rubygems"
-class TestExit < Gem::TestCase
+class TestGemExit < Gem::TestCase
def test_exit
system(*ruby_with_rubygems_in_load_path, "-e", "raise Gem::SystemExitException.new(2)")
assert_equal 2, $?.exitstatus
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index bbb3e6dd0a..244b7749a5 100644
--- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb
@@ -1,4 +1,5 @@
# coding: US-ASCII
+
require_relative "helper"
require "rubygems"
require "rubygems/command"
@@ -10,7 +11,7 @@ require "rbconfig"
class TestGem < Gem::TestCase
PLUGINS_LOADED = [] # rubocop:disable Style/MutableConstant
- PROJECT_DIR = File.expand_path("../..", __dir__).tap(&Gem::UNTAINT)
+ PROJECT_DIR = File.expand_path("../..", __dir__)
def setup
super
@@ -95,9 +96,9 @@ class TestGem < Gem::TestCase
gemhome2 = "#{@gemhome}2"
- installed = Gem.install "a", "= 1", :install_dir => gemhome2
+ installed = Gem.install "a", "= 1", install_dir: gemhome2
- assert_equal %w[a-1], installed.map {|spec| spec.full_name }
+ assert_equal %w[a-1], installed.map(&:full_name)
assert_path_exist File.join(gemhome2, "gems", "a-1")
end
@@ -114,9 +115,9 @@ class TestGem < Gem::TestCase
begin
raise "Error"
rescue StandardError
- Gem.install "a", "= 1", :install_dir => gemhome2
+ Gem.install "a", "= 1", install_dir: gemhome2
end
- assert_equal %w[a-1], installed.map {|spec| spec.full_name }
+ assert_equal %w[a-1], installed.map(&:full_name)
end
def test_self_install_permissions
@@ -131,8 +132,8 @@ class TestGem < Gem::TestCase
end
def test_self_install_permissions_umask_077
- umask = File.umask(077)
- assert_self_install_permissions
+ umask = File.umask(0o077)
+ assert_self_install_permissions(data_mode: 0o600)
ensure
File.umask(umask)
end
@@ -150,21 +151,21 @@ class TestGem < Gem::TestCase
Gem::Installer.exec_format = nil
end
- def assert_self_install_permissions(format_executable: false)
- mask = win_platform? ? 0700 : 0777
+ def assert_self_install_permissions(format_executable: false, data_mode: 0o640)
+ mask = Gem.win_platform? ? 0o700 : 0o777
options = {
- :dir_mode => 0500,
- :prog_mode => win_platform? ? 0410 : 0510,
- :data_mode => 0640,
- :wrappers => true,
- :format_executable => format_executable,
+ dir_mode: 0o500,
+ prog_mode: Gem.win_platform? ? 0o410 : 0o510,
+ data_mode: data_mode,
+ wrappers: true,
+ format_executable: format_executable,
}
Dir.chdir @tempdir do
Dir.mkdir "bin"
Dir.mkdir "data"
File.write "bin/foo", "#!/usr/bin/env ruby\n"
- File.chmod 0755, "bin/foo"
+ File.chmod 0o755, "bin/foo"
File.write "data/foo.txt", "blah\n"
@@ -191,7 +192,7 @@ class TestGem < Gem::TestCase
"gems/foo-1/data/foo.txt" => data_mode,
}
# add Windows script
- expected["bin/#{prog_name}.bat"] = mask.to_s(8) if win_platform?
+ expected["bin/#{prog_name}.bat"] = mask.to_s(8) if Gem.win_platform?
result = {}
Dir.chdir @gemhome do
expected.each_key do |n|
@@ -200,7 +201,7 @@ class TestGem < Gem::TestCase
end
assert_equal(expected, result)
ensure
- File.chmod(0755, *Dir.glob(@gemhome + "/gems/**/").map {|path| path.tap(&Gem::UNTAINT) })
+ File.chmod(0o755, *Dir.glob(@gemhome + "/gems/**/"))
end
def test_require_missing
@@ -366,7 +367,7 @@ class TestGem < Gem::TestCase
install_specs bundler_latest, bundler_previous
File.open("Gemfile.lock", "w") do |f|
- f.write <<-L.gsub(/ {8}/, "")
+ f.write <<~L
GEM
remote: https://rubygems.org/
specs:
@@ -400,7 +401,7 @@ class TestGem < Gem::TestCase
install_specs bundler_latest, bundler_previous
File.open("Gemfile.lock", "w") do |f|
- f.write <<-L.gsub(/ {8}/, "")
+ f.write <<~L
GEM
remote: https://rubygems.org/
specs:
@@ -424,7 +425,7 @@ class TestGem < Gem::TestCase
def test_activate_bin_path_gives_proper_error_for_bundler_when_underscore_selection_given
File.open("Gemfile.lock", "w") do |f|
- f.write <<-L.gsub(/ {8}/, "")
+ f.write <<~L
GEM
remote: https://rubygems.org/
specs:
@@ -616,25 +617,6 @@ class TestGem < Gem::TestCase
assert_equal %w[https://rubygems.org/], Gem.default_sources
end
- def test_self_use_gemdeps
- with_rubygems_gemdeps("-") do
- FileUtils.mkdir_p "detect/a/b"
- FileUtils.mkdir_p "detect/a/Isolate"
-
- FileUtils.touch "detect/Isolate"
-
- begin
- Dir.chdir "detect/a/b"
-
- Gem.use_gemdeps
-
- assert_equal add_bundler_full_name([]), loaded_spec_names
- ensure
- Dir.chdir @tempdir
- end
- end
- end
-
def test_self_dir
assert_equal @gemhome, Gem.dir
end
@@ -657,13 +639,13 @@ class TestGem < Gem::TestCase
FileUtils.rm_r @gemhome
Gem.use_paths @gemhome
- Gem.ensure_gem_subdirectories @gemhome, 0750
+ Gem.ensure_gem_subdirectories @gemhome, 0o750
assert_directory_exists File.join(@gemhome, "cache")
- assert_equal 0750, File::Stat.new(@gemhome).mode & 0777
- assert_equal 0750, File::Stat.new(File.join(@gemhome, "cache")).mode & 0777
- end unless win_platform?
+ assert_equal 0o750, File::Stat.new(@gemhome).mode & 0o777
+ assert_equal 0o750, File::Stat.new(File.join(@gemhome, "cache")).mode & 0o777
+ end unless Gem.win_platform?
def test_self_ensure_gem_directories_safe_permissions
FileUtils.rm_r @gemhome
@@ -673,17 +655,21 @@ class TestGem < Gem::TestCase
File.umask 0
Gem.ensure_gem_subdirectories @gemhome
- assert_equal 0, File::Stat.new(@gemhome).mode & 002
- assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 002
+ assert_equal 0, File::Stat.new(@gemhome).mode & 0o002
+ assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 0o002
ensure
File.umask old_umask
- end unless win_platform?
+ end unless Gem.win_platform?
def test_self_ensure_gem_directories_missing_parents
gemdir = File.join @tempdir, "a/b/c/gemdir"
- FileUtils.rm_rf File.join(@tempdir, "a") rescue nil
+ begin
+ FileUtils.rm_rf File.join(@tempdir, "a")
+ rescue StandardError
+ nil
+ end
refute File.exist?(File.join(@tempdir, "a")),
- "manually remove #{File.join @tempdir, 'a'}, tests are broken"
+ "manually remove #{File.join @tempdir, "a"}, tests are broken"
Gem.use_paths gemdir
Gem.ensure_gem_subdirectories gemdir
@@ -691,37 +677,45 @@ class TestGem < Gem::TestCase
assert_directory_exists util_cache_dir
end
- unless win_platform? || Process.uid.zero? # only for FS that support write protection
+ unless Gem.win_platform? || Process.uid.zero? # only for FS that support write protection
def test_self_ensure_gem_directories_write_protected
gemdir = File.join @tempdir, "egd"
- FileUtils.rm_r gemdir rescue nil
+ begin
+ FileUtils.rm_r gemdir
+ rescue StandardError
+ nil
+ end
refute File.exist?(gemdir), "manually remove #{gemdir}, tests are broken"
FileUtils.mkdir_p gemdir
- FileUtils.chmod 0400, gemdir
+ FileUtils.chmod 0o400, gemdir
Gem.use_paths gemdir
Gem.ensure_gem_subdirectories gemdir
refute File.exist?(util_cache_dir)
ensure
- FileUtils.chmod 0600, gemdir
+ FileUtils.chmod 0o600, gemdir
end
def test_self_ensure_gem_directories_write_protected_parents
parent = File.join(@tempdir, "egd")
gemdir = "#{parent}/a/b/c"
- FileUtils.rm_r parent rescue nil
+ begin
+ FileUtils.rm_r parent
+ rescue StandardError
+ nil
+ end
refute File.exist?(parent), "manually remove #{parent}, tests are broken"
FileUtils.mkdir_p parent
- FileUtils.chmod 0400, parent
+ FileUtils.chmod 0o400, parent
Gem.use_paths(gemdir)
Gem.ensure_gem_subdirectories gemdir
refute File.exist? File.join(gemdir, "gems")
ensure
- FileUtils.chmod 0600, parent
+ FileUtils.chmod 0o600, parent
end
def test_self_ensure_gem_directories_non_existent_paths
@@ -753,7 +747,7 @@ class TestGem < Gem::TestCase
s.files << discover_path
end
- write_file(File.join "gems", spec.full_name, discover_path) do |fp|
+ write_file(File.join("gems", spec.full_name, discover_path)) do |fp|
fp.puts "# #{spec.full_name}"
end
@@ -774,42 +768,6 @@ class TestGem < Gem::TestCase
assert_equal cwd, $LOAD_PATH.shift
end
- def test_self_find_files_with_gemfile
- cwd = File.expand_path("test/rubygems", PROJECT_DIR)
- actual_load_path = $LOAD_PATH.unshift(cwd).dup
-
- discover_path = File.join "lib", "sff", "discover.rb"
-
- foo1, _ = %w[1 2].map do |version|
- spec = quick_gem "sff", version do |s|
- s.files << discover_path
- end
-
- write_file(File.join "gems", spec.full_name, discover_path) do |fp|
- fp.puts "# #{spec.full_name}"
- end
-
- spec
- end
- Gem.refresh
-
- write_file(File.join Dir.pwd, "Gemfile") do |fp|
- fp.puts "source 'https://rubygems.org'"
- fp.puts "gem '#{foo1.name}', '#{foo1.version}'"
- end
- Gem.use_gemdeps(File.join Dir.pwd, "Gemfile")
-
- expected = [
- File.expand_path("test/rubygems/sff/discover.rb", PROJECT_DIR),
- File.join(foo1.full_gem_path, discover_path),
- ].sort
-
- assert_equal expected, Gem.find_files("sff/discover").sort
- assert_equal expected, Gem.find_files("sff/**.rb").sort, "[ruby-core:31730]"
- ensure
- assert_equal cwd, actual_load_path.shift unless Gem.java_platform?
- end
-
def test_self_find_latest_files
cwd = File.expand_path("test/rubygems", PROJECT_DIR)
$LOAD_PATH.unshift cwd
@@ -821,7 +779,7 @@ class TestGem < Gem::TestCase
s.files << discover_path
end
- write_file(File.join "gems", spec.full_name, discover_path) do |fp|
+ write_file(File.join("gems", spec.full_name, discover_path)) do |fp|
fp.puts "# #{spec.full_name}"
end
@@ -1019,11 +977,11 @@ class TestGem < Gem::TestCase
pend "chmod not supported" if Gem.win_platform?
begin
- File.chmod 0444, "test"
+ File.chmod 0o444, "test"
assert_equal ["\xCF", "\x80"], Gem.read_binary("test").chars.to_a
ensure
- File.chmod 0644, "test"
+ File.chmod 0o644, "test"
end
end
@@ -1084,7 +1042,8 @@ class TestGem < Gem::TestCase
end
def test_self_ruby_api_version
- orig_ruby_version, RbConfig::CONFIG["ruby_version"] = RbConfig::CONFIG["ruby_version"], "1.2.3"
+ orig_ruby_version = RbConfig::CONFIG["ruby_version"]
+ RbConfig::CONFIG["ruby_version"] = "1.2.3"
Gem.instance_variable_set :@ruby_api_version, nil
@@ -1107,7 +1066,7 @@ class TestGem < Gem::TestCase
end
def test_self_ruby_version_with_non_mri_implementations
- util_set_RUBY_VERSION "2.5.0", 0, 60928, "jruby 9.2.0.0 (2.5.0) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]"
+ util_set_RUBY_VERSION "2.5.0", 0, 60_928, "jruby 9.2.0.0 (2.5.0) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]"
assert_equal Gem::Version.new("2.5.0"), Gem.ruby_version
ensure
@@ -1115,7 +1074,7 @@ class TestGem < Gem::TestCase
end
def test_self_ruby_version_with_svn_prerelease
- util_set_RUBY_VERSION "2.6.0", -1, 63539, "ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-linux]"
+ util_set_RUBY_VERSION "2.6.0", -1, 63_539, "ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-linux]"
assert_equal Gem::Version.new("2.6.0.preview2"), Gem.ruby_version
ensure
@@ -1131,7 +1090,7 @@ class TestGem < Gem::TestCase
end
def test_self_ruby_version_with_non_mri_implementations_with_mri_prerelase_compatibility
- util_set_RUBY_VERSION "2.6.0", -1, 63539, "weirdjruby 9.2.0.0 (2.6.0preview2) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]", "weirdjruby", "9.2.0.0"
+ util_set_RUBY_VERSION "2.6.0", -1, 63_539, "weirdjruby 9.2.0.0 (2.6.0preview2) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]", "weirdjruby", "9.2.0.0"
assert_equal Gem::Version.new("2.6.0.preview2"), Gem.ruby_version
ensure
@@ -1139,7 +1098,7 @@ class TestGem < Gem::TestCase
end
def test_self_ruby_version_with_svn_trunk
- util_set_RUBY_VERSION "1.9.2", -1, 23493, "ruby 1.9.2dev (2009-05-20 trunk 23493) [x86_64-linux]"
+ util_set_RUBY_VERSION "1.9.2", -1, 23_493, "ruby 1.9.2dev (2009-05-20 trunk 23493) [x86_64-linux]"
assert_equal Gem::Version.new("1.9.2.dev"), Gem.ruby_version
ensure
@@ -1295,8 +1254,8 @@ class TestGem < Gem::TestCase
Gem.try_activate "a_file"
end
- assert_match %r{Could not find 'b' }, e.message
- assert_match %r{at: #{a.spec_file}}, e.message
+ assert_include(e.message, "Could not find 'b' ")
+ assert_include(e.message, "at: #{a.spec_file}")
end
def test_self_try_activate_missing_prerelease
@@ -1316,7 +1275,7 @@ class TestGem < Gem::TestCase
Gem.try_activate "a_file"
end
- assert_match %r{Could not find 'b' \(= 1.0rc1\)}, e.message
+ assert_match(/Could not find 'b' \(= 1.0rc1\)/, e.message)
end
def test_self_try_activate_missing_extensions
@@ -1335,12 +1294,10 @@ class TestGem < Gem::TestCase
refute Gem.try_activate "nonexistent"
end
- unless Gem.java_platform?
- expected = "Ignoring ext-1 because its extensions are not built. " +
- "Try: gem pristine ext --version 1\n"
+ expected = "Ignoring ext-1 because its extensions are not built. " \
+ "Try: gem pristine ext --version 1\n"
- assert_equal expected, err
- end
+ assert_equal expected, err
end
def test_self_use_paths_with_nils
@@ -1357,8 +1314,8 @@ class TestGem < Gem::TestCase
def test_setting_paths_does_not_warn_about_unknown_keys
stdout, stderr = capture_output do
- Gem.paths = { "foo" => [],
- "bar" => Object.new,
+ Gem.paths = { "foo" => [],
+ "bar" => Object.new,
"GEM_HOME" => Gem.paths.home,
"GEM_PATH" => "foo" }
end
@@ -1369,7 +1326,7 @@ class TestGem < Gem::TestCase
def test_setting_paths_does_not_mutate_parameter_object
Gem.paths = { "GEM_HOME" => Gem.paths.home,
- "GEM_PATH" => "foo" }.freeze
+ "GEM_PATH" => "foo" } .freeze
assert_equal ["foo", Gem.paths.home], Gem.paths.path
end
@@ -1421,7 +1378,7 @@ class TestGem < Gem::TestCase
r.gem "b", "= 1"
end
- activated = Gem::Specification.map {|x| x.full_name }
+ activated = Gem::Specification.map(&:full_name)
assert_equal %w[a-1 b-1 c-2], activated.sort
end
@@ -1446,7 +1403,7 @@ class TestGem < Gem::TestCase
end
def test_self_gunzip
- input = "\x1F\x8B\b\0\xED\xA3\x1AQ\0\x03\xCBH" +
+ input = "\x1F\x8B\b\0\xED\xA3\x1AQ\0\x03\xCBH" \
"\xCD\xC9\xC9\a\0\x86\xA6\x106\x05\0\0\0"
output = Gem::Util.gunzip input
@@ -1492,6 +1449,8 @@ class TestGem < Gem::TestCase
def test_load_plugins
plugin_path = File.join "lib", "rubygems_plugin.rb"
+ foo1_plugin_path = nil
+ foo2_plugin_path = nil
Dir.chdir @tempdir do
FileUtils.mkdir_p "lib"
File.open plugin_path, "w" do |fp|
@@ -1501,17 +1460,22 @@ class TestGem < Gem::TestCase
foo1 = util_spec "foo", "1" do |s|
s.files << plugin_path
end
+ foo1_plugin_path = File.join(foo1.gem_dir, plugin_path)
install_gem foo1
foo2 = util_spec "foo", "2" do |s|
s.files << plugin_path
end
+ foo2_plugin_path = File.join(foo2.gem_dir, plugin_path)
install_gem foo2
end
Gem::Specification.reset
+ PLUGINS_LOADED.clear
+ $LOADED_FEATURES.delete(foo1_plugin_path)
+ $LOADED_FEATURES.delete(foo2_plugin_path)
gem "foo"
@@ -1521,6 +1485,9 @@ class TestGem < Gem::TestCase
end
def test_load_user_installed_plugins
+ @orig_gem_home = ENV["GEM_HOME"]
+ ENV["GEM_HOME"] = @gemhome
+
plugin_path = File.join "lib", "rubygems_plugin.rb"
Dir.chdir @tempdir do
@@ -1543,23 +1510,37 @@ class TestGem < Gem::TestCase
Gem.load_plugins
assert_equal %w[plugin], PLUGINS_LOADED
+ ensure
+ ENV["GEM_HOME"] = @orig_gem_home
end
def test_load_env_plugins
with_plugin("load") { Gem.load_env_plugins }
- assert_equal :loaded, TEST_PLUGIN_LOAD rescue nil
+ begin
+ assert_equal :loaded, TEST_PLUGIN_LOAD
+ rescue StandardError
+ nil
+ end
util_remove_interrupt_command
# Should attempt to cause a StandardError
with_plugin("standarderror") { Gem.load_env_plugins }
- assert_equal :loaded, TEST_PLUGIN_STANDARDERROR rescue nil
+ begin
+ assert_equal :loaded, TEST_PLUGIN_STANDARDERROR
+ rescue StandardError
+ nil
+ end
util_remove_interrupt_command
# Should attempt to cause an Exception
- with_plugin("exception") { Gem.load_env_plugins }
- assert_equal :loaded, TEST_PLUGIN_EXCEPTION rescue nil
+ with_plugin("scripterror") { Gem.load_env_plugins }
+ begin
+ assert_equal :loaded, TEST_PLUGIN_EXCEPTION
+ rescue StandardError
+ nil
+ end
end
def test_gem_path_ordering
@@ -1571,20 +1552,20 @@ class TestGem < Gem::TestCase
g = util_spec "g", "1", nil, "lib/g.rb"
m = util_spec "m", "1", nil, "lib/m.rb"
- install_gem g, :install_dir => Gem.dir
- m0 = install_gem m, :install_dir => Gem.dir
- m1 = install_gem m, :install_dir => Gem.user_dir
+ install_gem g, install_dir: Gem.dir
+ m0 = install_gem m, install_dir: Gem.dir
+ m1 = install_gem m, install_dir: Gem.user_dir
assert_equal m0.gem_dir, File.join(Gem.dir, "gems", "m-1")
assert_equal m1.gem_dir, File.join(Gem.user_dir, "gems", "m-1")
tests = [
- [:dir0, [ Gem.dir, Gem.user_dir], m0],
- [:dir1, [ Gem.user_dir, Gem.dir], m1],
+ [:dir0, [Gem.dir, Gem.user_dir], m0],
+ [:dir1, [Gem.user_dir, Gem.dir], m1],
]
- tests.each do |_name, _paths, expected|
- Gem.use_paths _paths.first, _paths
+ tests.each do |name, paths, expected|
+ Gem.use_paths paths.first, paths
Gem::Specification.reset
Gem.searcher = nil
@@ -1594,25 +1575,25 @@ class TestGem < Gem::TestCase
assert_equal \
[expected.gem_dir],
Gem::Dependency.new("m","1").to_specs.map(&:gem_dir).sort,
- "Wrong specs for #{_name}"
+ "Wrong specs for #{name}"
spec = Gem::Dependency.new("m","1").to_spec
assert_equal \
- File.join(_paths.first, "gems", "m-1"),
+ File.join(paths.first, "gems", "m-1"),
spec.gem_dir,
- "Wrong spec before require for #{_name}"
- refute spec.activated?, "dependency already activated for #{_name}"
+ "Wrong spec before require for #{name}"
+ refute spec.activated?, "dependency already activated for #{name}"
gem "m"
spec = Gem::Dependency.new("m","1").to_spec
- assert spec.activated?, "dependency not activated for #{_name}"
+ assert spec.activated?, "dependency not activated for #{name}"
assert_equal \
- File.join(_paths.first, "gems", "m-1"),
+ File.join(paths.first, "gems", "m-1"),
spec.gem_dir,
- "Wrong spec after require for #{_name}"
+ "Wrong spec after require for #{name}"
spec.instance_variable_set :@activated, false
Gem.loaded_specs.delete(spec.name)
@@ -1627,11 +1608,11 @@ class TestGem < Gem::TestCase
g = util_spec "g", "1", nil, "lib/g.rb"
m = util_spec "m", "1", nil, "lib/m.rb"
- install_gem g, :install_dir => Gem.dir
- install_gem m, :install_dir => Gem.dir
- install_gem m, :install_dir => Gem.user_dir
+ install_gem g, install_dir: Gem.dir
+ install_gem m, install_dir: Gem.dir
+ install_gem m, install_dir: Gem.user_dir
- Gem.use_paths Gem.dir, [ Gem.dir, Gem.user_dir]
+ Gem.use_paths Gem.dir, [Gem.dir, Gem.user_dir]
assert_equal \
File.join(Gem.dir, "gems", "m-1"),
@@ -1639,163 +1620,6 @@ class TestGem < Gem::TestCase
"Wrong spec selected"
end
- def test_auto_activation_of_specific_gemdeps_file
- a = util_spec "a", "1", nil, "lib/a.rb"
- b = util_spec "b", "1", nil, "lib/b.rb"
- c = util_spec "c", "1", nil, "lib/c.rb"
-
- install_specs a, b, c
-
- path = File.join @tempdir, "gem.deps.rb"
-
- File.open path, "w" do |f|
- f.puts "gem 'a'"
- f.puts "gem 'b'"
- f.puts "gem 'c'"
- end
-
- with_rubygems_gemdeps(path) do
- Gem.use_gemdeps
-
- assert_equal add_bundler_full_name(%W[a-1 b-1 c-1]), loaded_spec_names
- end
- end
-
- def test_auto_activation_of_used_gemdeps_file
- a = util_spec "a", "1", nil, "lib/a.rb"
- b = util_spec "b", "1", nil, "lib/b.rb"
- c = util_spec "c", "1", nil, "lib/c.rb"
-
- install_specs a, b, c
-
- path = File.join @tempdir, "gem.deps.rb"
-
- File.open path, "w" do |f|
- f.puts "gem 'a'"
- f.puts "gem 'b'"
- f.puts "gem 'c'"
- end
-
- with_rubygems_gemdeps("-") do
- expected_specs = [a, b, util_spec("bundler", Bundler::VERSION), c].compact.map(&:full_name)
-
- Gem.use_gemdeps
-
- assert_equal expected_specs, loaded_spec_names
- end
- end
-
- BUNDLER_LIB_PATH = File.expand_path $LOAD_PATH.find {|lp| File.file?(File.join(lp, "bundler.rb")) }
- BUNDLER_FULL_NAME = "bundler-#{Bundler::VERSION}".freeze
-
- def add_bundler_full_name(names)
- names << BUNDLER_FULL_NAME
- names.sort!
- names
- end
-
- def test_looks_for_gemdeps_files_automatically_from_binstubs
- pend "Requiring bundler messes things up" if Gem.java_platform?
-
- a = util_spec "a", "1" do |s|
- s.executables = %w[foo]
- s.bindir = "exe"
- end
-
- write_file File.join(@tempdir, "exe", "foo") do |fp|
- fp.puts "puts Gem.loaded_specs.values.map(&:full_name).sort"
- end
-
- b = util_spec "b", "1", nil, "lib/b.rb"
- c = util_spec "c", "1", nil, "lib/c.rb"
-
- install_specs a, b, c
-
- path = File.join(@tempdir, "gd-tmp")
- install_gem a, :install_dir => path
- install_gem b, :install_dir => path
- install_gem c, :install_dir => path
-
- ENV["GEM_PATH"] = path
-
- with_rubygems_gemdeps("-") do
- new_PATH = [File.join(path, "bin"), ENV["PATH"]].join(File::PATH_SEPARATOR)
- new_RUBYOPT = "-I#{rubygems_path} -I#{BUNDLER_LIB_PATH}"
-
- path = File.join @tempdir, "gem.deps.rb"
-
- File.open path, "w" do |f|
- f.puts "gem 'a'"
- end
- out0 = with_path_and_rubyopt(new_PATH, new_RUBYOPT) do
- IO.popen("foo", &:read).split(/\n/)
- end
-
- File.open path, "a" do |f|
- f.puts "gem 'b'"
- f.puts "gem 'c'"
- end
- out = with_path_and_rubyopt(new_PATH, new_RUBYOPT) do
- IO.popen("foo", &:read).split(/\n/)
- end
-
- assert_equal ["b-1", "c-1"], out - out0
- end
- end
-
- def test_looks_for_gemdeps_files_automatically_from_binstubs_in_parent_dir
- pend "Requiring bundler messes things up" if Gem.java_platform?
-
- a = util_spec "a", "1" do |s|
- s.executables = %w[foo]
- s.bindir = "exe"
- end
-
- write_file File.join(@tempdir, "exe", "foo") do |fp|
- fp.puts "puts Gem.loaded_specs.values.map(&:full_name).sort"
- end
-
- b = util_spec "b", "1", nil, "lib/b.rb"
- c = util_spec "c", "1", nil, "lib/c.rb"
-
- install_specs a, b, c
-
- path = File.join(@tempdir, "gd-tmp")
- install_gem a, :install_dir => path
- install_gem b, :install_dir => path
- install_gem c, :install_dir => path
-
- ENV["GEM_PATH"] = path
-
- with_rubygems_gemdeps("-") do
- Dir.mkdir "sub1"
-
- new_PATH = [File.join(path, "bin"), ENV["PATH"]].join(File::PATH_SEPARATOR)
- new_RUBYOPT = "-I#{rubygems_path} -I#{BUNDLER_LIB_PATH}"
-
- path = File.join @tempdir, "gem.deps.rb"
-
- File.open path, "w" do |f|
- f.puts "gem 'a'"
- end
- out0 = with_path_and_rubyopt(new_PATH, new_RUBYOPT) do
- IO.popen("foo", :chdir => "sub1", &:read).split(/\n/)
- end
-
- File.open path, "a" do |f|
- f.puts "gem 'b'"
- f.puts "gem 'c'"
- end
- out = with_path_and_rubyopt(new_PATH, new_RUBYOPT) do
- IO.popen("foo", :chdir => "sub1", &:read).split(/\n/)
- end
-
- Dir.rmdir "sub1"
-
- assert_equal ["b-1", "c-1"], out - out0
- end
- end
-
def test_register_default_spec
Gem.clear_default_specs
@@ -1836,155 +1660,17 @@ class TestGem < Gem::TestCase
assert_equal old_style, Gem.find_unresolved_default_spec("foo.rb")
end
- def test_use_gemdeps
- gem_deps_file = "gem.deps.rb".tap(&Gem::UNTAINT)
- spec = util_spec "a", 1
- install_specs spec
-
- spec = Gem::Specification.find {|s| s == spec }
- refute spec.activated?
-
- File.open gem_deps_file, "w" do |io|
- io.write 'gem "a"'
- end
-
- assert_nil Gem.gemdeps
-
- Gem.use_gemdeps gem_deps_file
-
- assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names
- refute_nil Gem.gemdeps
- end
-
- def test_use_gemdeps_ENV
- with_rubygems_gemdeps(nil) do
- spec = util_spec "a", 1
-
- refute spec.activated?
-
- File.open "gem.deps.rb", "w" do |io|
- io.write 'gem "a"'
- end
-
- Gem.use_gemdeps
-
- refute spec.activated?
- end
- end
-
- def test_use_gemdeps_argument_missing
- e = assert_raise ArgumentError do
- Gem.use_gemdeps "gem.deps.rb"
- end
-
- assert_equal "Unable to find gem dependencies file at gem.deps.rb",
- e.message
- end
-
- def test_use_gemdeps_argument_missing_match_ENV
- with_rubygems_gemdeps("gem.deps.rb") do
- e = assert_raise ArgumentError do
- Gem.use_gemdeps "gem.deps.rb"
- end
-
- assert_equal "Unable to find gem dependencies file at gem.deps.rb",
- e.message
- end
- end
-
- def test_use_gemdeps_automatic
- with_rubygems_gemdeps("-") do
- spec = util_spec "a", 1
- install_specs spec
- spec = Gem::Specification.find {|s| s == spec }
-
- refute spec.activated?
-
- File.open "Gemfile", "w" do |io|
- io.write 'gem "a"'
- end
-
- Gem.use_gemdeps
-
- assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names
- end
- end
-
- def test_use_gemdeps_automatic_missing
- with_rubygems_gemdeps("-") do
- Gem.use_gemdeps
-
- assert true # count
- end
- end
-
- def test_use_gemdeps_disabled
- with_rubygems_gemdeps("") do
- spec = util_spec "a", 1
-
- refute spec.activated?
-
- File.open "gem.deps.rb", "w" do |io|
- io.write 'gem "a"'
- end
-
- Gem.use_gemdeps
-
- refute spec.activated?
- end
- end
-
- def test_use_gemdeps_missing_gem
- with_rubygems_gemdeps("x") do
- File.open "x", "w" do |io|
- io.write 'gem "a"'
- end
-
- expected = <<-EXPECTED
-Could not find gem 'a' in locally installed gems.
-You may need to `bundle install` to install missing gems
-
- EXPECTED
-
- Gem::Deprecate.skip_during do
- actual_stdout, actual_stderr = capture_output do
- Gem.use_gemdeps
- end
- assert_empty actual_stdout
- assert_equal(expected, actual_stderr)
- end
- end
- end
-
- def test_use_gemdeps_specific
- with_rubygems_gemdeps("x") do
- spec = util_spec "a", 1
- install_specs spec
-
- spec = Gem::Specification.find {|s| s == spec }
- refute spec.activated?
-
- File.open "x", "w" do |io|
- io.write 'gem "a"'
- end
-
- Gem.use_gemdeps
-
- assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names
- end
- end
-
def test_operating_system_defaults
operating_system_defaults = Gem.operating_system_defaults
- assert operating_system_defaults != nil
+ assert !operating_system_defaults.nil?
assert operating_system_defaults.is_a? Hash
end
def test_platform_defaults
platform_defaults = Gem.platform_defaults
- assert platform_defaults != nil
+ assert !platform_defaults.nil?
assert platform_defaults.is_a? Hash
end
@@ -2006,18 +1692,42 @@ You may need to `bundle install` to install missing gems
ENV["SOURCE_DATE_EPOCH"] = old_epoch
end
+ def test_data_home_default
+ expected = File.join(@userhome, ".local", "share")
+ assert_equal expected, Gem.data_home
+ end
+
+ def test_data_home_from_env
+ ENV["XDG_DATA_HOME"] = expected = "/test/data/home"
+ assert_equal expected, Gem.data_home
+ end
+
+ def test_state_home_default
+ Gem.instance_variable_set :@state_home, nil
+ Gem.data_home # memoize @data_home, to demonstrate GH-6418
+ expected = File.join(@userhome, ".local", "state")
+ assert_equal expected, Gem.state_home
+ end
+
+ def test_state_home_from_env
+ Gem.instance_variable_set :@state_home, nil
+ Gem.data_home # memoize @data_home, to demonstrate GH-6418
+ ENV["XDG_STATE_HOME"] = expected = "/test/state/home"
+ assert_equal expected, Gem.state_home
+ end
+
private
def ruby_install_name(name)
with_clean_path_to_ruby do
- orig_RUBY_INSTALL_NAME = RbConfig::CONFIG["ruby_install_name"]
+ orig_ruby_install_name = RbConfig::CONFIG["ruby_install_name"]
RbConfig::CONFIG["ruby_install_name"] = name
begin
yield
ensure
- if orig_RUBY_INSTALL_NAME
- RbConfig::CONFIG["ruby_install_name"] = orig_RUBY_INSTALL_NAME
+ if orig_ruby_install_name
+ RbConfig::CONFIG["ruby_install_name"] = orig_ruby_install_name
else
RbConfig::CONFIG.delete "ruby_install_name"
end
@@ -2037,13 +1747,8 @@ You may need to `bundle install` to install missing gems
end
def redefine_method(base, method, new_result)
- if RUBY_VERSION >= "2.5"
- base.alias_method(method, method)
- base.define_method(method) { new_result }
- else
- base.send(:alias_method, method, method)
- base.send(:define_method, method) { new_result }
- end
+ base.alias_method(method, method)
+ base.define_method(method) { new_result }
end
def with_plugin(path)
@@ -2068,7 +1773,7 @@ You may need to `bundle install` to install missing gems
#
# FIXME what does this solve precisely? -ebh
#
- @additional.each do |dir|
+ @additional.each do |_dir|
Gem.ensure_gem_subdirectories @gemhome
end
end
@@ -2091,22 +1796,4 @@ You may need to `bundle install` to install missing gems
def util_cache_dir
File.join Gem.dir, "cache"
end
-
- def with_path_and_rubyopt(path_value, rubyopt_value)
- path, ENV["PATH"] = ENV["PATH"], path_value
- rubyopt, ENV["RUBYOPT"] = ENV["RUBYOPT"], rubyopt_value
-
- yield
- ensure
- ENV["PATH"] = path
- ENV["RUBYOPT"] = rubyopt
- end
-
- def with_rubygems_gemdeps(value)
- rubygems_gemdeps, ENV["RUBYGEMS_GEMDEPS"] = ENV["RUBYGEMS_GEMDEPS"], value
-
- yield
- ensure
- ENV["RUBYGEMS_GEMDEPS"] = rubygems_gemdeps
- end
end
diff --git a/test/rubygems/test_gem_available_set.rb b/test/rubygems/test_gem_available_set.rb
index 576f3f4221..7c24d25bcb 100644
--- a/test/rubygems/test_gem_available_set.rb
+++ b/test/rubygems/test_gem_available_set.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/available_set"
require "rubygems/security"
@@ -36,12 +37,12 @@ class TestGemAvailableSet < Gem::TestCase
dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
- assert_equal %w[a-1], set.find_all(dep).map {|spec| spec.full_name }
+ assert_equal %w[a-1], set.find_all(dep).map(&:full_name)
dep = Gem::Resolver::DependencyRequest.new dep("a", ">= 0.a"), nil
assert_equal %w[a-1 a-1.a],
- set.find_all(dep).map {|spec| spec.full_name }.sort
+ set.find_all(dep).map(&:full_name).sort
end
def test_match_platform
@@ -122,7 +123,7 @@ class TestGemAvailableSet < Gem::TestCase
set.add a2a, @source
set.add a2, @source
- g = set.sorted.map {|t| t.spec }
+ g = set.sorted.map(&:spec)
assert_equal [a3a, a2, a2a, a1, a1a], g
end
diff --git a/test/rubygems/test_gem_bundler_version_finder.rb b/test/rubygems/test_gem_bundler_version_finder.rb
index 60e2b65047..6d88810493 100644
--- a/test/rubygems/test_gem_bundler_version_finder.rb
+++ b/test/rubygems/test_gem_bundler_version_finder.rb
@@ -1,12 +1,14 @@
# frozen_string_literal: true
+
require_relative "helper"
+require "rubygems/bundler_version_finder"
class TestGemBundlerVersionFinder < Gem::TestCase
def setup
- super
-
@argv = ARGV.dup
@dollar_0 = $0
+ super
+
without_any_upwards_gemfiles
end
@@ -77,7 +79,7 @@ class TestGemBundlerVersionFinder < Gem::TestCase
end
def test_deleted_directory
- pend "Cannot perform this test on windows" if win_platform?
+ pend "Cannot perform this test on windows" if Gem.win_platform?
pend "Cannot perform this test on Solaris" if RUBY_PLATFORM.include?("solaris")
require "tmpdir"
diff --git a/test/rubygems/test_gem_ci_detector.rb b/test/rubygems/test_gem_ci_detector.rb
new file mode 100644
index 0000000000..3caefce97d
--- /dev/null
+++ b/test/rubygems/test_gem_ci_detector.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems"
+
+class TestCiDetector < Test::Unit::TestCase
+ def test_ci?
+ with_env("FOO" => "bar") { assert_equal(false, Gem::CIDetector.ci?) }
+ with_env("CI" => "true") { assert_equal(true, Gem::CIDetector.ci?) }
+ with_env("CONTINUOUS_INTEGRATION" => "1") { assert_equal(true, Gem::CIDetector.ci?) }
+ with_env("RUN_ID" => "0", "TASKCLUSTER_ROOT_URL" => "2") do
+ assert_equal(true, Gem::CIDetector.ci?)
+ end
+ end
+
+ def test_ci_strings
+ with_env("FOO" => "bar") { assert_empty(Gem::CIDetector.ci_strings) }
+ with_env("TRAVIS" => "true") { assert_equal(["travis"], Gem::CIDetector.ci_strings) }
+ with_env("CI" => "true", "CIRCLECI" => "true", "GITHUB_ACTIONS" => "true") do
+ assert_equal(["ci", "circle", "github"], Gem::CIDetector.ci_strings)
+ end
+ with_env("CI" => "true", "CI_NAME" => "MYCI") do
+ assert_equal(["ci", "myci"], Gem::CIDetector.ci_strings)
+ end
+ with_env("GITHUB_ACTIONS" => "true", "CI_NAME" => "github") do
+ assert_equal(["github"], Gem::CIDetector.ci_strings)
+ end
+ with_env("TASKCLUSTER_ROOT_URL" => "https://foo.bar", "DSARI" => "1", "CI_NAME" => "") do
+ 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_command.rb b/test/rubygems/test_gem_command.rb
index 99fa89364d..3695f9488f 100644
--- a/test/rubygems/test_gem_command.rb
+++ b/test/rubygems/test_gem_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/command"
@@ -15,7 +16,7 @@ class TestGemCommand < Gem::TestCase
@common_options = Gem::Command.common_options.dup
Gem::Command.common_options.clear
Gem::Command.common_options << [
- ["-x", "--exe", "Execute"], lambda do |*a|
+ ["-x", "--exe", "Execute"], lambda do |*_a|
@xopt = true
end
]
@@ -55,7 +56,9 @@ class TestGemCommand < Gem::TestCase
end
def test_self_extra_args
- verbose, $VERBOSE, separator = $VERBOSE, nil, $;
+ verbose = $VERBOSE
+ $VERBOSE = nil
+ separator = $;
extra_args = Gem::Command.extra_args
Gem::Command.extra_args = %w[--all]
@@ -68,7 +71,6 @@ class TestGemCommand < Gem::TestCase
Gem::Command.extra_args = "--awesome=true --verbose"
assert_equal %w[--awesome=true --verbose], Gem::Command.extra_args
-
ensure
Gem::Command.extra_args = extra_args
$; = separator
@@ -90,7 +92,7 @@ class TestGemCommand < Gem::TestCase
options[:help] = value
end
- @cmd.defaults = { :help => true }
+ @cmd.defaults = { help: true }
@cmd.when_invoked do |options|
assert options[:help], "Help options should default true"
@@ -100,7 +102,7 @@ class TestGemCommand < Gem::TestCase
@cmd.invoke
end
- assert_match %r{Usage: gem doit}, @ui.output
+ assert_match(/Usage: gem doit/, @ui.output)
end
def test_invoke
@@ -151,7 +153,7 @@ class TestGemCommand < Gem::TestCase
done = false
use_ui @ui do
- @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |value, options|
+ @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |_value, options|
options[:help] = true
done = true
end
@@ -174,7 +176,7 @@ class TestGemCommand < Gem::TestCase
end
def test_invoke_with_options
- @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |value, options|
+ @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |_value, options|
options[:help] = true
end
@@ -186,7 +188,7 @@ class TestGemCommand < Gem::TestCase
@cmd.invoke "-h"
end
- assert_match %r{Usage: gem doit}, @ui.output
+ assert_match(/Usage: gem doit/, @ui.output)
end
def test_add_option
@@ -202,13 +204,13 @@ class TestGemCommand < Gem::TestCase
end
def test_option_recognition
- @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |value, options|
+ @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |_value, options|
options[:help] = true
end
- @cmd.add_option("-f", "--file FILE", "File option") do |value, options|
+ @cmd.add_option("-f", "--file FILE", "File option") do |_value, options|
options[:help] = true
end
- @cmd.add_option("--silent", "Silence RubyGems output") do |value, options|
+ @cmd.add_option("--silent", "Silence RubyGems output") do |_value, options|
options[:silent] = true
end
assert @cmd.handles?(["-x"])
@@ -232,11 +234,11 @@ class TestGemCommand < Gem::TestCase
WARNING: The \"--test\" option has been deprecated and will be removed in Rubygems 3.1.
EXPECTED
- testCommand = Class.new(Gem::Command) do
+ test_command = Class.new(Gem::Command) do
def initialize
super("test", "Gem::Command instance for testing")
- add_option("-t", "--test", "Test command") do |value, options|
+ add_option("-t", "--test", "Test command") do |_value, options|
options[:test] = true
end
@@ -248,7 +250,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg
end
end
- cmd = testCommand.new
+ cmd = test_command.new
use_ui @ui do
cmd.invoke("--test")
@@ -261,11 +263,11 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg
WARNING: The \"--test\" option has been deprecated and will be removed in future versions of Rubygems.
EXPECTED
- testCommand = Class.new(Gem::Command) do
+ test_command = Class.new(Gem::Command) do
def initialize
super("test", "Gem::Command instance for testing")
- add_option("-t", "--test", "Test command") do |value, options|
+ add_option("-t", "--test", "Test command") do |_value, options|
options[:test] = true
end
@@ -277,7 +279,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in futur
end
end
- cmd = testCommand.new
+ cmd = test_command.new
use_ui @ui do
cmd.invoke("--test")
@@ -290,11 +292,11 @@ WARNING: The \"--test\" option has been deprecated and will be removed in futur
WARNING: The \"--test\" option has been deprecated and will be removed in Rubygems 3.1. Whether you set `--test` mode or not, this dummy app always runs in test mode.
EXPECTED
- testCommand = Class.new(Gem::Command) do
+ test_command = Class.new(Gem::Command) do
def initialize
super("test", "Gem::Command instance for testing")
- add_option("-t", "--test", "Test command") do |value, options|
+ add_option("-t", "--test", "Test command") do |_value, options|
options[:test] = true
end
@@ -306,7 +308,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg
end
end
- cmd = testCommand.new
+ cmd = test_command.new
use_ui @ui do
cmd.invoke("--test")
@@ -319,11 +321,11 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg
WARNING: The \"--test\" option has been deprecated and will be removed in future versions of Rubygems. Whether you set `--test` mode or not, this dummy app always runs in test mode.
EXPECTED
- testCommand = Class.new(Gem::Command) do
+ test_command = Class.new(Gem::Command) do
def initialize
super("test", "Gem::Command instance for testing")
- add_option("-t", "--test", "Test command") do |value, options|
+ add_option("-t", "--test", "Test command") do |_value, options|
options[:test] = true
end
@@ -335,7 +337,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in futur
end
end
- cmd = testCommand.new
+ cmd = test_command.new
use_ui @ui do
cmd.invoke("--test")
diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb
index b8f35192ae..f04ec0cafa 100644
--- a/test/rubygems/test_gem_command_manager.rb
+++ b/test/rubygems/test_gem_command_manager.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/command_manager"
class TestGemCommandManager < Gem::TestCase
- PROJECT_DIR = File.expand_path("../..", __dir__).tap(&Gem::UNTAINT)
+ PROJECT_DIR = File.expand_path("../..", __dir__)
def setup
super
@@ -76,7 +77,7 @@ class TestGemCommandManager < Gem::TestCase
message = "Unknown command pish".dup
- if RUBY_VERSION >= "2.4" && defined?(DidYouMean::SPELL_CHECKERS) && defined?(DidYouMean::Correctable)
+ if defined?(DidYouMean::SPELL_CHECKERS) && defined?(DidYouMean::Correctable)
message << "\nDid you mean? \"push\""
end
@@ -126,6 +127,46 @@ class TestGemCommandManager < Gem::TestCase
@command_manager.unregister_command :crash
end
+ def test_process_args_with_c_flag
+ custom_start_point = File.join @tempdir, "nice_folder"
+ FileUtils.mkdir_p custom_start_point
+
+ execution_path = nil
+ use_ui @ui do
+ @command_manager[:install].when_invoked do
+ execution_path = Dir.pwd
+ true
+ end
+ @command_manager.process_args %W[-C #{custom_start_point} install net-scp-4.0.0.gem --local]
+ end
+
+ assert_equal custom_start_point, execution_path
+ end
+
+ def test_process_args_with_c_flag_without_path
+ use_ui @ui do
+ assert_raise Gem::MockGemUi::TermError do
+ @command_manager.process_args %w[-C install net-scp-4.0.0.gem --local]
+ end
+ end
+
+ assert_match(/install isn't a directory\./i, @ui.error)
+ end
+
+ def test_process_args_with_c_flag_path_not_found
+ custom_start_point = File.join @tempdir, "nice_folder"
+ FileUtils.mkdir_p custom_start_point
+ custom_start_point.tr!("_", "-")
+
+ use_ui @ui do
+ assert_raise Gem::MockGemUi::TermError do
+ @command_manager.process_args %W[-C #{custom_start_point} install net-scp-4.0.0.gem --local]
+ end
+ end
+
+ assert_match(/#{Regexp.quote(custom_start_point)} isn't a directory\./i, @ui.error)
+ end
+
def test_process_args_bad_arg
use_ui @ui do
assert_raise Gem::MockGemUi::TermError do
@@ -136,9 +177,9 @@ class TestGemCommandManager < Gem::TestCase
assert_match(/invalid option: --bad-arg/i, @ui.error)
end
- # HACK move to install command test
+ # HACK: move to install command test
def test_process_args_install
- #capture all install options
+ # capture all install options
use_ui @ui do
check_options = nil
@command_manager["install"].when_invoked do |options|
@@ -146,7 +187,7 @@ class TestGemCommandManager < Gem::TestCase
true
end
- #check defaults
+ # check defaults
@command_manager.process_args %w[install]
assert_equal %w[ri], check_options[:document].sort
assert_equal false, check_options[:force]
@@ -156,7 +197,7 @@ class TestGemCommandManager < Gem::TestCase
assert_nil check_options[:install_dir]
assert_nil check_options[:bin_dir]
- #check settings
+ # check settings
check_options = nil
@command_manager.process_args %w[
install --force --local --document=ri,rdoc --install-dir .
@@ -170,91 +211,91 @@ class TestGemCommandManager < Gem::TestCase
assert_equal Dir.pwd, check_options[:install_dir]
assert_equal Dir.pwd, check_options[:bin_dir]
- #check remote domain
+ # check remote domain
check_options = nil
@command_manager.process_args %w[install --remote]
assert_equal :remote, check_options[:domain]
- #check both domain
+ # check both domain
check_options = nil
@command_manager.process_args %w[install --both]
assert_equal :both, check_options[:domain]
- #check both domain
+ # check both domain
check_options = nil
@command_manager.process_args %w[install --both]
assert_equal :both, check_options[:domain]
end
end
- # HACK move to uninstall command test
+ # HACK: move to uninstall command test
def test_process_args_uninstall
- #capture all uninstall options
+ # capture all uninstall options
check_options = nil
@command_manager["uninstall"].when_invoked do |options|
check_options = options
true
end
- #check defaults
+ # check defaults
@command_manager.process_args %w[uninstall]
assert_equal Gem::Requirement.default, check_options[:version]
- #check settings
+ # check settings
check_options = nil
@command_manager.process_args %w[uninstall foobar --version 3.0]
assert_equal "foobar", check_options[:args].first
assert_equal Gem::Requirement.new("3.0"), check_options[:version]
end
- # HACK move to check command test
+ # HACK: move to check command test
def test_process_args_check
- #capture all check options
+ # capture all check options
check_options = nil
@command_manager["check"].when_invoked do |options|
check_options = options
true
end
- #check defaults
+ # check defaults
@command_manager.process_args %w[check]
assert_equal true, check_options[:alien]
- #check settings
+ # check settings
check_options = nil
@command_manager.process_args %w[check foobar --alien]
assert_equal true, check_options[:alien]
end
- # HACK move to build command test
+ # HACK: move to build command test
def test_process_args_build
- #capture all build options
+ # capture all build options
check_options = nil
@command_manager["build"].when_invoked do |options|
check_options = options
true
end
- #check defaults
+ # check defaults
@command_manager.process_args %w[build]
- #NOTE: Currently no defaults
+ # NOTE: Currently no defaults
- #check settings
+ # check settings
check_options = nil
@command_manager.process_args %w[build foobar.rb]
assert_equal "foobar.rb", check_options[:args].first
end
- # HACK move to query command test
+ # HACK: move to query command test
def test_process_args_query
- #capture all query options
+ # capture all query options
check_options = nil
@command_manager["query"].when_invoked do |options|
check_options = options
true
end
- #check defaults
+ # check defaults
Gem::Deprecate.skip_during do
@command_manager.process_args %w[query]
end
@@ -262,7 +303,7 @@ class TestGemCommandManager < Gem::TestCase
assert_equal :local, check_options[:domain]
assert_equal false, check_options[:details]
- #check settings
+ # check settings
check_options = nil
Gem::Deprecate.skip_during do
@command_manager.process_args %w[query --name foobar --local --details]
@@ -271,14 +312,14 @@ class TestGemCommandManager < Gem::TestCase
assert_equal :local, check_options[:domain]
assert_equal true, check_options[:details]
- #remote domain
+ # remote domain
check_options = nil
Gem::Deprecate.skip_during do
@command_manager.process_args %w[query --remote]
end
assert_equal :remote, check_options[:domain]
- #both (local/remote) domains
+ # both (local/remote) domains
check_options = nil
Gem::Deprecate.skip_during do
@command_manager.process_args %w[query --both]
@@ -286,20 +327,20 @@ class TestGemCommandManager < Gem::TestCase
assert_equal :both, check_options[:domain]
end
- # HACK move to update command test
+ # HACK: move to update command test
def test_process_args_update
- #capture all update options
+ # capture all update options
check_options = nil
@command_manager["update"].when_invoked do |options|
check_options = options
true
end
- #check defaults
+ # check defaults
@command_manager.process_args %w[update]
assert_includes check_options[:document], "ri"
- #check settings
+ # check settings
check_options = nil
@command_manager.process_args %w[update --force --document=ri --install-dir .]
assert_includes check_options[:document], "ri"
@@ -327,7 +368,32 @@ class TestGemCommandManager < Gem::TestCase
end
assert_equal "pew pew!\n", @ui.output
- assert_match(/WARNING: foo command is deprecated. It will be removed in Rubygems [0-9]+/, @ui.error)
+ assert_match(/WARNING: foo command is deprecated\. It will be removed in Rubygems [0-9]+/, @ui.error)
+ ensure
+ Gem::Commands.send(:remove_const, :FooCommand)
+ end
+
+ def test_deprecated_command_with_version
+ require "rubygems/command"
+ foo_command = Class.new(Gem::Command) do
+ extend Gem::Deprecate
+
+ rubygems_deprecate_command("9.9.9")
+
+ def execute
+ say "pew pew!"
+ end
+ end
+
+ Gem::Commands.send(:const_set, :FooCommand, foo_command)
+ @command_manager.register_command(:foo, foo_command.new("foo"))
+
+ use_ui @ui do
+ @command_manager.process_args(%w[foo])
+ end
+
+ assert_equal "pew pew!\n", @ui.output
+ assert_match(/WARNING: foo command is deprecated\. It will be removed in Rubygems 9\.9\.9/, @ui.error)
ensure
Gem::Commands.send(:remove_const, :FooCommand)
end
diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb
index 1edb30f221..d44126d204 100644
--- a/test/rubygems/test_gem_commands_build_command.rb
+++ b/test/rubygems/test_gem_commands_build_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/build_command"
require "rubygems/package"
@@ -25,8 +26,9 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
@gem = util_spec "some_gem" do |s|
- s.license = "AGPL-3.0"
+ s.license = "AGPL-3.0-only"
s.files = ["README.md"]
+ s.required_ruby_version = "2.3.0"
end
@cmd = Gem::Commands::BuildCommand.new
@@ -41,6 +43,16 @@ class TestGemCommandsBuildCommand < Gem::TestCase
assert_includes Gem.platforms, Gem::Platform.local
end
+ def test_handle_deprecated_options
+ use_ui @ui do
+ @cmd.handle_options %w[-C ./test/dir]
+ end
+
+ assert_equal "WARNING: The \"-C\" option has been deprecated and will be removed in Rubygems 4.0. " \
+ "-C is a global flag now. Use `gem -C PATH build GEMSPEC_FILE [options]` instead\n",
+ @ui.error
+ end
+
def test_options_filename
gemspec_file = File.join(@tempdir, @gem.spec_name)
@@ -167,6 +179,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
def test_execute_strict_with_warnings
bad_gem = util_spec "some_bad_gem" do |s|
s.files = ["README.md"]
+ s.required_ruby_version = ">= 1.9.3"
end
gemspec_file = File.join(@tempdir, bad_gem.spec_name)
@@ -187,8 +200,9 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
error = @ui.error.split "\n"
- assert_equal "WARNING: licenses is empty, but is recommended. Use a license identifier from", error.shift
- assert_equal "http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.", error.shift
+ assert_equal "WARNING: licenses is empty, but is recommended. Use an license identifier from", error.shift
+ assert_equal "https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,", error.shift
+ assert_equal "or set it to nil if you don't want to specify a license.", error.shift
assert_equal "WARNING: See https://guides.rubygems.org/specification-reference/ for help", error.shift
assert_equal [], error
@@ -582,7 +596,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
def test_build_signed_gem
- pend "openssl is missing" unless Gem::HAVE_OPENSSL && !java_platform?
+ pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform?
trust_dir = Gem::Security.trust_dir
@@ -609,7 +623,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
def test_build_signed_gem_with_cert_expiration_length_days
- pend "openssl is missing" unless Gem::HAVE_OPENSSL && !java_platform?
+ pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform?
gem_path = File.join Gem.user_home, ".gem"
Dir.mkdir gem_path
@@ -653,7 +667,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
end
def test_build_auto_resign_cert
- pend "openssl is missing" unless Gem::HAVE_OPENSSL && !java_platform?
+ pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform?
gem_path = File.join Gem.user_home, ".gem"
Dir.mkdir gem_path
@@ -689,7 +703,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase
output = @ui.output.split "\n"
assert_equal "INFO: Your certificate has expired, trying to re-sign it...", output.shift
- assert_equal "INFO: Your cert: #{tmp_expired_cert_file } has been auto re-signed with the key: #{tmp_private_key_file}", output.shift
+ assert_equal "INFO: Your cert: #{tmp_expired_cert_file} has been auto re-signed with the key: #{tmp_private_key_file}", output.shift
assert_match(/INFO: Your expired cert will be located at: .+\Wgem-public_cert\.pem\.expired\.[0-9]+/, output.shift)
end
diff --git a/test/rubygems/test_gem_commands_cert_command.rb b/test/rubygems/test_gem_commands_cert_command.rb
index ffcc14ffbb..c173467935 100644
--- a/test/rubygems/test_gem_commands_cert_command.rb
+++ b/test/rubygems/test_gem_commands_cert_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/cert_command"
@@ -46,7 +47,7 @@ class TestGemCommandsCertCommand < Gem::TestCase
matches = @cmd.certificates_matching ""
- # HACK OpenSSL::X509::Certificate#== is Object#==, so do this the hard way
+ # HACK: OpenSSL::X509::Certificate#== is Object#==, so do this the hard way
match = matches.next
assert_equal ALTERNATE_CERT.to_pem, match.first.to_pem
assert_equal @trust_dir.cert_path(ALTERNATE_CERT), match.last
@@ -128,9 +129,9 @@ Added '/CN=alternate/DC=example'
output.shift
assert_equal "Please repeat the passphrase for your Private Key: ",
output.shift
- assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}",
output.shift
- assert_equal "Private Key: #{File.join @tempdir, 'gem-private_key.pem'}",
+ assert_equal "Private Key: #{File.join @tempdir, "gem-private_key.pem"}",
output.shift
assert_equal "Don't forget to move the key file to somewhere private!",
@@ -160,9 +161,9 @@ Added '/CN=alternate/DC=example'
output.shift
assert_equal "Please repeat the passphrase for your Private Key: ",
output.shift
- assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}",
output.shift
- assert_equal "Private Key: #{File.join @tempdir, 'gem-private_key.pem'}",
+ assert_equal "Private Key: #{File.join @tempdir, "gem-private_key.pem"}",
output.shift
assert_equal "Don't forget to move the key file to somewhere private!",
@@ -220,9 +221,9 @@ Added '/CN=alternate/DC=example'
output.shift
assert_equal "Please repeat the passphrase for your Private Key: ",
output.shift
- assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}",
output.shift
- assert_equal "Private Key: #{File.join @tempdir, 'gem-private_key.pem'}",
+ assert_equal "Private Key: #{File.join @tempdir, "gem-private_key.pem"}",
output.shift
assert_equal "Don't forget to move the key file to somewhere private!",
@@ -283,7 +284,7 @@ Added '/CN=alternate/DC=example'
output = @ui.output.split "\n"
- assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}",
output.shift
assert_empty output
@@ -305,7 +306,7 @@ Added '/CN=alternate/DC=example'
output = @ui.output.split "\n"
- assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}",
output.shift
assert_empty output
@@ -326,7 +327,7 @@ Added '/CN=alternate/DC=example'
output = @ui.output.split "\n"
- assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}",
output.shift
assert_empty output
@@ -475,7 +476,7 @@ Removed '/CN=alternate/DC=example'
def test_execute_sign
path = File.join @tempdir, "cert.pem"
- Gem::Security.write ALTERNATE_CERT, path, 0600
+ Gem::Security.write ALTERNATE_CERT, path, 0o600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -497,14 +498,14 @@ Removed '/CN=alternate/DC=example'
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
- mask = 0100600 & (~File.umask)
+ mask = 0o100600 & (~File.umask)
- assert_equal mask, File.stat(path).mode unless win_platform?
+ assert_equal mask, File.stat(path).mode unless Gem.win_platform?
end
def test_execute_sign_encrypted_key
path = File.join @tempdir, "cert.pem"
- Gem::Security.write ALTERNATE_CERT, path, 0600
+ Gem::Security.write ALTERNATE_CERT, path, 0o600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -526,9 +527,9 @@ Removed '/CN=alternate/DC=example'
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
- mask = 0100600 & (~File.umask)
+ mask = 0o100600 & (~File.umask)
- assert_equal mask, File.stat(path).mode unless win_platform?
+ assert_equal mask, File.stat(path).mode unless Gem.win_platform?
end
def test_execute_sign_default
@@ -541,7 +542,7 @@ Removed '/CN=alternate/DC=example'
Gem::Security.write PUBLIC_CERT, public_cert_path
path = File.join @tempdir, "cert.pem"
- Gem::Security.write ALTERNATE_CERT, path, 0600
+ Gem::Security.write ALTERNATE_CERT, path, 0o600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -558,22 +559,22 @@ Removed '/CN=alternate/DC=example'
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
- mask = 0100600 & (~File.umask)
+ mask = 0o100600 & (~File.umask)
- assert_equal mask, File.stat(path).mode unless win_platform?
+ assert_equal mask, File.stat(path).mode unless Gem.win_platform?
end
def test_execute_sign_default_encrypted_key
FileUtils.mkdir_p File.join(Gem.user_home, ".gem")
private_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem"
- Gem::Security.write ENCRYPTED_PRIVATE_KEY, private_key_path, 0600, PRIVATE_KEY_PASSPHRASE
+ Gem::Security.write ENCRYPTED_PRIVATE_KEY, private_key_path, 0o600, PRIVATE_KEY_PASSPHRASE
public_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem"
Gem::Security.write PUBLIC_CERT, public_cert_path
path = File.join @tempdir, "cert.pem"
- Gem::Security.write ALTERNATE_CERT, path, 0600
+ Gem::Security.write ALTERNATE_CERT, path, 0o600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -590,9 +591,9 @@ Removed '/CN=alternate/DC=example'
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
- mask = 0100600 & (~File.umask)
+ mask = 0o100600 & (~File.umask)
- assert_equal mask, File.stat(path).mode unless win_platform?
+ assert_equal mask, File.stat(path).mode unless Gem.win_platform?
end
def test_execute_sign_no_cert
@@ -602,7 +603,7 @@ Removed '/CN=alternate/DC=example'
Gem::Security.write PRIVATE_KEY, private_key_path
path = File.join @tempdir, "cert.pem"
- Gem::Security.write ALTERNATE_CERT, path, 0600
+ Gem::Security.write ALTERNATE_CERT, path, 0o600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -630,7 +631,7 @@ ERROR: --certificate not specified and ~/.gem/gem-public_cert.pem does not exis
Gem::Security.write PUBLIC_CERT, public_cert_path
path = File.join @tempdir, "cert.pem"
- Gem::Security.write ALTERNATE_CERT, path, 0600
+ Gem::Security.write ALTERNATE_CERT, path, 0o600
assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s
@@ -656,7 +657,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
Dir.mkdir gem_path
path = File.join @tempdir, "cert.pem"
- Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0600
+ Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0o600
assert_equal "/CN=nobody/DC=example", EXPIRED_PUBLIC_CERT.issuer.to_s
@@ -676,8 +677,9 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
expected_path = File.join(gem_path, "#{File.basename(tmp_expired_cert_file)}.expired")
+ assert_include(@ui.output, "INFO: Your certificate #{tmp_expired_cert_file} has been re-signed\n")
assert_match(
- /INFO: Your certificate #{tmp_expired_cert_file} has been re-signed\nINFO: Your expired certificate will be located at: #{expected_path}\.[0-9]+/,
+ /INFO: Your expired certificate will be located at: #{Regexp.quote(expected_path)}\.[0-9]+/,
@ui.output
)
assert_equal "", @ui.error
@@ -688,7 +690,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
Dir.mkdir gem_path
path = File.join @tempdir, "cert.pem"
- Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0600
+ Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0o600
assert_equal "/CN=nobody/DC=example", EXPIRED_PUBLIC_CERT.issuer.to_s
@@ -731,12 +733,12 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
]
assert_equal [PUBLIC_CERT.to_pem, ALTERNATE_CERT.to_pem],
- @cmd.options[:add].map {|cert| cert.to_pem }
+ @cmd.options[:add].map(&:to_pem)
assert_equal %w[nobody example], @cmd.options[:remove]
assert_equal %w[nobody@example other@example],
- @cmd.options[:build].map {|name| name.to_s }
+ @cmd.options[:build].map(&:to_s)
assert_equal ["", "example"], @cmd.options[:list]
end
@@ -777,7 +779,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
@cmd.handle_options %W[--certificate #{bad}]
end
- assert_equal "invalid argument: " +
+ assert_equal "invalid argument: " \
"--certificate #{bad}: invalid X509 certificate",
e.message
end
@@ -788,7 +790,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
@cmd.handle_options %W[--private-key #{nonexistent}]
end
- assert_equal "invalid argument: " +
+ assert_equal "invalid argument: " \
"--private-key #{nonexistent}: does not exist",
e.message
@@ -806,7 +808,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis
@cmd.handle_options %W[--private-key #{PUBLIC_KEY_FILE}]
end
- assert_equal "invalid argument: " +
+ assert_equal "invalid argument: " \
"--private-key #{PUBLIC_KEY_FILE}: private key not found",
e.message
end
diff --git a/test/rubygems/test_gem_commands_check_command.rb b/test/rubygems/test_gem_commands_check_command.rb
index 9233f7b5ce..65a3093b13 100644
--- a/test/rubygems/test_gem_commands_check_command.rb
+++ b/test/rubygems/test_gem_commands_check_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/check_command"
diff --git a/test/rubygems/test_gem_commands_cleanup_command.rb b/test/rubygems/test_gem_commands_cleanup_command.rb
index 51d59df58c..bcb8871b57 100644
--- a/test/rubygems/test_gem_commands_cleanup_command.rb
+++ b/test/rubygems/test_gem_commands_cleanup_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/cleanup_command"
require "rubygems/installer"
@@ -165,10 +166,10 @@ class TestGemCommandsCleanupCommand < Gem::TestCase
end
def test_execute_all_user_no_sudo
- FileUtils.chmod 0555, @gemhome
+ FileUtils.chmod 0o555, @gemhome
@a_1_1, = util_gem "a", "1.1"
- @a_1_1 = install_gem @a_1_1, :user_install => true # pick up user install path
+ @a_1_1 = install_gem @a_1_1, user_install: true # pick up user install path
Gem::Specification.dirs = [Gem.dir, Gem.user_dir]
@@ -182,8 +183,8 @@ class TestGemCommandsCleanupCommand < Gem::TestCase
assert_path_exist @a_1.gem_dir
assert_path_exist @a_1_1.gem_dir
ensure
- FileUtils.chmod 0755, @gemhome
- end unless win_platform? || Process.uid.zero?
+ FileUtils.chmod 0o755, @gemhome
+ end unless Gem.win_platform? || Process.uid.zero?
def test_execute_dry_run
@cmd.options[:args] = %w[a]
@@ -230,7 +231,7 @@ class TestGemCommandsCleanupCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{^Skipped default gems: b-2}, @ui.output
+ assert_match(/^Skipped default gems: b-2/, @ui.output)
assert_empty @ui.error
end
@@ -242,11 +243,11 @@ class TestGemCommandsCleanupCommand < Gem::TestCase
e_1, = util_gem "e", "1"
e_2, = util_gem "e", "2"
- c_1 = install_gem c_1, :user_install => true # pick up user install path
+ c_1 = install_gem c_1, user_install: true # pick up user install path
c_2 = install_gem c_2
d_1 = install_gem d_1
- d_2 = install_gem d_2, :user_install => true # pick up user install path
+ d_2 = install_gem d_2, user_install: true # pick up user install path
e_1 = install_gem e_1
e_2 = install_gem e_2
@@ -269,8 +270,8 @@ class TestGemCommandsCleanupCommand < Gem::TestCase
d_1, = util_gem "d", "1.0"
d_2, = util_gem "d", "1.1"
- c_1 = install_gem c_1, :user_install => true # pick up user install path
- c_2 = install_gem c_2, :user_install => true # pick up user install path
+ c_1 = install_gem c_1, user_install: true # pick up user install path
+ c_2 = install_gem c_2, user_install: true # pick up user install path
d_1 = install_gem d_1
d_2 = install_gem d_2
diff --git a/test/rubygems/test_gem_commands_contents_command.rb b/test/rubygems/test_gem_commands_contents_command.rb
index 1b9da8a92e..d8e6ba3dec 100644
--- a/test/rubygems/test_gem_commands_contents_command.rb
+++ b/test/rubygems/test_gem_commands_contents_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/contents_command"
@@ -27,7 +28,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
end
assert_match %r{lib/foo\.rb}, @ui.output
- assert_match %r{Rakefile}, @ui.output
+ assert_match(/Rakefile/, @ui.output)
assert_equal "", @ui.error
end
@@ -43,7 +44,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
assert_match %r{lib/foo\.rb}, @ui.output
assert_match %r{lib/bar\.rb}, @ui.output
- assert_match %r{Rakefile}, @ui.output
+ assert_match(/Rakefile/, @ui.output)
assert_equal "", @ui.error
end
@@ -56,8 +57,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase
end
end
- assert_match %r{Unable to find gem 'foo' in default gem paths}, @ui.output
- assert_match %r{Directories searched:}, @ui.output
+ assert_match(/Unable to find gem 'foo' in default gem paths/, @ui.output)
+ assert_match(/Directories searched:/, @ui.output)
assert_equal "", @ui.error
end
@@ -71,7 +72,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
end
assert_match %r{lib/foo\.rb}, @ui.output
- assert_match %r{Rakefile}, @ui.output
+ assert_match(/Rakefile/, @ui.output)
assert_equal "", @ui.error
end
@@ -86,7 +87,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
end
assert_match %r{lib/foo\.rb}, @ui.output
- refute_match %r{Rakefile}, @ui.output
+ refute_match(/Rakefile/, @ui.output)
assert_equal "", @ui.error
end
@@ -147,7 +148,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase
assert_match %r{lib/foo\.rb}, @ui.output
assert_match %r{lib/bar\.rb}, @ui.output
- assert_match %r{Rakefile}, @ui.output
+ assert_match(/Rakefile/, @ui.output)
assert_equal "", @ui.error
end
diff --git a/test/rubygems/test_gem_commands_dependency_command.rb b/test/rubygems/test_gem_commands_dependency_command.rb
index d9571275cb..48fe2f8e8d 100644
--- a/test/rubygems/test_gem_commands_dependency_command.rb
+++ b/test/rubygems/test_gem_commands_dependency_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/dependency_command"
diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb
index 91ed774cb6..48252d84d4 100644
--- a/test/rubygems/test_gem_commands_environment_command.rb
+++ b/test/rubygems/test_gem_commands_environment_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/environment_command"
@@ -11,7 +12,8 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase
def test_execute
orig_sources = Gem.sources.dup
- orig_path, ENV["PATH"] = ENV["PATH"], %w[/usr/local/bin /usr/bin /bin].join(File::PATH_SEPARATOR)
+ orig_path = ENV["PATH"]
+ ENV["PATH"] = %w[/usr/local/bin /usr/bin /bin].join(File::PATH_SEPARATOR)
Gem.sources.replace %w[http://gems.example.com]
Gem.configuration["gemcutter_key"] = "blah"
@@ -21,34 +23,33 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{RUBYGEMS VERSION: (\d\.)+\d}, @ui.output
- assert_match %r{RUBY VERSION: \d+\.\d+\.\d+ \(.*\) \[.*\]}, @ui.output
- assert_match %r{INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}},
- @ui.output
- assert_match %r{USER INSTALLATION DIRECTORY: #{Regexp.escape Gem.user_dir}},
- @ui.output
- assert_match %r{RUBYGEMS PREFIX: }, @ui.output
- assert_match %r{RUBY EXECUTABLE:.*#{RbConfig::CONFIG['ruby_install_name']}},
- @ui.output
- assert_match %r{GIT EXECUTABLE: #{@cmd.send(:git_path)}}, @ui.output
- assert_match %r{SYSTEM CONFIGURATION DIRECTORY:}, @ui.output
- assert_match %r{EXECUTABLE DIRECTORY:}, @ui.output
- assert_match %r{RUBYGEMS PLATFORMS:}, @ui.output
- assert_match %r{- #{Gem::Platform.local}}, @ui.output
- assert_match %r{GEM PATHS:}, @ui.output
- assert_match %r{- #{Regexp.escape @gemhome}}, @ui.output
- assert_match %r{GEM CONFIGURATION:}, @ui.output
- assert_match %r{"gemcutter_key" => "\*\*\*\*"}, @ui.output
- assert_match %r{:verbose => }, @ui.output
- assert_match %r{REMOTE SOURCES:}, @ui.output
-
- assert_match %r{- SHELL PATH:}, @ui.output
+ assert_match(/RUBYGEMS VERSION: (\d\.)+\d/, @ui.output)
+ assert_match(/RUBY VERSION: \d+\.\d+\.\d+ \(.*\) \[.*\]/, @ui.output)
+ assert_match(/INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}/,
+ @ui.output)
+ assert_match(/USER INSTALLATION DIRECTORY: #{Regexp.escape Gem.user_dir}/,
+ @ui.output)
+ assert_match(/RUBYGEMS PREFIX: /, @ui.output)
+ assert_match(/RUBY EXECUTABLE:.*#{RbConfig::CONFIG["ruby_install_name"]}/,
+ @ui.output)
+ assert_match(/GIT EXECUTABLE: #{@cmd.send(:git_path)}/, @ui.output)
+ assert_match(/SYSTEM CONFIGURATION DIRECTORY:/, @ui.output)
+ assert_match(/EXECUTABLE DIRECTORY:/, @ui.output)
+ assert_match(/RUBYGEMS PLATFORMS:/, @ui.output)
+ assert_match(/- #{Gem::Platform.local}/, @ui.output)
+ assert_match(/GEM PATHS:/, @ui.output)
+ assert_match(/- #{Regexp.escape @gemhome}/, @ui.output)
+ assert_match(/GEM CONFIGURATION:/, @ui.output)
+ assert_match(/"gemcutter_key" => "\*\*\*\*"/, @ui.output)
+ assert_match(/:verbose => /, @ui.output)
+ assert_match(/REMOTE SOURCES:/, @ui.output)
+
+ assert_match(/- SHELL PATH:/, @ui.output)
assert_match %r{- /usr/local/bin$}, @ui.output
assert_match %r{- /usr/bin$}, @ui.output
assert_match %r{- /bin$}, @ui.output
assert_empty @ui.error
-
ensure
Gem.sources.replace orig_sources
ENV["PATH"] = orig_path
@@ -125,7 +126,6 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase
assert_equal "http://gems.example.com\n", @ui.output
assert_equal "", @ui.error
-
ensure
Gem.sources.replace orig_sources
end
diff --git a/test/rubygems/test_gem_commands_exec_command.rb b/test/rubygems/test_gem_commands_exec_command.rb
new file mode 100644
index 0000000000..e52fe247a2
--- /dev/null
+++ b/test/rubygems/test_gem_commands_exec_command.rb
@@ -0,0 +1,859 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems/commands/exec_command"
+
+class TestGemCommandsExecCommand < Gem::TestCase
+ def setup
+ @orig_args = Gem::Command.build_args
+ @orig_specific_extra_args = Gem::Command.specific_extra_args_hash.dup
+ @orig_extra_args = Gem::Command.extra_args.dup
+
+ super
+ common_installer_setup
+
+ @cmd = Gem::Commands::ExecCommand.new
+
+ @gem_home = Gem.dir
+ @gem_path = Gem.path
+ @test_arch = RbConfig::CONFIG["arch"]
+
+ @installed_specs = []
+ Gem.post_install {|installer| @installed_specs << installer.spec }
+ end
+
+ def teardown
+ super
+
+ common_installer_teardown
+
+ Gem::Command.build_args = @orig_args
+ Gem::Command.specific_extra_args_hash = @orig_specific_extra_args
+ Gem::Command.extra_args = @orig_extra_args
+ Gem.configuration = nil
+ end
+
+ def invoke(*args)
+ @ui.outs.truncate(0)
+ @ui.outs.rewind
+ @ui.errs.truncate(0)
+ @ui.errs.rewind
+ @installed_specs.clear
+
+ @cmd.invoke(*args)
+ ensure
+ Gem::Specification.unresolved_deps.clear
+ Gem.loaded_specs.clear
+ Gem.instance_variable_set(:@activated_gem_paths, 0)
+ Gem.clear_default_specs
+ Gem.use_paths(@gem_home, @gem_path)
+ Gem.refresh
+ end
+
+ def test_error_with_no_arguments
+ e = assert_raise Gem::CommandLineError do
+ @cmd.invoke
+ end
+ assert_equal "Please specify an executable to run (e.g. gem exec COMMAND)",
+ e.message
+ end
+
+ def test_error_with_no_executable
+ e = assert_raise Gem::CommandLineError do
+ @cmd.invoke "--verbose", "--gem", "GEM", "--version", "< 10", "--conservative"
+ end
+ assert_equal "Please specify an executable to run (e.g. gem exec COMMAND)",
+ e.message
+ end
+
+ def test_full_option_parsing
+ @cmd.when_invoked do |options|
+ assert_equal options, {
+ args: ["install", "--no-color", "--help", "--verbose"],
+ executable: "pod",
+ explicit_prerelease: false,
+ gem_name: "cocoapods",
+ prerelease: false,
+ version: Gem::Requirement.new(["> 1", "< 1.3"]),
+ build_args: nil,
+ }
+ end
+ @cmd.invoke "--gem", "cocoapods", "-v", "> 1", "--version", "< 1.3", "--verbose", "--", "pod", "install", "--no-color", "--help", "--verbose"
+ end
+
+ def test_single_arg_parsing
+ @cmd.when_invoked do |options|
+ assert_equal options, {
+ args: [],
+ executable: "rails",
+ gem_name: "rails",
+ version: Gem::Requirement.new([">= 0"]),
+ build_args: nil,
+ }
+ end
+ @cmd.invoke "rails"
+ end
+
+ def test_single_arg_parsing_with_version
+ @cmd.when_invoked do |options|
+ assert_equal options, {
+ args: [],
+ executable: "rails",
+ gem_name: "rails",
+ version: Gem::Requirement.new(["= 7.1"]),
+ build_args: nil,
+ }
+ end
+ @cmd.invoke "rails:7.1"
+ end
+
+ def test_gem_without_executable
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ e = assert_raise Gem::MockGemUi::TermError, @ui.error do
+ @cmd.invoke "a:2"
+ end
+ assert_equal 1, e.exit_code
+ assert_equal "ERROR: Failed to load executable `a`, are you sure the gem `a` contains it?\n", @ui.error
+ end
+ end
+
+ def test_gem_with_executable
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump}"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ @cmd.invoke "a:2"
+ assert_equal "a-2\n", @ui.output
+ end
+ end
+
+ def test_gem_with_platforms
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump}"
+ end
+ end
+
+ fetcher.download "a", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb]
+ s.platform = "x86_64-darwin"
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump}"
+ end
+ end
+ end
+
+ use_ui @ui do
+ invoke "a:2"
+ assert_equal "a-2\n", @ui.output
+ end
+
+ use_ui @ui do
+ util_set_arch "x86_64-darwin-18"
+ invoke "a:2"
+ assert_equal "a-2-x86_64-darwin\n", @ui.output
+ end
+ end
+
+ def test_gem_with_platform_dependencies
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb]
+ s.add_runtime_dependency "with_platform"
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << 'require "with_platform"' << "\n"
+ f << 'Gem.ui.say Gem.loaded_specs.each_value.map(&:original_name).sort.join("\n")'
+ end
+ end
+
+ fetcher.download "with_platform", 2 do |s|
+ s.files = %w[lib/with_platform.rb]
+ s.platform = Gem::Platform.local
+ end
+
+ fetcher.download "with_platform", 2 do |s|
+ s.files = %w[lib/with_platform.rb]
+ end
+ end
+
+ use_ui @ui do
+ util_set_arch "unknown-unknown"
+ invoke "a"
+ assert_equal "a-2\nwith_platform-2\n", @ui.output
+ end
+
+ use_ui @ui do
+ util_set_arch @test_arch
+ invoke "a"
+ assert_empty @ui.error
+ assert_equal "a-2\nwith_platform-2-#{Gem::Platform.local}\n", @ui.output
+ end
+ end
+
+ def test_gem_with_platform_and_platform_dependencies
+ pend "extensions don't quite work on jruby" if Gem.java_platform?
+ pend "terminates on mswin" if vc_windows? && ruby_repo?
+
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb]
+ s.add_runtime_dependency "with_platform"
+ s.platform = Gem::Platform.local.to_s
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << 'require "with_platform"' << "\n"
+ f << 'Gem.ui.say Gem.loaded_specs.each_value.map(&:original_name).sort.join("\n")'
+ end
+ end
+
+ fetcher.download "a", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb extconf.rb]
+ s.add_runtime_dependency "with_platform"
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << 'require "with_platform"' << "\n"
+ f << 'Gem.ui.say Gem.loaded_specs.each_value.map(&:original_name).sort.join("\n")'
+ end
+
+ s.extensions = %w[extconf.rb]
+ write_file File.join(*%W[gems #{s.original_name} extconf.rb]) do |f|
+ f.write <<-RUBY
+ gem('with_platform', '~> 2.0')
+ require 'with_platform'
+ gem 'sometimes_used'
+ require 'sometimes_used'
+ require "mkmf"
+ create_makefile("#{s.name}")
+ RUBY
+ end
+ end
+
+ fetcher.download "with_platform", 2 do |s|
+ s.files = %w[lib/with_platform.rb]
+ s.platform = Gem::Platform.local.to_s
+ end
+
+ fetcher.download "with_platform", 2 do |s|
+ s.files = %w[lib/with_platform.rb]
+ s.add_runtime_dependency "sometimes_used"
+ end
+
+ fetcher.download "sometimes_used", 2 do |s|
+ s.files = %w[lib/sometimes_used.rb]
+ end
+ end
+
+ use_ui @ui do
+ util_set_arch "unknown-unknown"
+ invoke "a"
+ assert_empty @ui.error
+ assert_equal "Building native extensions. This could take a while...\na-2\nsometimes_used-2\nwith_platform-2\n", @ui.output
+ end
+
+ use_ui @ui do
+ util_set_arch @test_arch
+ invoke "a"
+ assert_empty @ui.error
+ assert_equal "a-2-#{Gem::Platform.local}\nwith_platform-2-#{Gem::Platform.local}\n", @ui.output
+ end
+ end
+
+ def test_gem_with_other_executable_name
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump}"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ @cmd.invoke "a:2"
+ assert_equal "a-2\n", @ui.output
+ end
+ end
+
+ def test_gem_with_executable_error
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "raise #{s.original_name.dump}"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ e = assert_raise RuntimeError do
+ @cmd.invoke "a:2"
+ end
+ assert_equal "a-2", e.message
+ assert_empty @ui.error
+ end
+ end
+
+ def test_gem_with_multiple_executables_one_match
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2 do |s|
+ s.executables = %w[foo a]
+ s.files = %w[bin/foo bin/a lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ @cmd.invoke "a:2"
+ assert_equal "a-2 a\n", @ui.output
+ end
+ end
+
+ def test_gem_with_multiple_executables_no_match
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2 do |s|
+ s.executables = %w[foo bar]
+ s.files = %w[bin/foo bin/bar lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+
+ write_file File.join(*%W[gems #{s.original_name} bin bar]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ @cmd.invoke "a:2"
+ assert_equal "a-2 foo\n", @ui.output
+ end
+ end
+
+ def test_gem_dependency_contains_executable
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2 do |s|
+ s.executables = %w[]
+ s.files = %w[lib/a.rb]
+
+ s.add_dependency "b"
+ end
+
+ fetcher.gem "b", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/b.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ @cmd.invoke "a:2"
+ assert_equal "b-2 a\n", @ui.output
+ end
+ end
+
+ def test_gem_dependency_contains_other_executable
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2 do |s|
+ s.executables = %w[]
+ s.files = %w[lib/a.rb]
+
+ s.add_dependency "b"
+ end
+
+ fetcher.gem "b", 2 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/b.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ e = assert_raise Gem::MockGemUi::TermError do
+ @cmd.invoke "a:2"
+ end
+ assert_equal 1, e.exit_code
+ assert_equal <<~ERR, @ui.error
+ ERROR: Failed to load executable `a`, are you sure the gem `a` contains it?
+ ERR
+ end
+ end
+
+ def test_other_gem_contains_executable
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2 do |s|
+ s.executables = %w[]
+ s.files = %w[lib/a.rb]
+ end
+
+ fetcher.gem "b", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/b.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ e = assert_raise Gem::MockGemUi::TermError do
+ @cmd.invoke "a:2"
+ end
+ assert_equal 1, e.exit_code
+ assert_equal <<~ERR, @ui.error
+ ERROR: Failed to load executable `a`, are you sure the gem `a` contains it?
+ ERR
+ end
+ end
+
+ def test_missing_gem
+ spec_fetcher do |fetcher|
+ end
+
+ use_ui @ui do
+ e = assert_raise Gem::MockGemUi::TermError do
+ @cmd.invoke "a"
+ end
+ assert_equal 2, e.exit_code
+ assert_equal <<~ERR, @ui.error
+ ERROR: Could not find a valid gem 'a' (>= 0) in any repository
+ ERR
+ end
+ end
+
+ def test_version_mismatch
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 1
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ e = assert_raise Gem::MockGemUi::TermError do
+ @cmd.invoke "a:2"
+ end
+ assert_equal 2, e.exit_code
+ assert_equal <<~ERR, @ui.error
+ ERROR: Could not find a valid gem 'a' (= 2) in any repository
+ ERROR: Possible alternatives: a
+ ERR
+ end
+ end
+
+ def test_pre_argument
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 1 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ fetcher.gem "a", "1.1.a" do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ @cmd.invoke "--pre", "a"
+ assert_equal "a-1.1.a foo\n", @ui.output
+ end
+ end
+
+ def test_pre_version_option
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 1 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ fetcher.download "a", "1.1.a" do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ use_ui @ui do
+ @cmd.invoke "-v", ">= 0.a", "a"
+ assert_equal "a-1.1.a foo\n", @ui.output
+ end
+ end
+
+ def test_conservative_missing_gem
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 1 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ util_clear_gems
+
+ use_ui @ui do
+ e = assert_raise Gem::MockGemUi::TermError do
+ @cmd.invoke "--verbose", "--conservative", "a:2"
+ end
+ assert_equal 2, e.exit_code
+ assert_include @ui.output, "a (= 2) not available locally"
+ assert_equal <<~ERROR, @ui.error
+ ERROR: Could not find a valid gem 'a' (= 2) in any repository
+ ERROR: Possible alternatives: a
+ ERROR
+ end
+ end
+
+ def test_conservative
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 1 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ use_ui @ui do
+ invoke "--verbose", "--conservative", "a"
+ assert_include @ui.output, "a (>= 0) not available locally"
+ assert_include @ui.output, "a-1 foo"
+ assert_equal %w[a-1], @installed_specs.map(&:original_name)
+ end
+
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 1 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+
+ fetcher.download "a", 2 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ use_ui @ui do
+ invoke "--verbose", "--conservative", "a"
+ assert_not_include @ui.output, "a (>= 0) not available locally"
+ assert_include @ui.output, "a-1 foo"
+ assert_empty @installed_specs.map(&:original_name)
+ end
+ end
+
+ def test_uses_newest_version
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 1 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ use_ui @ui do
+ invoke "a"
+ assert_include @ui.output, "a-1 foo"
+ end
+
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 1 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+
+ fetcher.download "a", 2 do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ use_ui @ui do
+ invoke "--verbose", "a:2"
+ refute_predicate @ui, :terminated?
+ assert_empty @ui.error
+ assert_include @ui.output, "a-2 foo"
+ assert_equal %w[a-2], @installed_specs.map(&:original_name)
+ end
+ end
+
+ def test_uses_newest_version_of_dependency
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 1 do |s|
+ s.executables = %w[]
+ s.files = %w[lib/a.rb]
+ s.add_runtime_dependency "b"
+ end
+
+ fetcher.gem "b", 1 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+
+ fetcher.download "b", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb]
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ use_ui @ui do
+ invoke "a"
+ assert_include @ui.output, "b-2 a"
+ assert_equal %w[b-2], @installed_specs.map(&:original_name)
+ end
+ end
+
+ def test_gem_exec_gem_uninstall
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 2 do |s|
+ s.executables = %w[a]
+ s.files = %w[bin/a lib/a.rb]
+ s.add_runtime_dependency "b"
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump}"
+ end
+ end
+
+ fetcher.download "b", 2 do |s|
+ s.files = %w[lib/b.rb]
+ end
+ end
+
+ use_ui @ui do
+ invoke "a:2"
+ assert_equal "a-2\n", @ui.output
+
+ invoke "gem", "list", "--local"
+ assert_includes @ui.output, "a (2)\n"
+ assert_includes @ui.output, "b (2)\n"
+
+ begin
+ invoke "gem", "uninstall", "--verbose", "-x", "a"
+ rescue StandardError
+ nil
+ end
+
+ assert_empty @ui.error
+ refute_includes @ui.output, "running gem exec with"
+ assert_includes @ui.output, "Successfully uninstalled a-2\n"
+
+ invoke "--verbose", "gem", "uninstall", "b"
+ assert_includes @ui.output, "Successfully uninstalled b-2\n"
+
+ invoke "gem", "list", "--local"
+ assert_empty @ui.error
+ assert_match(/\A\s*\** LOCAL GEMS \**\s*\z/m, @ui.output)
+
+ invoke "gem", "env", "GEM_HOME"
+ assert_equal "#{@gem_home}/gem_exec\n", @ui.output
+ end
+ end
+
+ def test_only_prerelease_available
+ spec_fetcher do |fetcher|
+ fetcher.download "a", "1.a" do |s|
+ s.executables = %w[a]
+ s.files = %w[lib/a.rb bin/a]
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ use_ui @ui do
+ assert_raise Gem::MockGemUi::TermError do
+ invoke "a"
+ end
+ assert_equal "ERROR: Could not find a valid gem 'a' (>= 0) in any repository\n" \
+ "ERROR: Possible alternatives: a\n", @ui.error
+ assert_empty @ui.output
+ assert_empty @installed_specs
+ end
+
+ use_ui @ui do
+ invoke "a:1.a"
+ assert_empty @ui.error
+ assert_equal "a-1.a a\n", @ui.output
+ assert_equal %w[a-1.a], @installed_specs.map(&:full_name)
+ end
+
+ FileUtils.rm_rf Gem.dir
+
+ use_ui @ui do
+ invoke "--version", ">= 1.a", "a"
+ assert_empty @ui.error
+ assert_equal "a-1.a a\n", @ui.output
+ assert_equal %w[a-1.a], @installed_specs.map(&:full_name)
+ end
+
+ FileUtils.rm_rf Gem.dir
+
+ use_ui @ui do
+ invoke "--pre", "a"
+ assert_empty @ui.error
+ assert_equal "a-1.a a\n", @ui.output
+ assert_equal %w[a-1.a], @installed_specs.map(&:full_name)
+ end
+ end
+
+ def test_newer_prerelease_available
+ spec_fetcher do |fetcher|
+ fetcher.download "a", "1" do |s|
+ s.executables = %w[a]
+ s.files = %w[lib/a.rb bin/a]
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+
+ fetcher.download "a", "1.1.a" do |s|
+ s.executables = %w[a]
+ s.files = %w[lib/a.rb bin/a]
+
+ write_file File.join(*%W[gems #{s.original_name} bin a]) do |f|
+ f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)"
+ end
+ end
+ end
+
+ use_ui @ui do
+ invoke "a"
+ assert_empty @ui.error
+ assert_equal "a-1 a\n", @ui.output
+ assert_equal %w[a-1], @installed_specs.map(&:full_name)
+ end
+
+ FileUtils.rm_rf Gem.dir
+
+ use_ui @ui do
+ invoke "a:1.1.a"
+ assert_empty @ui.error
+ assert_equal "a-1.1.a a\n", @ui.output
+ assert_equal %w[a-1.1.a], @installed_specs.map(&:full_name)
+ end
+
+ FileUtils.rm_rf Gem.dir
+
+ use_ui @ui do
+ invoke "--version", ">= 1.a", "a"
+ assert_empty @ui.error
+ assert_equal "a-1.1.a a\n", @ui.output
+ assert_equal %w[a-1.1.a], @installed_specs.map(&:full_name)
+ end
+
+ FileUtils.rm_rf Gem.dir
+
+ use_ui @ui do
+ invoke "--pre", "a"
+ assert_empty @ui.error
+ assert_equal "a-1.1.a a\n", @ui.output
+ assert_equal %w[a-1.1.a], @installed_specs.map(&:full_name)
+ end
+ end
+end
diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb
index f2a4464c7d..e8710d3cd1 100644
--- a/test/rubygems/test_gem_commands_fetch_command.rb
+++ b/test/rubygems/test_gem_commands_fetch_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/package"
require "rubygems/security"
diff --git a/test/rubygems/test_gem_commands_generate_index_command.rb b/test/rubygems/test_gem_commands_generate_index_command.rb
deleted file mode 100644
index c0e18119ed..0000000000
--- a/test/rubygems/test_gem_commands_generate_index_command.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-# frozen_string_literal: true
-require_relative "helper"
-require "rubygems/indexer"
-require "rubygems/commands/generate_index_command"
-
-class TestGemCommandsGenerateIndexCommand < Gem::TestCase
- def setup
- super
-
- @cmd = Gem::Commands::GenerateIndexCommand.new
- @cmd.options[:directory] = @gemhome
- end
-
- def test_execute
- use_ui @ui do
- @cmd.execute
- end
-
- specs = File.join @gemhome, "specs.4.8.gz"
-
- assert File.exist?(specs), specs
- end
-
- def test_execute_no_modern
- @cmd.options[:modern] = false
-
- use_ui @ui do
- @cmd.execute
- end
-
- specs = File.join @gemhome, "specs.4.8.gz"
-
- assert File.exist?(specs), specs
- end
-
- def test_handle_options_directory
- return if win_platform?
- refute_equal "/nonexistent", @cmd.options[:directory]
-
- @cmd.handle_options %w[--directory /nonexistent]
-
- assert_equal "/nonexistent", @cmd.options[:directory]
- end
-
- def test_handle_options_directory_windows
- return unless win_platform?
-
- refute_equal "/nonexistent", @cmd.options[:directory]
-
- @cmd.handle_options %w[--directory C:/nonexistent]
-
- assert_equal "C:/nonexistent", @cmd.options[:directory]
- end
-
- def test_handle_options_update
- @cmd.handle_options %w[--update]
-
- assert @cmd.options[:update]
- end
-
- def test_handle_options_modern
- use_ui @ui do
- @cmd.handle_options %w[--modern]
- end
-
- assert_equal \
- "WARNING: The \"--modern\" option has been deprecated and will be removed in Rubygems 4.0. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated, so this option is not needed.\n",
- @ui.error
- end
-
- def test_handle_options_no_modern
- use_ui @ui do
- @cmd.handle_options %w[--no-modern]
- end
-
- assert_equal \
- "WARNING: The \"--no-modern\" option has been deprecated and will be removed in Rubygems 4.0. The `--no-modern` option is currently ignored. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated.\n",
- @ui.error
- end
-end
diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb
index b84bc4f7ef..359da0a6d0 100644
--- a/test/rubygems/test_gem_commands_help_command.rb
+++ b/test/rubygems/test_gem_commands_help_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "rubygems"
require_relative "helper"
require "rubygems/commands/help_command"
@@ -55,7 +56,7 @@ class TestGemCommandsHelpCommand < Gem::TestCase
if Gem::HAVE_OPENSSL
assert_empty err
- refute_match %r{No command found for }, out
+ refute_match(/No command found for /, out)
end
end
end
@@ -63,7 +64,7 @@ class TestGemCommandsHelpCommand < Gem::TestCase
def test_gem_help_commands_omits_deprecated_commands
mgr = Gem::CommandManager.new
- util_gem "commands" do |out, err|
+ util_gem "commands" do |out, _err|
deprecated_commands = mgr.command_names.select {|cmd| mgr[cmd].deprecated? }
deprecated_commands.each do |cmd|
refute_match(/\A\s+#{cmd}\s+\S+\z/, out)
diff --git a/test/rubygems/test_gem_commands_info_command.rb b/test/rubygems/test_gem_commands_info_command.rb
index b18b405da6..83e4c8a896 100644
--- a/test/rubygems/test_gem_commands_info_command.rb
+++ b/test/rubygems/test_gem_commands_info_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/info_command"
@@ -32,12 +33,38 @@ class TestGemCommandsInfoCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{#{@gem.name} \(#{@gem.version}\)\n}, @ui.output
- assert_match %r{Authors: #{@gem.authors.join(', ')}\n}, @ui.output
- assert_match %r{Homepage: #{@gem.homepage}\n}, @ui.output
- assert_match %r{License: #{@gem.license}\n}, @ui.output
- assert_match %r{Installed at: #{@gem.base_dir}\n}, @ui.output
- assert_match %r{#{@gem.summary}\n}, @ui.output
+ assert_include(@ui.output, "#{@gem.name} (#{@gem.version})\n")
+ assert_include(@ui.output, "Authors: #{@gem.authors.join(", ")}\n")
+ assert_include(@ui.output, "Homepage: #{@gem.homepage}\n")
+ assert_include(@ui.output, "License: #{@gem.license}\n")
+ assert_include(@ui.output, "Installed at: #{@gem.base_dir}\n")
+ assert_include(@ui.output, "#{@gem.summary}\n")
assert_match "", @ui.error
end
+
+ def test_execute_with_version_flag
+ spec_fetcher do |fetcher|
+ fetcher.spec "coolgem", "1.0"
+ fetcher.spec "coolgem", "2.0"
+ end
+
+ @cmd.handle_options %w[coolgem --remote --version 1.0]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+coolgem (1.0)
+ Author: A User
+ Homepage: http://example.com
+
+ this is a summary
+ EOF
+
+ assert_equal expected, @ui.output
+ end
end
diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb
index 7a58bcd7cb..5b09512ac4 100644
--- a/test/rubygems/test_gem_commands_install_command.rb
+++ b/test/rubygems/test_gem_commands_install_command.rb
@@ -1,11 +1,14 @@
# frozen_string_literal: true
+
require_relative "helper"
+require_relative "test_gem_update_suggestion"
require "rubygems/commands/install_command"
require "rubygems/request_set"
require "rubygems/rdoc"
class TestGemCommandsInstallCommand < Gem::TestCase
def setup
+ @orig_args = Gem::Command.build_args
super
common_installer_setup
@@ -13,7 +16,6 @@ class TestGemCommandsInstallCommand < Gem::TestCase
@cmd.options[:document] = []
@gemdeps = "tmp_install_gemdeps"
- @orig_args = Gem::Command.build_args
common_installer_setup
end
@@ -42,7 +44,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
end
def test_execute_explicit_version_includes_prerelease
@@ -64,7 +66,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
end
- assert_equal %w[a-2.a], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2.a], @cmd.installed_specs.map(&:full_name)
end
def test_execute_local
@@ -90,7 +92,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
assert_match "1 gem installed", @ui.output
end
@@ -181,40 +183,35 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a
end
end
- assert_equal %w[a-2 b-2.a c-3], @cmd.installed_specs.map {|spec| spec.full_name }.sort
+ assert_equal %w[a-2 b-2.a c-3], @cmd.installed_specs.map(&:full_name).sort
assert_match "3 gems installed", @ui.output
end
def test_execute_no_user_install
- pend "skipped on MS Windows (chmod has no effect)" if win_platform?
+ pend "skipped on MS Windows (chmod has no effect)" if Gem.win_platform?
pend "skipped in root privilege" if Process.uid.zero?
- specs = spec_fetcher do |fetcher|
- fetcher.gem "a", 2
+ spec_fetcher do |fetcher|
+ fetcher.download "a", 2
end
@cmd.options[:user_install] = false
- FileUtils.mv specs["a-2"].cache_file, @tempdir
-
@cmd.options[:args] = %w[a]
use_ui @ui do
- orig_dir = Dir.pwd
- begin
- FileUtils.chmod 0755, @userhome
- FileUtils.chmod 0555, @gemhome
+ FileUtils.chmod 0o755, @userhome
+ FileUtils.chmod 0o555, @gemhome
- Dir.chdir @tempdir
- assert_raise Gem::FilePermissionError do
- @cmd.execute
- end
- ensure
- Dir.chdir orig_dir
- FileUtils.chmod 0755, @gemhome
+ assert_raise Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
end
+ ensure
+ FileUtils.chmod 0o755, @gemhome
end
+
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name).sort
end
def test_execute_local_missing
@@ -231,7 +228,7 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a
assert_equal 2, e.exit_code
end
- # HACK no repository was checked
+ # HACK: no repository was checked
assert_match(/ould not find a valid gem 'no_such_gem'/, @ui.error)
end
@@ -250,7 +247,7 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a
assert_equal 2, e.exit_code
end
- # HACK no repository was checked
+ # HACK: no repository was checked
assert_match(/ould not find a valid gem 'no_such_gem'/, @ui.error)
end
@@ -434,21 +431,6 @@ ERROR: Possible alternatives: non_existent_with_hint
assert_equal expected, output
end
- def test_execute_conflicting_install_options
- @cmd.options[:user_install] = true
- @cmd.options[:install_dir] = "whatever"
-
- use_ui @ui do
- assert_raise Gem::MockGemUi::TermError do
- @cmd.execute
- end
- end
-
- expected = "ERROR: Use --install-dir or --user-install but not both\n"
-
- assert_equal expected, @ui.error
- end
-
def test_execute_prerelease_skipped_when_no_flag_set
spec_fetcher do |fetcher|
fetcher.gem "a", 1
@@ -464,7 +446,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name)
end
def test_execute_prerelease_wins_over_previous_ver
@@ -482,7 +464,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2.a], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2.a], @cmd.installed_specs.map(&:full_name)
end
def test_execute_with_version_specified_by_colon
@@ -499,7 +481,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name)
end
def test_execute_prerelease_skipped_when_non_pre_available
@@ -517,7 +499,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
end
def test_execute_required_ruby_version
@@ -547,7 +529,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
end
def test_execute_required_ruby_version_upper_bound
@@ -568,7 +550,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2.0], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2.0], @cmd.installed_specs.map(&:full_name)
end
def test_execute_required_ruby_version_specific_not_met
@@ -606,7 +588,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1.0], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-1.0], @cmd.installed_specs.map(&:full_name)
end
def test_execute_required_ruby_version_specific_prerelease_not_met
@@ -773,7 +755,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
assert_match "1 gem installed", @ui.output
end
@@ -793,7 +775,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
assert_match "1 gem installed", @ui.output
end
@@ -813,7 +795,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name)
assert_match "1 gem installed", @ui.output
a1_gemspec = File.join(@gemhome, "specifications", "a-1.gemspec")
@@ -867,7 +849,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name)
assert_match "1 gem installed", @ui.output
@@ -901,7 +883,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2 b-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2 b-2], @cmd.installed_specs.map(&:full_name)
assert_match "2 gems installed", @ui.output
end
@@ -943,7 +925,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-1 b-1], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-1 b-1], @cmd.installed_specs.map(&:full_name)
end
def test_execute_conservative
@@ -969,7 +951,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[b-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[b-2], @cmd.installed_specs.map(&:full_name)
assert_equal "", @ui.error
assert_match "1 gem installed", @ui.output
@@ -991,7 +973,7 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.install_gem "a", ">= 0"
- assert_equal %w[a-2], @cmd.installed_specs.map {|s| s.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
assert done_installing, "documentation was not generated"
end
@@ -1005,7 +987,7 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.install_gem "a", ">= 0"
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
end
def test_install_gem_ignore_dependencies_remote_platform_local
@@ -1022,7 +1004,7 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.install_gem "a", ">= 0"
- assert_equal %W[a-3-#{local}], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %W[a-3-#{local}], @cmd.installed_specs.map(&:full_name)
end
def test_install_gem_ignore_dependencies_specific_file
@@ -1036,7 +1018,7 @@ ERROR: Possible alternatives: non_existent_with_hint
@cmd.install_gem File.join(@tempdir, spec.file_name), nil
- assert_equal %w[a-2], @cmd.installed_specs.map {|s| s.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
end
def test_parses_requirement_from_gemname
@@ -1065,7 +1047,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
assert_equal 2, e.exit_code
- assert_match %r{Could not find a valid gem 'a' \(= 10.0\)}, @ui.error
+ assert_match(/Could not find a valid gem 'a' \(= 10.0\)/, @ui.error)
end
def test_show_errors_on_failure
@@ -1106,7 +1088,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
assert_match "1 gem installed", @ui.output
@@ -1131,7 +1113,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
assert_match "1 gem installed", @ui.output
@@ -1158,7 +1140,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[], @cmd.installed_specs.map(&:full_name)
assert_match "Using a (2)", @ui.output
assert File.exist?("#{@gemdeps}.lock")
@@ -1182,7 +1164,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[], @cmd.installed_specs.map(&:full_name)
assert_match "Using a (2)", @ui.output
assert !File.exist?("#{@gemdeps}.lock")
@@ -1207,7 +1189,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[], @cmd.installed_specs.map(&:full_name)
assert_match "Using a (1)", @ui.output
end
@@ -1229,7 +1211,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name }
+ assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name)
assert_match "Installing a (2)", @ui.output
end
@@ -1252,7 +1234,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map {|spec| spec.full_name }
+ names = @cmd.installed_specs.map(&:full_name)
assert_equal %w[q-1.0 r-2.0], names
@@ -1279,7 +1261,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map {|spec| spec.full_name }
+ names = @cmd.installed_specs.map(&:full_name)
assert_equal %w[r-2.0], names
@@ -1306,7 +1288,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map {|spec| spec.full_name }
+ names = @cmd.installed_specs.map(&:full_name)
assert_equal %w[q-1.0 r-2.0], names
@@ -1338,7 +1320,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map {|spec| spec.full_name }
+ names = @cmd.installed_specs.map(&:full_name)
assert_equal %w[q-1.0 r-2.0], names
@@ -1355,7 +1337,7 @@ ERROR: Possible alternatives: non_existent_with_hint
fetcher.gem "r", "2.0", "q" => nil
end
- i = Gem::Installer.at specs["q-1.0"].cache_file, :install_dir => "gf-path"
+ i = Gem::Installer.at specs["q-1.0"].cache_file, install_dir: "gf-path"
i.install
assert File.file?("gf-path/specifications/q-1.0.gemspec"), "not installed"
@@ -1373,7 +1355,7 @@ ERROR: Possible alternatives: non_existent_with_hint
end
end
- names = @cmd.installed_specs.map {|spec| spec.full_name }
+ names = @cmd.installed_specs.map(&:full_name)
assert_equal %w[r-2.0], names
@@ -1550,4 +1532,22 @@ ERROR: Possible alternatives: non_existent_with_hint
assert_equal " a-3", out.shift
assert_empty out
end
+
+ def test_suggest_update_if_enabled
+ TestUpdateSuggestion.with_eligible_environment(cmd: @cmd) do
+ spec_fetcher do |fetcher|
+ fetcher.gem "a", 2
+ end
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ assert_raise Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_includes @ui.output, "A new release of RubyGems is available: 1.2.3 → 2.0.0!"
+ end
+ end
end
diff --git a/test/rubygems/test_gem_commands_list_command.rb b/test/rubygems/test_gem_commands_list_command.rb
index ec3f2517bf..c83dd51b67 100644
--- a/test/rubygems/test_gem_commands_list_command.rb
+++ b/test/rubygems/test_gem_commands_list_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/list_command"
diff --git a/test/rubygems/test_gem_commands_lock_command.rb b/test/rubygems/test_gem_commands_lock_command.rb
index b785cbcfdd..6afe4f35c5 100644
--- a/test/rubygems/test_gem_commands_lock_command.rb
+++ b/test/rubygems/test_gem_commands_lock_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/lock_command"
diff --git a/test/rubygems/test_gem_commands_mirror.rb b/test/rubygems/test_gem_commands_mirror.rb
index 423aba2656..2256a3ab33 100644
--- a/test/rubygems/test_gem_commands_mirror.rb
+++ b/test/rubygems/test_gem_commands_mirror.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/mirror_command"
@@ -14,6 +15,6 @@ class TestGemCommandsMirrorCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{Install the rubygems-mirror}i, @ui.error
+ assert_match(/Install the rubygems-mirror/i, @ui.error)
end
end
diff --git a/test/rubygems/test_gem_commands_open_command.rb b/test/rubygems/test_gem_commands_open_command.rb
index f970ca12d6..d9e518048c 100644
--- a/test/rubygems/test_gem_commands_open_command.rb
+++ b/test/rubygems/test_gem_commands_open_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/open_command"
@@ -21,20 +22,23 @@ class TestGemCommandsOpenCommand < Gem::TestCase
def test_execute
@cmd.options[:args] = %w[foo]
- @cmd.options[:editor] = "#{ruby_with_rubygems_in_load_path} -eexit --"
+ @cmd.options[:editor] = (ruby_with_rubygems_in_load_path + ["-e", "puts(ARGV,Dir.pwd)", "--"]).join(" ")
gem "foo", "1.0.0"
spec = gem "foo", "1.0.1"
assert_nothing_raised Gem::MockGemUi::TermError do
- Dir.stub(:chdir, spec.full_gem_path) do
+ stdout, stderr = capture_subprocess_io do
use_ui @ui do
@cmd.execute
end
end
+ assert_equal [spec.full_gem_path, spec.full_gem_path], stdout.split("\n")
+ assert_equal "", stderr
end
assert_equal "", @ui.error
+ assert_equal "", @ui.output
end
def test_wrong_version
@@ -49,7 +53,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase
end
end
- assert_match %r{Unable to find gem 'foo'}, @ui.output
+ assert_match(/Unable to find gem 'foo'/, @ui.output)
assert_equal "", @ui.error
end
@@ -62,7 +66,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase
end
end
- assert_match %r{Unable to find gem 'foo'}, @ui.output
+ assert_match(/Unable to find gem 'foo'/, @ui.output)
assert_equal "", @ui.error
end
@@ -91,7 +95,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase
end
end
- assert_match %r{'foo' is a default gem and can't be opened\.} , @ui.output
+ assert_match(/'foo' is a default gem and can't be opened\./, @ui.output)
assert_equal "", @ui.error
end
end
diff --git a/test/rubygems/test_gem_commands_outdated_command.rb b/test/rubygems/test_gem_commands_outdated_command.rb
index 4ed111a0e7..3e61033af3 100644
--- a/test/rubygems/test_gem_commands_outdated_command.rb
+++ b/test/rubygems/test_gem_commands_outdated_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/outdated_command"
diff --git a/test/rubygems/test_gem_commands_owner_command.rb b/test/rubygems/test_gem_commands_owner_command.rb
index ca77041000..eddd8afaf5 100644
--- a/test/rubygems/test_gem_commands_owner_command.rb
+++ b/test/rubygems/test_gem_commands_owner_command.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+
require_relative "helper"
+require_relative "multifactor_auth_utilities"
require "rubygems/commands/owner_command"
class TestGemCommandsOwnerCommand < Gem::TestCase
@@ -10,7 +12,7 @@ class TestGemCommandsOwnerCommand < Gem::TestCase
ENV["RUBYGEMS_HOST"] = nil
@stub_ui = Gem::MockGemUi.new
- @stub_fetcher = Gem::FakeFetcher.new
+ @stub_fetcher = Gem::MultifactorAuthFetcher.new
Gem::RemoteFetcher.fetcher = @stub_fetcher
Gem.configuration = nil
Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
@@ -36,20 +38,20 @@ class TestGemCommandsOwnerCommand < Gem::TestCase
- id: 4
EOF
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
use_ui @stub_ui do
@cmd.show_owners("freewill")
end
- assert_equal Net::HTTP::Get, @stub_fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Get, @stub_fetcher.last_request.class
assert_equal Gem.configuration.rubygems_api_key, @stub_fetcher.last_request["Authorization"]
- assert_match %r{Owners for gem: freewill}, @stub_ui.output
- assert_match %r{- user1@example.com}, @stub_ui.output
- assert_match %r{- user2@example.com}, @stub_ui.output
- assert_match %r{- user3}, @stub_ui.output
- assert_match %r{- 4}, @stub_ui.output
+ assert_match(/Owners for gem: freewill/, @stub_ui.output)
+ assert_match(/- user1@example.com/, @stub_ui.output)
+ assert_match(/- user2@example.com/, @stub_ui.output)
+ assert_match(/- user3/, @stub_ui.output)
+ assert_match(/- 4/, @stub_ui.output)
end
def test_show_owners_dont_load_objects
@@ -66,7 +68,7 @@ EOF
- id: 4
EOF
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
assert_raise Psych::DisallowedClass do
use_ui @ui do
@@ -80,14 +82,14 @@ EOF
host = "http://rubygems.example"
ENV["RUBYGEMS_HOST"] = host
- @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
use_ui @stub_ui do
@cmd.show_owners("freewill")
end
- assert_match %r{Owners for gem: freewill}, @stub_ui.output
- assert_match %r{- user1@example.com}, @stub_ui.output
+ assert_match(/Owners for gem: freewill/, @stub_ui.output)
+ assert_match(/- user1@example.com/, @stub_ui.output)
end
def test_show_owners_setting_up_host
@@ -95,19 +97,19 @@ EOF
host = "http://rubygems.example"
@cmd.host = host
- @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
use_ui @stub_ui do
@cmd.show_owners("freewill")
end
- assert_match %r{Owners for gem: freewill}, @stub_ui.output
- assert_match %r{- user1@example.com}, @stub_ui.output
+ assert_match(/Owners for gem: freewill/, @stub_ui.output)
+ assert_match(/- user1@example.com/, @stub_ui.output)
end
def test_show_owners_denied
response = "You don't have permission to push to this gem"
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 403, "Forbidden"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden")
assert_raise Gem::MockGemUi::TermError do
use_ui @stub_ui do
@@ -118,9 +120,32 @@ EOF
assert_match response, @stub_ui.output
end
+ def test_show_owners_permanent_redirect
+ host = "http://rubygems.example"
+ ENV["RUBYGEMS_HOST"] = host
+ path = "/api/v1/gems/freewill/owners.yaml"
+ redirected_uri = "https://rubygems.example#{path}"
+
+ @stub_fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create(
+ body: "",
+ code: "301",
+ msg: "Moved Permanently",
+ headers: { "location" => redirected_uri }
+ )
+
+ assert_raise Gem::MockGemUi::TermError do
+ use_ui @stub_ui do
+ @cmd.show_owners("freewill")
+ end
+ end
+
+ response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
+ assert_match response, @stub_ui.output
+ end
+
def test_show_owners_key
response = "- email: user1@example.com\n"
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
File.open Gem.configuration.credentials_path, "a" do |f|
f.write ":other: 701229f217cdf23b1344c7b4b54ca97"
end
@@ -134,13 +159,13 @@ EOF
def test_add_owners
response = "Owner added successfully."
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
use_ui @stub_ui do
@cmd.add_owners("freewill", ["user-new1@example.com"])
end
- assert_equal Net::HTTP::Post, @stub_fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @stub_fetcher.last_request.class
assert_equal Gem.configuration.rubygems_api_key, @stub_fetcher.last_request["Authorization"]
assert_equal "email=user-new1%40example.com", @stub_fetcher.last_request.body
@@ -149,7 +174,7 @@ EOF
def test_add_owners_denied
response = "You don't have permission to push to this gem"
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 403, "Forbidden"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden")
use_ui @stub_ui do
@cmd.add_owners("freewill", ["user-new1@example.com"])
@@ -158,12 +183,33 @@ EOF
assert_match response, @stub_ui.output
end
+ def test_add_owners_permanent_redirect
+ host = "http://rubygems.example"
+ ENV["RUBYGEMS_HOST"] = host
+ path = "/api/v1/gems/freewill/owners"
+ redirected_uri = "https://rubygems.example#{path}"
+
+ @stub_fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create(
+ body: "",
+ code: "308",
+ msg: "Permanent Redirect",
+ headers: { "location" => redirected_uri }
+ )
+
+ use_ui @stub_ui do
+ @cmd.add_owners("freewill", ["user-new1@example.com"])
+ end
+
+ response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
+ assert_match response, @stub_ui.output
+ end
+
def test_add_owner_with_host_option_through_execute
host = "http://rubygems.example"
add_owner_response = "Owner added successfully."
show_owners_response = "- email: user1@example.com\n"
- @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners"] = [add_owner_response, 200, "OK"]
- @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [show_owners_response, 200, "OK"]
+ @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: add_owner_response, code: 200, msg: "OK")
+ @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: show_owners_response, code: 200, msg: "OK")
@cmd.handle_options %W[--host #{host} --add user-new1@example.com freewill]
@@ -172,13 +218,13 @@ EOF
end
assert_match add_owner_response, @stub_ui.output
- assert_match %r{Owners for gem: freewill}, @stub_ui.output
- assert_match %r{- user1@example.com}, @stub_ui.output
+ assert_match(/Owners for gem: freewill/, @stub_ui.output)
+ assert_match(/- user1@example.com/, @stub_ui.output)
end
def test_add_owners_key
response = "Owner added successfully."
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
File.open Gem.configuration.credentials_path, "a" do |f|
f.write ":other: 701229f217cdf23b1344c7b4b54ca97"
end
@@ -192,13 +238,13 @@ EOF
def test_remove_owners
response = "Owner removed successfully."
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
use_ui @stub_ui do
@cmd.remove_owners("freewill", ["user-remove1@example.com"])
end
- assert_equal Net::HTTP::Delete, @stub_fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Delete, @stub_fetcher.last_request.class
assert_equal Gem.configuration.rubygems_api_key, @stub_fetcher.last_request["Authorization"]
assert_equal "email=user-remove1%40example.com", @stub_fetcher.last_request.body
@@ -207,18 +253,55 @@ EOF
def test_remove_owners_denied
response = "You don't have permission to push to this gem"
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 403, "Forbidden"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden")
+
+ use_ui @stub_ui do
+ @cmd.remove_owners("freewill", ["user-remove1@example.com"])
+ end
+
+ assert_match response, @stub_ui.output
+ end
+
+ def test_remove_owners_permanent_redirect
+ host = "http://rubygems.example"
+ ENV["RUBYGEMS_HOST"] = host
+ path = "/api/v1/gems/freewill/owners"
+ redirected_uri = "https://rubygems.example#{path}"
+ @stub_fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create(
+ body: "",
+ code: "308",
+ msg: "Permanent Redirect",
+ headers: { "location" => redirected_uri }
+ )
use_ui @stub_ui do
@cmd.remove_owners("freewill", ["user-remove1@example.com"])
end
+ response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
+ assert_match response, @stub_ui.output
+
+ path = "/api/v1/gems/freewill/owners"
+ redirected_uri = "https://rubygems.example#{path}"
+
+ @stub_fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create(
+ body: "",
+ code: "308",
+ msg: "Permanent Redirect",
+ headers: { "location" => redirected_uri }
+ )
+
+ use_ui @stub_ui do
+ @cmd.add_owners("freewill", ["user-new1@example.com"])
+ end
+
+ response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
assert_match response, @stub_ui.output
end
def test_remove_owners_key
response = "Owner removed successfully."
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK")
File.open Gem.configuration.credentials_path, "a" do |f|
f.write ":other: 701229f217cdf23b1344c7b4b54ca97"
end
@@ -232,7 +315,7 @@ EOF
def test_remove_owners_missing
response = "Owner could not be found."
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 404, "Not Found"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 404, msg: "Not Found")
use_ui @stub_ui do
@cmd.remove_owners("freewill", ["missing@example"])
@@ -242,13 +325,8 @@ EOF
end
def test_otp_verified_success
- response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
response_success = "Owner added successfully."
-
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [
- [response_fail, 401, "Unauthorized"],
- [response_success, 200, "OK"],
- ]
+ @stub_fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems/freewill/owners", response_success)
@otp_ui = Gem::MockGemUi.new "111111\n"
use_ui @otp_ui do
@@ -263,7 +341,9 @@ EOF
def test_otp_verified_failure
response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
- @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 401, "Unauthorized"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
+ @stub_fetcher.data["#{Gem.host}/api/v1/webauthn_verification"] =
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
@otp_ui = Gem::MockGemUi.new "111111\n"
use_ui @otp_ui do
@@ -276,15 +356,112 @@ EOF
assert_equal "111111", @stub_fetcher.last_request["OTP"]
end
+ def test_with_webauthn_enabled_success
+ response_success = "Owner added successfully."
+ server = Gem::MockTCPServer.new
+
+ @stub_fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems/freewill/owners", response_success)
+ @stub_fetcher.respond_with_webauthn_url
+
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
+ use_ui @stub_ui do
+ @cmd.add_owners("freewill", ["user-new1@example.com"])
+ end
+ end
+ end
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@stub_fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @stub_ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @stub_ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @stub_fetcher.last_request["OTP"]
+ assert_match response_success, @stub_ui.output
+ end
+
+ def test_with_webauthn_enabled_failure
+ response_success = "Owner added successfully."
+ server = Gem::MockTCPServer.new
+ error = Gem::WebauthnVerificationError.new("Something went wrong")
+
+ @stub_fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems/freewill/owners", response_success)
+ @stub_fetcher.respond_with_webauthn_url
+
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
+ use_ui @stub_ui do
+ @cmd.add_owners("freewill", ["user-new1@example.com"])
+ end
+ end
+ end
+
+ assert_match @stub_fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
+ assert_match "You have enabled multi-factor authentication. Please visit #{@stub_fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @stub_ui.output
+ assert_match "ERROR: Security device verification failed: Something went wrong", @stub_ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @stub_ui.output
+ refute_match response_success, @stub_ui.output
+ end
+
+ def test_with_webauthn_enabled_success_with_polling
+ response_success = "Owner added successfully."
+ server = Gem::MockTCPServer.new
+
+ @stub_fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems/freewill/owners", response_success)
+ @stub_fetcher.respond_with_webauthn_url
+ @stub_fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
+
+ TCPServer.stub(:new, server) do
+ use_ui @stub_ui do
+ @cmd.add_owners("freewill", ["user-new1@example.com"])
+ end
+ end
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@stub_fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \
+ "command with the `--otp [your_code]` option.", @stub_ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @stub_ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @stub_fetcher.last_request["OTP"]
+ assert_match response_success, @stub_ui.output
+ end
+
+ def test_with_webauthn_enabled_failure_with_polling
+ response_success = "Owner added successfully."
+ server = Gem::MockTCPServer.new
+
+ @stub_fetcher.respond_with_require_otp(
+ "#{Gem.host}/api/v1/gems/freewill/owners",
+ response_success
+ )
+ @stub_fetcher.respond_with_webauthn_url
+ @stub_fetcher.respond_with_webauthn_polling_failure
+
+ TCPServer.stub(:new, server) do
+ use_ui @stub_ui do
+ @cmd.add_owners("freewill", ["user-new1@example.com"])
+ end
+ end
+
+ assert_match @stub_fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
+ assert_match "You have enabled multi-factor authentication. Please visit #{@stub_fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \
+ "command with the `--otp [your_code]` option.", @stub_ui.output
+ assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \
+ "or been used already.", @stub_ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @stub_ui.output
+ refute_match response_success, @stub_ui.output
+ end
+
def test_remove_owners_unathorized_api_key
response_forbidden = "The API key doesn't have access"
response_success = "Owner removed successfully."
@stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [
- [response_forbidden, 403, "Forbidden"],
- [response_success, 200, "OK"],
+ HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"),
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
]
- @stub_fetcher.data["#{Gem.host}/api/v1/api_key"] = ["", 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK")
@cmd.instance_variable_set :@scope, :remove_owner
@stub_ui = Gem::MockGemUi.new "some@mail.com\npass\n"
@@ -294,7 +471,7 @@ EOF
access_notice = "The existing key doesn't have access of remove_owner on RubyGems.org. Please sign in to update access."
assert_match access_notice, @stub_ui.output
- assert_match "Email:", @stub_ui.output
+ assert_match "Username/email:", @stub_ui.output
assert_match "Password:", @stub_ui.output
assert_match "Added remove_owner scope to the existing API key", @stub_ui.output
assert_match response_success, @stub_ui.output
@@ -305,10 +482,10 @@ EOF
response_success = "Owner added successfully."
@stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [
- [response_forbidden, 403, "Forbidden"],
- [response_success, 200, "OK"],
+ HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"),
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
]
- @stub_fetcher.data["#{Gem.host}/api/v1/api_key"] = ["", 200, "OK"]
+ @stub_fetcher.data["#{Gem.host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK")
@cmd.instance_variable_set :@scope, :add_owner
@stub_ui = Gem::MockGemUi.new "some@mail.com\npass\n"
@@ -318,7 +495,7 @@ EOF
access_notice = "The existing key doesn't have access of add_owner on RubyGems.org. Please sign in to update access."
assert_match access_notice, @stub_ui.output
- assert_match "Email:", @stub_ui.output
+ assert_match "Username/email:", @stub_ui.output
assert_match "Password:", @stub_ui.output
assert_match "Added add_owner scope to the existing API key", @stub_ui.output
assert_match response_success, @stub_ui.output
diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb
index 5bf1d27eb9..a17d7837c9 100644
--- a/test/rubygems/test_gem_commands_pristine_command.rb
+++ b/test/rubygems/test_gem_commands_pristine_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/pristine_command"
@@ -53,7 +54,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
end
def test_execute_user_install
- FileUtils.chmod 0555, @gemhome
+ FileUtils.chmod 0o555, @gemhome
a = util_spec "a" do |s|
s.executables = %w[foo]
@@ -98,7 +99,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
assert_equal "Restored #{a.full_name}", out.shift
assert_empty out, out.inspect
ensure
- FileUtils.chmod(0755, @gemhome)
+ FileUtils.chmod(0o755, @gemhome)
end
def test_execute_all
@@ -157,11 +158,11 @@ class TestGemCommandsPristineCommand < Gem::TestCase
assert_path_exist gem_exec
- ruby_exec = sprintf Gem.default_exec_format, "ruby"
+ ruby_exec = format Gem.default_exec_format, "ruby"
- bin_env = win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " "
+ bin_env = Gem.win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " "
- assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(gem_exec)
+ assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(gem_exec))
end
def test_execute_extensions_explicit
@@ -202,6 +203,54 @@ class TestGemCommandsPristineCommand < Gem::TestCase
assert_empty out, out.inspect
end
+ def test_execute_extensions_only_missing_extensions
+ a = util_spec "a" do |s|
+ s.extensions << "ext/a/extconf.rb"
+ end
+
+ ext_path = File.join @tempdir, "ext", "a", "extconf.rb"
+ write_file ext_path do |io|
+ io.write <<-'RUBY'
+ File.open "Makefile", "w" do |f|
+ f.puts "clean:\n\techo cleaned\n"
+ f.puts "all:\n\techo built\n"
+ f.puts "install:\n\techo installed\n"
+ end
+ RUBY
+ end
+
+ b = util_spec "b" do |s|
+ s.extensions << "ext/b/extconf.rb"
+ end
+
+ ext_path = File.join @tempdir, "ext", "b", "extconf.rb"
+ write_file ext_path do |io|
+ io.write <<-'RUBY'
+ File.open "Makefile", "w" do |f|
+ f.puts "clean:\n\techo cleaned\n"
+ f.puts "all:\n\techo built\n"
+ f.puts "install:\n\techo installed\n"
+ end
+ RUBY
+ end
+
+ install_gem a
+ install_gem b
+
+ # Remove the extension files for b
+ FileUtils.rm_rf b.gem_build_complete_path
+
+ @cmd.options[:only_missing_extensions] = true
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ refute_includes @ui.output, "Restored #{a.full_name}"
+ assert_includes @ui.output, "Restored #{b.full_name}"
+ end
+
def test_execute_no_extension
a = util_spec "a" do |s|
s.extensions << "ext/a/extconf.rb"
@@ -247,7 +296,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
build_args = %w[--with-awesome=true --sweet]
- install_gem a, :build_args => build_args
+ install_gem a, build_args: build_args
@cmd.options[:args] = %w[a]
@@ -343,6 +392,9 @@ class TestGemCommandsPristineCommand < Gem::TestCase
b = util_spec "b"
install_gem b
+ assert_path_exist File.join(gemhome2, "gems", "b-2")
+ assert_path_not_exist File.join(@gemhome, "gems", "b-2")
+
@cmd.options[:args] = %w[a b]
use_ui @ui do
@@ -455,7 +507,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
end
end
- assert_match %r{at least one gem name}, e.message
+ assert_match(/at least one gem name/, e.message)
end
def test_execute_only_executables
@@ -497,7 +549,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
fp.puts "puts __FILE__"
end
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |fp|
- fp.puts "puts __FILE__"
+ fp.puts "# do nothing"
end
write_file File.join(@tempdir, "bin", "foo") do |fp|
fp.puts "#!/usr/bin/ruby"
@@ -547,7 +599,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase
FileUtils.rm gem_exec
FileUtils.rm gem_bindir
- @cmd.handle_options ["--all", "--only-executables", "--bindir", "#{gem_bindir}"]
+ @cmd.handle_options ["--all", "--only-executables", "--bindir", gem_bindir.to_s]
use_ui @ui do
@cmd.execute
diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb
index f38a2ae7a1..a7a18ff4ab 100644
--- a/test/rubygems/test_gem_commands_push_command.rb
+++ b/test/rubygems/test_gem_commands_push_command.rb
@@ -1,6 +1,9 @@
# frozen_string_literal: true
+
require_relative "helper"
+require_relative "multifactor_auth_utilities"
require "rubygems/commands/push_command"
+require "rubygems/config_file"
class TestGemCommandsPushCommand < Gem::TestCase
def setup
@@ -24,7 +27,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
@host = "https://rubygems.example"
@api_key = Gem.configuration.rubygems_api_key
- @fetcher = Gem::FakeFetcher.new
+ @fetcher = Gem::MultifactorAuthFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
@cmd = Gem::Commands::PushCommand.new
@@ -55,9 +58,9 @@ class TestGemCommandsPushCommand < Gem::TestCase
@cmd.send_gem(@path)
end
- assert_match %r{Pushing gem to #{@host}...}, @ui.output
+ assert_match(/Pushing gem to #{@host}.../, @ui.output)
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
@@ -68,13 +71,13 @@ class TestGemCommandsPushCommand < Gem::TestCase
def test_execute
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
@cmd.options[:args] = [@path]
@cmd.execute
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal "application/octet-stream",
@fetcher.last_request["Content-Type"]
@@ -84,7 +87,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
host = "https://other.example"
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
@fetcher.data["#{Gem.host}/api/v1/gems"] =
["fail", 500, "Internal Server Error"]
@@ -93,7 +96,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
@cmd.execute
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal "application/octet-stream",
@fetcher.last_request["Content-Type"]
@@ -105,7 +108,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
end
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@spec.metadata['allowed_push_host']}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{@spec.metadata["allowed_push_host"]}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
@fetcher.data["#{Gem.host}/api/v1/gems"] =
["fail", 500, "Internal Server Error"]
@@ -113,7 +116,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
@cmd.execute
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal "application/octet-stream",
@fetcher.last_request["Content-Type"]
@@ -136,7 +139,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
ENV["RUBYGEMS_HOST"] = @host
Gem.configuration.disable_default_gem_server = true
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -156,21 +159,21 @@ class TestGemCommandsPushCommand < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
FileUtils.rm Gem.configuration.credentials_path
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
def test_sending_gem
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -190,14 +193,14 @@ class TestGemCommandsPushCommand < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
FileUtils.rm Gem.configuration.credentials_path
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -212,7 +215,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
ENV["GEM_HOST_API_KEY"] = "PRIVKEY"
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -227,18 +230,18 @@ class TestGemCommandsPushCommand < Gem::TestCase
@api_key = "DOESNTMATTER"
keys = {
- :rubygems_api_key => @api_key,
+ rubygems_api_key: @api_key,
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
FileUtils.rm Gem.configuration.credentials_path
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
send_battery
end
@@ -272,7 +275,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
@@ -302,21 +305,21 @@ class TestGemCommandsPushCommand < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
FileUtils.rm Gem.configuration.credentials_path
@response = "Successfully registered gem: freebird (1.0.1)"
- @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
# do not set @host
use_ui(@ui) { @cmd.send_gem(@path) }
- assert_match %r{Pushing gem to #{host}...}, @ui.output
+ assert_match(/Pushing gem to #{host}.../, @ui.output)
- assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
@@ -325,6 +328,27 @@ class TestGemCommandsPushCommand < Gem::TestCase
assert_match @response, @ui.output
end
+ def test_sending_gem_to_host_permanent_redirect
+ @host = "http://rubygems.example"
+ redirected_uri = "https://rubygems.example/api/v1/gems"
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(
+ body: "",
+ code: 308,
+ msg: "Permanent Redirect",
+ headers: { "Location" => redirected_uri }
+ )
+
+ assert_raise Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.instance_variable_set :@host, @host
+ @cmd.send_gem(@path)
+ end
+ end
+
+ response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
+ assert_match response, @ui.output
+ end
+
def test_raises_error_with_no_arguments
def @cmd.sign_in(*); end
assert_raise Gem::CommandLineError do
@@ -334,7 +358,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
def test_sending_gem_denied
response = "You don't have permission to push to this gem"
- @fetcher.data["#{@host}/api/v1/gems"] = [response, 403, "Forbidden"]
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden")
@cmd.instance_variable_set :@host, @host
assert_raise Gem::MockGemUi::TermError do
@@ -348,7 +372,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
def test_sending_gem_key
@response = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK")
File.open Gem.configuration.credentials_path, "a" do |f|
f.write ":other: 701229f217cdf23b1344c7b4b54ca97"
end
@@ -363,13 +387,9 @@ class TestGemCommandsPushCommand < Gem::TestCase
end
def test_otp_verified_success
- response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
response_success = "Successfully registered gem: freewill (1.0.0)"
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [
- [response_fail, 401, "Unauthorized"],
- [response_success, 200, "OK"],
- ]
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
@otp_ui = Gem::MockGemUi.new "111111\n"
use_ui @otp_ui do
@@ -384,7 +404,9 @@ class TestGemCommandsPushCommand < Gem::TestCase
def test_otp_verified_failure
response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
- @fetcher.data["#{Gem.host}/api/v1/gems"] = [response, 401, "Unauthorized"]
+ @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
+ @fetcher.data["#{Gem.host}/api/v1/webauthn_verification"] =
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
@otp_ui = Gem::MockGemUi.new "111111\n"
assert_raise Gem::MockGemUi::TermError do
@@ -399,18 +421,120 @@ class TestGemCommandsPushCommand < Gem::TestCase
assert_equal "111111", @fetcher.last_request["OTP"]
end
+ def test_with_webauthn_enabled_success
+ response_success = "Successfully registered gem: freewill (1.0.0)"
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
+ @fetcher.respond_with_webauthn_url
+
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+ end
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
+ assert_match response_success, @ui.output
+ end
+
+ def test_with_webauthn_enabled_failure
+ response_success = "Successfully registered gem: freewill (1.0.0)"
+ server = Gem::MockTCPServer.new
+ error = Gem::WebauthnVerificationError.new("Something went wrong")
+
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
+ @fetcher.respond_with_webauthn_url
+
+ error = assert_raise Gem::MockGemUi::TermError do
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+ end
+ end
+ assert_equal 1, error.exit_code
+
+ assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @ui.output
+ refute_match response_success, @ui.output
+ end
+
+ def test_with_webauthn_enabled_success_with_polling
+ response_success = "Successfully registered gem: freewill (1.0.0)"
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
+ @fetcher.respond_with_webauthn_url
+ @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
+
+ TCPServer.stub(:new, server) do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
+ assert_match response_success, @ui.output
+ end
+
+ def test_with_webauthn_enabled_failure_with_polling
+ response_success = "Successfully registered gem: freewill (1.0.0)"
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success)
+ @fetcher.respond_with_webauthn_url
+ @fetcher.respond_with_webauthn_polling_failure
+
+ error = assert_raise Gem::MockGemUi::TermError do
+ TCPServer.stub(:new, server) do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+ end
+ assert_equal 1, error.exit_code
+
+ assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \
+ "command with the `--otp [your_code]` option.", @ui.output
+ assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \
+ "or been used already.", @ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @ui.output
+ refute_match response_success, @ui.output
+ end
+
def test_sending_gem_unathorized_api_key_with_mfa_enabled
response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
response_forbidden = "The API key doesn't have access"
response_success = "Successfully registered gem: freewill (1.0.0)"
@fetcher.data["#{@host}/api/v1/gems"] = [
- [response_mfa_enabled, 401, "Unauthorized"],
- [response_forbidden, 403, "Forbidden"],
- [response_success, 200, "OK"],
+ HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"),
+ HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"),
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
]
+ @fetcher.data["#{@host}/api/v1/webauthn_verification"] =
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
- @fetcher.data["#{@host}/api/v1/api_key"] = ["", 200, "OK"]
+ @fetcher.data["#{@host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK")
@cmd.instance_variable_set :@host, @host
@cmd.instance_variable_set :@scope, :push_rubygem
@@ -423,7 +547,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
access_notice = "The existing key doesn't have access of push_rubygem on https://rubygems.example. Please sign in to update access."
assert_match mfa_notice, @ui.output
assert_match access_notice, @ui.output
- assert_match "Email:", @ui.output
+ assert_match "Username/email:", @ui.output
assert_match "Password:", @ui.output
assert_match "Added push_rubygem scope to the existing API key", @ui.output
assert_match response_success, @ui.output
@@ -438,17 +562,19 @@ class TestGemCommandsPushCommand < Gem::TestCase
response_profile = "mfa: disabled\n"
@fetcher.data["#{@host}/api/v1/gems"] = [
- [response_success, 200, "OK"],
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
]
@fetcher.data["#{@host}/api/v1/api_key"] = [
- [response_mfa_enabled, 401, "Unauthorized"],
- ["", 200, "OK"],
+ HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"),
+ HTTPResponseFactory.create(body: "", code: 200, msg: "OK"),
]
@fetcher.data["#{@host}/api/v1/profile/me.yaml"] = [
- [response_profile, 200, "OK"],
+ HTTPResponseFactory.create(body: response_profile, code: 200, msg: "OK"),
]
+ @fetcher.data["#{@host}/api/v1/webauthn_verification"] =
+ HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity")
@cmd.instance_variable_set :@scope, :push_rubygem
@cmd.options[:args] = [@path]
@@ -462,7 +588,7 @@ class TestGemCommandsPushCommand < Gem::TestCase
mfa_notice = "You have enabled multi-factor authentication. Please enter OTP code."
assert_match mfa_notice, @ui.output
assert_match "Enter your https://rubygems.example credentials.", @ui.output
- assert_match "Email:", @ui.output
+ assert_match "Username/email:", @ui.output
assert_match "Password:", @ui.output
assert_match "Signed in with API key:", @ui.output
assert_match response_success, @ui.output
diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb
index 6882098c53..8e590df124 100644
--- a/test/rubygems/test_gem_commands_query_command.rb
+++ b/test/rubygems/test_gem_commands_query_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/query_command"
@@ -22,9 +23,7 @@ class TestGemCommandsQueryCommandWithInstalledGems < Gem::TestCase
include TestGemCommandsQueryCommandSetup
def test_execute
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[-r]
@@ -45,9 +44,7 @@ pl (1 i386-linux)
end
def test_execute_all
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[-r --all]
@@ -68,9 +65,7 @@ pl (1 i386-linux)
end
def test_execute_all_prerelease
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[-r --all --prerelease]
@@ -310,9 +305,7 @@ pl (1)
end
def test_execute_local
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.options[:domain] = :local
@@ -333,9 +326,7 @@ pl (1 i386-linux)
end
def test_execute_local_notty
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[]
@@ -355,9 +346,7 @@ pl (1 i386-linux)
end
def test_execute_local_quiet
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.options[:domain] = :local
Gem.configuration.verbose = false
@@ -376,9 +365,7 @@ pl (1 i386-linux)
end
def test_execute_no_versions
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[-r --no-versions]
@@ -399,9 +386,7 @@ pl
end
def test_execute_notty
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[-r]
@@ -439,9 +424,7 @@ a (3.a)
end
def test_execute_prerelease_local
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[-l --prerelease]
@@ -461,9 +444,7 @@ pl (1 i386-linux)
end
def test_execute_no_prerelease_local
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[-l --no-prerelease]
@@ -483,9 +464,7 @@ pl (1 i386-linux)
end
def test_execute_remote
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.options[:domain] = :remote
@@ -506,9 +485,7 @@ pl (1 i386-linux)
end
def test_execute_remote_notty
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[]
@@ -528,9 +505,7 @@ pl (1 i386-linux)
end
def test_execute_remote_quiet
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.options[:domain] = :remote
Gem.configuration.verbose = false
@@ -569,9 +544,7 @@ pl (1 i386-linux)
# Test for multiple args handling!
def test_execute_multiple_args
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
@cmd.handle_options %w[a pl]
@@ -579,8 +552,8 @@ pl (1 i386-linux)
@cmd.execute
end
- assert_match %r{^a }, @stub_ui.output
- assert_match %r{^pl }, @stub_ui.output
+ assert_match(/^a /, @stub_ui.output)
+ assert_match(/^pl /, @stub_ui.output)
assert_equal "", @stub_ui.error
end
@@ -592,8 +565,8 @@ pl (1 i386-linux)
@cmd.send :show_gems, /a/i
end
- assert_match %r{^a }, @stub_ui.output
- refute_match %r{^pl }, @stub_ui.output
+ assert_match(/^a /, @stub_ui.output)
+ refute_match(/^pl /, @stub_ui.output)
assert_empty @stub_ui.error
end
diff --git a/test/rubygems/test_gem_commands_rebuild_command.rb b/test/rubygems/test_gem_commands_rebuild_command.rb
new file mode 100644
index 0000000000..5e8c797e2d
--- /dev/null
+++ b/test/rubygems/test_gem_commands_rebuild_command.rb
@@ -0,0 +1,145 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems/commands/build_command"
+require "rubygems/commands/rebuild_command"
+require "rubygems/package"
+
+class TestGemCommandsRebuildCommand < Gem::TestCase
+ def setup
+ super
+
+ readme_file = File.join(@tempdir, "README.md")
+
+ begin
+ umask_orig = File.umask(2)
+ File.open readme_file, "w" do |f|
+ f.write "My awesome gem"
+ end
+ ensure
+ File.umask(umask_orig)
+ end
+
+ @gem_name = "rebuild_test_gem"
+ @gem_version = "1.0.0"
+ @gem = util_spec @gem_name do |s|
+ s.version = @gem_version
+ s.license = "AGPL-3.0"
+ s.files = ["README.md"]
+ end
+ end
+
+ def util_test_build_gem(gem, args)
+ @ui = Gem::MockGemUi.new
+
+ cmd = Gem::Commands::BuildCommand.new
+
+ cmd.options[:args] = args
+ cmd.options[:build_path] = @tempdir
+ use_ui @ui do
+ cmd.execute
+ end
+ gem_file = "#{@gem_name}-#{@gem_version}.gem"
+ output = @ui.output.split "\n"
+ assert_equal " Successfully built RubyGem", output.shift
+ assert_equal " Name: #{@gem_name}", output.shift
+ assert_equal " Version: #{@gem_version}", output.shift
+ assert_equal " File: #{gem_file}", output.shift
+ assert_equal [], output
+
+ gem_file = File.join(@tempdir, gem_file)
+ assert File.exist?(gem_file)
+
+ spec = Gem::Package.new(gem_file).spec
+
+ assert_equal @gem_name, spec.name
+ assert_equal "this is a summary", spec.summary
+ gem_file
+ end
+
+ def util_test_rebuild_gem(gem, args, original_gem_file, gemspec_file, timestamp)
+ @ui = Gem::MockGemUi.new
+
+ cmd = Gem::Commands::RebuildCommand.new
+
+ cmd.options[:args] = args
+ cmd.options[:original_gem_file] = original_gem_file
+ cmd.options[:build_path] = @tempdir
+ cmd.options[:gemspec_file] = gemspec_file
+ use_ui @ui do
+ cmd.execute
+ end
+ gem_file = "#{@gem_name}-#{@gem_version}.gem"
+ output = @ui.output.split "\n"
+
+ assert_equal " Successfully built RubyGem", output.shift
+ assert_equal " Name: #{@gem_name}", output.shift
+ assert_equal " Version: #{@gem_version}", output.shift
+ assert_equal " File: #{gem_file}", output.shift
+ assert_empty output.shift
+ assert_match(/^Built at: .+ \(#{timestamp}\)/, output.shift)
+ original_line = output.shift
+ original = original_line.split(" ")[-1]
+ assert_match(/^Original build saved to: /, original_line)
+ reproduced_line = output.shift
+ reproduced = reproduced_line.split(" ")[-1]
+ assert_match(/^Reproduced build saved to: /, reproduced_line)
+ assert_equal "Working directory: #{@tempdir}", output.shift
+ assert_equal "", output.shift
+ assert_equal "Hash comparison:", output.shift
+ output.shift # " #{old_hash}\t#{old_file}"
+ output.shift # " #{new_hash}\t#{new_file}"
+ assert_empty output.shift
+ assert_equal "SUCCESS - original and rebuild hashes matched", output.shift
+ assert_equal [], output
+
+ assert File.exist?(original)
+ assert File.exist?(reproduced)
+
+ old_spec = Gem::Package.new(original).spec
+ new_spec = Gem::Package.new(reproduced).spec
+
+ assert_equal @gem_name, old_spec.name
+ assert_equal "this is a summary", old_spec.summary
+
+ assert_equal old_spec.name, new_spec.name
+ assert_equal old_spec.summary, new_spec.summary
+
+ reproduced
+ end
+
+ def test_build_is_reproducible
+ # Back up SOURCE_DATE_EPOCH to restore later.
+ epoch = ENV["SOURCE_DATE_EPOCH"]
+
+ gemspec_file = File.join(@tempdir, @gem.spec_name)
+
+ # Initial Build
+
+ # Set SOURCE_DATE_EPOCH to 2001-02-03 04:05:06 -0500.
+ ENV["SOURCE_DATE_EPOCH"] = timestamp = Time.new(2001, 2, 3, 4, 5, 6).to_i.to_s
+ File.write(gemspec_file, @gem.to_ruby)
+ gem_file = util_test_build_gem @gem, [gemspec_file]
+
+ build_contents = File.read(gem_file)
+
+ gem_file_dir = File.dirname(gem_file)
+ gem_file_name = File.basename(gem_file)
+ original_gem_file = File.join(gem_file_dir, "original-" + gem_file_name)
+ File.rename(gem_file, original_gem_file)
+
+ # Rebuild
+
+ # Set SOURCE_DATE_EPOCH to a different value, meaning we are
+ # 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_contents = File.read(rebuild_gem_file)
+
+ assert_equal build_contents, rebuild_contents
+ ensure
+ ENV["SOURCE_DATE_EPOCH"] = epoch
+ end
+end
diff --git a/test/rubygems/test_gem_commands_search_command.rb b/test/rubygems/test_gem_commands_search_command.rb
index afa6ff8d13..47aefa0cf7 100644
--- a/test/rubygems/test_gem_commands_search_command.rb
+++ b/test/rubygems/test_gem_commands_search_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/search_command"
diff --git a/test/rubygems/test_gem_commands_server_command.rb b/test/rubygems/test_gem_commands_server_command.rb
index 1becde3ae2..cabb7cf49d 100644
--- a/test/rubygems/test_gem_commands_server_command.rb
+++ b/test/rubygems/test_gem_commands_server_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/server_command"
@@ -14,6 +15,6 @@ class TestGemCommandsServerCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{Install the rubygems-server}i, @ui.error
+ assert_match(/Install the rubygems-server/i, @ui.error)
end
end
diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb
index 1c0963ee96..43f695f147 100644
--- a/test/rubygems/test_gem_commands_setup_command.rb
+++ b/test/rubygems/test_gem_commands_setup_command.rb
@@ -8,16 +8,17 @@ class TestGemCommandsSetupCommand < Gem::TestCase
if File.exist?(bundler_gemspec)
BUNDLER_VERS = File.read(bundler_gemspec).match(/VERSION = "(#{Gem::Version::VERSION_PATTERN})"/)[1]
else
- BUNDLER_VERS = "2.0.1".freeze
+ BUNDLER_VERS = "2.0.1"
end
def setup
super
@cmd = Gem::Commands::SetupCommand.new
+ @cmd.options[:document] = []
filelist = %w[
- bin/gem
+ exe/gem
lib/rubygems.rb
lib/rubygems/requirement.rb
lib/rubygems/ssl_certs/rubygems.org/foo.pem
@@ -30,17 +31,14 @@ class TestGemCommandsSetupCommand < Gem::TestCase
bundler/lib/bundler/man/gemfile.5
bundler/lib/bundler/man/gemfile.5.ronn
bundler/lib/bundler/templates/.circleci/config.yml
- bundler/lib/bundler/templates/.travis.yml
]
create_dummy_files(filelist)
- gemspec = Gem::Specification.new
- gemspec.author = "Us"
- gemspec.name = "bundler"
- gemspec.version = BUNDLER_VERS
- gemspec.bindir = "exe"
- gemspec.executables = ["bundle", "bundler"]
+ gemspec = util_spec "bundler", BUNDLER_VERS do |s|
+ s.bindir = "exe"
+ s.executables = ["bundle", "bundler"]
+ end
File.open "bundler/bundler.gemspec", "w" do |io|
io.puts gemspec.to_ruby
@@ -66,10 +64,9 @@ class TestGemCommandsSetupCommand < Gem::TestCase
io.puts "I changed it!"
end
- @cmd.options[:document] = []
@cmd.execute
- assert_match %r{\A#!}, File.read(gem_bin_path)
+ assert_match(/\A#!/, File.read(gem_bin_path))
end
def test_execute_no_regenerate_binstubs
@@ -78,7 +75,6 @@ class TestGemCommandsSetupCommand < Gem::TestCase
io.puts "I changed it!"
end
- @cmd.options[:document] = []
@cmd.options[:regenerate_binstubs] = false
@cmd.execute
@@ -91,10 +87,9 @@ class TestGemCommandsSetupCommand < Gem::TestCase
io.puts "I changed it!"
end
- @cmd.options[:document] = []
@cmd.execute
- assert_match %r{\Arequire}, File.read(gem_plugin_path)
+ assert_match(/\Arequire/, File.read(gem_plugin_path))
end
def test_execute_no_regenerate_plugins
@@ -103,7 +98,6 @@ class TestGemCommandsSetupCommand < Gem::TestCase
io.puts "I changed it!"
end
- @cmd.options[:document] = []
@cmd.options[:regenerate_plugins] = false
@cmd.execute
@@ -116,15 +110,12 @@ class TestGemCommandsSetupCommand < Gem::TestCase
# Simulate gem installed with an older rubygems without a plugins layout
FileUtils.rm_rf Gem.plugindir
- @cmd.options[:document] = []
@cmd.execute
- assert_match %r{\Arequire}, File.read(gem_plugin_path)
+ assert_match(/\Arequire/, File.read(gem_plugin_path))
end
def test_execute_informs_about_installed_executables
- @cmd.options[:document] = []
-
use_ui @ui do
@cmd.execute
end
@@ -143,17 +134,16 @@ class TestGemCommandsSetupCommand < Gem::TestCase
io.puts "I changed it!"
end
- @cmd.options[:document] = []
@cmd.options[:env_shebang] = true
@cmd.execute
- ruby_exec = sprintf Gem.default_exec_format, "ruby"
+ ruby_exec = format Gem.default_exec_format, "ruby"
- bin_env = win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " "
- assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(default_gem_bin_path)
- assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(default_bundle_bin_path)
- assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(default_bundler_bin_path)
- assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(gem_bin_path)
+ bin_env = Gem.win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " "
+ assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(default_gem_bin_path))
+ assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(default_bundle_bin_path))
+ assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(default_bundler_bin_path))
+ assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(gem_bin_path))
end
def test_destdir_flag_does_not_try_to_write_to_the_default_gem_home
@@ -187,7 +177,6 @@ class TestGemCommandsSetupCommand < Gem::TestCase
assert_path_exist File.join(dir, "bundler/b.rb")
assert_path_exist File.join(dir, "bundler/templates/.circleci/config.yml")
- assert_path_exist File.join(dir, "bundler/templates/.travis.yml")
end
end
@@ -440,7 +429,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
s.files = %W[lib/rubygems_plugin.rb]
end
write_file File.join @tempdir, "lib", "rubygems_plugin.rb" do |f|
- f.puts "require '#{gem.plugins.first}'"
+ f.puts "# do nothing"
end
install_gem gem
diff --git a/test/rubygems/test_gem_commands_signin_command.rb b/test/rubygems/test_gem_commands_signin_command.rb
index ce745bff20..29e5edceb7 100644
--- a/test/rubygems/test_gem_commands_signin_command.rb
+++ b/test/rubygems/test_gem_commands_signin_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/signin_command"
require "rubygems/installer"
@@ -23,14 +24,14 @@ class TestGemCommandsSigninCommand < Gem::TestCase
def test_execute_when_not_already_signed_in
sign_in_ui = util_capture { @cmd.execute }
- assert_match %r{Signed in.}, sign_in_ui.output
+ assert_match(/Signed in./, sign_in_ui.output)
end
def test_execute_when_not_already_signed_in_and_not_preexisting_credentials_folder
FileUtils.rm Gem.configuration.credentials_path
sign_in_ui = util_capture { @cmd.execute }
- assert_match %r{Signed in.}, sign_in_ui.output
+ assert_match(/Signed in./, sign_in_ui.output)
end
def test_execute_when_already_signed_in_with_same_host
@@ -63,14 +64,39 @@ class TestGemCommandsSigninCommand < Gem::TestCase
host = "http://some-gemcutter-compatible-host.org"
sign_in_ui = util_capture(nil, host) { @cmd.execute }
- assert_match %r{Enter your #{host} credentials.}, sign_in_ui.output
- assert_match %r{Signed in.}, sign_in_ui.output
+ assert_match(/Enter your #{host} credentials./, sign_in_ui.output)
+ assert_match(/Signed in./, sign_in_ui.output)
api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
credentials = load_yaml_file Gem.configuration.credentials_path
assert_equal api_key, credentials[host]
end
+ def test_execute_with_host_permanent_redirect
+ host = "http://rubygems.example/"
+ ENV["RUBYGEMS_HOST"] = host
+ path = "/api/v1/api_key"
+ redirected_uri = "http://rubygems.example#{path}"
+ fetcher = Gem::FakeFetcher.new
+ fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create(
+ body: "",
+ code: "308",
+ msg: "Permanent Redirect",
+ headers: { "location" => redirected_uri }
+ )
+ Gem::RemoteFetcher.fetcher = fetcher
+ ui = Gem::MockGemUi.new("you@example.com\nsecret\n\n\n")
+
+ assert_raise Gem::MockGemUi::TermError do
+ use_ui ui do
+ @cmd.execute
+ end
+ end
+
+ response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL."
+ assert_match response, ui.output
+ end
+
def test_execute_with_valid_creds_set_for_default_host
util_capture { @cmd.execute }
@@ -80,51 +106,98 @@ class TestGemCommandsSigninCommand < Gem::TestCase
assert_equal api_key, credentials[:rubygems_api_key]
end
- def test_execute_with_key_name_and_scope
+ def test_execute_with_key_name_default_scope
+ email = "you@example.com"
+ password = "secret"
+ api_key = "1234abcd"
+ fetcher = Gem::RemoteFetcher.fetcher
+
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\n"
+ util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute }
+
+ user = ENV["USER"] || ENV["USERNAME"]
+
+ assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
+ assert_match "The default access scope is:", key_name_ui.output
+ assert_match "index_rubygems: y", key_name_ui.output
+ assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
+ assert_equal "name=test-key&index_rubygems=true", fetcher.last_request.body
+
+ credentials = load_yaml_file Gem.configuration.credentials_path
+ assert_equal api_key, credentials[:rubygems_api_key]
+ end
+
+ def test_execute_with_key_name_and_custom_scope
email = "you@example.com"
password = "secret"
- api_key = "1234"
+ api_key = "1234abcd"
fetcher = Gem::RemoteFetcher.fetcher
- key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\n"
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\n"
util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute }
user = ENV["USER"] || ENV["USERNAME"]
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
+ assert_match "The default access scope is:", key_name_ui.output
+ assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
+ assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
assert_match "index_rubygems [yN]", key_name_ui.output
assert_match "push_rubygem [yN]", key_name_ui.output
assert_match "yank_rubygem [yN]", key_name_ui.output
assert_match "add_owner [yN]", key_name_ui.output
assert_match "remove_owner [yN]", key_name_ui.output
assert_match "access_webhooks [yN]", key_name_ui.output
- assert_match "show_dashboard [yN]", key_name_ui.output
assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body
credentials = load_yaml_file Gem.configuration.credentials_path
assert_equal api_key, credentials[:rubygems_api_key]
end
- def test_execute_with_key_name_scope_and_mfa_level_of_ui_only
+ def test_execute_with_key_name_and_exclusive_scope
email = "you@example.com"
password = "secret"
- api_key = "1234"
+ api_key = "1234abcd"
+ fetcher = Gem::RemoteFetcher.fetcher
+
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\ny\n"
+ util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute }
+
+ user = ENV["USER"] || ENV["USERNAME"]
+
+ assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
+ assert_match "The default access scope is:", key_name_ui.output
+ assert_match "index_rubygems: y", key_name_ui.output
+ assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
+ assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
+ assert_equal "name=test-key&show_dashboard=true", fetcher.last_request.body
+
+ credentials = load_yaml_file Gem.configuration.credentials_path
+ assert_equal api_key, credentials[:rubygems_api_key]
+ end
+
+ def test_execute_with_key_name_custom_scope_and_mfa_level_of_ui_only
+ email = "you@example.com"
+ password = "secret"
+ api_key = "1234abcd"
fetcher = Gem::RemoteFetcher.fetcher
mfa_level = "ui_only"
- key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny"
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute }
user = ENV["USER"] || ENV["USERNAME"]
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
+ assert_match "The default access scope is:", key_name_ui.output
+ assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
+ assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
assert_match "index_rubygems [yN]", key_name_ui.output
assert_match "push_rubygem [yN]", key_name_ui.output
assert_match "yank_rubygem [yN]", key_name_ui.output
assert_match "add_owner [yN]", key_name_ui.output
assert_match "remove_owner [yN]", key_name_ui.output
assert_match "access_webhooks [yN]", key_name_ui.output
- assert_match "show_dashboard [yN]", key_name_ui.output
assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output
assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body
@@ -132,26 +205,28 @@ class TestGemCommandsSigninCommand < Gem::TestCase
assert_equal api_key, credentials[:rubygems_api_key]
end
- def test_execute_with_key_name_scope_and_mfa_level_of_gem_signin
+ def test_execute_with_key_name_custom_scope_and_mfa_level_of_gem_signin
email = "you@example.com"
password = "secret"
- api_key = "1234"
+ api_key = "1234abcd"
fetcher = Gem::RemoteFetcher.fetcher
mfa_level = "ui_and_gem_signin"
- key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny"
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute }
user = ENV["USER"] || ENV["USERNAME"]
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
+ assert_match "The default access scope is:", key_name_ui.output
+ assert_match "Do you want to customise scopes? [yN]", key_name_ui.output
+ assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
assert_match "index_rubygems [yN]", key_name_ui.output
assert_match "push_rubygem [yN]", key_name_ui.output
assert_match "yank_rubygem [yN]", key_name_ui.output
assert_match "add_owner [yN]", key_name_ui.output
assert_match "remove_owner [yN]", key_name_ui.output
assert_match "access_webhooks [yN]", key_name_ui.output
- assert_match "show_dashboard [yN]", key_name_ui.output
assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output
assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body
@@ -162,7 +237,7 @@ class TestGemCommandsSigninCommand < Gem::TestCase
def test_execute_with_warnings
email = "you@example.com"
password = "secret"
- api_key = "1234"
+ api_key = "1234abcd"
fetcher = Gem::RemoteFetcher.fetcher
mfa_level = "disabled"
warning = "/[WARNING/] For protection of your account and gems"
@@ -178,15 +253,15 @@ class TestGemCommandsSigninCommand < Gem::TestCase
email = "you@example.com"
password = "secret"
- api_key = "1234"
+ api_key = "1234abcd"
fetcher = Gem::RemoteFetcher.fetcher
- key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny"
+ key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny"
# Set the expected response for the Web-API supplied
ENV["RUBYGEMS_HOST"] = host
- data_key = "#{ENV['RUBYGEMS_HOST']}/api/v1/api_key"
- fetcher.data[data_key] = [api_key, 200, "OK"]
+ data_key = "#{ENV["RUBYGEMS_HOST"]}/api/v1/api_key"
+ fetcher.data[data_key] = HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
use_ui key_name_ui do
@cmd.execute
@@ -195,13 +270,13 @@ class TestGemCommandsSigninCommand < Gem::TestCase
user = ENV["USER"] || ENV["USERNAME"]
assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output
+ assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output
assert_match "index_rubygems [yN]", key_name_ui.output
assert_match "push_rubygem [yN]", key_name_ui.output
assert_match "yank_rubygem [yN]", key_name_ui.output
assert_match "add_owner [yN]", key_name_ui.output
assert_match "remove_owner [yN]", key_name_ui.output
assert_match "access_webhooks [yN]", key_name_ui.output
- assert_match "show_dashboard [yN]", key_name_ui.output
assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body
end
@@ -209,20 +284,20 @@ class TestGemCommandsSigninCommand < Gem::TestCase
def util_capture(ui_stub = nil, host = nil, api_key = nil, fetcher = Gem::FakeFetcher.new, mfa_level = "disabled", warning = nil)
api_key ||= "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
- response = [api_key, 200, "OK"]
- profile_response = [ "mfa: #{mfa_level}\nwarning: #{warning}" , 200, "OK"]
+ response = HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK")
+ profile_response = HTTPResponseFactory.create(body: "mfa: #{mfa_level}\nwarning: #{warning}", code: 200, msg: "OK")
email = "you@example.com"
password = "secret"
# Set the expected response for the Web-API supplied
ENV["RUBYGEMS_HOST"] = host || Gem::DEFAULT_HOST
- data_key = "#{ENV['RUBYGEMS_HOST']}/api/v1/api_key"
+ data_key = "#{ENV["RUBYGEMS_HOST"]}/api/v1/api_key"
fetcher.data[data_key] = response
- profile = "#{ENV['RUBYGEMS_HOST']}/api/v1/profile/me.yaml"
+ profile = "#{ENV["RUBYGEMS_HOST"]}/api/v1/profile/me.yaml"
fetcher.data[profile] = profile_response
Gem::RemoteFetcher.fetcher = fetcher
- sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n")
+ sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n\n\n")
use_ui sign_in_ui do
yield
diff --git a/test/rubygems/test_gem_commands_signout_command.rb b/test/rubygems/test_gem_commands_signout_command.rb
index 992b127a94..999a14080f 100644
--- a/test/rubygems/test_gem_commands_signout_command.rb
+++ b/test/rubygems/test_gem_commands_signout_command.rb
@@ -12,12 +12,12 @@ class TestGemCommandsSignoutCommand < Gem::TestCase
def test_execute_when_user_is_signed_in
FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path)
- FileUtils::touch Gem.configuration.credentials_path
+ FileUtils.touch Gem.configuration.credentials_path
@sign_out_ui = Gem::MockGemUi.new
use_ui(@sign_out_ui) { @cmd.execute }
- assert_match %r{You have successfully signed out}, @sign_out_ui.output
+ assert_match(/You have successfully signed out/, @sign_out_ui.output)
assert_equal false, File.exist?(Gem.configuration.credentials_path)
end
@@ -25,6 +25,6 @@ class TestGemCommandsSignoutCommand < Gem::TestCase
@sign_out_ui = Gem::MockGemUi.new
use_ui(@sign_out_ui) { @cmd.execute }
- assert_match %r{You are not currently signed in}, @sign_out_ui.error
+ assert_match(/You are not currently signed in/, @sign_out_ui.error)
end
end
diff --git a/test/rubygems/test_gem_commands_sources_command.rb b/test/rubygems/test_gem_commands_sources_command.rb
index b7c164c0e6..5e675e5c84 100644
--- a/test/rubygems/test_gem_commands_sources_command.rb
+++ b/test/rubygems/test_gem_commands_sources_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/sources_command"
diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb
index 7564baa2ca..454d6ea1c6 100644
--- a/test/rubygems/test_gem_commands_specification_command.rb
+++ b/test/rubygems/test_gem_commands_specification_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/specification_command"
@@ -20,8 +21,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{Gem::Specification}, @ui.output
- assert_match %r{name: foo}, @ui.output
+ assert_match(/Gem::Specification/, @ui.output)
+ assert_match(/name: foo/, @ui.output)
assert_equal "", @ui.error
end
@@ -36,10 +37,10 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{Gem::Specification}, @ui.output
- assert_match %r{name: foo}, @ui.output
- assert_match %r{version: 0.0.1}, @ui.output
- assert_match %r{version: 0.0.2}, @ui.output
+ assert_match(/Gem::Specification/, @ui.output)
+ assert_match(/name: foo/, @ui.output)
+ assert_match(/version: 0.0.1/, @ui.output)
+ assert_match(/version: 0.0.2/, @ui.output)
assert_equal "", @ui.error
end
@@ -98,8 +99,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{Gem::Specification}, @ui.output
- assert_match %r{name: foo}, @ui.output
+ assert_match(/Gem::Specification/, @ui.output)
+ assert_match(/name: foo/, @ui.output)
assert_equal "", @ui.error
end
@@ -130,8 +131,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{Gem::Specification}, @ui.output
- assert_match %r{name: foo}, @ui.output
+ assert_match(/Gem::Specification/, @ui.output)
+ assert_match(/name: foo/, @ui.output)
assert_equal "", @ui.error
end
@@ -164,7 +165,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end
assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output
- assert_match %r{name: foo}, @ui.output
+ assert_match(/name: foo/, @ui.output)
end
def test_execute_remote_with_version
@@ -228,7 +229,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end
assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output
- assert_match %r{name: foo}, @ui.output
+ assert_match(/name: foo/, @ui.output)
spec = load_yaml @ui.output
@@ -250,7 +251,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
end
assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output
- assert_match %r{name: foo}, @ui.output
+ assert_match(/name: foo/, @ui.output)
spec = load_yaml @ui.output
@@ -269,8 +270,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase
@cmd.execute
end
- assert_match %r{Gem::Specification.new}, @ui.output
- assert_match %r{s.name = "foo"}, @ui.output
+ assert_match(/Gem::Specification.new/, @ui.output)
+ assert_match(/s.name = "foo"/, @ui.output)
assert_equal "", @ui.error
end
end
diff --git a/test/rubygems/test_gem_commands_stale_command.rb b/test/rubygems/test_gem_commands_stale_command.rb
index 99eb23fb30..ea7493b418 100644
--- a/test/rubygems/test_gem_commands_stale_command.rb
+++ b/test/rubygems/test_gem_commands_stale_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/stale_command"
@@ -24,11 +25,11 @@ class TestGemCommandsStaleCommand < Gem::TestCase
files.each do |file|
filename = File.join(bar_baz.full_gem_path, file)
FileUtils.mkdir_p File.dirname filename
- FileUtils.touch(filename, :mtime => Time.now)
+ FileUtils.touch(filename, mtime: Time.now)
filename = File.join(foo_bar.full_gem_path, file)
FileUtils.mkdir_p File.dirname filename
- FileUtils.touch(filename, :mtime => Time.now - 86400)
+ FileUtils.touch(filename, mtime: Time.now - 86_400)
end
use_ui @stub_ui do
diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb
index 083b831c98..4daa61cb0c 100644
--- a/test/rubygems/test_gem_commands_uninstall_command.rb
+++ b/test/rubygems/test_gem_commands_uninstall_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "installer_test_case"
require "rubygems/commands/uninstall_command"
@@ -20,14 +21,9 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
gemhome2 = "#{@gemhome}2"
a_4, = util_gem "a", 4
- install_gem a_4, :install_dir => gemhome2
-
- Gem::Specification.dirs = [@gemhome, gemhome2]
+ install_gem a_4, install_dir: gemhome2
- assert_includes Gem::Specification.all_names, "a-1"
- assert_includes Gem::Specification.all_names, "a-4"
- assert_includes Gem::Specification.all_names, "b-2"
- assert_includes Gem::Specification.all_names, "default-1"
+ assert_gems_presence "a-1", "a-4", "b-2", "default-1", dirs: [@gemhome, gemhome2]
@cmd.options[:all] = true
@cmd.options[:args] = %w[a]
@@ -118,7 +114,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
def test_execute_removes_executable
initial_install
- if win_platform?
+ if Gem.win_platform?
assert File.exist?(@executable)
else
assert File.symlink?(@executable)
@@ -162,7 +158,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
@cmd.execute
assert_equal false, File.exist?(formatted_executable)
- rescue
+ rescue StandardError
Gem::Installer.exec_format = nil
end
@@ -233,6 +229,26 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
assert File.exist? File.join(@gemhome, "bin", "executable")
end
+ def test_execute_with_multiple_version_specified_as_colon
+ initial_install
+
+ ui = Gem::MockGemUi.new "y\n"
+
+ util_make_gems
+
+ assert_equal 3, Gem::Specification.find_all_by_name("a").length
+
+ @cmd.options[:force] = true
+ @cmd.options[:args] = ["a:1", "a:2"]
+
+ use_ui ui do
+ @cmd.execute
+ end
+
+ assert_equal 1, Gem::Specification.find_all_by_name("a").length
+ assert_equal Gem::Version.new("3.a"), Gem::Specification.find_by_name("a").version
+ end
+
def test_uninstall_selection
ui = Gem::MockGemUi.new "1\n"
@@ -346,11 +362,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
a_4, = util_gem "a", 4
install_gem a_4
- Gem::Specification.dirs = [@gemhome, gemhome2]
-
- assert_includes Gem::Specification.all_names, "a-1"
- assert_includes Gem::Specification.all_names, "a-4"
- assert_includes Gem::Specification.all_names, "default-1"
+ assert_gems_presence "a-1", "a-4", "default-1", dirs: [@gemhome, gemhome2]
@cmd.options[:all] = true
@cmd.options[:args] = []
@@ -369,11 +381,9 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
gemhome2 = "#{@gemhome}2"
a_4, = util_gem "a", 4
- install_gem a_4 , :install_dir => gemhome2
+ install_gem a_4, install_dir: gemhome2
- Gem::Specification.dirs = [@gemhome, gemhome2]
-
- assert_includes Gem::Specification.all_names, "a-4"
+ assert_gems_presence "a-4", dirs: [@gemhome, gemhome2]
@cmd.options[:args] = ["a:4"]
@@ -386,6 +396,26 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
assert_includes e.message, "a is not installed in GEM_HOME"
end
+ def test_execute_outside_gem_home_when_install_dir_given
+ gemhome2 = "#{@gemhome}2"
+
+ a_4, = util_gem "a", 4
+ install_gem a_4, install_dir: gemhome2
+
+ assert_gems_presence "a-4", dirs: [@gemhome, gemhome2]
+
+ Gem::Specification.dirs = [@gemhome]
+
+ @cmd.options[:install_dir] = gemhome2
+ @cmd.options[:args] = ["a:4"]
+
+ @cmd.execute
+
+ Gem::Specification.dirs = [gemhome2]
+
+ refute_includes Gem::Specification.all_names.sort, "a-4"
+ end
+
def test_handle_options
@cmd.handle_options %w[]
@@ -486,7 +516,7 @@ WARNING: Use your OS package manager to uninstall vendor gems
end
assert_empty @ui.output
- assert_match %r{Error: unable to successfully uninstall '#{@spec.name}'}, @ui.error
+ assert_match(/Error: unable to successfully uninstall '#{@spec.name}'/, @ui.error)
end
private
@@ -501,4 +531,12 @@ WARNING: Use your OS package manager to uninstall vendor gems
end
end
end
+
+ def assert_gems_presence(*gems, dirs:)
+ Gem::Specification.dirs = dirs
+
+ gems.each do |full_name|
+ assert_includes Gem::Specification.all_names, full_name
+ end
+ end
end
diff --git a/test/rubygems/test_gem_commands_unpack_command.rb b/test/rubygems/test_gem_commands_unpack_command.rb
index 1d9d0b6bd0..61cf8a611a 100644
--- a/test/rubygems/test_gem_commands_unpack_command.rb
+++ b/test/rubygems/test_gem_commands_unpack_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/unpack_command"
@@ -15,7 +16,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
util_make_gems
assert_equal(
- @cmd.find_in_cache(File.basename @a1.cache_file),
+ @cmd.find_in_cache(File.basename(@a1.cache_file)),
@a1.cache_file,
"found a-1.gem in the cache"
)
@@ -151,11 +152,11 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
end
def test_execute_sudo
- pend "Cannot perform this test on windows (chmod)" if win_platform?
+ pend "Cannot perform this test on windows (chmod)" if Gem.win_platform?
util_make_gems
- FileUtils.chmod 0555, @gemhome
+ FileUtils.chmod 0o555, @gemhome
@cmd.options[:args] = %w[b]
@@ -167,7 +168,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase
assert File.exist?(File.join(@tempdir, "b-2")), "b should be unpacked"
ensure
- FileUtils.chmod 0755, @gemhome
+ FileUtils.chmod 0o755, @gemhome
end
def test_execute_with_target_option
diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb
index 58bc7576da..2683840f2e 100644
--- a/test/rubygems/test_gem_commands_update_command.rb
+++ b/test/rubygems/test_gem_commands_update_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/update_command"
@@ -78,7 +79,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
out = @ui.output.split "\n"
- assert_equal "Updating rubygems-update", out.shift
assert_equal "Installing RubyGems 9", out.shift
assert_equal "RubyGems system software updated", out.shift
@@ -122,7 +122,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
out = @ui.output.split "\n"
- assert_equal "Updating rubygems-update", out.shift
assert_empty out
err = @ui.error.split "\n"
@@ -131,6 +130,34 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
assert_empty err
end
+ def test_execute_system_when_latest_does_not_support_your_ruby_but_previous_one_does
+ spec_fetcher do |fetcher|
+ fetcher.download "rubygems-update", 9 do |s|
+ s.files = %w[setup.rb]
+ s.required_ruby_version = "> 9"
+ end
+
+ fetcher.download "rubygems-update", 8 do |s|
+ s.files = %w[setup.rb]
+ end
+ end
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ err = @ui.error.split "\n"
+ assert_empty err
+
+ out = @ui.output.split "\n"
+ assert_equal "Installing RubyGems 8", out.shift
+ assert_equal "RubyGems system software updated", out.shift
+ assert_empty out
+ end
+
def test_execute_system_multiple
spec_fetcher do |fetcher|
fetcher.download "rubygems-update", 8 do |s|
@@ -150,7 +177,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
out = @ui.output.split "\n"
- assert_equal "Updating rubygems-update", out.shift
assert_equal "Installing RubyGems 9", out.shift
assert_equal "RubyGems system software updated", out.shift
@@ -184,7 +210,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
out = @ui.output.split "\n"
- assert_equal "Updating rubygems-update", out.shift
assert_equal "Installing RubyGems 9", out.shift
assert_equal "RubyGems system software updated", out.shift
@@ -204,7 +229,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
gemhome2 = "#{@gemhome}2"
- Gem::Installer.at(rubygems_update_package, :install_dir => gemhome2).install
+ Gem::Installer.at(rubygems_update_package, install_dir: gemhome2).install
Gem.use_paths @gemhome, [gemhome2, @gemhome]
@@ -241,7 +266,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
out = @ui.output.split "\n"
- assert_equal "Updating rubygems-update", out.shift
assert_equal "Installing RubyGems 8", out.shift
assert_equal "RubyGems system software updated", out.shift
@@ -352,7 +376,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
end
out = @ui.output.split "\n"
- assert_equal "Updating rubygems-update", out.shift
assert_equal "Installing RubyGems 9", out.shift
assert_equal "RubyGems system software updated", out.shift
@@ -669,10 +692,10 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
@cmd.handle_options %w[--system]
expected = {
- :args => [],
- :document => %w[ri],
- :force => false,
- :system => true,
+ args: [],
+ document: %w[ri],
+ force: false,
+ system: true,
}
assert_equal expected, @cmd.options
@@ -688,10 +711,10 @@ class TestGemCommandsUpdateCommand < Gem::TestCase
@cmd.handle_options %w[--system 1.3.7]
expected = {
- :args => [],
- :document => %w[ri],
- :force => false,
- :system => "1.3.7",
+ args: [],
+ document: %w[ri],
+ force: false,
+ system: "1.3.7",
}
assert_equal expected, @cmd.options
diff --git a/test/rubygems/test_gem_commands_which_command.rb b/test/rubygems/test_gem_commands_which_command.rb
index 46e95bf619..cbd5b5ef14 100644
--- a/test/rubygems/test_gem_commands_which_command.rb
+++ b/test/rubygems/test_gem_commands_which_command.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/commands/which_command"
@@ -32,8 +33,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
assert_equal "", @ui.output
- assert_match %r{Can.t find Ruby library file or shared library directory\n},
- @ui.error
+ assert_match(/Can.t find Ruby library file or shared library directory\n/,
+ @ui.error)
end
def test_execute_one_missing
@@ -50,8 +51,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
- assert_match %r{Can.t find Ruby library file or shared library missinglib\n},
- @ui.error
+ assert_match(/Can.t find Ruby library file or shared library missinglib\n/,
+ @ui.error)
end
def test_execute_missing
@@ -64,8 +65,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase
end
assert_equal "", @ui.output
- assert_match %r{Can.t find Ruby library file or shared library missinglib\n},
- @ui.error
+ assert_match(/Can.t find Ruby library file or shared library missinglib\n/,
+ @ui.error)
end
def util_foo_bar
diff --git a/test/rubygems/test_gem_commands_yank_command.rb b/test/rubygems/test_gem_commands_yank_command.rb
index 878b52416e..eb78e3a542 100644
--- a/test/rubygems/test_gem_commands_yank_command.rb
+++ b/test/rubygems/test_gem_commands_yank_command.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+
require_relative "helper"
+require_relative "multifactor_auth_utilities"
require "rubygems/commands/yank_command"
class TestGemCommandsYankCommand < Gem::TestCase
@@ -11,7 +13,8 @@ class TestGemCommandsYankCommand < Gem::TestCase
@cmd = Gem::Commands::YankCommand.new
@cmd.options[:host] = "http://example"
- @fetcher = Gem::RemoteFetcher.fetcher
+ @fetcher = Gem::MultifactorAuthFetcher.new(host: "http://example")
+ Gem::RemoteFetcher.fetcher = @fetcher
Gem.configuration.rubygems_api_key = "key"
Gem.configuration.api_keys[:KEY] = "other"
@@ -43,7 +46,7 @@ class TestGemCommandsYankCommand < Gem::TestCase
def test_execute
yank_uri = "http://example/api/v1/gems/yank"
- @fetcher.data[yank_uri] = ["Successfully yanked", 200, "OK"]
+ @fetcher.data[yank_uri] = HTTPResponseFactory.create(body: "Successfully yanked", code: 200, msg: "OK")
@cmd.options[:args] = %w[a]
@cmd.options[:added_platform] = true
@@ -54,7 +57,7 @@ class TestGemCommandsYankCommand < Gem::TestCase
end
assert_match %r{Yanking gem from http://example}, @ui.output
- assert_match %r{Successfully yanked}, @ui.output
+ assert_match(/Successfully yanked/, @ui.output)
platform = Gem.platforms[1]
body = @fetcher.last_request.body.split("&").sort
@@ -69,8 +72,8 @@ class TestGemCommandsYankCommand < Gem::TestCase
response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
yank_uri = "http://example/api/v1/gems/yank"
@fetcher.data[yank_uri] = [
- [response_fail, 401, "Unauthorized"],
- ["Successfully yanked", 200, "OK"],
+ HTTPResponseFactory.create(body: response_fail, code: 401, msg: "Unauthorized"),
+ HTTPResponseFactory.create(body: "Successfully yanked", code: 200, msg: "OK"),
]
@cmd.options[:args] = %w[a]
@@ -85,14 +88,14 @@ class TestGemCommandsYankCommand < Gem::TestCase
assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output
assert_match "Code: ", @otp_ui.output
assert_match %r{Yanking gem from http://example}, @otp_ui.output
- assert_match %r{Successfully yanked}, @otp_ui.output
+ assert_match(/Successfully yanked/, @otp_ui.output)
assert_equal "111111", @fetcher.last_request["OTP"]
end
def test_execute_with_otp_failure
response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
yank_uri = "http://example/api/v1/gems/yank"
- @fetcher.data[yank_uri] = [response, 401, "Unauthorized"]
+ @fetcher.data[yank_uri] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
@cmd.options[:args] = %w[a]
@cmd.options[:added_platform] = true
@@ -109,9 +112,125 @@ class TestGemCommandsYankCommand < Gem::TestCase
assert_equal "111111", @fetcher.last_request["OTP"]
end
+ def test_with_webauthn_enabled_success
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("http://example/api/v1/gems/yank", "Successfully yanked")
+ @fetcher.respond_with_webauthn_url
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:added_platform] = true
+ @cmd.options[:version] = req("= 1.0")
+
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+ end
+
+ assert_match %r{Yanking gem from http://example}, @ui.output
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
+ assert_match "Successfully yanked", @ui.output
+ end
+
+ def test_with_webauthn_enabled_failure
+ server = Gem::MockTCPServer.new
+ error = Gem::WebauthnVerificationError.new("Something went wrong")
+
+ @fetcher.respond_with_require_otp("http://example/api/v1/gems/yank", "Successfully yanked")
+ @fetcher.respond_with_webauthn_url
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:added_platform] = true
+ @cmd.options[:version] = req("= 1.0")
+
+ error = assert_raise Gem::MockGemUi::TermError do
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+ end
+ end
+ assert_equal 1, error.exit_code
+
+ assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
+ assert_match %r{Yanking gem from http://example}, @ui.output
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @ui.output
+ refute_match "Successfully yanked", @ui.output
+ end
+
+ def test_with_webauthn_enabled_success_with_polling
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("http://example/api/v1/gems/yank", "Successfully yanked")
+ @fetcher.respond_with_webauthn_url
+ @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:added_platform] = true
+ @cmd.options[:version] = req("= 1.0")
+
+ TCPServer.stub(:new, server) do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_match %r{Yanking gem from http://example}, @ui.output
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
+ assert_match "Successfully yanked", @ui.output
+ end
+
+ def test_with_webauthn_enabled_failure_with_polling
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp("http://example/api/v1/gems/yank", "Successfully yanked")
+ @fetcher.respond_with_webauthn_url
+ @fetcher.respond_with_webauthn_polling_failure
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:added_platform] = true
+ @cmd.options[:version] = req("= 1.0")
+
+ error = assert_raise Gem::MockGemUi::TermError do
+ TCPServer.stub(:new, server) do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+ end
+ assert_equal 1, error.exit_code
+
+ assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key
+ assert_match %r{Yanking gem from http://example}, @ui.output
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output
+ assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \
+ "or been used already.", @ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @ui.output
+ refute_match "Successfully yanked", @ui.output
+ end
+
def test_execute_key
yank_uri = "http://example/api/v1/gems/yank"
- @fetcher.data[yank_uri] = ["Successfully yanked", 200, "OK"]
+ @fetcher.data[yank_uri] = HTTPResponseFactory.create(body: "Successfully yanked", code: 200, msg: "OK")
@cmd.options[:args] = %w[a]
@cmd.options[:version] = req("= 1.0")
@@ -129,7 +248,7 @@ class TestGemCommandsYankCommand < Gem::TestCase
def test_execute_host
host = "https://other.example"
yank_uri = "#{host}/api/v1/gems/yank"
- @fetcher.data[yank_uri] = ["Successfully yanked", 200, "OK"]
+ @fetcher.data[yank_uri] = HTTPResponseFactory.create(body: "Successfully yanked", code: 200, msg: "OK")
@cmd.options[:args] = %w[a]
@cmd.options[:version] = req("= 1.0")
@@ -140,7 +259,7 @@ class TestGemCommandsYankCommand < Gem::TestCase
end
assert_match %r{Yanking gem from https://other.example}, @ui.output
- assert_match %r{Successfully yanked}, @ui.output
+ assert_match(/Successfully yanked/, @ui.output)
body = @fetcher.last_request.body.split("&").sort
assert_equal %w[gem_name=a version=1.0], body
@@ -154,11 +273,11 @@ class TestGemCommandsYankCommand < Gem::TestCase
host = "http://example"
@fetcher.data["#{host}/api/v1/gems/yank"] = [
- [response_forbidden, 403, "Forbidden"],
- [response_success, 200, "OK"],
+ HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"),
+ HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"),
]
- @fetcher.data["#{host}/api/v1/api_key"] = ["", 200, "OK"]
+ @fetcher.data["#{host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK")
@cmd.options[:args] = %w[a]
@cmd.options[:added_platform] = true
@cmd.options[:version] = req("= 1.0")
@@ -172,7 +291,7 @@ class TestGemCommandsYankCommand < Gem::TestCase
access_notice = "The existing key doesn't have access of yank_rubygem on http://example. Please sign in to update access."
assert_match access_notice, @ui.output
- assert_match "Email:", @ui.output
+ assert_match "Username/email:", @ui.output
assert_match "Password:", @ui.output
assert_match "Added yank_rubygem scope to the existing API key", @ui.output
assert_match response_success, @ui.output
diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb
index e23773a133..a055f248be 100644
--- a/test/rubygems/test_gem_config_file.rb
+++ b/test/rubygems/test_gem_config_file.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/config_file"
@@ -57,6 +58,7 @@ class TestGemConfigFile < Gem::TestCase
fp.puts ":ssl_verify_mode: 0"
fp.puts ":ssl_ca_cert: /etc/ssl/certs"
fp.puts ":cert_expiration_length_days: 28"
+ fp.puts ":install_extension_in_lib: true"
fp.puts ":ipv4_fallback_enabled: true"
end
@@ -72,6 +74,7 @@ class TestGemConfigFile < Gem::TestCase
assert_equal 0, @cfg.ssl_verify_mode
assert_equal "/etc/ssl/certs", @cfg.ssl_ca_cert
assert_equal 28, @cfg.cert_expiration_length_days
+ assert_equal true, @cfg.install_extension_in_lib
assert_equal true, @cfg.ipv4_fallback_enabled
end
@@ -184,22 +187,22 @@ class TestGemConfigFile < Gem::TestCase
temp_cred = File.join Gem.user_home, ".gem", "credentials"
FileUtils.mkdir_p File.dirname(temp_cred)
- File.open temp_cred, "w", 0600 do |fp|
+ File.open temp_cred, "w", 0o600 do |fp|
fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
end
util_config_file
- assert_equal({ :rubygems => "701229f217cdf23b1344c7b4b54ca97" },
+ assert_equal({ rubygems: "701229f217cdf23b1344c7b4b54ca97" },
@cfg.api_keys)
end
def test_check_credentials_permissions
- pend "chmod not supported" if win_platform?
+ pend "chmod not supported" if Gem.win_platform?
@cfg.rubygems_api_key = "x"
- File.chmod 0644, @cfg.credentials_path
+ File.chmod 0o644, @cfg.credentials_path
use_ui @ui do
assert_raise Gem::MockGemUi::TermError do
@@ -322,23 +325,28 @@ if you believe they were disclosed to a third party.
def test_load_api_keys
temp_cred = File.join Gem.user_home, ".gem", "credentials"
FileUtils.mkdir_p File.dirname(temp_cred)
- File.open temp_cred, "w", 0600 do |fp|
- fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
- fp.puts ":other: a5fdbb6ba150cbb83aad2bb2fede64c"
+ File.open temp_cred, "w", 0o600 do |fp|
+ fp.puts ":rubygems_api_key: rubygems_b9ce70c306b3a2e248679fbbbd66722d408d3c8c4f00566c"
+ fp.puts ":other: rubygems_9636a120106ea8b81fbc792188251738665711d2ece160c5"
+ fp.puts "http://localhost:3000: rubygems_be293ad9dd71550a012b17d848893b41960b811ce9312b47"
end
util_config_file
- assert_equal({ :rubygems => "701229f217cdf23b1344c7b4b54ca97",
- :other => "a5fdbb6ba150cbb83aad2bb2fede64c" }, @cfg.api_keys)
+ assert_equal(
+ { :rubygems => "rubygems_b9ce70c306b3a2e248679fbbbd66722d408d3c8c4f00566c",
+ :other => "rubygems_9636a120106ea8b81fbc792188251738665711d2ece160c5",
+ "http://localhost:3000" => "rubygems_be293ad9dd71550a012b17d848893b41960b811ce9312b47" },
+ @cfg.api_keys
+ )
end
def test_load_api_keys_bad_permission
- pend "chmod not supported" if win_platform?
+ pend "chmod not supported" if Gem.win_platform?
@cfg.rubygems_api_key = "x"
- File.chmod 0644, @cfg.credentials_path
+ File.chmod 0o644, @cfg.credentials_path
assert_raise Gem::MockGemUi::TermError do
@cfg.load_api_keys
@@ -363,38 +371,38 @@ if you believe they were disclosed to a third party.
assert_equal "x", @cfg.rubygems_api_key
expected = {
- :rubygems_api_key => "x",
+ rubygems_api_key: "x",
}
assert_equal expected, load_yaml_file(@cfg.credentials_path)
- unless win_platform?
+ unless Gem.win_platform?
stat = File.stat @cfg.credentials_path
- assert_equal 0600, stat.mode & 0600
+ assert_equal 0o600, stat.mode & 0o600
end
end
def test_rubygems_api_key_equals_bad_permission
- pend "chmod not supported" if win_platform?
+ pend "chmod not supported" if Gem.win_platform?
@cfg.rubygems_api_key = "x"
- File.chmod 0644, @cfg.credentials_path
+ File.chmod 0o644, @cfg.credentials_path
assert_raise Gem::MockGemUi::TermError do
@cfg.rubygems_api_key = "y"
end
expected = {
- :rubygems_api_key => "x",
+ rubygems_api_key: "x",
}
assert_equal expected, load_yaml_file(@cfg.credentials_path)
stat = File.stat @cfg.credentials_path
- assert_equal 0644, stat.mode & 0644
+ assert_equal 0o644, stat.mode & 0o644
end
def test_write
@@ -470,7 +478,8 @@ if you believe they were disclosed to a third party.
end
begin
- verbose, $VERBOSE = $VERBOSE, nil
+ verbose = $VERBOSE
+ $VERBOSE = nil
util_config_file
ensure
@@ -478,6 +487,16 @@ if you believe they were disclosed to a third party.
end
end
+ def test_accept_string_key
+ File.open @temp_conf, "w" do |fp|
+ fp.puts "verbose: false"
+ end
+
+ util_config_file
+
+ assert_equal false, @cfg.verbose
+ end
+
def test_load_ssl_verify_mode_from_config
File.open @temp_conf, "w" do |fp|
fp.puts ":ssl_verify_mode: 1"
@@ -502,8 +521,12 @@ if you believe they were disclosed to a third party.
assert_equal("/home/me/mine.pem", @cfg.ssl_client_cert)
end
- def util_config_file(args = @cfg_args)
- @cfg = Gem::ConfigFile.new args
+ def test_load_install_extension_in_lib_from_config
+ File.open @temp_conf, "w" do |fp|
+ fp.puts ":install_extension_in_lib: false"
+ end
+ util_config_file
+ assert_equal(false, @cfg.install_extension_in_lib)
end
def test_disable_default_gem_server
@@ -513,4 +536,46 @@ if you believe they were disclosed to a third party.
util_config_file
assert_equal(true, @cfg.disable_default_gem_server)
end
+
+ def test_load_with_rubygems_config_hash
+ yaml = <<~YAML
+ ---
+ :foo: bar
+ bar: 100
+ buzz: true
+ alpha: :bravo
+ charlie: ""
+ delta:
+ YAML
+ actual = Gem::ConfigFile.load_with_rubygems_config_hash(yaml)
+
+ assert_equal "bar", actual[:foo]
+ assert_equal 100, actual["bar"]
+ assert_equal true, actual["buzz"]
+ assert_equal :bravo, actual["alpha"]
+ assert_equal nil, actual["charlie"]
+ assert_equal nil, actual["delta"]
+ end
+
+ def test_dump_with_rubygems_yaml
+ symbol_key_hash = { foo: "bar" }
+
+ actual = Gem::ConfigFile.dump_with_rubygems_yaml(symbol_key_hash)
+
+ assert_equal("---\n:foo: \"bar\"\n", actual)
+ end
+
+ def test_handle_comment
+ yaml = <<~YAML
+ ---
+ :foo: bar # buzz
+ YAML
+
+ actual = Gem::ConfigFile.load_with_rubygems_config_hash(yaml)
+ assert_equal("bar", actual[:foo])
+ end
+
+ def util_config_file(args = @cfg_args)
+ @cfg = Gem::ConfigFile.new args
+ end
end
diff --git a/test/rubygems/test_gem_console_ui.rb b/test/rubygems/test_gem_console_ui.rb
new file mode 100644
index 0000000000..b8a619625f
--- /dev/null
+++ b/test/rubygems/test_gem_console_ui.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems/user_interaction"
+
+class TestGemConsoleUI < Gem::TestCase
+ def test_output_can_be_captured_by_test_unit
+ output = capture_output do
+ ui = Gem::ConsoleUI.new
+
+ ui.alert_error "test error"
+ ui.alert_warning "test warning"
+ ui.alert "test alert"
+ end
+
+ assert_equal "INFO: test alert\n", output.first
+ assert_equal "ERROR: test error\n" + "WARNING: test warning\n", output.last
+ end
+end
diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb
index c585e87087..2a989a5551 100644
--- a/test/rubygems/test_gem_dependency.rb
+++ b/test/rubygems/test_gem_dependency.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/dependency"
@@ -105,8 +106,13 @@ class TestGemDependency < Gem::TestCase
def test_equals_tilde_object
o = Object.new
- def o.name ; "a" end
- def o.version ; "0" end
+ def o.name
+ "a"
+ end
+
+ def o.version
+ "0"
+ end
assert_match dep("a"), o
end
@@ -358,6 +364,8 @@ class TestGemDependency < Gem::TestCase
assert_equal [b, b_1], dep.to_specs
+ require "rubygems/bundler_version_finder"
+
Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("1")) do
assert_equal [b_1, b], dep.to_specs
end
@@ -386,6 +394,16 @@ class TestGemDependency < Gem::TestCase
assert_match "Could not find 'b' (= 2.0) among 1 total gem(s)", e.message
end
+ def test_to_spec_with_only_prereleases
+ a_2_a_1 = util_spec "a", "2.a1"
+ a_2_a_2 = util_spec "a", "2.a2"
+ install_specs a_2_a_1, a_2_a_2
+
+ a_dep = dep "a", ">= 1"
+
+ assert_equal a_2_a_2, a_dep.to_spec
+ end
+
def test_identity
assert_equal dep("a", "= 1").identity, :released
assert_equal dep("a", "= 1.a").identity, :complete
diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb
index 2b0b874b2d..8999723ba1 100644
--- a/test/rubygems/test_gem_dependency_installer.rb
+++ b/test/rubygems/test_gem_dependency_installer.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/dependency_installer"
require "rubygems/security"
@@ -74,7 +75,7 @@ class TestGemDependencyInstaller < Gem::TestCase
@fetcher.data["http://gems.example.com/gems/a-10.a.gem"] = p1a_data
dep = Gem::Dependency.new "a"
- inst = Gem::DependencyInstaller.new :prerelease => true
+ inst = Gem::DependencyInstaller.new prerelease: true
inst.install dep
assert_equal %w[a-10.a], Gem::Specification.map(&:full_name)
@@ -96,7 +97,7 @@ class TestGemDependencyInstaller < Gem::TestCase
dep = Gem::Dependency.new "a"
- inst = Gem::DependencyInstaller.new :prerelease => true
+ inst = Gem::DependencyInstaller.new prerelease: true
inst.install dep
assert_equal %w[a-1.b b-1.b c-1.1.b], Gem::Specification.map(&:full_name)
@@ -131,7 +132,7 @@ class TestGemDependencyInstaller < Gem::TestCase
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = p1a_data
dep = Gem::Dependency.new "a"
- inst = Gem::DependencyInstaller.new :prerelease => true
+ inst = Gem::DependencyInstaller.new prerelease: true
inst.install dep
assert_equal %w[a-1], Gem::Specification.map(&:full_name)
@@ -152,11 +153,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :ignore_dependencies => true
+ inst = Gem::DependencyInstaller.new ignore_dependencies: true
inst.install "b"
end
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name },
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name),
"sanity check"
Dir.chdir @tempdir do
@@ -164,7 +165,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "e"
end
- assert_equal %w[a-1 e-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 e-1], inst.installed_gems.map(&:full_name)
end
def test_install_cache_dir
@@ -177,11 +178,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir dir do
- inst = Gem::DependencyInstaller.new :cache_dir => @tempdir
+ inst = Gem::DependencyInstaller.new cache_dir: @tempdir
inst.install "b"
end
- assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
assert File.exist? File.join(@gemhome, "cache", @a1.file_name)
assert File.exist? File.join(@gemhome, "cache", @b1.file_name)
@@ -197,7 +198,7 @@ class TestGemDependencyInstaller < Gem::TestCase
Gem::Specification.reset
FileUtils.mv @a1_gem, @tempdir
- FileUtils.mv a2_gem, @tempdir # not in index
+ FileUtils.mv a2_gem, @tempdir # not in index
FileUtils.mv @b1_gem, @tempdir
inst = nil
@@ -206,7 +207,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "a", req("= 2")
end
- assert_equal %w[a-2], inst.installed_gems.map {|s| s.full_name },
+ assert_equal %w[a-2], inst.installed_gems.map(&:full_name),
"sanity check"
FileUtils.rm File.join(@tempdir, a2.file_name)
@@ -217,7 +218,7 @@ class TestGemDependencyInstaller < Gem::TestCase
end
assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name)
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
end
# This asserts that if a gem's dependency is satisfied by an
@@ -236,7 +237,7 @@ class TestGemDependencyInstaller < Gem::TestCase
Gem::Specification.reset
FileUtils.mv @a1_gem, @tempdir
- FileUtils.mv a2_gem, @tempdir # not in index
+ FileUtils.mv a2_gem, @tempdir # not in index
FileUtils.mv @b1_gem, @tempdir
FileUtils.mv a3_gem, @tempdir
@@ -254,7 +255,7 @@ class TestGemDependencyInstaller < Gem::TestCase
end
assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name)
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
end
def test_install_dependency
@@ -273,11 +274,11 @@ class TestGemDependencyInstaller < Gem::TestCase
FileUtils.mv @b1_gem, @tempdir
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new(:build_docs_in_background => false)
+ inst = Gem::DependencyInstaller.new(build_docs_in_background: false)
inst.install "b"
end
- assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
assert done_installing_ran, "post installs hook was not run"
end
@@ -293,11 +294,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new(:development => true)
+ inst = Gem::DependencyInstaller.new(development: true)
inst.install "b"
end
- assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map(&:full_name)
end
def test_install_dependency_development_deep
@@ -313,11 +314,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new(:development => true)
+ inst = Gem::DependencyInstaller.new(development: true)
inst.install "d"
end
- assert_equal %w[a-1 aa-1 b-1 c-1 d-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 aa-1 b-1 c-1 d-1], inst.installed_gems.map(&:full_name)
end
def test_install_dependency_development_shallow
@@ -333,11 +334,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new(:development => true, :dev_shallow => true)
+ inst = Gem::DependencyInstaller.new(development: true, dev_shallow: true)
inst.install "d"
end
- assert_equal %w[c-1 d-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[c-1 d-1], inst.installed_gems.map(&:full_name)
end
def test_install_dependency_existing
@@ -353,7 +354,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "b"
end
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
end
def test_install_dependency_existing_extension
@@ -390,7 +391,7 @@ class TestGemDependencyInstaller < Gem::TestCase
Dir.chdir pwd
end
- assert_equal %w[f-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[f-1], inst.installed_gems.map(&:full_name)
assert_path_exist e1.extension_dir
end
@@ -410,7 +411,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "f"
end
- assert_equal %w[f-2], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[f-2], inst.installed_gems.map(&:full_name)
end
def test_install_local
@@ -420,11 +421,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :domain => :local
+ inst = Gem::DependencyInstaller.new domain: :local
inst.install "a-1.gem"
end
- assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
end
def test_install_local_prerelease
@@ -434,11 +435,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :domain => :local
+ inst = Gem::DependencyInstaller.new domain: :local
inst.install "a-1.a.gem"
end
- assert_equal %w[a-1.a], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1.a], inst.installed_gems.map(&:full_name)
end
def test_install_local_dependency
@@ -450,11 +451,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :domain => :local
+ inst = Gem::DependencyInstaller.new domain: :local
inst.install "b-1.gem"
end
- assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
end
def test_install_local_dependency_installed
@@ -468,11 +469,45 @@ class TestGemDependencyInstaller < Gem::TestCase
Dir.chdir @tempdir do
Gem::Installer.at("a-1.gem").install
- inst = Gem::DependencyInstaller.new :domain => :local
+ inst = Gem::DependencyInstaller.new domain: :local
inst.install "b-1.gem"
end
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
+ end
+
+ def test_install_local_dependency_no_network_for_target_gem
+ a1, a1_gem = util_gem "a", "1"
+ _, b1_gem = util_gem "b", "1" do |s|
+ s.add_dependency "a"
+ end
+
+ util_setup_spec_fetcher(a1)
+
+ a1_data = Gem.read_binary(a1_gem)
+ @fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data
+
+ # compact index is available
+ compact_index_response = Gem::Net::HTTPResponse.new "1.1", 200, "OK"
+ compact_index_response.uri = Gem::URI("http://gems.example.com")
+ @fetcher.data["http://gems.example.com/"] = compact_index_response
+
+ # but private local gem not present there
+ @fetcher.data["http://gems.example.com/info/b"] =
+ proc do
+ raise "should not happen"
+ end
+
+ FileUtils.mv b1_gem, @tempdir
+
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install "b-1.gem"
+ end
+
+ assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
end
def test_install_local_subdir
@@ -481,11 +516,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :domain => :local
+ inst = Gem::DependencyInstaller.new domain: :local
inst.install "gems/a-1.gem"
end
- assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
end
def test_install_minimal_deps
@@ -507,19 +542,19 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :ignore_dependencies => true
+ inst = Gem::DependencyInstaller.new ignore_dependencies: true
inst.install "b", req("= 1")
end
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name },
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name),
"sanity check"
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :minimal_deps => true
+ inst = Gem::DependencyInstaller.new minimal_deps: true
inst.install "e"
end
- assert_equal %w[a-1 e-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 e-1], inst.installed_gems.map(&:full_name)
end
def test_install_no_minimal_deps
@@ -541,19 +576,19 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :ignore_dependencies => true
+ inst = Gem::DependencyInstaller.new ignore_dependencies: true
inst.install "b", req("= 1")
end
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name },
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name),
"sanity check"
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :minimal_deps => false
+ inst = Gem::DependencyInstaller.new minimal_deps: false
inst.install "e"
end
- assert_equal %w[a-1 b-2 e-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 b-2 e-1], inst.installed_gems.map(&:full_name)
end
def test_install_no_document
@@ -561,12 +596,12 @@ class TestGemDependencyInstaller < Gem::TestCase
done_installing_called = false
- Gem.done_installing do |dep_installer, specs|
+ Gem.done_installing do |dep_installer, _specs|
done_installing_called = true
assert_empty dep_installer.document
end
- inst = Gem::DependencyInstaller.new :domain => :local, :document => []
+ inst = Gem::DependencyInstaller.new domain: :local, document: []
inst.install @a1_gem
@@ -580,14 +615,14 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true, :format_executable => false
+ inst = Gem::DependencyInstaller.new env_shebang: true, wrappers: true, format_executable: false
inst.install "a"
end
env = "/\\S+/env" unless Gem.win_platform?
- assert_match %r{\A#!#{env} #{RbConfig::CONFIG['ruby_install_name']}\n},
- File.read(File.join(@gemhome, "bin", "a_bin"))
+ assert_match(/\A#!#{env} #{RbConfig::CONFIG["ruby_install_name"]}\n/,
+ File.read(File.join(@gemhome, "bin", "a_bin")))
end
def test_install_force
@@ -599,11 +634,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :force => true
+ inst = Gem::DependencyInstaller.new force: true
inst.install "b"
end
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
end
def test_install_build_args
@@ -614,8 +649,7 @@ class TestGemDependencyInstaller < Gem::TestCase
build_args = %w[--a --b="c"]
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new(
- :build_args => build_args)
+ inst = Gem::DependencyInstaller.new(build_args: build_args)
inst.install "a"
end
@@ -629,11 +663,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :ignore_dependencies => true
+ inst = Gem::DependencyInstaller.new ignore_dependencies: true
inst.install "b"
end
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
end
def test_install_install_dir
@@ -650,11 +684,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :install_dir => gemhome2
+ inst = Gem::DependencyInstaller.new install_dir: gemhome2
inst.install "b"
end
- assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
assert File.exist?(File.join(gemhome2, "specifications", @a1.spec_name))
assert File.exist?(File.join(gemhome2, "cache", @a1.file_name))
@@ -674,11 +708,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :domain => :both
+ inst = Gem::DependencyInstaller.new domain: :both
inst.install "b"
end
- assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
a1, b1 = inst.installed_gems
assert_equal a1.spec_file, a1.loaded_from
@@ -698,11 +732,11 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :domain => :both
+ inst = Gem::DependencyInstaller.new domain: :both
inst.install "b"
end
- assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name)
end
def test_install_domain_local
@@ -713,7 +747,7 @@ class TestGemDependencyInstaller < Gem::TestCase
Dir.chdir @tempdir do
e = assert_raise Gem::UnsatisfiableDependencyError do
- inst = Gem::DependencyInstaller.new :domain => :local
+ inst = Gem::DependencyInstaller.new domain: :local
inst.install "b"
end
@@ -721,7 +755,7 @@ class TestGemDependencyInstaller < Gem::TestCase
assert_equal expected, e.message
end
- assert_equal [], inst.installed_gems.map {|s| s.full_name }
+ assert_equal [], inst.installed_gems.map(&:full_name)
end
def test_install_domain_remote
@@ -734,10 +768,10 @@ class TestGemDependencyInstaller < Gem::TestCase
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data
- inst = Gem::DependencyInstaller.new :domain => :remote
+ inst = Gem::DependencyInstaller.new domain: :remote
inst.install "a"
- assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
end
def test_install_dual_repository
@@ -750,11 +784,11 @@ class TestGemDependencyInstaller < Gem::TestCase
gemhome2 = "#{@gemhome}2"
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :install_dir => gemhome2
+ inst = Gem::DependencyInstaller.new install_dir: gemhome2
inst.install "a"
end
- assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name },
+ assert_equal %w[a-1], inst.installed_gems.map(&:full_name),
"sanity check"
ENV["GEM_HOME"] = @gemhome
@@ -766,7 +800,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "b"
end
- assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[b-1], inst.installed_gems.map(&:full_name)
end
def test_install_reinstall
@@ -777,7 +811,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = nil
Dir.chdir @tempdir do
- inst = Gem::DependencyInstaller.new :force => true
+ inst = Gem::DependencyInstaller.new force: true
inst.install "a"
end
@@ -801,7 +835,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install "a"
end
- assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
end
def test_install_remote_dep
@@ -821,7 +855,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst.install dep
end
- assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
end
def test_install_remote_platform_newer
@@ -851,10 +885,10 @@ class TestGemDependencyInstaller < Gem::TestCase
@fetcher.data["http://gems.example.com/gems/#{a2_o.file_name}"] =
a2_o_data
- inst = Gem::DependencyInstaller.new :domain => :remote
+ inst = Gem::DependencyInstaller.new domain: :remote
inst.install "a"
- assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1], inst.installed_gems.map(&:full_name)
end
def test_install_platform_is_ignored_when_a_file_is_specified
@@ -862,10 +896,10 @@ class TestGemDependencyInstaller < Gem::TestCase
s.platform = Gem::Platform.new %w[cpu other_platform 1]
end
- inst = Gem::DependencyInstaller.new :domain => :local
+ inst = Gem::DependencyInstaller.new domain: :local
inst.install a_gem
- assert_equal %w[a-1-cpu-other_platform-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[a-1-cpu-other_platform-1], inst.installed_gems.map(&:full_name)
end
require "rubygems/openssl"
@@ -874,14 +908,14 @@ class TestGemDependencyInstaller < Gem::TestCase
def test_install_security_policy
util_setup_gems
- data = File.open(@a1_gem, "rb") {|f| f.read }
+ data = File.open(@a1_gem, "rb", &:read)
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = data
- data = File.open(@b1_gem, "rb") {|f| f.read }
+ data = File.open(@b1_gem, "rb", &:read)
@fetcher.data["http://gems.example.com/gems/b-1.gem"] = data
policy = Gem::Security::HighSecurity
- inst = Gem::DependencyInstaller.new :security_policy => policy
+ inst = Gem::DependencyInstaller.new security_policy: policy
e = assert_raise Gem::Security::Exception do
inst.install "b"
@@ -890,21 +924,21 @@ class TestGemDependencyInstaller < Gem::TestCase
assert_equal "unsigned gems are not allowed by the High Security policy",
e.message
- assert_equal %w[], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[], inst.installed_gems.map(&:full_name)
end
end
# Wrappers don't work on mswin
- unless win_platform?
+ unless Gem.win_platform?
def test_install_no_wrappers
util_setup_gems
@fetcher.data["http://gems.example.com/gems/a-1.gem"] = read_binary(@a1_gem)
- inst = Gem::DependencyInstaller.new :wrappers => false, :format_executable => false
+ inst = Gem::DependencyInstaller.new wrappers: false, format_executable: false
inst.install "a"
- refute_match(%r{This file was generated by RubyGems.},
+ refute_match(/This file was generated by RubyGems./,
File.read(File.join(@gemhome, "bin", "a_bin")))
end
end
@@ -912,32 +946,32 @@ class TestGemDependencyInstaller < Gem::TestCase
def test_install_version
util_setup_d
- data = File.open(@d2_gem, "rb") {|f| f.read }
+ data = File.open(@d2_gem, "rb", &:read)
@fetcher.data["http://gems.example.com/gems/d-2.gem"] = data
- data = File.open(@d1_gem, "rb") {|f| f.read }
+ data = File.open(@d1_gem, "rb", &:read)
@fetcher.data["http://gems.example.com/gems/d-1.gem"] = data
inst = Gem::DependencyInstaller.new
inst.install "d", "= 1"
- assert_equal %w[d-1], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[d-1], inst.installed_gems.map(&:full_name)
end
def test_install_version_default
util_setup_d
- data = File.open(@d2_gem, "rb") {|f| f.read }
+ data = File.open(@d2_gem, "rb", &:read)
@fetcher.data["http://gems.example.com/gems/d-2.gem"] = data
- data = File.open(@d1_gem, "rb") {|f| f.read }
+ data = File.open(@d1_gem, "rb", &:read)
@fetcher.data["http://gems.example.com/gems/d-1.gem"] = data
inst = Gem::DependencyInstaller.new
inst.install "d"
- assert_equal %w[d-2], inst.installed_gems.map {|s| s.full_name }
+ assert_equal %w[d-2], inst.installed_gems.map(&:full_name)
end
def test_install_legacy_spec_with_nil_required_ruby_version
@@ -1110,7 +1144,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = Gem::DependencyInstaller.new
request_set = inst.resolve_dependencies "b", req(">= 0")
- requests = request_set.sorted_requests.map {|req| req.full_name }
+ requests = request_set.sorted_requests.map(&:full_name)
assert_equal %w[a-1 b-1], requests
end
@@ -1121,10 +1155,10 @@ class TestGemDependencyInstaller < Gem::TestCase
FileUtils.mv @a1_gem, @tempdir
FileUtils.mv @b1_gem, @tempdir
- inst = Gem::DependencyInstaller.new :ignore_dependencies => true
+ inst = Gem::DependencyInstaller.new ignore_dependencies: true
request_set = inst.resolve_dependencies "b", req(">= 0")
- requests = request_set.sorted_requests.map {|req| req.full_name }
+ requests = request_set.sorted_requests.map(&:full_name)
assert request_set.ignore_dependencies
@@ -1141,7 +1175,7 @@ class TestGemDependencyInstaller < Gem::TestCase
inst = Gem::DependencyInstaller.new
request_set = inst.resolve_dependencies "a-1.gem", req(">= 0")
- requests = request_set.sorted_requests.map {|req| req.full_name }
+ requests = request_set.sorted_requests.map(&:full_name)
assert_equal %w[a-1], requests
end
diff --git a/test/rubygems/test_gem_dependency_list.rb b/test/rubygems/test_gem_dependency_list.rb
index 0dca8f8c3a..590e042315 100644
--- a/test/rubygems/test_gem_dependency_list.rb
+++ b/test/rubygems/test_gem_dependency_list.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/dependency_list"
@@ -52,7 +53,7 @@ class TestGemDependencyList < Gem::TestCase
order = @deplist.dependency_order
- assert_equal %w[d-1 c-1 b-1 a-1], order.map {|s| s.full_name }
+ assert_equal %w[d-1 c-1 b-1 a-1], order.map(&:full_name)
end
def test_dependency_order_circle
@@ -61,7 +62,7 @@ class TestGemDependencyList < Gem::TestCase
order = @deplist.dependency_order
- assert_equal %w[b-1 c-1 a-1], order.map {|s| s.full_name }
+ assert_equal %w[b-1 c-1 a-1], order.map(&:full_name)
end
def test_dependency_order_development
@@ -79,7 +80,7 @@ class TestGemDependencyList < Gem::TestCase
order = deplist.dependency_order
- assert_equal %w[g-1 a-1 f-1 e-1], order.map {|s| s.full_name },
+ assert_equal %w[g-1 a-1 f-1 e-1], order.map(&:full_name),
"development on"
deplist2 = Gem::DependencyList.new
@@ -87,7 +88,7 @@ class TestGemDependencyList < Gem::TestCase
order = deplist2.dependency_order
- assert_equal %w[a-1 g-1 f-1 e-1], order.map {|s| s.full_name },
+ assert_equal %w[a-1 g-1 f-1 e-1], order.map(&:full_name),
"development off"
end
@@ -99,7 +100,7 @@ class TestGemDependencyList < Gem::TestCase
order = @deplist.dependency_order
- assert_equal %w[d-1 c-2 b-1 a-2 e-1], order.map {|s| s.full_name },
+ assert_equal %w[d-1 c-2 b-1 a-2 e-1], order.map(&:full_name),
"deps of trimmed specs not included"
end
@@ -108,7 +109,7 @@ class TestGemDependencyList < Gem::TestCase
order = @deplist.dependency_order
- assert_equal %w[c-2 a-1], order.map {|s| s.full_name }
+ assert_equal %w[c-2 a-1], order.map(&:full_name)
end
def test_find_name
diff --git a/test/rubygems/test_gem_dependency_resolution_error.rb b/test/rubygems/test_gem_dependency_resolution_error.rb
index 26b9e4ddc0..98a6b6b8fd 100644
--- a/test/rubygems/test_gem_dependency_resolution_error.rb
+++ b/test/rubygems/test_gem_dependency_resolution_error.rb
@@ -1,26 +1,25 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemDependencyResolutionError < Gem::TestCase
def setup
super
- @DR = Gem::Resolver
-
@spec = util_spec "a", 2
- @a1_req = @DR::DependencyRequest.new dep("a", "= 1"), nil
- @a2_req = @DR::DependencyRequest.new dep("a", "= 2"), nil
+ @a1_req = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil
+ @a2_req = Gem::Resolver::DependencyRequest.new dep("a", "= 2"), nil
- @activated = @DR::ActivationRequest.new @spec, @a2_req
+ @activated = Gem::Resolver::ActivationRequest.new @spec, @a2_req
- @conflict = @DR::Conflict.new @a1_req, @activated
+ @conflict = Gem::Resolver::Conflict.new @a1_req, @activated
@error = Gem::DependencyResolutionError.new @conflict
end
def test_message
- assert_match %r{^conflicting dependencies a \(= 1\) and a \(= 2\)$},
- @error.message
+ assert_match(/^conflicting dependencies a \(= 1\) and a \(= 2\)$/,
+ @error.message)
end
end
diff --git a/test/rubygems/test_gem_doctor.rb b/test/rubygems/test_gem_doctor.rb
index d26a6ee310..1bcdc39022 100644
--- a/test/rubygems/test_gem_doctor.rb
+++ b/test/rubygems/test_gem_doctor.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/doctor"
diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb
index 34d8903595..d5812da2aa 100644
--- a/test/rubygems/test_gem_ext_builder.rb
+++ b/test/rubygems/test_gem_ext_builder.rb
@@ -1,10 +1,13 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/ext"
require "rubygems/installer"
class TestGemExtBuilder < Gem::TestCase
def setup
+ @orig_destdir = ENV["DESTDIR"]
+ @orig_make = ENV["make"]
super
@ext = File.join @tempdir, "ext"
@@ -13,19 +16,15 @@ class TestGemExtBuilder < Gem::TestCase
FileUtils.mkdir_p @ext
FileUtils.mkdir_p @dest_path
- @orig_DESTDIR = ENV["DESTDIR"]
- @orig_make = ENV["make"]
-
@spec = util_spec "a"
@builder = Gem::Ext::Builder.new @spec, ""
end
def teardown
- ENV["DESTDIR"] = @orig_DESTDIR
- ENV["make"] = @orig_make
-
super
+ ENV["DESTDIR"] = @orig_destdir
+ ENV["make"] = @orig_make
end
def test_class_make
@@ -49,14 +48,14 @@ install:
results = results.join("\n").b
- assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} clean$}, results
- assert_match %r{DESTDIR\\=#{ENV['DESTDIR']}$}, results
- assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} install$}, results
+ assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} clean$/, results)
+ assert_match(/DESTDIR\\=#{ENV["DESTDIR"]}$/, results)
+ assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} install$/, results)
- if /nmake/ !~ results
- assert_match %r{^clean: destination$}, results
- assert_match %r{^all: destination$}, results
- assert_match %r{^install: destination$}, results
+ unless results.include?("nmake")
+ assert_match(/^clean: destination$/, results)
+ assert_match(/^all: destination$/, results)
+ assert_match(/^install: destination$/, results)
end
end
@@ -78,12 +77,14 @@ install:
results = results.join("\n").b
- assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} clean$}, results
- assert_match %r{DESTDIR\\=#{ENV['DESTDIR']}$}, results
- assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} install$}, results
+ assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} clean$/, results)
+ assert_match(/DESTDIR\\=#{ENV["DESTDIR"]}$/, results)
+ assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} install$/, results)
end
def test_custom_make_with_options
+ pend "native windows platform only provides nmake" if vc_windows?
+
ENV["make"] = "make V=1"
results = []
File.open File.join(@ext, "Makefile"), "w" do |io|
@@ -100,49 +101,52 @@ install:
end
Gem::Ext::Builder.make @dest_path, results, @ext
results = results.join("\n").b
- assert_match %r{clean: OK}, results
- assert_match %r{all: OK}, results
- assert_match %r{install: OK}, results
+ assert_match(/clean: OK/, results)
+ assert_match(/all: OK/, results)
+ assert_match(/install: OK/, results)
end
def test_build_extensions
- pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
- @spec.extensions << "ext/extconf.rb"
+ pend "terminates on mswin" if vc_windows? && ruby_repo?
- ext_dir = File.join @spec.gem_dir, "ext"
+ extension_in_lib do
+ @spec.extensions << "ext/extconf.rb"
- FileUtils.mkdir_p ext_dir
+ ext_dir = File.join @spec.gem_dir, "ext"
- extconf_rb = File.join ext_dir, "extconf.rb"
+ FileUtils.mkdir_p ext_dir
- File.open extconf_rb, "w" do |f|
- f.write <<-'RUBY'
- require 'mkmf'
+ extconf_rb = File.join ext_dir, "extconf.rb"
- create_makefile 'a'
- RUBY
- end
+ File.open extconf_rb, "w" do |f|
+ f.write <<-'RUBY'
+ require 'mkmf'
- ext_lib_dir = File.join ext_dir, "lib"
- FileUtils.mkdir ext_lib_dir
- FileUtils.touch File.join ext_lib_dir, "a.rb"
- FileUtils.mkdir File.join ext_lib_dir, "a"
- FileUtils.touch File.join ext_lib_dir, "a", "b.rb"
+ create_makefile 'a'
+ RUBY
+ end
- use_ui @ui do
- @builder.build_extensions
- end
+ ext_lib_dir = File.join ext_dir, "lib"
+ FileUtils.mkdir ext_lib_dir
+ FileUtils.touch File.join ext_lib_dir, "a.rb"
+ FileUtils.mkdir File.join ext_lib_dir, "a"
+ FileUtils.touch File.join ext_lib_dir, "a", "b.rb"
- assert_path_exist @spec.extension_dir
- assert_path_exist @spec.gem_build_complete_path
- assert_path_exist File.join @spec.extension_dir, "gem_make.out"
- assert_path_exist File.join @spec.extension_dir, "a.rb"
- assert_path_exist File.join @spec.gem_dir, "lib", "a.rb"
- assert_path_exist File.join @spec.gem_dir, "lib", "a", "b.rb"
+ use_ui @ui do
+ @builder.build_extensions
+ end
+
+ assert_path_exist @spec.extension_dir
+ assert_path_exist @spec.gem_build_complete_path
+ assert_path_exist File.join @spec.extension_dir, "gem_make.out"
+ assert_path_exist File.join @spec.extension_dir, "a.rb"
+ assert_path_exist File.join @spec.gem_dir, "lib", "a.rb"
+ assert_path_exist File.join @spec.gem_dir, "lib", "a", "b.rb"
+ end
end
def test_build_extensions_with_gemhome_with_space
- pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
+ pend "terminates on mswin" if vc_windows? && ruby_repo?
new_gemhome = File.join @tempdir, "gem home"
File.rename(@gemhome, new_gemhome)
@gemhome = new_gemhome
@@ -154,55 +158,47 @@ install:
end
def test_build_extensions_install_ext_only
- class << Gem
- alias orig_install_extension_in_lib install_extension_in_lib
+ pend "terminates on mswin" if vc_windows? && ruby_repo?
- remove_method :install_extension_in_lib
+ extension_in_lib(false) do
+ @orig_install_extension_in_lib = Gem.configuration.install_extension_in_lib
+ Gem.configuration.install_extension_in_lib = false
- def Gem.install_extension_in_lib
- false
- end
- end
- pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
+ @spec.extensions << "ext/extconf.rb"
- @spec.extensions << "ext/extconf.rb"
+ ext_dir = File.join @spec.gem_dir, "ext"
- ext_dir = File.join @spec.gem_dir, "ext"
+ FileUtils.mkdir_p ext_dir
- FileUtils.mkdir_p ext_dir
+ extconf_rb = File.join ext_dir, "extconf.rb"
- extconf_rb = File.join ext_dir, "extconf.rb"
+ File.open extconf_rb, "w" do |f|
+ f.write <<-'RUBY'
+ require 'mkmf'
- File.open extconf_rb, "w" do |f|
- f.write <<-'RUBY'
- require 'mkmf'
+ create_makefile 'a'
+ RUBY
+ end
- create_makefile 'a'
- RUBY
- end
+ ext_lib_dir = File.join ext_dir, "lib"
+ FileUtils.mkdir ext_lib_dir
+ FileUtils.touch File.join ext_lib_dir, "a.rb"
+ FileUtils.mkdir File.join ext_lib_dir, "a"
+ FileUtils.touch File.join ext_lib_dir, "a", "b.rb"
- ext_lib_dir = File.join ext_dir, "lib"
- FileUtils.mkdir ext_lib_dir
- FileUtils.touch File.join ext_lib_dir, "a.rb"
- FileUtils.mkdir File.join ext_lib_dir, "a"
- FileUtils.touch File.join ext_lib_dir, "a", "b.rb"
+ use_ui @ui do
+ @builder.build_extensions
+ end
- use_ui @ui do
- @builder.build_extensions
+ assert_path_exist @spec.extension_dir
+ assert_path_exist @spec.gem_build_complete_path
+ assert_path_exist File.join @spec.extension_dir, "gem_make.out"
+ assert_path_exist File.join @spec.extension_dir, "a.rb"
+ assert_path_not_exist File.join @spec.gem_dir, "lib", "a.rb"
+ assert_path_not_exist File.join @spec.gem_dir, "lib", "a", "b.rb"
end
-
- assert_path_exist @spec.extension_dir
- assert_path_exist @spec.gem_build_complete_path
- assert_path_exist File.join @spec.extension_dir, "gem_make.out"
- assert_path_exist File.join @spec.extension_dir, "a.rb"
- assert_path_not_exist File.join @spec.gem_dir, "lib", "a.rb"
- assert_path_not_exist File.join @spec.gem_dir, "lib", "a", "b.rb"
ensure
- class << Gem
- remove_method :install_extension_in_lib
-
- alias install_extension_in_lib orig_install_extension_in_lib
- end
+ Gem.configuration.install_extension_in_lib = @orig_install_extension_in_lib
end
def test_build_extensions_none
@@ -252,7 +248,7 @@ install:
cmd_make_out = File.read(gem_make_out)
assert_match %r{#{Regexp.escape Gem.ruby} .* extconf\.rb}, cmd_make_out
- assert_match %r{: No such file}, cmd_make_out
+ assert_match(/: No such file/, cmd_make_out)
assert_path_not_exist @spec.gem_build_complete_path
diff --git a/test/rubygems/test_gem_ext_cargo_builder.rb b/test/rubygems/test_gem_ext_cargo_builder.rb
index c6bbab2cb3..5faf3e2480 100644
--- a/test/rubygems/test_gem_ext_cargo_builder.rb
+++ b/test/rubygems/test_gem_ext_cargo_builder.rb
@@ -2,6 +2,7 @@
require_relative "helper"
require "rubygems/ext"
+require "open3"
class TestGemExtCargoBuilder < Gem::TestCase
def setup
@@ -22,25 +23,6 @@ class TestGemExtCargoBuilder < Gem::TestCase
FileUtils.cp_r(@fixture_dir.to_s, @ext)
end
- def test_build_staticlib
- skip_unsupported_platforms!
- setup_rust_gem "rust_ruby_example"
-
- content = @fixture_dir.join("Cargo.toml").read.gsub("cdylib", "staticlib")
- File.write(File.join(@ext, "Cargo.toml"), content)
-
- output = []
-
- Dir.chdir @ext do
- ENV.update(@rust_envs)
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
- assert_raise(Gem::Ext::CargoBuilder::DylibNotFoundError) do
- builder.build nil, @dest_path, output
- end
- end
- end
-
def test_build_cdylib
skip_unsupported_platforms!
setup_rust_gem "rust_ruby_example"
@@ -49,42 +31,43 @@ class TestGemExtCargoBuilder < Gem::TestCase
Dir.chdir @ext do
ENV.update(@rust_envs)
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
- builder.build nil, @dest_path, output
+ builder = Gem::Ext::CargoBuilder.new
+ builder.build "Cargo.toml", @dest_path, output
end
output = output.join "\n"
- bundle = File.join(@dest_path, "release/rust_ruby_example.#{RbConfig::CONFIG['DLEXT']}")
+ bundle = File.join(@dest_path, "rust_ruby_example.#{RbConfig::CONFIG["DLEXT"]}")
- assert_match "Finished release [optimized] target(s)", output
+ assert_match(/Finished/, output)
+ assert_match(/release/, output)
assert_ffi_handle bundle, "Init_rust_ruby_example"
- rescue Exception => e
+ rescue StandardError => e
pp output if output
raise(e)
end
- def test_build_dev_profile
+ def test_rubygems_cfg_passed_to_rustc
skip_unsupported_platforms!
setup_rust_gem "rust_ruby_example"
-
+ version_slug = Gem::VERSION.tr(".", "_")
output = []
+ replace_in_rust_file("src/lib.rs", "rubygems_x_x_x", "rubygems_#{version_slug}")
+
Dir.chdir @ext do
ENV.update(@rust_envs)
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
- builder.profile = :dev
- builder.build nil, @dest_path, output
+ builder = Gem::Ext::CargoBuilder.new
+ builder.build "Cargo.toml", @dest_path, output
end
output = output.join "\n"
- bundle = File.join(@dest_path, "debug/rust_ruby_example.#{RbConfig::CONFIG['DLEXT']}")
+ bundle = File.join(@dest_path, "rust_ruby_example.#{RbConfig::CONFIG["DLEXT"]}")
- assert_match "Finished dev [unoptimized + debuginfo] target(s)", output
- assert_ffi_handle bundle, "Init_rust_ruby_example"
- rescue Exception => e
+ assert_ffi_handle bundle, "hello_from_rubygems"
+ assert_ffi_handle bundle, "hello_from_rubygems_version"
+ refute_ffi_handle bundle, "should_never_exist"
+ rescue StandardError => e
pp output if output
raise(e)
@@ -94,22 +77,17 @@ class TestGemExtCargoBuilder < Gem::TestCase
skip_unsupported_platforms!
setup_rust_gem "rust_ruby_example"
- output = []
-
FileUtils.rm(File.join(@ext, "src/lib.rs"))
error = assert_raise(Gem::InstallError) do
Dir.chdir @ext do
ENV.update(@rust_envs)
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
- builder.build nil, @dest_path, output
+ builder = Gem::Ext::CargoBuilder.new
+ builder.build "Cargo.toml", @dest_path, []
end
end
- output = output.join "\n"
-
- assert_match "cargo failed", error.message
+ assert_match(/cargo\s.*\sfailed/, error.message)
end
def test_full_integration
@@ -122,7 +100,7 @@ class TestGemExtCargoBuilder < Gem::TestCase
require "tmpdir"
env_for_subprocess = @rust_envs.merge("GEM_HOME" => Gem.paths.home)
- gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../bin/gem", __dir__)]
+ gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../exe/gem", __dir__)]
Dir.mktmpdir("rust_ruby_example") do |dir|
built_gem = File.expand_path(File.join(dir, "rust_ruby_example.gem"))
@@ -144,7 +122,7 @@ class TestGemExtCargoBuilder < Gem::TestCase
require "tmpdir"
env_for_subprocess = @rust_envs.merge("GEM_HOME" => Gem.paths.home)
- gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../bin/gem", __dir__)]
+ gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../exe/gem", __dir__)]
Dir.mktmpdir("custom_name") do |dir|
built_gem = File.expand_path(File.join(dir, "custom_name.gem"))
@@ -162,17 +140,32 @@ class TestGemExtCargoBuilder < Gem::TestCase
private
def skip_unsupported_platforms!
- pend "jruby not supported" if java_platform?
+ pend "jruby not supported" if Gem.java_platform?
pend "truffleruby not supported (yet)" if RUBY_ENGINE == "truffleruby"
- pend "mswin not supported (yet)" if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS")
system(@rust_envs, "cargo", "-V", out: IO::NULL, err: [:child, :out])
pend "cargo not present" unless $?.success?
pend "ruby.h is not provided by ruby repo" if ruby_repo?
+ pend "rust toolchain of mingw is broken" if mingw_windows?
end
def assert_ffi_handle(bundle, name)
require "fiddle"
dylib_handle = Fiddle.dlopen bundle
assert_nothing_raised { dylib_handle[name] }
+ ensure
+ dylib_handle&.close
+ end
+
+ def refute_ffi_handle(bundle, name)
+ require "fiddle"
+ dylib_handle = Fiddle.dlopen bundle
+ assert_raise { dylib_handle[name] }
+ ensure
+ dylib_handle&.close
+ end
+
+ def replace_in_rust_file(name, from, to)
+ content = @fixture_dir.join(name).read.gsub(from, to)
+ File.write(File.join(@ext, name), content)
end
end
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock
deleted file mode 100644
index da09e717f0..0000000000
--- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock
+++ /dev/null
@@ -1,243 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "aho-corasick"
-version = "0.7.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "bindgen"
-version = "0.60.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6"
-dependencies = [
- "bitflags",
- "cexpr",
- "clang-sys",
- "lazy_static",
- "lazycell",
- "peeking_take_while",
- "proc-macro2",
- "quote",
- "regex",
- "rustc-hash",
- "shlex",
-]
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "cexpr"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
-dependencies = [
- "nom",
-]
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "clang-sys"
-version = "1.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b"
-dependencies = [
- "glob",
- "libc",
- "libloading",
-]
-
-[[package]]
-name = "custom-name-ext"
-version = "0.1.0"
-dependencies = [
- "rb-sys",
-]
-
-[[package]]
-name = "glob"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "lazycell"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
-
-[[package]]
-name = "libc"
-version = "0.2.126"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
-
-[[package]]
-name = "libloading"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
-dependencies = [
- "cfg-if",
- "winapi",
-]
-
-[[package]]
-name = "linkify"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96dd5884008358112bc66093362197c7248ece00d46624e2cf71e50029f8cff5"
-dependencies = [
- "memchr",
-]
-
-[[package]]
-name = "memchr"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
-
-[[package]]
-name = "minimal-lexical"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-
-[[package]]
-name = "nom"
-version = "7.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
-dependencies = [
- "memchr",
- "minimal-lexical",
-]
-
-[[package]]
-name = "peeking_take_while"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "rb-sys"
-version = "0.9.29"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0317cb843cdeef14c5622917c55c0a170cee31348eb600c4a1683fb8c9e87e7a"
-dependencies = [
- "bindgen",
- "linkify",
- "rb-sys-build",
-]
-
-[[package]]
-name = "rb-sys-build"
-version = "0.9.29"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4b8274327aecb7edcff86e290d9cbe7b572b7889c1cfc7476358f4831f78ce5"
-dependencies = [
- "regex",
- "shell-words",
-]
-
-[[package]]
-name = "regex"
-version = "1.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.6.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
-
-[[package]]
-name = "rustc-hash"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
-
-[[package]]
-name = "shell-words"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
-
-[[package]]
-name = "shlex"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml
deleted file mode 100644
index 2a215a55dd..0000000000
--- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-[package]
-name = "custom-name-ext"
-version = "0.1.0"
-edition = "2021"
-
-[lib]
-crate-type = ["cdylib"]
-
-[dependencies]
-rb-sys = { version = "0.9.29", features = ["gem"] }
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb b/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb
deleted file mode 100644
index 0e04f0de5e..0000000000
--- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-if ENV["RUBYOPT"] || defined? Gem
- ENV.delete "RUBYOPT"
-
- require "rbconfig"
- cmd = [RbConfig.ruby, "--disable-gems", "build.rb", *ARGV]
-
- exec(*cmd)
-end
-
-require "tmpdir"
-
-lp = File.expand_path("../../../../lib", __dir__)
-gem = ["ruby", "-I#{lp}", File.expand_path("../../../../bin/gem", __dir__)]
-gemspec = File.expand_path("custom_name.gemspec", __dir__)
-
-Dir.mktmpdir("custom_name") do |dir|
- built_gem = File.expand_path(File.join(dir, "custom_name.gem"))
- system(*gem, "build", gemspec, "--output", built_gem)
- system(*gem, "install", "--verbose", "--local", built_gem, *ARGV)
- system %q(ruby -rcustom_name -e "puts 'Result: ' + CustomName.say_hello")
-end
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec b/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec
index 1f8e270e96..5f130527dd 100644
--- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec
+++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec
@@ -1,10 +1,10 @@
+# frozen_string_literal: true
+
Gem::Specification.new do |s|
s.name = "custom_name"
s.version = "0.1.0"
s.summary = "A Rust extension for Ruby"
- s.extensions = ["Cargo.toml"]
+ s.extensions = ["ext/custom_name_lib/Cargo.toml"]
s.authors = ["Ian Ker-Seymer"]
- s.files = ["Cargo.toml", "Cargo.lock", "src/lib.rs"]
-
- s.metadata["cargo_crate_name"] = "custom-name-ext"
+ s.files = ["lib/custom_name.rb", "ext/custom_name_lib/Cargo.toml", "ext/custom_name_lib/Cargo.lock", "ext/custom_name_lib/src/lib.rs"]
end
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock
new file mode 100644
index 0000000000..b9fed0e2b0
--- /dev/null
+++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock
@@ -0,0 +1,249 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "bindgen"
+version = "0.69.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "clang-sys",
+ "lazy_static",
+ "lazycell",
+ "peeking_take_while",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "syn",
+]
+
+[[package]]
+name = "bitflags"
+version = "2.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
+
+[[package]]
+name = "cexpr"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clang-sys"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "custom-name-ext"
+version = "0.1.0"
+dependencies = [
+ "rb-sys",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "lazycell"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+
+[[package]]
+name = "libc"
+version = "0.2.138"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
+
+[[package]]
+name = "libloading"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
+dependencies = [
+ "cfg-if",
+ "winapi",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "nom"
+version = "7.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.66"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rb-sys"
+version = "0.9.94"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06dab8dbb0beb0a575a80c4b46355c8ace1f3dc5df60a3109758f205f1061366"
+dependencies = [
+ "rb-sys-build",
+]
+
+[[package]]
+name = "rb-sys-build"
+version = "0.9.94"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "164d44950a42f2ba2f94efdcb650e14764270f84d281352aebb261806da0b2ce"
+dependencies = [
+ "bindgen",
+ "lazy_static",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "shell-words",
+ "syn",
+]
+
+[[package]]
+name = "regex"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "shell-words"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "syn"
+version = "2.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml
new file mode 100644
index 0000000000..9f844b62be
--- /dev/null
+++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "custom-name-ext"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+rb-sys = "0.9.94"
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs
new file mode 100644
index 0000000000..28ba3be564
--- /dev/null
+++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs
@@ -0,0 +1,27 @@
+extern crate rb_sys;
+
+use rb_sys::{rb_define_module, rb_define_module_function, rb_utf8_str_new, VALUE};
+use std::ffi::CString;
+
+#[no_mangle]
+unsafe extern "C" fn say_hello(_klass: VALUE) -> VALUE {
+ let cstr = CString::new("Hello world!").unwrap();
+
+ rb_utf8_str_new(cstr.as_ptr(), 12)
+}
+
+#[allow(non_snake_case)]
+#[no_mangle]
+pub extern "C" fn Init_custom_name_ext() {
+ let name = CString::new("CustomName").unwrap();
+ let function_name = CString::new("say_hello").unwrap();
+ // bindgen does not properly detect the arity of the ruby callback function, so we have to transmute
+ let callback = unsafe {
+ std::mem::transmute::<unsafe extern "C" fn(VALUE) -> VALUE, unsafe extern "C" fn() -> VALUE>(
+ say_hello,
+ )
+ };
+ let klass = unsafe { rb_define_module(name.as_ptr()) };
+
+ unsafe { rb_define_module_function(klass, function_name.as_ptr(), Some(callback), 0) }
+}
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb b/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb
new file mode 100644
index 0000000000..9f8d190baf
--- /dev/null
+++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb
@@ -0,0 +1,3 @@
+# frozen_string_literal: true
+
+require "custom_name_lib/custom_name_ext"
diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs b/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs
deleted file mode 100644
index 543ad4a70e..0000000000
--- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-extern crate rb_sys;
-
-use rb_sys::{rb_define_module, rb_define_module_function, rb_utf8_str_new, VALUE};
-use std::ffi::CString;
-
-#[no_mangle]
-unsafe extern "C" fn say_hello(_klass: VALUE) -> VALUE {
- let cstr = CString::new("Hello world!").unwrap();
-
- rb_utf8_str_new(cstr.as_ptr(), 12)
-}
-
-#[allow(non_snake_case)]
-#[no_mangle]
-pub extern "C" fn Init_custom_name() {
- let name = CString::new("CustomName").unwrap();
- let function_name = CString::new("say_hello").unwrap();
- // bindgen does not properly detect the arity of the ruby callback function, so we have to transmute
- let callback = unsafe {
- std::mem::transmute::<unsafe extern "C" fn(VALUE) -> VALUE, unsafe extern "C" fn() -> VALUE>(
- say_hello,
- )
- };
- let klass = unsafe { rb_define_module(name.as_ptr()) };
-
- unsafe { rb_define_module_function(klass, function_name.as_ptr(), Some(callback), 0) }
-}
diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock
index e351819848..7e1617a663 100644
--- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock
+++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock
@@ -4,18 +4,18 @@ version = 3
[[package]]
name = "aho-corasick"
-version = "0.7.18"
+version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "bindgen"
-version = "0.60.1"
+version = "0.69.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6"
+checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2"
dependencies = [
"bitflags",
"cexpr",
@@ -28,13 +28,14 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
+ "syn",
]
[[package]]
name = "bitflags"
-version = "1.3.2"
+version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
[[package]]
name = "cexpr"
@@ -53,9 +54,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-sys"
-version = "1.3.3"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b"
+checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
dependencies = [
"glob",
"libc",
@@ -82,30 +83,21 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
-version = "0.2.126"
+version = "0.2.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]]
name = "libloading"
-version = "0.7.3"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
-name = "linkify"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96dd5884008358112bc66093362197c7248ece00d46624e2cf71e50029f8cff5"
-dependencies = [
- "memchr",
-]
-
-[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -135,48 +127,51 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "proc-macro2"
-version = "1.0.40"
+version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
+checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.20"
+version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
+checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rb-sys"
-version = "0.9.29"
+version = "0.9.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0317cb843cdeef14c5622917c55c0a170cee31348eb600c4a1683fb8c9e87e7a"
+checksum = "06dab8dbb0beb0a575a80c4b46355c8ace1f3dc5df60a3109758f205f1061366"
dependencies = [
- "bindgen",
- "linkify",
"rb-sys-build",
]
[[package]]
name = "rb-sys-build"
-version = "0.9.29"
+version = "0.9.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4b8274327aecb7edcff86e290d9cbe7b572b7889c1cfc7476358f4831f78ce5"
+checksum = "164d44950a42f2ba2f94efdcb650e14764270f84d281352aebb261806da0b2ce"
dependencies = [
+ "bindgen",
+ "lazy_static",
+ "proc-macro2",
+ "quote",
"regex",
"shell-words",
+ "syn",
]
[[package]]
name = "regex"
-version = "1.5.6"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
+checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
dependencies = [
"aho-corasick",
"memchr",
@@ -185,9 +180,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.6.26"
+version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "rust_ruby_example"
@@ -210,15 +205,26 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]]
name = "shlex"
-version = "1.1.0"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "syn"
+version = "2.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
+checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
[[package]]
name = "unicode-ident"
-version = "1.0.1"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "winapi"
diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml
index 1867db8e66..a84cc8aabb 100644
--- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml
+++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml
@@ -7,4 +7,4 @@ edition = "2021"
crate-type = ["cdylib"]
[dependencies]
-rb-sys = { version = "0.9.29", features = ["gem"] }
+rb-sys = "0.9.94"
diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb
deleted file mode 100644
index f404aa3468..0000000000
--- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-if ENV["RUBYOPT"] || defined? Gem
- ENV.delete "RUBYOPT"
-
- require "rbconfig"
- cmd = [RbConfig.ruby, "--disable-gems", "build.rb", *ARGV]
-
- exec(*cmd)
-end
-
-require "tmpdir"
-
-lp = File.expand_path("../../../../lib", __dir__)
-gem = ["ruby", "-I#{lp}", File.expand_path("../../../../bin/gem", __dir__)]
-gemspec = File.expand_path("rust_ruby_example.gemspec", __dir__)
-
-Dir.mktmpdir("rust_ruby_example") do |dir|
- built_gem = File.expand_path(File.join(dir, "rust_ruby_example.gem"))
- system(*gem, "build", gemspec, "--output", built_gem)
- system(*gem, "install", "--verbose", "--local", built_gem, *ARGV)
- system %q(ruby -rrust_ruby_example -e "puts 'Result: ' + RustRubyExample.reverse('hello world')")
-end
diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec
index 82c84ba818..d3f8b11a8b 100644
--- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec
+++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
Gem::Specification.new do |s|
s.name = "rust_ruby_example"
s.version = "0.1.0"
diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs
index b2a907c736..0626f04e0f 100644
--- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs
+++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs
@@ -21,6 +21,18 @@ unsafe extern "C" fn pub_reverse(_klass: VALUE, mut input: VALUE) -> VALUE {
rb_utf8_str_new(reversed_cstring.as_ptr(), size)
}
+#[cfg(rubygems)]
+#[no_mangle]
+pub extern "C" fn hello_from_rubygems() {}
+
+#[cfg(rubygems_0_0_0)]
+#[no_mangle]
+pub extern "C" fn should_never_exist() {}
+
+#[cfg(rubygems_x_x_x)]
+#[no_mangle]
+pub extern "C" fn hello_from_rubygems_version() {}
+
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn Init_rust_ruby_example() {
diff --git a/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb b/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb
index 88581ea4d8..a3fef50d54 100644
--- a/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb
+++ b/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb
@@ -1,26 +1,27 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/ext"
require "rubygems/ext/cargo_builder/link_flag_converter"
class TestGemExtCargoBuilderLinkFlagConverter < Gem::TestCase
CASES = {
- test_search_path_basic: ["-L/usr/local/lib", ["-L", "native=/usr/local/lib"]],
- test_search_path_space: ["-L /usr/local/lib", ["-L", "native=/usr/local/lib"]],
- test_search_path_space_in_path: ["-L/usr/local/my\ lib", ["-L", "native=/usr/local/my\ lib"]],
- test_simple_lib: ["-lfoo", ["-l", "foo"]],
- test_lib_with_nonascii: ["-lws2_32", ["-l", "ws2_32"]],
- test_simple_lib_space: ["-l foo", ["-l", "foo"]],
- test_verbose_lib_space: ["--library=foo", ["-l", "foo"]],
- test_libstatic_with_colon: ["-l:libssp.a", ["-l", "static=ssp"]],
- test_libstatic_with_colon_space: ["-l :libssp.a", ["-l", "static=ssp"]],
- test_unconventional_lib_with_colon: ["-l:ssp.a", ["-C", "link_arg=-l:ssp.a"]],
- test_dylib_with_colon_space: ["-l :libssp.dylib", ["-l", "dylib=ssp"]],
- test_so_with_colon_space: ["-l :libssp.so", ["-l", "dylib=ssp"]],
- test_dll_with_colon_space: ["-l :libssp.dll", ["-l", "dylib=ssp"]],
- test_framework: ["-F/some/path", ["-l", "framework=/some/path"]],
- test_framework_space: ["-F /some/path", ["-l", "framework=/some/path"]],
- test_non_lib_dash_l: ["test_rubygems_20220413-976-lemgf9/prefix", ["-C", "link_arg=test_rubygems_20220413-976-lemgf9/prefix"]],
+ test_search_path_basic: ["-L/usr/local/lib", ["-L", "native=/usr/local/lib"]],
+ test_search_path_space: ["-L /usr/local/lib", ["-L", "native=/usr/local/lib"]],
+ test_search_path_space_in_path: ["-L/usr/local/my\ lib", ["-L", "native=/usr/local/my\ lib"]],
+ test_simple_lib: ["-lfoo", ["-l", "foo"]],
+ test_lib_with_nonascii: ["-lws2_32", ["-l", "ws2_32"]],
+ test_simple_lib_space: ["-l foo", ["-l", "foo"]],
+ test_verbose_lib_space: ["--library=foo", ["-l", "foo"]],
+ test_libstatic_with_colon: ["-l:libssp.a", ["-C", "link-args=-l:libssp.a"]],
+ test_libstatic_with_colon_space: ["-l :libssp.a", ["-C", "link-args=-l :libssp.a"]],
+ test_unconventional_lib_with_colon: ["-l:ssp.a", ["-C", "link-args=-l:ssp.a"]],
+ test_dylib_with_colon_space: ["-l :libssp.dylib", ["-C", "link-args=-l :libssp.dylib"]],
+ test_so_with_colon_space: ["-l :libssp.so", ["-C", "link-args=-l :libssp.so"]],
+ test_dll_with_colon_space: ["-l :libssp.dll", ["-C", "link-args=-l :libssp.dll"]],
+ test_framework: ["-F/some/path", ["-l", "framework=/some/path"]],
+ test_framework_space: ["-F /some/path", ["-l", "framework=/some/path"]],
+ test_non_lib_dash_l: ["test_rubygems_20220413-976-lemgf9/prefix", ["-C", "link-args=test_rubygems_20220413-976-lemgf9/prefix"]],
}.freeze
CASES.each do |test_name, (arg, expected)|
diff --git a/test/rubygems/test_gem_ext_cargo_builder_unit.rb b/test/rubygems/test_gem_ext_cargo_builder_unit.rb
index 4484f48ca9..89495b84ff 100644
--- a/test/rubygems/test_gem_ext_cargo_builder_unit.rb
+++ b/test/rubygems/test_gem_ext_cargo_builder_unit.rb
@@ -6,8 +6,7 @@ require "rubygems/ext"
class TestGemExtCargoBuilderUnit < Gem::TestCase
def test_cargo_command_passes_args
skip_unsupported_platforms!
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
+ builder = Gem::Ext::CargoBuilder.new
command = builder.cargo_command(Dir.pwd, @tempdir, ["--all-features"])
assert_includes command, "--all-features"
@@ -15,30 +14,18 @@ class TestGemExtCargoBuilderUnit < Gem::TestCase
def test_cargo_command_locks_in_release_profile
skip_unsupported_platforms!
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
+ builder = Gem::Ext::CargoBuilder.new
builder.profile = :release
command = builder.cargo_command(Dir.pwd, @tempdir)
assert_includes command, "--locked"
end
- def test_cargo_command_does_not_lock_in_dev_profile
- skip_unsupported_platforms!
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
- builder.profile = :dev
- command = builder.cargo_command(Dir.pwd, @tempdir)
-
- assert_not_includes command, "--locked"
- end
-
def test_cargo_command_passes_respects_cargo_env_var
skip_unsupported_platforms!
old_cargo = ENV["CARGO"]
ENV["CARGO"] = "mycargo"
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
+ builder = Gem::Ext::CargoBuilder.new
command = builder.cargo_command(Dir.pwd, @tempdir)
assert_includes command, "mycargo"
@@ -48,8 +35,7 @@ class TestGemExtCargoBuilderUnit < Gem::TestCase
def test_build_env_includes_rbconfig
skip_unsupported_platforms!
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
+ builder = Gem::Ext::CargoBuilder.new
env = builder.build_env
assert_equal env.fetch("RBCONFIG_RUBY_SO_NAME"), RbConfig::CONFIG["RUBY_SO_NAME"]
@@ -59,8 +45,7 @@ class TestGemExtCargoBuilderUnit < Gem::TestCase
skip_unsupported_platforms!
old_cargo = ENV["CARGO_BUILD_TARGET"]
ENV["CARGO_BUILD_TARGET"] = "x86_64-unknown-linux-gnu"
- spec = Gem::Specification.new "rust_ruby_example", "0.1.0"
- builder = Gem::Ext::CargoBuilder.new(spec)
+ builder = Gem::Ext::CargoBuilder.new
command = builder.cargo_command(Dir.pwd, @tempdir, ["--locked"])
assert_includes command, "--target"
@@ -70,6 +55,6 @@ class TestGemExtCargoBuilderUnit < Gem::TestCase
end
def skip_unsupported_platforms!
- pend "jruby not supported" if java_platform?
+ pend "jruby not supported" if Gem.java_platform?
end
end
diff --git a/test/rubygems/test_gem_ext_cmake_builder.rb b/test/rubygems/test_gem_ext_cmake_builder.rb
index ee84b8e728..5f886af05f 100644
--- a/test/rubygems/test_gem_ext_cmake_builder.rb
+++ b/test/rubygems/test_gem_ext_cmake_builder.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/ext"
@@ -42,11 +43,11 @@ install (FILES test.txt DESTINATION bin)
output = output.join "\n"
- assert_match %r{^cmake \. -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}}, output
- assert_match %r{#{Regexp.escape @ext}}, output
+ assert_match(/^cmake \. -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}/, output)
+ assert_match(/#{Regexp.escape @ext}/, output)
assert_contains_make_command "", output
assert_contains_make_command "install", output
- assert_match %r{test\.txt}, output
+ assert_match(/test\.txt/, output)
end
def test_self_build_fail
@@ -58,12 +59,12 @@ install (FILES test.txt DESTINATION bin)
output = output.join "\n"
- shell_error_msg = %r{(CMake Error: .*)}
+ shell_error_msg = /(CMake Error: .*)/
assert_match "cmake failed", error.message
- assert_match %r{^cmake . -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}}, output
- assert_match %r{#{shell_error_msg}}, output
+ assert_match(/^cmake . -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}/, output)
+ assert_match(/#{shell_error_msg}/, output)
end
def test_self_build_has_makefile
diff --git a/test/rubygems/test_gem_ext_configure_builder.rb b/test/rubygems/test_gem_ext_configure_builder.rb
index 191b332dda..6a2f9883f0 100644
--- a/test/rubygems/test_gem_ext_configure_builder.rb
+++ b/test/rubygems/test_gem_ext_configure_builder.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/ext"
@@ -56,7 +57,7 @@ class TestGemExtConfigureBuilder < Gem::TestCase
assert_match(/^current directory:/, output.shift)
assert_equal "#{sh_prefix_configure}#{@dest_path}", output.shift
- assert_match %r{#{shell_error_msg}}, output.shift
+ assert_match(/#{shell_error_msg}/, output.shift)
assert_equal true, output.empty?
end
diff --git a/test/rubygems/test_gem_ext_ext_conf_builder.rb b/test/rubygems/test_gem_ext_ext_conf_builder.rb
index e6b980a96b..218c6f3d5e 100644
--- a/test/rubygems/test_gem_ext_ext_conf_builder.rb
+++ b/test/rubygems/test_gem_ext_ext_conf_builder.rb
@@ -15,7 +15,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase
end
def test_class_build
- if java_platform?
+ if Gem.java_platform?
pend("failing on jruby")
end
@@ -34,7 +34,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase
assert_same result, output
assert_match(/^current directory:/, output[0])
- assert_match(/^#{Gem.ruby}.* extconf.rb/, output[1])
+ assert_match(/^#{Regexp.quote(Gem.ruby)}.* extconf.rb/, output[1])
assert_equal "creating Makefile\n", output[2]
assert_match(/^current directory:/, output[3])
assert_contains_make_command "clean", output[4]
@@ -45,7 +45,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase
end
def test_class_build_rbconfig_make_prog
- if java_platform?
+ if Gem.java_platform?
pend("failing on jruby")
end
@@ -65,14 +65,14 @@ class TestGemExtExtConfBuilder < Gem::TestCase
end
end
- def test_class_build_env_MAKE
+ def test_class_build_env_make
env_make = ENV.delete "make"
ENV["make"] = nil
- env_MAKE = ENV.delete "MAKE"
+ env_large_make = ENV.delete "MAKE"
ENV["MAKE"] = "anothermake"
- if java_platform?
+ if Gem.java_platform?
pend("failing on jruby")
end
@@ -91,7 +91,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase
assert_contains_make_command "clean", output[4]
end
ensure
- ENV["MAKE"] = env_MAKE
+ ENV["MAKE"] = env_large_make
ENV["make"] = env_make
end
@@ -114,7 +114,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase
assert_equal "extconf failed, exit code 1", error.message
- assert_match(/^#{Gem.ruby}.* extconf.rb/, output[1])
+ assert_match(/^#{Regexp.quote(Gem.ruby)}.* extconf.rb/, output[1])
assert_match(File.join(@dest_path, "mkmf.log"), output[4])
assert_includes(output, "To see why this extension failed to compile, please check the mkmf.log which can be found here:\n")
@@ -218,7 +218,6 @@ end
RbConfig::CONFIG["configure_args"] = args if args
yield
-
ensure
if configure_args
RbConfig::CONFIG["configure_args"] = configure_args
diff --git a/test/rubygems/test_gem_ext_rake_builder.rb b/test/rubygems/test_gem_ext_rake_builder.rb
index 3ed818a7f8..bd72c1aa08 100644
--- a/test/rubygems/test_gem_ext_rake_builder.rb
+++ b/test/rubygems/test_gem_ext_rake_builder.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/ext"
@@ -22,9 +23,9 @@ class TestGemExtRakeBuilder < Gem::TestCase
output = output.join "\n"
- refute_match %r{^rake failed:}, output
- assert_match %r{^#{Regexp.escape Gem.ruby} mkrf_conf\.rb}, output
- assert_match %r{^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}}, output
+ refute_match(/^rake failed:/, output)
+ assert_match(/^#{Regexp.escape Gem.ruby} mkrf_conf\.rb/, output)
+ assert_match(/^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}/, output)
end
end
@@ -41,9 +42,9 @@ class TestGemExtRakeBuilder < Gem::TestCase
output = output.join "\n"
- refute_match %r{^rake failed:}, output
- assert_match %r{^#{Regexp.escape Gem.ruby} mkrf_conf\.rb}, output
- assert_match %r{^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}}, output
+ refute_match(/^rake failed:/, output)
+ assert_match(/^#{Regexp.escape Gem.ruby} mkrf_conf\.rb/, output)
+ assert_match(/^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}/, output)
end
end
@@ -71,7 +72,7 @@ class TestGemExtRakeBuilder < Gem::TestCase
output = output.join "\n"
assert_match "OpenSSL", output
- assert_match %r{^#{Regexp.escape Gem.ruby} mkrf_conf\.rb}, output
+ assert_match(/^#{Regexp.escape Gem.ruby} mkrf_conf\.rb/, output)
end
def test_class_build_no_mkrf_passes_args
@@ -82,8 +83,8 @@ class TestGemExtRakeBuilder < Gem::TestCase
output = output.join "\n"
- refute_match %r{^rake failed:}, output
- assert_match %r{^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path} test1 test2}, output
+ refute_match(/^rake failed:/, output)
+ assert_match(/^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path} test1 test2/, output)
end
end
@@ -91,12 +92,12 @@ class TestGemExtRakeBuilder < Gem::TestCase
create_temp_mkrf_file("task :default do abort 'fail' end")
output = []
- build_rake_in(false) do |rake|
+ build_rake_in(false) do |_rake|
error = assert_raise Gem::InstallError do
Gem::Ext::RakeBuilder.build "mkrf_conf.rb", @dest_path, output, [], nil, @ext
end
- assert_match %r{^rake failed}, error.message
+ assert_match(/^rake failed/, error.message)
end
end
diff --git a/test/rubygems/test_gem_gem_runner.rb b/test/rubygems/test_gem_gem_runner.rb
index f0128febc8..c05e74c991 100644
--- a/test/rubygems/test_gem_gem_runner.rb
+++ b/test/rubygems/test_gem_gem_runner.rb
@@ -1,20 +1,26 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemGemRunner < Gem::TestCase
def setup
- super
-
require "rubygems/command"
@orig_args = Gem::Command.build_args
@orig_specific_extra_args = Gem::Command.specific_extra_args_hash.dup
@orig_extra_args = Gem::Command.extra_args.dup
+ super
+
+ @orig_gem_home = ENV["GEM_HOME"]
+ ENV["GEM_HOME"] = @gemhome
+
require "rubygems/gem_runner"
@runner = Gem::GemRunner.new
end
def teardown
+ ENV["GEM_HOME"] = @orig_gem_home
+
super
Gem::Command.build_args = @orig_args
diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb
index 2ca5b402d9..a3236e6276 100644
--- a/test/rubygems/test_gem_gemcutter_utilities.rb
+++ b/test/rubygems/test_gem_gemcutter_utilities.rb
@@ -1,14 +1,18 @@
# frozen_string_literal: true
+
require_relative "helper"
+require_relative "multifactor_auth_utilities"
require "rubygems"
require "rubygems/command"
require "rubygems/gemcutter_utilities"
+require "rubygems/config_file"
class TestGemGemcutterUtilities < Gem::TestCase
def setup
super
credential_setup
+ @fetcher = SignInFetcher.new
# below needed for random testing, class property
Gem.configuration.disable_default_gem_server = nil
@@ -38,7 +42,7 @@ class TestGemGemcutterUtilities < Gem::TestCase
}
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
ENV["RUBYGEMS_HOST"] = "http://rubygems.engineyard.com"
@@ -49,10 +53,10 @@ class TestGemGemcutterUtilities < Gem::TestCase
end
def test_api_key
- keys = { :rubygems_api_key => "KEY" }
+ keys = { rubygems_api_key: "KEY" }
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
@@ -61,10 +65,10 @@ class TestGemGemcutterUtilities < Gem::TestCase
end
def test_api_key_override
- keys = { :rubygems_api_key => "KEY", :other => "OTHER" }
+ keys = { rubygems_api_key: "KEY", other: "OTHER" }
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
@@ -92,120 +96,111 @@ class TestGemGemcutterUtilities < Gem::TestCase
end
def test_sign_in
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
- util_sign_in [api_key, 200, "OK"]
+ util_sign_in
- assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
+ assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output)
assert @fetcher.last_request["authorization"]
- assert_match %r{Signed in.}, @sign_in_ui.output
+ assert_match(/Signed in./, @sign_in_ui.output)
credentials = load_yaml_file Gem.configuration.credentials_path
- assert_equal api_key, credentials[:rubygems_api_key]
+ assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
end
def test_sign_in_with_host
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
-
- util_sign_in [api_key, 200, "OK"], "http://example.com", ["http://example.com"]
+ @fetcher = SignInFetcher.new(host: "http://example.com")
+ util_sign_in
assert_match "Enter your http://example.com credentials.",
@sign_in_ui.output
assert @fetcher.last_request["authorization"]
- assert_match %r{Signed in.}, @sign_in_ui.output
+ assert_match(/Signed in./, @sign_in_ui.output)
credentials = load_yaml_file Gem.configuration.credentials_path
- assert_equal api_key, credentials["http://example.com"]
+ assert_equal @fetcher.api_key, credentials["http://example.com"]
end
def test_sign_in_with_host_nil
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
-
- util_sign_in [api_key, 200, "OK"], nil, [nil]
+ @fetcher = SignInFetcher.new(host: nil)
+ util_sign_in(args: [nil])
assert_match "Enter your RubyGems.org credentials.",
@sign_in_ui.output
assert @fetcher.last_request["authorization"]
- assert_match %r{Signed in.}, @sign_in_ui.output
+ assert_match(/Signed in./, @sign_in_ui.output)
credentials = load_yaml_file Gem.configuration.credentials_path
- assert_equal api_key, credentials[:rubygems_api_key]
+ assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
end
def test_sign_in_with_host_ENV
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
- util_sign_in [api_key, 200, "OK"], "http://example.com"
+ @fetcher = SignInFetcher.new(host: "http://example.com")
+ util_sign_in
assert_match "Enter your http://example.com credentials.",
@sign_in_ui.output
assert @fetcher.last_request["authorization"]
- assert_match %r{Signed in.}, @sign_in_ui.output
+ assert_match(/Signed in./, @sign_in_ui.output)
credentials = load_yaml_file Gem.configuration.credentials_path
- assert_equal api_key, credentials["http://example.com"]
+ assert_equal @fetcher.api_key, credentials["http://example.com"]
end
def test_sign_in_skips_with_existing_credentials
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
- Gem.configuration.rubygems_api_key = api_key
+ Gem.configuration.rubygems_api_key = @fetcher.api_key
- util_sign_in [api_key, 200, "OK"]
+ util_sign_in
assert_equal "", @sign_in_ui.output
end
def test_sign_in_skips_with_key_override
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
Gem.configuration.api_keys[:KEY] = "other"
@cmd.options[:key] = :KEY
- util_sign_in [api_key, 200, "OK"]
+ util_sign_in
assert_equal "", @sign_in_ui.output
end
def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
other_api_key = "f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf"
+ config = Hash[:other_api_key, other_api_key]
+
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write Hash[:other_api_key, other_api_key].to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(config)
end
- util_sign_in [api_key, 200, "OK"]
+ util_sign_in
- assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
- assert_match %r{Signed in.}, @sign_in_ui.output
+ assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output)
+ assert_match(/Signed in./, @sign_in_ui.output)
credentials = load_yaml_file Gem.configuration.credentials_path
- assert_equal api_key, credentials[:rubygems_api_key]
+ assert_equal @fetcher.api_key, credentials[:rubygems_api_key]
assert_equal other_api_key, credentials[:other_api_key]
end
def test_sign_in_with_bad_credentials
+ @fetcher.respond_with_forbidden_api_key_response
assert_raise Gem::MockGemUi::TermError do
- util_sign_in ["Access Denied.", 403, "Forbidden"]
+ util_sign_in
end
- assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
- assert_match %r{Access Denied.}, @sign_in_ui.output
+ assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output)
+ assert_match(/Access Denied./, @sign_in_ui.output)
end
def test_signin_with_env_otp_code
ENV["GEM_HOST_OTP_CODE"] = "111111"
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
- util_sign_in [api_key, 200, "OK"]
+ util_sign_in
assert_match "Signed in with API key:", @sign_in_ui.output
assert_equal "111111", @fetcher.last_request["OTP"]
end
def test_sign_in_with_correct_otp_code
- api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
- response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
-
- util_sign_in(proc do
- @call_count ||= 0
- (@call_count += 1).odd? ? [response_fail, 401, "Unauthorized"] : [api_key, 200, "OK"]
- end, nil, [], "111111\n")
+ @fetcher.respond_with_require_otp
+ util_sign_in(extra_input: "111111\n")
assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @sign_in_ui.output
assert_match "Code: ", @sign_in_ui.output
@@ -216,8 +211,9 @@ class TestGemGemcutterUtilities < Gem::TestCase
def test_sign_in_with_incorrect_otp_code
response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
+ @fetcher.respond_with_unauthorized_api_key_response
assert_raise Gem::MockGemUi::TermError do
- util_sign_in [response, 401, "Unauthorized"], nil, [], "111111\n"
+ util_sign_in(extra_input: "111111\n")
end
assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @sign_in_ui.output
@@ -226,23 +222,91 @@ class TestGemGemcutterUtilities < Gem::TestCase
assert_equal "111111", @fetcher.last_request["OTP"]
end
- def util_sign_in(response, host = nil, args = [], extra_input = "")
- email = "you@example.com"
- password = "secret"
- profile_response = [ "mfa: disabled\n" , 200, "OK"]
+ def test_sign_in_with_webauthn_enabled
+ server = Gem::MockTCPServer.new
+
+ @fetcher.respond_with_require_otp
+ @fetcher.respond_with_webauthn_url
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do
+ util_sign_in
+ end
+ end
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
+ end
+
+ def test_sign_in_with_webauthn_enabled_with_error
+ server = Gem::MockTCPServer.new
+ error = Gem::WebauthnVerificationError.new("Something went wrong")
+
+ @fetcher.respond_with_require_otp
+ @fetcher.respond_with_webauthn_url
+ error = assert_raise Gem::MockGemUi::TermError do
+ TCPServer.stub(:new, server) do
+ Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do
+ util_sign_in
+ end
+ end
+ end
+ assert_equal 1, error.exit_code
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
+ assert_match "ERROR: Security device verification failed: Something went wrong", @sign_in_ui.error
+ refute_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
+ refute_match "Signed in with API key:", @sign_in_ui.output
+ end
+
+ def test_sign_in_with_webauthn_enabled_with_polling
+ server = Gem::MockTCPServer.new
+ @fetcher.respond_with_require_otp
+ @fetcher.respond_with_webauthn_url
+ @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo")
+
+ TCPServer.stub(:new, server) do
+ util_sign_in
+ end
+
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
+ assert_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output
+ assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"]
+ end
+
+ def test_sign_in_with_webauthn_enabled_with_polling_failure
+ server = Gem::MockTCPServer.new
+ @fetcher.respond_with_require_otp
+ @fetcher.respond_with_webauthn_url
+ @fetcher.respond_with_webauthn_polling_failure
- if host
- ENV["RUBYGEMS_HOST"] = host
- else
- host = Gem.host
+ assert_raise Gem::MockGemUi::TermError do
+ TCPServer.stub(:new, server) do
+ util_sign_in
+ end
end
- @fetcher = Gem::FakeFetcher.new
- @fetcher.data["#{host}/api/v1/api_key"] = response
- @fetcher.data["#{host}/api/v1/profile/me.yaml"] = profile_response
+ assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \
+ "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \
+ "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output
+ assert_match "ERROR: Security device verification failed: " \
+ "The token in the link you used has either expired or been used already.", @sign_in_ui.error
+ end
+
+ def util_sign_in(args: [], extra_input: "")
+ email = "you@example.com"
+ password = "secret"
+
+ ENV["RUBYGEMS_HOST"] = @fetcher.host
Gem::RemoteFetcher.fetcher = @fetcher
- @sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n" + extra_input)
+ @sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n" + extra_input)
use_ui @sign_in_ui do
if args.length > 0
@@ -254,9 +318,9 @@ class TestGemGemcutterUtilities < Gem::TestCase
end
def test_verify_api_key
- keys = { :other => "a5fdbb6ba150cbb83aad2bb2fede64cf040453903" }
+ keys = { other: "a5fdbb6ba150cbb83aad2bb2fede64cf040453903" }
File.open Gem.configuration.credentials_path, "w" do |f|
- f.write keys.to_yaml
+ f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys)
end
Gem.configuration.load_api_keys
@@ -269,4 +333,29 @@ class TestGemGemcutterUtilities < Gem::TestCase
@cmd.verify_api_key :missing
end
end
+
+ class SignInFetcher < Gem::MultifactorAuthFetcher
+ attr_reader :api_key
+
+ def initialize(host: nil)
+ super(host: host)
+ @api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903"
+ @data["#{@host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: @api_key, code: 200, msg: "OK")
+ @data["#{@host}/api/v1/profile/me.yaml"] = Gem::HTTPResponseFactory.create(body: "mfa: disabled\n", code: 200, msg: "OK")
+ end
+
+ def respond_with_require_otp
+ super("#{host}/api/v1/api_key", @api_key)
+ end
+
+ def respond_with_forbidden_api_key_response
+ @data["#{host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: "Access Denied.", code: 403, msg: "Forbidden")
+ end
+
+ def respond_with_unauthorized_api_key_response
+ response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry."
+
+ @data["#{host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized")
+ end
+ end
end
diff --git a/test/rubygems/test_gem_impossible_dependencies_error.rb b/test/rubygems/test_gem_impossible_dependencies_error.rb
index 59395f0bbd..94c0290ea1 100644
--- a/test/rubygems/test_gem_impossible_dependencies_error.rb
+++ b/test/rubygems/test_gem_impossible_dependencies_error.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemImpossibleDependenciesError < Gem::TestCase
diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb
deleted file mode 100644
index cfdff6e4c5..0000000000
--- a/test/rubygems/test_gem_indexer.rb
+++ /dev/null
@@ -1,361 +0,0 @@
-# frozen_string_literal: true
-require_relative "helper"
-require "rubygems/indexer"
-
-class TestGemIndexer < Gem::TestCase
- def setup
- super
-
- util_make_gems
-
- @d2_0 = util_spec "d", "2.0" do |s|
- s.date = Gem::Specification::TODAY - 86400 * 3
- end
- util_build_gem @d2_0
-
- @d2_0_a = util_spec "d", "2.0.a"
- util_build_gem @d2_0_a
-
- @d2_0_b = util_spec "d", "2.0.b"
- util_build_gem @d2_0_b
-
- @default = new_default_spec "default", 2
- install_default_gems @default
-
- @indexerdir = File.join(@tempdir, "indexer")
-
- gems = File.join(@indexerdir, "gems")
- FileUtils.mkdir_p gems
- FileUtils.mv Dir[File.join(@gemhome, "cache", "*.gem")], gems
-
- @indexer = Gem::Indexer.new(@indexerdir)
- end
-
- def test_initialize
- assert_equal @indexerdir, @indexer.dest_directory
- assert_match %r{#{Dir.mktmpdir('gem_generate_index').match(/.*-/)}}, @indexer.directory
-
- indexer = Gem::Indexer.new @indexerdir
- assert indexer.build_modern
-
- indexer = Gem::Indexer.new @indexerdir, :build_modern => true
- assert indexer.build_modern
- end
-
- def test_build_indices
- @indexer.make_temp_directories
-
- use_ui @ui do
- @indexer.build_indices
- end
-
- specs_path = File.join @indexer.directory, "specs.#{@marshal_version}"
- specs_dump = Gem.read_binary specs_path
- specs = Marshal.load specs_dump
-
- expected = [["a", Gem::Version.new("1"), "ruby"],
- ["a", Gem::Version.new("2"), "ruby"],
- ["a_evil", Gem::Version.new("9"), "ruby"],
- ["b", Gem::Version.new("2"), "ruby"],
- ["c", Gem::Version.new("1.2"), "ruby"],
- ["d", Gem::Version.new("2.0"), "ruby"],
- ["dep_x", Gem::Version.new("1"), "ruby"],
- ["pl", Gem::Version.new("1"), "i386-linux"],
- ["x", Gem::Version.new("1"), "ruby"]]
-
- assert_equal expected, specs
-
- latest_specs_path = File.join(@indexer.directory,
- "latest_specs.#{@marshal_version}")
- latest_specs_dump = Gem.read_binary latest_specs_path
- latest_specs = Marshal.load latest_specs_dump
-
- expected = [["a", Gem::Version.new("2"), "ruby"],
- ["a_evil", Gem::Version.new("9"), "ruby"],
- ["b", Gem::Version.new("2"), "ruby"],
- ["c", Gem::Version.new("1.2"), "ruby"],
- ["d", Gem::Version.new("2.0"), "ruby"],
- ["dep_x", Gem::Version.new("1"), "ruby"],
- ["pl", Gem::Version.new("1"), "i386-linux"],
- ["x", Gem::Version.new("1"), "ruby"]]
-
- assert_equal expected, latest_specs, "latest_specs"
- end
-
- def test_generate_index
- use_ui @ui do
- @indexer.generate_index
- end
-
- quickdir = File.join @indexerdir, "quick"
- marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
-
- assert_directory_exists quickdir
- assert_directory_exists marshal_quickdir
-
- assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
- assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
-
- refute_indexed marshal_quickdir, File.basename(@c1_2.spec_file)
-
- assert_indexed @indexerdir, "specs.#{@marshal_version}"
- assert_indexed @indexerdir, "specs.#{@marshal_version}.gz"
-
- assert_indexed @indexerdir, "latest_specs.#{@marshal_version}"
- assert_indexed @indexerdir, "latest_specs.#{@marshal_version}.gz"
-
- refute_directory_exists @indexer.directory
- end
-
- def test_generate_index_modern
- @indexer.build_modern = true
-
- use_ui @ui do
- @indexer.generate_index
- end
-
- refute_indexed @indexerdir, "yaml"
- refute_indexed @indexerdir, "yaml.Z"
- refute_indexed @indexerdir, "Marshal.#{@marshal_version}"
- refute_indexed @indexerdir, "Marshal.#{@marshal_version}.Z"
-
- quickdir = File.join @indexerdir, "quick"
- marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
-
- assert_directory_exists quickdir, "quickdir should be directory"
- assert_directory_exists marshal_quickdir
-
- refute_indexed quickdir, "index"
- refute_indexed quickdir, "index.rz"
-
- refute_indexed quickdir, "latest_index"
- refute_indexed quickdir, "latest_index.rz"
-
- refute_indexed quickdir, "#{File.basename(@a1.spec_file)}.rz"
- refute_indexed quickdir, "#{File.basename(@a2.spec_file)}.rz"
- refute_indexed quickdir, "#{File.basename(@b2.spec_file)}.rz"
- refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}.rz"
-
- refute_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
- refute_indexed quickdir, "#{File.basename(@pl1.spec_file)}.rz"
-
- assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
- assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
-
- refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}"
- refute_indexed marshal_quickdir, "#{File.basename(@c1_2.spec_file)}"
-
- assert_indexed @indexerdir, "specs.#{@marshal_version}"
- assert_indexed @indexerdir, "specs.#{@marshal_version}.gz"
-
- assert_indexed @indexerdir, "latest_specs.#{@marshal_version}"
- assert_indexed @indexerdir, "latest_specs.#{@marshal_version}.gz"
- end
-
- def test_generate_index_modern_back_to_back
- @indexer.build_modern = true
-
- use_ui @ui do
- @indexer.generate_index
- end
-
- @indexer = Gem::Indexer.new @indexerdir
- @indexer.build_modern = true
-
- use_ui @ui do
- @indexer.generate_index
- end
- quickdir = File.join @indexerdir, "quick"
- marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
-
- assert_directory_exists quickdir
- assert_directory_exists marshal_quickdir
-
- assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz"
- assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz"
-
- assert_indexed @indexerdir, "specs.#{@marshal_version}"
- assert_indexed @indexerdir, "specs.#{@marshal_version}.gz"
-
- assert_indexed @indexerdir, "latest_specs.#{@marshal_version}"
- assert_indexed @indexerdir, "latest_specs.#{@marshal_version}.gz"
- end
-
- def test_generate_index_ui
- use_ui @ui do
- @indexer.generate_index
- end
-
- assert_match %r{^\.\.\.\.\.\.\.\.\.\.\.\.$}, @ui.output
- assert_match %r{^Generating Marshal quick index gemspecs for 12 gems$},
- @ui.output
- assert_match %r{^Complete$}, @ui.output
- assert_match %r{^Generating specs index$}, @ui.output
- assert_match %r{^Generating latest specs index$}, @ui.output
- assert_match %r{^Generating prerelease specs index$}, @ui.output
- assert_match %r{^Complete$}, @ui.output
- assert_match %r{^Compressing indices$}, @ui.output
-
- assert_equal "", @ui.error
- end
-
- def test_generate_index_specs
- use_ui @ui do
- @indexer.generate_index
- end
-
- specs_path = File.join @indexerdir, "specs.#{@marshal_version}"
-
- specs_dump = Gem.read_binary specs_path
- specs = Marshal.load specs_dump
-
- expected = [
- ["a", Gem::Version.new(1), "ruby"],
- ["a", Gem::Version.new(2), "ruby"],
- ["a_evil", Gem::Version.new(9), "ruby"],
- ["b", Gem::Version.new(2), "ruby"],
- ["c", Gem::Version.new("1.2"), "ruby"],
- ["d", Gem::Version.new("2.0"), "ruby"],
- ["dep_x", Gem::Version.new(1), "ruby"],
- ["pl", Gem::Version.new(1), "i386-linux"],
- ["x", Gem::Version.new(1), "ruby"],
- ]
-
- assert_equal expected, specs
-
- assert_same specs[0].first, specs[1].first,
- "identical names not identical"
-
- assert_same specs[0][1], specs[-1][1],
- "identical versions not identical"
-
- assert_same specs[0].last, specs[1].last,
- "identical platforms not identical"
-
- refute_same specs[1][1], specs[5][1],
- "different versions not different"
- end
-
- def test_generate_index_latest_specs
- use_ui @ui do
- @indexer.generate_index
- end
-
- latest_specs_path = File.join @indexerdir, "latest_specs.#{@marshal_version}"
-
- latest_specs_dump = Gem.read_binary latest_specs_path
- latest_specs = Marshal.load latest_specs_dump
-
- expected = [
- ["a", Gem::Version.new(2), "ruby"],
- ["a_evil", Gem::Version.new(9), "ruby"],
- ["b", Gem::Version.new(2), "ruby"],
- ["c", Gem::Version.new("1.2"), "ruby"],
- ["d", Gem::Version.new("2.0"), "ruby"],
- ["dep_x", Gem::Version.new(1), "ruby"],
- ["pl", Gem::Version.new(1), "i386-linux"],
- ["x", Gem::Version.new(1), "ruby"],
- ]
-
- assert_equal expected, latest_specs
-
- assert_same latest_specs[0][1], latest_specs[2][1],
- "identical versions not identical"
-
- assert_same latest_specs[0].last, latest_specs[1].last,
- "identical platforms not identical"
- end
-
- def test_generate_index_prerelease_specs
- use_ui @ui do
- @indexer.generate_index
- end
-
- prerelease_specs_path = File.join @indexerdir, "prerelease_specs.#{@marshal_version}"
-
- prerelease_specs_dump = Gem.read_binary prerelease_specs_path
- prerelease_specs = Marshal.load prerelease_specs_dump
-
- assert_equal [["a", Gem::Version.new("3.a"), "ruby"],
- ["d", Gem::Version.new("2.0.a"), "ruby"],
- ["d", Gem::Version.new("2.0.b"), "ruby"]],
- prerelease_specs
- end
-
- ##
- # Emulate the starting state of Gem::Specification in a live environment,
- # where it will carry the list of system gems
- def with_system_gems
- Gem::Specification.reset
-
- sys_gem = util_spec "systemgem", "1.0"
- util_build_gem sys_gem
- install_default_gems sys_gem
- yield
- util_remove_gem sys_gem
- end
-
- def test_update_index
- use_ui @ui do
- @indexer.generate_index
- end
-
- quickdir = File.join @indexerdir, "quick"
- marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}"
-
- assert_directory_exists quickdir
- assert_directory_exists marshal_quickdir
-
- @d2_1 = util_spec "d", "2.1"
- util_build_gem @d2_1
- @d2_1_tuple = [@d2_1.name, @d2_1.version, @d2_1.original_platform]
-
- @d2_1_a = util_spec "d", "2.2.a"
- util_build_gem @d2_1_a
- @d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform]
-
- gems = File.join @indexerdir, "gems"
-
- FileUtils.mv @d2_1.cache_file, gems
- FileUtils.mv @d2_1_a.cache_file, gems
-
- with_system_gems do
- use_ui @ui do
- @indexer.update_index
- end
-
- assert_indexed marshal_quickdir, "#{File.basename(@d2_1.spec_file)}.rz"
-
- specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index)
-
- assert_includes specs_index, @d2_1_tuple
- refute_includes specs_index, @d2_1_a_tuple
-
- latest_specs_index = Marshal.load \
- Gem.read_binary(@indexer.dest_latest_specs_index)
-
- assert_includes latest_specs_index, @d2_1_tuple
- assert_includes latest_specs_index,
- [@d2_0.name, @d2_0.version, @d2_0.original_platform]
- refute_includes latest_specs_index, @d2_1_a_tuple
-
- pre_specs_index = Marshal.load \
- Gem.read_binary(@indexer.dest_prerelease_specs_index)
-
- assert_includes pre_specs_index, @d2_1_a_tuple
- refute_includes pre_specs_index, @d2_1_tuple
-
- refute_directory_exists @indexer.directory
- end
- end
-
- def assert_indexed(dir, name)
- file = File.join dir, name
- assert File.exist?(file), "#{file} does not exist"
- end
-
- def refute_indexed(dir, name)
- file = File.join dir, name
- refute File.exist?(file), "#{file} exists"
- end
-end
diff --git a/test/rubygems/test_gem_install_update_options.rb b/test/rubygems/test_gem_install_update_options.rb
index e2225a1eba..8fd5d9c543 100644
--- a/test/rubygems/test_gem_install_update_options.rb
+++ b/test/rubygems/test_gem_install_update_options.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "installer_test_case"
require "rubygems/install_update_options"
require "rubygems/command"
@@ -129,6 +130,9 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
end
def test_user_install_disabled_read_only
+ pend "skipped on MS Windows (chmod has no effect)" if Gem.win_platform?
+ pend "skipped in root privilege" if Process.uid.zero?
+
@spec = quick_gem "a" do |spec|
util_make_exec spec
end
@@ -136,26 +140,20 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase
util_build_gem @spec
@gem = @spec.cache_file
- if win_platform?
- pend("test_user_install_disabled_read_only test skipped on MS Windows")
- elsif Process.uid.zero?
- pend("test_user_install_disabled_read_only test skipped in root privilege")
- else
- @cmd.handle_options %w[--no-user-install]
+ @cmd.handle_options %w[--no-user-install]
- refute @cmd.options[:user_install]
+ refute @cmd.options[:user_install]
- FileUtils.chmod 0755, @userhome
- FileUtils.chmod 0000, @gemhome
+ FileUtils.chmod 0o755, @userhome
+ FileUtils.chmod 0o000, @gemhome
- Gem.use_paths @gemhome, @userhome
+ Gem.use_paths @gemhome, @userhome
- assert_raise(Gem::FilePermissionError) do
- Gem::Installer.at(@gem, @cmd.options).install
- end
+ assert_raise(Gem::FilePermissionError) do
+ Gem::Installer.at(@gem, @cmd.options).install
end
ensure
- FileUtils.chmod 0755, @gemhome
+ FileUtils.chmod 0o755, @gemhome
end
def test_vendor
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
index 0d0746ec84..61609a26c9 100644
--- a/test/rubygems/test_gem_installer.rb
+++ b/test/rubygems/test_gem_installer.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "installer_test_case"
class TestGemInstaller < Gem::InstallerTestCase
@@ -83,7 +84,7 @@ end
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
end
def test_check_executable_overwrite_default_bin_dir
@@ -99,8 +100,8 @@ end
end
conflicted = File.join @gemhome, "bin", "executable"
- assert_match %r{\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z},
- e.message
+ assert_match(/\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z/,
+ e.message)
end
end
end
@@ -141,7 +142,7 @@ gem 'other', version
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
ensure
Gem::Installer.exec_format = nil
end
@@ -176,7 +177,7 @@ gem 'other', version
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
end
def test_check_executable_overwrite_other_non_gem
@@ -191,7 +192,7 @@ gem 'other', version
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
end unless Gem.win_platform?
def test_check_that_user_bin_dir_is_in_path
@@ -203,8 +204,8 @@ gem 'other', version
bin_dir = bin_dir.downcase
end
- orig_PATH, ENV["PATH"] =
- ENV["PATH"], [ENV["PATH"], bin_dir].join(File::PATH_SEPARATOR)
+ orig_path = ENV["PATH"]
+ ENV["PATH"] = [ENV["PATH"], bin_dir].join(File::PATH_SEPARATOR)
use_ui @ui do
installer.check_that_user_bin_dir_is_in_path
@@ -212,9 +213,9 @@ gem 'other', version
assert_empty @ui.error
- return unless win_platform?
+ return unless Gem.win_platform?
- ENV["PATH"] = [orig_PATH, bin_dir.tr(File::SEPARATOR, File::ALT_SEPARATOR)].join(File::PATH_SEPARATOR)
+ ENV["PATH"] = [orig_path, bin_dir.tr(File::SEPARATOR, File::ALT_SEPARATOR)].join(File::PATH_SEPARATOR)
use_ui @ui do
installer.check_that_user_bin_dir_is_in_path
@@ -222,14 +223,14 @@ gem 'other', version
assert_empty @ui.error
ensure
- ENV["PATH"] = orig_PATH
+ ENV["PATH"] = orig_path
end
def test_check_that_user_bin_dir_is_in_path_tilde
- pend "Tilde is PATH is not supported under MS Windows" if win_platform?
+ pend "Tilde is PATH is not supported under MS Windows" if Gem.win_platform?
- orig_PATH, ENV["PATH"] =
- ENV["PATH"], [ENV["PATH"], "~/bin"].join(File::PATH_SEPARATOR)
+ orig_path = ENV["PATH"]
+ ENV["PATH"] = [ENV["PATH"], "~/bin"].join(File::PATH_SEPARATOR)
installer = setup_base_installer
installer.bin_dir.replace File.join @userhome, "bin"
@@ -240,7 +241,7 @@ gem 'other', version
assert_empty @ui.error
ensure
- ENV["PATH"] = orig_PATH unless win_platform?
+ ENV["PATH"] = orig_path unless Gem.win_platform?
end
def test_check_that_user_bin_dir_is_in_path_not_in_path
@@ -286,7 +287,7 @@ gem 'other', version
installer.ensure_loadable_spec
end
- assert_equal "The specification for #{a.full_name} is corrupt " +
+ assert_equal "The specification for #{a.full_name} is corrupt " \
"(SyntaxError)", e.message
end
@@ -298,7 +299,7 @@ gem 'other', version
end
policy = Gem::Security::HighSecurity
- installer = Gem::Installer.at a_gem, :security_policy => policy
+ installer = Gem::Installer.at a_gem, security_policy: policy
assert_raise Gem::Security::Exception do
installer.ensure_loadable_spec
@@ -334,22 +335,25 @@ gem 'other', version
assert_directory_exists util_inst_bindir
installed_exec = File.join(util_inst_bindir, "executable")
assert_path_exist installed_exec
- assert_equal mask, File.stat(installed_exec).mode unless win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform?
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
end
def test_generate_bin_bindir_with_user_install_warning
- bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]).upcase :
- "/usr/bin"
+ bin_dir = if Gem.win_platform?
+ File.expand_path(ENV["WINDIR"]).upcase
+ else
+ "/usr/bin"
+ end
old_path = ENV["PATH"]
ENV["PATH"] = [ENV["PATH"], bin_dir].compact.join(File::PATH_SEPARATOR)
options = {
- :bin_dir => bin_dir,
- :install_dir => "/non/existent",
+ bin_dir: bin_dir,
+ install_dir: "/non/existent",
}
inst = Gem::Installer.at "", options
@@ -361,7 +365,6 @@ gem 'other', version
end
assert_equal "", @ui.error
-
ensure
ENV["PATH"] = old_path
end
@@ -377,10 +380,10 @@ gem 'other', version
assert_directory_exists util_inst_bindir
installed_exec = File.join util_inst_bindir, "executable"
assert_path_exist installed_exec
- assert_equal mask, File.stat(installed_exec).mode unless win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform?
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
end
def test_generate_bin_script_format
@@ -436,10 +439,10 @@ gem 'other', version
installed_exec = File.join("#{@gemhome}2", "bin", "executable")
assert_path_exist installed_exec
- assert_equal mask, File.stat(installed_exec).mode unless win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform?
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
end
def test_generate_bin_script_no_execs
@@ -461,19 +464,19 @@ gem 'other', version
Dir.mkdir util_inst_bindir
- if win_platform?
+ if Gem.win_platform?
pend("test_generate_bin_script_no_perms skipped on MS Windows")
elsif Process.uid.zero?
pend("test_generate_bin_script_no_perms skipped in root privilege")
else
- FileUtils.chmod 0000, util_inst_bindir
+ FileUtils.chmod 0o000, util_inst_bindir
assert_raise Gem::FilePermissionError do
installer.generate_bin
end
end
ensure
- FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG || win_platform?)
+ FileUtils.chmod 0o755, util_inst_bindir unless $DEBUG || Gem.win_platform?
end
def test_generate_bin_script_no_shebang
@@ -493,12 +496,12 @@ gem 'other', version
installed_exec = File.join @gemhome, "bin", "executable"
assert_path_exist installed_exec
- assert_equal mask, File.stat(installed_exec).mode unless win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform?
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
- # HACK some gems don't have #! in their executables, restore 2008/06
- #assert_no_match %r|generated by RubyGems|, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
+ # HACK: some gems don't have #! in their executables, restore 2008/06
+ # assert_no_match %r|generated by RubyGems|, wrapper
end
def test_generate_bin_script_wrappers
@@ -520,12 +523,12 @@ gem 'other', version
installer.generate_bin
assert_directory_exists util_inst_bindir
assert_path_exist installed_exec
- assert_equal mask, File.stat(installed_exec).mode unless win_platform?
+ assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform?
- assert_match %r{generated by RubyGems}, File.read(installed_exec)
+ assert_match(/generated by RubyGems/, File.read(installed_exec))
- refute_match %r{generated by RubyGems}, File.read(real_exec),
- "real executable overwritten"
+ refute_match(/generated by RubyGems/, File.read(real_exec),
+ "real executable overwritten")
end
def test_generate_bin_symlink
@@ -565,19 +568,19 @@ gem 'other', version
Dir.mkdir util_inst_bindir
- if win_platform?
+ if Gem.win_platform?
pend("test_generate_bin_symlink_no_perms skipped on MS Windows")
elsif Process.uid.zero?
pend("test_user_install_disabled_read_only test skipped in root privilege")
else
- FileUtils.chmod 0000, util_inst_bindir
+ FileUtils.chmod 0o000, util_inst_bindir
assert_raise Gem::FilePermissionError do
installer.generate_bin
end
end
ensure
- FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG || win_platform?)
+ FileUtils.chmod 0o755, util_inst_bindir unless $DEBUG || Gem.win_platform?
end
def test_generate_bin_symlink_update_newer
@@ -735,9 +738,9 @@ gem 'other', version
installer.generate_bin
default_shebang = Gem.ruby
- shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first }
+ shebang_line = File.open("#{@gemhome}/bin/executable", &:gets)
assert_match(/\A#!/, shebang_line)
- assert_match(/#{default_shebang}/, shebang_line)
+ assert_include(shebang_line, default_shebang)
end
end
@@ -746,8 +749,8 @@ gem 'other', version
installer = Gem::Installer.at(
gem_with_dangling_symlink,
- :user_install => false,
- :force => true
+ user_install: false,
+ force: true
)
build_rake_in do
@@ -766,7 +769,7 @@ gem 'other', version
def test_generate_plugins
installer = util_setup_installer do |spec|
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
- io.write "puts __FILE__"
+ io.write "# do nothing"
end
spec.files += %w[lib/rubygems_plugin.rb]
@@ -815,10 +818,10 @@ gem 'other', version
util_build_gem spec
- File.chmod(0555, Gem.plugindir)
+ File.chmod(0o555, Gem.plugindir)
system_path = File.join(Gem.plugindir, "a_plugin.rb")
user_path = File.join(Gem.plugindir(Gem.user_dir), "a_plugin.rb")
- installer = util_installer spec, Gem.dir, :user
+ installer = Gem::Installer.at spec.cache_file, user_install: true, force: true
assert_equal spec, installer.install
@@ -837,13 +840,13 @@ gem 'other', version
util_build_gem spec
- File.chmod(0555, Gem.plugindir)
+ File.chmod(0o555, Gem.plugindir)
system_path = File.join(Gem.plugindir, "a_plugin.rb")
build_root = File.join(@tempdir, "build_root")
build_root_path = File.join(build_root, Gem.plugindir.gsub(/^[a-zA-Z]:/, ""), "a_plugin.rb")
- installer = Gem::Installer.at spec.cache_file, :build_root => build_root
+ installer = Gem::Installer.at spec.cache_file, build_root: build_root
assert_equal spec, installer.install
@@ -853,11 +856,59 @@ gem 'other', version
refute_includes File.read(build_root_path), build_root
end
+ class << self
+ attr_accessor :plugin_loaded
+ attr_accessor :post_install_is_called
+ end
+
+ def test_use_plugin_immediately
+ self.class.plugin_loaded = false
+ self.class.post_install_is_called = false
+ spec_version = nil
+ plugin_path = nil
+ installer = util_setup_installer do |spec|
+ spec_version = spec.version
+ plugin_path = File.join("lib", "rubygems_plugin.rb")
+ write_file File.join(@tempdir, plugin_path) do |io|
+ io.write <<-PLUGIN
+#{self.class}.plugin_loaded = true
+Gem.post_install do
+ #{self.class}.post_install_is_called = true
+end
+ PLUGIN
+ end
+ spec.files += [plugin_path]
+ plugin_path = File.join(spec.gem_dir, plugin_path)
+ end
+ build_rake_in do
+ installer.install
+ end
+ assert self.class.plugin_loaded, "plugin is not loaded"
+ assert self.class.post_install_is_called,
+ "post install hook registered by plugin is not called"
+
+ self.class.plugin_loaded = false
+ $LOADED_FEATURES.delete(plugin_path)
+ installer_new = util_setup_installer do |spec_new|
+ spec_new.version = spec_version.version.succ
+ plugin_path = File.join("lib", "rubygems_plugin.rb")
+ write_file File.join(@tempdir, plugin_path) do |io|
+ io.write "#{self.class}.plugin_loaded = true"
+ end
+ spec_new.files += [plugin_path]
+ end
+ build_rake_in do
+ installer_new.install
+ end
+ assert !self.class.plugin_loaded,
+ "plugin is loaded even when old version is already loaded"
+ end
+
def test_keeps_plugins_up_to_date
# NOTE: version a-2 is already installed by setup hooks
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
- io.write "puts __FILE__"
+ io.write "# do nothing"
end
build_rake_in do
@@ -902,7 +953,7 @@ gem 'other', version
path = Gem::Package.build @spec
- installer = Gem::Installer.at path, :install_dir => "#{@gemhome}3"
+ installer = Gem::Installer.at path, install_dir: "#{@gemhome}3"
assert_equal @spec, installer.install
end
@@ -926,7 +977,7 @@ gem 'other', version
def test_initialize_user_install
@gem = setup_base_gem
- installer = Gem::Installer.at @gem, :user_install => true
+ installer = Gem::Installer.at @gem, user_install: true
assert_equal File.join(Gem.user_dir, "gems", @spec.full_name),
installer.gem_dir
@@ -937,13 +988,26 @@ gem 'other', version
@gem = setup_base_gem
installer =
- Gem::Installer.at @gem, :user_install => true, :bin_dir => @tempdir
+ Gem::Installer.at @gem, user_install: true, bin_dir: @tempdir
assert_equal File.join(Gem.user_dir, "gems", @spec.full_name),
installer.gem_dir
assert_equal @tempdir, installer.bin_dir
end
+ def test_install_dir_takes_precedence_to_user_install
+ gemhome2 = "#{@gemhome}2"
+
+ @gem = setup_base_gem
+
+ installer =
+ Gem::Installer.at @gem, install_dir: gemhome2, user_install: true
+ installer.install
+
+ assert_path_exist File.join(gemhome2, "gems", @spec.full_name)
+ assert_path_not_exist File.join(Gem.user_dir, "gems", @spec.full_name)
+ end
+
def test_install
installer = util_setup_installer
@@ -983,8 +1047,8 @@ gem 'other', version
exe = File.join gemdir, "bin", "executable"
assert_path_exist exe
- exe_mode = File.stat(exe).mode & 0111
- assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
+ exe_mode = File.stat(exe).mode & 0o111
+ assert_equal 0o111, exe_mode, format("0%o", exe_mode) unless Gem.win_platform?
assert_path_exist File.join gemdir, "lib", "code.rb"
@@ -1025,7 +1089,7 @@ gem 'other', version
@gem = setup_base_gem
# build old version that has a bin file
- installer = util_setup_gem do |spec|
+ installer = util_setup_gem do |_spec|
File.open File.join("bin", "executable"), "w" do |f|
f.puts "require 'code'"
end
@@ -1186,7 +1250,7 @@ gem 'other', version
Gem::Package.build @spec
end
end
- installer = Gem::Installer.at @gem, :force => true
+ installer = Gem::Installer.at @gem, force: true
build_rake_in do
use_ui @ui do
assert_equal @spec, installer.install
@@ -1204,7 +1268,7 @@ gem 'other', version
end
use_ui @ui do
- installer = Gem::Installer.at missing_dep_gem, :force => true
+ installer = Gem::Installer.at missing_dep_gem, force: true
installer.install
end
@@ -1216,11 +1280,31 @@ gem 'other', version
build_root = File.join(@tempdir, "build_root")
@gem = setup_base_gem
- installer = Gem::Installer.at @gem, :build_root => build_root
+ installer = Gem::Installer.at @gem, build_root: build_root
assert_equal @spec, installer.install
end
+ def test_install_build_root_when_gem_home_not_writable_does_not_fallback_to_user_install_inside_build_root
+ build_root = File.join(@tempdir, "build_root")
+
+ orig_gem_home = ENV.delete("GEM_HOME")
+
+ @gem = setup_base_gem
+
+ FileUtils.chmod "-w", @gemhome
+
+ installer = Gem::Installer.at @gem, build_root: build_root
+
+ assert_equal @spec, installer.install
+
+ build_root_path = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ""))
+ assert File.exist?(build_root_path), "gem not written to build_root"
+ ensure
+ FileUtils.chmod "+w", @gemhome
+ ENV["GEM_HOME"] = orig_gem_home
+ end
+
def test_install_missing_dirs
installer = setup_base_installer
@@ -1335,7 +1419,7 @@ gem 'other', version
installer.install
end
- assert_match %r{I am a shiny gem!}, @ui.output
+ assert_match(/I am a shiny gem!/, @ui.output)
end
def test_install_with_skipped_message
@@ -1345,11 +1429,11 @@ gem 'other', version
use_ui @ui do
path = Gem::Package.build @spec
- installer = Gem::Installer.at path, :post_install_message => false
+ installer = Gem::Installer.at path, post_install_message: false
installer.install
end
- refute_match %r{I am a shiny gem!}, @ui.output
+ refute_match(/I am a shiny gem!/, @ui.output)
end
def test_install_extension_dir
@@ -1369,7 +1453,7 @@ gem 'other', version
use_ui @ui do
path = Gem::Package.build @spec
- installer = Gem::Installer.at path, :install_dir => gemhome2
+ installer = Gem::Installer.at path, install_dir: gemhome2
installer.install
end
@@ -1408,7 +1492,7 @@ gem 'other', version
# reinstall the gem, this is also the same as pristine
use_ui @ui do
- installer = Gem::Installer.at path, :force => true
+ installer = Gem::Installer.at path, force: true
installer.install
end
@@ -1434,7 +1518,7 @@ gem 'other', version
use_ui @ui do
path = Gem::Package.build @spec
- installer = Gem::Installer.at path, :user_install => true
+ installer = Gem::Installer.at path, user_install: true
installer.install
end
@@ -1493,7 +1577,7 @@ gem 'other', version
def test_install_extension_and_script
pend "Makefile creation crashes on jruby" if Gem.java_platform?
- pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
+ pend "terminates on mswin" if vc_windows? && ruby_repo?
@spec = setup_base_spec
@spec.extensions << "extconf.rb"
@@ -1559,7 +1643,7 @@ gem 'other', version
write_file File.join(@tempdir, file)
end
- so = File.join(@spec.gem_dir, "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}")
+ so = File.join(@spec.extension_dir, "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}")
assert_path_not_exist so
use_ui @ui do
path = Gem::Package.build @spec
@@ -1568,20 +1652,42 @@ gem 'other', version
installer.install
end
assert_path_exist so
- rescue
- puts "-" * 78
- puts File.read File.join(@gemhome, "gems", "a-2", "Makefile")
- puts "-" * 78
+ end
+ end
- path = File.join(@gemhome, "gems", "a-2", "gem_make.out")
+ def test_install_extension_clean_intermediate_files
+ pend "extensions don't quite work on jruby" if Gem.java_platform?
+ @spec = setup_base_spec
+ @spec.require_paths = ["."]
+ @spec.extensions << "extconf.rb"
- if File.exist?(path)
- puts File.read(path)
- puts "-" * 78
- end
+ File.write File.join(@tempdir, "extconf.rb"), <<-RUBY
+ require "mkmf"
+ CONFIG['CC'] = '$(TOUCH) $@ ||'
+ CONFIG['LDSHARED'] = '$(TOUCH) $@ ||'
+ $ruby = '#{Gem.ruby}'
+ create_makefile("#{@spec.name}")
+ RUBY
+
+ # empty depend file for no auto dependencies
+ @spec.files += %W[depend #{@spec.name}.c].each do |file|
+ write_file File.join(@tempdir, file)
+ end
+
+ shared_object = "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}"
+ extension_file = File.join @spec.extension_dir, shared_object
+ intermediate_file = File.join @spec.gem_dir, shared_object
+
+ assert_path_not_exist extension_file, "no before installing"
+ use_ui @ui do
+ path = Gem::Package.build @spec
- raise
+ installer = Gem::Installer.at path
+ installer.install
end
+
+ assert_path_exist extension_file, "installed"
+ assert_path_not_exist intermediate_file
end
def test_installation_satisfies_dependency_eh
@@ -1651,7 +1757,7 @@ gem 'other', version
# that it work everything out on it's own.
Gem::Specification.reset
- installer = Gem::Installer.at gem, :install_dir => gemhome2
+ installer = Gem::Installer.at gem, install_dir: gemhome2
build_rake_in do
use_ui @ui do
@@ -1665,6 +1771,7 @@ gem 'other', version
def spec.full_name # so the spec is buildable
"malicious-1"
end
+
def spec.validate(packaging, strict); end
util_build_gem spec
@@ -1685,6 +1792,7 @@ gem 'other', version
def spec.full_name # so the spec is buildable
"malicious-1"
end
+
def spec.validate(*args); end
util_build_gem spec
@@ -1706,6 +1814,7 @@ gem 'other', version
def spec.full_name # so the spec is buildable
"malicious-1"
end
+
def spec.validate(*args); end
spec.require_paths = ["malicious\n``"]
@@ -1729,6 +1838,7 @@ gem 'other', version
def spec.full_name # so the spec is buildable
"malicious-1"
end
+
def spec.validate(*args); end
spec.extensions = ["malicious\n``"]
@@ -1750,6 +1860,7 @@ gem 'other', version
def spec.full_name # so the spec is buildable
"malicious-1"
end
+
def spec.validate(*args); end
spec.specification_version = "malicious\n``"
@@ -1771,6 +1882,7 @@ gem 'other', version
def spec.full_name # so the spec is buildable
"malicious-1"
end
+
def spec.validate(*args); end
spec.add_dependency "b\nfoo", "> 5"
@@ -1793,9 +1905,9 @@ gem 'other', version
installer = Gem::Installer.at(
gem_with_ill_formated_platform,
- :install_dir => @gem_home,
- :user_install => false,
- :force => true
+ install_dir: @gemhome,
+ user_install: false,
+ force: true
)
use_ui @ui do
@@ -1835,7 +1947,7 @@ gem 'other', version
plugins_dir = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ""), "plugins")
@gem = setup_base_gem
- installer = use_ui(@ui) { Gem::Installer.at @gem, :build_root => build_root }
+ installer = use_ui(@ui) { Gem::Installer.at @gem, build_root: build_root }
assert_equal build_root, installer.build_root
assert_equal bin_dir, installer.bin_dir
@@ -1850,6 +1962,48 @@ gem 'other', version
assert_equal " Plugins dir: #{plugins_dir}", errors.shift
end
+ def test_process_options_fallback_to_user_install_when_gem_home_not_writable
+ if Process.uid.zero?
+ pend("skipped in root privilege")
+ return
+ end
+
+ orig_gem_home = ENV.delete("GEM_HOME")
+
+ @gem = setup_base_gem
+
+ FileUtils.chmod 0o000, @gemhome
+
+ installer = use_ui(@ui) { Gem::Installer.at @gem }
+
+ assert_equal Gem.user_dir, installer.gem_home
+ assert_equal "Defaulting to user installation because default installation directory (#{@gemhome}) is not writable.", @ui.output.strip
+ ensure
+ FileUtils.chmod 0o755, @gemhome
+ ENV["GEM_HOME"] = orig_gem_home
+ end
+
+ def test_process_options_does_not_fallback_to_user_install_when_gem_home_not_writable_and_no_user_install
+ if Process.uid.zero?
+ pend("skipped in root privilege")
+ return
+ end
+
+ orig_gem_home = ENV.delete("GEM_HOME")
+
+ @gem = setup_base_gem
+
+ FileUtils.chmod 0o000, @gemhome
+
+ installer = use_ui(@ui) { Gem::Installer.at @gem, user_install: false }
+
+ assert_equal @gemhome, installer.gem_home
+ assert_empty @ui.output.strip
+ ensure
+ FileUtils.chmod 0o755, @gemhome
+ ENV["GEM_HOME"] = orig_gem_home
+ end
+
def test_shebang_arguments
load_relative "no" do
installer = setup_base_installer
@@ -1937,7 +2091,7 @@ gem 'other', version
bin_env = get_bin_env
- assert_equal("#!#{bin_env} #{RbConfig::CONFIG['ruby_install_name']}",
+ assert_equal("#!#{bin_env} #{RbConfig::CONFIG["ruby_install_name"]}",
shebang)
end
@@ -2074,7 +2228,7 @@ gem 'other', version
end
def get_bin_env
- if win_platform?
+ if Gem.win_platform?
""
else
%w[/usr/bin/env /bin/env].find {|f| File.executable?(f) }
@@ -2156,7 +2310,7 @@ gem 'other', version
def test_write_build_info_file_install_dir
@gem = setup_base_gem
- installer = Gem::Installer.at @gem, :install_dir => "#{@gemhome}2"
+ installer = Gem::Installer.at @gem, install_dir: "#{@gemhome}2"
installer.build_args = %w[
--with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4
@@ -2222,6 +2376,37 @@ gem 'other', version
assert_equal @spec, eval(File.read(@spec.spec_file))
end
+ def test_leaves_no_empty_cached_spec_when_no_more_disk_space
+ @spec = setup_base_spec
+ FileUtils.rm @spec.spec_file
+ assert_path_not_exist @spec.spec_file
+
+ @spec.files = %w[a.rb b.rb c.rb]
+
+ installer = Gem::Installer.for_spec @spec
+ installer.gem_home = @gemhome
+
+ File.class_eval do
+ alias_method :original_write, :write
+
+ def write(data)
+ raise Errno::ENOSPC
+ end
+ end
+
+ assert_raise Errno::ENOSPC do
+ installer.write_spec
+ end
+
+ assert_path_not_exist @spec.spec_file
+ ensure
+ File.class_eval do
+ remove_method :write
+ alias_method :write, :original_write
+ remove_method :original_write
+ end
+ end
+
def test_dir
installer = setup_base_installer
@@ -2230,7 +2415,7 @@ gem 'other', version
def test_default_gem_loaded_from
spec = util_spec "a"
- installer = Gem::Installer.for_spec spec, :install_as_default => true
+ installer = Gem::Installer.for_spec spec, install_as_default: true
installer.install
assert_predicate spec, :default_gem?
end
@@ -2267,10 +2452,10 @@ gem 'other', version
wrapper = File.read installed_exec
if symlink_supported?
- refute_match %r{generated by RubyGems}, wrapper
+ refute_match(/generated by RubyGems/, wrapper)
else # when symlink not supported, it warns and fallbacks back to installing wrapper
- assert_match %r{Unable to use symlinks, installing wrapper}, @ui.error
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/Unable to use symlinks, installing wrapper/, @ui.error)
+ assert_match(/generated by RubyGems/, wrapper)
end
end
@@ -2291,7 +2476,7 @@ gem 'other', version
assert_path_exist installed_exec
wrapper = File.read installed_exec
- assert_match %r{generated by RubyGems}, wrapper
+ assert_match(/generated by RubyGems/, wrapper)
end
def test_default_gem_with_exe_as_bindir
@@ -2383,15 +2568,15 @@ gem 'other', version
end
def mask
- 0100755
+ 0o100755
end
def load_relative(value)
- orig_LIBRUBY_RELATIVE = RbConfig::CONFIG["LIBRUBY_RELATIVE"]
+ orig_libruby_relative = RbConfig::CONFIG["LIBRUBY_RELATIVE"]
RbConfig::CONFIG["LIBRUBY_RELATIVE"] = value
yield
ensure
- RbConfig::CONFIG["LIBRUBY_RELATIVE"] = orig_LIBRUBY_RELATIVE
+ RbConfig::CONFIG["LIBRUBY_RELATIVE"] = orig_libruby_relative
end
end
diff --git a/test/rubygems/test_gem_local_remote_options.rb b/test/rubygems/test_gem_local_remote_options.rb
index 0c662a3f50..cea9cde82b 100644
--- a/test/rubygems/test_gem_local_remote_options.rb
+++ b/test/rubygems/test_gem_local_remote_options.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/local_remote_options"
require "rubygems/command"
@@ -33,7 +34,7 @@ class TestGemLocalRemoteOptions < Gem::TestCase
def test_clear_sources_option
@cmd.add_local_remote_options
- s = URI.parse "http://only-gems.example.com/"
+ s = Gem::URI.parse "http://only-gems.example.com/"
@cmd.handle_options %W[--clear-sources --source #{s}]
assert_equal [s.to_s], Gem.sources
@@ -75,10 +76,10 @@ class TestGemLocalRemoteOptions < Gem::TestCase
def test_source_option
@cmd.add_source_option
- s1 = URI.parse "http://more-gems.example.com/"
- s2 = URI.parse "http://even-more-gems.example.com/"
- s3 = URI.parse "http://other-gems.example.com/some_subdir"
- s4 = URI.parse "http://more-gems.example.com/" # Intentional duplicate
+ s1 = Gem::URI.parse "http://more-gems.example.com/"
+ s2 = Gem::URI.parse "http://even-more-gems.example.com/"
+ s3 = Gem::URI.parse "http://other-gems.example.com/some_subdir"
+ s4 = Gem::URI.parse "http://more-gems.example.com/" # Intentional duplicate
original_sources = Gem.sources.dup
@@ -96,7 +97,7 @@ class TestGemLocalRemoteOptions < Gem::TestCase
original_sources = Gem.sources.dup
- source = URI.parse "http://more-gems.example.com/"
+ source = Gem::URI.parse "http://more-gems.example.com/"
@cmd.handle_options %W[-s #{source}]
original_sources << source
diff --git a/test/rubygems/test_gem_name_tuple.rb b/test/rubygems/test_gem_name_tuple.rb
index 6eca69084c..bdb8181ce8 100644
--- a/test/rubygems/test_gem_name_tuple.rb
+++ b/test/rubygems/test_gem_name_tuple.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/name_tuple"
@@ -18,14 +19,31 @@ class TestGemNameTuple < Gem::TestCase
end
def test_platform_normalization
- n = Gem::NameTuple.new "a", Gem::Version.new(0), "ruby"
- assert_equal "ruby", n.platform
-
- n = Gem::NameTuple.new "a", Gem::Version.new(0), nil
- assert_equal "ruby", n.platform
-
- n = Gem::NameTuple.new "a", Gem::Version.new(0), ""
- assert_equal "ruby", n.platform
+ a = Gem::NameTuple.new "a", Gem::Version.new(0), "ruby"
+ b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform::RUBY
+ assert_equal a, b
+ assert_equal a.hash, b.hash
+
+ a = Gem::NameTuple.new "a", Gem::Version.new(0), nil
+ b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.new("ruby")
+ assert_equal a, b
+ assert_equal a.hash, b.hash
+
+ a = Gem::NameTuple.new "a", Gem::Version.new(0), ""
+ b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.new("ruby")
+ assert_equal a, b
+ assert_equal a.hash, b.hash
+
+ a = Gem::NameTuple.new "a", Gem::Version.new(0), "universal-darwin-23"
+ b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.new("universal-darwin-23")
+ assert_equal a, b
+ assert_equal a.hash, b.hash
+
+ # Gem::Platform does normalization so that these are equal (note the missing dash before 21)
+ a = Gem::NameTuple.new "a", Gem::Version.new(0), "universal-darwin-21"
+ b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.new("universal-darwin21")
+ assert_equal a, b
+ assert_equal a.hash, b.hash
end
def test_spec_name
diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb
index 9295f42dba..2065864107 100644
--- a/test/rubygems/test_gem_package.rb
+++ b/test/rubygems/test_gem_package.rb
@@ -189,7 +189,7 @@ class TestGemPackage < Gem::Package::TarTestCase
File.symlink("code.rb", "lib/code_sym.rb")
File.symlink("../lib/code.rb", "lib/code_sym2.rb")
rescue Errno::EACCES => e
- if win_platform?
+ if Gem.win_platform?
pend "symlink - must be admin with no UAC on Windows"
else
raise e
@@ -205,7 +205,8 @@ class TestGemPackage < Gem::Package::TarTestCase
tar.rewind
- files, symlinks = [], []
+ files = []
+ symlinks = []
Gem::Package::TarReader.new tar do |tar_io|
tar_io.each_entry do |entry|
@@ -286,8 +287,8 @@ class TestGemPackage < Gem::Package::TarTestCase
assert_equal [PUBLIC_CERT.to_pem], reader.spec.cert_chain
- assert_equal %w[metadata.gz metadata.gz.sig
- data.tar.gz data.tar.gz.sig
+ assert_equal %w[metadata.gz metadata.gz.sig
+ data.tar.gz data.tar.gz.sig
checksums.yaml.gz checksums.yaml.gz.sig],
reader.files
@@ -329,8 +330,8 @@ class TestGemPackage < Gem::Package::TarTestCase
assert_equal [PUBLIC_CERT.to_pem], reader.spec.cert_chain
- assert_equal %w[metadata.gz metadata.gz.sig
- data.tar.gz data.tar.gz.sig
+ assert_equal %w[metadata.gz metadata.gz.sig
+ data.tar.gz data.tar.gz.sig
checksums.yaml.gz checksums.yaml.gz.sig],
reader.files
@@ -392,8 +393,8 @@ class TestGemPackage < Gem::Package::TarTestCase
assert_equal spec, reader.spec
- assert_equal %w[metadata.gz metadata.gz.sig
- data.tar.gz data.tar.gz.sig
+ assert_equal %w[metadata.gz metadata.gz.sig
+ data.tar.gz data.tar.gz.sig
checksums.yaml.gz checksums.yaml.gz.sig],
reader.files
@@ -429,8 +430,8 @@ class TestGemPackage < Gem::Package::TarTestCase
assert_equal spec, reader.spec
- assert_equal %w[metadata.gz metadata.gz.sig
- data.tar.gz data.tar.gz.sig
+ assert_equal %w[metadata.gz metadata.gz.sig
+ data.tar.gz data.tar.gz.sig
checksums.yaml.gz checksums.yaml.gz.sig],
reader.files
@@ -441,11 +442,11 @@ class TestGemPackage < Gem::Package::TarTestCase
data_tgz = util_tar_gz {}
gem = util_tar do |tar|
- tar.add_file "data.tar.gz", 0644 do |io|
+ tar.add_file "data.tar.gz", 0o644 do |io|
io.write data_tgz.string
end
- tar.add_file "metadata.gz", 0644 do |io|
+ tar.add_file "metadata.gz", 0o644 do |io|
Zlib::GzipWriter.wrap io do |gzio|
gzio.write @spec.to_yaml
end
@@ -478,21 +479,21 @@ class TestGemPackage < Gem::Package::TarTestCase
extracted = File.join @destination, "lib/code.rb"
assert_path_exist extracted
- mask = 0100666 & (~File.umask)
+ mask = 0o100666 & (~File.umask)
assert_equal mask.to_s(8), File.stat(extracted).mode.to_s(8) unless
- win_platform?
+ Gem.win_platform?
end
def test_extract_files_empty
data_tgz = util_tar_gz {}
gem = util_tar do |tar|
- tar.add_file "data.tar.gz", 0644 do |io|
+ tar.add_file "data.tar.gz", 0o644 do |io|
io.write data_tgz.string
end
- tar.add_file "metadata.gz", 0644 do |io|
+ tar.add_file "metadata.gz", 0o644 do |io|
Zlib::GzipWriter.wrap io do |gzio|
gzio.write @spec.to_yaml
end
@@ -510,11 +511,26 @@ class TestGemPackage < Gem::Package::TarTestCase
assert_path_exist @destination
end
+ def test_extract_file_permissions
+ pend "chmod not supported" if Gem.win_platform?
+
+ gem_with_long_permissions = File.expand_path("packages/Bluebie-legs-0.6.2.gem", __dir__)
+
+ package = Gem::Package.new gem_with_long_permissions
+
+ package.extract_files @destination
+
+ filepath = File.join @destination, "README.rdoc"
+ assert_path_exist filepath
+
+ assert_equal 0o104444, File.stat(filepath).mode
+ end
+
def test_extract_tar_gz_absolute
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.add_file "/absolute.rb", 0644 do |io|
+ tar.add_file "/absolute.rb", 0o644 do |io|
io.write "hi"
end
end
@@ -523,7 +539,7 @@ class TestGemPackage < Gem::Package::TarTestCase
package.extract_tar_gz tgz_io, @destination
end
- assert_equal("installing into parent path /absolute.rb of " +
+ assert_equal("installing into parent path /absolute.rb of " \
"#{@destination} is not allowed", e.message)
end
@@ -532,18 +548,18 @@ class TestGemPackage < Gem::Package::TarTestCase
package.verify
tgz_io = util_tar_gz do |tar|
- tar.add_file "relative.rb", 0644 do |io|
+ tar.add_file "relative.rb", 0o644 do |io|
io.write "hi"
end
- tar.mkdir "lib", 0755
- tar.add_symlink "lib/foo.rb", "../relative.rb", 0644
+ tar.mkdir "lib", 0o755
+ tar.add_symlink "lib/foo.rb", "../relative.rb", 0o644
end
begin
package.extract_tar_gz tgz_io, @destination
rescue Errno::EACCES => e
- if win_platform?
+ if Gem.win_platform?
pend "symlink - must be admin with no UAC on Windows"
else
raise e
@@ -558,13 +574,39 @@ class TestGemPackage < Gem::Package::TarTestCase
File.read(extracted)
end
+ def test_extract_symlink_into_symlink_dir
+ package = Gem::Package.new @gem
+ tgz_io = util_tar_gz do |tar|
+ tar.mkdir "lib", 0o755
+ tar.add_symlink "lib/link", "./inside.rb", 0o644
+ tar.add_file "lib/inside.rb", 0o644 do |io|
+ io.write "hi"
+ end
+ end
+
+ destination_subdir = File.join @destination, "subdir"
+ FileUtils.mkdir_p destination_subdir
+
+ destination_linkdir = File.join @destination, "linkdir"
+ File.symlink(destination_subdir, destination_linkdir)
+
+ package.extract_tar_gz tgz_io, destination_linkdir
+
+ extracted = File.join destination_subdir, "lib/link"
+ assert_path_exist extracted
+ assert_equal "./inside.rb",
+ File.readlink(extracted)
+ assert_equal "hi",
+ File.read(extracted)
+ end
+
def test_extract_tar_gz_symlink_broken_relative_path
package = Gem::Package.new @gem
package.verify
tgz_io = util_tar_gz do |tar|
- tar.mkdir "lib", 0755
- tar.add_symlink "lib/foo.rb", "../broken.rb", 0644
+ tar.mkdir "lib", 0o755
+ tar.add_symlink "lib/foo.rb", "../broken.rb", 0o644
end
ui = Gem::MockGemUi.new
@@ -583,9 +625,9 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.mkdir "lib", 0755
- tar.add_symlink "lib/link", "../..", 0644
- tar.add_file "lib/link/outside.txt", 0644 do |io|
+ tar.mkdir "lib", 0o755
+ tar.add_symlink "lib/link", "../..", 0o644
+ tar.add_file "lib/link/outside.txt", 0o644 do |io|
io.write "hi"
end
end
@@ -596,7 +638,7 @@ class TestGemPackage < Gem::Package::TarTestCase
destination_subdir = File.join @destination, "subdir"
FileUtils.mkdir_p destination_subdir
- expected_exceptions = win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError]
+ expected_exceptions = Gem.win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError]
e = assert_raise(*expected_exceptions) do
package.extract_tar_gz tgz_io, destination_subdir
@@ -604,7 +646,7 @@ class TestGemPackage < Gem::Package::TarTestCase
pend "symlink - must be admin with no UAC on Windows" if Errno::EACCES === e
- assert_equal("installing symlink 'lib/link' pointing to parent path #{@destination} of " +
+ assert_equal("installing symlink 'lib/link' pointing to parent path #{@destination} of " \
"#{destination_subdir} is not allowed", e.message)
assert_path_not_exist File.join(@destination, "outside.txt")
@@ -627,11 +669,11 @@ class TestGemPackage < Gem::Package::TarTestCase
pend "TMPDIR seems too long to add it as symlink into tar" if destination_user_dir.size > 90
tgz_io = util_tar_gz do |tar|
- tar.add_symlink "link", destination_user_dir, 16877
- tar.add_symlink "link/dir", ".", 16877
+ tar.add_symlink "link", destination_user_dir, 16_877
+ tar.add_symlink "link/dir", ".", 16_877
end
- expected_exceptions = win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError]
+ expected_exceptions = Gem.win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError]
e = assert_raise(*expected_exceptions) do
package.extract_tar_gz tgz_io, destination_subdir
@@ -639,7 +681,7 @@ class TestGemPackage < Gem::Package::TarTestCase
pend "symlink - must be admin with no UAC on Windows" if Errno::EACCES === e
- assert_equal("installing symlink 'link' pointing to parent path #{destination_user_dir} of " +
+ assert_equal("installing symlink 'link' pointing to parent path #{destination_user_dir} of " \
"#{destination_subdir} is not allowed", e.message)
assert_path_exist destination_user_subdir
@@ -651,11 +693,11 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.mkdir "lib", 0755
- tar.add_file "lib/foo.rb", 0644 do |io|
+ tar.mkdir "lib", 0o755
+ tar.add_file "lib/foo.rb", 0o644 do |io|
io.write "hi"
end
- tar.mkdir "lib/foo", 0755
+ tar.mkdir "lib/foo", 0o755
end
package.extract_tar_gz tgz_io, @destination
@@ -671,7 +713,7 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.add_file "./dot_slash.rb", 0644 do |io|
+ tar.add_file "./dot_slash.rb", 0o644 do |io|
io.write "hi"
end
end
@@ -686,7 +728,7 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.add_file ".dot_file.rb", 0644 do |io|
+ tar.add_file ".dot_file.rb", 0o644 do |io|
io.write "hi"
end
end
@@ -702,7 +744,7 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
tgz_io = util_tar_gz do |tar|
- tar.add_file "foo/file.rb", 0644 do |io|
+ tar.add_file "foo/file.rb", 0o644 do |io|
io.write "hi"
end
end
@@ -718,12 +760,10 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
file = "file.rb".dup
- file.taint if RUBY_VERSION < "2.7"
destination = package.install_location file, @destination
assert_equal File.join(@destination, "file.rb"), destination
- refute destination.tainted? if RUBY_VERSION < "2.7"
end
def test_install_location_absolute
@@ -733,7 +773,7 @@ class TestGemPackage < Gem::Package::TarTestCase
package.install_location "/absolute.rb", @destination
end
- assert_equal("installing into parent path /absolute.rb of " +
+ assert_equal("installing into parent path /absolute.rb of " \
"#{@destination} is not allowed", e.message)
end
@@ -757,12 +797,10 @@ class TestGemPackage < Gem::Package::TarTestCase
package = Gem::Package.new @gem
file = "foo//file.rb".dup
- file.taint if RUBY_VERSION < "2.7"
destination = package.install_location file, @destination
assert_equal File.join(@destination, "foo", "file.rb"), destination
- refute destination.tainted? if RUBY_VERSION < "2.7"
end
def test_install_location_relative
@@ -774,7 +812,7 @@ class TestGemPackage < Gem::Package::TarTestCase
parent = File.expand_path File.join @destination, "../relative.rb"
- assert_equal("installing into parent path #{parent} of " +
+ assert_equal("installing into parent path #{parent} of " \
"#{@destination} is not allowed", e.message)
end
@@ -789,13 +827,15 @@ class TestGemPackage < Gem::Package::TarTestCase
parent = File.expand_path File.join @destination, filename
- assert_equal("installing into parent path #{parent} of " +
+ assert_equal("installing into parent path #{parent} of " \
"#{@destination} is not allowed", e.message)
end
def test_load_spec
entry = StringIO.new Gem::Util.gzip @spec.to_yaml
- def entry.full_name() "metadata.gz" end
+ def entry.full_name
+ "metadata.gz"
+ end
package = Gem::Package.new "nonexistent.gem"
@@ -816,7 +856,7 @@ class TestGemPackage < Gem::Package::TarTestCase
def test_verify_checksum_bad
data_tgz = util_tar_gz do |tar|
- tar.add_file "lib/code.rb", 0444 do |io|
+ tar.add_file "lib/code.rb", 0o444 do |io|
io.write "# lib/code.rb"
end
end
@@ -826,11 +866,11 @@ class TestGemPackage < Gem::Package::TarTestCase
gem = util_tar do |tar|
metadata_gz = Gem::Util.gzip @spec.to_yaml
- tar.add_file "metadata.gz", 0444 do |io|
+ tar.add_file "metadata.gz", 0o444 do |io|
io.write metadata_gz
end
- tar.add_file "data.tar.gz", 0444 do |io|
+ tar.add_file "data.tar.gz", 0o444 do |io|
io.write data_tgz
end
@@ -840,7 +880,7 @@ class TestGemPackage < Gem::Package::TarTestCase
"metadata.gz" => "bogus",
},
}
- tar.add_file "checksums.yaml.gz", 0444 do |io|
+ tar.add_file "checksums.yaml.gz", 0o444 do |io|
Zlib::GzipWriter.wrap io do |gz_io|
gz_io.write Psych.dump bogus_checksums
end
@@ -863,7 +903,7 @@ class TestGemPackage < Gem::Package::TarTestCase
def test_verify_checksum_missing
data_tgz = util_tar_gz do |tar|
- tar.add_file "lib/code.rb", 0444 do |io|
+ tar.add_file "lib/code.rb", 0o444 do |io|
io.write "# lib/code.rb"
end
end
@@ -873,7 +913,7 @@ class TestGemPackage < Gem::Package::TarTestCase
gem = util_tar do |tar|
metadata_gz = Gem::Util.gzip @spec.to_yaml
- tar.add_file "metadata.gz", 0444 do |io|
+ tar.add_file "metadata.gz", 0o444 do |io|
io.write metadata_gz
end
@@ -886,13 +926,13 @@ class TestGemPackage < Gem::Package::TarTestCase
},
}
- tar.add_file "checksums.yaml.gz", 0444 do |io|
+ tar.add_file "checksums.yaml.gz", 0o444 do |io|
Zlib::GzipWriter.wrap io do |gz_io|
gz_io.write Psych.dump checksums
end
end
- tar.add_file "data.tar.gz", 0444 do |io|
+ tar.add_file "data.tar.gz", 0o444 do |io|
io.write data_tgz
end
end
@@ -911,7 +951,7 @@ class TestGemPackage < Gem::Package::TarTestCase
tf = Tempfile.open "corrupt" do |io|
data = Gem::Util.gzip "a" * 10
io.write \
- tar_file_header("metadata.gz", "\000x", 0644, data.length, Time.now)
+ tar_file_header("metadata.gz", "\000x", 0o644, data.length, Time.now)
io.write data
io.rewind
@@ -928,6 +968,95 @@ class TestGemPackage < Gem::Package::TarTestCase
tf.close!
end
+ def test_verify_corrupt_tar_metadata_entry
+ gem = tar_file_header("metadata.gz", "", 0, 999, Time.now)
+
+ File.open "corrupt.gem", "wb" do |io|
+ io.write gem
+ end
+
+ package = Gem::Package.new "corrupt.gem"
+
+ e = nil
+ out_err = capture_output do
+ e = assert_raise Gem::Package::FormatError do
+ package.verify
+ end
+ end
+
+ assert_match(/(EOFError|end of file reached) in corrupt.gem/i, e.message)
+ assert_equal(["", "Exception while verifying corrupt.gem\n"], out_err)
+ end
+
+ def test_verify_corrupt_tar_checksums_entry
+ gem = tar_file_header("checksums.yaml.gz", "", 0, 100, Time.now)
+
+ File.open "corrupt.gem", "wb" do |io|
+ io.write gem
+ end
+
+ package = Gem::Package.new "corrupt.gem"
+
+ e = assert_raise Gem::Package::FormatError do
+ package.verify
+ end
+
+ assert_equal "not in gzip format in corrupt.gem", e.message
+ end
+
+ def test_verify_corrupt_tar_data_entry
+ gem = tar_file_header("data.tar.gz", "", 0, 100, Time.now)
+
+ File.open "corrupt.gem", "wb" do |io|
+ io.write gem
+ end
+
+ package = Gem::Package.new "corrupt.gem"
+
+ e = nil
+ out_err = capture_output do
+ e = assert_raise Gem::Package::FormatError do
+ package.verify
+ end
+ end
+
+ assert_match(/(EOFError|end of file reached) in corrupt.gem/i, e.message)
+ assert_equal(["", "Exception while verifying corrupt.gem\n"], out_err)
+ end
+
+ def test_corrupt_data_tar_gz
+ data_tgz = util_gzip tar_file_header("lib/code.rb", "", 0, 100, Time.now)
+ metadata_gz = util_gzip @spec.to_yaml
+
+ gem = util_tar do |tar|
+ tar.add_file "data.tar.gz", 0o444 do |io|
+ io.write data_tgz
+ end
+
+ tar.add_file "metadata.gz", 0o644 do |io|
+ io.write metadata_gz
+ end
+ end
+
+ File.open "corrupt.gem", "wb" do |io|
+ io.write gem.string
+ end
+
+ package = Gem::Package.new "corrupt.gem"
+
+ e = assert_raise Gem::Package::FormatError do
+ package.contents
+ end
+
+ assert_match(/(EOFError|end of file reached) in corrupt.gem/i, e.message)
+
+ e = assert_raise Gem::Package::FormatError do
+ package.extract_files @destination
+ end
+
+ assert_match(/(EOFError|end of file reached) in corrupt.gem/i, e.message)
+ end
+
def test_verify_empty
FileUtils.touch "empty.gem"
@@ -947,8 +1076,8 @@ class TestGemPackage < Gem::Package::TarTestCase
package.verify
end
- assert_match %r{^No such file or directory}, e.message
- assert_match %r{nonexistent.gem$}, e.message
+ assert_match(/^No such file or directory/, e.message)
+ assert_match(/nonexistent.gem$/, e.message)
end
def test_verify_duplicate_file
@@ -963,8 +1092,8 @@ class TestGemPackage < Gem::Package::TarTestCase
build.add_metadata gem
build.add_contents gem
- gem.add_file_simple "a.sig", 0444, 0
- gem.add_file_simple "a.sig", 0444, 0
+ gem.add_file_simple "a.sig", 0o444, 0
+ gem.add_file_simple "a.sig", 0o444, 0
end
end
@@ -1035,12 +1164,23 @@ class TestGemPackage < Gem::Package::TarTestCase
# write bogus data.tar.gz to foil signature
bogus_data = Gem::Util.gzip "hello"
fake_signer = Class.new do
- def digest_name; "SHA512"; end
- def digest_algorithm; OpenSSL::Digest(:SHA512).new; end
- def key; "key"; end
- def sign(*); "fake_sig"; end
+ def digest_name
+ "SHA512"
+ end
+
+ def digest_algorithm
+ OpenSSL::Digest(:SHA512).new
+ end
+
+ def key
+ "key"
+ end
+
+ def sign(*)
+ "fake_sig"
+ end
end
- gem.add_file_signed "data2.tar.gz", 0444, fake_signer.new do |io|
+ gem.add_file_signed "data2.tar.gz", 0o444, fake_signer.new do |io|
io.write bogus_data
end
@@ -1082,7 +1222,9 @@ class TestGemPackage < Gem::Package::TarTestCase
def test_verify_entry
entry = Object.new
- def entry.full_name() raise ArgumentError, "whatever" end
+ def entry.full_name
+ raise ArgumentError, "whatever"
+ end
package = Gem::Package.new @gem
@@ -1109,11 +1251,15 @@ class TestGemPackage < Gem::Package::TarTestCase
$good_name = vm
entry = Object.new
- def entry.full_name() $good_name end
+ def entry.full_name
+ $good_name
+ end
package = Gem::Package.new(@gem)
package.instance_variable_set(:@files, [])
- def package.load_spec(entry) $spec_loaded = true end
+ def package.load_spec(entry)
+ $spec_loaded = true
+ end
package.verify_entry(entry)
@@ -1126,11 +1272,15 @@ class TestGemPackage < Gem::Package::TarTestCase
$bad_name = vm
entry = Object.new
- def entry.full_name() $bad_name end
+ def entry.full_name
+ $bad_name
+ end
package = Gem::Package.new(@gem)
package.instance_variable_set(:@files, [])
- def package.load_spec(entry) $spec_loaded = true end
+ def package.load_spec(entry)
+ $spec_loaded = true
+ end
package.verify_entry(entry)
@@ -1172,29 +1322,4 @@ class TestGemPackage < Gem::Package::TarTestCase
assert_equal %w[lib/code.rb], package.contents
end
-
- def util_tar
- tar_io = StringIO.new
-
- Gem::Package::TarWriter.new tar_io do |tar|
- yield tar
- end
-
- tar_io.rewind
-
- tar_io
- end
-
- def util_tar_gz(&block)
- tar_io = util_tar(&block)
-
- tgz_io = StringIO.new
-
- # can't wrap TarWriter because it seeks
- Zlib::GzipWriter.wrap tgz_io do |io|
- io.write tar_io.string
- end
-
- StringIO.new tgz_io.string
- end
end
diff --git a/test/rubygems/test_gem_package_old.rb b/test/rubygems/test_gem_package_old.rb
index d65d1edad6..7582dbedd4 100644
--- a/test/rubygems/test_gem_package_old.rb
+++ b/test/rubygems/test_gem_package_old.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
unless Gem.java_platform? # jruby can't require the simple_gem file
@@ -38,9 +39,9 @@ unless Gem.java_platform? # jruby can't require the simple_gem file
extracted = File.join @destination, "lib/foo.rb"
assert_path_exist extracted
- mask = 0100644 & (~File.umask)
+ mask = 0o100644 & (~File.umask)
- assert_equal mask, File.stat(extracted).mode unless win_platform?
+ assert_equal mask, File.stat(extracted).mode unless Gem.win_platform?
end
def test_extract_files_security_policy
@@ -82,7 +83,7 @@ unless Gem.java_platform? # jruby can't require the simple_gem file
@package.verify
end
- assert_equal "old format gems do not contain signatures " +
+ assert_equal "old format gems do not contain signatures " \
"and cannot be verified",
e.message
end
diff --git a/test/rubygems/test_gem_package_tar_header.rb b/test/rubygems/test_gem_package_tar_header.rb
index 3ff4f0b30b..4469750f9a 100644
--- a/test/rubygems/test_gem_package_tar_header.rb
+++ b/test/rubygems/test_gem_package_tar_header.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "package/tar_test_case"
require "rubygems/package"
@@ -7,19 +8,19 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase
super
header = {
- :name => "x",
- :mode => 0644,
- :uid => 1000,
- :gid => 10000,
- :size => 100,
- :mtime => 12345,
- :typeflag => "0",
- :linkname => "link",
- :uname => "user",
- :gname => "group",
- :devmajor => 1,
- :devminor => 2,
- :prefix => "y",
+ name: "x",
+ mode: 0o644,
+ uid: 1000,
+ gid: 10_000,
+ size: 100,
+ mtime: 12_345,
+ typeflag: "0",
+ linkname: "link",
+ uname: "user",
+ gname: "group",
+ devmajor: 1,
+ devminor: 2,
+ prefix: "y",
}
@tar_header = Gem::Package::TarHeader.new header
@@ -39,12 +40,12 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase
assert_equal "", @tar_header.checksum, "checksum"
assert_equal 1, @tar_header.devmajor, "devmajor"
assert_equal 2, @tar_header.devminor, "devminor"
- assert_equal 10000, @tar_header.gid, "gid"
+ assert_equal 10_000, @tar_header.gid, "gid"
assert_equal "group", @tar_header.gname, "gname"
assert_equal "link", @tar_header.linkname, "linkname"
assert_equal "ustar", @tar_header.magic, "magic"
- assert_equal 0644, @tar_header.mode, "mode"
- assert_equal 12345, @tar_header.mtime, "mtime"
+ assert_equal 0o644, @tar_header.mode, "mode"
+ assert_equal 12_345, @tar_header.mtime, "mtime"
assert_equal "x", @tar_header.name, "name"
assert_equal "y", @tar_header.prefix, "prefix"
assert_equal 100, @tar_header.size, "size"
@@ -58,29 +59,29 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase
def test_initialize_bad
assert_raise ArgumentError do
- Gem::Package::TarHeader.new :name => "", :size => "", :mode => ""
+ Gem::Package::TarHeader.new name: "", size: "", mode: ""
end
assert_raise ArgumentError do
- Gem::Package::TarHeader.new :name => "", :size => "", :prefix => ""
+ Gem::Package::TarHeader.new name: "", size: "", prefix: ""
end
assert_raise ArgumentError do
- Gem::Package::TarHeader.new :name => "", :prefix => "", :mode => ""
+ Gem::Package::TarHeader.new name: "", prefix: "", mode: ""
end
assert_raise ArgumentError do
- Gem::Package::TarHeader.new :prefix => "", :size => "", :mode => ""
+ Gem::Package::TarHeader.new prefix: "", size: "", mode: ""
end
end
def test_initialize_typeflag
header = {
- :mode => "",
- :name => "",
- :prefix => "",
- :size => "",
- :typeflag => "",
+ mode: "",
+ name: "",
+ prefix: "",
+ size: "",
+ typeflag: "",
}
tar_header = Gem::Package::TarHeader.new header
@@ -91,9 +92,9 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase
def test_empty_eh
refute_empty @tar_header
- @tar_header = Gem::Package::TarHeader.new :name => "x", :prefix => "",
- :mode => 0, :size => 0,
- :empty => true
+ @tar_header = Gem::Package::TarHeader.new name: "x", prefix: "",
+ mode: 0, size: 0,
+ empty: true
assert_empty @tar_header
end
@@ -159,6 +160,7 @@ group\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
assert_raise ArgumentError do
Gem::Package::TarHeader.from io
end
+ ensure
io.close!
end
end
@@ -194,13 +196,13 @@ tjmather\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
tar_header = Gem::Package::TarHeader.from stream
- assert_equal 1991400094, tar_header.uid
- assert_equal 1991400094, tar_header.gid
+ assert_equal 1_991_400_094, tar_header.uid
+ assert_equal 1_991_400_094, tar_header.gid
assert_equal "GeoIP2-City_20190528/", tar_header.name
- assert_equal 0755, tar_header.mode
+ assert_equal 0o755, tar_header.mode
assert_equal 0, tar_header.size
- assert_equal 1559064640, tar_header.mtime
+ assert_equal 1_559_064_640, tar_header.mtime
assert_equal 6932, tar_header.checksum
end
diff --git a/test/rubygems/test_gem_package_tar_reader.rb b/test/rubygems/test_gem_package_tar_reader.rb
index 19860eb7e8..b2f7cc2d5c 100644
--- a/test/rubygems/test_gem_package_tar_reader.rb
+++ b/test/rubygems/test_gem_package_tar_reader.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "package/tar_test_case"
require "rubygems/package"
@@ -24,11 +25,26 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase
io.close!
end
+ def test_each_with_not_a_tar
+ text = "Hello, world!!?\n" * 256 # 4 KiB
+ io = TempIO.new text
+
+ Gem::Package::TarReader.new io do |tar|
+ assert_raise Gem::Package::TarInvalidError do
+ tar.each do
+ flunk "TarInvalidError was expected to occur, but an entry was found"
+ end
+ end
+ end
+ ensure
+ io.close!
+ end
+
def test_rewind
content = ("a".."z").to_a.join(" ")
str =
- tar_file_header("lib/foo", "", 010644, content.size, Time.now) +
+ tar_file_header("lib/foo", "", 0o10644, content.size, Time.now) +
content + "\0" * (512 - content.size)
str << "\0" * 1024
@@ -56,12 +72,14 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase
io = TempIO.new tar
Gem::Package::TarReader.new io do |tar_reader|
- tar_reader.seek "baz/bar" do |entry|
+ retval = tar_reader.seek "baz/bar" do |entry|
assert_kind_of Gem::Package::TarReader::Entry, entry
assert_equal "baz/bar", entry.full_name
+ entry.read
end
+ assert_equal "", retval
assert_equal 0, io.pos
end
ensure
@@ -75,7 +93,7 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase
io = TempIO.new tar
Gem::Package::TarReader.new io do |tar_reader|
- tar_reader.seek "nonexistent" do |entry|
+ tar_reader.seek "nonexistent" do |_entry|
flunk "entry missing but entry-found block was run"
end
@@ -84,4 +102,49 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase
ensure
io.close!
end
+
+ def test_read_in_gem_data
+ gem_tar = util_gem_data_tar do |tar|
+ tar.add_file "lib/code.rb", 0o444 do |io|
+ io.write "# lib/code.rb"
+ end
+ end
+
+ count = 0
+ Gem::Package::TarReader.new(gem_tar).each do |entry|
+ next unless entry.full_name == "data.tar.gz"
+
+ Zlib::GzipReader.wrap entry do |gzio|
+ Gem::Package::TarReader.new(gzio).each do |contents_entry|
+ assert_equal "# lib/code.rb", contents_entry.read
+ count += 1
+ end
+ end
+ end
+
+ assert_equal 1, count, "should have found one file"
+ end
+
+ def test_seek_in_gem_data
+ gem_tar = util_gem_data_tar do |tar|
+ tar.add_file "lib/code.rb", 0o444 do |io|
+ io.write "# lib/code.rb"
+ end
+ tar.add_file "lib/foo.rb", 0o444 do |io|
+ io.write "# lib/foo.rb"
+ end
+ end
+
+ count = 0
+ Gem::Package::TarReader.new(gem_tar).seek("data.tar.gz") do |entry|
+ Zlib::GzipReader.wrap entry do |gzio|
+ Gem::Package::TarReader.new(gzio).seek("lib/foo.rb") do |contents_entry|
+ assert_equal "# lib/foo.rb", contents_entry.read
+ count += 1
+ end
+ end
+ end
+
+ assert_equal 1, count, "should have found one file"
+ end
end
diff --git a/test/rubygems/test_gem_package_tar_reader_entry.rb b/test/rubygems/test_gem_package_tar_reader_entry.rb
index ffb4542178..67ab7922b5 100644
--- a/test/rubygems/test_gem_package_tar_reader_entry.rb
+++ b/test/rubygems/test_gem_package_tar_reader_entry.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "package/tar_test_case"
require "rubygems/package"
@@ -10,8 +11,7 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
@tar = String.new
@tar << tar_file_header("lib/foo", "", 0, @contents.size, Time.now)
- @tar << @contents
- @tar << "\0" * (512 - (@tar.size % 512))
+ @tar << tar_file_contents(@contents)
@entry = util_entry @tar
end
@@ -21,8 +21,39 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
super
end
- def close_util_entry(entry)
- entry.instance_variable_get(:@io).close!
+ def test_open
+ io = TempIO.new @tar
+ header = Gem::Package::TarHeader.from io
+ retval = Gem::Package::TarReader::Entry.open header, io, &:getc
+ assert_equal "a", retval
+ assert_equal @tar.size, io.pos, "should have read to end of entry"
+ ensure
+ io&.close!
+ end
+
+ def test_open_closes_entry
+ io = TempIO.new @tar
+ header = Gem::Package::TarHeader.from io
+ entry = nil
+ Gem::Package::TarReader::Entry.open header, io do |e|
+ entry = e
+ end
+ assert entry.closed?
+ assert_raise(IOError) { entry.getc }
+ ensure
+ io&.close!
+ end
+
+ def test_open_returns_entry
+ io = TempIO.new @tar
+ header = Gem::Package::TarHeader.from io
+ entry = Gem::Package::TarReader::Entry.open header, io
+ refute entry.closed?
+ assert_equal "a", entry.getc
+ assert_nil entry.close
+ assert entry.closed?
+ ensure
+ io&.close!
end
def test_bytes_read
@@ -86,7 +117,7 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
end
def test_getc
- assert_equal ?a, @entry.getc
+ assert_equal "a", @entry.getc
end
def test_directory_eh
@@ -125,6 +156,18 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
assert_equal @contents, @entry.read
end
+ def test_consecutive_read
+ expected = StringIO.new(@contents)
+ assert_equal expected.read, @entry.read
+ assert_equal expected.read, @entry.read
+ end
+
+ def test_consecutive_read_bytes_past_eof
+ expected = StringIO.new(@contents)
+ assert_equal expected.read, @entry.read
+ assert_equal expected.read(1), @entry.read(1)
+ end
+
def test_read_big
assert_equal @contents, @entry.read(@contents.size * 2)
end
@@ -133,13 +176,64 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
assert_equal @contents[0...100], @entry.read(100)
end
+ def test_read_remaining
+ @entry.read(100)
+ assert_equal @contents[100..-1], @entry.read
+ end
+
def test_readpartial
+ assert_equal @contents[0...100], @entry.readpartial(100)
+ end
+
+ def test_readpartial_to_eof
+ assert_equal @contents, @entry.readpartial(4096)
+ assert @entry.eof?
+ end
+
+ def test_read_partial_buffer
+ buffer = "".b
+ @entry.readpartial(100, buffer)
+ assert_equal @contents[0...100], buffer
+ end
+
+ def test_readpartial_past_eof
+ @entry.readpartial(@contents.size)
+ assert @entry.eof?
assert_raise(EOFError) do
- @entry.read(@contents.size)
@entry.readpartial(1)
end
end
+ def test_read_corrupted_tar
+ corrupt_tar = String.new
+ corrupt_tar << tar_file_header("lib/foo", "", 0, 100, Time.now)
+ corrupt_tar << tar_file_contents("")
+ corrupt_entry = util_entry corrupt_tar
+
+ assert_equal "", corrupt_entry.read(0)
+ assert_equal "", corrupt_entry.read, "IO.read without len should return empty string (even though it's at an unpexpected EOF)"
+
+ corrupt_entry.rewind
+
+ assert_nil corrupt_entry.read(100), "IO.read with len should return nil as per IO.read docs"
+ ensure
+ close_util_entry(corrupt_entry) if corrupt_entry
+ end
+
+ def test_readpartial_corrupted_tar
+ corrupt_tar = String.new
+ corrupt_tar << tar_file_header("lib/foo", "", 0, 100, Time.now)
+ corrupt_tar << tar_file_contents("")
+
+ corrupt_entry = util_entry corrupt_tar
+
+ assert_raise EOFError do
+ corrupt_entry.readpartial(100)
+ end
+ ensure
+ close_util_entry(corrupt_entry) if corrupt_entry
+ end
+
def test_rewind
char = @entry.getc
@@ -149,4 +243,116 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase
assert_equal char, @entry.getc
end
+
+ def test_seek
+ @entry.seek(50)
+ assert_equal 50, @entry.pos
+ assert_equal @contents[50..-1], @entry.read, "read remaining after seek"
+ @entry.seek(-50, IO::SEEK_CUR)
+ assert_equal @contents.size - 50, @entry.pos
+ assert_equal @contents[-50..-1], @entry.read, "read after stepping back 50 from the end"
+ @entry.seek(0, IO::SEEK_SET)
+ assert_equal 0, @entry.pos
+ assert_equal @contents, @entry.read, "read from beginning"
+ @entry.seek(-10, IO::SEEK_END)
+ assert_equal @contents.size - 10, @entry.pos
+ assert_equal @contents[-10..-1], @entry.read, "read from end"
+ end
+
+ def test_read_zero
+ expected = StringIO.new("")
+ assert_equal expected.read(0), @entry.read(0)
+ end
+
+ def test_readpartial_zero
+ expected = StringIO.new("")
+ assert_equal expected.readpartial(0), @entry.readpartial(0)
+ end
+
+ def test_zero_byte_file_read
+ zero_entry = util_entry(tar_file_header("foo", "", 0, 0, Time.now))
+ expected = StringIO.new("")
+ assert_equal expected.read, zero_entry.read
+ ensure
+ close_util_entry(zero_entry) if zero_entry
+ end
+
+ def test_zero_byte_file_readpartial
+ zero_entry = util_entry(tar_file_header("foo", "", 0, 0, Time.now))
+ expected = StringIO.new("")
+ assert_equal expected.readpartial(0), zero_entry.readpartial(0)
+ ensure
+ close_util_entry(zero_entry) if zero_entry
+ end
+
+ def test_read_from_gzip_io
+ tgz = util_gzip(@tar)
+
+ Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio|
+ entry = util_entry(gzio)
+ assert_equal @contents, entry.read
+ entry.rewind
+ assert_equal @contents, entry.read, "second read after rewind should read same contents"
+ end
+ end
+
+ def test_read_from_gzip_io_with_non_zero_offset
+ contents2 = ("0".."9").to_a.join * 100
+ @tar << tar_file_header("lib/bar", "", 0, contents2.size, Time.now)
+ @tar << tar_file_contents(contents2)
+
+ tgz = util_gzip(@tar)
+
+ Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio|
+ util_entry(gzio).close # skip the first entry so io.pos is not 0, preventing easy rewind
+ entry = util_entry(gzio)
+
+ assert_equal contents2, entry.read
+ entry.rewind
+ assert_equal contents2, entry.read, "second read after rewind should read same contents"
+ end
+ end
+
+ def test_seek_in_gzip_io_with_non_zero_offset
+ contents2 = ("0".."9").to_a.join * 100
+ @tar << tar_file_header("lib/bar", "", 0, contents2.size, Time.now)
+ @tar << tar_file_contents(contents2)
+
+ tgz = util_gzip(@tar)
+
+ Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio|
+ util_entry(gzio).close # skip the first entry so io.pos is not 0
+ entry = util_entry(gzio)
+
+ entry.seek(50)
+ assert_equal 50, entry.pos
+ assert_equal contents2[50..-1], entry.read, "read remaining after seek"
+ entry.seek(-50, IO::SEEK_CUR)
+ assert_equal contents2.size - 50, entry.pos
+ assert_equal contents2[-50..-1], entry.read, "read after stepping back 50 from the end"
+ entry.seek(0, IO::SEEK_SET)
+ assert_equal 0, entry.pos
+ assert_equal contents2, entry.read, "read from beginning"
+ entry.seek(-10, IO::SEEK_END)
+ assert_equal contents2.size - 10, entry.pos
+ assert_equal contents2[-10..-1], entry.read, "read from end"
+ assert_equal contents2.size, entry.pos
+ end
+ end
+
+ def test_seek_in_gzip_io_corrupted
+ @tar << tar_file_header("lib/bar", "", 0, 100, Time.now)
+ @tar << tar_file_contents("")
+
+ tgz = util_gzip(@tar)
+
+ Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio|
+ util_entry(gzio).close # skip the first entry so io.pos is not 0
+ entry = util_entry(gzio)
+
+ assert_raise EOFError do
+ entry.seek(50)
+ end
+ end
+ end
end
diff --git a/test/rubygems/test_gem_package_tar_writer.rb b/test/rubygems/test_gem_package_tar_writer.rb
index 5dcb90c14e..751ceaca81 100644
--- a/test/rubygems/test_gem_package_tar_writer.rb
+++ b/test/rubygems/test_gem_package_tar_writer.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "package/tar_test_case"
require "rubygems/package/tar_writer"
@@ -27,12 +28,12 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
end
def test_add_file
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.add_file "x", 0644 do |f|
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.add_file "x", 0o644 do |f|
f.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
@io.string[0, 512])
end
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -41,19 +42,19 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
def test_add_file_source_date_epoch
ENV["SOURCE_DATE_EPOCH"] = "123456789"
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.mkdir "foo", 0644
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.mkdir "foo", 0o644
- assert_headers_equal tar_dir_header("foo", "", 0644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
+ assert_headers_equal tar_dir_header("foo", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
@io.string[0, 512]
end
end
def test_add_symlink
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.add_symlink "x", "y", 0644
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.add_symlink "x", "y", 0o644
- assert_headers_equal(tar_symlink_header("x", "", 0644, Time.now, "y"),
+ assert_headers_equal(tar_symlink_header("x", "", 0o644, Time.now, "y"),
@io.string[0, 512])
end
assert_equal 512, @io.pos
@@ -61,19 +62,19 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
def test_add_symlink_source_date_epoch
ENV["SOURCE_DATE_EPOCH"] = "123456789"
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.add_symlink "x", "y", 0644
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.add_symlink "x", "y", 0o644
- assert_headers_equal(tar_symlink_header("x", "", 0644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc, "y"),
+ assert_headers_equal(tar_symlink_header("x", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc, "y"),
@io.string[0, 512])
end
end
def test_add_file_digest
- digest_algorithms = Digest::SHA1.new, Digest::SHA512.new
+ digest_algorithms = OpenSSL::Digest::SHA1.new, OpenSSL::Digest::SHA512.new
- Time.stub :now, Time.at(1458518157) do
- digests = @tar_writer.add_file_digest "x", 0644, digest_algorithms do |io|
+ Time.stub :now, Time.at(1_458_518_157) do
+ digests = @tar_writer.add_file_digest "x", 0o644, digest_algorithms do |io|
io.write "a" * 10
end
@@ -85,7 +86,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
"e1cf14b0",
digests["SHA512"].hexdigest
- assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
@io.string[0, 512])
end
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -93,10 +94,10 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
end
def test_add_file_digest_multiple
- digest_algorithms = [Digest::SHA1.new, Digest::SHA512.new]
+ digest_algorithms = [OpenSSL::Digest::SHA1.new, OpenSSL::Digest::SHA512.new]
- Time.stub :now, Time.at(1458518157) do
- digests = @tar_writer.add_file_digest "x", 0644, digest_algorithms do |io|
+ Time.stub :now, Time.at(1_458_518_157) do
+ digests = @tar_writer.add_file_digest "x", 0o644, digest_algorithms do |io|
io.write "a" * 10
end
@@ -108,7 +109,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
"e1cf14b0",
digests["SHA512"].hexdigest
- assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
@io.string[0, 512])
end
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -120,12 +121,12 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT]
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.add_file_signed "x", 0644, signer do |io|
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.add_file_signed "x", 0o644, signer do |io|
io.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
@io.string[0, 512])
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -135,7 +136,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
signature = signer.sign digest.digest
- assert_headers_equal(tar_file_header("x.sig", "", 0444, signature.length,
+ assert_headers_equal(tar_file_header("x.sig", "", 0o444, signature.length,
Time.now),
@io.string[1024, 512])
assert_equal "#{signature}#{"\0" * (512 - signature.length)}",
@@ -148,12 +149,12 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
def test_add_file_signer_empty
signer = Gem::Security::Signer.new nil, nil
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.add_file_signed "x", 0644, signer do |io|
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.add_file_signed "x", 0o644, signer do |io|
io.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
@io.string[0, 512])
end
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -162,12 +163,12 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
end
def test_add_file_simple
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.add_file_simple "x", 0644, 10 do |io|
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.add_file_simple "x", 0o644, 10 do |io|
io.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.now),
+ assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now),
@io.string[0, 512])
assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
@@ -177,18 +178,18 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
def test_add_file_simple_source_date_epoch
ENV["SOURCE_DATE_EPOCH"] = "123456789"
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.add_file_simple "x", 0644, 10 do |io|
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.add_file_simple "x", 0o644, 10 do |io|
io.write "a" * 10
end
- assert_headers_equal(tar_file_header("x", "", 0644, 10, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
+ assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
@io.string[0, 512])
end
end
def test_add_file_simple_padding
- Time.stub :now, Time.at(1458518157) do
+ Time.stub :now, Time.at(1_458_518_157) do
@tar_writer.add_file_simple "x", 0, 100
assert_headers_equal tar_file_header("x", "", 0, 100, Time.now),
@@ -246,10 +247,10 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
end
def test_mkdir
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.mkdir "foo", 0644
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.mkdir "foo", 0o644
- assert_headers_equal tar_dir_header("foo", "", 0644, Time.now),
+ assert_headers_equal tar_dir_header("foo", "", 0o644, Time.now),
@io.string[0, 512]
assert_equal 512, @io.pos
@@ -258,20 +259,20 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
def test_mkdir_source_date_epoch
ENV["SOURCE_DATE_EPOCH"] = "123456789"
- Time.stub :now, Time.at(1458518157) do
- @tar_writer.mkdir "foo", 0644
+ Time.stub :now, Time.at(1_458_518_157) do
+ @tar_writer.mkdir "foo", 0o644
- assert_headers_equal tar_dir_header("foo", "", 0644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
+ assert_headers_equal tar_dir_header("foo", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc),
@io.string[0, 512]
end
end
def test_split_name
assert_equal ["b" * 100, "a" * 155],
- @tar_writer.split_name("#{'a' * 155}/#{'b' * 100}")
+ @tar_writer.split_name("#{"a" * 155}/#{"b" * 100}")
- assert_equal ["#{'qwer/' * 19}bla", "a" * 151],
- @tar_writer.split_name("#{'a' * 151}/#{'qwer/' * 19}bla")
+ assert_equal ["#{"qwer/" * 19}bla", "a" * 151],
+ @tar_writer.split_name("#{"a" * 151}/#{"qwer/" * 19}bla")
names = [
([""] + ["123456789"] * 9 + ["1234567890"]).join("/"), # 101 bytes (several pieces)
(["123456789"] * 9 + ["1234567890"] + [""]).join("/"), # 101 bytes (several pieces)
@@ -282,7 +283,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase
]
names.each do |name|
newname, prefix = @tar_writer.split_name(name)
- assert(!(newname.empty?), "split_name() returned empty name")
+ assert(!newname.empty?, "split_name() returned empty name")
assert(newname.bytesize <= 100, "split_name() returned name longer than 100 bytes: '#{newname}' for '#{name}'")
assert(prefix.bytesize <= 155, "split_name() returned prefix longer than 155 bytes: '#{prefix}' for '#{name}'")
newname = [prefix, newname].join("/") unless prefix.empty?
diff --git a/test/rubygems/test_gem_package_task.rb b/test/rubygems/test_gem_package_task.rb
index 65fb818d7a..6f322ad61e 100644
--- a/test/rubygems/test_gem_package_task.rb
+++ b/test/rubygems/test_gem_package_task.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems"
@@ -8,10 +9,6 @@ rescue LoadError => e
raise unless e.path == "rake/packagetask"
end
-unless defined?(Rake::PackageTask)
- warn "Skipping Gem::PackageTask tests. rake not found."
-end
-
class TestGemPackageTask < Gem::TestCase
def test_gem_package
original_rake_fileutils_verbosity = RakeFileUtils.verbose_flag
diff --git a/test/rubygems/test_gem_path_support.rb b/test/rubygems/test_gem_path_support.rb
index fa0e3990be..8720bcf858 100644
--- a/test/rubygems/test_gem_path_support.rb
+++ b/test/rubygems/test_gem_path_support.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems"
require "fileutils"
diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb
index 0fb5bf59a5..e4bf882317 100644
--- a/test/rubygems/test_gem_platform.rb
+++ b/test/rubygems/test_gem_platform.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/platform"
require "rbconfig"
@@ -27,7 +28,7 @@ class TestGemPlatform < Gem::TestCase
end
def test_self_match_spec?
- make_spec = -> platform do
+ make_spec = ->(platform) do
util_spec "mygem-for-platform-match_spec", "1" do |s|
s.platform = platform
end
@@ -40,7 +41,7 @@ class TestGemPlatform < Gem::TestCase
end
def test_self_match_spec_with_match_gem_override
- make_spec = -> name, platform do
+ make_spec = ->(name, platform) do
util_spec name, "1" do |s|
s.platform = platform
end
@@ -70,7 +71,7 @@ class TestGemPlatform < Gem::TestCase
Gem.platforms = platforms
class << Gem::Platform
remove_method :match_gem?
- alias_method :match_gem?, :original_match_gem? # rubocop:disable Lint/DuplicateMethods
+ alias_method :match_gem?, :original_match_gem?
remove_method :original_match_gem?
end
end
@@ -85,65 +86,71 @@ class TestGemPlatform < Gem::TestCase
def test_initialize
test_cases = {
- "amd64-freebsd6" => ["amd64", "freebsd", "6"],
- "hppa2.0w-hpux11.31" => ["hppa2.0w", "hpux", "11"],
- "java" => [nil, "java", nil],
- "jruby" => [nil, "java", nil],
- "universal-dotnet" => ["universal", "dotnet", nil],
- "universal-dotnet2.0" => ["universal", "dotnet", "2.0"],
- "universal-dotnet4.0" => ["universal", "dotnet", "4.0"],
- "powerpc-aix5.3.0.0" => ["powerpc", "aix", "5"],
- "powerpc-darwin7" => ["powerpc", "darwin", "7"],
- "powerpc-darwin8" => ["powerpc", "darwin", "8"],
- "powerpc-linux" => ["powerpc", "linux", nil],
- "powerpc64-linux" => ["powerpc64", "linux", nil],
- "sparc-solaris2.10" => ["sparc", "solaris", "2.10"],
- "sparc-solaris2.8" => ["sparc", "solaris", "2.8"],
- "sparc-solaris2.9" => ["sparc", "solaris", "2.9"],
- "universal-darwin8" => ["universal", "darwin", "8"],
- "universal-darwin9" => ["universal", "darwin", "9"],
- "universal-macruby" => ["universal", "macruby", nil],
- "i386-cygwin" => ["x86", "cygwin", nil],
- "i686-darwin" => ["x86", "darwin", nil],
- "i686-darwin8.4.1" => ["x86", "darwin", "8"],
- "i386-freebsd4.11" => ["x86", "freebsd", "4"],
- "i386-freebsd5" => ["x86", "freebsd", "5"],
- "i386-freebsd6" => ["x86", "freebsd", "6"],
- "i386-freebsd7" => ["x86", "freebsd", "7"],
- "i386-freebsd" => ["x86", "freebsd", nil],
- "universal-freebsd" => ["universal", "freebsd", nil],
- "i386-java1.5" => ["x86", "java", "1.5"],
- "x86-java1.6" => ["x86", "java", "1.6"],
- "i386-java1.6" => ["x86", "java", "1.6"],
- "i686-linux" => ["x86", "linux", nil],
- "i586-linux" => ["x86", "linux", nil],
- "i486-linux" => ["x86", "linux", nil],
- "i386-linux" => ["x86", "linux", nil],
- "i586-linux-gnu" => ["x86", "linux", nil],
- "i386-linux-gnu" => ["x86", "linux", nil],
- "i386-mingw32" => ["x86", "mingw32", nil],
- "x64-mingw-ucrt" => ["x64", "mingw", "ucrt"],
- "i386-mswin32" => ["x86", "mswin32", nil],
- "i386-mswin32_80" => ["x86", "mswin32", "80"],
- "i386-mswin32-80" => ["x86", "mswin32", "80"],
- "x86-mswin32" => ["x86", "mswin32", nil],
- "x86-mswin32_60" => ["x86", "mswin32", "60"],
- "x86-mswin32-60" => ["x86", "mswin32", "60"],
- "i386-netbsdelf" => ["x86", "netbsdelf", nil],
- "i386-openbsd4.0" => ["x86", "openbsd", "4.0"],
- "i386-solaris2.10" => ["x86", "solaris", "2.10"],
- "i386-solaris2.8" => ["x86", "solaris", "2.8"],
- "mswin32" => ["x86", "mswin32", nil],
- "x86_64-linux" => ["x86_64", "linux", nil],
- "x86_64-linux-musl" => ["x86_64", "linux", "musl"],
- "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],
+ "amd64-freebsd6" => ["amd64", "freebsd", "6"],
+ "java" => [nil, "java", nil],
+ "jruby" => [nil, "java", nil],
+ "universal-dotnet" => ["universal", "dotnet", nil],
+ "universal-dotnet2.0" => ["universal", "dotnet", "2.0"],
+ "universal-dotnet4.0" => ["universal", "dotnet", "4.0"],
+ "powerpc-aix5.3.0.0" => ["powerpc", "aix", "5"],
+ "powerpc-darwin7" => ["powerpc", "darwin", "7"],
+ "powerpc-darwin8" => ["powerpc", "darwin", "8"],
+ "powerpc-linux" => ["powerpc", "linux", nil],
+ "powerpc64-linux" => ["powerpc64", "linux", nil],
+ "sparc-solaris2.10" => ["sparc", "solaris", "2.10"],
+ "sparc-solaris2.8" => ["sparc", "solaris", "2.8"],
+ "sparc-solaris2.9" => ["sparc", "solaris", "2.9"],
+ "universal-darwin8" => ["universal", "darwin", "8"],
+ "universal-darwin9" => ["universal", "darwin", "9"],
+ "universal-macruby" => ["universal", "macruby", nil],
+ "i386-cygwin" => ["x86", "cygwin", nil],
+ "i686-darwin" => ["x86", "darwin", nil],
+ "i686-darwin8.4.1" => ["x86", "darwin", "8"],
+ "i386-freebsd4.11" => ["x86", "freebsd", "4"],
+ "i386-freebsd5" => ["x86", "freebsd", "5"],
+ "i386-freebsd6" => ["x86", "freebsd", "6"],
+ "i386-freebsd7" => ["x86", "freebsd", "7"],
+ "i386-freebsd" => ["x86", "freebsd", nil],
+ "universal-freebsd" => ["universal", "freebsd", nil],
+ "i386-java1.5" => ["x86", "java", "1.5"],
+ "x86-java1.6" => ["x86", "java", "1.6"],
+ "i386-java1.6" => ["x86", "java", "1.6"],
+ "i686-linux" => ["x86", "linux", nil],
+ "i586-linux" => ["x86", "linux", nil],
+ "i486-linux" => ["x86", "linux", nil],
+ "i386-linux" => ["x86", "linux", nil],
+ "i586-linux-gnu" => ["x86", "linux", "gnu"],
+ "i386-linux-gnu" => ["x86", "linux", "gnu"],
+ "i386-mingw32" => ["x86", "mingw32", nil],
+ "x64-mingw-ucrt" => ["x64", "mingw", "ucrt"],
+ "i386-mswin32" => ["x86", "mswin32", nil],
+ "i386-mswin32_80" => ["x86", "mswin32", "80"],
+ "i386-mswin32-80" => ["x86", "mswin32", "80"],
+ "x86-mswin32" => ["x86", "mswin32", nil],
+ "x86-mswin32_60" => ["x86", "mswin32", "60"],
+ "x86-mswin32-60" => ["x86", "mswin32", "60"],
+ "i386-netbsdelf" => ["x86", "netbsdelf", nil],
+ "i386-openbsd4.0" => ["x86", "openbsd", "4.0"],
+ "i386-solaris2.10" => ["x86", "solaris", "2.10"],
+ "i386-solaris2.8" => ["x86", "solaris", "2.8"],
+ "mswin32" => ["x86", "mswin32", nil],
+ "x86_64-linux" => ["x86_64", "linux", nil],
+ "x86_64-linux-gnu" => ["x86_64", "linux", "gnu"],
+ "x86_64-linux-musl" => ["x86_64", "linux", "musl"],
+ "x86_64-linux-uclibc" => ["x86_64", "linux", "uclibc"],
+ "arm-linux-eabi" => ["arm", "linux", "eabi"],
+ "arm-linux-gnueabi" => ["arm", "linux", "gnueabi"],
+ "arm-linux-musleabi" => ["arm", "linux", "musleabi"],
+ "arm-linux-uclibceabi" => ["arm", "linux", "uclibceabi"],
+ "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],
}
test_cases.each do |arch, expected|
platform = Gem::Platform.new arch
assert_equal expected, platform.to_a, arch.inspect
+ assert_equal expected, Gem::Platform.new(platform.to_s).to_a, arch.inspect
end
end
@@ -168,7 +175,7 @@ class TestGemPlatform < Gem::TestCase
end
def test_initialize_mswin32_vc6
- orig_RUBY_SO_NAME = RbConfig::CONFIG["RUBY_SO_NAME"]
+ orig_ruby_so_name = RbConfig::CONFIG["RUBY_SO_NAME"]
RbConfig::CONFIG["RUBY_SO_NAME"] = "msvcrt-ruby18"
expected = ["x86", "mswin32", nil]
@@ -177,8 +184,8 @@ class TestGemPlatform < Gem::TestCase
assert_equal expected, platform.to_a, "i386-mswin32 VC6"
ensure
- if orig_RUBY_SO_NAME
- RbConfig::CONFIG["RUBY_SO_NAME"] = orig_RUBY_SO_NAME
+ if orig_ruby_so_name
+ RbConfig::CONFIG["RUBY_SO_NAME"] = orig_ruby_so_name
else
RbConfig::CONFIG.delete "RUBY_SO_NAME"
end
@@ -205,7 +212,7 @@ class TestGemPlatform < Gem::TestCase
end
def test_to_s
- if win_platform?
+ if Gem.win_platform?
assert_equal "x86-mswin32-60", Gem::Platform.local.to_s
else
assert_equal "x86-darwin-8", Gem::Platform.local.to_s
@@ -225,7 +232,7 @@ class TestGemPlatform < Gem::TestCase
my = Gem::Platform.new %w[cpu my_platform 1]
other = Gem::Platform.new %w[cpu other_platform 1]
- assert(my === my)
+ assert(my === my) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
refute(other === my)
refute(my === other)
end
@@ -262,6 +269,98 @@ class TestGemPlatform < Gem::TestCase
assert((with_x86_arch === with_nil_arch), "x86 =~ nil")
end
+ def test_nil_version_is_treated_as_any_version
+ x86_darwin_8 = Gem::Platform.new "i686-darwin8.0"
+ x86_darwin_nil = Gem::Platform.new "i686-darwin"
+
+ assert((x86_darwin_8 === x86_darwin_nil), "8.0 =~ nil")
+ assert((x86_darwin_nil === x86_darwin_8), "nil =~ 8.0")
+ end
+
+ def test_nil_version_is_stricter_for_linux_os
+ x86_linux = Gem::Platform.new "i686-linux"
+ x86_linux_gnu = Gem::Platform.new "i686-linux-gnu"
+ x86_linux_musl = Gem::Platform.new "i686-linux-musl"
+ x86_linux_uclibc = Gem::Platform.new "i686-linux-uclibc"
+
+ # a naked linux runtime is implicit gnu, as it represents the common glibc-linked runtime
+ assert(x86_linux === x86_linux_gnu, "linux =~ linux-gnu")
+ assert(x86_linux_gnu === x86_linux, "linux-gnu =~ linux")
+
+ # musl and explicit gnu should differ
+ refute(x86_linux_gnu === x86_linux_musl, "linux-gnu =~ linux-musl")
+ refute(x86_linux_musl === x86_linux_gnu, "linux-musl =~ linux-gnu")
+
+ # explicit libc differ
+ refute(x86_linux_uclibc === x86_linux_musl, "linux-uclibc =~ linux-musl")
+ refute(x86_linux_musl === x86_linux_uclibc, "linux-musl =~ linux-uclibc")
+
+ # musl host runtime accepts libc-generic or statically linked gems...
+ assert(x86_linux === x86_linux_musl, "linux =~ linux-musl")
+ # ...but implicit gnu runtime generally does not accept musl-specific gems
+ refute(x86_linux_musl === x86_linux, "linux-musl =~ linux")
+
+ # other libc are not glibc compatible
+ refute(x86_linux === x86_linux_uclibc, "linux =~ linux-uclibc")
+ refute(x86_linux_uclibc === x86_linux, "linux-uclibc =~ linux")
+ end
+
+ def test_eabi_version_is_stricter_for_linux_os
+ arm_linux_eabi = Gem::Platform.new "arm-linux-eabi"
+ arm_linux_gnueabi = Gem::Platform.new "arm-linux-gnueabi"
+ arm_linux_musleabi = Gem::Platform.new "arm-linux-musleabi"
+ arm_linux_uclibceabi = Gem::Platform.new "arm-linux-uclibceabi"
+
+ # a naked linux runtime is implicit gnu, as it represents the common glibc-linked runtime
+ assert(arm_linux_eabi === arm_linux_gnueabi, "linux-eabi =~ linux-gnueabi")
+ assert(arm_linux_gnueabi === arm_linux_eabi, "linux-gnueabi =~ linux-eabi")
+
+ # musl and explicit gnu should differ
+ refute(arm_linux_gnueabi === arm_linux_musleabi, "linux-gnueabi =~ linux-musleabi")
+ refute(arm_linux_musleabi === arm_linux_gnueabi, "linux-musleabi =~ linux-gnueabi")
+
+ # explicit libc differ
+ refute(arm_linux_uclibceabi === arm_linux_musleabi, "linux-uclibceabi =~ linux-musleabi")
+ refute(arm_linux_musleabi === arm_linux_uclibceabi, "linux-musleabi =~ linux-uclibceabi")
+
+ # musl host runtime accepts libc-generic or statically linked gems...
+ assert(arm_linux_eabi === arm_linux_musleabi, "linux-eabi =~ linux-musleabi")
+ # ...but implicit gnu runtime generally does not accept musl-specific gems
+ refute(arm_linux_musleabi === arm_linux_eabi, "linux-musleabi =~ linux-eabi")
+
+ # other libc are not glibc compatible
+ refute(arm_linux_eabi === arm_linux_uclibceabi, "linux-eabi =~ linux-uclibceabi")
+ refute(arm_linux_uclibceabi === arm_linux_eabi, "linux-uclibceabi =~ linux-eabi")
+ end
+
+ def test_eabi_and_nil_version_combination_strictness
+ arm_linux = Gem::Platform.new "arm-linux"
+ arm_linux_eabi = Gem::Platform.new "arm-linux-eabi"
+ arm_linux_eabihf = Gem::Platform.new "arm-linux-eabihf"
+ arm_linux_gnueabi = Gem::Platform.new "arm-linux-gnueabi"
+ arm_linux_gnueabihf = Gem::Platform.new "arm-linux-gnueabihf"
+ arm_linux_musleabi = Gem::Platform.new "arm-linux-musleabi"
+ arm_linux_musleabihf = Gem::Platform.new "arm-linux-musleabihf"
+ arm_linux_uclibceabi = Gem::Platform.new "arm-linux-uclibceabi"
+ arm_linux_uclibceabihf = Gem::Platform.new "arm-linux-uclibceabihf"
+
+ # generic arm host runtime with eabi modifier accepts generic arm gems
+ assert(arm_linux === arm_linux_eabi, "arm-linux =~ arm-linux-eabi")
+ assert(arm_linux === arm_linux_eabihf, "arm-linux =~ arm-linux-eabihf")
+
+ # explicit gnu arm host runtime with eabi modifier accepts generic arm gems
+ assert(arm_linux === arm_linux_gnueabi, "arm-linux =~ arm-linux-gnueabi")
+ assert(arm_linux === arm_linux_gnueabihf, "arm-linux =~ arm-linux-gnueabihf")
+
+ # musl arm host runtime accepts libc-generic or statically linked gems...
+ assert(arm_linux === arm_linux_musleabi, "arm-linux =~ arm-linux-musleabi")
+ assert(arm_linux === arm_linux_musleabihf, "arm-linux =~ arm-linux-musleabihf")
+
+ # other libc arm hosts are not glibc compatible
+ refute(arm_linux === arm_linux_uclibceabi, "arm-linux =~ arm-linux-uclibceabi")
+ refute(arm_linux === arm_linux_uclibceabihf, "arm-linux =~ arm-linux-uclibceabihf")
+ end
+
def test_equals3_cpu_arm
arm = Gem::Platform.new "arm-linux"
armv5 = Gem::Platform.new "armv5-linux"
@@ -381,6 +480,15 @@ class TestGemPlatform < Gem::TestCase
assert_equal 1, result.scan(/@version=/).size
end
+ def test_gem_platform_match_with_string_argument
+ util_set_arch "x86_64-linux-musl"
+
+ Gem::Deprecate.skip_during do
+ assert(Gem::Platform.match(Gem::Platform.new("x86_64-linux")), "should match Gem::Platform")
+ assert(Gem::Platform.match("x86_64-linux"), "should match String platform")
+ end
+ end
+
def assert_local_match(name)
assert_match Gem::Platform.local, name
end
diff --git a/test/rubygems/test_gem_rdoc.rb b/test/rubygems/test_gem_rdoc.rb
index 7a34542360..f9b1df6cd5 100644
--- a/test/rubygems/test_gem_rdoc.rb
+++ b/test/rubygems/test_gem_rdoc.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "rubygems"
require_relative "helper"
require "rubygems/rdoc"
@@ -99,7 +100,7 @@ class TestGemRDoc < Gem::TestCase
assert_equal @a.base_dir, e.directory
ensure
- FileUtils.chmod(0755, @a.base_dir) if File.directory?(@a.base_dir)
+ FileUtils.chmod(0o755, @a.base_dir) if File.directory?(@a.base_dir)
end
def test_ri_installed?
@@ -129,7 +130,7 @@ class TestGemRDoc < Gem::TestCase
assert_equal @a.doc_dir, e.directory
ensure
if File.exist? @a.doc_dir
- FileUtils.chmod 0755, @a.doc_dir
+ FileUtils.chmod 0o755, @a.doc_dir
FileUtils.rm_r @a.doc_dir
end
end
diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb
index d8b55a5f7a..e71b2f5ff6 100644
--- a/test/rubygems/test_gem_remote_fetcher.rb
+++ b/test/rubygems/test_gem_remote_fetcher.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "webrick"
@@ -28,7 +29,7 @@ require "rubygems/package"
class TestGemRemoteFetcher < Gem::TestCase
include Gem::DefaultUserInteraction
- SERVER_DATA = <<-EOY.freeze
+ SERVER_DATA = <<-EOY
--- !ruby/object:Gem::Cache
gems:
rake-0.4.11: !ruby/object:Gem::Specification
@@ -161,7 +162,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_cache_update_path
- uri = URI "http://example/file"
+ uri = Gem::URI "http://example/file"
path = File.join @tempdir, "file"
fetcher = util_fuck_with_fetcher "hello"
@@ -175,7 +176,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_cache_update_path_with_utf8_internal_encoding
with_internal_encoding("UTF-8") do
- uri = URI "http://example/file"
+ uri = Gem::URI "http://example/file"
path = File.join @tempdir, "file"
data = String.new("\xC8").force_encoding(Encoding::BINARY)
@@ -189,7 +190,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_cache_update_path_no_update
- uri = URI "http://example/file"
+ uri = Gem::URI "http://example/file"
path = File.join @tempdir, "file"
fetcher = util_fuck_with_fetcher "hello"
@@ -205,12 +206,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
fetcher = Gem::RemoteFetcher.fetcher
fetcher.instance_variable_set :@test_data, data
- unless blow
- def fetcher.fetch_path(arg, *rest)
- @test_arg = arg
- @test_data
- end
- else
+ if blow
def fetcher.fetch_path(arg, *rest)
# OMG I'm such an ass
class << self; remove_method :fetch_path; end
@@ -221,6 +217,11 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
raise Gem::RemoteFetcher::FetchError.new("haha!", "")
end
+ else
+ def fetcher.fetch_path(arg, *rest)
+ @test_arg = arg
+ @test_data
+ end
end
fetcher
@@ -310,6 +311,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_download_local
+ omit "doesn't work if tempdir has +" if @tempdir.include?("+")
FileUtils.mv @a1_gem, @tempdir
local_path = File.join @tempdir, @a1.file_name
inst = nil
@@ -322,6 +324,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_download_local_space
+ omit "doesn't work if tempdir has +" if @tempdir.include?("+")
space_path = File.join @tempdir, "space path"
FileUtils.mkdir space_path
FileUtils.mv @a1_gem, space_path
@@ -336,9 +339,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_download_install_dir
- a1_data = File.open @a1_gem, "rb" do |fp|
- fp.read
- end
+ a1_data = File.open @a1_gem, "rb", &:read
fetcher = util_fuck_with_fetcher a1_data
@@ -355,14 +356,19 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
assert File.exist?(a1_cache_gem)
end
- unless win_platform? || Process.uid.zero? # File.chmod doesn't work
+ unless Gem.win_platform? || Process.uid.zero? # File.chmod doesn't work
def test_download_local_read_only
+ omit "doesn't work if tempdir has +" if @tempdir.include?("+")
FileUtils.mv @a1_gem, @tempdir
local_path = File.join @tempdir, @a1.file_name
inst = nil
- FileUtils.chmod 0555, @a1.cache_dir
- FileUtils.mkdir_p File.join(Gem.user_dir, "cache") rescue nil
- FileUtils.chmod 0555, File.join(Gem.user_dir, "cache")
+ FileUtils.chmod 0o555, @a1.cache_dir
+ begin
+ FileUtils.mkdir_p File.join(Gem.user_dir, "cache")
+ rescue StandardError
+ nil
+ end
+ FileUtils.chmod 0o555, File.join(Gem.user_dir, "cache")
Dir.chdir @tempdir do
inst = Gem::RemoteFetcher.fetcher
@@ -371,21 +377,23 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
assert_equal(File.join(@tempdir, @a1.file_name),
inst.download(@a1, local_path))
ensure
- FileUtils.chmod 0755, File.join(Gem.user_dir, "cache")
- FileUtils.chmod 0755, @a1.cache_dir
+ if local_path
+ FileUtils.chmod 0o755, File.join(Gem.user_dir, "cache")
+ FileUtils.chmod 0o755, @a1.cache_dir
+ end
end
def test_download_read_only
- FileUtils.chmod 0555, @a1.cache_dir
- FileUtils.chmod 0555, @gemhome
+ FileUtils.chmod 0o555, @a1.cache_dir
+ FileUtils.chmod 0o555, @gemhome
fetcher = util_fuck_with_fetcher File.read(@a1_gem)
fetcher.download(@a1, "http://gems.example.com")
a1_cache_gem = File.join Gem.user_dir, "cache", @a1.file_name
assert File.exist? a1_cache_gem
ensure
- FileUtils.chmod 0755, @gemhome
- FileUtils.chmod 0755, @a1.cache_dir
+ FileUtils.chmod 0o755, @gemhome
+ FileUtils.chmod 0o755, @a1.cache_dir
end
end
@@ -415,6 +423,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_download_same_file
+ omit "doesn't work if tempdir has +" if @tempdir.include?("+")
FileUtils.mv @a1_gem, @tempdir
local_path = File.join @tempdir, @a1.file_name
inst = nil
@@ -535,8 +544,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
fetcher.fetch_path url
end
- assert_match %r{ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z},
- e.message
+ assert_match(/ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z/,
+ e.message)
assert_equal url, e.uri
end
@@ -545,7 +554,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@fetcher = fetcher
def fetcher.fetch_http(uri, mtime = nil, head = nil)
- raise Timeout::Error, "timed out"
+ raise Gem::Timeout::Error, "timed out"
end
url = "http://example.com/uri"
@@ -554,8 +563,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
fetcher.fetch_path url
end
- assert_match %r{Timeout::Error: timed out \(#{Regexp.escape url}\)\z},
- e.message
+ assert_match(/Gem::Timeout::Error: timed out \(#{Regexp.escape url}\)\z/,
+ e.message)
assert_equal url, e.uri
end
@@ -573,8 +582,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
fetcher.fetch_path url
end
- assert_match %r{SocketError: getaddrinfo: nodename nor servname provided \(#{Regexp.escape url}\)\z},
- e.message
+ assert_match(/SocketError: getaddrinfo: nodename nor servname provided \(#{Regexp.escape url}\)\z/,
+ e.message)
assert_equal url, e.uri
end
@@ -604,7 +613,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
nil
end
- assert_nil fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0))
+ assert_nil fetcher.fetch_path(Gem::URI.parse(@gem_repo), Time.at(0))
end
def test_implicit_no_proxy
@@ -649,19 +658,20 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def fetcher.request(uri, request_class, last_modified = nil)
url = "http://gems.example.com/redirect"
- unless defined? @requested
+ if defined? @requested
+ res = Gem::Net::HTTPOK.new nil, 200, nil
+ def res.body
+ "real_path"
+ end
+ else
@requested = true
- res = Net::HTTPMovedPermanently.new nil, 301, nil
+ res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil
res.add_field "Location", url
- res
- else
- res = Net::HTTPOK.new nil, 200, nil
- def res.body() "real_path" end
- res
end
+ res
end
- data = fetcher.fetch_http URI.parse(url)
+ data = fetcher.fetch_http Gem::URI.parse(url)
assert_equal "real_path", data
end
@@ -673,13 +683,13 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def fetcher.request(uri, request_class, last_modified = nil)
url = "http://gems.example.com/redirect"
- res = Net::HTTPMovedPermanently.new nil, 301, nil
+ res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil
res.add_field "Location", url
res
end
e = assert_raise Gem::RemoteFetcher::FetchError do
- fetcher.fetch_http URI.parse(url)
+ fetcher.fetch_http Gem::URI.parse(url)
end
assert_equal "too many redirects (#{url})", e.message
@@ -691,12 +701,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
url = "http://gems.example.com/redirect"
def fetcher.request(uri, request_class, last_modified = nil)
- res = Net::HTTPMovedPermanently.new nil, 301, nil
+ res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil
res
end
e = assert_raise Gem::RemoteFetcher::FetchError do
- fetcher.fetch_http URI.parse(url)
+ fetcher.fetch_http Gem::URI.parse(url)
end
assert_equal "redirecting but no redirect location was given (#{url})", e.message
@@ -704,7 +714,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_http_with_additional_headers
ENV["http_proxy"] = @proxy_uri
- ENV["no_proxy"] = URI::parse(@server_uri).host
+ ENV["no_proxy"] = Gem::URI.parse(@server_uri).host
fetcher = Gem::RemoteFetcher.new nil, nil, { "X-Captain" => "murphy" }
@fetcher = fetcher
assert_equal "murphy", fetcher.fetch_path(@server_uri)
@@ -718,8 +728,10 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def fetcher.request(uri, request_class, last_modified = nil)
$fetched_uri = uri
- res = Net::HTTPOK.new nil, 200, nil
- def res.body() "success" end
+ res = Gem::Net::HTTPOK.new nil, 200, nil
+ def res.body
+ "success"
+ end
res
end
@@ -735,7 +747,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
s3_uri_signer
end
- data = fetcher.fetch_s3 URI.parse(url)
+ data = fetcher.fetch_s3 Gem::URI.parse(url)
assert_equal "https://my-bucket.s3.#{region}.amazonaws.com/gems/specs.4.8.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=testuser%2F20190624%2F#{region}%2Fs3%2Faws4_request&X-Amz-Date=20190624T050641Z&X-Amz-Expires=86400#{token ? "&X-Amz-Security-Token=" + token : ""}&X-Amz-SignedHeaders=host&X-Amz-Signature=#{signature}", $fetched_uri.to_s
assert_equal "success", data
@@ -745,10 +757,10 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_s3_config_creds
Gem.configuration[:s3_source] = {
- "my-bucket" => { :id => "testuser", :secret => "testpass" },
+ "my-bucket" => { id: "testuser", secret: "testpass" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b"
end
ensure
@@ -757,10 +769,10 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_s3_config_creds_with_region
Gem.configuration[:s3_source] = {
- "my-bucket" => { :id => "testuser", :secret => "testpass", :region => "us-west-2" },
+ "my-bucket" => { id: "testuser", secret: "testpass", region: "us-west-2" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2"
end
ensure
@@ -769,10 +781,10 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_s3_config_creds_with_token
Gem.configuration[:s3_source] = {
- "my-bucket" => { :id => "testuser", :secret => "testpass", :security_token => "testtoken" },
+ "my-bucket" => { id: "testuser", secret: "testpass", security_token: "testtoken" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken"
end
ensure
@@ -784,10 +796,10 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
ENV["AWS_SECRET_ACCESS_KEY"] = "testpass"
ENV["AWS_SESSION_TOKEN"] = nil
Gem.configuration[:s3_source] = {
- "my-bucket" => { :provider => "env" },
+ "my-bucket" => { provider: "env" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b"
end
ensure
@@ -800,10 +812,10 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
ENV["AWS_SECRET_ACCESS_KEY"] = "testpass"
ENV["AWS_SESSION_TOKEN"] = nil
Gem.configuration[:s3_source] = {
- "my-bucket" => { :provider => "env", :region => "us-west-2" },
+ "my-bucket" => { provider: "env", region: "us-west-2" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2"
end
ensure
@@ -816,10 +828,10 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
ENV["AWS_SECRET_ACCESS_KEY"] = "testpass"
ENV["AWS_SESSION_TOKEN"] = "testtoken"
Gem.configuration[:s3_source] = {
- "my-bucket" => { :provider => "env" },
+ "my-bucket" => { provider: "env" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken"
end
ensure
@@ -829,18 +841,18 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_s3_url_creds
url = "s3://testuser:testpass@my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b"
end
end
def test_fetch_s3_instance_profile_creds
Gem.configuration[:s3_source] = {
- "my-bucket" => { :provider => "instance_profile" },
+ "my-bucket" => { provider: "instance_profile" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b", nil, "us-east-1",
'{"AccessKeyId": "testuser", "SecretAccessKey": "testpass"}'
end
@@ -850,11 +862,11 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_s3_instance_profile_creds_with_region
Gem.configuration[:s3_source] = {
- "my-bucket" => { :provider => "instance_profile", :region => "us-west-2" },
+ "my-bucket" => { provider: "instance_profile", region: "us-west-2" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2",
'{"AccessKeyId": "testuser", "SecretAccessKey": "testpass"}'
end
@@ -864,11 +876,11 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_s3_instance_profile_creds_with_token
Gem.configuration[:s3_source] = {
- "my-bucket" => { :provider => "instance_profile" },
+ "my-bucket" => { provider: "instance_profile" },
}
url = "s3://my-bucket/gems/specs.4.8.gz"
- Time.stub :now, Time.at(1561353581) do
+ Time.stub :now, Time.at(1_561_353_581) do
assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken", "us-east-1",
'{"AccessKeyId": "testuser", "SecretAccessKey": "testpass", "Token": "testtoken"}'
end
@@ -881,7 +893,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@fetcher = fetcher
e = assert_raise Gem::RemoteFetcher::FetchError do
- fetcher.fetch_s3 URI.parse(url)
+ fetcher.fetch_s3 Gem::URI.parse(url)
end
assert_match expected_message, e.message
@@ -894,7 +906,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_fetch_s3_no_host
Gem.configuration[:s3_source] = {
- "my-bucket" => { :id => "testuser", :secret => "testpass" },
+ "my-bucket" => { id: "testuser", secret: "testpass" },
}
url = "s3://other-bucket/gems/specs.4.8.gz"
@@ -904,7 +916,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_fetch_s3_no_id
- Gem.configuration[:s3_source] = { "my-bucket" => { :secret => "testpass" } }
+ Gem.configuration[:s3_source] = { "my-bucket" => { secret: "testpass" } }
url = "s3://my-bucket/gems/specs.4.8.gz"
refute_fetch_s3 url, "s3_source for my-bucket missing id or secret"
@@ -913,7 +925,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_fetch_s3_no_secret
- Gem.configuration[:s3_source] = { "my-bucket" => { :id => "testuser" } }
+ Gem.configuration[:s3_source] = { "my-bucket" => { id: "testuser" } }
url = "s3://my-bucket/gems/specs.4.8.gz"
refute_fetch_s3 url, "s3_source for my-bucket missing id or secret"
@@ -924,7 +936,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_observe_no_proxy_env_single_host
use_ui @stub_ui do
ENV["http_proxy"] = @proxy_uri
- ENV["no_proxy"] = URI::parse(@server_uri).host
+ ENV["no_proxy"] = Gem::URI.parse(@server_uri).host
fetcher = Gem::RemoteFetcher.new nil
@fetcher = fetcher
assert_data_from_server fetcher.fetch_path(@server_uri)
@@ -934,7 +946,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def test_observe_no_proxy_env_list
use_ui @stub_ui do
ENV["http_proxy"] = @proxy_uri
- ENV["no_proxy"] = "fakeurl.com, #{URI::parse(@server_uri).host}"
+ ENV["no_proxy"] = "fakeurl.com, #{Gem::URI.parse(@server_uri).host}"
fetcher = Gem::RemoteFetcher.new nil
@fetcher = fetcher
assert_data_from_server fetcher.fetch_path(@server_uri)
@@ -946,8 +958,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@fetcher = fetcher
assert_throws :block_called do
- fetcher.request URI("http://example"), Net::HTTP::Get do |req|
- assert_kind_of Net::HTTPGenericRequest, req
+ fetcher.request Gem::URI("http://example"), Gem::Net::HTTP::Get do |req|
+ assert_kind_of Gem::Net::HTTPGenericRequest, req
throw :block_called
end
end
@@ -971,31 +983,33 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
def test_ssl_client_cert_auth_connection
- ssl_server = start_ssl_server({
- :SSLVerifyClient =>
- OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT })
+ ssl_server = start_ssl_server(
+ { SSLVerifyClient: OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT }
+ )
temp_ca_cert = File.join(__dir__, "ca_cert.pem")
temp_client_cert = File.join(__dir__, "client.pem")
with_configured_fetcher(
- ":ssl_ca_cert: #{temp_ca_cert}\n" +
- ":ssl_client_cert: #{temp_client_cert}\n") do |fetcher|
+ ":ssl_ca_cert: #{temp_ca_cert}\n" \
+ ":ssl_client_cert: #{temp_client_cert}\n"
+ ) do |fetcher|
fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml")
end
end
def test_do_not_allow_invalid_client_cert_auth_connection
- ssl_server = start_ssl_server({
- :SSLVerifyClient =>
- OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT })
+ ssl_server = start_ssl_server(
+ { SSLVerifyClient: OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT }
+ )
temp_ca_cert = File.join(__dir__, "ca_cert.pem")
temp_client_cert = File.join(__dir__, "invalid_client.pem")
with_configured_fetcher(
- ":ssl_ca_cert: #{temp_ca_cert}\n" +
- ":ssl_client_cert: #{temp_client_cert}\n") do |fetcher|
+ ":ssl_ca_cert: #{temp_ca_cert}\n" \
+ ":ssl_client_cert: #{temp_client_cert}\n"
+ ) do |fetcher|
assert_raise Gem::RemoteFetcher::FetchError do
fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml")
end
@@ -1080,7 +1094,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
class NilLog < WEBrick::Log
- def log(level, data) #Do nothing
+ def log(level, data) # Do nothing
end
end
@@ -1115,8 +1129,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@ssl_server_thread.kill.join
@ssl_server_thread = nil
end
- utils = WEBrick::Utils # TimeoutHandler is since 1.9
- utils::TimeoutHandler.terminate if defined?(utils::TimeoutHandler.terminate)
+ WEBrick::Utils::TimeoutHandler.terminate
end
def normal_server_port
@@ -1132,17 +1145,17 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
null_logger = NilLog.new
server = WEBrick::HTTPServer.new({
- :Port => 0,
- :Logger => null_logger,
- :AccessLog => [],
- :SSLEnable => true,
- :SSLCACertificateFile => File.join(__dir__, "ca_cert.pem"),
- :SSLCertificate => cert("ssl_cert.pem"),
- :SSLPrivateKey => key("ssl_key.pem"),
- :SSLVerifyClient => nil,
- :SSLCertName => nil,
+ Port: 0,
+ Logger: null_logger,
+ AccessLog: [],
+ SSLEnable: true,
+ SSLCACertificateFile: File.join(__dir__, "ca_cert.pem"),
+ SSLCertificate: cert("ssl_cert.pem"),
+ SSLPrivateKey: key("ssl_key.pem"),
+ SSLVerifyClient: nil,
+ SSLCertName: nil,
}.merge(config))
- server.mount_proc("/yaml") do |req, res|
+ server.mount_proc("/yaml") do |_req, res|
res.body = "--- true\n"
end
server.mount_proc("/insecure_redirect") do |req, res|
@@ -1150,14 +1163,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
server.ssl_context.tmp_dh_callback = proc { TEST_KEY_DH2048 }
t = Thread.new do
- begin
- server.start
- rescue Exception => ex
- puts "ERROR during server thread: #{ex.message}"
- raise
- ensure
- server.shutdown
- end
+ server.start
+ rescue StandardError => ex
+ puts "ERROR during server thread: #{ex.message}"
+ raise
+ ensure
+ server.shutdown
end
while server.status != :Running
sleep 0.1
@@ -1174,12 +1185,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
def start_server(data)
null_logger = NilLog.new
s = WEBrick::HTTPServer.new(
- :Port => 0,
- :DocumentRoot => nil,
- :Logger => null_logger,
- :AccessLog => null_logger
+ Port: 0,
+ DocumentRoot: nil,
+ Logger: null_logger,
+ AccessLog: null_logger
)
- s.mount_proc("/kill") {|req, res| s.shutdown }
+ s.mount_proc("/kill") {|_req, _res| s.shutdown }
s.mount_proc("/yaml") do |req, res|
if req["X-Captain"]
res.body = req["X-Captain"]
@@ -1193,7 +1204,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
res["Content-Type"] = "text/html"
end
end
- s.mount_proc("/yaml.Z") do |req, res|
+ s.mount_proc("/yaml.Z") do |_req, res|
if @enable_zip
res.body = Zlib::Deflate.deflate(data)
res["Content-Type"] = "text/plain"
@@ -1204,13 +1215,11 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
end
end
th = Thread.new do
- begin
- s.start
- rescue Exception => ex
- abort "ERROR during server thread: #{ex.message}"
- ensure
- s.shutdown
- end
+ s.start
+ rescue StandardError => ex
+ abort "ERROR during server thread: #{ex.message}"
+ ensure
+ s.shutdown
end
th[:server] = s
th
diff --git a/test/rubygems/test_gem_request.rb b/test/rubygems/test_gem_request.rb
index aba9dc5447..5e9b264dac 100644
--- a/test/rubygems/test_gem_request.rb
+++ b/test/rubygems/test_gem_request.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/request"
require "ostruct"
-require "base64"
unless Gem::HAVE_OPENSSL
warn "Skipping Gem::Request tests. openssl not found."
@@ -20,6 +20,12 @@ class TestGemRequest < Gem::TestCase
Gem::Request.create_with_proxy uri, request_class, last_modified, proxy
end
+ # This method is same code as Base64.encode64
+ # We should not use Base64.encode64 because we need to avoid gem activation.
+ def base64_encode64(bin)
+ [bin].pack("m")
+ end
+
def setup
@proxies = %w[http_proxy https_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY]
@old_proxies = @proxies.map {|k| ENV[k] }
@@ -28,7 +34,7 @@ class TestGemRequest < Gem::TestCase
super
@proxy_uri = "http://localhost:1234"
- @uri = URI("http://example")
+ @uri = Gem::URI("http://example")
@request = make_request @uri, nil, nil, nil
end
@@ -50,7 +56,7 @@ class TestGemRequest < Gem::TestCase
def test_initialize_proxy_URI
proxy_uri = "http://proxy.example.com"
- request = make_request @uri, nil, nil, URI(proxy_uri)
+ request = make_request @uri, nil, nil, Gem::URI(proxy_uri)
assert_equal proxy_uri, request.proxy_uri.to_s
end
@@ -71,18 +77,18 @@ class TestGemRequest < Gem::TestCase
def test_initialize_proxy_ENV_https
ENV["https_proxy"] = @proxy_uri
- request = make_request URI("https://example"), nil, nil, nil
+ request = make_request Gem::URI("https://example"), nil, nil, nil
proxy = request.proxy_uri
- assert_equal URI(@proxy_uri), proxy
+ assert_equal Gem::URI(@proxy_uri), proxy
end
def test_proxy_ENV
ENV["http_proxy"] = "http://proxy"
ENV["https_proxy"] = ""
- request = make_request URI("https://example"), nil, nil, nil
+ request = make_request Gem::URI("https://example"), nil, nil, nil
proxy = request.proxy_uri
@@ -90,13 +96,13 @@ class TestGemRequest < Gem::TestCase
end
def test_configure_connection_for_https
- connection = Net::HTTP.new "localhost", 443
+ connection = Gem::Net::HTTP.new "localhost", 443
request = Class.new(Gem::Request) do
def self.get_cert_files
[TestGemRequest::PUBLIC_CERT_FILE]
end
- end.create_with_proxy URI("https://example"), nil, nil, nil
+ end.create_with_proxy Gem::URI("https://example"), nil, nil, nil
Gem::Request.configure_connection_for_https connection, request.cert_files
@@ -106,16 +112,16 @@ class TestGemRequest < Gem::TestCase
end
def test_configure_connection_for_https_ssl_ca_cert
- ssl_ca_cert, Gem.configuration.ssl_ca_cert =
- Gem.configuration.ssl_ca_cert, CA_CERT_FILE
+ ssl_ca_cert = Gem.configuration.ssl_ca_cert
+ Gem.configuration.ssl_ca_cert = CA_CERT_FILE
- connection = Net::HTTP.new "localhost", 443
+ connection = Gem::Net::HTTP.new "localhost", 443
request = Class.new(Gem::Request) do
def self.get_cert_files
[TestGemRequest::PUBLIC_CERT_FILE]
end
- end.create_with_proxy URI("https://example"), nil, nil, nil
+ end.create_with_proxy Gem::URI("https://example"), nil, nil, nil
Gem::Request.configure_connection_for_https connection, request.cert_files
@@ -132,17 +138,17 @@ class TestGemRequest < Gem::TestCase
request = make_request @uri, nil, nil, nil
proxy = request.proxy_uri
- assert_equal URI(@proxy_uri), proxy
+ assert_equal Gem::URI(@proxy_uri), proxy
end
def test_get_proxy_from_env_https
ENV["https_proxy"] = @proxy_uri
- uri = URI("https://example")
+ uri = Gem::URI("https://example")
request = make_request uri, nil, nil, nil
proxy = request.proxy_uri
- assert_equal URI(@proxy_uri), proxy
+ assert_equal Gem::URI(@proxy_uri), proxy
end
def test_get_proxy_from_env_domain
@@ -185,9 +191,9 @@ class TestGemRequest < Gem::TestCase
end
def test_fetch
- uri = Gem::Uri.new(URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}")
- response = util_stub_net_http(:body => :junk, :code => 200) do
- @request = make_request(uri, Net::HTTP::Get, nil, nil)
+ uri = Gem::Uri.new(Gem::URI.parse("#{@gem_repo}/specs.#{Gem.marshal_version}"))
+ response = util_stub_net_http(body: :junk, code: 200) do
+ @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil)
@request.fetch
end
@@ -198,58 +204,58 @@ class TestGemRequest < Gem::TestCase
def test_fetch_basic_auth
Gem.configuration.verbose = :really
- uri = Gem::Uri.new(URI.parse "https://user:pass@example.rubygems/specs.#{Gem.marshal_version}")
- conn = util_stub_net_http(:body => :junk, :code => 200) do |c|
+ uri = Gem::Uri.new(Gem::URI.parse("https://user:pass@example.rubygems/specs.#{Gem.marshal_version}"))
+ conn = util_stub_net_http(body: :junk, code: 200) do |c|
use_ui @ui do
- @request = make_request(uri, Net::HTTP::Get, nil, nil)
+ @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil)
@request.fetch
end
c
end
auth_header = conn.payload["Authorization"]
- assert_equal "Basic #{Base64.encode64('user:pass')}".strip, auth_header
+ assert_equal "Basic #{base64_encode64("user:pass")}".strip, auth_header
assert_includes @ui.output, "GET https://user:REDACTED@example.rubygems/specs.#{Gem.marshal_version}"
end
def test_fetch_basic_auth_encoded
Gem.configuration.verbose = :really
- uri = Gem::Uri.new(URI.parse "https://user:%7BDEScede%7Dpass@example.rubygems/specs.#{Gem.marshal_version}")
+ uri = Gem::Uri.new(Gem::URI.parse("https://user:%7BDEScede%7Dpass@example.rubygems/specs.#{Gem.marshal_version}"))
- conn = util_stub_net_http(:body => :junk, :code => 200) do |c|
+ conn = util_stub_net_http(body: :junk, code: 200) do |c|
use_ui @ui do
- @request = make_request(uri, Net::HTTP::Get, nil, nil)
+ @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil)
@request.fetch
end
c
end
auth_header = conn.payload["Authorization"]
- assert_equal "Basic #{Base64.encode64('user:{DEScede}pass')}".strip, auth_header
+ assert_equal "Basic #{base64_encode64("user:{DEScede}pass")}".strip, auth_header
assert_includes @ui.output, "GET https://user:REDACTED@example.rubygems/specs.#{Gem.marshal_version}"
end
def test_fetch_basic_oauth_encoded
Gem.configuration.verbose = :really
- uri = Gem::Uri.new(URI.parse "https://%7BDEScede%7Dpass:x-oauth-basic@example.rubygems/specs.#{Gem.marshal_version}")
+ uri = Gem::Uri.new(Gem::URI.parse("https://%7BDEScede%7Dpass:x-oauth-basic@example.rubygems/specs.#{Gem.marshal_version}"))
- conn = util_stub_net_http(:body => :junk, :code => 200) do |c|
+ conn = util_stub_net_http(body: :junk, code: 200) do |c|
use_ui @ui do
- @request = make_request(uri, Net::HTTP::Get, nil, nil)
+ @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil)
@request.fetch
end
c
end
auth_header = conn.payload["Authorization"]
- assert_equal "Basic #{Base64.encode64('{DEScede}pass:x-oauth-basic')}".strip, auth_header
+ assert_equal "Basic #{base64_encode64("{DEScede}pass:x-oauth-basic")}".strip, auth_header
assert_includes @ui.output, "GET https://REDACTED:x-oauth-basic@example.rubygems/specs.#{Gem.marshal_version}"
end
def test_fetch_head
- uri = Gem::Uri.new(URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}")
- response = util_stub_net_http(:body => "", :code => 200) do |conn|
- @request = make_request(uri, Net::HTTP::Get, nil, nil)
+ uri = Gem::Uri.new(Gem::URI.parse("#{@gem_repo}/specs.#{Gem.marshal_version}"))
+ response = util_stub_net_http(body: "", code: 200) do |_conn|
+ @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil)
@request.fetch
end
@@ -258,10 +264,10 @@ class TestGemRequest < Gem::TestCase
end
def test_fetch_unmodified
- uri = Gem::Uri.new(URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}")
+ uri = Gem::Uri.new(Gem::URI.parse("#{@gem_repo}/specs.#{Gem.marshal_version}"))
t = Time.utc(2013, 1, 2, 3, 4, 5)
- conn, response = util_stub_net_http(:body => "", :code => 304) do |c|
- @request = make_request(uri, Net::HTTP::Get, t, nil)
+ conn, response = util_stub_net_http(body: "", code: 304) do |c|
+ @request = make_request(uri, Gem::Net::HTTP::Get, t, nil)
[c, @request.fetch]
end
@@ -280,7 +286,7 @@ class TestGemRequest < Gem::TestCase
assert_match %r{RubyGems/#{Regexp.escape Gem::VERSION}}, ua
assert_match %r{ #{Regexp.escape Gem::Platform.local.to_s} }, ua
assert_match %r{Ruby/#{Regexp.escape RUBY_VERSION}}, ua
- assert_match %r{\(#{Regexp.escape RUBY_RELEASE_DATE} }, ua
+ assert_match(/\(#{Regexp.escape RUBY_RELEASE_DATE} /, ua)
end
def test_user_agent_engine
@@ -291,7 +297,7 @@ class TestGemRequest < Gem::TestCase
ua = make_request(@uri, nil, nil, nil).user_agent
- assert_match %r{\) vroom}, ua
+ assert_match(/\) vroom/, ua)
ensure
util_restore_version
end
@@ -304,7 +310,7 @@ class TestGemRequest < Gem::TestCase
ua = make_request(@uri, nil, nil, nil).user_agent
- assert_match %r{\)}, ua
+ assert_match(/\)/, ua)
ensure
util_restore_version
end
@@ -327,7 +333,7 @@ class TestGemRequest < Gem::TestCase
Object.send :remove_const, :RUBY_PATCHLEVEL
Object.send :const_set, :RUBY_PATCHLEVEL, -1
- Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+ Object.send :remove_const, :RUBY_REVISION
Object.send :const_set, :RUBY_REVISION, 6
ua = make_request(@uri, nil, nil, nil).user_agent
@@ -338,20 +344,6 @@ class TestGemRequest < Gem::TestCase
util_restore_version
end
- def test_user_agent_revision_missing
- util_save_version
-
- Object.send :remove_const, :RUBY_PATCHLEVEL
- Object.send :const_set, :RUBY_PATCHLEVEL, -1
- Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
-
- ua = make_request(@uri, nil, nil, nil).user_agent
-
- assert_match %r{\(#{Regexp.escape RUBY_RELEASE_DATE}\)}, ua
- ensure
- util_restore_version
- end
-
def test_verify_certificate
pend if Gem.java_platform?
@@ -492,21 +484,19 @@ ERROR: Certificate is an invalid CA certificate
def util_restore_version
Object.send :remove_const, :RUBY_ENGINE
- Object.send :const_set, :RUBY_ENGINE, @orig_RUBY_ENGINE if
- defined?(@orig_RUBY_ENGINE)
+ Object.send :const_set, :RUBY_ENGINE, @orig_ruby_engine
Object.send :remove_const, :RUBY_PATCHLEVEL
- Object.send :const_set, :RUBY_PATCHLEVEL, @orig_RUBY_PATCHLEVEL
+ Object.send :const_set, :RUBY_PATCHLEVEL, @orig_ruby_patchlevel
- Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
- Object.send :const_set, :RUBY_REVISION, @orig_RUBY_REVISION if
- defined?(@orig_RUBY_REVISION)
+ Object.send :remove_const, :RUBY_REVISION
+ Object.send :const_set, :RUBY_REVISION, @orig_ruby_revision
end
def util_save_version
- @orig_RUBY_ENGINE = RUBY_ENGINE
- @orig_RUBY_PATCHLEVEL = RUBY_PATCHLEVEL
- @orig_RUBY_REVISION = RUBY_REVISION if defined? RUBY_REVISION
+ @orig_ruby_engine = RUBY_ENGINE
+ @orig_ruby_patchlevel = RUBY_PATCHLEVEL
+ @orig_ruby_revision = RUBY_REVISION
end
def util_stub_net_http(hash)
@@ -521,7 +511,10 @@ ERROR: Certificate is an invalid CA certificate
class Conn
attr_accessor :payload
- def new(*args); self; end
+ def new(*args)
+ self
+ end
+
def use_ssl=(bool); end
def verify_callback=(setting); end
def verify_mode=(setting); end
diff --git a/test/rubygems/test_gem_request_connection_pools.rb b/test/rubygems/test_gem_request_connection_pools.rb
index 964d5c961f..966447bff6 100644
--- a/test/rubygems/test_gem_request_connection_pools.rb
+++ b/test/rubygems/test_gem_request_connection_pools.rb
@@ -1,7 +1,8 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/request"
-require "timeout"
+require "rubygems/vendored_timeout"
class TestGemRequestConnectionPool < Gem::TestCase
class FakeHttp
@@ -17,7 +18,7 @@ class TestGemRequestConnectionPool < Gem::TestCase
@old_client = Gem::Request::ConnectionPools.client
Gem::Request::ConnectionPools.client = FakeHttp
- @proxy = URI "http://proxy.example"
+ @proxy = Gem::URI "http://proxy.example"
end
def teardown
@@ -48,7 +49,7 @@ class TestGemRequestConnectionPool < Gem::TestCase
end
def test_checkout_same_connection
- uri = URI.parse("http://example/some_endpoint")
+ uri = Gem::URI.parse("http://example/some_endpoint")
pools = Gem::Request::ConnectionPools.new nil, []
pool = pools.pool_for uri
@@ -98,7 +99,7 @@ class TestGemRequestConnectionPool < Gem::TestCase
def test_net_http_args
pools = Gem::Request::ConnectionPools.new nil, []
- net_http_args = pools.send :net_http_args, URI("http://example"), nil
+ net_http_args = pools.send :net_http_args, Gem::URI("http://example"), nil
assert_equal ["example", 80], net_http_args
end
@@ -106,7 +107,7 @@ class TestGemRequestConnectionPool < Gem::TestCase
def test_net_http_args_ipv6
pools = Gem::Request::ConnectionPools.new nil, []
- net_http_args = pools.send :net_http_args, URI("http://[::1]"), nil
+ net_http_args = pools.send :net_http_args, Gem::URI("http://[::1]"), nil
assert_equal ["::1", 80], net_http_args
end
@@ -114,34 +115,34 @@ class TestGemRequestConnectionPool < Gem::TestCase
def test_net_http_args_proxy
pools = Gem::Request::ConnectionPools.new nil, []
- net_http_args = pools.send :net_http_args, URI("http://example"), @proxy
+ net_http_args = pools.send :net_http_args, Gem::URI("http://example"), @proxy
assert_equal ["example", 80, "proxy.example", 80, nil, nil], net_http_args
end
def test_net_http_args_no_proxy
- orig_no_proxy, ENV["no_proxy"] = ENV["no_proxy"], "example"
+ orig_no_proxy = ENV["no_proxy"]
+ ENV["no_proxy"] = "example"
pools = Gem::Request::ConnectionPools.new nil, []
- net_http_args = pools.send :net_http_args, URI("http://example"), @proxy
+ net_http_args = pools.send :net_http_args, Gem::URI("http://example"), @proxy
assert_equal ["example", 80, nil, nil], net_http_args
-
ensure
ENV["no_proxy"] = orig_no_proxy
end
def test_thread_waits_for_connection
- uri = URI.parse("http://example/some_endpoint")
+ uri = Gem::URI.parse("http://example/some_endpoint")
pools = Gem::Request::ConnectionPools.new nil, []
pool = pools.pool_for uri
pool.checkout
Thread.new do
- assert_raise(Timeout::Error) do
- Timeout.timeout(1) do
+ assert_raise(Gem::Timeout::Error) do
+ Gem::Timeout.timeout(1) do
pool.checkout
end
end
diff --git a/test/rubygems/test_gem_request_set.rb b/test/rubygems/test_gem_request_set.rb
index 6d14321126..9aa244892c 100644
--- a/test/rubygems/test_gem_request_set.rb
+++ b/test/rubygems/test_gem_request_set.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/request_set"
@@ -7,8 +8,6 @@ class TestGemRequestSet < Gem::TestCase
super
Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
-
- @DR = Gem::Resolver
end
def test_gem
@@ -45,7 +44,7 @@ class TestGemRequestSet < Gem::TestCase
done_installing_ran = false
- Gem.done_installing do |installer, specs|
+ Gem.done_installing do |_installer, _specs|
done_installing_ran = true
end
@@ -56,7 +55,7 @@ class TestGemRequestSet < Gem::TestCase
io.puts 'gem "a"'
io.flush
- result = rs.install_from_gemdeps :gemdeps => io.path do |req, installer|
+ result = rs.install_from_gemdeps gemdeps: io.path do |req, _installer|
installed << req.full_name
end
@@ -88,7 +87,7 @@ Gems to install:
EXPECTED
actual, _ = capture_output do
- rs.install_from_gemdeps :gemdeps => io.path, :explain => true
+ rs.install_from_gemdeps gemdeps: io.path, explain: true
end
assert_equal(expected, actual)
end
@@ -110,11 +109,11 @@ Gems to install:
end
options = {
- :gemdeps => "gem.deps.rb",
- :install_dir => "#{@gemhome}2",
+ gemdeps: "gem.deps.rb",
+ install_dir: "#{@gemhome}2",
}
- rs.install_from_gemdeps options do |req, installer|
+ rs.install_from_gemdeps options do |req, _installer|
installed << req.full_name
end
@@ -134,7 +133,7 @@ Gems to install:
io.flush
assert_raise Gem::UnsatisfiableDependencyError do
- rs.install_from_gemdeps :gemdeps => io.path, :domain => :local
+ rs.install_from_gemdeps gemdeps: io.path, domain: :local
end
end
@@ -172,7 +171,7 @@ DEPENDENCIES
io.puts 'gem "b"'
end
- rs.install_from_gemdeps :gemdeps => "gem.deps.rb" do |req, installer|
+ rs.install_from_gemdeps gemdeps: "gem.deps.rb" do |req, _installer|
installed << req.full_name
end
@@ -226,7 +225,7 @@ end
io.puts("gemspec")
end
- rs.install_from_gemdeps :gemdeps => "Gemfile" do |req, installer|
+ rs.install_from_gemdeps gemdeps: "Gemfile" do |req, _installer|
installed << req.full_name
end
@@ -251,7 +250,7 @@ ruby "0"
io.flush
- rs.install_from_gemdeps :gemdeps => io.path do |req, installer|
+ rs.install_from_gemdeps gemdeps: io.path do |req, _installer|
installed << req.full_name
end
end
@@ -324,7 +323,7 @@ ruby "0"
res = rs.resolve StaticSet.new([a, b])
assert_equal 2, res.size
- names = res.map {|s| s.full_name }.sort
+ names = res.map(&:full_name).sort
assert_equal ["a-2", "b-2"], names
@@ -343,7 +342,7 @@ ruby "0"
res = rs.resolve StaticSet.new([a, b, c])
assert_equal 3, res.size
- names = res.map {|s| s.full_name }.sort
+ names = res.map(&:full_name).sort
assert_equal %w[a-1.b b-1.b c-1.1.b], names
end
@@ -410,12 +409,12 @@ ruby "0"
res = rs.resolve
assert_equal 1, res.size
- names = res.map {|s| s.full_name }.sort
+ names = res.map(&:full_name).sort
assert_equal %w[a-1], names
- assert_equal [@DR::BestSet, @DR::GitSet, @DR::VendorSet, @DR::SourceSet],
- rs.sets.map {|set| set.class }
+ assert_equal [Gem::Resolver::BestSet, Gem::Resolver::GitSet, Gem::Resolver::VendorSet, Gem::Resolver::SourceSet],
+ rs.sets.map(&:class)
end
def test_resolve_ignore_dependencies
@@ -429,7 +428,7 @@ ruby "0"
res = rs.resolve StaticSet.new([a, b])
assert_equal 1, res.size
- names = res.map {|s| s.full_name }.sort
+ names = res.map(&:full_name).sort
assert_equal %w[a-2], names
end
@@ -474,12 +473,12 @@ ruby "0"
res = rs.resolve
assert_equal 2, res.size
- names = res.map {|s| s.full_name }.sort
+ names = res.map(&:full_name).sort
assert_equal ["a-1", "b-2"], names
- assert_equal [@DR::BestSet, @DR::GitSet, @DR::VendorSet, @DR::SourceSet],
- rs.sets.map {|set| set.class }
+ assert_equal [Gem::Resolver::BestSet, Gem::Resolver::GitSet, Gem::Resolver::VendorSet, Gem::Resolver::SourceSet],
+ rs.sets.map(&:class)
end
def test_sorted_requests
@@ -492,7 +491,7 @@ ruby "0"
rs.resolve StaticSet.new([a, b, c])
- names = rs.sorted_requests.map {|s| s.full_name }
+ names = rs.sorted_requests.map(&:full_name)
assert_equal %w[c-2 b-2 a-2], names
end
@@ -521,14 +520,14 @@ ruby "0"
installers << installer
end
- assert_equal %w[b-1 a-1], reqs.map {|req| req.full_name }
+ assert_equal %w[b-1 a-1], reqs.map(&:full_name)
assert_equal %w[b-1 a-1],
installers.map {|installer| installer.spec.full_name }
assert_path_exist File.join @gemhome, "specifications", "a-1.gemspec"
assert_path_exist File.join @gemhome, "specifications", "b-1.gemspec"
- assert_equal %w[b-1 a-1], installed.map {|s| s.full_name }
+ assert_equal %w[b-1 a-1], installed.map(&:full_name)
assert done_installing_ran
end
@@ -551,7 +550,7 @@ ruby "0"
assert_path_exist File.join @tempdir, "specifications", "a-1.gemspec"
assert_path_exist File.join @tempdir, "specifications", "b-1.gemspec"
- assert_equal %w[b-1 a-1], installed.map {|s| s.full_name }
+ assert_equal %w[b-1 a-1], installed.map(&:full_name)
end
def test_install_into_development_shallow
@@ -575,15 +574,15 @@ ruby "0"
rs.resolve
options = {
- :development => true,
- :development_shallow => true,
+ development: true,
+ development_shallow: true,
}
installed = rs.install_into @tempdir, true, options do
assert_equal @tempdir, ENV["GEM_HOME"]
end
- assert_equal %w[a-1 b-1], installed.map {|s| s.full_name }.sort
+ assert_equal %w[a-1 b-1], installed.map(&:full_name).sort
end
def test_sorted_requests_development_shallow
@@ -608,7 +607,7 @@ ruby "0"
rs.resolve StaticSet.new [a_spec, b_spec, c_spec]
- assert_equal %w[b-1 a-1], rs.sorted_requests.map {|req| req.full_name }
+ assert_equal %w[b-1 a-1], rs.sorted_requests.map(&:full_name)
end
def test_tsort_each_child_development
@@ -637,7 +636,7 @@ ruby "0"
deps = rs.enum_for(:tsort_each_child, a_req).to_a
- assert_equal %w[b], deps.map {|dep| dep.name }
+ assert_equal %w[b], deps.map(&:name)
end
def test_tsort_each_child_development_shallow
diff --git a/test/rubygems/test_gem_request_set_gem_dependency_api.rb b/test/rubygems/test_gem_request_set_gem_dependency_api.rb
index d1411ddc56..af32005a16 100644
--- a/test/rubygems/test_gem_request_set_gem_dependency_api.rb
+++ b/test/rubygems/test_gem_request_set_gem_dependency_api.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/request_set"
@@ -6,14 +7,12 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def setup
super
- @GDA = Gem::RequestSet::GemDependencyAPI
-
@set = Gem::RequestSet.new
@git_set = Gem::Resolver::GitSet.new
@vendor_set = Gem::Resolver::VendorSet.new
- @gda = @GDA.new @set, "gem.deps.rb"
+ @gda = Gem::RequestSet::GemDependencyAPI.new @set, "gem.deps.rb"
@gda.instance_variable_set :@git_set, @git_set
@gda.instance_variable_set :@vendor_set, @vendor_set
end
@@ -48,7 +47,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
s.add_runtime_dependency "bar", ">= 1.6.0", "< 1.6.4"
end
@gda.gemspec
- assert_equal %w[ foo bar ].sort, @set.dependencies.map(&:name).sort
+ assert_equal %w[foo bar].sort, @set.dependencies.map(&:name).sort
bar = @set.dependencies.find {|d| d.name == "bar" }
assert_equal [["<", Gem::Version.create("1.6.4")],
[">=", Gem::Version.create("1.6.0")]], bar.requirement.requirements.sort
@@ -91,11 +90,11 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_git
- @gda.gem "a", :git => "git/a"
+ @gda.gem "a", git: "git/a"
assert_equal [dep("a")], @set.dependencies
- assert_equal %w[git/a master], @git_set.repositories["a"]
+ assert_equal ["git/a", nil], @git_set.repositories["a"]
expected = { "a" => Gem::Requirement.create("!") }
@@ -103,11 +102,11 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_bitbucket
- @gda.gem "a", :bitbucket => "example/repository"
+ @gda.gem "a", bitbucket: "example/repository"
assert_equal [dep("a")], @set.dependencies
- assert_equal %w[https://example@bitbucket.org/example/repository.git master],
+ assert_equal ["https://example@bitbucket.org/example/repository.git", nil],
@git_set.repositories["a"]
expected = { "a" => Gem::Requirement.create("!") }
@@ -116,11 +115,11 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_bitbucket_expand_path
- @gda.gem "a", :bitbucket => "example"
+ @gda.gem "a", bitbucket: "example"
assert_equal [dep("a")], @set.dependencies
- assert_equal %w[https://example@bitbucket.org/example/example.git master],
+ assert_equal ["https://example@bitbucket.org/example/example.git", nil],
@git_set.repositories["a"]
expected = { "a" => Gem::Requirement.create("!") }
@@ -130,7 +129,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_git_branch
_, err = capture_output do
- @gda.gem "a", :git => "git/a", :branch => "other", :tag => "v1"
+ @gda.gem "a", git: "git/a", branch: "other", tag: "v1"
end
expected = "Gem dependencies file gem.deps.rb includes git reference for both ref/branch and tag but only ref/branch is used."
assert_match expected, err
@@ -141,17 +140,17 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_git_gist
- @gda.gem "a", :gist => "a"
+ @gda.gem "a", gist: "a"
assert_equal [dep("a")], @set.dependencies
- assert_equal %w[https://gist.github.com/a.git master],
+ assert_equal ["https://gist.github.com/a.git", nil],
@git_set.repositories["a"]
end
def test_gem_git_ref
_, err = capture_output do
- @gda.gem "a", :git => "git/a", :ref => "abcd123", :branch => "other"
+ @gda.gem "a", git: "git/a", ref: "abcd123", branch: "other"
end
expected = "Gem dependencies file gem.deps.rb includes git reference for both ref and branch but only ref is used."
assert_match expected, err
@@ -162,16 +161,16 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_git_submodules
- @gda.gem "a", :git => "git/a", :submodules => true
+ @gda.gem "a", git: "git/a", submodules: true
assert_equal [dep("a")], @set.dependencies
- assert_equal %w[git/a master], @git_set.repositories["a"]
+ assert_equal ["git/a", nil], @git_set.repositories["a"]
assert_equal %w[git/a], @git_set.need_submodules.keys
end
def test_gem_git_tag
- @gda.gem "a", :git => "git/a", :tag => "v1"
+ @gda.gem "a", git: "git/a", tag: "v1"
assert_equal [dep("a")], @set.dependencies
@@ -179,11 +178,11 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_github
- @gda.gem "a", :github => "example/repository"
+ @gda.gem "a", github: "example/repository"
assert_equal [dep("a")], @set.dependencies
- assert_equal %w[git://github.com/example/repository.git master],
+ assert_equal ["https://github.com/example/repository.git", nil],
@git_set.repositories["a"]
expected = { "a" => Gem::Requirement.create("!") }
@@ -192,11 +191,11 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_github_expand_path
- @gda.gem "a", :github => "example"
+ @gda.gem "a", github: "example"
assert_equal [dep("a")], @set.dependencies
- assert_equal %w[git://github.com/example/example.git master],
+ assert_equal ["https://github.com/example/example.git", nil],
@git_set.repositories["a"]
expected = { "a" => Gem::Requirement.create("!") }
@@ -205,7 +204,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_group
- @gda.gem "a", :group => :test
+ @gda.gem "a", group: :test
assert_equal [dep("a")], @set.dependencies
end
@@ -213,7 +212,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_group_without
@gda.without_groups << :test
- @gda.gem "a", :group => :test
+ @gda.gem "a", group: :test
assert_empty @set.dependencies
@@ -223,7 +222,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_groups
- @gda.gem "a", :groups => [:test, :development]
+ @gda.gem "a", groups: [:test, :development]
assert_equal [dep("a")], @set.dependencies
end
@@ -231,7 +230,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_path
name, version, directory = vendor_gem
- @gda.gem name, :path => directory
+ @gda.gem name, path: directory
assert_equal [dep(name)], @set.dependencies
@@ -245,10 +244,11 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_platforms
- win_platform, Gem.win_platform = Gem.win_platform?, false
+ win_platform = Gem.win_platform?
+ Gem.win_platform = false
with_engine_version "ruby", "2.0.0" do
- @gda.gem "a", :platforms => :ruby
+ @gda.gem "a", platforms: :ruby
refute_empty @set.dependencies
end
@@ -257,36 +257,37 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_platforms_bundler_ruby
- win_platform, Gem.win_platform = Gem.win_platform?, false
+ win_platform = Gem.win_platform?
+ Gem.win_platform = false
with_engine_version "ruby", "2.0.0" do
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :ruby
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :ruby
refute_empty set.dependencies
end
with_engine_version "rbx", "2.0.0" do
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :ruby
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :ruby
refute_empty set.dependencies
end
with_engine_version "truffleruby", "2.0.0" do
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :ruby
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :ruby
refute_empty set.dependencies
end
with_engine_version "jruby", "1.7.6" do
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :ruby
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :ruby
assert_empty set.dependencies
end
@@ -295,8 +296,8 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
with_engine_version "ruby", "2.0.0" do
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :ruby
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :ruby
assert_empty set.dependencies
end
@@ -306,31 +307,32 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_platforms_engine
with_engine_version "jruby", "1.7.6" do
- @gda.gem "a", :platforms => :mri
+ @gda.gem "a", platforms: :mri
assert_empty @set.dependencies
end
with_engine_version "truffleruby", "1.2.3" do
- @gda.gem "a", :platforms => :mri
+ @gda.gem "a", platforms: :mri
assert_empty @set.dependencies
end
end
def test_gem_platforms_maglev
- win_platform, Gem.win_platform = Gem.win_platform?, false
+ win_platform = Gem.win_platform?
+ Gem.win_platform = false
with_engine_version "maglev", "1.0.0" do
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :ruby
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :ruby
refute_empty set.dependencies
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :maglev
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :maglev
refute_empty set.dependencies
end
@@ -341,37 +343,38 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_platforms_truffleruby
with_engine_version "truffleruby", "1.0.0" do
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :truffleruby
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :truffleruby
refute_empty set.dependencies
set = Gem::RequestSet.new
- gda = @GDA.new set, "gem.deps.rb"
- gda.gem "a", :platforms => :maglev
+ gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb"
+ gda.gem "a", platforms: :maglev
assert_empty set.dependencies
end
end
def test_gem_platforms_multiple
- win_platform, Gem.win_platform = Gem.win_platform?, false
+ win_platform = Gem.win_platform?
+ Gem.win_platform = false
with_engine_version "ruby", "2.0.0" do
- @gda.gem "a", :platforms => [:mswin, :jruby]
+ @gda.gem "a", platforms: [:mswin, :jruby]
assert_empty @set.dependencies
end
-
ensure
Gem.win_platform = win_platform
end
def test_gem_platforms_platform
- win_platform, Gem.win_platform = Gem.win_platform?, false
+ win_platform = Gem.win_platform?
+ Gem.win_platform = false
with_engine_version "ruby", "2.0.0" do
- @gda.gem "a", :platforms => :jruby, :platform => :ruby
+ @gda.gem "a", platforms: :jruby, platform: :ruby
refute_empty @set.dependencies
end
@@ -381,7 +384,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_platforms_version
with_engine_version "ruby", "2.0.0" do
- @gda.gem "a", :platforms => :ruby_18
+ @gda.gem "a", platforms: :ruby_18
assert_empty @set.dependencies
end
@@ -389,15 +392,15 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_platforms_unknown
e = assert_raise ArgumentError do
- @gda.gem "a", :platforms => :unknown
+ @gda.gem "a", platforms: :unknown
end
assert_equal "unknown platform :unknown", e.message
end
def test_gem_requires
- @gda.gem "a", :require => %w[b c]
- @gda.gem "d", :require => "e"
+ @gda.gem "a", require: %w[b c]
+ @gda.gem "d", require: "e"
assert_equal [dep("a"), dep("d")], @set.dependencies
@@ -406,7 +409,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_requires_false
- @gda.gem "a", :require => false
+ @gda.gem "a", require: false
assert_equal [dep("a")], @set.dependencies
@@ -416,7 +419,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_requires_without_group
@gda.without_groups << :test
- @gda.gem "a", :group => :test
+ @gda.gem "a", group: :test
assert_empty @set.dependencies
@@ -444,7 +447,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
end
def test_gem_requirements_options
- @gda.gem "c", :git => "https://example/c.git"
+ @gda.gem "c", git: "https://example/c.git"
assert_equal [dep("c")], @set.dependencies
end
@@ -452,19 +455,19 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_source_mismatch
name, _, directory = vendor_gem
- gda = @GDA.new @set, nil
+ gda = Gem::RequestSet::GemDependencyAPI.new @set, nil
gda.gem name
e = assert_raise ArgumentError do
- gda.gem name, :path => directory
+ gda.gem name, path: directory
end
assert_equal "duplicate source path: #{directory} for gem #{name}",
e.message
- gda = @GDA.new @set, nil
+ gda = Gem::RequestSet::GemDependencyAPI.new @set, nil
gda.instance_variable_set :@vendor_set, @vendor_set
- gda.gem name, :path => directory
+ gda.gem name, path: directory
e = assert_raise ArgumentError do
gda.gem name
@@ -477,7 +480,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
def test_gem_deps_file
assert_equal "gem.deps.rb", @gda.gem_deps_file
- gda = @GDA.new @set, "foo/Gemfile"
+ gda = Gem::RequestSet::GemDependencyAPI.new @set, "foo/Gemfile"
assert_equal "Gemfile", gda.gem_deps_file
end
@@ -486,10 +489,10 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
groups = []
@gda.group :a do
- groups = @gda.send :gem_group, "a", :group => :b, :groups => [:c, :d]
+ groups = @gda.send :gem_group, "a", group: :b, groups: [:c, :d]
end
- assert_equal [:a, :b, :c, :d], groups.sort_by {|group| group.to_s }
+ assert_equal [:a, :b, :c, :d], groups.sort_by(&:to_s)
end
def test_gemspec
@@ -534,7 +537,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
@gda.without_groups << :other
- @gda.gemspec :development_group => :other
+ @gda.gemspec development_group: :other
assert_equal [dep("a", "= 1"), dep("b", "= 2")], @set.dependencies
@@ -566,7 +569,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
s.add_dependency "c", 3
end
- @gda.gemspec :name => "b"
+ @gda.gemspec name: "b"
assert_equal [dep("b", "= 2"), dep("c", "= 3")], @set.dependencies
end
@@ -596,7 +599,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
s.add_dependency "b", 2
end
- @gda.gemspec :path => "other"
+ @gda.gemspec path: "other"
assert_equal [dep("a", "= 1"), dep("b", "= 2")], @set.dependencies
end
@@ -609,8 +612,8 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
assert_equal [dep("a"), dep("b")], @set.dependencies
- assert_equal %w[git://example/repo.git master], @git_set.repositories["a"]
- assert_equal %w[git://example/repo.git master], @git_set.repositories["b"]
+ assert_equal ["git://example/repo.git", nil], @git_set.repositories["a"]
+ assert_equal ["git://example/repo.git", nil], @git_set.repositories["b"]
end
def test_git_source
@@ -618,9 +621,9 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
"git://example/#{repo_name}.git"
end
- @gda.gem "a", :example => "repo"
+ @gda.gem "a", example: "repo"
- assert_equal %w[git://example/repo.git master], @git_set.repositories["a"]
+ assert_equal ["git://example/repo.git", nil], @git_set.repositories["a"]
end
def test_group
@@ -642,7 +645,7 @@ end
GEM_DEPS
io.flush
- gda = @GDA.new @set, io.path
+ gda = Gem::RequestSet::GemDependencyAPI.new @set, io.path
assert_equal gda, gda.load
@@ -653,7 +656,7 @@ end
end
def test_pin_gem_source
- gda = @GDA.new @set, nil
+ gda = Gem::RequestSet::GemDependencyAPI.new @set, nil
gda.send :pin_gem_source, "a"
gda.send :pin_gem_source, "a"
@@ -674,7 +677,7 @@ end
end
def test_platform_mswin
- if win_platform?
+ if Gem.win_platform?
util_set_arch "x86-mswin32-60" do
@gda.platform :mswin do
@gda.gem "a"
@@ -695,9 +698,10 @@ end
end
def test_platform_multiple
- win_platform, Gem.win_platform = Gem.win_platform?, false
+ win_platform = Gem.win_platform?
+ Gem.win_platform = false
- gda = @GDA.new @set, nil
+ gda = Gem::RequestSet::GemDependencyAPI.new @set, nil
with_engine_version "ruby", "1.8.7" do
gda.platform :mri_19, :mri_20 do
@@ -707,7 +711,7 @@ end
assert_empty @set.dependencies
- gda = @GDA.new @set, nil
+ gda = Gem::RequestSet::GemDependencyAPI.new @set, nil
with_engine_version "ruby", "2.0.0" do
gda.platform :mri_19, :mri_20 do
@@ -721,7 +725,8 @@ end
end
def test_platform_ruby
- win_platform, Gem.win_platform = Gem.win_platform?, false
+ win_platform = Gem.win_platform?
+ Gem.win_platform = false
@gda.platform :ruby do
@gda.gem "a"
@@ -733,7 +738,7 @@ end
end
def test_platforms
- unless win_platform?
+ unless Gem.win_platform?
util_set_arch "i686-darwin8.10.1" do
@gda.platforms :ruby do
@gda.gem "a"
@@ -757,19 +762,19 @@ end
def test_ruby_engine
with_engine_version "jruby", "1.7.6" do
assert @gda.ruby RUBY_VERSION,
- :engine => "jruby", :engine_version => "1.7.6"
+ engine: "jruby", engine_version: "1.7.6"
end
with_engine_version "truffleruby", "1.0.0-rc11" do
assert @gda.ruby RUBY_VERSION,
- :engine => "truffleruby", :engine_version => "1.0.0-rc11"
+ engine: "truffleruby", engine_version: "1.0.0-rc11"
end
end
def test_ruby_engine_mismatch_engine
with_engine_version "ruby", "2.0.0" do
e = assert_raise Gem::RubyVersionMismatch do
- @gda.ruby RUBY_VERSION, :engine => "jruby", :engine_version => "1.7.4"
+ @gda.ruby RUBY_VERSION, engine: "jruby", engine_version: "1.7.4"
end
assert_equal "Your Ruby engine is ruby, but your gem.deps.rb requires jruby",
@@ -780,7 +785,7 @@ end
def test_ruby_engine_mismatch_version
with_engine_version "jruby", "1.7.6" do
e = assert_raise Gem::RubyVersionMismatch do
- @gda.ruby RUBY_VERSION, :engine => "jruby", :engine_version => "1.7.4"
+ @gda.ruby RUBY_VERSION, engine: "jruby", engine_version: "1.7.4"
end
assert_equal "Your Ruby engine version is jruby 1.7.6, but your gem.deps.rb requires jruby 1.7.4",
@@ -790,7 +795,7 @@ end
def test_ruby_engine_no_engine_version
e = assert_raise ArgumentError do
- @gda.ruby RUBY_VERSION, :engine => "jruby"
+ @gda.ruby RUBY_VERSION, engine: "jruby"
end
assert_equal "You must specify engine_version along with the Ruby engine",
diff --git a/test/rubygems/test_gem_request_set_lockfile.rb b/test/rubygems/test_gem_request_set_lockfile.rb
index 30dcbbbfdc..83f5002508 100644
--- a/test/rubygems/test_gem_request_set_lockfile.rb
+++ b/test/rubygems/test_gem_request_set_lockfile.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/request_set"
require "rubygems/request_set/lockfile"
diff --git a/test/rubygems/test_gem_request_set_lockfile_parser.rb b/test/rubygems/test_gem_request_set_lockfile_parser.rb
index 757c764dc1..253a59b243 100644
--- a/test/rubygems/test_gem_request_set_lockfile_parser.rb
+++ b/test/rubygems/test_gem_request_set_lockfile_parser.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/request_set"
require "rubygems/request_set/lockfile"
@@ -93,7 +94,7 @@ DEPENDENCIES
assert lockfile_set, "could not find a LockSet"
- assert_equal %w[a-2], lockfile_set.specs.map {|tuple| tuple.full_name }
+ assert_equal %w[a-2], lockfile_set.specs.map(&:full_name)
end
def test_parse_dependencies
@@ -123,7 +124,7 @@ DEPENDENCIES
assert lockfile_set, "could not find a LockSet"
- assert_equal %w[a-2], lockfile_set.specs.map {|tuple| tuple.full_name }
+ assert_equal %w[a-2], lockfile_set.specs.map(&:full_name)
end
def test_parse_DEPENDENCIES_git
@@ -217,7 +218,7 @@ DEPENDENCIES
assert lockfile_set, "found a LockSet"
- assert_equal %w[a-2], lockfile_set.specs.map {|s| s.full_name }
+ assert_equal %w[a-2], lockfile_set.specs.map(&:full_name)
end
def test_parse_GEM_remote_multiple
@@ -245,7 +246,7 @@ DEPENDENCIES
assert lockfile_set, "found a LockSet"
- assert_equal %w[a-2], lockfile_set.specs.map {|s| s.full_name }
+ assert_equal %w[a-2], lockfile_set.specs.map(&:full_name)
assert_equal %w[https://gems.example/ https://other.example/],
lockfile_set.specs.flat_map {|s| s.sources.map {|src| src.uri.to_s } }
@@ -257,7 +258,7 @@ DEPENDENCIES
write_lockfile <<-LOCKFILE
GIT
remote: git://example/a.git
- revision: master
+ revision: abranch
specs:
a (2)
b (>= 3)
@@ -275,7 +276,7 @@ DEPENDENCIES
Gem::Resolver::LockSet === set
end
- refute lockfile_set, "fount a LockSet"
+ refute lockfile_set, "found a LockSet"
git_set = @set.sets.find do |set|
Gem::Resolver::GitSet === set
@@ -283,13 +284,13 @@ DEPENDENCIES
assert git_set, "could not find a GitSet"
- assert_equal %w[a-2], git_set.specs.values.map {|s| s.full_name }
+ assert_equal %w[a-2], git_set.specs.values.map(&:full_name)
assert_equal [dep("b", ">= 3"), dep("c")],
git_set.specs.values.first.dependencies
expected = {
- "a" => %w[git://example/a.git master],
+ "a" => %w[git://example/a.git abranch],
}
assert_equal expected, git_set.repositories
@@ -318,7 +319,7 @@ DEPENDENCIES
Gem::Resolver::LockSet === set
end
- refute lockfile_set, "fount a LockSet"
+ refute lockfile_set, "found a LockSet"
git_set = @set.sets.find do |set|
Gem::Resolver::GitSet === set
@@ -355,7 +356,7 @@ DEPENDENCIES
Gem::Resolver::LockSet === set
end
- refute lockfile_set, "fount a LockSet"
+ refute lockfile_set, "found a LockSet"
git_set = @set.sets.find do |set|
Gem::Resolver::GitSet === set
@@ -392,7 +393,7 @@ DEPENDENCIES
Gem::Resolver::LockSet === set
end
- refute lockfile_set, "fount a LockSet"
+ refute lockfile_set, "found a LockSet"
git_set = @set.sets.find do |set|
Gem::Resolver::GitSet === set
@@ -437,7 +438,7 @@ DEPENDENCIES
assert vendor_set, "could not find a VendorSet"
- assert_equal %w[a-1], vendor_set.specs.values.map {|s| s.full_name }
+ assert_equal %w[a-1], vendor_set.specs.values.map(&:full_name)
spec = vendor_set.load_spec "a", nil, nil, nil
@@ -496,14 +497,14 @@ DEPENDENCIES
assert lockfile_set, "could not find a LockSet"
- assert_equal %w[a-2 b-3], lockfile_set.specs.map {|tuple| tuple.full_name }
+ assert_equal %w[a-2 b-3], lockfile_set.specs.map(&:full_name)
expected = [
Gem::Platform::RUBY,
Gem::Platform.new("x86_64-linux"),
]
- assert_equal expected, lockfile_set.specs.map {|tuple| tuple.platform }
+ assert_equal expected, lockfile_set.specs.map(&:platform)
spec = lockfile_set.specs.first
diff --git a/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb b/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb
index 8db180eb27..dce8c9ada5 100644
--- a/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb
+++ b/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/request_set"
require "rubygems/request_set/lockfile"
diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb
index 29bb264454..de0d11ec00 100644
--- a/test/rubygems/test_gem_requirement.rb
+++ b/test/rubygems/test_gem_requirement.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/requirement"
@@ -11,6 +12,14 @@ class TestGemRequirement < Gem::TestCase
assert_equal [[">=", v(1)], ["<", v(2)]], r.requirements
end
+ def test_initialize_copy
+ r = req("= 1.2")
+ r2 = r.dup
+
+ assert_equal r.requirements, r2.requirements
+ refute_same r.requirements, r2.requirements
+ end
+
def test_equals2
r = req "= 1.2"
assert_equal r, r.dup
@@ -83,7 +92,7 @@ class TestGemRequirement < Gem::TestCase
Gem::Requirement.parse(Gem::Version.new("2"))
end
- if RUBY_VERSION >= "2.5" && !(Gem.java_platform? && ENV["JRUBY_OPTS"].to_s.include?("--debug"))
+ unless Gem.java_platform? && ENV["JRUBY_OPTS"].to_s.include?("--debug")
def test_parse_deduplication
assert_same "~>", Gem::Requirement.parse("~> 1").first
end
@@ -286,7 +295,7 @@ class TestGemRequirement < Gem::TestCase
end
def test_illformed_requirements
- [ ">>> 1.3.5", "> blah" ].each do |rq|
+ [">>> 1.3.5", "> blah"].each do |rq|
assert_raise Gem::Requirement::BadRequirementError, "req [#{rq}] should fail" do
Gem::Requirement.new rq
end
@@ -436,19 +445,19 @@ class TestGemRequirement < Gem::TestCase
end
def test_marshal_load_attack
- wa = Net::WriteAdapter.allocate
+ wa = Gem::Net::WriteAdapter.allocate
wa.instance_variable_set(:@socket, self.class)
wa.instance_variable_set(:@method_id, :exploit)
request_set = Gem::RequestSet.allocate
request_set.instance_variable_set(:@git_set, "id")
request_set.instance_variable_set(:@sets, wa)
- wa = Net::WriteAdapter.allocate
+ wa = Gem::Net::WriteAdapter.allocate
wa.instance_variable_set(:@socket, request_set)
wa.instance_variable_set(:@method_id, :resolve)
ent = Gem::Package::TarReader::Entry.allocate
ent.instance_variable_set(:@read, 0)
ent.instance_variable_set(:@header, "aaa")
- io = Net::BufferedIO.allocate
+ io = Gem::Net::BufferedIO.allocate
io.instance_variable_set(:@io, ent)
io.instance_variable_set(:@debug_output, wa)
reader = Gem::Package::TarReader.allocate
diff --git a/test/rubygems/test_gem_resolver.rb b/test/rubygems/test_gem_resolver.rb
index 2271244729..b7dadda708 100644
--- a/test/rubygems/test_gem_resolver.rb
+++ b/test/rubygems/test_gem_resolver.rb
@@ -1,19 +1,14 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolver < Gem::TestCase
- def setup
- super
-
- @DR = Gem::Resolver
- end
-
def make_dep(name, *req)
Gem::Dependency.new(name, *req)
end
def set(*specs)
- source = Gem::Source.new URI @gem_repo
+ source = Gem::Source.new Gem::URI @gem_repo
specs = specs.map do |spec|
Gem::Resolver::SpecSpecification.new nil, spec, source
@@ -25,10 +20,10 @@ class TestGemResolver < Gem::TestCase
def assert_resolves_to(expected, resolver)
actual = resolver.resolve
- exp = expected.sort_by {|s| s.full_name }
- act = actual.map {|a| a.spec.spec }.sort_by {|s| s.full_name }
+ exp = expected.sort_by(&:full_name)
+ act = actual.map {|a| a.spec.spec }.sort_by(&:full_name)
- msg = "Set of gems was not the same: #{exp.map {|x| x.full_name }.inspect} != #{act.map {|x| x.full_name }.inspect}"
+ msg = "Set of gems was not the same: #{exp.map(&:full_name).inspect} != #{act.map(&:full_name).inspect}"
assert_equal exp, act, msg
rescue Gem::DependencyResolutionError => e
@@ -36,18 +31,18 @@ class TestGemResolver < Gem::TestCase
end
def test_self_compose_sets_best_set
- best_set = @DR::BestSet.new
+ best_set = Gem::Resolver::BestSet.new
- composed = @DR.compose_sets best_set
+ composed = Gem::Resolver.compose_sets best_set
assert_equal best_set, composed
end
def test_self_compose_sets_multiple
- index_set = @DR::IndexSet.new
- vendor_set = @DR::VendorSet.new
+ index_set = Gem::Resolver::IndexSet.new
+ vendor_set = Gem::Resolver::VendorSet.new
- composed = @DR.compose_sets index_set, vendor_set
+ composed = Gem::Resolver.compose_sets index_set, vendor_set
assert_kind_of Gem::Resolver::ComposedSet, composed
@@ -55,14 +50,14 @@ class TestGemResolver < Gem::TestCase
end
def test_self_compose_sets_nest
- index_set = @DR::IndexSet.new
- vendor_set = @DR::VendorSet.new
+ index_set = Gem::Resolver::IndexSet.new
+ vendor_set = Gem::Resolver::VendorSet.new
- inner = @DR.compose_sets index_set, vendor_set
+ inner = Gem::Resolver.compose_sets index_set, vendor_set
- current_set = @DR::CurrentSet.new
+ current_set = Gem::Resolver::CurrentSet.new
- composed = @DR.compose_sets inner, current_set
+ composed = Gem::Resolver.compose_sets inner, current_set
assert_kind_of Gem::Resolver::ComposedSet, composed
@@ -70,23 +65,23 @@ class TestGemResolver < Gem::TestCase
end
def test_self_compose_sets_nil
- index_set = @DR::IndexSet.new
+ index_set = Gem::Resolver::IndexSet.new
- composed = @DR.compose_sets index_set, nil
+ composed = Gem::Resolver.compose_sets index_set, nil
assert_same index_set, composed
e = assert_raise ArgumentError do
- @DR.compose_sets nil
+ Gem::Resolver.compose_sets nil
end
assert_equal "one set in the composition must be non-nil", e.message
end
def test_self_compose_sets_single
- index_set = @DR::IndexSet.new
+ index_set = Gem::Resolver::IndexSet.new
- composed = @DR.compose_sets index_set
+ composed = Gem::Resolver.compose_sets index_set
assert_same index_set, composed
end
@@ -104,7 +99,7 @@ class TestGemResolver < Gem::TestCase
res.requests a1, act, reqs
- assert_equal ["b (= 2)"], reqs.map {|req| req.to_s }
+ assert_equal ["b (= 2)"], reqs.map(&:to_s)
end
def test_requests_development
@@ -126,7 +121,7 @@ class TestGemResolver < Gem::TestCase
res.requests spec, act, reqs
- assert_equal ["b (= 2)"], reqs.map {|req| req.to_s }
+ assert_equal ["b (= 2)"], reqs.map(&:to_s)
assert spec.instance_variable_defined? :@called
end
@@ -207,8 +202,8 @@ class TestGemResolver < Gem::TestCase
s.add_development_dependency "b"
end
- b_spec = util_spec "b", 1 do
- |s| s.add_development_dependency "c"
+ b_spec = util_spec "b", 1 do |s|
+ s.add_development_dependency "c"
end
c_spec = util_spec "c", 1
@@ -322,16 +317,15 @@ class TestGemResolver < Gem::TestCase
def test_picks_best_platform
is = Gem::Resolver::IndexSpecification
unknown = Gem::Platform.new "unknown"
- a2_p1 = a3_p2 = nil
spec_fetcher do |fetcher|
fetcher.spec "a", 2
- a2_p1 = fetcher.spec "a", 2 do |s|
+ fetcher.spec "a", 2 do |s|
s.platform = Gem::Platform.local
end
- a3_p2 = fetcher.spec "a", 3 do |s|
+ fetcher.spec "a", 3 do |s|
s.platform = unknown
end
end
@@ -357,6 +351,74 @@ class TestGemResolver < Gem::TestCase
assert_resolves_to [a2_p1.spec], res
end
+ def test_does_not_pick_musl_variants_on_non_musl_linux
+ util_set_arch "aarch64-linux" do
+ is = Gem::Resolver::IndexSpecification
+
+ linux_musl = Gem::Platform.new("aarch64-linux-musl")
+
+ spec_fetcher do |fetcher|
+ fetcher.spec "libv8-node", "15.14.0.1" do |s|
+ s.platform = Gem::Platform.local
+ end
+
+ fetcher.spec "libv8-node", "15.14.0.1" do |s|
+ s.platform = linux_musl
+ end
+ end
+
+ v15 = v("15.14.0.1")
+ source = Gem::Source.new @gem_repo
+
+ s = set
+
+ v15_linux = is.new s, "libv8-node", v15, source, Gem::Platform.local.to_s
+ v15_linux_musl = is.new s, "libv8-node", v15, source, linux_musl.to_s
+
+ s.add v15_linux
+ s.add v15_linux_musl
+
+ ad = make_dep "libv8-node", "= 15.14.0.1"
+
+ res = Gem::Resolver.new([ad], s)
+
+ assert_resolves_to [v15_linux.spec], res
+ end
+ end
+
+ def test_pick_generic_linux_variants_on_musl_linux
+ util_set_arch "aarch64-linux-musl" do
+ is = Gem::Resolver::IndexSpecification
+
+ linux = Gem::Platform.new("aarch64-linux")
+
+ spec_fetcher do |fetcher|
+ fetcher.spec "libv8-node", "15.14.0.1" do |s|
+ s.platform = linux
+ end
+
+ fetcher.spec "libv8-node", "15.14.0.1"
+ end
+
+ v15 = v("15.14.0.1")
+ source = Gem::Source.new @gem_repo
+
+ s = set
+
+ v15_ruby = is.new s, "libv8-node", v15, source, Gem::Platform::RUBY
+ v15_linux = is.new s, "libv8-node", v15, source, linux.to_s
+
+ s.add v15_linux
+ s.add v15_ruby
+
+ ad = make_dep "libv8-node", "= 15.14.0.1"
+
+ res = Gem::Resolver.new([ad], s)
+
+ assert_resolves_to [v15_linux.spec], res
+ end
+ end
+
def test_only_returns_spec_once
a1 = util_spec "a", "1", "c" => "= 1"
b1 = util_spec "b", "1", "c" => "= 1"
@@ -711,29 +773,29 @@ class TestGemResolver < Gem::TestCase
end
def test_sorts_by_source_then_version
- sourceA = Gem::Source.new "http://example.com/a"
- sourceB = Gem::Source.new "http://example.com/b"
- sourceC = Gem::Source.new "http://example.com/c"
+ source_a = Gem::Source.new "http://example.com/a"
+ source_b = Gem::Source.new "http://example.com/b"
+ source_c = Gem::Source.new "http://example.com/c"
- spec_A_1 = util_spec "some-dep", "0.0.1"
- spec_A_2 = util_spec "some-dep", "1.0.0"
- spec_B_1 = util_spec "some-dep", "0.0.1"
- spec_B_2 = util_spec "some-dep", "0.0.2"
- spec_C_1 = util_spec "some-dep", "0.1.0"
+ spec_a_1 = util_spec "some-dep", "0.0.1"
+ spec_a_2 = util_spec "some-dep", "1.0.0"
+ spec_b_1 = util_spec "some-dep", "0.0.1"
+ spec_b_2 = util_spec "some-dep", "0.0.2"
+ spec_c_1 = util_spec "some-dep", "0.1.0"
set = StaticSet.new [
- Gem::Resolver::SpecSpecification.new(nil, spec_B_1, sourceB),
- Gem::Resolver::SpecSpecification.new(nil, spec_B_2, sourceB),
- Gem::Resolver::SpecSpecification.new(nil, spec_C_1, sourceC),
- Gem::Resolver::SpecSpecification.new(nil, spec_A_2, sourceA),
- Gem::Resolver::SpecSpecification.new(nil, spec_A_1, sourceA),
+ Gem::Resolver::SpecSpecification.new(nil, spec_b_1, source_b),
+ Gem::Resolver::SpecSpecification.new(nil, spec_b_2, source_b),
+ Gem::Resolver::SpecSpecification.new(nil, spec_c_1, source_c),
+ Gem::Resolver::SpecSpecification.new(nil, spec_a_2, source_a),
+ Gem::Resolver::SpecSpecification.new(nil, spec_a_1, source_a),
]
dependency = make_dep "some-dep", "> 0"
resolver = Gem::Resolver.new [dependency], set
- assert_resolves_to [spec_B_2], resolver
+ assert_resolves_to [spec_b_2], resolver
end
def test_select_local_platforms
diff --git a/test/rubygems/test_gem_resolver_activation_request.rb b/test/rubygems/test_gem_resolver_activation_request.rb
index 397eb1e10d..53875b72cb 100644
--- a/test/rubygems/test_gem_resolver_activation_request.rb
+++ b/test/rubygems/test_gem_resolver_activation_request.rb
@@ -1,28 +1,27 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverActivationRequest < Gem::TestCase
def setup
super
- @DR = Gem::Resolver
-
- @dep = @DR::DependencyRequest.new dep("a", ">= 0"), nil
+ @dep = Gem::Resolver::DependencyRequest.new dep("a", ">= 0"), nil
source = Gem::Source::Local.new
platform = Gem::Platform::RUBY
- @a3 = @DR::IndexSpecification.new nil, "a", v(3), source, platform
+ @a3 = Gem::Resolver::IndexSpecification.new nil, "a", v(3), source, platform
- @req = @DR::ActivationRequest.new @a3, @dep
+ @req = Gem::Resolver::ActivationRequest.new @a3, @dep
end
def test_development_eh
refute @req.development?
- dep_req = @DR::DependencyRequest.new dep("a", ">= 0", :development), nil
+ dep_req = Gem::Resolver::DependencyRequest.new dep("a", ">= 0", :development), nil
- act_req = @DR::ActivationRequest.new @a3, dep_req
+ act_req = Gem::Resolver::ActivationRequest.new @a3, dep_req
assert act_req.development?
end
@@ -35,7 +34,7 @@ class TestGemResolverActivationRequest < Gem::TestCase
def test_installed_eh
v_spec = Gem::Resolver::VendorSpecification.new nil, @a3
- @req = @DR::ActivationRequest.new v_spec, @dep
+ @req = Gem::Resolver::ActivationRequest.new v_spec, @dep
assert @req.installed?
end
diff --git a/test/rubygems/test_gem_resolver_api_set.rb b/test/rubygems/test_gem_resolver_api_set.rb
index 5c13311b1b..5781cf37d2 100644
--- a/test/rubygems/test_gem_resolver_api_set.rb
+++ b/test/rubygems/test_gem_resolver_api_set.rb
@@ -1,55 +1,55 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverAPISet < Gem::TestCase
def setup
super
- @DR = Gem::Resolver
- @dep_uri = URI "#{@gem_repo}info/"
+ @dep_uri = Gem::URI "#{@gem_repo}info/"
end
def test_initialize
- set = @DR::APISet.new
+ set = Gem::Resolver::APISet.new
- assert_equal URI("https://index.rubygems.org/info/"), set.dep_uri
- assert_equal URI("https://index.rubygems.org/"), set.uri
- assert_equal Gem::Source.new(URI("https://index.rubygems.org")), set.source
+ assert_equal Gem::URI("https://index.rubygems.org/info/"), set.dep_uri
+ assert_equal Gem::URI("https://index.rubygems.org/"), set.uri
+ assert_equal Gem::Source.new(Gem::URI("https://index.rubygems.org")), set.source
end
def test_initialize_deeper_uri
- set = @DR::APISet.new "https://rubygemsserver.com/mygems/info"
+ set = Gem::Resolver::APISet.new "https://rubygemsserver.com/mygems/info"
- assert_equal URI("https://rubygemsserver.com/mygems/info"), set.dep_uri
- assert_equal URI("https://rubygemsserver.com/"), set.uri
- assert_equal Gem::Source.new(URI("https://rubygemsserver.com/")), set.source
+ assert_equal Gem::URI("https://rubygemsserver.com/mygems/info"), set.dep_uri
+ assert_equal Gem::URI("https://rubygemsserver.com/"), set.uri
+ assert_equal Gem::Source.new(Gem::URI("https://rubygemsserver.com/")), set.source
end
def test_initialize_uri
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
- assert_equal URI("#{@gem_repo}info/"), set.dep_uri
- assert_equal URI("#{@gem_repo}"), set.uri
+ assert_equal Gem::URI("#{@gem_repo}info/"), set.dep_uri
+ assert_equal Gem::URI(@gem_repo.to_s), set.uri
end
def test_find_all
spec_fetcher
data = [
- { :name => "a",
- :number => "1",
- :platform => "ruby",
- :dependencies => [] },
+ { name: "a",
+ number: "1",
+ platform: "ruby",
+ dependencies: [] },
]
@fetcher.data["#{@dep_uri}a"] = "---\n1 "
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
- a_dep = @DR::DependencyRequest.new dep("a"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
expected = [
- @DR::APISpecification.new(set, data.first),
+ Gem::Resolver::APISpecification.new(set, data.first),
]
assert_equal expected, set.find_all(a_dep)
@@ -59,26 +59,26 @@ class TestGemResolverAPISet < Gem::TestCase
spec_fetcher
data = [
- { :name => "a",
- :number => "1",
- :platform => "ruby",
- :dependencies => [] },
- { :name => "a",
- :number => "2.a",
- :platform => "ruby",
- :dependencies => [] },
+ { name: "a",
+ number: "1",
+ platform: "ruby",
+ dependencies: [] },
+ { name: "a",
+ number: "2.a",
+ platform: "ruby",
+ dependencies: [] },
]
@fetcher.data["#{@dep_uri}a"] = "---\n1\n2.a"
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
set.prerelease = true
- a_dep = @DR::DependencyRequest.new dep("a"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
expected = [
- @DR::APISpecification.new(set, data.first),
- @DR::APISpecification.new(set, data.last),
+ Gem::Resolver::APISpecification.new(set, data.first),
+ Gem::Resolver::APISpecification.new(set, data.last),
]
assert_equal expected, set.find_all(a_dep)
@@ -88,22 +88,22 @@ class TestGemResolverAPISet < Gem::TestCase
spec_fetcher
data = [
- { :name => "a",
- :number => "1",
- :platform => "ruby",
- :dependencies => [] },
+ { name: "a",
+ number: "1",
+ platform: "ruby",
+ dependencies: [] },
]
@fetcher.data["#{@dep_uri}a"] = "---\n1 "
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
- a_dep = @DR::DependencyRequest.new dep("a"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
set.prefetch [a_dep]
expected = [
- @DR::APISpecification.new(set, data.first),
+ Gem::Resolver::APISpecification.new(set, data.first),
]
assert_equal expected, set.find_all(a_dep)
@@ -112,10 +112,10 @@ class TestGemResolverAPISet < Gem::TestCase
end
def test_find_all_local
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
set.remote = false
- a_dep = @DR::DependencyRequest.new dep("a"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
assert_empty set.find_all(a_dep)
end
@@ -125,9 +125,9 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---"
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
- a_dep = @DR::DependencyRequest.new dep("a"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
assert_empty set.find_all(a_dep)
@@ -142,14 +142,14 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---\n1 \n"
@fetcher.data["#{@dep_uri}b"] = "---"
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
- a_dep = @DR::DependencyRequest.new dep("a"), nil
- b_dep = @DR::DependencyRequest.new dep("b"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil
set.prefetch [a_dep, b_dep]
- assert_equal %w[a-1], set.find_all(a_dep).map {|s| s.full_name }
+ assert_equal %w[a-1], set.find_all(a_dep).map(&:full_name)
assert_empty set.find_all(b_dep)
end
@@ -158,10 +158,10 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---\n1 \n"
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
- a_dep = @DR::DependencyRequest.new dep("a"), nil
- b_dep = @DR::DependencyRequest.new dep("b"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil
set.prefetch [a_dep]
@@ -177,10 +177,10 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---\n1 \n"
@fetcher.data["#{@dep_uri}b"] = "---"
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
- a_dep = @DR::DependencyRequest.new dep("a"), nil
- b_dep = @DR::DependencyRequest.new dep("b"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil
set.prefetch [a_dep, b_dep]
@@ -196,11 +196,11 @@ class TestGemResolverAPISet < Gem::TestCase
@fetcher.data["#{@dep_uri}a"] = "---\n1 \n"
@fetcher.data["#{@dep_uri}b"] = "---"
- set = @DR::APISet.new @dep_uri
+ set = Gem::Resolver::APISet.new @dep_uri
set.remote = false
- a_dep = @DR::DependencyRequest.new dep("a"), nil
- b_dep = @DR::DependencyRequest.new dep("b"), nil
+ a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil
+ b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil
set.prefetch [a_dep, b_dep]
diff --git a/test/rubygems/test_gem_resolver_api_specification.rb b/test/rubygems/test_gem_resolver_api_specification.rb
index 98981e53e9..2119d73478 100644
--- a/test/rubygems/test_gem_resolver_api_specification.rb
+++ b/test/rubygems/test_gem_resolver_api_specification.rb
@@ -1,14 +1,15 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverAPISpecification < Gem::TestCase
def test_initialize
set = Gem::Resolver::APISet.new
data = {
- :name => "rails",
- :number => "3.0.3",
- :platform => Gem::Platform.local.to_s,
- :dependencies => [
+ name: "rails",
+ number: "3.0.3",
+ platform: Gem::Platform.local.to_s,
+ dependencies: [
["bundler", "~> 1.0"],
["railties", "= 3.0.3"],
],
@@ -44,10 +45,10 @@ class TestGemResolverAPISpecification < Gem::TestCase
set = Gem::Resolver::APISet.new repo
data = {
- :name => "rails",
- :number => "3.0.3",
- :platform => "ruby",
- :dependencies => [
+ name: "rails",
+ number: "3.0.3",
+ platform: "ruby",
+ dependencies: [
["bundler", "~> 1.0"],
["railties", "= 3.0.3"],
],
@@ -71,10 +72,10 @@ class TestGemResolverAPISpecification < Gem::TestCase
def test_installable_platform_eh
set = Gem::Resolver::APISet.new
data = {
- :name => "a",
- :number => "1",
- :platform => "ruby",
- :dependencies => [],
+ name: "a",
+ number: "1",
+ platform: "ruby",
+ dependencies: [],
}
a_spec = Gem::Resolver::APISpecification.new set, data
@@ -82,10 +83,10 @@ class TestGemResolverAPISpecification < Gem::TestCase
assert a_spec.installable_platform?
data = {
- :name => "b",
- :number => "1",
- :platform => "cpu-other_platform-1",
- :dependencies => [],
+ name: "b",
+ number: "1",
+ platform: "cpu-other_platform-1",
+ dependencies: [],
}
b_spec = Gem::Resolver::APISpecification.new set, data
@@ -93,10 +94,10 @@ class TestGemResolverAPISpecification < Gem::TestCase
refute b_spec.installable_platform?
data = {
- :name => "c",
- :number => "1",
- :platform => Gem::Platform.local.to_s,
- :dependencies => [],
+ name: "c",
+ number: "1",
+ platform: Gem::Platform.local.to_s,
+ dependencies: [],
}
c_spec = Gem::Resolver::APISpecification.new set, data
@@ -107,10 +108,10 @@ class TestGemResolverAPISpecification < Gem::TestCase
def test_source
set = Gem::Resolver::APISet.new
data = {
- :name => "a",
- :number => "1",
- :platform => "ruby",
- :dependencies => [],
+ name: "a",
+ number: "1",
+ platform: "ruby",
+ dependencies: [],
}
api_spec = Gem::Resolver::APISpecification.new set, data
@@ -123,13 +124,13 @@ class TestGemResolverAPISpecification < Gem::TestCase
fetcher.spec "a", 1
end
- dep_uri = URI(@gem_repo) + "info"
+ dep_uri = Gem::URI(@gem_repo) + "info"
set = Gem::Resolver::APISet.new dep_uri
data = {
- :name => "a",
- :number => "1",
- :platform => "ruby",
- :dependencies => [],
+ name: "a",
+ number: "1",
+ platform: "ruby",
+ dependencies: [],
}
api_spec = Gem::Resolver::APISpecification.new set, data
@@ -147,13 +148,13 @@ class TestGemResolverAPISpecification < Gem::TestCase
end
end
- dep_uri = URI(@gem_repo) + "info"
+ dep_uri = Gem::URI(@gem_repo) + "info"
set = Gem::Resolver::APISet.new dep_uri
data = {
- :name => "j",
- :number => "1",
- :platform => "jruby",
- :dependencies => [],
+ name: "j",
+ number: "1",
+ platform: "jruby",
+ dependencies: [],
}
api_spec = Gem::Resolver::APISpecification.new set, data
diff --git a/test/rubygems/test_gem_resolver_best_set.rb b/test/rubygems/test_gem_resolver_best_set.rb
index c1c67ba832..8a750cdf8f 100644
--- a/test/rubygems/test_gem_resolver_best_set.rb
+++ b/test/rubygems/test_gem_resolver_best_set.rb
@@ -1,15 +1,10 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverBestSet < Gem::TestCase
- def setup
- super
-
- @DR = Gem::Resolver
- end
-
def test_initialize
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
assert_empty set.sets
end
@@ -21,15 +16,15 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "b", 1
end
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
dependency = dep "a", "~> 1"
- req = @DR::DependencyRequest.new dependency, nil
+ req = Gem::Resolver::DependencyRequest.new dependency, nil
found = set.find_all req
- assert_equal %w[a-1], found.map {|s| s.full_name }
+ assert_equal %w[a-1], found.map(&:full_name)
end
def test_find_all_fallback
@@ -37,19 +32,19 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "a", 1
end
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
- api_uri = URI(@gem_repo)
+ api_uri = Gem::URI(@gem_repo)
set.sets << Gem::Resolver::APISet.new(api_uri)
dependency = dep "a", "~> 1"
- req = @DR::DependencyRequest.new dependency, nil
+ req = Gem::Resolver::DependencyRequest.new dependency, nil
found = set.find_all req
- assert_equal %w[a-1], found.map {|s| s.full_name }
+ assert_equal %w[a-1], found.map(&:full_name)
end
def test_find_all_local
@@ -59,12 +54,12 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "b", 1
end
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
set.remote = false
dependency = dep "a", "~> 1"
- req = @DR::DependencyRequest.new dependency, nil
+ req = Gem::Resolver::DependencyRequest.new dependency, nil
found = set.find_all req
@@ -76,7 +71,7 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "a", 1
end
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
set.prefetch []
@@ -88,7 +83,7 @@ class TestGemResolverBestSet < Gem::TestCase
fetcher.spec "a", 1
end
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
set.remote = false
set.prefetch []
@@ -97,9 +92,9 @@ class TestGemResolverBestSet < Gem::TestCase
end
def test_replace_failed_api_set
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
- api_uri = URI(@gem_repo) + "./info/"
+ api_uri = Gem::URI(@gem_repo) + "./info/"
api_set = Gem::Resolver::APISet.new api_uri
set.sets << api_set
@@ -118,7 +113,7 @@ class TestGemResolverBestSet < Gem::TestCase
end
def test_replace_failed_api_set_no_api_set
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
index_set = Gem::Resolver::IndexSet.new Gem::Source.new @gem_repo
@@ -134,9 +129,9 @@ class TestGemResolverBestSet < Gem::TestCase
end
def test_replace_failed_api_set_uri_with_credentials
- set = @DR::BestSet.new
+ set = Gem::Resolver::BestSet.new
- api_uri = URI(@gem_repo) + "./info/"
+ api_uri = Gem::URI(@gem_repo) + "./info/"
api_uri.user = "user"
api_uri.password = "pass"
api_set = Gem::Resolver::APISet.new api_uri
diff --git a/test/rubygems/test_gem_resolver_composed_set.rb b/test/rubygems/test_gem_resolver_composed_set.rb
index 5feceebb34..5a53000ec7 100644
--- a/test/rubygems/test_gem_resolver_composed_set.rb
+++ b/test/rubygems/test_gem_resolver_composed_set.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverComposedSet < Gem::TestCase
diff --git a/test/rubygems/test_gem_resolver_conflict.rb b/test/rubygems/test_gem_resolver_conflict.rb
index 8bee6699c8..5696ff266d 100644
--- a/test/rubygems/test_gem_resolver_conflict.rb
+++ b/test/rubygems/test_gem_resolver_conflict.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverConflict < Gem::TestCase
@@ -35,16 +36,14 @@ class TestGemResolverConflict < Gem::TestCase
end
def test_explanation_user_request
- @DR = Gem::Resolver
-
spec = util_spec "a", 2
- a1_req = @DR::DependencyRequest.new dep("a", "= 1"), nil
- a2_req = @DR::DependencyRequest.new dep("a", "= 2"), nil
+ a1_req = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil
+ a2_req = Gem::Resolver::DependencyRequest.new dep("a", "= 2"), nil
- activated = @DR::ActivationRequest.new spec, a2_req
+ activated = Gem::Resolver::ActivationRequest.new spec, a2_req
- conflict = @DR::Conflict.new a1_req, activated
+ conflict = Gem::Resolver::Conflict.new a1_req, activated
expected = <<-EXPECTED
Activated a-2
diff --git a/test/rubygems/test_gem_resolver_dependency_request.rb b/test/rubygems/test_gem_resolver_dependency_request.rb
index 6ad3a09028..3e14771da8 100644
--- a/test/rubygems/test_gem_resolver_dependency_request.rb
+++ b/test/rubygems/test_gem_resolver_dependency_request.rb
@@ -1,23 +1,18 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverDependencyRequest < Gem::TestCase
- def setup
- super
-
- @DR = Gem::Resolver::DependencyRequest
- end
-
def test_development_eh
a_dep = dep "a", ">= 1"
- a_dep_req = @DR.new a_dep, nil
+ a_dep_req = Gem::Resolver::DependencyRequest.new a_dep, nil
refute a_dep_req.development?
b_dep = dep "b", ">= 1", :development
- b_dep_req = @DR.new b_dep, nil
+ b_dep_req = Gem::Resolver::DependencyRequest.new b_dep, nil
assert b_dep_req.development?
end
@@ -26,7 +21,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", 1
dependency = dep "a", ">= 1"
- dr = @DR.new dependency, nil
+ dr = Gem::Resolver::DependencyRequest.new dependency, nil
assert dr.match? spec
end
@@ -35,12 +30,12 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", "1.a"
a_dep = dep "a", ">= 1"
- a_dr = @DR.new a_dep, nil
+ a_dr = Gem::Resolver::DependencyRequest.new a_dep, nil
refute a_dr.match? spec
a_pre_dep = dep "a", ">= 1.a"
- a_pre_dr = @DR.new a_pre_dep, nil
+ a_pre_dr = Gem::Resolver::DependencyRequest.new a_pre_dep, nil
assert a_pre_dr.match? spec
end
@@ -49,7 +44,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", "2.a"
a_dep = dep "a", ">= 1"
- a_dr = @DR.new a_dep, nil
+ a_dr = Gem::Resolver::DependencyRequest.new a_dep, nil
assert a_dr.match? spec, true
end
@@ -58,7 +53,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", 1
dependency = dep "a", ">= 1"
- dr = @DR.new dependency, nil
+ dr = Gem::Resolver::DependencyRequest.new dependency, nil
assert dr.matches_spec? spec
end
@@ -67,7 +62,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
spec = util_spec "a", "1.a"
dependency = dep "a", ">= 0"
- dr = @DR.new dependency, nil
+ dr = Gem::Resolver::DependencyRequest.new dependency, nil
assert dr.matches_spec? spec
end
@@ -75,7 +70,7 @@ class TestGemResolverDependencyRequest < Gem::TestCase
def test_requirement
dependency = dep "a", ">= 1"
- dr = @DR.new dependency, nil
+ dr = Gem::Resolver::DependencyRequest.new dependency, nil
assert_equal dependency, dr.dependency
end
diff --git a/test/rubygems/test_gem_resolver_git_set.rb b/test/rubygems/test_gem_resolver_git_set.rb
index f7063b3d45..90749d712c 100644
--- a/test/rubygems/test_gem_resolver_git_set.rb
+++ b/test/rubygems/test_gem_resolver_git_set.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverGitSet < Gem::TestCase
@@ -13,7 +14,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_add_git_gem
name, version, repository, = git_gem
- @set.add_git_gem name, repository, "master", false
+ @set.add_git_gem name, repository, nil, false
dependency = dep "a"
@@ -27,7 +28,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_add_git_gem_submodules
name, _, repository, = git_gem
- @set.add_git_gem name, repository, "master", true
+ @set.add_git_gem name, repository, nil, true
dependency = dep "a"
@@ -57,7 +58,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_find_all
name, _, repository, = git_gem
- @set.add_git_gem name, repository, "master", false
+ @set.add_git_gem name, repository, nil, false
dependency = dep "a", "~> 1.0"
req = Gem::Resolver::DependencyRequest.new dependency, nil
@@ -73,7 +74,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_find_all_local
name, _, repository, = git_gem
- @set.add_git_gem name, repository, "master", false
+ @set.add_git_gem name, repository, nil, false
@set.remote = false
dependency = dep "a", "~> 1.0"
@@ -88,7 +89,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_find_all_prerelease
name, _, repository, = git_gem "a", "1.a"
- @set.add_git_gem name, repository, "master", false
+ @set.add_git_gem name, repository, nil, false
dependency = dep "a", ">= 0"
req = Gem::Resolver::DependencyRequest.new dependency, nil
@@ -122,7 +123,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_prefetch
name, _, repository, = git_gem
- @set.add_git_gem name, repository, "master", false
+ @set.add_git_gem name, repository, nil, false
dependency = dep name
req = Gem::Resolver::DependencyRequest.new dependency, nil
@@ -136,7 +137,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_prefetch_cache
name, _, repository, = git_gem
- @set.add_git_gem name, repository, "master", false
+ @set.add_git_gem name, repository, nil, false
dependency = dep name
req = Gem::Resolver::DependencyRequest.new dependency, nil
@@ -154,7 +155,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_prefetch_filter
name, _, repository, = git_gem
- @set.add_git_gem name, repository, "master", false
+ @set.add_git_gem name, repository, nil, false
dependency = dep "b"
req = Gem::Resolver::DependencyRequest.new dependency, nil
@@ -168,7 +169,7 @@ class TestGemResolverGitSet < Gem::TestCase
def test_prefetch_root_dir
name, _, repository, = git_gem
- @set.add_git_gem name, repository, "master", false
+ @set.add_git_gem name, repository, nil, false
dependency = dep name
req = Gem::Resolver::DependencyRequest.new dependency, nil
diff --git a/test/rubygems/test_gem_resolver_git_specification.rb b/test/rubygems/test_gem_resolver_git_specification.rb
index 454fd9c6e4..621333d3bf 100644
--- a/test/rubygems/test_gem_resolver_git_specification.rb
+++ b/test/rubygems/test_gem_resolver_git_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/installer"
@@ -28,7 +29,8 @@ class TestGemResolverGitSpecification < Gem::TestCase
i_set = Gem::Resolver::IndexSet.new
source = Gem::Source.new @gem_repo
i_spec = Gem::Resolver::IndexSpecification.new(
- i_set, "a", v(1), source, Gem::Platform::RUBY)
+ i_set, "a", v(1), source, Gem::Platform::RUBY
+ )
refute_equal g_spec_a, i_spec
end
@@ -63,7 +65,7 @@ class TestGemResolverGitSpecification < Gem::TestCase
def test_install_extension
pend if Gem.java_platform?
- pend if RUBY_PLATFORM.include?("mswin") && ENV.key?("GITHUB_ACTIONS") # not working from the beginning
+ pend "terminates on mswin" if vc_windows? && ruby_repo?
name, _, repository, = git_gem "a", 1 do |s|
s.extensions << "ext/extconf.rb"
end
@@ -84,7 +86,7 @@ class TestGemResolverGitSpecification < Gem::TestCase
system @git, "commit", "--quiet", "-m", "Add extension files"
end
- source = Gem::Source::Git.new name, repository, "master", true
+ source = Gem::Source::Git.new name, repository, nil, true
spec = source.specs.first
diff --git a/test/rubygems/test_gem_resolver_index_set.rb b/test/rubygems/test_gem_resolver_index_set.rb
index 3b8f047808..8ff1acbf1e 100644
--- a/test/rubygems/test_gem_resolver_index_set.rb
+++ b/test/rubygems/test_gem_resolver_index_set.rb
@@ -1,15 +1,10 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverIndexSet < Gem::TestCase
- def setup
- super
-
- @DR = Gem::Resolver
- end
-
def test_initialize
- set = @DR::IndexSet.new
+ set = Gem::Resolver::IndexSet.new
fetcher = set.instance_variable_get :@f
@@ -17,7 +12,7 @@ class TestGemResolverIndexSet < Gem::TestCase
end
def test_initialize_source
- set = @DR::IndexSet.new "http://alternate.example"
+ set = Gem::Resolver::IndexSet.new "http://alternate.example"
fetcher = set.instance_variable_get :@f
@@ -33,15 +28,15 @@ class TestGemResolverIndexSet < Gem::TestCase
fetcher.spec "b", 1
end
- set = @DR::IndexSet.new
+ set = Gem::Resolver::IndexSet.new
dependency = dep "a", "~> 1"
- req = @DR::DependencyRequest.new dependency, nil
+ req = Gem::Resolver::DependencyRequest.new dependency, nil
found = set.find_all req
- assert_equal %w[a-1], found.map {|s| s.full_name }
+ assert_equal %w[a-1], found.map(&:full_name)
end
def test_find_all_local
@@ -51,12 +46,12 @@ class TestGemResolverIndexSet < Gem::TestCase
fetcher.spec "b", 1
end
- set = @DR::IndexSet.new
+ set = Gem::Resolver::IndexSet.new
set.remote = false
dependency = dep "a", "~> 1"
- req = @DR::DependencyRequest.new dependency, nil
+ req = Gem::Resolver::DependencyRequest.new dependency, nil
assert_empty set.find_all req
end
@@ -66,11 +61,11 @@ class TestGemResolverIndexSet < Gem::TestCase
fetcher.spec "a", "1.a"
end
- set = @DR::IndexSet.new
+ set = Gem::Resolver::IndexSet.new
dependency = dep "a"
- req = @DR::DependencyRequest.new dependency, nil
+ req = Gem::Resolver::DependencyRequest.new dependency, nil
found = set.find_all req
@@ -78,10 +73,10 @@ class TestGemResolverIndexSet < Gem::TestCase
dependency.prerelease = true
- req = @DR::DependencyRequest.new dependency, nil
+ req = Gem::Resolver::DependencyRequest.new dependency, nil
found = set.find_all req
- assert_equal %w[a-1.a], found.map {|s| s.full_name }
+ assert_equal %w[a-1.a], found.map(&:full_name)
end
end
diff --git a/test/rubygems/test_gem_resolver_index_specification.rb b/test/rubygems/test_gem_resolver_index_specification.rb
index b479757bd5..ed9475f0cf 100644
--- a/test/rubygems/test_gem_resolver_index_specification.rb
+++ b/test/rubygems/test_gem_resolver_index_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/available_set"
@@ -9,7 +10,8 @@ class TestGemResolverIndexSpecification < Gem::TestCase
version = Gem::Version.new "3.0.3"
spec = Gem::Resolver::IndexSpecification.new(
- set, "rails", version, source, Gem::Platform::RUBY)
+ set, "rails", version, source, Gem::Platform::RUBY
+ )
assert_equal "rails", spec.name
assert_equal version, spec.version
@@ -24,7 +26,8 @@ class TestGemResolverIndexSpecification < Gem::TestCase
version = Gem::Version.new "3.0.3"
spec = Gem::Resolver::IndexSpecification.new(
- set, "rails", version, source, Gem::Platform.local)
+ set, "rails", version, source, Gem::Platform.local
+ )
assert_equal Gem::Platform.local, spec.platform
end
@@ -38,7 +41,8 @@ class TestGemResolverIndexSpecification < Gem::TestCase
source = Gem::Source.new @gem_repo
spec = Gem::Resolver::IndexSpecification.new(
- set, "a", v(2), source, Gem::Platform::RUBY)
+ set, "a", v(2), source, Gem::Platform::RUBY
+ )
called = false
diff --git a/test/rubygems/test_gem_resolver_installed_specification.rb b/test/rubygems/test_gem_resolver_installed_specification.rb
index 156a88144d..5b10273b13 100644
--- a/test/rubygems/test_gem_resolver_installed_specification.rb
+++ b/test/rubygems/test_gem_resolver_installed_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverInstalledSpecification < Gem::TestCase
diff --git a/test/rubygems/test_gem_resolver_installer_set.rb b/test/rubygems/test_gem_resolver_installer_set.rb
index 7617919e2c..202fe9d653 100644
--- a/test/rubygems/test_gem_resolver_installer_set.rb
+++ b/test/rubygems/test_gem_resolver_installer_set.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverInstallerSet < Gem::TestCase
@@ -14,7 +15,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-2], set.always_install.map {|s| s.full_name }
+ assert_equal %w[a-2], set.always_install.map(&:full_name)
e = assert_raise Gem::UnsatisfiableDependencyError do
set.add_always_install dep("b")
@@ -48,7 +49,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-1], set.always_install.map {|s| s.full_name }
+ assert_equal %w[a-1], set.always_install.map(&:full_name)
end
def test_add_always_install_platform_if_gem_platforms_modified_by_platform_flag
@@ -67,7 +68,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-1-x86-freebsd-9], set.always_install.map {|s| s.full_name }
+ assert_equal %w[a-1-x86-freebsd-9], set.always_install.map(&:full_name)
end
def test_add_always_install_index_spec_platform
@@ -80,7 +81,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set = Gem::Resolver::InstallerSet.new :both
set.add_always_install dep("a")
- assert_equal [Gem::Platform.local], set.always_install.map {|s| s.platform }
+ assert_equal [Gem::Platform.local], set.always_install.map(&:platform)
end
def test_add_always_install_prerelease
@@ -93,7 +94,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-1], set.always_install.map {|s| s.full_name }
+ assert_equal %w[a-1], set.always_install.map(&:full_name)
end
def test_add_always_install_prerelease_github_problem
@@ -111,7 +112,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
set.add_always_install dep("a")
- assert_equal %w[a-1], set.always_install.map {|s| s.full_name }
+ assert_equal %w[a-1], set.always_install.map(&:full_name)
end
def test_add_always_install_prerelease_only
@@ -142,7 +143,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
req = Gem::Resolver::DependencyRequest.new dep("a"), nil
- assert_equal %w[a-1], set.find_all(req).map {|spec| spec.full_name }
+ assert_equal %w[a-1], set.find_all(req).map(&:full_name)
end
def test_consider_local_eh
@@ -198,7 +199,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
req = Gem::Resolver::DependencyRequest.new dep("a"), nil
- assert_equal %w[a-2], set.find_all(req).map {|spec| spec.full_name }
+ assert_equal %w[a-2], set.find_all(req).map(&:full_name)
end
def test_find_all_prerelease
@@ -211,12 +212,12 @@ class TestGemResolverInstallerSet < Gem::TestCase
req = Gem::Resolver::DependencyRequest.new dep("a"), nil
- assert_equal %w[a-1], set.find_all(req).map {|spec| spec.full_name }
+ assert_equal %w[a-1], set.find_all(req).map(&:full_name)
req = Gem::Resolver::DependencyRequest.new dep("a", ">= 0.a"), nil
assert_equal %w[a-1 a-1.a],
- set.find_all(req).map {|spec| spec.full_name }.sort
+ set.find_all(req).map(&:full_name).sort
end
def test_find_all_prerelease_dependencies_with_add_local
@@ -228,7 +229,7 @@ class TestGemResolverInstallerSet < Gem::TestCase
req = Gem::Resolver::DependencyRequest.new dep("activesupport", ">= 4.2.0"), nil
- assert_equal %w[activesupport-7.1.0.alpha], set.find_all(req).map {|spec| spec.full_name }
+ assert_equal %w[activesupport-7.1.0.alpha], set.find_all(req).map(&:full_name)
end
def test_load_spec
diff --git a/test/rubygems/test_gem_resolver_local_specification.rb b/test/rubygems/test_gem_resolver_local_specification.rb
index 4ada391cb9..cefd761520 100644
--- a/test/rubygems/test_gem_resolver_local_specification.rb
+++ b/test/rubygems/test_gem_resolver_local_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/available_set"
diff --git a/test/rubygems/test_gem_resolver_lock_set.rb b/test/rubygems/test_gem_resolver_lock_set.rb
index e01d73093c..ebb64ef583 100644
--- a/test/rubygems/test_gem_resolver_lock_set.rb
+++ b/test/rubygems/test_gem_resolver_lock_set.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverLockSet < Gem::TestCase
@@ -15,7 +16,7 @@ class TestGemResolverLockSet < Gem::TestCase
specs = @set.add "a", "2", Gem::Platform::RUBY
spec = specs.first
- assert_equal %w[a-2], @set.specs.map {|t| t.full_name }
+ assert_equal %w[a-2], @set.specs.map(&:full_name)
assert_kind_of Gem::Resolver::LockSpecification, spec
@@ -33,11 +34,11 @@ class TestGemResolverLockSet < Gem::TestCase
found = @set.find_all dep "a"
- assert_equal %w[a-2], found.map {|s| s.full_name }
+ assert_equal %w[a-2], found.map(&:full_name)
found = @set.find_all dep "a", ">= 0.a"
- assert_equal %w[a-1.a a-2], found.map {|s| s.full_name }
+ assert_equal %w[a-1.a a-2], found.map(&:full_name)
end
def test_load_spec
diff --git a/test/rubygems/test_gem_resolver_lock_specification.rb b/test/rubygems/test_gem_resolver_lock_specification.rb
index 32adc25f94..402f5d1509 100644
--- a/test/rubygems/test_gem_resolver_lock_specification.rb
+++ b/test/rubygems/test_gem_resolver_lock_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/installer"
require "rubygems/resolver"
@@ -7,14 +8,12 @@ class TestGemResolverLockSpecification < Gem::TestCase
def setup
super
- @LS = Gem::Resolver::LockSpecification
-
@source = Gem::Source.new @gem_repo
@set = Gem::Resolver::LockSet.new [@source]
end
def test_initialize
- spec = @LS.new @set, "a", v(2), [@source], Gem::Platform::RUBY
+ spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY
assert_equal "a", spec.name
assert_equal v(2), spec.version
@@ -24,7 +23,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
end
def test_add_dependency
- l_spec = @LS.new @set, "a", v(2), [@source], Gem::Platform::RUBY
+ l_spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY
b_dep = dep("b", ">= 0")
@@ -38,7 +37,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
fetcher.download "a", 2
end
- spec = @LS.new @set, "a", v(2), [@source], Gem::Platform::RUBY
+ spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY
called = false
@@ -50,7 +49,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
end
def test_install_installed
- spec = @LS.new @set, "a", v(2), [@source], Gem::Platform::RUBY
+ spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY
FileUtils.touch File.join(@gemhome, "specifications", spec.spec.spec_name)
@@ -66,7 +65,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
def test_spec
version = v(2)
- l_spec = @LS.new @set, "a", version, [@source], Gem::Platform::RUBY
+ l_spec = Gem::Resolver::LockSpecification.new @set, "a", version, [@source], Gem::Platform::RUBY
b_dep = dep "b", ">= 0"
c_dep = dep "c", "~> 1"
@@ -90,7 +89,7 @@ class TestGemResolverLockSpecification < Gem::TestCase
version = v(2)
- l_spec = @LS.new @set, "a", version, [@source], Gem::Platform::RUBY
+ l_spec = Gem::Resolver::LockSpecification.new @set, "a", version, [@source], Gem::Platform::RUBY
assert_same real_spec, l_spec.spec
end
diff --git a/test/rubygems/test_gem_resolver_requirement_list.rb b/test/rubygems/test_gem_resolver_requirement_list.rb
index e9e0d87bf5..20251805fc 100644
--- a/test/rubygems/test_gem_resolver_requirement_list.rb
+++ b/test/rubygems/test_gem_resolver_requirement_list.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverRequirementList < Gem::TestCase
diff --git a/test/rubygems/test_gem_resolver_specification.rb b/test/rubygems/test_gem_resolver_specification.rb
index a8cba3dfd6..e2bbce0c0c 100644
--- a/test/rubygems/test_gem_resolver_specification.rb
+++ b/test/rubygems/test_gem_resolver_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverSpecification < Gem::TestCase
@@ -24,7 +25,7 @@ class TestGemResolverSpecification < Gem::TestCase
a_spec = TestSpec.new a
a_spec.source = Gem::Source.new @gem_repo
- a_spec.install :install_dir => gemhome
+ a_spec.install install_dir: gemhome
assert_path_exist File.join gemhome, "gems", a.full_name
diff --git a/test/rubygems/test_gem_resolver_vendor_set.rb b/test/rubygems/test_gem_resolver_vendor_set.rb
index 9517a4b06e..25a3c5fc7b 100644
--- a/test/rubygems/test_gem_resolver_vendor_set.rb
+++ b/test/rubygems/test_gem_resolver_vendor_set.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverVendorSet < Gem::TestCase
diff --git a/test/rubygems/test_gem_resolver_vendor_specification.rb b/test/rubygems/test_gem_resolver_vendor_specification.rb
index d92ef0b010..3525a6c14c 100644
--- a/test/rubygems/test_gem_resolver_vendor_specification.rb
+++ b/test/rubygems/test_gem_resolver_vendor_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemResolverVendorSpecification < Gem::TestCase
@@ -27,7 +28,8 @@ class TestGemResolverVendorSpecification < Gem::TestCase
i_set = Gem::Resolver::IndexSet.new
source = Gem::Source.new @gem_repo
i_spec = Gem::Resolver::IndexSpecification.new(
- i_set, "a", v(1), source, Gem::Platform::RUBY)
+ i_set, "a", v(1), source, Gem::Platform::RUBY
+ )
refute_equal v_spec_a, i_spec
end
diff --git a/test/rubygems/test_gem_safe_marshal.rb b/test/rubygems/test_gem_safe_marshal.rb
new file mode 100644
index 0000000000..ebb000a9ef
--- /dev/null
+++ b/test/rubygems/test_gem_safe_marshal.rb
@@ -0,0 +1,404 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+
+require "date"
+require "rubygems/safe_marshal"
+
+class TestGemSafeMarshal < Gem::TestCase
+ define_method("test_safe_load_marshal Date #<Date: 1994-12-09 ((2449696j,0s,0n),+0s,2299161j)>") { assert_safe_load_marshal "\x04\bU:\tDate[\vi\x00i\x03 a%i\x00i\x00i\x00f\f2299161" }
+ define_method("test_safe_load_marshal Float 0.0") { assert_safe_load_marshal "\x04\bf\x060" }
+ define_method("test_safe_load_marshal Float -0.0") { assert_safe_load_marshal "\x04\bf\a-0" }
+ define_method("test_safe_load_marshal Float Infinity") { assert_safe_load_marshal "\x04\bf\binf" }
+ define_method("test_safe_load_marshal Float -Infinity") { assert_safe_load_marshal "\x04\bf\t-inf" }
+ define_method("test_safe_load_marshal Float NaN") { assert_safe_load_marshal "\x04\bf\bnan", equality: false }
+ define_method("test_safe_load_marshal Float 1.1") { assert_safe_load_marshal "\x04\bf\b1.1" }
+ define_method("test_safe_load_marshal Float -1.1") { assert_safe_load_marshal "\x04\bf\t-1.1" }
+ define_method("test_safe_load_marshal Float 30000000.0") { assert_safe_load_marshal "\x04\bf\b3e7" }
+ define_method("test_safe_load_marshal Float -30000000.0") { assert_safe_load_marshal "\x04\bf\t-3e7" }
+ define_method("test_safe_load_marshal Gem::Version #<Gem::Version \"1.abc\">") { assert_safe_load_marshal "\x04\bU:\x11Gem::Version[\x06I\"\n1.abc\x06:\x06ET" }
+ define_method("test_safe_load_marshal Hash {} default value") { assert_safe_load_marshal "\x04\b}\x00[\x00", additional_methods: [:default] }
+ define_method("test_safe_load_marshal Hash {}") { assert_safe_load_marshal "\x04\b{\x00" }
+ define_method("test_safe_load_marshal Array {}") { assert_safe_load_marshal "\x04\b[\x00" }
+ define_method("test_safe_load_marshal Hash {:runtime=>:development}") { assert_safe_load_marshal "\x04\bI{\x06:\fruntime:\x10development\x06:\n@type[\x00", permitted_ivars: { "Hash" => %w[@type] } }
+ define_method("test_safe_load_marshal Integer -1") { assert_safe_load_marshal "\x04\bi\xFA" }
+ define_method("test_safe_load_marshal Integer -1048575") { assert_safe_load_marshal "\x04\bi\xFD\x01\x00\xF0" }
+ define_method("test_safe_load_marshal Integer -122") { assert_safe_load_marshal "\x04\bi\x81" }
+ define_method("test_safe_load_marshal Integer -123") { assert_safe_load_marshal "\x04\bi\x80" }
+ define_method("test_safe_load_marshal Integer -124") { assert_safe_load_marshal "\x04\bi\xFF\x84" }
+ define_method("test_safe_load_marshal Integer -127") { assert_safe_load_marshal "\x04\bi\xFF\x81" }
+ define_method("test_safe_load_marshal Integer -128") { assert_safe_load_marshal "\x04\bi\xFF\x80" }
+ define_method("test_safe_load_marshal Integer -2") { assert_safe_load_marshal "\x04\bi\xF9" }
+ define_method("test_safe_load_marshal Integer -255") { assert_safe_load_marshal "\x04\bi\xFF\x01" }
+ define_method("test_safe_load_marshal Integer -256") { assert_safe_load_marshal "\x04\bi\xFF\x00" }
+ define_method("test_safe_load_marshal Integer -257") { assert_safe_load_marshal "\x04\bi\xFE\xFF\xFE" }
+ define_method("test_safe_load_marshal Integer -268435455") { assert_safe_load_marshal "\x04\bi\xFC\x01\x00\x00\xF0" }
+ define_method("test_safe_load_marshal Integer -268435456") { assert_safe_load_marshal "\x04\bi\xFC\x00\x00\x00\xF0" }
+ define_method("test_safe_load_marshal Integer -3") { assert_safe_load_marshal "\x04\bi\xF8" }
+ define_method("test_safe_load_marshal Integer -4") { assert_safe_load_marshal "\x04\bi\xF7" }
+ define_method("test_safe_load_marshal Integer -4294967295") { assert_safe_load_marshal "\x04\bl-\a\xFF\xFF\xFF\xFF" }
+ define_method("test_safe_load_marshal Integer -4294967296") { assert_safe_load_marshal "\x04\bl-\b\x00\x00\x00\x00\x01\x00" }
+ define_method("test_safe_load_marshal Integer -5") { assert_safe_load_marshal "\x04\bi\xF6" }
+ define_method("test_safe_load_marshal Integer -6") { assert_safe_load_marshal "\x04\bi\xF5" }
+ define_method("test_safe_load_marshal Integer -65535") { assert_safe_load_marshal "\x04\bi\xFE\x01\x00" }
+ define_method("test_safe_load_marshal Integer -65536") { assert_safe_load_marshal "\x04\bi\xFE\x00\x00" }
+ define_method("test_safe_load_marshal Integer -9223372036854775807") { assert_safe_load_marshal "\x04\bl-\t\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F" }
+ define_method("test_safe_load_marshal Integer -9223372036854775808") { assert_safe_load_marshal "\x04\bl-\t\x00\x00\x00\x00\x00\x00\x00\x80" }
+ define_method("test_safe_load_marshal Integer 0") { assert_safe_load_marshal "\x04\bi\x00" }
+ define_method("test_safe_load_marshal Integer 1") { assert_safe_load_marshal "\x04\bi\x06" }
+ define_method("test_safe_load_marshal Integer 1048574") { assert_safe_load_marshal "\x04\bi\x03\xFE\xFF\x0F" }
+ define_method("test_safe_load_marshal Integer 1048575") { assert_safe_load_marshal "\x04\bi\x03\xFF\xFF\x0F" }
+ define_method("test_safe_load_marshal Integer 1048576") { assert_safe_load_marshal "\x04\bi\x03\x00\x00\x10" }
+ define_method("test_safe_load_marshal Integer 121") { assert_safe_load_marshal "\x04\bi~" }
+ define_method("test_safe_load_marshal Integer 122") { assert_safe_load_marshal "\x04\bi\x7F" }
+ define_method("test_safe_load_marshal Integer 123") { assert_safe_load_marshal "\x04\bi\x01{" }
+ define_method("test_safe_load_marshal Integer 124") { assert_safe_load_marshal "\x04\bi\x01|" }
+ define_method("test_safe_load_marshal Integer 125") { assert_safe_load_marshal "\x04\bi\x01}" }
+ define_method("test_safe_load_marshal Integer 126") { assert_safe_load_marshal "\x04\bi\x01~" }
+ define_method("test_safe_load_marshal Integer 127") { assert_safe_load_marshal "\x04\bi\x01\x7F" }
+ define_method("test_safe_load_marshal Integer 128") { assert_safe_load_marshal "\x04\bi\x01\x80" }
+ define_method("test_safe_load_marshal Integer 129") { assert_safe_load_marshal "\x04\bi\x01\x81" }
+ define_method("test_safe_load_marshal Integer 2") { assert_safe_load_marshal "\x04\bi\a" }
+ define_method("test_safe_load_marshal Integer 254") { assert_safe_load_marshal "\x04\bi\x01\xFE" }
+ define_method("test_safe_load_marshal Integer 255") { assert_safe_load_marshal "\x04\bi\x01\xFF" }
+ define_method("test_safe_load_marshal Integer 256") { assert_safe_load_marshal "\x04\bi\x02\x00\x01" }
+ define_method("test_safe_load_marshal Integer 257") { assert_safe_load_marshal "\x04\bi\x02\x01\x01" }
+ define_method("test_safe_load_marshal Integer 258") { assert_safe_load_marshal "\x04\bi\x02\x02\x01" }
+ define_method("test_safe_load_marshal Integer 268435454") { assert_safe_load_marshal "\x04\bi\x04\xFE\xFF\xFF\x0F" }
+ define_method("test_safe_load_marshal Integer 268435455") { assert_safe_load_marshal "\x04\bi\x04\xFF\xFF\xFF\x0F" }
+ define_method("test_safe_load_marshal Integer 268435456") { assert_safe_load_marshal "\x04\bi\x04\x00\x00\x00\x10" }
+ define_method("test_safe_load_marshal Integer 268435457") { assert_safe_load_marshal "\x04\bi\x04\x01\x00\x00\x10" }
+ define_method("test_safe_load_marshal Integer 3") { assert_safe_load_marshal "\x04\bi\b" }
+ define_method("test_safe_load_marshal Integer 4") { assert_safe_load_marshal "\x04\bi\t" }
+ define_method("test_safe_load_marshal Integer 4294967294") { assert_safe_load_marshal "\x04\bl+\a\xFE\xFF\xFF\xFF" }
+ define_method("test_safe_load_marshal Integer 4294967295") { assert_safe_load_marshal "\x04\bl+\a\xFF\xFF\xFF\xFF" }
+ define_method("test_safe_load_marshal Integer 4294967296") { assert_safe_load_marshal "\x04\bl+\b\x00\x00\x00\x00\x01\x00" }
+ define_method("test_safe_load_marshal Integer 4294967297") { assert_safe_load_marshal "\x04\bl+\b\x01\x00\x00\x00\x01\x00" }
+ define_method("test_safe_load_marshal Integer 5") { assert_safe_load_marshal "\x04\bi\n" }
+ define_method("test_safe_load_marshal Integer 6") { assert_safe_load_marshal "\x04\bi\v" }
+ define_method("test_safe_load_marshal Integer 65534") { assert_safe_load_marshal "\x04\bi\x02\xFE\xFF" }
+ define_method("test_safe_load_marshal Integer 65535") { assert_safe_load_marshal "\x04\bi\x02\xFF\xFF" }
+ define_method("test_safe_load_marshal Integer 65536") { assert_safe_load_marshal "\x04\bi\x03\x00\x00\x01" }
+ define_method("test_safe_load_marshal Integer 65537") { assert_safe_load_marshal "\x04\bi\x03\x01\x00\x01" }
+ define_method("test_safe_load_marshal Integer 7") { assert_safe_load_marshal "\x04\bi\f" }
+ define_method("test_safe_load_marshal Integer 9223372036854775806") { assert_safe_load_marshal "\x04\bl+\t\xFE\xFF\xFF\xFF\xFF\xFF\xFF\x7F" }
+ define_method("test_safe_load_marshal Integer 9223372036854775807") { assert_safe_load_marshal "\x04\bl+\t\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F" }
+ define_method("test_safe_load_marshal Integer 9223372036854775808") { assert_safe_load_marshal "\x04\bl+\t\x00\x00\x00\x00\x00\x00\x00\x80" }
+ define_method("test_safe_load_marshal Integer 9223372036854775809") { assert_safe_load_marshal "\x04\bl+\t\x01\x00\x00\x00\x00\x00\x00\x80" }
+ define_method("test_safe_load_marshal Rational (1/3)") { assert_safe_load_marshal "\x04\bU:\rRational[\ai\x06i\b" }
+ define_method("test_safe_load_marshal Array [[...]]") { assert_safe_load_marshal "\x04\b[\x06@\x00" }
+ define_method("test_safe_load_marshal String \"hello\" ivar") { assert_safe_load_marshal "\x04\bI\"\nhello\a:\x06ET:\n@type@\x00", additional_methods: [:instance_variables], permitted_ivars: { "String" => %w[@type E] } }
+ define_method("test_safe_load_marshal Array [\"hello\", [\"hello\"], \"hello\", [\"hello\"]]") { assert_safe_load_marshal "\x04\b[\tI\"\nhello\x06:\x06ET[\x06@\x06@\x06@\a" }
+ define_method("test_safe_load_marshal Array [\"hello\", \"hello\"]") { assert_safe_load_marshal "\x04\b[\aI\"\nhello\x06:\x06ET@\x06" }
+ define_method("test_safe_load_marshal Array [:development, :development]") { assert_safe_load_marshal "\x04\b[\a:\x10development;\x00" }
+ define_method("test_safe_load_marshal String \"abc\" ascii") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\x06EF", additional_methods: [:encoding] }
+ define_method("test_safe_load_marshal Array [\"abc\", \"abc\"] ascii") { assert_safe_load_marshal "\x04\b[\aI\"\babc\x06:\x06EF@\x06", additional_methods: [->(x) { x.map(&:encoding) }] }
+ define_method("test_safe_load_marshal String \"abc\" utf8") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\x06ET", additional_methods: [:encoding] }
+ define_method("test_safe_load_marshal Array [\"abc\", \"abc\"] utf8") { assert_safe_load_marshal "\x04\b[\aI\"\babc\x06:\x06ET@\x06", additional_methods: [->(x) { x.map(&:encoding) }] }
+ define_method("test_safe_load_marshal String \"abc\" Windows-1256") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\rencoding\"\x11Windows-1256", additional_methods: [:encoding] }
+ define_method("test_safe_load_marshal Array [\"abc\", \"abc\"] Windows-1256") { assert_safe_load_marshal "\x04\b[\aI\"\babc\x06:\rencoding\"\x11Windows-1256@\x06", additional_methods: [->(x) { x.map(&:encoding) }] }
+ define_method("test_safe_load_marshal String \"abc\" binary") { assert_safe_load_marshal "\x04\b\"\babc", additional_methods: [:encoding] }
+ define_method("test_safe_load_marshal Array [\"abc\", \"abc\"] binary") { assert_safe_load_marshal "\x04\b[\a\"\babc@\x06", additional_methods: [->(x) { x.map(&:encoding) }] }
+ define_method("test_safe_load_marshal String \"\\x61\\x62\\x63\" utf32") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\rencoding\"\vUTF-32", additional_methods: [:encoding] }
+ define_method("test_safe_load_marshal Array [\"\\x61\\x62\\x63\", \"\\x61\\x62\\x63\"] utf32") { assert_safe_load_marshal "\x04\b[\aI\"\babc\x06:\rencoding\"\vUTF-32@\x06", additional_methods: [->(x) { x.map(&:encoding) }] }
+ define_method("test_safe_load_marshal String \"abc\" ivar") { assert_safe_load_marshal "\x04\bI\"\babc\a:\x06ET:\n@typeI\"\ttype\x06;\x00T", permitted_ivars: { "String" => %w[@type E] } }
+ define_method("test_safe_load_marshal String \"\"") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\x06ET" }
+ define_method("test_safe_load_marshal Time 2000-12-31 20:07:59 -1152") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\a:\voffseti\xFE Y:\tzone0", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\a:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 2254051613498933/2251799813685248000000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numl+\t5^\xBAI\f\x02\b\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\b\x00:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 2476979795053773/2251799813685248000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80L\x04\xB0\xEF\t:\rnano_numi\x025\f:\rnano_denl+\b\x00\x00\x00\x00\x00 :\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 2476979795053773/2251799813685248000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x01\x00\xB0\xEF\n:\rnano_numl+\t\x19\x00\x00\x00\x00\x00d\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\x01\x00:\rsubmicro\"\x06\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 2476979795053773/2251799813685248000000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numl+\t\xCD\xCC\xCC\xCC\xCC\xCC\b\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\b\x00:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 450364466336677/450359962737049600000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numl+\t9b->\x05\x00\b\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\b\x00:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 4548635623644201/4503599627370496000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\xF2\x03\xB0\xEF\t:\rnano_numi\x02q\x02:\rnano_denl+\b\x00\x00\x00\x00\x00@:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 4548635623644201/4503599627370496000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x01\x00\xB0\xEF\n:\rnano_numl+\t\x05\x00\x00\x00\x00\x00\x14\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\x02\x00:\rsubmicro\"\x06\x01:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 4548635623644201/4503599627370496000000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numl+\t)\\\x8F\xC2\xF5(\x10\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\x10\x00:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59.000000001 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numi\x06:\rnano_deni\x06:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59.000001 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x01\x00\xB0\xEF\a:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2000-12-31 23:59:59.001 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\xE8\x03\xB0\xEF\a:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2001-01-01 07:59:59 +0000") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\a:\voffseti\x00:\tzone0", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2001-01-01 07:59:59 UTC") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\xC0\x00\x00\xB0\xEF\x06:\tzoneI\"\bUTC\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2001-01-01 11:59:59 +0400") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\a:\voffseti\x02@8:\tzone0", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] }
+ define_method("test_safe_load_marshal Time 2023-08-24 10:10:39.09565 -0700") { assert_safe_load_marshal "\x04\bIu:\tTime\r\x11\xDF\x1E\x80\xA2uq*\a:\voffseti\xFE\x90\x9D:\tzoneI\"\bPDT\x06:\x06EF" }
+ define_method("test_safe_load_marshal Time 2023-08-24 10:10:39.098453 -0700") { assert_safe_load_marshal "\x04\bIu:\tTime\r\x11\xDF\x1E\x80\x95\x80q*\b:\n@typeI\"\fruntime\x06:\x06ET:\voffseti\xFE\x90\x9D:\tzoneI\"\bPDT\x06;\aF", permitted_ivars: { "Time" => %w[@type offset zone], "String" => %w[E @debug_created_info] }, marshal_dump_equality: true }
+
+ def test_repeated_symbol
+ assert_safe_load_as [:development, :development]
+ end
+
+ def test_length_one_symbols
+ with_const(Gem::SafeMarshal, :PERMITTED_SYMBOLS, %w[E A b 0] << "") do
+ assert_safe_load_as [:A, :E, :E, :A, "".to_sym, "".to_sym], additional_methods: [:instance_variables]
+ end
+ end
+
+ def test_repeated_string
+ s = "hello"
+ a = [s]
+ assert_safe_load_as [s, a, s, a]
+ assert_safe_load_as [s, s]
+ end
+
+ def test_recursive_string
+ s = String.new("hello")
+ s.instance_variable_set(:@type, s)
+ with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { "String" => %w[@type E] }) do
+ assert_safe_load_as s, additional_methods: [:instance_variables]
+ end
+ end
+
+ def test_recursive_array
+ a = []
+ a << a
+ assert_safe_load_as a
+ end
+
+ def test_time_loads
+ assert_safe_load_as Time.new
+ end
+
+ def test_string_with_encoding
+ [
+ String.new("abc", encoding: "US-ASCII"),
+ String.new("abc", encoding: "UTF-8"),
+ String.new("abc", encoding: "Windows-1256"),
+ String.new("abc", encoding: Encoding::BINARY),
+ String.new("abc", encoding: "UTF-32"),
+
+ String.new("", encoding: "US-ASCII"),
+ String.new("", encoding: "UTF-8"),
+ String.new("", encoding: "Windows-1256"),
+ String.new("", encoding: Encoding::BINARY),
+ String.new("", encoding: "UTF-32"),
+ ].each do |s|
+ assert_safe_load_as s, additional_methods: [:encoding]
+ assert_safe_load_as [s, s], additional_methods: [->(a) { a.map(&:encoding) }]
+ end
+ end
+
+ def test_string_with_ivar
+ str = String.new("abc")
+ str.instance_variable_set :@type, "type"
+ with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { "String" => %w[@type E @debug_created_info] }) do
+ assert_safe_load_as str
+ end
+ end
+
+ def test_time_with_ivar
+ pend "Marshal.load of Time with ivars is broken on jruby, see https://github.com/jruby/jruby/issues/7902" if RUBY_ENGINE == "jruby"
+
+ with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { "Time" => %w[@type offset zone nano_num nano_den submicro], "String" => %w[E @debug_created_info] }) do
+ assert_safe_load_as Time.new.tap {|t| t.instance_variable_set :@type, "runtime" }, marshal_dump_equality: true
+ end
+ end
+
+ secs = Time.new(2000, 12, 31, 23, 59, 59).to_i
+ [
+ Time.at(secs),
+ Time.at(secs, in: "+04:00"),
+ Time.at(secs, in: "-11:52"),
+ Time.at(secs, in: "+00:00"),
+ Time.at(secs, in: "-00:00"),
+ Time.at(secs, 1, :millisecond),
+ Time.at(secs, 1.1, :millisecond),
+ Time.at(secs, 1.01, :millisecond),
+ Time.at(secs, 1, :microsecond),
+ Time.at(secs, 1.1, :microsecond),
+ Time.at(secs, 1.01, :microsecond),
+ Time.at(secs, 1, :nanosecond),
+ Time.at(secs, 1.1, :nanosecond),
+ Time.at(secs, 1.01, :nanosecond),
+ Time.at(secs, 1.001, :nanosecond),
+ Time.at(secs, 1.00001, :nanosecond),
+ Time.at(secs, 1.00001, :nanosecond),
+ Time.at(secs, in: "UTC"),
+ Time.at(secs, in: "Z"),
+ ].each_with_index do |t, i|
+ define_method("test_time_#{i} #{t.inspect}") do
+ additional_methods = [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a]
+ assert_safe_load_as t, additional_methods: additional_methods
+ end
+ end
+
+ def test_floats
+ [0.0, Float::INFINITY, Float::NAN, 1.1, 3e7].each do |f|
+ assert_safe_load_as f
+ assert_safe_load_as(-f)
+ end
+ end
+
+ def test_hash_with_ivar
+ h = { runtime: :development }
+ h.instance_variable_set :@type, []
+ with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { "Hash" => %w[@type] }) do
+ assert_safe_load_as(h)
+ end
+ end
+
+ def test_hash_with_default_value
+ assert_safe_load_as Hash.new([])
+ end
+
+ def test_hash_with_compare_by_identity
+ with_const(Gem::SafeMarshal, :PERMITTED_CLASSES, %w[Hash]) do
+ assert_safe_load_as Hash.new.compare_by_identity.tap {|h|
+ h[+"a"] = 1
+ h[+"a"] = 2 }, additional_methods: [:compare_by_identity?], equality: false
+ assert_safe_load_as Hash.new.compare_by_identity, additional_methods: [:compare_by_identity?]
+ assert_safe_load_as Hash.new(0).compare_by_identity.tap {|h|
+ h[+"a"] = 1
+ h[+"a"] = 2 }, additional_methods: [:compare_by_identity?, :default], equality: false
+ end
+ end
+
+ class StringSubclass < ::String
+ end
+
+ def test_string_subclass
+ with_const(Gem::SafeMarshal, :PERMITTED_CLASSES, [StringSubclass.name]) do
+ with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { StringSubclass.name => %w[E] }) do
+ e = assert_raise(Gem::SafeMarshal::Visitors::ToRuby::UnsupportedError) do
+ Gem::SafeMarshal.safe_load Marshal.dump StringSubclass.new("abc")
+ end
+ assert_equal "Unsupported user class #{StringSubclass.name} in marshal stream @ root.object", e.message
+ end
+ end
+ end
+
+ class ArraySubclass < ::Array
+ end
+
+ def test_array_subclass
+ with_const(Gem::SafeMarshal, :PERMITTED_CLASSES, [ArraySubclass.name]) do
+ e = assert_raise(Gem::SafeMarshal::Visitors::ToRuby::UnsupportedError) do
+ Gem::SafeMarshal.safe_load(Marshal.dump(ArraySubclass.new << "abc"))
+ end
+ assert_equal "Unsupported user class #{ArraySubclass.name} in marshal stream @ root", e.message
+ end
+ end
+
+ def test_frozen_object
+ assert_safe_load_as Gem::Version.new("1.abc").freeze
+ end
+
+ def test_date
+ assert_safe_load_as Date.new(1994, 12, 9)
+ end
+
+ def test_rational
+ assert_safe_load_as Rational(1, 3)
+ end
+
+ [
+ 0, 1, 2, 3, 4, 5, 6, 122, 123, 124, 127, 128, 255, 256, 257,
+ 2**16, 2**16 - 1, 2**20 - 1,
+ 2**28, 2**28 - 1,
+ 2**32, 2**32 - 1,
+ 2**63, 2**63 - 1
+ ].
+ each do |i|
+ define_method("test_int_ #{i}") do
+ assert_safe_load_as i
+ assert_safe_load_as(-i)
+ assert_safe_load_as(i + 1)
+ assert_safe_load_as(i - 1)
+ end
+ end
+
+ def test_gem_spec_disallowed_symbol
+ e = assert_raise(Gem::SafeMarshal::Visitors::ToRuby::UnpermittedSymbolError) do
+ spec = Gem::Specification.new do |s|
+ s.name = "hi"
+ s.version = "1.2.3"
+
+ s.dependencies << Gem::Dependency.new("rspec", Gem::Requirement.new([">= 1.2.3"]), :runtime).tap {|d| d.instance_variable_set(:@name, :rspec) }
+ end
+ Gem::SafeMarshal.safe_load(Marshal.dump(spec))
+ end
+
+ assert_equal e.message, "Attempting to load unpermitted symbol \"rspec\" @ root.[9].[0].@name"
+ end
+
+ def test_gem_spec_disallowed_ivar
+ e = assert_raise(Gem::SafeMarshal::Visitors::ToRuby::UnpermittedIvarError) do
+ spec = Gem::Specification.new do |s|
+ s.name = "hi"
+ s.version = "1.2.3"
+
+ s.metadata.instance_variable_set(:@foobar, "rspec")
+ end
+ Gem::SafeMarshal.safe_load(Marshal.dump(spec))
+ end
+
+ assert_equal e.message, "Attempting to set unpermitted ivar \"@foobar\" on object of class Hash @ root.[18].ivar_0"
+ end
+
+ def test_unexpected_eof
+ e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do
+ Gem::SafeMarshal.safe_load("\x04\x08")
+ end
+ assert_equal e.message, "Unexpected EOF"
+
+ e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do
+ Gem::SafeMarshal.safe_load("\x04\x08[")
+ end
+ assert_equal e.message, "Unexpected EOF"
+
+ e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do
+ Gem::SafeMarshal.safe_load("\x04\x08[\x06")
+ end
+ assert_equal e.message, "Unexpected EOF"
+ end
+
+ def assert_safe_load_marshal(dumped, additional_methods: [], permitted_ivars: nil, equality: true, marshal_dump_equality: true)
+ loaded = Marshal.load(dumped)
+ safe_loaded =
+ if permitted_ivars
+ with_const(Gem::SafeMarshal, :PERMITTED_IVARS, permitted_ivars) do
+ Gem::SafeMarshal.safe_load(dumped)
+ end
+ else
+ Gem::SafeMarshal.safe_load(dumped)
+ end
+
+ # NaN != NaN, for example
+ if equality
+ assert_equal loaded, safe_loaded, "should equal what Marshal.load returns"
+ end
+
+ assert_equal loaded.to_s, safe_loaded.to_s, "should have equal to_s"
+ assert_equal loaded.inspect, safe_loaded.inspect, "should have equal inspect"
+ additional_methods.each do |m|
+ if m.is_a?(Proc)
+ call = m
+ else
+ call = ->(obj) { obj.__send__(m) }
+ end
+
+ assert_equal call[loaded], call[safe_loaded], "should have equal #{m}"
+ end
+ if marshal_dump_equality
+ assert_equal Marshal.dump(loaded).dump, Marshal.dump(safe_loaded).dump, "should Marshal.dump the same"
+ end
+ end
+
+ def assert_safe_load_as(x, **kwargs)
+ dumped = Marshal.dump(x)
+ equality = x == x # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_safe_load_marshal(dumped, equality: equality, **kwargs)
+ end
+
+ def with_const(mod, name, new_value, &block)
+ orig = mod.const_get(name)
+ mod.send :remove_const, name
+ mod.const_set name, new_value
+
+ begin
+ yield
+ ensure
+ mod.send :remove_const, name
+ mod.const_set name, orig
+ mod.send :private_constant, name
+ end
+ end
+end
diff --git a/test/rubygems/test_gem_safe_yaml.rb b/test/rubygems/test_gem_safe_yaml.rb
new file mode 100644
index 0000000000..02df9f97da
--- /dev/null
+++ b/test/rubygems/test_gem_safe_yaml.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+
+Gem.load_yaml
+
+class TestGemSafeYAML < Gem::TestCase
+ def test_aliases_enabled_by_default
+ assert_predicate Gem::SafeYAML, :aliases_enabled?
+ assert_equal({ "a" => "a", "b" => "a" }, Gem::SafeYAML.safe_load("a: &a a\nb: *a\n"))
+ end
+
+ def test_aliases_disabled
+ aliases_enabled = Gem::SafeYAML.aliases_enabled?
+ Gem::SafeYAML.aliases_enabled = false
+ refute_predicate Gem::SafeYAML, :aliases_enabled?
+ expected_error = defined?(Psych::AliasesNotEnabled) ? Psych::AliasesNotEnabled : Psych::BadAlias
+ assert_raise expected_error do
+ Gem::SafeYAML.safe_load("a: &a\nb: *a\n")
+ end
+ ensure
+ Gem::SafeYAML.aliases_enabled = aliases_enabled
+ end
+end
diff --git a/test/rubygems/test_gem_security.rb b/test/rubygems/test_gem_security.rb
index f0b9824aab..82449a8626 100644
--- a/test/rubygems/test_gem_security.rb
+++ b/test/rubygems/test_gem_security.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/security"
@@ -18,17 +19,11 @@ class TestGemSecurity < Gem::TestCase
CHILD_CERT = load_cert "child"
EXPIRED_CERT = load_cert "expired"
- def setup
- super
-
- @SEC = Gem::Security
- end
-
def test_class_create_cert
name = PUBLIC_CERT.subject
key = PRIVATE_KEY
- cert = @SEC.create_cert name, key, 60, Gem::Security::EXTENSIONS, 5
+ cert = Gem::Security.create_cert name, key, 60, Gem::Security::EXTENSIONS, 5
assert_kind_of OpenSSL::X509::Certificate, cert
@@ -51,7 +46,7 @@ class TestGemSecurity < Gem::TestCase
key_ident = cert.extensions.find {|ext| ext.oid == "subjectKeyIdentifier" }
assert_equal 59, key_ident.value.length
- assert_equal "5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B",
+ assert_equal "B1:1A:54:09:67:45:60:02:02:D7:CE:F4:1D:60:4A:89:DF:E7:58:D9",
key_ident.value
assert_equal "", cert.issuer.to_s
@@ -61,7 +56,7 @@ class TestGemSecurity < Gem::TestCase
def test_class_create_cert_self_signed
subject = PUBLIC_CERT.subject
- cert = @SEC.create_cert_self_signed subject, PRIVATE_KEY, 60
+ cert = Gem::Security.create_cert_self_signed subject, PRIVATE_KEY, 60
assert_equal "/CN=nobody/DC=example", cert.issuer.to_s
assert_equal "sha256WithRSAEncryption", cert.signature_algorithm
@@ -72,7 +67,7 @@ class TestGemSecurity < Gem::TestCase
name = PUBLIC_CERT.subject
key = PRIVATE_KEY
- cert = @SEC.create_cert_email email, key, 60
+ cert = Gem::Security.create_cert_email email, key, 60
assert_kind_of OpenSSL::X509::Certificate, cert
@@ -99,25 +94,25 @@ class TestGemSecurity < Gem::TestCase
key_ident = cert.extensions.find {|ext| ext.oid == "subjectKeyIdentifier" }
assert_equal 59, key_ident.value.length
- assert_equal "5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B",
+ assert_equal "B1:1A:54:09:67:45:60:02:02:D7:CE:F4:1D:60:4A:89:DF:E7:58:D9",
key_ident.value
end
def test_class_create_key
- key = @SEC.create_key "rsa"
+ key = Gem::Security.create_key "rsa"
assert_kind_of OpenSSL::PKey::RSA, key
end
def test_class_create_key_downcases
- key = @SEC.create_key "DSA"
+ key = Gem::Security.create_key "DSA"
assert_kind_of OpenSSL::PKey::DSA, key
end
def test_class_create_key_raises_unknown_algorithm
e = assert_raise Gem::Security::Exception do
- @SEC.create_key "NOT_RSA"
+ Gem::Security.create_key "NOT_RSA"
end
assert_equal "NOT_RSA algorithm not found. RSA, DSA, and EC algorithms are supported.",
@@ -127,31 +122,31 @@ class TestGemSecurity < Gem::TestCase
def test_class_get_public_key_rsa
pkey_pem = PRIVATE_KEY.public_key.to_pem
- assert_equal pkey_pem, @SEC.get_public_key(PRIVATE_KEY).to_pem
+ assert_equal pkey_pem, Gem::Security.get_public_key(PRIVATE_KEY).to_pem
end
def test_class_get_public_key_ec
- pkey = @SEC.get_public_key(EC_KEY)
+ pkey = Gem::Security.get_public_key(EC_KEY)
assert_respond_to pkey, :to_pem
end
def test_class_email_to_name
assert_equal "/CN=nobody/DC=example",
- @SEC.email_to_name("nobody@example").to_s
+ Gem::Security.email_to_name("nobody@example").to_s
assert_equal "/CN=nobody/DC=example/DC=com",
- @SEC.email_to_name("nobody@example.com").to_s
+ Gem::Security.email_to_name("nobody@example.com").to_s
assert_equal "/CN=no.body/DC=example",
- @SEC.email_to_name("no.body@example").to_s
+ Gem::Security.email_to_name("no.body@example").to_s
assert_equal "/CN=no_body/DC=example",
- @SEC.email_to_name("no+body@example").to_s
+ Gem::Security.email_to_name("no+body@example").to_s
end
def test_class_re_sign
- assert_equal "sha1WithRSAEncryption", EXPIRED_CERT.signature_algorithm
+ assert_equal "sha256WithRSAEncryption", EXPIRED_CERT.signature_algorithm
re_signed = Gem::Security.re_sign EXPIRED_CERT, PRIVATE_KEY, 60
assert_in_delta Time.now, re_signed.not_before, 10
@@ -171,7 +166,7 @@ class TestGemSecurity < Gem::TestCase
extension.oid == "subjectAltName"
end
- assert_equal "#{child_alt_name.value} is not self-signed, contact " +
+ assert_equal "#{child_alt_name.value} is not self-signed, contact " \
"#{ALTERNATE_CERT.issuer} to obtain a valid certificate",
e.message
end
@@ -182,16 +177,16 @@ class TestGemSecurity < Gem::TestCase
end
assert_equal "incorrect signing key for re-signing " +
- "#{ALTERNATE_CERT.subject}",
+ ALTERNATE_CERT.subject.to_s,
e.message
end
def test_class_reset
- trust_dir = @SEC.trust_dir
+ trust_dir = Gem::Security.trust_dir
- @SEC.reset
+ Gem::Security.reset
- refute_equal trust_dir, @SEC.trust_dir
+ refute_equal trust_dir, Gem::Security.trust_dir
end
def test_class_sign
@@ -205,7 +200,7 @@ class TestGemSecurity < Gem::TestCase
cert.subject = signee
cert.public_key = key.public_key
- signed = @SEC.sign cert, key, PUBLIC_CERT, 60
+ signed = Gem::Security.sign cert, key, PUBLIC_CERT, 60
assert_equal key.public_key.to_pem, signed.public_key.to_pem
assert_equal signee.to_s, signed.subject.to_s
@@ -230,7 +225,7 @@ class TestGemSecurity < Gem::TestCase
key_ident =
signed.extensions.find {|ext| ext.oid == "subjectKeyIdentifier" }
assert_equal 59, key_ident.value.length
- assert_equal "5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B",
+ assert_equal "B1:1A:54:09:67:45:60:02:02:D7:CE:F4:1D:60:4A:89:DF:E7:58:D9",
key_ident.value
assert signed.verify key
@@ -240,9 +235,9 @@ class TestGemSecurity < Gem::TestCase
issuer = PUBLIC_CERT.subject
signee = OpenSSL::X509::Name.parse "/CN=signee/DC=example"
- cert = @SEC.create_cert_email "signee@example", PRIVATE_KEY
+ cert = Gem::Security.create_cert_email "signee@example", PRIVATE_KEY
- signed = @SEC.sign cert, PRIVATE_KEY, PUBLIC_CERT, 60
+ signed = Gem::Security.sign cert, PRIVATE_KEY, PUBLIC_CERT, 60
assert_equal PUBLIC_KEY.to_pem, signed.public_key.to_pem
assert_equal signee.to_s, signed.subject.to_s
@@ -272,14 +267,14 @@ class TestGemSecurity < Gem::TestCase
key_ident =
signed.extensions.find {|ext| ext.oid == "subjectKeyIdentifier" }
assert_equal 59, key_ident.value.length
- assert_equal "5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B",
+ assert_equal "B1:1A:54:09:67:45:60:02:02:D7:CE:F4:1D:60:4A:89:DF:E7:58:D9",
key_ident.value
assert signed.verify PUBLIC_KEY
end
def test_class_trust_dir
- trust_dir = @SEC.trust_dir
+ trust_dir = Gem::Security.trust_dir
expected = File.join Gem.user_home, ".gem/trust"
@@ -287,11 +282,11 @@ class TestGemSecurity < Gem::TestCase
end
def test_class_write
- key = @SEC.create_key "rsa"
+ key = Gem::Security.create_key "rsa"
path = File.join @tempdir, "test-private_key.pem"
- @SEC.write key, path
+ Gem::Security.write key, path
assert_path_exist path
@@ -301,13 +296,13 @@ class TestGemSecurity < Gem::TestCase
end
def test_class_write_encrypted
- key = @SEC.create_key "rsa"
+ key = Gem::Security.create_key "rsa"
path = File.join @tempdir, "test-private_encrypted_key.pem"
passphrase = "It should be long."
- @SEC.write key, path, 0600, passphrase
+ Gem::Security.write key, path, 0o600, passphrase
assert_path_exist path
@@ -317,7 +312,7 @@ class TestGemSecurity < Gem::TestCase
end
def test_class_write_encrypted_cipher
- key = @SEC.create_key "rsa"
+ key = Gem::Security.create_key "rsa"
path = File.join @tempdir, "test-private_encrypted__with_non_default_cipher_key.pem"
@@ -325,7 +320,7 @@ class TestGemSecurity < Gem::TestCase
cipher = OpenSSL::Cipher.new "AES-192-CBC"
- @SEC.write key, path, 0600, passphrase, cipher
+ Gem::Security.write key, path, 0o600, passphrase, cipher
assert_path_exist path
diff --git a/test/rubygems/test_gem_security_policy.rb b/test/rubygems/test_gem_security_policy.rb
index 6680238245..2f4fb1ce28 100644
--- a/test/rubygems/test_gem_security_policy.rb
+++ b/test/rubygems/test_gem_security_policy.rb
@@ -33,7 +33,7 @@ class TestGemSecurityPolicy < Gem::TestCase
end
@digest = OpenSSL::Digest.new Gem::Security::DIGEST_NAME
- @trust_dir = Gem::Security.trust_dir.dir # HACK use the object
+ @trust_dir = Gem::Security.trust_dir.dir # HACK: use the object
@no = Gem::Security::NoSecurity
@almost_no = Gem::Security::AlmostNoSecurity
@@ -43,22 +43,22 @@ class TestGemSecurityPolicy < Gem::TestCase
@chain = Gem::Security::Policy.new(
"Chain",
- :verify_data => true,
- :verify_signer => true,
- :verify_chain => true,
- :verify_root => false,
- :only_trusted => false,
- :only_signed => false
+ verify_data: true,
+ verify_signer: true,
+ verify_chain: true,
+ verify_root: false,
+ only_trusted: false,
+ only_signed: false
)
@root = Gem::Security::Policy.new(
"Root",
- :verify_data => true,
- :verify_signer => true,
- :verify_chain => true,
- :verify_root => true,
- :only_trusted => false,
- :only_signed => false
+ verify_data: true,
+ verify_signer: true,
+ verify_chain: true,
+ verify_root: true,
+ only_trusted: false,
+ only_signed: false
)
end
@@ -105,8 +105,8 @@ class TestGemSecurityPolicy < Gem::TestCase
@chain.check_chain chain, Time.now
end
- assert_equal "invalid signing chain: " +
- "certificate #{INVALIDCHILD_CERT.subject} " +
+ assert_equal "invalid signing chain: " \
+ "certificate #{INVALIDCHILD_CERT.subject} " \
"was not issued by #{CHILD_CERT.subject}", e.message
end
@@ -127,7 +127,7 @@ class TestGemSecurityPolicy < Gem::TestCase
@low.check_cert EXPIRED_CERT, nil, Time.now
end
- assert_equal "certificate #{EXPIRED_CERT.subject} " +
+ assert_equal "certificate #{EXPIRED_CERT.subject} " \
"not valid after #{EXPIRED_CERT.not_after}",
e.message
end
@@ -137,7 +137,7 @@ class TestGemSecurityPolicy < Gem::TestCase
@low.check_cert FUTURE_CERT, nil, Time.now
end
- assert_equal "certificate #{FUTURE_CERT.subject} " +
+ assert_equal "certificate #{FUTURE_CERT.subject} " \
"not valid before #{FUTURE_CERT.not_before}",
e.message
end
@@ -147,7 +147,7 @@ class TestGemSecurityPolicy < Gem::TestCase
@low.check_cert INVALID_ISSUER_CERT, PUBLIC_CERT, Time.now
end
- assert_equal "certificate #{INVALID_ISSUER_CERT.subject} " +
+ assert_equal "certificate #{INVALID_ISSUER_CERT.subject} " \
"was not issued by #{PUBLIC_CERT.subject}",
e.message
end
@@ -183,7 +183,7 @@ class TestGemSecurityPolicy < Gem::TestCase
@almost_no.check_key(PUBLIC_CERT, ALTERNATE_KEY)
end
- assert_equal "certificate #{PUBLIC_CERT.subject} " +
+ assert_equal "certificate #{PUBLIC_CERT.subject} " \
"does not match the signing key", e.message
end
@@ -208,7 +208,7 @@ class TestGemSecurityPolicy < Gem::TestCase
@chain.check_root chain, Time.now
end
- assert_equal "certificate #{INVALID_SIGNER_CERT.subject} " +
+ assert_equal "certificate #{INVALID_SIGNER_CERT.subject} " \
"was not issued by #{INVALID_SIGNER_CERT.issuer}",
e.message
end
@@ -220,7 +220,7 @@ class TestGemSecurityPolicy < Gem::TestCase
@chain.check_root chain, Time.now
end
- assert_equal "root certificate #{INVALID_ISSUER_CERT.subject} " +
+ assert_equal "root certificate #{INVALID_ISSUER_CERT.subject} " \
"is not self-signed (issuer #{INVALID_ISSUER_CERT.issuer})",
e.message
end
@@ -260,7 +260,7 @@ class TestGemSecurityPolicy < Gem::TestCase
@high.check_trust [WRONG_KEY_CERT], @digest, @trust_dir
end
- assert_equal "trusted root certificate #{PUBLIC_CERT.subject} checksum " +
+ assert_equal "trusted root certificate #{PUBLIC_CERT.subject} checksum " \
"does not match signing root certificate checksum", e.message
end
@@ -285,7 +285,7 @@ class TestGemSecurityPolicy < Gem::TestCase
@high.check_trust [PUBLIC_CERT, CHILD_CERT], @digest, @trust_dir
end
- assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted " +
+ assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted " \
"(root of signing cert #{CHILD_CERT.subject})", e.message
end
@@ -452,7 +452,9 @@ class TestGemSecurityPolicy < Gem::TestCase
package.checksums[Gem::Security::DIGEST_NAME] = {}
s = StringIO.new metadata_gz
- def s.full_name() "metadata.gz" end
+ def s.full_name
+ "metadata.gz"
+ end
digests = package.digest s
metadata_gz_digest = digests[Gem::Security::DIGEST_NAME]["metadata.gz"]
@@ -475,7 +477,9 @@ class TestGemSecurityPolicy < Gem::TestCase
package.checksums[Gem::Security::DIGEST_NAME] = {}
s = StringIO.new metadata_gz
- def s.full_name() "metadata.gz" end
+ def s.full_name
+ "metadata.gz"
+ end
digests = package.digest s
digests[Gem::Security::DIGEST_NAME]["data.tar.gz"] = @digest.hexdigest "hello"
@@ -504,7 +508,9 @@ class TestGemSecurityPolicy < Gem::TestCase
package.checksums[Gem::Security::DIGEST_NAME] = {}
s = StringIO.new metadata_gz
- def s.full_name() "metadata.gz" end
+ def s.full_name
+ "metadata.gz"
+ end
digests = package.digest s
digests[Gem::Security::DIGEST_NAME]["data.tar.gz"] = @digest.hexdigest "hello"
@@ -530,6 +536,6 @@ class TestGemSecurityPolicy < Gem::TestCase
digests = { Gem::Security::DIGEST_NAME => { 0 => data } }
signatures = { 0 => sign(data, key) }
- return digests, signatures
+ [digests, signatures]
end
end if Gem::HAVE_OPENSSL
diff --git a/test/rubygems/test_gem_security_signer.rb b/test/rubygems/test_gem_security_signer.rb
index d9f320eeb0..f4799cbd46 100644
--- a/test/rubygems/test_gem_security_signer.rb
+++ b/test/rubygems/test_gem_security_signer.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
unless Gem::HAVE_OPENSSL
@@ -36,8 +37,8 @@ class TestGemSecuritySigner < Gem::TestCase
def test_initialize_cert_chain_mixed
signer = Gem::Security::Signer.new nil, [@cert_file, CHILD_CERT]
- assert_equal [PUBLIC_CERT, CHILD_CERT].map {|c| c.to_pem },
- signer.cert_chain.map {|c| c.to_pem }
+ assert_equal [PUBLIC_CERT, CHILD_CERT].map(&:to_pem),
+ signer.cert_chain.map(&:to_pem)
end
def test_initialize_cert_chain_invalid
@@ -49,8 +50,8 @@ class TestGemSecuritySigner < Gem::TestCase
def test_initialize_cert_chain_path
signer = Gem::Security::Signer.new nil, [@cert_file]
- assert_equal [PUBLIC_CERT].map {|c| c.to_pem },
- signer.cert_chain.map {|c| c.to_pem }
+ assert_equal [PUBLIC_CERT].map(&:to_pem),
+ signer.cert_chain.map(&:to_pem)
end
def test_initialize_default
@@ -65,7 +66,7 @@ class TestGemSecuritySigner < Gem::TestCase
signer = Gem::Security::Signer.new nil, nil
assert_equal PRIVATE_KEY.to_pem, signer.key.to_pem
- assert_equal [PUBLIC_CERT.to_pem], signer.cert_chain.map {|c| c.to_pem }
+ assert_equal [PUBLIC_CERT.to_pem], signer.cert_chain.map(&:to_pem)
end
def test_initialize_key_path
@@ -99,7 +100,7 @@ class TestGemSecuritySigner < Gem::TestCase
signer.load_cert_chain
assert_equal [PUBLIC_CERT.to_pem, CHILD_CERT.to_pem],
- signer.cert_chain.map {|c| c.to_pem }
+ signer.cert_chain.map(&:to_pem)
end
def test_load_cert_chain_broken
@@ -111,7 +112,7 @@ class TestGemSecuritySigner < Gem::TestCase
signer.load_cert_chain
assert_equal [CHILD_CERT.to_pem, GRANDCHILD_CERT.to_pem],
- signer.cert_chain.map {|c| c.to_pem }
+ signer.cert_chain.map(&:to_pem)
end
def test_sign
@@ -120,12 +121,12 @@ class TestGemSecuritySigner < Gem::TestCase
signature = signer.sign "hello"
expected = <<-EXPECTED
-cHze2sEfRysoUMCfGVAx/7o8jxj5liJJ2ptNxe2jf3l+EZvyjdqpXo9Ndzxx
-6xLp2rxLG4K2//ip4aCH5Sh7hnia+F5u6iuLBETPlklPrmw5dnuKZxolz+vM
-0O1aOZsQHcVzQoESTGjkms3KZk+gn3lg0sSBbAV5/LyDYoHCEjxlcA5D+Olb
-rDmRyBMOnMS+q489OZ5Hr6B2YJJ3QbUwIZNhUeNmOxIBEYTrrKkZ92qkxbRN
-qhlqFP4jR6zXFeyBCOr0KpTiWBNuxBFXDsxmhGyt2BOIjD6qmKn7RSIfYg/U
-toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA==
+FmrCYxEXW3dgYYNMxPdS16VrdXT+d5nyXTVlRm64ZHSgMxMAaPtQJsVYv73m
+DWHTzNnLhhINSpgBMLh5a4atM52yxVdkPUTgqIH+LeIPBXn8xaP5JLmfDcmI
+tBpc/9DhS3v9iKCX40igAArFu7Gg3swbgQ61SP+U22LvG5nDQZQz3sudtsw3
+qKPykFVaYjrRwzvBdSdJ1PwlAsanSwcwS/GKPtmE/ykZ6X5XOx7wvCDL/zGy
+B8khkB8hDKC6moCzebmUxCBmTmXD0Wjzon+bf4MOriVE3a0ySGRvpr1mKR2+
+9EaVo7pDJLEM487+xg1CAZHRhwshd6II00XEzG/jBQ==
EXPECTED
assert_equal expected, [signature].pack("m")
@@ -143,7 +144,7 @@ toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA==
def test_sign_expired_auto_update
pend if Gem.java_platform?
- FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), :mode => 0700
+ FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), mode: 0o700
private_key_path = File.join(Gem.user_home, ".gem", "gem-private_key.pem")
Gem::Security.write PRIVATE_KEY, private_key_path
@@ -170,7 +171,7 @@ toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA==
end
def test_sign_expired_auto_update_exists
- FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), :mode => 0700
+ FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), mode: 0o700
expiry = EXPIRED_CERT.not_after.strftime "%Y%m%d%H%M%S"
expired_path =
diff --git a/test/rubygems/test_gem_security_trust_dir.rb b/test/rubygems/test_gem_security_trust_dir.rb
index b74e21fb5c..cfde8e9d48 100644
--- a/test/rubygems/test_gem_security_trust_dir.rb
+++ b/test/rubygems/test_gem_security_trust_dir.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
unless Gem::HAVE_OPENSSL
@@ -55,9 +56,9 @@ class TestGemSecurityTrustDir < Gem::TestCase
assert_path_exist trusted
- mask = 0100600 & (~File.umask)
+ mask = 0o100600 & (~File.umask)
- assert_equal mask, File.stat(trusted).mode unless win_platform?
+ assert_equal mask, File.stat(trusted).mode unless Gem.win_platform?
assert_equal PUBLIC_CERT.to_pem, File.read(trusted)
end
@@ -69,10 +70,10 @@ class TestGemSecurityTrustDir < Gem::TestCase
assert_path_exist @dest_dir
- mask = 040700 & (~File.umask)
- mask |= 0200000 if RUBY_PLATFORM.include?("aix")
+ mask = 0o040700 & (~File.umask)
+ mask |= 0o200000 if RUBY_PLATFORM.include?("aix")
- assert_equal mask, File.stat(@dest_dir).mode unless win_platform?
+ assert_equal mask, File.stat(@dest_dir).mode unless Gem.win_platform?
end
def test_verify_file
@@ -86,13 +87,13 @@ class TestGemSecurityTrustDir < Gem::TestCase
end
def test_verify_wrong_permissions
- FileUtils.mkdir_p @dest_dir, :mode => 0777
+ FileUtils.mkdir_p @dest_dir, mode: 0o777
@trust_dir.verify
- mask = 040700 & (~File.umask)
- mask |= 0200000 if RUBY_PLATFORM.include?("aix")
+ mask = 0o40700 & (~File.umask)
+ mask |= 0o200000 if RUBY_PLATFORM.include?("aix")
- assert_equal mask, File.stat(@dest_dir).mode unless win_platform?
+ assert_equal mask, File.stat(@dest_dir).mode unless Gem.win_platform?
end
end if Gem::HAVE_OPENSSL
diff --git a/test/rubygems/test_gem_silent_ui.rb b/test/rubygems/test_gem_silent_ui.rb
index c5d2a35c34..001a73eb51 100644
--- a/test/rubygems/test_gem_silent_ui.rb
+++ b/test/rubygems/test_gem_silent_ui.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/user_interaction"
-require "timeout"
class TestGemSilentUI < Gem::TestCase
def setup
@@ -115,7 +115,7 @@ class TestGemSilentUI < Gem::TestCase
end
def test_new_without_dev_null
- File.stub(:open, ->(path, mode) { raise Errno::ENOTCAPABLE if path == IO::NULL }) do
+ File.stub(:open, ->(path, _mode) { raise Errno::ENOTCAPABLE if path == IO::NULL }) do
Gem::SilentUI.new
end
end
diff --git a/test/rubygems/test_gem_source.rb b/test/rubygems/test_gem_source.rb
index e164215b57..6baa203dcb 100644
--- a/test/rubygems/test_gem_source.rb
+++ b/test/rubygems/test_gem_source.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/source"
-require "rubygems/indexer"
class TestGemSource < Gem::TestCase
def tuple(*args)
@@ -22,7 +22,7 @@ class TestGemSource < Gem::TestCase
end
def test_initialize_invalid_uri
- assert_raise URI::InvalidURIError do
+ assert_raise Gem::URI::InvalidURIError do
Gem::Source.new "git@example:a.git"
end
end
@@ -30,21 +30,21 @@ class TestGemSource < Gem::TestCase
def test_initialize_git
repository = "git@example:a.git"
- source = Gem::Source::Git.new "a", repository, "master", false
+ source = Gem::Source::Git.new "a", repository, nil, false
assert_equal repository, source.uri
end
def test_cache_dir_escapes_windows_paths
- uri = URI.parse("file:///C:/WINDOWS/Temp/gem_repo")
+ uri = Gem::URI.parse("file:///C:/WINDOWS/Temp/gem_repo")
root = Gem.spec_cache_dir
cache_dir = @source.cache_dir(uri).gsub(root, "")
- assert cache_dir !~ /:/, "#{cache_dir} should not contain a :"
+ assert !cache_dir.include?(":"), "#{cache_dir} should not contain a :"
end
def test_dependency_resolver_set_bundler_api
- response = Net::HTTPResponse.new "1.1", 200, "OK"
- response.uri = URI("http://example")
+ response = Gem::Net::HTTPResponse.new "1.1", 200, "OK"
+ response.uri = Gem::URI("http://example")
@fetcher.data[@gem_repo] = response
@@ -54,7 +54,9 @@ class TestGemSource < Gem::TestCase
end
def test_dependency_resolver_set_file_uri
- Gem::Indexer.new(@tempdir).generate_index
+ empty_dump = Gem::Util.gzip("\x04\x08[\x05".b)
+ File.binwrite(File.join(@tempdir, "prerelease_specs.4.8.gz"), empty_dump)
+ File.binwrite(File.join(@tempdir, "specs.4.8.gz"), empty_dump)
source = Gem::Source.new "file://#{@tempdir}/"
@@ -77,7 +79,7 @@ class TestGemSource < Gem::TestCase
spec = @source.fetch_spec tuple("a", Gem::Version.new(1), "ruby")
assert_equal a1.full_name, spec.full_name
- cache_dir = @source.cache_dir URI.parse(spec_uri)
+ cache_dir = @source.cache_dir Gem::URI.parse(spec_uri)
cache_file = File.join cache_dir, a1.spec_name
@@ -90,7 +92,7 @@ class TestGemSource < Gem::TestCase
spec_uri = "#{@gem_repo}/#{Gem::MARSHAL_SPEC_DIR}#{a1.spec_name}"
@fetcher.data["#{spec_uri}.rz"] = nil
- cache_dir = @source.cache_dir URI.parse(spec_uri)
+ cache_dir = @source.cache_dir Gem::URI.parse(spec_uri)
FileUtils.mkdir_p cache_dir
cache_file = File.join cache_dir, a1.spec_name
@@ -104,9 +106,7 @@ class TestGemSource < Gem::TestCase
end
def test_fetch_spec_platform
- specs = spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ specs = spec_fetcher(&:legacy_platform)
spec = @source.fetch_spec tuple("pl", Gem::Version.new(1), "i386-linux")
@@ -122,7 +122,7 @@ class TestGemSource < Gem::TestCase
end
def test_load_specs
- released = @source.load_specs(:released).map {|spec| spec.full_name }
+ released = @source.load_specs(:released).map(&:full_name)
assert_equal %W[a-2 a-1 b-2], released
cache_dir = File.join Gem.spec_cache_dir, "gems.example.com%80"
@@ -164,7 +164,7 @@ class TestGemSource < Gem::TestCase
latest_specs << Gem::NameTuple.new("fixed", Gem::Version.new("1.0.0"), "ruby")
# Setup valid data on the 'remote'
@fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] =
- util_gzip(Marshal.dump(latest_specs))
+ util_gzip(Marshal.dump(latest_specs))
cache_dir = File.join Gem.spec_cache_dir, "gems.example.com%80"
@@ -196,7 +196,7 @@ class TestGemSource < Gem::TestCase
installed = Gem::Source::Installed.new
local = Gem::Source::Local.new
- assert_equal(0, remote.<=>(remote), "remote <=> remote")
+ assert_equal(0, remote.<=>(remote), "remote <=> remote") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(-1, remote.<=>(specific), "remote <=> specific")
assert_equal(1, specific.<=>(remote), "specific <=> remote")
@@ -214,12 +214,12 @@ class TestGemSource < Gem::TestCase
end
def test_spaceship_order_is_preserved_when_uri_differs
- sourceA = Gem::Source.new "http://example.com/a"
- sourceB = Gem::Source.new "http://example.com/b"
+ source_a = Gem::Source.new "http://example.com/a"
+ source_b = Gem::Source.new "http://example.com/b"
- assert_equal(0, sourceA.<=>(sourceA), "sourceA <=> sourceA")
- assert_equal(1, sourceA.<=>(sourceB), "sourceA <=> sourceB")
- assert_equal(1, sourceB.<=>(sourceA), "sourceB <=> sourceA")
+ assert_equal(0, source_a.<=>(source_a), "source_a <=> source_a") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
+ assert_equal(1, source_a.<=>(source_b), "source_a <=> source_b")
+ assert_equal(1, source_b.<=>(source_a), "source_b <=> source_a")
end
def test_update_cache_eh
diff --git a/test/rubygems/test_gem_source_fetch_problem.rb b/test/rubygems/test_gem_source_fetch_problem.rb
index 143c29050e..6d8ef360ae 100644
--- a/test/rubygems/test_gem_source_fetch_problem.rb
+++ b/test/rubygems/test_gem_source_fetch_problem.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemSourceFetchProblem < Gem::TestCase
diff --git a/test/rubygems/test_gem_source_git.rb b/test/rubygems/test_gem_source_git.rb
index 5702da0597..20e750a0d4 100644
--- a/test/rubygems/test_gem_source_git.rb
+++ b/test/rubygems/test_gem_source_git.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/source"
@@ -8,9 +9,9 @@ class TestGemSourceGit < Gem::TestCase
@name, @version, @repository, @head = git_gem
- @hash = Digest::SHA1.hexdigest @repository
+ @hash = OpenSSL::Digest::SHA1.hexdigest @repository
- @source = Gem::Source::Git.new @name, @repository, "master", false
+ @source = Gem::Source::Git.new @name, @repository, nil, false
end
def test_base_dir
@@ -27,12 +28,13 @@ class TestGemSourceGit < Gem::TestCase
assert_path_exist File.join @source.install_dir, "a.gemspec"
end
- def test_checkout_master
+ def test_checkout_default
Dir.chdir @repository do
+ default_branch = Gem::Util.popen(@git, "branch", "--show-current").strip
system @git, "checkout", "-q", "-b", "other"
system @git, "mv", "a.gemspec", "b.gemspec"
system @git, "commit", "-q", "-a", "-m", "rename gemspec"
- system @git, "checkout", "-q", "master"
+ system @git, "checkout", "-q", default_branch
end
@source = Gem::Source::Git.new @name, @repository, "other", false
@@ -63,7 +65,12 @@ class TestGemSourceGit < Gem::TestCase
end
def test_checkout_submodules
- source = Gem::Source::Git.new @name, @repository, "master", true
+ # We need to allow to checkout submodules with file:// protocol
+ # CVE-2022-39253
+ # https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
+ system(@git, *%W[config --global protocol.file.allow always])
+
+ source = Gem::Source::Git.new @name, @repository, nil, true
git_gem "b"
@@ -87,7 +94,7 @@ class TestGemSourceGit < Gem::TestCase
assert_path_exist @source.repo_cache_dir
Dir.chdir @source.repo_cache_dir do
- assert_equal @head, Gem::Util.popen(@git, "rev-parse", "master").strip
+ assert_equal @head, Gem::Util.popen(@git, "rev-parse", "HEAD").strip
end
end
@@ -173,7 +180,7 @@ class TestGemSourceGit < Gem::TestCase
system @git, "checkout", "--quiet", "-b", "other"
end
- master_head = @head
+ default_head = @head
git_gem "a", 2
@@ -181,7 +188,7 @@ class TestGemSourceGit < Gem::TestCase
source.cache
- refute_equal master_head, source.rev_parse
+ refute_equal default_head, source.rev_parse
source = Gem::Source::Git.new @name, @repository, "nonexistent", false
@@ -204,12 +211,12 @@ class TestGemSourceGit < Gem::TestCase
end
def test_spaceship
- git = Gem::Source::Git.new "a", "git/a", "master", false
+ git = Gem::Source::Git.new "a", "git/a", nil, false
remote = Gem::Source.new @gem_repo
installed = Gem::Source::Installed.new
vendor = Gem::Source::Vendor.new "vendor/foo"
- assert_equal(0, git.<=>(git), "git <=> git")
+ assert_equal(0, git.<=>(git), "git <=> git") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(1, git.<=>(remote), "git <=> remote")
assert_equal(-1, remote.<=>(git), "remote <=> git")
@@ -222,7 +229,7 @@ class TestGemSourceGit < Gem::TestCase
end
def test_specs
- source = Gem::Source::Git.new @name, @repository, "master", true
+ source = Gem::Source::Git.new @name, @repository, nil, true
Dir.chdir "git/a" do
FileUtils.mkdir "b"
@@ -245,7 +252,7 @@ class TestGemSourceGit < Gem::TestCase
specs = source.specs
end
- assert_equal %w[a-1 b-1], specs.map {|spec| spec.full_name }
+ assert_equal %w[a-1 b-1], specs.map(&:full_name)
a_spec = specs.shift
@@ -273,7 +280,7 @@ class TestGemSourceGit < Gem::TestCase
end
def test_specs_local
- source = Gem::Source::Git.new @name, @repository, "master", true
+ source = Gem::Source::Git.new @name, @repository, nil, true
source.remote = false
capture_output do
@@ -282,20 +289,20 @@ class TestGemSourceGit < Gem::TestCase
end
def test_uri
- assert_equal URI(@repository), @source.uri
+ assert_equal Gem::URI(@repository), @source.uri
end
def test_uri_hash
assert_equal @hash, @source.uri_hash
source =
- Gem::Source::Git.new "a", "http://git@example/repo.git", "master", false
+ Gem::Source::Git.new "a", "http://git@example/repo.git", nil, false
assert_equal "291c4caac7feba8bb64c297987028acb3dde6cfe",
source.uri_hash
source =
- Gem::Source::Git.new "a", "HTTP://git@EXAMPLE/repo.git", "master", false
+ Gem::Source::Git.new "a", "HTTP://git@EXAMPLE/repo.git", nil, false
assert_equal "291c4caac7feba8bb64c297987028acb3dde6cfe",
source.uri_hash
diff --git a/test/rubygems/test_gem_source_installed.rb b/test/rubygems/test_gem_source_installed.rb
index 7fb5017c59..0d6171b0e5 100644
--- a/test/rubygems/test_gem_source_installed.rb
+++ b/test/rubygems/test_gem_source_installed.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/source"
@@ -11,10 +12,10 @@ class TestGemSourceInstalled < Gem::TestCase
specific = Gem::Source::SpecificFile.new a1.cache_file
installed = Gem::Source::Installed.new
local = Gem::Source::Local.new
- git = Gem::Source::Git.new "a", "a", "master"
+ git = Gem::Source::Git.new "a", "a", nil
vendor = Gem::Source::Vendor.new "a"
- assert_equal(0, installed.<=>(installed), "installed <=> installed")
+ assert_equal(0, installed.<=>(installed), "installed <=> installed") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(-1, remote.<=>(installed), "remote <=> installed")
assert_equal(1, installed.<=>(remote), "installed <=> remote")
diff --git a/test/rubygems/test_gem_source_list.rb b/test/rubygems/test_gem_source_list.rb
index 9fd1b3bdf9..64353f8f90 100644
--- a/test/rubygems/test_gem_source_list.rb
+++ b/test/rubygems/test_gem_source_list.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "rubygems"
require "rubygems/source_list"
require_relative "helper"
@@ -36,7 +37,7 @@ class TestGemSourceList < Gem::TestCase
assert_kind_of Gem::Source, source
- assert_kind_of URI, source.uri
+ assert_kind_of Gem::URI, source.uri
assert_equal source.uri.to_s, @uri
assert_equal [source], sl.sources
@@ -98,7 +99,7 @@ class TestGemSourceList < Gem::TestCase
def test_include_eh
assert @sl.include?(@uri), "string comparison not working"
- assert @sl.include?(URI.parse(@uri)), "uri comparison not working"
+ assert @sl.include?(Gem::URI.parse(@uri)), "uri comparison not working"
end
def test_include_matches_a_source
diff --git a/test/rubygems/test_gem_source_local.rb b/test/rubygems/test_gem_source_local.rb
index ace3923009..c15e0e07c0 100644
--- a/test/rubygems/test_gem_source_local.rb
+++ b/test/rubygems/test_gem_source_local.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/source"
@@ -72,7 +73,7 @@ class TestGemSourceLocal < Gem::TestCase
@sl.load_specs :released
- inner = [@a, @ap, @b].map {|t| t.name_tuple }.inspect
+ inner = [@a, @ap, @b].map(&:name_tuple).inspect
assert_equal "#<Gem::Source::Local specs: #{inner}>", @sl.inspect
end
@@ -92,7 +93,7 @@ class TestGemSourceLocal < Gem::TestCase
installed = Gem::Source::Installed.new
local = Gem::Source::Local.new
- assert_equal(0, local.<=>(local), "local <=> local")
+ assert_equal(0, local.<=>(local), "local <=> local") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(-1, remote.<=>(local), "remote <=> local")
assert_equal(1, local.<=>(remote), "local <=> remote")
diff --git a/test/rubygems/test_gem_source_lock.rb b/test/rubygems/test_gem_source_lock.rb
index ff9465d0ad..91ffee68f2 100644
--- a/test/rubygems/test_gem_source_lock.rb
+++ b/test/rubygems/test_gem_source_lock.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemSourceLock < Gem::TestCase
@@ -18,7 +19,7 @@ class TestGemSourceLock < Gem::TestCase
end
def test_equals2
- git = Gem::Source::Git.new "a", "git/a", "master", false
+ git = Gem::Source::Git.new "a", "git/a", nil, false
g_lock = Gem::Source::Lock.new git
installed = Gem::Source::Installed.new
@@ -30,7 +31,7 @@ class TestGemSourceLock < Gem::TestCase
end
def test_spaceship
- git = Gem::Source::Git.new "a", "git/a", "master", false
+ git = Gem::Source::Git.new "a", "git/a", nil, false
g_lock = Gem::Source::Lock.new git
installed = Gem::Source::Installed.new
@@ -39,9 +40,11 @@ class TestGemSourceLock < Gem::TestCase
vendor = Gem::Source::Vendor.new "vendor/a"
v_lock = Gem::Source::Lock.new vendor
+ # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(0, g_lock.<=>(g_lock), "g_lock <=> g_lock")
assert_equal(0, i_lock.<=>(i_lock), "i_lock <=> i_lock")
assert_equal(0, v_lock.<=>(v_lock), "v_lock <=> v_lock")
+ # rubocop:enable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(1, g_lock.<=>(i_lock), "g_lock <=> i_lock")
assert_equal(-1, i_lock.<=>(g_lock), "i_lock <=> g_lock")
@@ -54,7 +57,7 @@ class TestGemSourceLock < Gem::TestCase
end
def test_spaceship_git
- git = Gem::Source::Git.new "a", "git/a", "master", false
+ git = Gem::Source::Git.new "a", "git/a", nil, false
lock = Gem::Source::Lock.new git
assert_equal(1, lock.<=>(git), "lock <=> git")
@@ -107,6 +110,6 @@ class TestGemSourceLock < Gem::TestCase
remote = Gem::Source.new @gem_repo
lock = Gem::Source::Lock.new remote
- assert_equal URI(@gem_repo), lock.uri
+ assert_equal Gem::URI(@gem_repo), lock.uri
end
end
diff --git a/test/rubygems/test_gem_source_specific_file.rb b/test/rubygems/test_gem_source_specific_file.rb
index f9a572b76d..3bc1901ee1 100644
--- a/test/rubygems/test_gem_source_specific_file.rb
+++ b/test/rubygems/test_gem_source_specific_file.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/source"
@@ -45,7 +46,7 @@ class TestGemSourceSpecificFile < Gem::TestCase
installed = Gem::Source::Installed.new
local = Gem::Source::Local.new
- assert_equal(0, specific.<=>(specific), "specific <=> specific")
+ assert_equal(0, specific.<=>(specific), "specific <=> specific") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(-1, remote.<=>(specific), "remote <=> specific")
assert_equal(1, specific.<=>(remote), "specific <=> remote")
@@ -69,7 +70,7 @@ class TestGemSourceSpecificFile < Gem::TestCase
assert_nil a1_source.<=>(b1_source), "a1_source <=> b1_source"
assert_equal(-1, a1_source.<=>(a2_source), "a1_source <=> a2_source")
- assert_equal(0, a1_source.<=>(a1_source), "a1_source <=> a1_source")
+ assert_equal(0, a1_source.<=>(a1_source), "a1_source <=> a1_source") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(1, a2_source.<=>(a1_source), "a2_source <=> a1_source")
end
end
diff --git a/test/rubygems/test_gem_source_subpath_problem.rb b/test/rubygems/test_gem_source_subpath_problem.rb
index 219c344290..a451a81a25 100644
--- a/test/rubygems/test_gem_source_subpath_problem.rb
+++ b/test/rubygems/test_gem_source_subpath_problem.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/source"
@@ -20,8 +21,8 @@ class TestGemSourceSubpathProblem < Gem::TestCase
end
def test_dependency_resolver_set
- response = Net::HTTPResponse.new "1.1", 200, "OK"
- response.uri = URI("http://example")
+ response = Gem::Net::HTTPResponse.new "1.1", 200, "OK"
+ response.uri = Gem::URI("http://example")
@fetcher.data["#{@gem_repo}/"] = response
@@ -43,7 +44,7 @@ class TestGemSourceSubpathProblem < Gem::TestCase
Gem::NameTuple.new(@b2.name, @b2.version, "ruby"),
]))
- released = @source.load_specs(:latest).map {|spec| spec.full_name }
+ released = @source.load_specs(:latest).map(&:full_name)
assert_equal %W[a-1 b-2], released
end
end
diff --git a/test/rubygems/test_gem_source_vendor.rb b/test/rubygems/test_gem_source_vendor.rb
index 29846e5c13..2543871439 100644
--- a/test/rubygems/test_gem_source_vendor.rb
+++ b/test/rubygems/test_gem_source_vendor.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/source"
@@ -12,10 +13,10 @@ class TestGemSourceVendor < Gem::TestCase
def test_spaceship
vendor = Gem::Source::Vendor.new "vendor/foo"
remote = Gem::Source.new @gem_repo
- git = Gem::Source::Git.new "a", "a", "master"
+ git = Gem::Source::Git.new "a", "a", nil
installed = Gem::Source::Installed.new
- assert_equal(0, vendor.<=>(vendor), "vendor <=> vendor")
+ assert_equal(0, vendor.<=>(vendor), "vendor <=> vendor") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(1, vendor.<=>(remote), "vendor <=> remote")
assert_equal(-1, remote.<=>(vendor), "remote <=> vendor")
diff --git a/test/rubygems/test_gem_spec_fetcher.rb b/test/rubygems/test_gem_spec_fetcher.rb
index f23a93350b..cb4a4f7204 100644
--- a/test/rubygems/test_gem_spec_fetcher.rb
+++ b/test/rubygems/test_gem_spec_fetcher.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/spec_fetcher"
@@ -10,7 +11,7 @@ class TestGemSpecFetcher < Gem::TestCase
def setup
super
- @uri = URI.parse @gem_repo
+ @uri = Gem::URI.parse @gem_repo
@source = Gem::Source.new(@uri)
@sf = Gem::SpecFetcher.new
@@ -40,12 +41,12 @@ class TestGemSpecFetcher < Gem::TestCase
def test_initialize_unwritable_home_dir
pend "chmod not supported" if Gem.win_platform?
- FileUtils.chmod 0000, Gem.user_home
+ FileUtils.chmod 0o000, Gem.user_home
begin
assert Gem::SpecFetcher.new
ensure
- FileUtils.chmod 0755, Gem.user_home
+ FileUtils.chmod 0o755, Gem.user_home
end
end
@@ -108,9 +109,7 @@ class TestGemSpecFetcher < Gem::TestCase
def test_spec_for_dependency_platform
util_set_arch "i386-linux"
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
dep = Gem::Dependency.new "pl", 1
specs_and_sources, _ = @sf.spec_for_dependency dep
@@ -126,9 +125,7 @@ class TestGemSpecFetcher < Gem::TestCase
def test_spec_for_dependency_mismatched_platform
util_set_arch "hrpa-989"
- spec_fetcher do |fetcher|
- fetcher.legacy_platform
- end
+ spec_fetcher(&:legacy_platform)
dep = Gem::Dependency.new "pl", 1
specs_and_sources, errors = @sf.spec_for_dependency dep
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb
index 8ce8293f33..9e05649f7c 100644
--- a/test/rubygems/test_gem_specification.rb
+++ b/test/rubygems/test_gem_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "benchmark"
require_relative "helper"
require "date"
@@ -10,7 +11,7 @@ require "rubygems/installer"
require "rubygems/platform"
class TestGemSpecification < Gem::TestCase
- LEGACY_YAML_SPEC = <<-EOF.freeze
+ LEGACY_YAML_SPEC = <<-EOF
--- !ruby/object:Gem::Specification
rubygems_version: "1.0"
name: keyedlist
@@ -29,7 +30,7 @@ email: flgr@ccan.de
has_rdoc: true
EOF
- LEGACY_RUBY_SPEC = <<-EOF.freeze
+ LEGACY_RUBY_SPEC = <<-EOF
Gem::Specification.new do |s|
s.name = %q{keyedlist}
s.version = %q{0.4.0}
@@ -89,6 +90,7 @@ end
Gem.instance_variable_set(:'@default_source_date_epoch', nil)
@a1 = util_spec "a", "1" do |s|
+ s.required_ruby_version = ">= 2.3.0"
s.executable = "exec"
s.test_file = "test/suite.rb"
s.requirements << "A working computer"
@@ -691,7 +693,7 @@ end
version
]
- actual_value = Gem::Specification.attribute_names.map {|a| a.to_s }.sort
+ actual_value = Gem::Specification.attribute_names.map(&:to_s).sort
assert_equal expected_value, actual_value
end
@@ -796,26 +798,6 @@ dependencies: []
assert_equal File.join(@tempdir, "a-2.gemspec"), spec.loaded_from
end
- if RUBY_ENGINE == "ruby" && RUBY_VERSION < "2.7"
- def test_self_load_tainted
- full_path = @a2.spec_file
- write_file full_path do |io|
- io.write @a2.to_ruby_for_cache
- end
-
- full_path.taint
- loader = Thread.new { $SAFE = 1; Gem::Specification.load full_path }
- spec = loader.value
-
- @a2.files.clear
-
- assert_equal @a2, spec
-
- ensure
- $SAFE = 0
- end
- end
-
def test_self_load_escape_curly
@a2.name = 'a};raise "improper escaping";%q{'
@@ -962,13 +944,13 @@ dependencies: []
install_specs @a1
assert_includes Gem::Specification.all_names, "a-1"
- assert_includes Gem::Specification.stubs.map {|s| s.full_name }, "a-1"
+ assert_includes Gem::Specification.stubs.map(&:full_name), "a-1"
uninstall_gem @a1
Gem::Specification.reset
refute_includes Gem::Specification.all_names, "a-1"
- refute_includes Gem::Specification.stubs.map {|s| s.full_name }, "a-1"
+ refute_includes Gem::Specification.stubs.map(&:full_name), "a-1"
end
def test_self_remove_spec_removed
@@ -983,7 +965,7 @@ dependencies: []
Gem::Specification.reset
refute_includes Gem::Specification.all_names, "a-1"
- refute_includes Gem::Specification.stubs.map {|s| s.full_name }, "a-1"
+ refute_includes Gem::Specification.stubs.map(&:full_name), "a-1"
end
def test_self_stubs_for_lazy_loading
@@ -995,14 +977,14 @@ dependencies: []
save_gemspec("a-1", "1", dir_standard_specs) {|s| s.name = "a" }
save_gemspec("b-1", "1", dir_standard_specs) {|s| s.name = "b" }
- assert_equal ["a-1"], Gem::Specification.stubs_for("a").map {|s| s.full_name }
+ 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 ["b-1"], Gem::Specification.stubs_for("b").map {|s| s.full_name }
+ 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(
- Gem::Specification.stubs_for("a").map {|s| s.object_id },
- Gem::Specification.stubs_for("a").map {|s| s.object_id }
+ Gem::Specification.stubs_for("a").map(&:object_id),
+ Gem::Specification.stubs_for("a").map(&:object_id)
)
Gem.loaded_specs.delete "a"
@@ -1015,7 +997,7 @@ dependencies: []
save_gemspec("b-1", "1", File.join(Gem.dir, "specifications")) {|s| s.name = "b" }
- assert_equal [], Gem::Specification.stubs_for("b").map {|s| s.full_name }
+ assert_equal [], Gem::Specification.stubs_for("b").map(&:full_name)
end
def test_self_stubs_for_mult_platforms
@@ -1034,7 +1016,7 @@ dependencies: []
v = "1.1.1"
platforms = ["x86-mingw32", "x64-mingw32"]
- #create specs
+ # create specs
platforms.each do |plat|
spec = Gem::Specification.new(gem, v) {|s| s.platform = plat }
File.open File.join(user_spec_dir, "#{gem}-#{v}-#{plat}.gemspec"), "w" do |io|
@@ -1068,19 +1050,46 @@ dependencies: []
end
def test_handles_private_null_type
+ yaml_defined = Object.const_defined?("YAML")
+
path = File.expand_path "data/pry-0.4.7.gemspec.rz", __dir__
data = Marshal.load Gem::Util.inflate(Gem.read_binary(path))
assert_instance_of Gem::Specification, data
+
+ assert_equal(yaml_defined, Object.const_defined?("YAML"))
end
def test_handles_dependencies_with_syck_requirements_bug
+ yaml_defined = Object.const_defined?("YAML")
+
path = File.expand_path "data/excon-0.7.7.gemspec.rz", __dir__
data = Marshal.load Gem::Util.inflate(Gem.read_binary(path))
assert_instance_of Gem::Specification, data
+
+ assert_equal(yaml_defined, Object.const_defined?("YAML"))
+ end
+
+ def test_handles_dependencies_with_other_syck_requirements_argument_error
+ yaml_defined = Object.const_defined?("YAML")
+
+ data = Marshal.dump(Gem::Specification.new do |s|
+ v = Gem::Version.allocate
+ v.instance_variable_set :@version, "YAML::Syck::DefaultKey"
+ s.instance_variable_set :@version, v
+ end)
+
+ assert_raise(ArgumentError) { Marshal.load(data) }
+ out, err = capture_output do
+ assert_raise(ArgumentError) { Marshal.load(data) }
+ end
+ assert_empty out
+ assert_empty err
+
+ assert_equal(yaml_defined, Object.const_defined?("YAML"))
end
def test_initialize
@@ -1186,10 +1195,13 @@ dependencies: []
assert_same spec.bindir, dup_spec.bindir
assert_equal ">= 0", spec.required_ruby_version.to_s
- assert_same spec.required_ruby_version, dup_spec.required_ruby_version
+ assert_equal spec.required_ruby_version, dup_spec.required_ruby_version
+ refute_same spec.required_ruby_version, dup_spec.required_ruby_version
assert_equal ">= 0", spec.required_rubygems_version.to_s
- assert_same spec.required_rubygems_version,
+ assert_equal spec.required_rubygems_version,
+ dup_spec.required_rubygems_version
+ refute_same spec.required_rubygems_version,
dup_spec.required_rubygems_version
end
@@ -1199,7 +1211,7 @@ dependencies: []
s.version = "1"
end
- spec.instance_variable_set :@licenses, (class << (Object.new);self;end)
+ spec.instance_variable_set :@licenses, (class << Object.new;self;end)
spec.loaded_from = "/path/to/file"
e = assert_raise Gem::FormatException do
@@ -1252,7 +1264,7 @@ dependencies: []
awesome.add_dependency :gem_name
end
- assert_equal %w[true gem_name], gem.dependencies.map {|dep| dep.name }
+ assert_equal %w[true gem_name], gem.dependencies.map(&:name)
end
def test_add_dependency_from_existing_dependency
@@ -1322,9 +1334,7 @@ dependencies: []
assert_empty @ext.build_args
- File.open @ext.build_info_file, "w" do |io|
- io.puts
- end
+ File.open @ext.build_info_file, "w", &:puts
assert_empty @ext.build_args
@@ -1444,15 +1454,15 @@ dependencies: []
end
FileUtils.mkdir_p File.join @ext.base_dir, "extensions"
- FileUtils.chmod 0555, @ext.base_dir
- FileUtils.chmod 0555, File.join(@ext.base_dir, "extensions")
+ FileUtils.chmod 0o555, @ext.base_dir
+ FileUtils.chmod 0o555, File.join(@ext.base_dir, "extensions")
@ext.build_extensions
assert_path_not_exist @ext.extension_dir
ensure
- unless ($DEBUG || win_platform? || Process.uid.zero? || Gem.java_platform?)
- FileUtils.chmod 0755, File.join(@ext.base_dir, "extensions")
- FileUtils.chmod 0755, @ext.base_dir
+ unless $DEBUG || Gem.win_platform? || Process.uid.zero? || Gem.java_platform?
+ FileUtils.chmod 0o755, File.join(@ext.base_dir, "extensions")
+ FileUtils.chmod 0o755, @ext.base_dir
end
end
@@ -1477,14 +1487,14 @@ dependencies: []
end
FileUtils.rm_r File.join @gemhome, "extensions"
- FileUtils.chmod 0555, @gemhome
+ FileUtils.chmod 0o555, @gemhome
@ext.build_extensions
gem_make_out = File.join @ext.extension_dir, "gem_make.out"
assert_path_not_exist gem_make_out
ensure
- FileUtils.chmod 0755, @gemhome
+ FileUtils.chmod 0o755, @gemhome
end
def test_build_extensions_none
@@ -1539,7 +1549,7 @@ dependencies: []
refute @ext.contains_requirable_file? "nonexistent"
end
- expected = "Ignoring ext-1 because its extensions are not built. " +
+ expected = "Ignoring ext-1 because its extensions are not built. " \
"Try: gem pristine ext --version 1\n"
assert_equal expected, err
@@ -1555,6 +1565,17 @@ dependencies: []
assert_empty err
end
+ def test_contains_requirable_file_extension_soext
+ ext_spec
+ dlext = RbConfig::CONFIG["DLEXT"]
+ @ext.files += ["lib/ext.#{dlext}"]
+
+ FileUtils.mkdir_p @ext.extension_dir
+ FileUtils.touch File.join(@ext.extension_dir, "ext.#{dlext}")
+ FileUtils.touch File.join(@ext.extension_dir, "gem.build_complete")
+ assert @ext.contains_requirable_file? "ext.so"
+ end
+
def test_date
assert_date @a1.date
end
@@ -1592,12 +1613,12 @@ dependencies: []
def test_date_tolerates_hour_sec_zulu
@a1.date = "2012-01-12 11:22:33.4444444 Z"
- assert_equal Time.utc(2012,01,12,0,0,0), @a1.date
+ assert_equal Time.utc(2012,1,12,0,0,0), @a1.date
end
def test_date_tolerates_hour_sec_and_timezone
@a1.date = "2012-01-12 11:22:33.4444444 +02:33"
- assert_equal Time.utc(2012,01,12,0,0,0), @a1.date
+ assert_equal Time.utc(2012,1,12,0,0,0), @a1.date
end
def test_date_use_env_source_date_epoch
@@ -1684,8 +1705,8 @@ dependencies: []
end
def test_extension_dir
- enable_shared, RbConfig::CONFIG["ENABLE_SHARED"] =
- RbConfig::CONFIG["ENABLE_SHARED"], "no"
+ enable_shared = RbConfig::CONFIG["ENABLE_SHARED"]
+ RbConfig::CONFIG["ENABLE_SHARED"] = "no"
ext_spec
@@ -1701,11 +1722,11 @@ dependencies: []
end
def test_extension_dir_override
- enable_shared, RbConfig::CONFIG["ENABLE_SHARED"] =
- RbConfig::CONFIG["ENABLE_SHARED"], "no"
+ enable_shared = RbConfig::CONFIG["ENABLE_SHARED"]
+ RbConfig::CONFIG["ENABLE_SHARED"] = "no"
class << Gem
- alias orig_default_ext_dir_for default_ext_dir_for
+ alias_method :orig_default_ext_dir_for, :default_ext_dir_for
remove_method :default_ext_dir_for
@@ -1727,7 +1748,7 @@ dependencies: []
class << Gem
remove_method :default_ext_dir_for
- alias default_ext_dir_for orig_default_ext_dir_for
+ alias_method :default_ext_dir_for, :orig_default_ext_dir_for
end
end
@@ -1839,7 +1860,7 @@ dependencies: []
end
def test_full_gem_path_double_slash
- gemhome = @gemhome.to_s.sub(/\w\//, '\&/')
+ gemhome = @gemhome.to_s.sub(%r{\w/}, '\&/')
@a1.loaded_from = File.join gemhome, "specifications", @a1.spec_name
expected = File.join @gemhome, "gems", @a1.full_name
@@ -1857,7 +1878,7 @@ dependencies: []
@a1.instance_variable_set :@new_platform, "mswin32"
assert_equal "a-1-mswin32", @a1.full_name, "legacy"
- return if win_platform?
+ return if Gem.win_platform?
@a1 = Gem::Specification.new "a", 1
@a1.platform = "current"
@@ -1866,9 +1887,9 @@ dependencies: []
def test_full_name_windows
test_cases = {
- "i386-mswin32" => "a-1-x86-mswin32-60",
- "i386-mswin32_80" => "a-1-x86-mswin32-80",
- "i386-mingw32" => "a-1-x86-mingw32",
+ "i386-mswin32" => "a-1-x86-mswin32-60",
+ "i386-mswin32_80" => "a-1-x86-mswin32-80",
+ "i386-mingw32" => "a-1-x86-mingw32",
}
test_cases.each do |arch, expected|
@@ -1969,10 +1990,10 @@ dependencies: []
assert_equal Gem::Platform::RUBY, @a1.platform
test_cases = {
- "i386-mswin32" => ["x86", "mswin32", "60"],
+ "i386-mswin32" => ["x86", "mswin32", "60"],
"i386-mswin32_80" => ["x86", "mswin32", "80"],
- "i386-mingw32" => ["x86", "mingw32", nil ],
- "x86-darwin8" => ["x86", "darwin", "8" ],
+ "i386-mingw32" => ["x86", "mingw32", nil],
+ "x86-darwin8" => ["x86", "darwin", "8"],
}
test_cases.each do |arch, expected|
@@ -1999,12 +2020,6 @@ dependencies: []
assert_equal Gem::Platform.new("ppc-darwin"), @a1.platform
end
- def test_prerelease_spec_adds_required_rubygems_version
- @prerelease = util_spec("tardis", "2.2.0.a")
- refute @prerelease.required_rubygems_version.satisfied_by?(Gem::Version.new("1.3.1"))
- assert @prerelease.required_rubygems_version.satisfied_by?(Gem::Version.new("1.4.0"))
- end
-
def test_require_paths
enable_shared "no" do
ext_spec
@@ -2186,7 +2201,7 @@ dependencies: []
expected = %w[rake jabber4r pqa]
- assert_equal expected, @c1.runtime_dependencies.map {|d| d.name }
+ assert_equal expected, @c1.runtime_dependencies.map(&:name)
end
def test_spaceship_name
@@ -2194,7 +2209,7 @@ dependencies: []
s2 = util_spec "b", "1"
assert_equal(-1, (s1 <=> s2))
- assert_equal(0, (s1 <=> s1))
+ assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(1, (s2 <=> s1))
end
@@ -2205,7 +2220,7 @@ dependencies: []
end
assert_equal(-1, (s1 <=> s2))
- assert_equal(0, (s1 <=> s1))
+ assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(1, (s2 <=> s1))
end
@@ -2214,7 +2229,7 @@ dependencies: []
s2 = util_spec "a", "2"
assert_equal(-1, (s1 <=> s2))
- assert_equal(0, (s1 <=> s1))
+ assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
assert_equal(1, (s2 <=> s1))
end
@@ -2263,7 +2278,7 @@ dependencies: []
Gem::Specification.new do |s|
s.name = "a".freeze
- s.version = "2"
+ s.version = "2".freeze
s.required_rubygems_version = Gem::Requirement.new(\"> 0\".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze, "other".freeze]
@@ -2278,7 +2293,7 @@ Gem::Specification.new do |s|
s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}
- s.add_runtime_dependency(%q<b>.freeze, [\"= 1\"])
+ s.add_runtime_dependency(%q<b>.freeze, [\"= 1\".freeze])
end
SPEC
@@ -2303,7 +2318,7 @@ end
Gem::Specification.new do |s|
s.name = "a".freeze
- s.version = "2"
+ s.version = "2".freeze
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
@@ -2336,7 +2351,7 @@ end
Gem::Specification.new do |s|
s.name = "a".freeze
- s.version = "2"
+ s.version = "2".freeze
s.required_rubygems_version = Gem::Requirement.new(\"> 0\".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
@@ -2348,11 +2363,11 @@ Gem::Specification.new do |s|
s.rubygems_version = "#{Gem::VERSION}".freeze
s.summary = "this is a summary".freeze
- s.installed_by_version = "#{Gem::VERSION}" if s.respond_to? :installed_by_version
+ s.installed_by_version = "#{Gem::VERSION}".freeze if s.respond_to? :installed_by_version
s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION}
- s.add_runtime_dependency(%q<b>.freeze, [\"= 1\"])
+ s.add_runtime_dependency(%q<b>.freeze, ["= 1".freeze])
end
SPEC
@@ -2372,19 +2387,19 @@ end
ruby_code = @c1.to_ruby
local = Gem::Platform.local
- expected_platform = "[#{local.cpu.inspect}, #{local.os.inspect}, #{local.version.inspect}]"
+ expected_platform = "[#{local.cpu.inspect}.freeze, #{local.os.inspect}.freeze, #{local.version.inspect}.freeze]"
stub_require_paths =
@c1.instance_variable_get(:@require_paths).join "\u0000"
extensions = @c1.extensions.join "\u0000"
expected = <<-SPEC
# -*- encoding: utf-8 -*-
-# stub: a 1 #{win_platform? ? "x86-mswin32-60" : "x86-darwin-8"} #{stub_require_paths}
+# stub: a 1 #{Gem.win_platform? ? "x86-mswin32-60" : "x86-darwin-8"} #{stub_require_paths}
# stub: #{extensions}
Gem::Specification.new do |s|
s.name = "a".freeze
- s.version = "1"
+ s.version = "1".freeze
s.platform = Gem::Platform.new(#{expected_platform})
s.required_rubygems_version = Gem::Requirement.new(\">= 0\".freeze) if s.respond_to? :required_rubygems_version=
@@ -2405,9 +2420,9 @@ Gem::Specification.new do |s|
s.specification_version = 4
- s.add_runtime_dependency(%q<rake>.freeze, [\"> 0.4\"])
- s.add_runtime_dependency(%q<jabber4r>.freeze, [\"> 0.0.0\"])
- s.add_runtime_dependency(%q<pqa>.freeze, [\"> 0.4\", \"<= 0.6\"])
+ s.add_runtime_dependency(%q<rake>.freeze, [\"> 0.4\".freeze])
+ s.add_runtime_dependency(%q<jabber4r>.freeze, [\"> 0.0.0\".freeze])
+ s.add_runtime_dependency(%q<pqa>.freeze, [\"> 0.4\".freeze, \"<= 0.6\".freeze])
end
SPEC
@@ -2423,7 +2438,7 @@ end
s.add_dependency "b", ["~> 1.0", ">= 1.0.0"]
end
- assert_includes spec.to_ruby, '"~> 1.0", ">= 1.0.0"'
+ assert_includes spec.to_ruby, '"~> 1.0".freeze, ">= 1.0.0".freeze'
end
def test_to_ruby_legacy
@@ -2438,13 +2453,13 @@ end
def test_to_ruby_nested_hash
metadata = {}
- metadata[metadata] = metadata
+ metadata[:metadata] = {}
@a2.metadata = metadata
ruby = @a2.to_ruby
- assert_match %r%^ s\.metadata = \{ "%, ruby
+ assert_match(/^ s\.metadata = \{ "/, ruby)
end
def test_to_ruby_platform
@@ -2461,7 +2476,7 @@ end
def test_to_yaml
yaml_str = @a1.to_yaml
- refute_match %r{!!null}, yaml_str
+ refute_match(/!!null/, yaml_str)
same_spec = Gem::Specification.from_yaml(yaml_str)
@@ -2482,7 +2497,7 @@ end
def test_to_yaml_platform_empty_string
@a1.instance_variable_set :@original_platform, ""
- assert_match %r{^platform: ruby$}, @a1.to_yaml
+ assert_match(/^platform: ruby$/, @a1.to_yaml)
end
def test_to_yaml_platform_legacy
@@ -2500,7 +2515,27 @@ end
def test_to_yaml_platform_nil
@a1.instance_variable_set :@original_platform, nil
- assert_match %r{^platform: ruby$}, @a1.to_yaml
+ assert_match(/^platform: ruby$/, @a1.to_yaml)
+ end
+
+ def test_to_yaml_no_autorequire
+ yaml_str = @a1.to_yaml
+
+ refute_match(/^autorequire:/, yaml_str)
+ end
+
+ def test_to_yaml_no_signing_key
+ @a1.signing_key = nil
+ yaml_str = @a1.to_yaml
+
+ refute_match(/^signing_key:/, yaml_str)
+ end
+
+ def test_to_yaml_no_post_install_message
+ @a1.post_install_message = nil
+ yaml_str = @a1.to_yaml
+
+ refute_match(/^post_install_message:/, yaml_str)
end
def test_validate
@@ -2511,10 +2546,21 @@ end
end
end
- def x(s); s.gsub(/xxx/, ""); end
- def w; x "WARxxxNING"; end
- def t; x "TOxxxDO"; end
- def f; x "FxxxIXME"; end
+ def x(s)
+ s.gsub(/xxx/, "")
+ end
+
+ def w
+ x "WARxxxNING"
+ end
+
+ def t
+ x "TOxxxDO"
+ end
+
+ def f
+ x "FxxxIXME"
+ end
def test_validate_authors
util_setup_validate
@@ -2598,18 +2644,18 @@ end
#{w}: prerelease dependency on c (>= 2.0.rc2, development) is not recommended
#{w}: open-ended dependency on i (>= 1.2) is not recommended
if i is semantically versioned, use:
- add_runtime_dependency 'i', '~> 1.2'
+ add_runtime_dependency "i", "~> 1.2"
#{w}: open-ended dependency on j (>= 1.2.3) is not recommended
if j is semantically versioned, use:
- add_runtime_dependency 'j', '~> 1.2', '>= 1.2.3'
+ add_runtime_dependency "j", "~> 1.2", ">= 1.2.3"
#{w}: open-ended dependency on k (> 1.2) is not recommended
if k is semantically versioned, use:
- add_runtime_dependency 'k', '~> 1.2', '> 1.2'
+ add_runtime_dependency "k", "~> 1.2", "> 1.2"
#{w}: open-ended dependency on l (> 1.2.3) is not recommended
if l is semantically versioned, use:
- add_runtime_dependency 'l', '~> 1.2', '> 1.2.3'
+ add_runtime_dependency "l", "~> 1.2", "> 1.2.3"
#{w}: open-ended dependency on o (>= 0) is not recommended
- use a bounded requirement, such as '~> x.y'
+ use a bounded requirement, such as "~> x.y"
#{w}: See https://guides.rubygems.org/specification-reference/ for help
EXPECTED
@@ -2633,9 +2679,9 @@ end
expected = <<-EXPECTED
duplicate dependency on b (>= 1.2.3), (~> 1.2) use:
- add_runtime_dependency 'b', '>= 1.2.3', '~> 1.2'
+ add_runtime_dependency "b", ">= 1.2.3", "~> 1.2"
duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
- add_development_dependency 'c', '>= 1.2.3', '~> 1.2'
+ add_development_dependency "c", ">= 1.2.3", "~> 1.2"
EXPECTED
assert_equal expected, e.message
@@ -2662,6 +2708,53 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
end
end
+ def test_validate_no_required_ruby_versions
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ use_ui @ui do
+ @a1.required_ruby_version = nil # reset
+ @a1.validate
+ end
+
+ assert_equal <<-EXPECTED, @ui.error
+#{w}: make sure you specify the oldest ruby version constraint (like \">= 3.0\") that you want your gem to support by setting the `required_ruby_version` gemspec attribute
+#{w}: See https://guides.rubygems.org/specification-reference/ for help
+ EXPECTED
+ end
+ end
+
+ def test_validate_open_required_ruby_versions
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.required_ruby_version = ">= 0"
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal <<-EXPECTED, @ui.error
+#{w}: make sure you specify the oldest ruby version constraint (like \">= 3.0\") that you want your gem to support by setting the `required_ruby_version` gemspec attribute
+#{w}: See https://guides.rubygems.org/specification-reference/ for help
+ EXPECTED
+ end
+ end
+
+ def test_validate_valid_required_ruby_versions
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.required_ruby_version = ">= 2.3.0"
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal "", @ui.error, "warning"
+ end
+ end
+
def test_validate_prerelease_dependencies_with_prerelease_version
util_setup_validate
@@ -2677,6 +2770,23 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
end
end
+ def test_validate_self_referencing_dependencies
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.add_runtime_dependency @a1.name, "1"
+
+ use_ui @ui do
+ @a1.validate
+ end
+
+ assert_equal <<-EXPECTED, @ui.error
+#{w}: Self referencing dependency is unnecessary and strongly discouraged.
+#{w}: See https://guides.rubygems.org/specification-reference/ for help
+ EXPECTED
+ end
+ end
+
def test_validate_rake_extension_have_rake_dependency_warning
util_setup_validate
@@ -2688,7 +2798,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
@a1.validate
end
- assert_match(/add rake as a dependency/, @ui.error)
+ assert_match(/add rake as a runtime dependency/, @ui.error)
end
end
@@ -2704,7 +2814,40 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
@a1.validate
end
- refute_match(/add rake as a dependency/, @ui.error)
+ refute_match(/add rake as a runtime dependency/, @ui.error)
+ end
+ end
+
+ def test_validate_rust_extension_have_missing_cargo_toml_error
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.extensions = ["Cargo.toml"]
+ File.write File.join(@tempdir, "Cargo.toml"), ""
+
+ e = assert_raise Gem::InvalidSpecificationException do
+ use_ui @ui do
+ @a1.validate
+ end
+ end
+
+ assert_match(/but Cargo.lock is not part of the gem files/, e.message)
+ end
+ end
+
+ def test_validate_rust_extension_have_no_missing_cargo_toml_error
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @a1.extensions = ["Cargo.toml"]
+ @a1.files << "Cargo.toml"
+ @a1.files << "Cargo.lock"
+ File.write File.join(@tempdir, "Cargo.toml"), ""
+ File.write File.join(@tempdir, "Cargo.lock"), ""
+
+ use_ui @ui do
+ @a1.validate
+ end
end
end
@@ -2835,7 +2978,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
end
def test_validate_empty_require_paths
- if win_platform?
+ if Gem.win_platform?
pend "test_validate_empty_require_paths skipped on MS Windows (symlink)"
else
util_setup_validate
@@ -2851,7 +2994,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
end
def test_validate_files
- pend "test_validate_files skipped on MS Windows (symlink)" if win_platform?
+ pend "test_validate_files skipped on MS Windows (symlink)" if Gem.win_platform?
util_setup_validate
@a1.files += ["lib", "lib2"]
@@ -2880,7 +3023,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use:
{ b: Gem::Dependency.new("x","1") }
end
- specification.define_singleton_method(:find_all_by_name) do |dep_name|
+ specification.define_singleton_method(:find_all_by_name) do |_dep_name|
[]
end
@@ -2907,7 +3050,7 @@ Please report a bug if this causes problems.
{ b: Gem::Dependency.new("x","1") }
end
- specification.define_singleton_method(:find_all_by_name) do |dep_name|
+ specification.define_singleton_method(:find_all_by_name) do |_dep_name|
[
specification.new {|s| s.name = "z", s.version = Gem::Version.new("1") },
specification.new {|s| s.name = "z", s.version = Gem::Version.new("2") },
@@ -2942,7 +3085,7 @@ Please report a bug if this causes problems.
def set_orig(cls)
s_cls = cls.singleton_class
- s_cls.send :alias_method, :orig_unresolved_deps , :unresolved_deps
+ s_cls.send :alias_method, :orig_unresolved_deps, :unresolved_deps
s_cls.send :alias_method, :orig_find_all_by_name, :find_all_by_name
end
@@ -3015,11 +3158,23 @@ Please report a bug if this causes problems.
end
assert_match <<-WARNING, @ui.error
-WARNING: licenses is empty, but is recommended. Use a license identifier from
-http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
+WARNING: licenses is empty, but is recommended. Use an license identifier from
+https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,
+or set it to nil if you don't want to specify a license.
WARNING
end
+ def test_validate_nil_license
+ util_setup_validate
+
+ use_ui @ui do
+ @a1.license = nil
+ @a1.validate
+ end
+
+ assert_empty @ui.error
+ end
+
def test_validate_license_in_a_non_packaging_context
util_setup_validate
@@ -3055,8 +3210,9 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
end
assert_match <<-WARNING, @ui.error
-WARNING: license value 'BSD' is invalid. Use a license identifier from
-http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
+WARNING: License identifier 'BSD' is invalid. Use an identifier from
+https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,
+or set it to nil if you don't want to specify a license.
WARNING
end
@@ -3071,7 +3227,7 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
assert_empty @ui.error
end
- def test_validate_license_values_plus
+ def test_validate_deprecated_license_values_plus
util_setup_validate
use_ui @ui do
@@ -3079,7 +3235,11 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
@a1.validate
end
- assert_empty @ui.error
+ assert_match <<-WARNING, @ui.error
+WARNING: License identifier 'GPL-2.0+' is deprecated. Use an identifier from
+https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,
+or set it to nil if you don't want to specify a license.
+ WARNING
end
def test_validate_license_values_or_later
@@ -3097,7 +3257,7 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
util_setup_validate
use_ui @ui do
- @a1.licenses = ["GPL-2.0+ WITH Autoconf-exception-2.0"]
+ @a1.licenses = ["GPL-2.0-or-later WITH Autoconf-exception-2.0"]
@a1.validate
end
@@ -3113,12 +3273,14 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
end
assert_match <<-WARNING, @ui.error
-WARNING: license value 'GPL-2.0+ FOO' is invalid. Use a license identifier from
-http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
+WARNING: License identifier 'GPL-2.0+ FOO' is invalid. Use an identifier from
+https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,
+or set it to nil if you don't want to specify a license.
WARNING
assert_match <<-WARNING, @ui.error
-WARNING: license value 'GPL-2.0 FOO' is invalid. Use a license identifier from
-http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
+WARNING: License identifier 'GPL-2.0+ FOO' is invalid. Use an identifier from
+https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,
+or set it to nil if you don't want to specify a license.
WARNING
end
@@ -3126,13 +3288,29 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
util_setup_validate
use_ui @ui do
- @a1.licenses = ["GPL-2.0+ WITH Autocofn-exception-2.0"]
+ @a1.licenses = ["GPL-2.0-only WITH Autocofn-exception-2.0"]
@a1.validate
end
assert_match <<-WARNING, @ui.error
-WARNING: license value 'GPL-2.0+ WITH Autocofn-exception-2.0' is invalid. Use a license identifier from
-http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
+WARNING: License identifier 'GPL-2.0-only WITH Autocofn-exception-2.0' is invalid. Use an identifier from
+https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,
+or set it to nil if you don't want to specify a license.
+ WARNING
+ end
+
+ def test_validate_license_with_deprecated_exception
+ util_setup_validate
+
+ use_ui @ui do
+ @a1.licenses = ["GPL-2.0-only WITH Nokia-Qt-exception-1.1"]
+ @a1.validate
+ end
+
+ assert_match <<-WARNING, @ui.error
+WARNING: Exception identifier at 'GPL-2.0-only WITH Nokia-Qt-exception-1.1' is deprecated. Use an identifier from
+https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,
+or set it to nil if you don't want to specify a license.
WARNING
end
@@ -3145,8 +3323,9 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
end
assert_match <<-WARNING, @ui.error
-WARNING: license value 'ruby' is invalid. Use a license identifier from
-http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
+WARNING: License identifier 'ruby' is invalid. Use an identifier from
+https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,
+or set it to nil if you don't want to specify a license.
Did you mean 'Ruby'?
WARNING
end
@@ -3244,7 +3423,7 @@ Did you mean 'Ruby'?
spec.validate
end
- assert_match %r{^#{name}}, e.message
+ assert_match(/^#{name}/, e.message)
end
end
end
@@ -3255,8 +3434,8 @@ Did you mean 'Ruby'?
util_setup_validate
Dir.chdir @tempdir do
- File.chmod 0640, File.join("lib", "code.rb")
- File.chmod 0640, File.join("bin", "exec")
+ File.chmod 0o640, File.join("lib", "code.rb")
+ File.chmod 0o640, File.join("bin", "exec")
use_ui @ui do
@a1.validate
@@ -3404,7 +3583,7 @@ Did you mean 'Ruby'?
capture_output do
Gem::Specification.load(specfile.path)
end
- rescue => e
+ rescue StandardError => e
name_rexp = Regexp.new(Regexp.escape(specfile.path))
assert e.backtrace.grep(name_rexp).any?
end
@@ -3449,10 +3628,10 @@ Did you mean 'Ruby'?
@m1 = quick_gem "m", "1" do |s|
s.files = %w[lib/code.rb]
s.metadata = {
- "one" => "two",
- "home" => "three",
+ "one" => "two",
+ "home" => "three",
"homepage_uri" => "https://example.com/user/repo",
- "funding_uri" => "https://example.com/donate",
+ "funding_uri" => "https://example.com/donate",
}
end
@@ -3547,6 +3726,39 @@ Did you mean 'Ruby'?
end
end
+ def test_metadata_link_validation_warns_for_duplicates
+ util_setup_validate
+
+ Dir.chdir @tempdir do
+ @m2 = quick_gem "m", "2" do |s|
+ s.required_ruby_version = ">= 2.3.0"
+ s.files = %w[lib/code.rb]
+ s.licenses = "BSD-2-Clause"
+ s.metadata = {
+ "source_code_uri" => "http://example.com",
+ "homepage_uri" => "http://example.com",
+ "changelog_uri" => "http://example.com/changelog",
+ }
+ end
+
+ use_ui @ui do
+ @m2.validate
+ end
+
+ expected = <<~EXPECTED
+ #{w}: You have specified the uri:
+ http://example.com
+ for all of the following keys:
+ homepage_uri
+ source_code_uri
+ Only the first one will be shown on rubygems.org
+ #{w}: See https://guides.rubygems.org/specification-reference/ for help
+ EXPECTED
+
+ assert_equal expected, @ui.error, "warning"
+ end
+ end
+
def test_metadata_specs
@m1 = quick_gem "m", "1" do |s|
s.files = %w[lib/code.rb]
@@ -3559,7 +3771,7 @@ Did you mean 'Ruby'?
Gem::Specification.new do |s|
s.name = "m".freeze
- s.version = "1"
+ s.version = "1".freeze
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.metadata = { "one" => "two", "two" => "three" } if s.respond_to? :metadata=
@@ -3658,6 +3870,13 @@ end
assert Gem::Specification.find_by_name "q"
end
+ def test_find_by_name_with_only_prereleases_with_requirements
+ q = util_spec "q", "2.a"
+ install_specs q
+
+ assert Gem::Specification.find_by_name "q", ">= 1"
+ end
+
def test_find_by_name_prerelease
b = util_spec "b", "2.a"
@@ -3676,6 +3895,23 @@ end
assert Gem::Specification.find_by_name "b", ">1"
end
+ def test_find_by_full_name
+ pl = Gem::Platform.new "x86_64-linux"
+
+ a = util_spec "a", "1"
+ install_specs a
+
+ a_pl = util_spec("a", "1") {|s| s.platform = pl }
+ install_specs a_pl
+
+ assert_equal a, Gem::Specification.find_by_full_name("a-1")
+ assert_equal a_pl, Gem::Specification.find_by_full_name("a-1-x86_64-linux")
+
+ assert_nil Gem::Specification.find_by_full_name("a-2")
+ assert_nil Gem::Specification.find_by_full_name("b-1")
+ assert_nil Gem::Specification.find_by_full_name("a-1-arm64-linux")
+ end
+
def test_find_by_path
a = util_spec "foo", "1", nil, "lib/foo.rb"
@@ -3733,7 +3969,7 @@ end
FileUtils.touch File.join("lib", "code.rb")
FileUtils.touch File.join("test", "suite.rb")
- File.open "bin/exec", "w", 0755 do |fp|
+ File.open "bin/exec", "w", 0o755 do |fp|
fp.puts "#!#{Gem.ruby}"
end
ensure
diff --git a/test/rubygems/test_gem_stream_ui.rb b/test/rubygems/test_gem_stream_ui.rb
index 3dbc346271..b1fcb3bc26 100644
--- a/test/rubygems/test_gem_stream_ui.rb
+++ b/test/rubygems/test_gem_stream_ui.rb
@@ -1,19 +1,20 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/user_interaction"
-require "timeout"
+require "rubygems/vendored_timeout"
class TestGemStreamUI < Gem::TestCase
- # increase timeout with MJIT for --jit-wait testing
- mjit_enabled = defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
- SHORT_TIMEOUT = (RUBY_ENGINE == "ruby" && !mjit_enabled) ? 0.1 : 1.0
+ # increase timeout with RJIT for --jit-wait testing
+ rjit_enabled = defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled?
+ SHORT_TIMEOUT = RUBY_ENGINE == "ruby" && !rjit_enabled ? 0.1 : 1.0
module IsTty
attr_accessor :tty
def tty?
@tty = true unless defined? @tty
- return @tty
+ @tty
end
alias_method :isatty, :tty?
@@ -39,7 +40,7 @@ class TestGemStreamUI < Gem::TestCase
end
def test_ask
- Timeout.timeout(5) do
+ Gem::Timeout.timeout(5) do
expected_answer = "Arthur, King of the Britons"
@in.string = "#{expected_answer}\n"
actual_answer = @sui.ask("What is your name?")
@@ -50,14 +51,14 @@ class TestGemStreamUI < Gem::TestCase
def test_ask_no_tty
@in.tty = false
- Timeout.timeout(SHORT_TIMEOUT) do
+ Gem::Timeout.timeout(SHORT_TIMEOUT) do
answer = @sui.ask("what is your favorite color?")
assert_nil answer
end
end
def test_ask_for_password
- Timeout.timeout(5) do
+ Gem::Timeout.timeout(5) do
expected_answer = "Arthur, King of the Britons"
@in.string = "#{expected_answer}\n"
actual_answer = @sui.ask_for_password("What is your name?")
@@ -68,7 +69,7 @@ class TestGemStreamUI < Gem::TestCase
def test_ask_for_password_no_tty
@in.tty = false
- Timeout.timeout(SHORT_TIMEOUT) do
+ Gem::Timeout.timeout(SHORT_TIMEOUT) do
answer = @sui.ask_for_password("what is the airspeed velocity of an unladen swallow?")
assert_nil answer
end
@@ -77,7 +78,7 @@ class TestGemStreamUI < Gem::TestCase
def test_ask_yes_no_no_tty_with_default
@in.tty = false
- Timeout.timeout(SHORT_TIMEOUT) do
+ Gem::Timeout.timeout(SHORT_TIMEOUT) do
answer = @sui.ask_yes_no("do coconuts migrate?", false)
assert_equal false, answer
@@ -89,7 +90,7 @@ class TestGemStreamUI < Gem::TestCase
def test_ask_yes_no_no_tty_without_default
@in.tty = false
- Timeout.timeout(SHORT_TIMEOUT) do
+ Gem::Timeout.timeout(SHORT_TIMEOUT) do
assert_raise(Gem::OperationNotSupportedError) do
@sui.ask_yes_no("do coconuts migrate?")
end
@@ -113,6 +114,36 @@ class TestGemStreamUI < Gem::TestCase
assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string
end
+ def test_choose_from_list_0
+ @in.puts "0"
+ @in.rewind
+
+ result = @sui.choose_from_list "which one?", %w[foo bar]
+
+ assert_equal [nil, nil], result
+ assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string
+ end
+
+ def test_choose_from_list_over
+ @in.puts "3"
+ @in.rewind
+
+ result = @sui.choose_from_list "which one?", %w[foo bar]
+
+ assert_equal [nil, nil], result
+ assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string
+ end
+
+ def test_choose_from_list_negative
+ @in.puts "-1"
+ @in.rewind
+
+ result = @sui.choose_from_list "which one?", %w[foo bar]
+
+ assert_equal [nil, nil], result
+ assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string
+ end
+
def test_progress_reporter_silent_nil
@cfg.verbose = nil
reporter = @sui.progress_reporter 10, "hi"
diff --git a/test/rubygems/test_gem_stub_specification.rb b/test/rubygems/test_gem_stub_specification.rb
index 22a0b6bb6f..fe30a78c0b 100644
--- a/test/rubygems/test_gem_stub_specification.rb
+++ b/test/rubygems/test_gem_stub_specification.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/stub_specification"
@@ -71,7 +72,7 @@ class TestStubSpecification < Gem::TestCase
refute stub.contains_requirable_file? "nonexistent"
end
- expected = "Ignoring stub_e-2 because its extensions are not built. " +
+ expected = "Ignoring stub_e-2 because its extensions are not built. " \
"Try: gem pristine stub_e --version 2\n"
assert_equal expected, err
diff --git a/test/rubygems/test_gem_text.rb b/test/rubygems/test_gem_text.rb
index 95cae1287c..8e99610946 100644
--- a/test/rubygems/test_gem_text.rb
+++ b/test/rubygems/test_gem_text.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/text"
diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb
index e81a9be0ff..9e0c1aa3d8 100644
--- a/test/rubygems/test_gem_uninstaller.rb
+++ b/test/rubygems/test_gem_uninstaller.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "installer_test_case"
require "rubygems/uninstaller"
@@ -24,7 +25,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
def test_initialize_expand_path
FileUtils.mkdir_p "foo/bar"
- uninstaller = Gem::Uninstaller.new nil, :install_dir => "foo//bar"
+ uninstaller = Gem::Uninstaller.new nil, install_dir: "foo//bar"
assert_match %r{foo/bar$}, uninstaller.instance_variable_get(:@gem_home)
end
@@ -58,7 +59,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
end
def test_remove_executables_force_keep
- uninstaller = Gem::Uninstaller.new nil, :executables => false
+ uninstaller = Gem::Uninstaller.new nil, executables: false
executable = File.join Gem.bindir(@user_spec.base_dir), "executable"
assert File.exist?(executable), "executable not written"
@@ -73,7 +74,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
end
def test_remove_executables_force_remove
- uninstaller = Gem::Uninstaller.new nil, :executables => true
+ uninstaller = Gem::Uninstaller.new nil, executables: true
executable = File.join Gem.bindir(@user_spec.base_dir), "executable"
assert File.exist?(executable), "executable not written"
@@ -88,7 +89,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
end
def test_remove_executables_user
- uninstaller = Gem::Uninstaller.new nil, :executables => true
+ uninstaller = Gem::Uninstaller.new nil, executables: true
use_ui @ui do
uninstaller.remove_executables @user_spec
@@ -103,7 +104,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
def test_remove_executables_user_format
Gem::Installer.exec_format = "foo-%s-bar"
- uninstaller = Gem::Uninstaller.new nil, :executables => true, :format_executable => true
+ uninstaller = Gem::Uninstaller.new nil, executables: true, format_executable: true
use_ui @ui do
uninstaller.remove_executables @user_spec
@@ -120,7 +121,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
def test_remove_executables_user_format_disabled
Gem::Installer.exec_format = "foo-%s-bar"
- uninstaller = Gem::Uninstaller.new nil, :executables => true
+ uninstaller = Gem::Uninstaller.new nil, executables: true
use_ui @ui do
uninstaller.remove_executables @user_spec
@@ -136,7 +137,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
def test_remove_not_in_home
Dir.mkdir "#{@gemhome}2"
- uninstaller = Gem::Uninstaller.new nil, :install_dir => "#{@gemhome}2"
+ uninstaller = Gem::Uninstaller.new nil, install_dir: "#{@gemhome}2"
e = assert_raise Gem::GemNotInHomeException do
use_ui ui do
@@ -160,7 +161,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
FileUtils.ln_s(@gemhome, dir)
- uninstaller = Gem::Uninstaller.new nil, :install_dir => symlinked_gem_home
+ uninstaller = Gem::Uninstaller.new nil, install_dir: symlinked_gem_home
use_ui ui do
uninstaller.remove @spec
@@ -172,12 +173,12 @@ class TestGemUninstaller < Gem::InstallerTestCase
def test_remove_plugins
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
- io.write "puts __FILE__"
+ io.write "# do nothing"
end
@spec.files += %w[lib/rubygems_plugin.rb]
- Gem::Installer.at(Gem::Package.build(@spec), :force => true).install
+ Gem::Installer.at(Gem::Package.build(@spec), force: true).install
plugin_path = File.join Gem.plugindir, "a_plugin.rb"
assert File.exist?(plugin_path), "plugin not written"
@@ -189,30 +190,30 @@ class TestGemUninstaller < Gem::InstallerTestCase
def test_remove_plugins_with_install_dir
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
- io.write "puts __FILE__"
+ io.write "# do nothing"
end
@spec.files += %w[lib/rubygems_plugin.rb]
- Gem::Installer.at(Gem::Package.build(@spec), :force => true).install
+ Gem::Installer.at(Gem::Package.build(@spec), 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
+ Gem::Uninstaller.new(nil, install_dir: "#{@gemhome}2").remove_plugins @spec
assert File.exist?(plugin_path), "plugin unintentionally removed"
end
def test_regenerate_plugins_for
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
- io.write "puts __FILE__"
+ io.write "# do nothing"
end
@spec.files += %w[lib/rubygems_plugin.rb]
- Gem::Installer.at(Gem::Package.build(@spec), :force => true).install
+ Gem::Installer.at(Gem::Package.build(@spec), force: true).install
plugin_path = File.join Gem.plugindir, "a_plugin.rb"
assert File.exist?(plugin_path), "plugin not written"
@@ -246,17 +247,17 @@ class TestGemUninstaller < Gem::InstallerTestCase
end
def test_uninstall
- uninstaller = Gem::Uninstaller.new @spec.name, :executables => true
+ uninstaller = Gem::Uninstaller.new @spec.name, executables: true
gem_dir = File.join @gemhome, "gems", @spec.full_name
Gem.pre_uninstall do
- sleep(0.1) if win_platform?
+ sleep(0.1) if Gem.win_platform?
assert File.exist?(gem_dir), "gem_dir should exist"
end
Gem.post_uninstall do
- sleep(0.1) if win_platform?
+ sleep(0.1) if Gem.win_platform?
refute File.exist?(gem_dir), "gem_dir should not exist"
end
@@ -273,7 +274,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
install_default_gems spec
- uninstaller = Gem::Uninstaller.new spec.name, :executables => true
+ uninstaller = Gem::Uninstaller.new spec.name, executables: true
use_ui @ui do
uninstaller.uninstall
@@ -293,7 +294,7 @@ class TestGemUninstaller < Gem::InstallerTestCase
Gem::Specification.reset
- uninstaller = Gem::Uninstaller.new spec.name, :executables => true
+ uninstaller = Gem::Uninstaller.new spec.name, executables: true
ui = Gem::MockGemUi.new "1\ny\n"
use_ui ui do
@@ -321,20 +322,20 @@ create_makefile '#{@spec.name}'
use_ui @ui do
path = Gem::Package.build @spec
- installer = Gem::Installer.at path, :force => true
+ installer = Gem::Installer.at path, force: true
installer.install
end
assert_path_exist @spec.extension_dir, "sanity check"
- uninstaller = Gem::Uninstaller.new @spec.name, :executables => true
+ uninstaller = Gem::Uninstaller.new @spec.name, executables: true
uninstaller.uninstall
assert_path_not_exist @spec.extension_dir
end
def test_uninstall_nonexistent
- uninstaller = Gem::Uninstaller.new "bogus", :executables => true
+ uninstaller = Gem::Uninstaller.new "bogus", executables: true
e = assert_raise Gem::InstallError do
uninstaller.uninstall
@@ -372,8 +373,8 @@ create_makefile '#{@spec.name}'
@user_spec = Gem::Specification.find_by_name "b"
uninstaller = Gem::Uninstaller.new(@user_spec.name,
- :executables => true,
- :user_install => true)
+ executables: true,
+ user_install: true)
gem_dir = File.join @user_spec.gem_dir
@@ -397,7 +398,7 @@ create_makefile '#{@spec.name}'
Dir.mkdir "#{@gemhome}2"
Gem.use_paths "#{@gemhome}2", [@gemhome]
- uninstaller = Gem::Uninstaller.new @spec.name, :executables => true
+ uninstaller = Gem::Uninstaller.new @spec.name, executables: true
e = assert_raise Gem::InstallError do
uninstaller.uninstall
@@ -466,12 +467,12 @@ create_makefile '#{@spec.name}'
lines = ui.output.split("\n")
lines.shift
- assert_match %r{You have requested to uninstall the gem:}, lines.shift
+ assert_match(/You have requested to uninstall the gem:/, lines.shift)
lines.shift
lines.shift
- assert_match %r{r-1 depends on q \(= 1\)}, lines.shift
- assert_match %r{Successfully uninstalled q-1}, lines.last
+ assert_match(/r-1 depends on q \(= 1\)/, lines.shift)
+ assert_match(/Successfully uninstalled q-1/, lines.last)
end
def test_uninstall_only_lists_unsatisfied_deps
@@ -486,7 +487,7 @@ create_makefile '#{@spec.name}'
quick_gem "q", "1.0"
quick_gem "q", "1.1"
- un = Gem::Uninstaller.new("q", :version => "1.0")
+ un = Gem::Uninstaller.new("q", version: "1.0")
ui = Gem::MockGemUi.new("y\n")
use_ui ui do
@@ -496,12 +497,12 @@ create_makefile '#{@spec.name}'
lines = ui.output.split("\n")
lines.shift
- assert_match %r{You have requested to uninstall the gem:}, lines.shift
+ assert_match(/You have requested to uninstall the gem:/, lines.shift)
lines.shift
lines.shift
- assert_match %r{x-1 depends on q \(= 1.0\)}, lines.shift
- assert_match %r{Successfully uninstalled q-1.0}, lines.last
+ assert_match(/x-1 depends on q \(= 1.0\)/, lines.shift)
+ assert_match(/Successfully uninstalled q-1.0/, lines.last)
end
def test_uninstall_doesnt_prompt_when_other_gem_satisfies_requirement
@@ -512,7 +513,7 @@ create_makefile '#{@spec.name}'
quick_gem "q", "1.0"
quick_gem "q", "1.1"
- un = Gem::Uninstaller.new("q", :version => "1.0")
+ un = Gem::Uninstaller.new("q", version: "1.0")
ui = Gem::MockGemUi.new("y\n")
use_ui ui do
@@ -531,7 +532,7 @@ create_makefile '#{@spec.name}'
quick_gem "q", "1.0"
- un = Gem::Uninstaller.new("q", :version => "1.0")
+ un = Gem::Uninstaller.new("q", version: "1.0")
ui = Gem::MockGemUi.new("y\n")
use_ui ui do
@@ -550,7 +551,7 @@ create_makefile '#{@spec.name}'
quick_gem "q", "1"
- un = Gem::Uninstaller.new("q", :abort_on_dependent => true)
+ un = Gem::Uninstaller.new("q", abort_on_dependent: true)
ui = Gem::MockGemUi.new("y\n")
assert_raise Gem::DependencyRemovalException do
@@ -567,7 +568,7 @@ create_makefile '#{@spec.name}'
quick_gem "q", "1"
- un = Gem::Uninstaller.new("q", :check_dev => true)
+ un = Gem::Uninstaller.new("q", check_dev: true)
ui = Gem::MockGemUi.new("y\n")
use_ui ui do
@@ -577,12 +578,12 @@ create_makefile '#{@spec.name}'
lines = ui.output.split("\n")
lines.shift
- assert_match %r{You have requested to uninstall the gem:}, lines.shift
+ assert_match(/You have requested to uninstall the gem:/, lines.shift)
lines.shift
lines.shift
- assert_match %r{r-1 depends on q \(= 1, development\)}, lines.shift
- assert_match %r{Successfully uninstalled q-1}, lines.last
+ assert_match(/r-1 depends on q \(= 1, development\)/, lines.shift)
+ assert_match(/Successfully uninstalled q-1/, lines.last)
end
def test_uninstall_prompt_only_lists_the_dependents_that_prevented_uninstallation
@@ -596,7 +597,7 @@ create_makefile '#{@spec.name}'
quick_gem "q", "1"
- un = Gem::Uninstaller.new("q", :check_dev => false)
+ un = Gem::Uninstaller.new("q", check_dev: false)
ui = Gem::MockGemUi.new("y\n")
use_ui ui do
@@ -606,16 +607,16 @@ create_makefile '#{@spec.name}'
lines = ui.output.split("\n")
lines.shift
- assert_match %r{You have requested to uninstall the gem:}, lines.shift
+ assert_match(/You have requested to uninstall the gem:/, lines.shift)
lines.shift
lines.shift
- assert_match %r{s-1 depends on q \(= 1\)}, lines.shift
- assert_match %r{Successfully uninstalled q-1}, lines.last
+ assert_match(/s-1 depends on q \(= 1\)/, lines.shift)
+ assert_match(/Successfully uninstalled q-1/, lines.last)
end
def test_uninstall_no_permission
- uninstaller = Gem::Uninstaller.new @spec.name, :executables => true
+ uninstaller = Gem::Uninstaller.new @spec.name, executables: true
stub_rm_r = lambda do |*args|
_path = args.shift
@@ -634,40 +635,40 @@ create_makefile '#{@spec.name}'
def test_uninstall_keeps_plugins_up_to_date
write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io|
- io.write "puts __FILE__"
+ io.write "# do nothing"
end
plugin_path = File.join Gem.plugindir, "a_plugin.rb"
@spec.version = "1"
- Gem::Installer.at(Gem::Package.build(@spec), :force => true).install
+ Gem::Installer.at(Gem::Package.build(@spec), force: true).install
refute File.exist?(plugin_path), "version without plugin installed, but plugin written"
@spec.files += %w[lib/rubygems_plugin.rb]
@spec.version = "2"
- Gem::Installer.at(Gem::Package.build(@spec), :force => true).install
+ Gem::Installer.at(Gem::Package.build(@spec), force: true).install
assert File.exist?(plugin_path), "version with plugin installed, but plugin not written"
assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), "written plugin has incorrect content"
@spec.version = "3"
- Gem::Installer.at(Gem::Package.build(@spec), :force => true).install
+ Gem::Installer.at(Gem::Package.build(@spec), force: true).install
assert File.exist?(plugin_path), "version with plugin installed, but plugin removed"
assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), "old version installed, but plugin updated"
- Gem::Uninstaller.new("a", :version => "1", :executables => true).uninstall
+ Gem::Uninstaller.new("a", version: "1", executables: true).uninstall
assert File.exist?(plugin_path), "plugin removed when old version uninstalled"
assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), "old version uninstalled, but plugin updated"
- Gem::Uninstaller.new("a", version: "3", :executables => true).uninstall
+ Gem::Uninstaller.new("a", version: "3", executables: true).uninstall
assert File.exist?(plugin_path), "plugin removed when old version uninstalled and another version with plugin still present"
assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), "latest version uninstalled, but plugin not updated to previous version"
- Gem::Uninstaller.new("a", version: "2", :executables => true).uninstall
+ Gem::Uninstaller.new("a", version: "2", executables: true).uninstall
refute File.exist?(plugin_path), "last version uninstalled, but plugin still present"
end
diff --git a/test/rubygems/test_gem_unsatisfiable_dependency_error.rb b/test/rubygems/test_gem_unsatisfiable_dependency_error.rb
index 3ce98b3cdf..5202010dac 100644
--- a/test/rubygems/test_gem_unsatisfiable_dependency_error.rb
+++ b/test/rubygems/test_gem_unsatisfiable_dependency_error.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
class TestGemUnsatisfiableDependencyError < Gem::TestCase
diff --git a/test/rubygems/test_gem_update_suggestion.rb b/test/rubygems/test_gem_update_suggestion.rb
new file mode 100644
index 0000000000..8cb8ee57ff
--- /dev/null
+++ b/test/rubygems/test_gem_update_suggestion.rb
@@ -0,0 +1,209 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems/command"
+require "rubygems/update_suggestion"
+
+class TestUpdateSuggestion < Gem::TestCase
+ def setup
+ super
+
+ @cmd = Gem::Command.new "dummy", "dummy"
+ @cmd.extend Gem::UpdateSuggestion
+ @start_time = 1_000_000
+ @minute = 60 * 60
+ @week = 7 * 24 * @minute
+ end
+
+ def with_eligible_environment(**params)
+ self.class.with_eligible_environment(**params) do
+ yield
+ end
+ end
+
+ def self.with_eligible_environment(
+ tty: true,
+ rubygems_version: Gem::Version.new("1.2.3"),
+ latest_rubygems_version: Gem::Version.new("2.0.0"),
+ ci: false,
+ reset_last_update_check: true,
+ cmd:
+ )
+ original_config = Gem.configuration[:prevent_update_suggestion]
+ Gem.configuration[:prevent_update_suggestion] = nil
+ original_env = ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"]
+ ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = nil
+ original_disable = Gem.disable_system_update_message
+ Gem.disable_system_update_message = nil
+ Gem.configuration.last_update_check = 0 if reset_last_update_check
+
+ Gem.ui.stub :tty?, tty do
+ Gem.stub :rubygems_version, rubygems_version do
+ Gem.stub :latest_rubygems_version, latest_rubygems_version do
+ Gem::CIDetector.stub :ci?, ci do
+ yield
+ end
+ end
+ end
+ end
+ ensure
+ Gem.configuration[:prevent_update_suggestion] = original_config
+ ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = original_env
+ Gem.disable_system_update_message = original_disable
+ end
+
+ def test_update_suggestion
+ Gem.stub :rubygems_version, Gem::Version.new("1.2.3") do
+ Gem.stub :latest_rubygems_version, Gem::Version.new("2.0.0") do
+ assert_equal @cmd.update_suggestion, <<~SUGGESTION
+
+ A new release of RubyGems is available: 1.2.3 → 2.0.0!
+ Run `gem update --system 2.0.0` to update your installation.
+
+ SUGGESTION
+ end
+ end
+ end
+
+ def test_eligible_for_update
+ with_eligible_environment(cmd: @cmd) do
+ Time.stub :now, 123_456_789 do
+ assert_predicate @cmd, :eligible_for_update?
+ assert_equal 123_456_789, Gem.configuration.last_update_check
+
+ # test last check is written to config file
+ assert_include File.read(Gem.configuration.state_file_name), "123456789"
+ end
+ end
+ end
+
+ def test_eligible_for_update_is_not_annoying_when_new_version_is_released
+ current_version = Gem::Version.new("1.2.0")
+ latest_version = current_version
+
+ # checking for first time, it is not eligible since new version
+ # is not released yet and stored
+ with_eligible_environment(cmd: @cmd, rubygems_version: current_version, latest_rubygems_version: latest_version) do
+ Time.stub :now, @start_time do
+ refute_predicate @cmd, :eligible_for_update?
+ assert_equal @start_time, Gem.configuration.last_update_check
+ end
+ end
+
+ # checking next week, it is not eligible since new version
+ # is not released yet and timestamp is stored
+ with_eligible_environment(
+ cmd: @cmd,
+ rubygems_version: current_version,
+ latest_rubygems_version: latest_version,
+ reset_last_update_check: false
+ ) do
+ Time.stub :now, @start_time + @week do
+ refute_predicate @cmd, :eligible_for_update?
+ assert_equal @start_time + @week, Gem.configuration.last_update_check
+ end
+ end
+
+ # pretend new version is released
+ latest_version = Gem::Version.new("1.3.0")
+
+ # checking later same next week, it is not eligible even new version
+ # is released and timestamp is not stored
+ with_eligible_environment(
+ cmd: @cmd,
+ rubygems_version: current_version,
+ latest_rubygems_version: latest_version,
+ reset_last_update_check: false
+ ) do
+ Time.stub :now, @start_time + @week + @minute do
+ refute_predicate @cmd, :eligible_for_update?
+ assert_equal @start_time + @week, Gem.configuration.last_update_check
+ end
+ end
+ end
+
+ def test_eligible_for_update_is_not_annoying_when_not_upgraded
+ with_eligible_environment(cmd: @cmd) do
+ # checking for first time, it is eligible and stored
+ Time.stub :now, @start_time do
+ assert_predicate @cmd, :eligible_for_update?
+ assert_equal @start_time, Gem.configuration.last_update_check
+ end
+
+ # checking minute later is not eligible and not stored
+ Time.stub :now, @start_time + @minute do
+ refute_predicate @cmd, :eligible_for_update?
+ assert_equal @start_time, Gem.configuration.last_update_check
+ end
+
+ # checking week later is eligible again and stored
+ Time.stub :now, @start_time + @week do
+ assert_predicate @cmd, :eligible_for_update?
+ assert_equal @start_time + @week, Gem.configuration.last_update_check
+ end
+ end
+ end
+
+ def test_eligible_for_update_prevent_config
+ with_eligible_environment(cmd: @cmd) do
+ original_config = Gem.configuration[:prevent_update_suggestion]
+ Gem.configuration[:prevent_update_suggestion] = true
+ refute_predicate @cmd, :eligible_for_update?
+ ensure
+ Gem.configuration[:prevent_update_suggestion] = original_config
+ end
+ end
+
+ def test_eligible_for_update_prevent_env
+ with_eligible_environment(cmd: @cmd) do
+ original_env = ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"]
+ ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = "yes"
+ refute_predicate @cmd, :eligible_for_update?
+ ensure
+ ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = original_env
+ end
+ end
+
+ def test_eligible_for_update_non_tty
+ with_eligible_environment(tty: false, cmd: @cmd) do
+ refute_predicate @cmd, :eligible_for_update?
+ end
+ end
+
+ def test_eligible_for_update_for_prerelease
+ with_eligible_environment(rubygems_version: Gem::Version.new("1.0.0-rc1"), cmd: @cmd) do
+ refute_predicate @cmd, :eligible_for_update?
+ end
+ end
+
+ def test_eligible_for_update_disabled_update
+ with_eligible_environment(cmd: @cmd) do
+ original_disable = Gem.disable_system_update_message
+ Gem.disable_system_update_message = "disabled"
+ refute_predicate @cmd, :eligible_for_update?
+ ensure
+ Gem.disable_system_update_message = original_disable
+ end
+ end
+
+ def test_eligible_for_update_on_ci
+ with_eligible_environment(ci: true, cmd: @cmd) do
+ refute_predicate @cmd, :eligible_for_update?
+ end
+ end
+
+ def test_eligible_for_update_unwrittable_config
+ with_eligible_environment(cmd: @cmd) do
+ Gem.configuration.stub :state_file_writable?, false do
+ refute_predicate @cmd, :eligible_for_update?
+ end
+ end
+ end
+
+ def test_eligible_for_update_notification_delay
+ with_eligible_environment(cmd: @cmd) do
+ Gem.configuration.last_update_check = Time.now.to_i
+ refute_predicate @cmd, :eligible_for_update?
+ end
+ end
+end
diff --git a/test/rubygems/test_gem_uri.rb b/test/rubygems/test_gem_uri.rb
index bcd7b3b2f0..1253ebc6de 100644
--- a/test/rubygems/test_gem_uri.rb
+++ b/test/rubygems/test_gem_uri.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/uri"
diff --git a/test/rubygems/test_gem_uri_formatter.rb b/test/rubygems/test_gem_uri_formatter.rb
index bdc3f76a25..5ab4730d62 100644
--- a/test/rubygems/test_gem_uri_formatter.rb
+++ b/test/rubygems/test_gem_uri_formatter.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/uri_formatter"
diff --git a/test/rubygems/test_gem_util.rb b/test/rubygems/test_gem_util.rb
index 04cb000f8d..608210a903 100644
--- a/test/rubygems/test_gem_util.rb
+++ b/test/rubygems/test_gem_util.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/util"
@@ -35,12 +36,12 @@ class TestGemUtil < Gem::TestCase
end
def test_traverse_parents_does_not_crash_on_permissions_error
- pend "skipped on MS Windows (chmod has no effect)" if win_platform? || java_platform?
+ pend "skipped on MS Windows (chmod has no effect)" if Gem.win_platform? || Gem.java_platform?
FileUtils.mkdir_p "d/e/f"
# remove 'execute' permission from "e" directory and make it
# impossible to cd into it and its children
- FileUtils.chmod(0666, "d/e")
+ FileUtils.chmod(0o666, "d/e")
pend "skipped in root privilege" if Process.uid.zero?
@@ -52,15 +53,7 @@ class TestGemUtil < Gem::TestCase
assert_equal File.realpath("../..", @tempdir), paths[3]
ensure
# restore default permissions, allow the directory to be removed
- FileUtils.chmod(0775, "d/e") unless win_platform? || java_platform?
- end
-
- def test_linked_list_find
- list = [1,2,3,4,5].inject(Gem::List.new(0)) do |m,o|
- Gem::List.new o, m
- end
- assert_equal 5, list.find {|x| x == 5 }
- assert_equal 4, list.find {|x| x == 4 }
+ FileUtils.chmod(0o775, "d/e") unless Gem.win_platform? || Gem.java_platform?
end
def test_glob_files_in_dir
diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb
index 9237608d4a..cf771bc5a1 100644
--- a/test/rubygems/test_gem_version.rb
+++ b/test/rubygems/test_gem_version.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/version"
@@ -43,7 +44,7 @@ class TestGemVersion < Gem::TestCase
assert_equal v("5.1"), Gem::Version.create("5.1")
- ver = "1.1".freeze
+ ver = "1.1"
assert_equal v("1.1"), Gem::Version.create(ver)
end
@@ -88,7 +89,7 @@ class TestGemVersion < Gem::TestCase
end
def test_initialize
- ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n", "1.0".freeze].each do |good|
+ ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n", "1.0"].each do |good|
assert_version_equal "1.0", good
end
@@ -268,7 +269,8 @@ class TestGemVersion < Gem::TestCase
# Assert that two versions are eql?. Checks both directions.
def assert_version_eql(first, second)
- first, second = v(first), v(second)
+ first = v(first)
+ second = v(second)
assert first.eql?(second), "#{first} is eql? #{second}"
assert second.eql?(first), "#{second} is eql? #{first}"
end
@@ -289,7 +291,8 @@ class TestGemVersion < Gem::TestCase
# directions.
def refute_version_eql(first, second)
- first, second = v(first), v(second)
+ first = v(first)
+ second = v(second)
refute first.eql?(second), "#{first} is NOT eql? #{second}"
refute second.eql?(first), "#{second} is NOT eql? #{first}"
end
diff --git a/test/rubygems/test_gem_version_option.rb b/test/rubygems/test_gem_version_option.rb
index 92945e1b08..8b6e14fc42 100644
--- a/test/rubygems/test_gem_version_option.rb
+++ b/test/rubygems/test_gem_version_option.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems/command"
require "rubygems/version_option"
@@ -81,10 +82,10 @@ class TestGemVersionOption < Gem::TestCase
@cmd.handle_options %w[--version >1]
expected = {
- :args => [],
- :explicit_prerelease => false,
- :prerelease => false,
- :version => Gem::Requirement.new("> 1"),
+ args: [],
+ explicit_prerelease: false,
+ prerelease: false,
+ version: Gem::Requirement.new("> 1"),
}
assert_equal expected, @cmd.options
@@ -96,10 +97,10 @@ class TestGemVersionOption < Gem::TestCase
@cmd.handle_options ["--version", "< 1, > 0.9"]
expected = {
- :args => [],
- :explicit_prerelease => false,
- :prerelease => false,
- :version => Gem::Requirement.new("< 1", "> 0.9"),
+ args: [],
+ explicit_prerelease: false,
+ prerelease: false,
+ version: Gem::Requirement.new("< 1", "> 0.9"),
}
assert_equal expected, @cmd.options
@@ -111,10 +112,10 @@ class TestGemVersionOption < Gem::TestCase
@cmd.handle_options ["--version", "< 1", "--version", "> 0.9"]
expected = {
- :args => [],
- :explicit_prerelease => false,
- :prerelease => false,
- :version => Gem::Requirement.new("< 1", "> 0.9"),
+ args: [],
+ explicit_prerelease: false,
+ prerelease: false,
+ version: Gem::Requirement.new("< 1", "> 0.9"),
}
assert_equal expected, @cmd.options
@@ -127,10 +128,10 @@ class TestGemVersionOption < Gem::TestCase
@cmd.handle_options %w[--pre --version >1]
expected = {
- :args => [],
- :explicit_prerelease => true,
- :prerelease => true,
- :version => Gem::Requirement.new("> 1"),
+ args: [],
+ explicit_prerelease: true,
+ prerelease: true,
+ version: Gem::Requirement.new("> 1"),
}
assert_equal expected, @cmd.options
@@ -142,10 +143,10 @@ class TestGemVersionOption < Gem::TestCase
@cmd.handle_options %w[--version >1.a]
expected = {
- :args => [],
- :explicit_prerelease => false,
- :prerelease => true,
- :version => Gem::Requirement.new("> 1.a"),
+ args: [],
+ explicit_prerelease: false,
+ prerelease: true,
+ version: Gem::Requirement.new("> 1.a"),
}
assert_equal expected, @cmd.options
@@ -153,10 +154,10 @@ class TestGemVersionOption < Gem::TestCase
@cmd.handle_options %w[--version >1]
expected = {
- :args => [],
- :explicit_prerelease => false,
- :prerelease => false,
- :version => Gem::Requirement.new("> 1"),
+ args: [],
+ explicit_prerelease: false,
+ prerelease: false,
+ version: Gem::Requirement.new("> 1"),
}
assert_equal expected, @cmd.options
diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb
index 091a5419fb..d862b26fe9 100644
--- a/test/rubygems/test_kernel.rb
+++ b/test/rubygems/test_kernel.rb
@@ -1,23 +1,16 @@
# frozen_string_literal: true
+
require_relative "helper"
-class TestKernel < Gem::TestCase
+class TestGemKernel < Gem::TestCase
def setup
super
- @old_path = $:.dup
-
util_make_gems
without_any_upwards_gemfiles
end
- def teardown
- super
-
- $:.replace @old_path
- end
-
def test_gem
assert gem("a", "= 1"), "Should load"
assert $:.any? {|p| p.include?("a-1/lib") }
@@ -50,19 +43,29 @@ class TestKernel < Gem::TestCase
def test_gem_redundant
assert gem("a", "= 1"), "Should load"
refute gem("a", "= 1"), "Should not load"
- assert_equal 1, $:.select {|p| p.include?("a-1/lib") }.size
+ assert_equal 1, $:.count {|p| p.include?("a-1/lib") }
end
def test_gem_overlapping
assert gem("a", "= 1"), "Should load"
refute gem("a", ">= 1"), "Should not load"
- assert_equal 1, $:.select {|p| p.include?("a-1/lib") }.size
+ assert_equal 1, $:.count {|p| p.include?("a-1/lib") }
end
- def test_gem_prerelease
+ def test_gem_prerelease_is_the_only_available
quick_gem "d", "1.1.a"
- refute gem("d", ">= 1"), "release requirement must not load prerelease"
- assert gem("d", ">= 1.a"), "prerelease requirement may load prerelease"
+
+ assert gem("d", ">= 1"), "release requirement may load prerelease when sole option"
+ assert $:.one? {|p| p.include?("/d-1.1.a/lib") }
+ end
+
+ def test_release_favored_over_prerelease
+ quick_gem "d", "1.1.a"
+ quick_gem "d", "1.2"
+ gem("d", ">= 1")
+
+ refute $:.any? {|p| p.include?("/d-1.1.a/lib") }
+ assert $:.one? {|p| p.include?("/d-1.2/lib") }
end
def test_gem_env_req
@@ -118,6 +121,8 @@ class TestKernel < Gem::TestCase
end
def test_gem_bundler_inferred_bundler_version
+ require "rubygems/bundler_version_finder"
+
Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("1")) do
quick_gem "bundler", "1"
quick_gem "bundler", "2.a"
diff --git a/test/rubygems/test_project_sanity.rb b/test/rubygems/test_project_sanity.rb
index aff7c66413..7a7b779b08 100644
--- a/test/rubygems/test_project_sanity.rb
+++ b/test/rubygems/test_project_sanity.rb
@@ -3,13 +3,36 @@
require_relative "helper"
require "open3"
-class TestProjectSanity < Gem::TestCase
+class TestGemProjectSanity < Gem::TestCase
+ def setup
+ end
+
+ def teardown
+ end
+
def test_manifest_is_up_to_date
- pend unless File.exist?(File.expand_path("../../Rakefile", __dir__))
+ pend unless File.exist?("#{root}/Rakefile")
_, status = Open3.capture2e("rake check_manifest")
- assert status.success?, "Expected Manifest.txt to be up to date, but it's not. Run `rake update_manifest` to sync it."
+ unless status.success?
+ original_contents = File.read("#{root}/Manifest.txt")
+
+ # Update the manifest to see if it fixes the problem
+ Open3.capture2e("rake update_manifest")
+
+ out, status = Open3.capture2e("rake check_manifest")
+
+ # If `rake update_manifest` fixed the problem, that was the original
+ # issue, otherwise it was an unknown error, so print the error output
+ if status.success?
+ File.write("#{root}/Manifest.txt", original_contents)
+
+ raise "Expected Manifest.txt to be up to date, but it's not. Run `rake update_manifest` to sync it."
+ else
+ raise "There was an error running `rake check_manifest`: #{out}"
+ end
+ end
end
def test_require_rubygems_package
@@ -17,4 +40,10 @@ class TestProjectSanity < Gem::TestCase
assert status.success?, err
end
+
+ private
+
+ def root
+ File.expand_path("../..", __dir__)
+ end
end
diff --git a/test/rubygems/test_remote_fetch_error.rb b/test/rubygems/test_remote_fetch_error.rb
index 55c505d879..5d9028ede7 100644
--- a/test/rubygems/test_remote_fetch_error.rb
+++ b/test/rubygems/test_remote_fetch_error.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
+
require_relative "helper"
-class TestRemoteFetchError < Gem::TestCase
+class TestGemRemoteFetchError < Gem::TestCase
def test_password_redacted
error = Gem::RemoteFetcher::FetchError.new("There was an error fetching", "https://user:secret@gemsource.org")
- refute_match %r{secret}, error.to_s
+ refute_match(/secret/, error.to_s)
end
def test_invalid_url
diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb
index 6135acea92..30a4a477f9 100644
--- a/test/rubygems/test_require.rb
+++ b/test/rubygems/test_require.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require_relative "helper"
require "rubygems"
@@ -91,12 +92,10 @@ class TestGemRequire < Gem::TestCase
def create_sync_thread
Thread.new do
- begin
- yield
- ensure
- FILE_ENTERED_LATCH.release
- FILE_EXIT_LATCH.await
- end
+ yield
+ ensure
+ FILE_ENTERED_LATCH.release
+ FILE_EXIT_LATCH.await
end
end
@@ -226,7 +225,7 @@ class TestGemRequire < Gem::TestCase
pend "Not sure what's going on. If another spec creates a 'a' gem before
this test, somehow require will load the benchmark in b, and ignore that the
stdlib one is already in $LOADED_FEATURES?. Reproducible by running the
- spaceship_specific_file test before this one" if java_platform?
+ spaceship_specific_file test before this one" if Gem.java_platform?
pend "not installed yet" unless RbConfig::TOPDIR
@@ -252,9 +251,9 @@ class TestGemRequire < Gem::TestCase
# Activates a-1, but not b-1 and b-2
assert_require "test_gem_require_a"
assert_equal %w[a-1], loaded_spec_names
- assert $LOAD_PATH.include? a1.load_paths[0]
- refute $LOAD_PATH.include? b1.load_paths[0]
- refute $LOAD_PATH.include? b2.load_paths[0]
+ assert $LOAD_PATH.include? a1.full_require_paths[0]
+ refute $LOAD_PATH.include? b1.full_require_paths[0]
+ refute $LOAD_PATH.include? b2.full_require_paths[0]
assert_equal unresolved_names, ["b (>= 1)"]
@@ -265,13 +264,13 @@ class TestGemRequire < Gem::TestCase
# and as a result #gem_original_require returns false.
refute require("benchmark"), "the benchmark stdlib should be recognized as already loaded"
- assert_includes $LOAD_PATH, b2.load_paths[0]
+ assert_includes $LOAD_PATH, b2.full_require_paths[0]
assert_includes $LOAD_PATH, rubylibdir
message = proc {
"this test relies on the b-2 gem lib/ to be before stdlib to make sense\n" +
$LOAD_PATH.pretty_inspect
}
- assert_operator $LOAD_PATH.index(b2.load_paths[0]), :<, $LOAD_PATH.index(rubylibdir), message
+ assert_operator $LOAD_PATH.index(b2.full_require_paths[0]), :<, $LOAD_PATH.index(rubylibdir), message
# We detected that we should activate b-2, so we did so, but
# then #gem_original_require decided "I've already got some benchmark.rb" loaded.
@@ -383,8 +382,8 @@ class TestGemRequire < Gem::TestCase
# Remove an old default gem version directly from disk as if someone ran
# gem cleanup.
- FileUtils.rm_rf(File.join @gemhome, "#{b1.full_name}")
- FileUtils.rm_rf(File.join @gemhome, "specifications", "default", "#{b1.full_name}.gemspec")
+ FileUtils.rm_rf(File.join(@gemhome, b1.full_name.to_s))
+ FileUtils.rm_rf(File.join(@gemhome, "specifications", "default", "#{b1.full_name}.gemspec"))
# Require gems that have not been removed.
assert_require "a/b"
@@ -425,7 +424,7 @@ class TestGemRequire < Gem::TestCase
times_called = 0
- Kernel.stub(:gem, ->(name, requirement) { times_called += 1 }) do
+ Kernel.stub(:gem, ->(_name, _requirement) { times_called += 1 }) do
refute_require "default/gem"
end
@@ -472,11 +471,11 @@ class TestGemRequire < Gem::TestCase
File.write(path, code)
output = Gem::Util.popen({ "GEM_HOME" => @gemhome }, *ruby_with_rubygems_in_load_path, path).strip
- assert $?.success?
refute_empty output
assert_equal "999.99.9", output.lines[0].chomp
# Make sure only files from the newer json gem are loaded, and no files from the default json gem
assert_equal ["#{@gemhome}/gems/json-999.99.9/lib/json.rb"], output.lines.grep(%r{/gems/json-}).map(&:chomp)
+ assert $?.success?
end
def test_default_gem_and_normal_gem
@@ -490,6 +489,17 @@ class TestGemRequire < Gem::TestCase
assert_equal %w[default-3.0], loaded_spec_names
end
+ def test_normal_gem_does_not_shadow_default_gem
+ default_gem_spec = new_default_spec("foo", "2.0", nil, "foo.rb")
+ install_default_gems(default_gem_spec)
+
+ normal_gem_spec = util_spec("fake-foo", "3.0", nil, "lib/foo.rb")
+ install_specs(normal_gem_spec)
+
+ assert_require "foo"
+ assert_equal %w[foo-2.0], loaded_spec_names
+ end
+
def test_normal_gems_with_overridden_load_error_message
normal_gem_spec = util_spec("normal", "3.0", nil, "lib/normal/gem.rb")
@@ -530,6 +540,65 @@ class TestGemRequire < Gem::TestCase
assert_equal %w[default-3.0.0.rc2], loaded_spec_names
end
+ def test_default_gem_with_unresolved_gems_depending_on_it
+ my_http_old = util_spec "my-http", "0.1.1", nil, "lib/my/http.rb"
+ install_gem my_http_old
+
+ my_http_default = new_default_spec "my-http", "0.3.0", nil, "my/http.rb"
+ install_default_gems my_http_default
+
+ faraday_1 = util_spec "faraday", "1", { "my-http" => ">= 0" }
+ install_gem faraday_1
+
+ faraday_2 = util_spec "faraday", "2", { "my-http" => ">= 0" }
+ install_gem faraday_2
+
+ chef = util_spec "chef", "1", { "faraday" => [">= 1", "< 3"] }, "lib/chef.rb"
+ install_gem chef
+
+ assert_require "chef"
+ assert_require "my/http"
+ end
+
+ def test_default_gem_required_circulary_with_unresolved_gems_depending_on_it
+ my_http_old = util_spec "my-http", "0.1.1", nil, "lib/my/http.rb"
+ install_gem my_http_old
+
+ my_http_default = new_default_spec "my-http", "0.3.0", nil, "my/http.rb"
+ my_http_default_path = File.join(@tempdir, "default_gems", "lib", "my/http.rb")
+ install_default_gems my_http_default
+ File.write(my_http_default_path, 'require "my/http"')
+
+ faraday_1 = util_spec "faraday", "1", { "my-http" => ">= 0" }
+ install_gem faraday_1
+
+ faraday_2 = util_spec "faraday", "2", { "my-http" => ">= 0" }
+ install_gem faraday_2
+
+ chef = util_spec "chef", "1", { "faraday" => [">= 1", "< 3"] }, "lib/chef.rb"
+ install_gem chef
+
+ assert_require "chef"
+
+ out, err = capture_output do
+ assert_require "my/http"
+ end
+
+ assert_empty out
+
+ circular_require_warning = false
+
+ err_lines = err.split("\n").reject do |line|
+ if line.include?("circular require")
+ circular_require_warning = true
+ elsif circular_require_warning # ignore backtrace lines for circular require warning
+ circular_require_warning = line.start_with?(/[\s]/)
+ end
+ end
+
+ assert_empty err_lines
+ end
+
def loaded_spec_names
Gem.loaded_specs.values.map(&:full_name).sort
end
@@ -541,8 +610,10 @@ class TestGemRequire < Gem::TestCase
def test_try_activate_error_unlocks_require_monitor
silence_warnings do
class << ::Gem
- alias old_try_activate try_activate
- def try_activate(*); raise "raised from try_activate"; end
+ alias_method :old_try_activate, :try_activate
+ def try_activate(*)
+ raise "raised from try_activate"
+ end
end
end
@@ -553,7 +624,7 @@ class TestGemRequire < Gem::TestCase
ensure
silence_warnings do
class << ::Gem
- alias try_activate old_try_activate
+ alias_method :try_activate, :old_try_activate
end
end
Kernel::RUBYGEMS_ACTIVATION_MONITOR.exit
@@ -596,79 +667,93 @@ class TestGemRequire < Gem::TestCase
assert_empty unresolved_names
end
- # uplevel is 2.5+ only
- if RUBY_VERSION >= "2.5"
- ["", "Kernel."].each do |prefix|
- define_method "test_no_kernel_require_in_#{prefix.tr(".", "_")}warn_with_uplevel" do
- Dir.mktmpdir("warn_test") do |dir|
- File.write(dir + "/sub.rb", "#{prefix}warn 'uplevel', 'test', uplevel: 1\n")
- File.write(dir + "/main.rb", "require 'sub'\n")
- _, err = capture_subprocess_io do
- system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "-I", dir, "main.rb")
- end
- assert_match(/main\.rb:1: warning: uplevel\ntest\n$/, err)
- _, err = capture_subprocess_io do
- system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "-I", dir, "main.rb")
- end
- assert_match(/main\.rb:1: warning: uplevel\ntest\n$/, err)
+ ["", "Kernel."].each do |prefix|
+ define_method "test_no_kernel_require_in_#{prefix.tr(".", "_")}warn_with_uplevel" do
+ Dir.mktmpdir("warn_test") do |dir|
+ File.write(dir + "/sub.rb", "#{prefix}warn 'uplevel', 'test', uplevel: 1\n")
+ File.write(dir + "/main.rb", "require 'sub'\n")
+ _, err = capture_subprocess_io do
+ system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "-I", dir, "main.rb")
end
- end
-
- define_method "test_no_other_behavioral_changes_with_#{prefix.tr(".", "_")}warn" do
- Dir.mktmpdir("warn_test") do |dir|
- File.write(dir + "/main.rb", "#{prefix}warn({x:1}, {y:2}, [])\n")
- _, err = capture_subprocess_io do
- system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "main.rb")
- end
- assert_match(/{:x=>1}\n{:y=>2}\n$/, err)
- _, err = capture_subprocess_io do
- system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "main.rb")
- end
- assert_match(/{:x=>1}\n{:y=>2}\n$/, err)
+ assert_match(/main\.rb:1: warning: uplevel\ntest\n$/, err)
+ _, err = capture_subprocess_io do
+ system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "-I", dir, "main.rb")
end
+ assert_match(/main\.rb:1: warning: uplevel\ntest\n$/, err)
end
end
- def test_no_crash_when_overriding_warn_with_warning_module
+ define_method "test_no_other_behavioral_changes_with_#{prefix.tr(".", "_")}warn" do
Dir.mktmpdir("warn_test") do |dir|
- File.write(dir + "/main.rb", "module Warning; def warn(str); super; end; end; warn 'Foo Bar'")
+ File.write(dir + "/main.rb", "#{prefix}warn({x:1}, {y:2}, [])\n")
_, err = capture_subprocess_io do
system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "main.rb")
end
- assert_match(/Foo Bar\n$/, err)
+ assert_match(/{:x=>1}\n{:y=>2}\n$/, err)
_, err = capture_subprocess_io do
system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "main.rb")
end
- assert_match(/Foo Bar\n$/, err)
+ assert_match(/{:x=>1}\n{:y=>2}\n$/, err)
end
end
+ end
- def test_expected_backtrace_location_when_inheriting_from_basic_object_and_including_kernel
- Dir.mktmpdir("warn_test") do |dir|
- File.write(dir + "/main.rb", "\nrequire 'sub'\n")
- File.write(dir + "/sub.rb", <<-'RUBY')
- require 'rubygems'
- class C < BasicObject
- include ::Kernel
- def deprecated
- warn "This is a deprecated method", uplevel: 2
- end
- end
- C.new.deprecated
- RUBY
+ def test_no_crash_when_overriding_warn_with_warning_module
+ Dir.mktmpdir("warn_test") do |dir|
+ File.write(dir + "/main.rb", "module Warning; def warn(str); super; end; end; warn 'Foo Bar'")
+ _, err = capture_subprocess_io do
+ system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "main.rb")
+ end
+ assert_match(/Foo Bar\n$/, err)
+ _, err = capture_subprocess_io do
+ system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "main.rb")
+ end
+ assert_match(/Foo Bar\n$/, err)
+ end
+ end
- _, err = capture_subprocess_io do
- system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "-I", dir, "main.rb")
- end
- assert_match(/main\.rb:2: warning: This is a deprecated method$/, err)
- _, err = capture_subprocess_io do
- system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "-I", dir, "main.rb")
+ def test_expected_backtrace_location_when_inheriting_from_basic_object_and_including_kernel
+ Dir.mktmpdir("warn_test") do |dir|
+ File.write(dir + "/main.rb", "\nrequire 'sub'\n")
+ File.write(dir + "/sub.rb", <<-'RUBY')
+ require 'rubygems'
+ class C < BasicObject
+ include ::Kernel
+ def deprecated
+ warn "This is a deprecated method", uplevel: 2
+ end
end
- assert_match(/main\.rb:2: warning: This is a deprecated method$/, err)
+ C.new.deprecated
+ RUBY
+
+ _, err = capture_subprocess_io do
+ system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "-I", dir, "main.rb")
end
+ assert_match(/main\.rb:2: warning: This is a deprecated method$/, err)
+ _, err = capture_subprocess_io do
+ system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "-I", dir, "main.rb")
+ end
+ assert_match(/main\.rb:2: warning: This is a deprecated method$/, err)
end
end
+ def test_require_does_not_crash_when_utilizing_bundler_version_finder
+ a1 = util_spec "a", "1.1", { "bundler" => ">= 0" }
+ a2 = util_spec "a", "1.2", { "bundler" => ">= 0" }
+ b1 = util_spec "bundler", "2.3.7"
+ b2 = util_spec "bundler", "2.3.24"
+ c = util_spec "c", "1", { "a" => [">= 1.1", "< 99.0"] }, "lib/test_gem_require_c.rb"
+
+ install_specs a1, a2, b1, b2, c
+
+ cmd = <<-RUBY
+ require "test_gem_require_c"
+ require "json"
+ RUBY
+ out = Gem::Util.popen({ "GEM_HOME" => @gemhome }, *ruby_with_rubygems_in_load_path, "-e", cmd)
+ assert_predicate $?, :success?, "Require failed due to #{out}"
+ end
+
private
def util_install_extension_file(name)
@@ -694,13 +779,13 @@ class TestGemRequire < Gem::TestCase
spec.files += ["extconf.rb", "depend", "#{name}.c"]
- so = File.join(spec.gem_dir, "#{name}.#{RbConfig::CONFIG["DLEXT"]}")
- assert_path_not_exist so
+ extension_file = File.join(spec.extension_dir, "#{name}.#{RbConfig::CONFIG["DLEXT"]}")
+ assert_path_not_exist extension_file
path = Gem::Package.build spec
installer = Gem::Installer.at path
installer.install
- assert_path_exist so
+ assert_path_exist extension_file
spec.gem_dir
end
diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb
index 8bd116646f..ec195b65cd 100644
--- a/test/rubygems/test_rubygems.rb
+++ b/test/rubygems/test_rubygems.rb
@@ -1,8 +1,10 @@
+# frozen_string_literal: true
+
require_relative "helper"
class GemTest < Gem::TestCase
def test_rubygems_normal_behaviour
- _ = Gem::Util.popen(*ruby_with_rubygems_in_load_path, "-e", "'require \"rubygems\"'", { :err => [:child, :out] }).strip
+ _ = Gem::Util.popen(*ruby_with_rubygems_in_load_path, "-e", "'require \"rubygems\"'", { err: [:child, :out] }).strip
assert $?.success?
end
@@ -13,9 +15,9 @@ class GemTest < Gem::TestCase
intentionally_not_implemented_method
RUBY
- output = Gem::Util.popen(*ruby_with_rubygems_and_fake_operating_system_in_load_path(path), "-e", "'require \"rubygems\"'", { :err => [:child, :out] }).strip
+ output = Gem::Util.popen(*ruby_with_rubygems_and_fake_operating_system_in_load_path(path), "-e", "'require \"rubygems\"'", { err: [:child, :out] }).strip
assert !$?.success?
- assert_includes output, "undefined local variable or method `intentionally_not_implemented_method'"
+ assert_match(/undefined local variable or method [`']intentionally_not_implemented_method'/, output)
assert_includes output, "Loading the #{operating_system_rb_at(path)} file caused an error. " \
"This file is owned by your OS, not by rubygems upstream. " \
"Please find out which OS package this file belongs to and follow the guidelines from your OS to report " \
@@ -40,7 +42,7 @@ class GemTest < Gem::TestCase
*ruby_with_rubygems_and_fake_operating_system_in_load_path(path),
"-e",
"require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)",
- { :err => [:child, :out] }
+ { err: [:child, :out] }
).strip
begin
assert_empty output
@@ -69,6 +71,6 @@ class GemTest < Gem::TestCase
end
def ruby_with_rubygems_and_fake_operating_system_in_load_path(operating_system_path)
- [Gem.ruby, "-I", operating_system_path, "-I" , $LOAD_PATH.find {|p| p == File.dirname($LOADED_FEATURES.find {|f| f.end_with?("/rubygems.rb") }) }]
+ [Gem.ruby, "-I", operating_system_path, "-I", $LOAD_PATH.find {|p| p == File.dirname($LOADED_FEATURES.find {|f| f.end_with?("/rubygems.rb") }) }]
end
end
diff --git a/test/rubygems/test_webauthn_listener.rb b/test/rubygems/test_webauthn_listener.rb
new file mode 100644
index 0000000000..08edabceb2
--- /dev/null
+++ b/test/rubygems/test_webauthn_listener.rb
@@ -0,0 +1,143 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems/gemcutter_utilities/webauthn_listener"
+require "rubygems/gemcutter_utilities"
+
+class WebauthnListenerTest < Gem::TestCase
+ def setup
+ super
+ @server = TCPServer.new 0
+ @port = @server.addr[1].to_s
+ end
+
+ def teardown
+ @thread.kill.join if @thread
+ @server&.close
+ super
+ end
+
+ def test_listener_thread_retreives_otp_code
+ thread = Gem::GemcutterUtilities::WebauthnListener.listener_thread(Gem.host, @server)
+ Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}?code=xyz")
+
+ thread.join
+ assert_equal "xyz", thread[:otp]
+ end
+
+ def test_listener_thread_sets_error
+ thread = Gem::GemcutterUtilities::WebauthnListener.listener_thread(Gem.host, @server)
+ Gem::MockBrowser.post Gem::URI("http://localhost:#{@port}?code=xyz")
+
+ thread.join
+ assert_equal "Security device verification failed: Invalid HTTP method POST received.", thread[:error].message
+ end
+
+ def test_wait_for_otp_code_get_follows_options
+ wait_for_otp_code
+ assert Gem::MockBrowser.options(Gem::URI("http://localhost:#{@port}?code=xyz")).is_a? Gem::Net::HTTPNoContent
+ assert Gem::MockBrowser.get(Gem::URI("http://localhost:#{@port}?code=xyz")).is_a? Gem::Net::HTTPOK
+ end
+
+ def test_wait_for_otp_code_options_request
+ wait_for_otp_code
+ response = Gem::MockBrowser.options Gem::URI("http://localhost:#{@port}?code=xyz")
+
+ assert response.is_a? Gem::Net::HTTPNoContent
+ assert_equal Gem.host, response["access-control-allow-origin"]
+ assert_equal "POST", response["access-control-allow-methods"]
+ assert_equal "Content-Type, Authorization, x-csrf-token", response["access-control-allow-headers"]
+ assert_equal "close", response["Connection"]
+ end
+
+ def test_wait_for_otp_code_get_request
+ wait_for_otp_code
+ response = Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}?code=xyz")
+
+ assert response.is_a? Gem::Net::HTTPOK
+ assert_equal "text/plain; charset=utf-8", response["Content-Type"]
+ assert_equal "7", response["Content-Length"]
+ assert_equal Gem.host, response["access-control-allow-origin"]
+ assert_equal "POST", response["access-control-allow-methods"]
+ assert_equal "Content-Type, Authorization, x-csrf-token", response["access-control-allow-headers"]
+ assert_equal "close", response["Connection"]
+ assert_equal "success", response.body
+
+ @thread.join
+ assert_equal "xyz", @thread[:otp]
+ end
+
+ def test_wait_for_otp_code_invalid_post_req_method
+ wait_for_otp_code_expect_error_with_message("Security device verification failed: Invalid HTTP method POST received.")
+ response = Gem::MockBrowser.post Gem::URI("http://localhost:#{@port}?code=xyz")
+
+ assert response
+ assert response.is_a? Gem::Net::HTTPMethodNotAllowed
+ assert_equal "GET, OPTIONS", response["allow"]
+ assert_equal "close", response["Connection"]
+
+ @thread.join
+ assert_nil @thread[:otp]
+ end
+
+ def test_wait_for_otp_code_incorrect_path
+ wait_for_otp_code_expect_error_with_message("Security device verification failed: Page at /path not found.")
+ response = Gem::MockBrowser.post Gem::URI("http://localhost:#{@port}/path?code=xyz")
+
+ assert response.is_a? Gem::Net::HTTPNotFound
+ assert_equal "close", response["Connection"]
+
+ @thread.join
+ assert_nil @thread[:otp]
+ end
+
+ def test_wait_for_otp_code_no_params_response
+ wait_for_otp_code_expect_error_with_message("Security device verification failed: Did not receive OTP from https://rubygems.org.")
+ response = Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}")
+
+ assert response.is_a? Gem::Net::HTTPBadRequest
+ assert_equal "text/plain; charset=utf-8", response["Content-Type"]
+ assert_equal "22", response["Content-Length"]
+ assert_equal "close", response["Connection"]
+ assert_equal "missing code parameter", response.body
+
+ @thread.join
+ assert_nil @thread[:otp]
+ end
+
+ def test_wait_for_otp_code_incorrect_params
+ wait_for_otp_code_expect_error_with_message("Security device verification failed: Did not receive OTP from https://rubygems.org.")
+ response = Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}?param=xyz")
+
+ assert response.is_a? Gem::Net::HTTPBadRequest
+ assert_equal "text/plain; charset=utf-8", response["Content-Type"]
+ assert_equal "22", response["Content-Length"]
+ assert_equal "close", response["Connection"]
+ assert_equal "missing code parameter", response.body
+
+ @thread.join
+ assert_nil @thread[:otp]
+ end
+
+ private
+
+ def wait_for_otp_code
+ @thread = Thread.new do
+ Thread.current[:otp] = Gem::GemcutterUtilities::WebauthnListener.new(Gem.host).wait_for_otp_code(@server)
+ end
+ @thread.abort_on_exception = true
+ @thread.report_on_exception = false
+ end
+
+ def wait_for_otp_code_expect_error_with_message(message)
+ @thread = Thread.new do
+ error = assert_raise Gem::WebauthnVerificationError do
+ Thread.current[:otp] = Gem::GemcutterUtilities::WebauthnListener.new(Gem.host).wait_for_otp_code(@server)
+ end
+
+ assert_equal message, error.message
+ end
+ @thread.abort_on_exception = true
+ @thread.report_on_exception = false
+ end
+end
diff --git a/test/rubygems/test_webauthn_listener_response.rb b/test/rubygems/test_webauthn_listener_response.rb
new file mode 100644
index 0000000000..377e5bfe5a
--- /dev/null
+++ b/test/rubygems/test_webauthn_listener_response.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems/gemcutter_utilities/webauthn_listener/response"
+
+class WebauthnListenerResponseTest < Gem::TestCase
+ def setup
+ super
+ @host = "rubygems.example"
+ end
+
+ def test_ok_response_to_s
+ to_s = Gem::GemcutterUtilities::WebauthnListener::OkResponse.new(@host).to_s
+
+ expected_to_s = <<~RESPONSE
+ HTTP/1.1 200 OK\r
+ connection: close\r
+ access-control-allow-origin: rubygems.example\r
+ access-control-allow-methods: POST\r
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
+ content-type: text/plain; charset=utf-8\r
+ content-length: 7\r
+ \r
+ success
+ RESPONSE
+
+ assert_equal expected_to_s, to_s
+ end
+
+ def test_no_to_s_response_to_s
+ to_s = Gem::GemcutterUtilities::WebauthnListener::NoContentResponse.new(@host).to_s
+
+ expected_to_s = <<~RESPONSE
+ HTTP/1.1 204 No Content\r
+ connection: close\r
+ access-control-allow-origin: rubygems.example\r
+ access-control-allow-methods: POST\r
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
+ \r
+ RESPONSE
+
+ assert_equal expected_to_s, to_s
+ end
+
+ def test_method_not_allowed_response_to_s
+ to_s = Gem::GemcutterUtilities::WebauthnListener::MethodNotAllowedResponse.new(@host).to_s
+
+ expected_to_s = <<~RESPONSE
+ HTTP/1.1 405 Method Not Allowed\r
+ connection: close\r
+ access-control-allow-origin: rubygems.example\r
+ access-control-allow-methods: POST\r
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
+ allow: GET, OPTIONS\r
+ \r
+ RESPONSE
+
+ assert_equal expected_to_s, to_s
+ end
+
+ def test_method_not_found_response_to_s
+ to_s = Gem::GemcutterUtilities::WebauthnListener::NotFoundResponse.new(@host).to_s
+
+ expected_to_s = <<~RESPONSE
+ HTTP/1.1 404 Not Found\r
+ connection: close\r
+ access-control-allow-origin: rubygems.example\r
+ access-control-allow-methods: POST\r
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
+ \r
+ RESPONSE
+
+ assert_equal expected_to_s, to_s
+ end
+
+ def test_bad_request_response_to_s
+ to_s = Gem::GemcutterUtilities::WebauthnListener::BadRequestResponse.new(@host).to_s
+
+ expected_to_s = <<~RESPONSE
+ HTTP/1.1 400 Bad Request\r
+ connection: close\r
+ access-control-allow-origin: rubygems.example\r
+ access-control-allow-methods: POST\r
+ access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r
+ content-type: text/plain; charset=utf-8\r
+ content-length: 22\r
+ \r
+ missing code parameter
+ RESPONSE
+
+ assert_equal expected_to_s, to_s
+ end
+end
diff --git a/test/rubygems/test_webauthn_poller.rb b/test/rubygems/test_webauthn_poller.rb
new file mode 100644
index 0000000000..23290d8ea1
--- /dev/null
+++ b/test/rubygems/test_webauthn_poller.rb
@@ -0,0 +1,124 @@
+# frozen_string_literal: true
+
+require_relative "helper"
+require "rubygems/gemcutter_utilities/webauthn_poller"
+require "rubygems/gemcutter_utilities"
+
+class WebauthnPollerTest < Gem::TestCase
+ def setup
+ super
+
+ @host = Gem.host
+ @webauthn_url = "#{@host}/api/v1/webauthn_verification/odow34b93t6aPCdY"
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+ @credentials = {
+ email: "email@example.com",
+ password: "password",
+ }
+ end
+
+ def test_poll_thread_success
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{\"status\":\"success\",\"code\":\"Uvh6T57tkWuUnWYo\"}",
+ code: 200,
+ msg: "OK"
+ )
+
+ thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials)
+ thread.join
+
+ assert_equal thread[:otp], "Uvh6T57tkWuUnWYo"
+ end
+
+ def test_poll_thread_webauthn_verification_error
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "HTTP Basic: Access denied.",
+ code: 401,
+ msg: "Unauthorized"
+ )
+
+ thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials)
+ thread.join
+
+ assert_equal thread[:error].message, "Security device verification failed: Unauthorized"
+ end
+
+ def test_poll_thread_timeout_error
+ raise_error = ->(*_args) { raise Gem::Timeout::Error, "execution expired" }
+ Gem::Timeout.stub(:timeout, raise_error) do
+ thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials)
+ thread.join
+ assert_equal thread[:error].message, "execution expired"
+ end
+ end
+
+ def test_poll_for_otp_success
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{\"status\":\"success\",\"code\":\"Uvh6T57tkWuUnWYo\"}",
+ code: 200,
+ msg: "OK"
+ )
+
+ otp = Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+
+ assert_equal otp, "Uvh6T57tkWuUnWYo"
+ end
+
+ def test_poll_for_otp_pending_sleeps
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{\"status\":\"pending\",\"message\":\"Security device authentication is still pending.\"}",
+ code: 200,
+ msg: "OK"
+ )
+
+ assert_raise Gem::Timeout::Error do
+ Gem::Timeout.timeout(0.1) do
+ Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials)
+ end
+ end
+ end
+
+ def test_poll_for_otp_not_http_success
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "HTTP Basic: Access denied.",
+ code: 401,
+ msg: "Unauthorized"
+ )
+
+ 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: Unauthorized"
+ end
+
+ def test_poll_for_otp_invalid_format
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{}",
+ code: 200,
+ msg: "OK"
+ )
+
+ 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: Invalid response from server"
+ end
+
+ def test_poll_for_otp_invalid_status
+ @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create(
+ body: "{\"status\":\"expired\",\"message\":\"The token in the link you used has either expired or been used already.\"}",
+ code: 200,
+ msg: "OK"
+ )
+
+ 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: The token in the link you used has either expired or been used already."
+ end
+end
diff --git a/test/rubygems/utilities.rb b/test/rubygems/utilities.rb
index c01f7acd48..357379f88d 100644
--- a/test/rubygems/utilities.rb
+++ b/test/rubygems/utilities.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+
require "tempfile"
require "rubygems"
require "rubygems/remote_fetcher"
@@ -39,28 +40,36 @@ class Gem::FakeFetcher
end
def find_data(path)
- return Gem.read_binary path.path if URI === path && "file" == path.scheme
+ return Gem.read_binary path.path if Gem::URI === path && path.scheme == "file"
- if URI === path && "URI::#{path.scheme.upcase}" != path.class.name
+ if Gem::URI === path && "Gem::URI::#{path.scheme.upcase}" != path.class.name
raise ArgumentError,
"mismatch for scheme #{path.scheme} and class #{path.class}"
end
path = path.to_s
@paths << path
- raise ArgumentError, "need full URI" unless path.start_with?("https://", "http://")
+ raise ArgumentError, "need full Gem::URI" unless path.start_with?("https://", "http://")
unless @data.key? path
raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
end
- if @data[path].kind_of?(Array) && @data[path].first.kind_of?(Array)
+ if @data[path].is_a?(Array)
@data[path].shift
else
@data[path]
end
end
+ def create_response(uri)
+ data = find_data(uri)
+ response = data.respond_to?(:call) ? data.call : data
+ raise TypeError, "#{response.class} is not a type of Gem::Net::HTTPResponse" unless response.is_a?(Gem::Net::HTTPResponse)
+
+ response
+ end
+
def fetch_path(path, mtime = nil, head = false)
data = find_data(path)
@@ -85,26 +94,16 @@ class Gem::FakeFetcher
# Thanks, FakeWeb!
def open_uri_or_path(path)
- data = find_data(path)
- body, code, msg = data
+ find_data(path)
- response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
- response.instance_variable_set(:@body, body)
- response.instance_variable_set(:@read, true)
- response
+ create_response(uri)
end
def request(uri, request_class, last_modified = nil)
- data = find_data(uri)
- body, code, msg = (data.respond_to?(:call) ? data.call : data)
-
@last_request = request_class.new uri.request_uri
yield @last_request if block_given?
- response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
- response.instance_variable_set(:@body, body)
- response.instance_variable_set(:@read, true)
- response
+ create_response(uri)
end
def pretty_print(q) # :nodoc:
@@ -121,7 +120,7 @@ class Gem::FakeFetcher
path = path.to_s
@paths << path
- raise ArgumentError, "need full URI" unless path =~ %r{^http://}
+ raise ArgumentError, "need full URI" unless %r{^http://}.match?(path)
unless @data.key? path
raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
@@ -142,7 +141,7 @@ class Gem::FakeFetcher
path = File.join path, name
- if source_uri =~ /^http/
+ if /^http/.match?(source_uri)
File.open(path, "wb") do |f|
f.write fetch_path(File.join(source_uri, "gems", name))
end
@@ -164,6 +163,66 @@ class Gem::FakeFetcher
end
end
+##
+# The HTTPResponseFactory allows easy creation of Gem::Net::HTTPResponse instances in RubyGems tests:
+#
+# Example:
+#
+# Gem::HTTPResponseFactory.create(
+# body: "",
+# code: 301,
+# msg: "Moved Permanently",
+# headers: { "location" => "http://example.com" }
+# )
+#
+
+class Gem::HTTPResponseFactory
+ def self.create(body:, code:, msg:, headers: {})
+ response = Gem::Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
+ response.instance_variable_set(:@body, body)
+ response.instance_variable_set(:@read, true)
+ headers.each {|name, value| response[name] = value }
+
+ response
+ end
+end
+
+##
+# A Gem::MockBrowser is used in tests to mock a browser in that it can
+# send HTTP requests to the defined URI.
+#
+# Example:
+#
+# # Sends a get request to http://localhost:5678
+# Gem::MockBrowser.get Gem::URI("http://localhost:5678")
+#
+# See RubyGems' tests for more examples of MockBrowser.
+#
+
+class Gem::MockBrowser
+ def self.options(uri)
+ options = Gem::Net::HTTP::Options.new(uri)
+ Gem::Net::HTTP.start(uri.hostname, uri.port) do |http|
+ http.request(options)
+ end
+ end
+
+ def self.get(uri)
+ get = Gem::Net::HTTP::Get.new(uri)
+ Gem::Net::HTTP.start(uri.hostname, uri.port) do |http|
+ http.request(get)
+ end
+ end
+
+ def self.post(uri, content_type: "application/x-www-form-urlencoded")
+ headers = { "content-type" => content_type } if content_type
+ post = Gem::Net::HTTP::Post.new(uri, headers)
+ Gem::Net::HTTP.start(uri.hostname, uri.port) do |http|
+ http.request(post)
+ end
+ end
+end
+
# :stopdoc:
class Gem::RemoteFetcher
def self.fetcher=(fetcher)
@@ -307,13 +366,14 @@ class Gem::TestCase::SpecFetcherSetup
Gem::Specification.reset
begin
- gem_repo, @test.gem_repo = @test.gem_repo, @repository
- @test.uri = URI @repository
+ gem_repo = @test.gem_repo
+ @test.gem_repo = @repository
+ @test.uri = Gem::URI @repository
@test.util_setup_spec_fetcher(*@downloaded)
ensure
@test.gem_repo = gem_repo
- @test.uri = URI gem_repo
+ @test.uri = Gem::URI gem_repo
end
@gems.each do |spec, gem|
@@ -350,7 +410,7 @@ end
#
# This class was added to flush out problems in Rubinius' IO implementation.
-class TempIO < Tempfile
+class Gem::TempIO < Tempfile
##
# Creates a new TempIO that will be initialized to contain +string+.
@@ -369,3 +429,8 @@ class TempIO < Tempfile
Gem.read_binary path
end
end
+
+class Gem::TestCase
+ TempIO = Gem::TempIO
+ HTTPResponseFactory = Gem::HTTPResponseFactory
+end
diff --git a/test/rubygems/wrong_key_cert.pem b/test/rubygems/wrong_key_cert.pem
index 23396d7c81..2f2cffbc61 100644
--- a/test/rubygems/wrong_key_cert.pem
+++ b/test/rubygems/wrong_key_cert.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDDTCCAfWgAwIBAgIBEjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDDTCCAfWgAwIBAgIBEjANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoYDzk5
OTkxMjMxMjM1OTU5WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ
-FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvZQipBa1
-xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu2ERWNnblm85upqBfjyZEnKer
-7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0B6SiWFYz3dYPS92bBK7Vks2/
-kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsjrZmXfIZrh7lkHhgCIrzPefjE
-3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PEOW80AD5w0THxDutGG0zPNCDy
-DEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISWTSpCp0Ww1QB55PONiCCn+o6v
-cIy46jI71dATAQIDAQABozwwOjAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAd
-BgNVHQ4EFgQUyvn/FwcZnA7AkzPjmoooB4/tKgcwDQYJKoZIhvcNAQEFBQADggEB
-ABswixv3veo8S0Omyhbch3t19xAd/I4ZAx/lq6a/Ubl+X33hRbZQ7ulXja6Y5ZCs
-iIkezGcpc182e7hZdHuEGGnJ1fJwxz3rbFWvs+MrtRSaCC73HbbxF1x0mQY6Kc7W
-PahB2v+Dx5n3dIN6ah5p+STUHmzhKGr3bsQswtSHrFn74wt6mBu/hyCz+t6UaQ7b
-rpRpzDFO1q3tZB8MeIHg57Lk2bu0LtfaHdkGDghNa3t7oZfV5A6pruiTy/EdQvFL
-ZJpvDgHCyUsDmukMMjz6U4ts+nx7kZ9JoIH9K2lMJo3SGw4iZ8rB+HTfsbUdRfBj
-UlyNcLqCW+FPlUHgHgNugFA=
+FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApebGm7NO
+nx+DtWG1xQsJBfTfwNlZvfzY61nlZccrhU6vx0AnYNiDZAG3J/gFQmYZ9gJ98rzE
+wfLMCGq9R/TZM+lAEaLhzYZCu3X4QdhKxr1xZ/SFC+1f8KVuH4tLXORW30DwayPh
+NxnrOvup4pWLiYuXUSZpV9CGMvPSUCW2odhMkBMKqaTTPjxoXJIcgacyprkNgIq4
+8cSvqWG/e/HrMRtkqvFbD5ta00uO1mlpajYYw1RRftEwktFo8vQgDBo9NT/EqoE7
+2tffaDnLq6rQrVtw4Kr9fy775DjNAWXyiCBjnJgOQSXCGPsM/AEdFrh/LKQQv2M/
+M7WNevnEUgsEIwIDAQABozwwOjAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAd
+BgNVHQ4EFgQUYPwS8g98+4Tq/8gcEK1iilkGXH4wDQYJKoZIhvcNAQELBQADggEB
+AJacpAT2GQQn5Rmb/LYaPhguWFHEdjHBO6rU0p7tE8QJW5pwMgim0mFtQlbuXE2L
+mbHrYCyRgVyaPV9gNiFg1sLzQMmmG4Afg1N4cpdg8zLZFZho+eyYGRkH+EtrAN0Q
+l8l603zovMXj8q8Q1eeurxkDHA6mDgwwMGiBQgAiPixQVOjvL+5M5PkwNw/kVzjA
+0EXumGQkeZ1jUAkVjp7uWbyoVatamUcpYvo51NQQQeuqwzdo2oDYLa27axWxaqj2
+m4TKsz2WnnrSnrpq3NnflXfWcOrnXI3odNlhQoPmtZQVt6P8pNbGrx4XD/WTGkGw
+i/6jlkwwjK7A7dSepfnTI4Y=
-----END CERTIFICATE-----
diff --git a/test/rubygems/wrong_key_cert_32.pem b/test/rubygems/wrong_key_cert_32.pem
index 7a3bb9f714..aca829ab44 100644
--- a/test/rubygems/wrong_key_cert_32.pem
+++ b/test/rubygems/wrong_key_cert_32.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDCzCCAfOgAwIBAgIBEzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+MIIDCzCCAfOgAwIBAgIBEzANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv
ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoXDTM4
MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH
-ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2UIqQWtcR9
-zPTqJ5K1GIRmXl/VBwHCYXuoyW1K/7h15IdU7thEVjZ25ZvObqagX48mRJynq+7g
-XMMJJL5orFYAvLgRAsprAcbhCMNK34imBJy7tAekolhWM93WD0vdmwSu1ZLNv5Dc
-l1JiyxqGd4nditHiuQvwCdI/qfODqj51YcpbI62Zl3yGa4e5ZB4YAiK8z3n4xN6T
-paIv7c+n4dpLW9BWCkDH8Hk9wWtkzHn5RtdzxDlvNAA+cNEx8Q7rRhtMzzQg8gxK
-E+1FNWtwd0TB2LlMRJNRlBGFqvS+mukjKWSElk0qQqdFsNUAeeTzjYggp/qOr3CM
-uOoyO9XQEwECAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD
-VR0OBBYEFMr5/xcHGZwOwJMz45qKKAeP7SoHMA0GCSqGSIb3DQEBBQUAA4IBAQCU
-VkESWkNeiJ1L3MfkMl2ybP2QPWP5nlhz+NOqwOCJSmEXF86Dq2XTY/GgSu1iPp4s
-pPm1RSpnjujtiV7gjCziNif/XqAxeSjU2deApvq4mknyk958N0IS8c86dUXms1DQ
-Rncmb3pxxvzP1d6Is35Uwoc5KqheJWR3aDwE8ejaFfO8pq/ncUDB25bc7OyslHMJ
-7Ah+2YlFjvHYuPvN8bP44UMYyAPZCCJnjIPn7m7giyQiIo6SA9aiLQ8F7+NN3SU4
-7I9ED0F7RTDxNYISr1sLZ7aNtnXkTAnZclwKohuGfZD3OGAOshLZZXIB2pIRr/Kj
-6zxTef39tli6orheYQXp
+ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKXmxpuzTp8f
+g7VhtcULCQX038DZWb382OtZ5WXHK4VOr8dAJ2DYg2QBtyf4BUJmGfYCffK8xMHy
+zAhqvUf02TPpQBGi4c2GQrt1+EHYSsa9cWf0hQvtX/Clbh+LS1zkVt9A8Gsj4TcZ
+6zr7qeKVi4mLl1EmaVfQhjLz0lAltqHYTJATCqmk0z48aFySHIGnMqa5DYCKuPHE
+r6lhv3vx6zEbZKrxWw+bWtNLjtZpaWo2GMNUUX7RMJLRaPL0IAwaPTU/xKqBO9rX
+32g5y6uq0K1bcOCq/X8u++Q4zQFl8oggY5yYDkElwhj7DPwBHRa4fyykEL9jPzO1
+jXr5xFILBCMCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD
+VR0OBBYEFGD8EvIPfPuE6v/IHBCtYopZBlx+MA0GCSqGSIb3DQEBCwUAA4IBAQBE
+lq/rPaPT+5uui42u4BTFayrQU9EFik9xPG6WJw+IJ/5CprECj6h90FC+GaMNeu2Z
+R0l+iEfgx4xBM4DERiRVLZIlHbZzuPp0YRYH9gyJot/+0piaAcnUEvjz2Z8axoFq
+lE3/q4s6Yw8xdqwxvc5kiwymv2nEm4+v5w6Pb3K/fP/QQLvDUBWrBUMHPgdYXYk2
+zvc58BBwgGDSpFRO0tw+lnqMTM1y+fbpfuvP9TY1m4y13nuw/g7KxVxYolAWVQs3
+TptnJqqzEwdFa2S9BidUIlDRRY8cuhY6R3DM6THNLjR3c1oyf04nhT3sd/ilAJdD
+YjnEtcLlkjxZyLLoWjn2
-----END CERTIFICATE-----
diff --git a/test/runner.rb b/test/runner.rb
index 1b1ae0956a..c34517cbf2 100644
--- a/test/runner.rb
+++ b/test/runner.rb
@@ -1,14 +1,5 @@
# frozen_string_literal: true
-# Should be done in rubygems test files?
-ENV["GEM_SKIP"] = ENV["GEM_HOME"] = ENV["GEM_PATH"] = "".freeze
-ENV.delete("RUBY_CODESIGN")
-
-Warning[:experimental] = false
-
-# Get bundled gems on load path
-Dir.glob("#{__dir__}/../.bundle/gems/*/*.gemspec")
- .reject {|f| f =~ /minitest|test-unit|power_assert/ }
- .map {|f| $LOAD_PATH.unshift File.join(File.dirname(f), "lib") }
+# NOTE: Do not add any settings here for test-all. Instead, please add it to ../tool/test/init.rb.
require_relative '../tool/test/runner'
diff --git a/test/fixtures/fake_sorted_set_gem/sorted_set.rb b/test/set/fixtures/fake_sorted_set_gem/sorted_set.rb
index f45a766303..f45a766303 100644
--- a/test/fixtures/fake_sorted_set_gem/sorted_set.rb
+++ b/test/set/fixtures/fake_sorted_set_gem/sorted_set.rb
diff --git a/test/set/test_set.rb b/test/set/test_set.rb
new file mode 100644
index 0000000000..49dc58ef7b
--- /dev/null
+++ b/test/set/test_set.rb
@@ -0,0 +1,892 @@
+# frozen_string_literal: false
+require 'test/unit'
+require 'set'
+
+class TC_Set < Test::Unit::TestCase
+ class Set2 < Set
+ end
+
+ def test_aref
+ assert_nothing_raised {
+ Set[]
+ Set[nil]
+ Set[1,2,3]
+ }
+
+ assert_equal(0, Set[].size)
+ assert_equal(1, Set[nil].size)
+ assert_equal(1, Set[[]].size)
+ assert_equal(1, Set[[nil]].size)
+
+ set = Set[2,4,6,4]
+ assert_equal(Set.new([2,4,6]), set)
+ end
+
+ def test_s_new
+ assert_nothing_raised {
+ Set.new()
+ Set.new(nil)
+ Set.new([])
+ Set.new([1,2])
+ Set.new('a'..'c')
+ }
+ assert_raise(ArgumentError) {
+ Set.new(false)
+ }
+ assert_raise(ArgumentError) {
+ Set.new(1)
+ }
+ assert_raise(ArgumentError) {
+ Set.new(1,2)
+ }
+
+ assert_equal(0, Set.new().size)
+ assert_equal(0, Set.new(nil).size)
+ assert_equal(0, Set.new([]).size)
+ assert_equal(1, Set.new([nil]).size)
+
+ ary = [2,4,6,4]
+ set = Set.new(ary)
+ ary.clear
+ assert_equal(false, set.empty?)
+ assert_equal(3, set.size)
+
+ ary = [1,2,3]
+
+ s = Set.new(ary) { |o| o * 2 }
+ assert_equal([2,4,6], s.sort)
+ end
+
+ def test_clone
+ set1 = Set.new
+ set2 = set1.clone
+ set1 << 'abc'
+ assert_equal(Set.new, set2)
+ end
+
+ def test_dup
+ set1 = Set[1,2]
+ set2 = set1.dup
+
+ assert_not_same(set1, set2)
+
+ assert_equal(set1, set2)
+
+ set1.add(3)
+
+ assert_not_equal(set1, set2)
+ end
+
+ def test_size
+ assert_equal(0, Set[].size)
+ assert_equal(2, Set[1,2].size)
+ assert_equal(2, Set[1,2,1].size)
+ end
+
+ def test_empty?
+ assert_equal(true, Set[].empty?)
+ assert_equal(false, Set[1, 2].empty?)
+ end
+
+ def test_clear
+ set = Set[1,2]
+ ret = set.clear
+
+ assert_same(set, ret)
+ assert_equal(true, set.empty?)
+ end
+
+ def test_replace
+ set = Set[1,2]
+ ret = set.replace('a'..'c')
+
+ assert_same(set, ret)
+ assert_equal(Set['a','b','c'], set)
+
+ set = Set[1,2]
+ assert_raise(ArgumentError) {
+ set.replace(3)
+ }
+ assert_equal(Set[1,2], set)
+ end
+
+ def test_to_a
+ set = Set[1,2,3,2]
+ ary = set.to_a
+
+ assert_equal([1,2,3], ary.sort)
+ end
+
+ def test_flatten
+ # test1
+ set1 = Set[
+ 1,
+ Set[
+ 5,
+ Set[7,
+ Set[0]
+ ],
+ Set[6,2],
+ 1
+ ],
+ 3,
+ Set[3,4]
+ ]
+
+ set2 = set1.flatten
+ set3 = Set.new(0..7)
+
+ assert_not_same(set2, set1)
+ assert_equal(set3, set2)
+
+ # test2; destructive
+ orig_set1 = set1
+ set1.flatten!
+
+ assert_same(orig_set1, set1)
+ assert_equal(set3, set1)
+
+ # test3; multiple occurrences of a set in an set
+ set1 = Set[1, 2]
+ set2 = Set[set1, Set[set1, 4], 3]
+
+ assert_nothing_raised {
+ set2.flatten!
+ }
+
+ assert_equal(Set.new(1..4), set2)
+
+ # test4; recursion
+ set2 = Set[]
+ set1 = Set[1, set2]
+ set2.add(set1)
+
+ assert_raise(ArgumentError) {
+ set1.flatten!
+ }
+
+ # test5; miscellaneous
+ empty = Set[]
+ set = Set[Set[empty, "a"],Set[empty, "b"]]
+
+ assert_nothing_raised {
+ set.flatten
+ }
+
+ set1 = empty.merge(Set["no_more", set])
+
+ assert_nil(Set.new(0..31).flatten!)
+
+ x = Set[Set[],Set[1,2]].flatten!
+ y = Set[1,2]
+
+ assert_equal(x, y)
+ end
+
+ def test_include?
+ set = Set[1,2,3]
+
+ assert_equal(true, set.include?(1))
+ assert_equal(true, set.include?(2))
+ assert_equal(true, set.include?(3))
+ assert_equal(false, set.include?(0))
+ assert_equal(false, set.include?(nil))
+
+ set = Set["1",nil,"2",nil,"0","1",false]
+ assert_equal(true, set.include?(nil))
+ assert_equal(true, set.include?(false))
+ assert_equal(true, set.include?("1"))
+ assert_equal(false, set.include?(0))
+ assert_equal(false, set.include?(true))
+ end
+
+ def test_eqq
+ set = Set[1,2,3]
+
+ assert_equal(true, set === 1)
+ assert_equal(true, set === 2)
+ assert_equal(true, set === 3)
+ assert_equal(false, set === 0)
+ assert_equal(false, set === nil)
+
+ set = Set["1",nil,"2",nil,"0","1",false]
+ assert_equal(true, set === nil)
+ assert_equal(true, set === false)
+ assert_equal(true, set === "1")
+ assert_equal(false, set === 0)
+ assert_equal(false, set === true)
+ end
+
+ def test_superset?
+ set = Set[1,2,3]
+
+ assert_raise(ArgumentError) {
+ set.superset?()
+ }
+
+ assert_raise(ArgumentError) {
+ set.superset?(2)
+ }
+
+ assert_raise(ArgumentError) {
+ set.superset?([2])
+ }
+
+ [Set, Set2].each { |klass|
+ assert_equal(true, set.superset?(klass[]), klass.name)
+ assert_equal(true, set.superset?(klass[1,2]), klass.name)
+ assert_equal(true, set.superset?(klass[1,2,3]), klass.name)
+ assert_equal(false, set.superset?(klass[1,2,3,4]), klass.name)
+ assert_equal(false, set.superset?(klass[1,4]), klass.name)
+
+ assert_equal(true, set >= klass[1,2,3], klass.name)
+ assert_equal(true, set >= klass[1,2], klass.name)
+
+ assert_equal(true, Set[].superset?(klass[]), klass.name)
+ }
+ end
+
+ def test_proper_superset?
+ set = Set[1,2,3]
+
+ assert_raise(ArgumentError) {
+ set.proper_superset?()
+ }
+
+ assert_raise(ArgumentError) {
+ set.proper_superset?(2)
+ }
+
+ assert_raise(ArgumentError) {
+ set.proper_superset?([2])
+ }
+
+ [Set, Set2].each { |klass|
+ assert_equal(true, set.proper_superset?(klass[]), klass.name)
+ assert_equal(true, set.proper_superset?(klass[1,2]), klass.name)
+ assert_equal(false, set.proper_superset?(klass[1,2,3]), klass.name)
+ assert_equal(false, set.proper_superset?(klass[1,2,3,4]), klass.name)
+ assert_equal(false, set.proper_superset?(klass[1,4]), klass.name)
+
+ assert_equal(false, set > klass[1,2,3], klass.name)
+ assert_equal(true, set > klass[1,2], klass.name)
+
+ assert_equal(false, Set[].proper_superset?(klass[]), klass.name)
+ }
+ end
+
+ def test_subset?
+ set = Set[1,2,3]
+
+ assert_raise(ArgumentError) {
+ set.subset?()
+ }
+
+ assert_raise(ArgumentError) {
+ set.subset?(2)
+ }
+
+ assert_raise(ArgumentError) {
+ set.subset?([2])
+ }
+
+ [Set, Set2].each { |klass|
+ assert_equal(true, set.subset?(klass[1,2,3,4]), klass.name)
+ assert_equal(true, set.subset?(klass[1,2,3]), klass.name)
+ assert_equal(false, set.subset?(klass[1,2]), klass.name)
+ assert_equal(false, set.subset?(klass[]), klass.name)
+
+ assert_equal(true, set <= klass[1,2,3], klass.name)
+ assert_equal(true, set <= klass[1,2,3,4], klass.name)
+
+ assert_equal(true, Set[].subset?(klass[1]), klass.name)
+ assert_equal(true, Set[].subset?(klass[]), klass.name)
+ }
+ end
+
+ def test_proper_subset?
+ set = Set[1,2,3]
+
+ assert_raise(ArgumentError) {
+ set.proper_subset?()
+ }
+
+ assert_raise(ArgumentError) {
+ set.proper_subset?(2)
+ }
+
+ assert_raise(ArgumentError) {
+ set.proper_subset?([2])
+ }
+
+ [Set, Set2].each { |klass|
+ assert_equal(true, set.proper_subset?(klass[1,2,3,4]), klass.name)
+ assert_equal(false, set.proper_subset?(klass[1,2,3]), klass.name)
+ assert_equal(false, set.proper_subset?(klass[1,2]), klass.name)
+ assert_equal(false, set.proper_subset?(klass[]), klass.name)
+
+ assert_equal(false, set < klass[1,2,3], klass.name)
+ assert_equal(true, set < klass[1,2,3,4], klass.name)
+
+ assert_equal(false, Set[].proper_subset?(klass[]), klass.name)
+ }
+ end
+
+ def test_spacecraft_operator
+ set = Set[1,2,3]
+
+ assert_nil(set <=> 2)
+
+ assert_nil(set <=> set.to_a)
+
+ [Set, Set2].each { |klass|
+ assert_equal(-1, set <=> klass[1,2,3,4], klass.name)
+ assert_equal( 0, set <=> klass[3,2,1] , klass.name)
+ assert_equal(nil, set <=> klass[1,2,4] , klass.name)
+ assert_equal(+1, set <=> klass[2,3] , klass.name)
+ assert_equal(+1, set <=> klass[] , klass.name)
+
+ assert_equal(0, Set[] <=> klass[], klass.name)
+ }
+ end
+
+ def assert_intersect(expected, set, other)
+ case expected
+ when true
+ assert_send([set, :intersect?, other])
+ assert_send([set, :intersect?, other.to_a])
+ assert_send([other, :intersect?, set])
+ assert_not_send([set, :disjoint?, other])
+ assert_not_send([set, :disjoint?, other.to_a])
+ assert_not_send([other, :disjoint?, set])
+ when false
+ assert_not_send([set, :intersect?, other])
+ assert_not_send([set, :intersect?, other.to_a])
+ assert_not_send([other, :intersect?, set])
+ assert_send([set, :disjoint?, other])
+ assert_send([set, :disjoint?, other.to_a])
+ assert_send([other, :disjoint?, set])
+ when Class
+ assert_raise(expected) {
+ set.intersect?(other)
+ }
+ assert_raise(expected) {
+ set.disjoint?(other)
+ }
+ else
+ raise ArgumentError, "%s: unsupported expected value: %s" % [__method__, expected.inspect]
+ end
+ end
+
+ def test_intersect?
+ set = Set[3,4,5]
+
+ assert_intersect(ArgumentError, set, 3)
+ assert_intersect(true, set, Set[2,4,6])
+
+ assert_intersect(true, set, set)
+ assert_intersect(true, set, Set[2,4])
+ assert_intersect(true, set, Set[5,6,7])
+ assert_intersect(true, set, Set[1,2,6,8,4])
+
+ assert_intersect(false, set, Set[])
+ assert_intersect(false, set, Set[0,2])
+ assert_intersect(false, set, Set[0,2,6])
+ assert_intersect(false, set, Set[0,2,6,8,10])
+
+ # Make sure set hasn't changed
+ assert_equal(Set[3,4,5], set)
+ end
+
+ def test_each
+ ary = [1,3,5,7,10,20]
+ set = Set.new(ary)
+
+ ret = set.each { |o| }
+ assert_same(set, ret)
+
+ e = set.each
+ assert_instance_of(Enumerator, e)
+
+ assert_nothing_raised {
+ set.each { |o|
+ ary.delete(o) or raise "unexpected element: #{o}"
+ }
+
+ ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
+ }
+
+ assert_equal(6, e.size)
+ set << 42
+ assert_equal(7, e.size)
+ end
+
+ def test_add
+ set = Set[1,2,3]
+
+ ret = set.add(2)
+ assert_same(set, ret)
+ assert_equal(Set[1,2,3], set)
+
+ ret = set.add?(2)
+ assert_nil(ret)
+ assert_equal(Set[1,2,3], set)
+
+ ret = set.add(4)
+ assert_same(set, ret)
+ assert_equal(Set[1,2,3,4], set)
+
+ ret = set.add?(5)
+ assert_same(set, ret)
+ assert_equal(Set[1,2,3,4,5], set)
+ end
+
+ def test_delete
+ set = Set[1,2,3]
+
+ ret = set.delete(4)
+ assert_same(set, ret)
+ assert_equal(Set[1,2,3], set)
+
+ ret = set.delete?(4)
+ assert_nil(ret)
+ assert_equal(Set[1,2,3], set)
+
+ ret = set.delete(2)
+ assert_equal(set, ret)
+ assert_equal(Set[1,3], set)
+
+ ret = set.delete?(1)
+ assert_equal(set, ret)
+ assert_equal(Set[3], set)
+ end
+
+ def test_delete_if
+ set = Set.new(1..10)
+ ret = set.delete_if { |i| i > 10 }
+ assert_same(set, ret)
+ assert_equal(Set.new(1..10), set)
+
+ set = Set.new(1..10)
+ ret = set.delete_if { |i| i % 3 == 0 }
+ assert_same(set, ret)
+ assert_equal(Set[1,2,4,5,7,8,10], set)
+
+ set = Set.new(1..10)
+ enum = set.delete_if
+ assert_equal(set.size, enum.size)
+ assert_same(set, enum.each { |i| i % 3 == 0 })
+ assert_equal(Set[1,2,4,5,7,8,10], set)
+ end
+
+ def test_keep_if
+ set = Set.new(1..10)
+ ret = set.keep_if { |i| i <= 10 }
+ assert_same(set, ret)
+ assert_equal(Set.new(1..10), set)
+
+ set = Set.new(1..10)
+ ret = set.keep_if { |i| i % 3 != 0 }
+ assert_same(set, ret)
+ assert_equal(Set[1,2,4,5,7,8,10], set)
+
+ set = Set.new(1..10)
+ enum = set.keep_if
+ assert_equal(set.size, enum.size)
+ assert_same(set, enum.each { |i| i % 3 != 0 })
+ assert_equal(Set[1,2,4,5,7,8,10], set)
+ end
+
+ def test_collect!
+ set = Set[1,2,3,'a','b','c',-1..1,2..4]
+
+ ret = set.collect! { |i|
+ case i
+ when Numeric
+ i * 2
+ when String
+ i.upcase
+ else
+ nil
+ end
+ }
+
+ assert_same(set, ret)
+ assert_equal(Set[2,4,6,'A','B','C',nil], set)
+
+ set = Set[1,2,3,'a','b','c',-1..1,2..4]
+ enum = set.collect!
+
+ assert_equal(set.size, enum.size)
+ assert_same(set, enum.each { |i|
+ case i
+ when Numeric
+ i * 2
+ when String
+ i.upcase
+ else
+ nil
+ end
+ })
+ assert_equal(Set[2,4,6,'A','B','C',nil], set)
+ end
+
+ def test_reject!
+ set = Set.new(1..10)
+
+ ret = set.reject! { |i| i > 10 }
+ assert_nil(ret)
+ assert_equal(Set.new(1..10), set)
+
+ ret = set.reject! { |i| i % 3 == 0 }
+ assert_same(set, ret)
+ assert_equal(Set[1,2,4,5,7,8,10], set)
+
+ set = Set.new(1..10)
+ enum = set.reject!
+ assert_equal(set.size, enum.size)
+ assert_same(set, enum.each { |i| i % 3 == 0 })
+ assert_equal(Set[1,2,4,5,7,8,10], set)
+ end
+
+ def test_select!
+ set = Set.new(1..10)
+ ret = set.select! { |i| i <= 10 }
+ assert_equal(nil, ret)
+ assert_equal(Set.new(1..10), set)
+
+ set = Set.new(1..10)
+ ret = set.select! { |i| i % 3 != 0 }
+ assert_same(set, ret)
+ assert_equal(Set[1,2,4,5,7,8,10], set)
+
+ set = Set.new(1..10)
+ enum = set.select!
+ assert_equal(set.size, enum.size)
+ assert_equal(nil, enum.each { |i| i <= 10 })
+ assert_equal(Set.new(1..10), set)
+ end
+
+ def test_filter!
+ set = Set.new(1..10)
+ ret = set.filter! { |i| i <= 10 }
+ assert_equal(nil, ret)
+ assert_equal(Set.new(1..10), set)
+
+ set = Set.new(1..10)
+ ret = set.filter! { |i| i % 3 != 0 }
+ assert_same(set, ret)
+ assert_equal(Set[1,2,4,5,7,8,10], set)
+
+ set = Set.new(1..10)
+ enum = set.filter!
+ assert_equal(set.size, enum.size)
+ assert_equal(nil, enum.each { |i| i <= 10 })
+ assert_equal(Set.new(1..10), set)
+ end
+
+ def test_merge
+ set = Set[1,2,3]
+ ret = set.merge([2,4,6])
+ assert_same(set, ret)
+ assert_equal(Set[1,2,3,4,6], set)
+
+ set = Set[1,2,3]
+ ret = set.merge()
+ assert_same(set, ret)
+ assert_equal(Set[1,2,3], set)
+
+ set = Set[1,2,3]
+ ret = set.merge([2,4,6], Set[4,5,6])
+ assert_same(set, ret)
+ assert_equal(Set[1,2,3,4,5,6], set)
+
+ assert_raise(ArgumentError) {
+ Set[].merge(a: 1)
+ }
+ end
+
+ def test_subtract
+ set = Set[1,2,3]
+
+ ret = set.subtract([2,4,6])
+ assert_same(set, ret)
+ assert_equal(Set[1,3], set)
+ end
+
+ def test_plus
+ set = Set[1,2,3]
+
+ ret = set + [2,4,6]
+ assert_not_same(set, ret)
+ assert_equal(Set[1,2,3,4,6], ret)
+ end
+
+ def test_minus
+ set = Set[1,2,3]
+
+ ret = set - [2,4,6]
+ assert_not_same(set, ret)
+ assert_equal(Set[1,3], ret)
+ end
+
+ def test_and
+ set = Set[1,2,3,4]
+
+ ret = set & [2,4,6]
+ assert_not_same(set, ret)
+ assert_equal(Set[2,4], ret)
+ end
+
+ def test_xor
+ set = Set[1,2,3,4]
+ ret = set ^ [2,4,5,5]
+ assert_not_same(set, ret)
+ assert_equal(Set[1,3,5], ret)
+ end
+
+ def test_eq
+ set1 = Set[2,3,1]
+ set2 = Set[1,2,3]
+
+ assert_equal(set1, set1)
+ assert_equal(set1, set2)
+ assert_not_equal(Set[1], [1])
+
+ set1 = Class.new(Set)["a", "b"]
+ set1.add(set1).reset # Make recursive
+ set2 = Set["a", "b", Set["a", "b", set1]]
+
+ assert_equal(set1, set2)
+
+ assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], "[ruby-dev:26127]")
+ end
+
+ def test_classify
+ set = Set.new(1..10)
+ ret = set.classify { |i| i % 3 }
+
+ assert_equal(3, ret.size)
+ assert_instance_of(Hash, ret)
+ ret.each_value { |value| assert_instance_of(Set, value) }
+ assert_equal(Set[3,6,9], ret[0])
+ assert_equal(Set[1,4,7,10], ret[1])
+ assert_equal(Set[2,5,8], ret[2])
+
+ set = Set.new(1..10)
+ enum = set.classify
+
+ assert_equal(set.size, enum.size)
+ ret = enum.each { |i| i % 3 }
+ assert_equal(3, ret.size)
+ assert_instance_of(Hash, ret)
+ ret.each_value { |value| assert_instance_of(Set, value) }
+ assert_equal(Set[3,6,9], ret[0])
+ assert_equal(Set[1,4,7,10], ret[1])
+ assert_equal(Set[2,5,8], ret[2])
+ end
+
+ def test_divide
+ set = Set.new(1..10)
+ ret = set.divide { |i| i % 3 }
+
+ assert_equal(3, ret.size)
+ n = 0
+ ret.each { |s| n += s.size }
+ assert_equal(set.size, n)
+ assert_equal(set, ret.flatten)
+
+ set = Set[7,10,5,11,1,3,4,9,0]
+ ret = set.divide { |a,b| (a - b).abs == 1 }
+
+ assert_equal(4, ret.size)
+ n = 0
+ ret.each { |s| n += s.size }
+ assert_equal(set.size, n)
+ assert_equal(set, ret.flatten)
+ ret.each { |s|
+ if s.include?(0)
+ assert_equal(Set[0,1], s)
+ elsif s.include?(3)
+ assert_equal(Set[3,4,5], s)
+ elsif s.include?(7)
+ assert_equal(Set[7], s)
+ elsif s.include?(9)
+ assert_equal(Set[9,10,11], s)
+ else
+ raise "unexpected group: #{s.inspect}"
+ end
+ }
+
+ set = Set.new(1..10)
+ enum = set.divide
+ ret = enum.each { |i| i % 3 }
+
+ assert_equal(set.size, enum.size)
+ assert_equal(3, ret.size)
+ n = 0
+ ret.each { |s| n += s.size }
+ assert_equal(set.size, n)
+ assert_equal(set, ret.flatten)
+ end
+
+ def test_freeze
+ orig = set = Set[1,2,3]
+ assert_equal false, set.frozen?
+ set << 4
+ assert_same orig, set.freeze
+ assert_equal true, set.frozen?
+ assert_raise(FrozenError) {
+ set << 5
+ }
+ assert_equal 4, set.size
+ end
+
+ def test_freeze_dup
+ set1 = Set[1,2,3]
+ set1.freeze
+ set2 = set1.dup
+
+ assert_not_predicate set2, :frozen?
+ assert_nothing_raised {
+ set2.add 4
+ }
+ end
+
+ def test_freeze_clone
+ set1 = Set[1,2,3]
+ set1.freeze
+ set2 = set1.clone
+
+ assert_predicate set2, :frozen?
+ assert_raise(FrozenError) {
+ set2.add 5
+ }
+ end
+
+ def test_freeze_clone_false
+ set1 = Set[1,2,3]
+ set1.freeze
+ set2 = set1.clone(freeze: false)
+
+ assert_not_predicate set2, :frozen?
+ set2.add 5
+ assert_equal Set[1,2,3,5], set2
+ assert_equal Set[1,2,3], set1
+ end if Kernel.instance_method(:initialize_clone).arity != 1
+
+ def test_join
+ assert_equal('123', Set[1, 2, 3].join)
+ assert_equal('1 & 2 & 3', Set[1, 2, 3].join(' & '))
+ end
+
+ def test_inspect
+ set1 = Set[1, 2]
+ assert_equal('#<Set: {1, 2}>', set1.inspect)
+
+ set2 = Set[Set[0], 1, 2, set1]
+ assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2}>}>', set2.inspect)
+
+ set1.add(set2)
+ assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2, #<Set: {...}>}>}>', set2.inspect)
+ end
+
+ def test_to_s
+ set1 = Set[1, 2]
+ assert_equal('#<Set: {1, 2}>', set1.to_s)
+
+ set2 = Set[Set[0], 1, 2, set1]
+ assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2}>}>', set2.to_s)
+
+ set1.add(set2)
+ assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2, #<Set: {...}>}>}>', set2.to_s)
+ end
+
+ def test_compare_by_identity
+ a1, a2 = "a", "a"
+ b1, b2 = "b", "b"
+ c = "c"
+ array = [a1, b1, c, a2, b2]
+
+ iset = Set.new.compare_by_identity
+ assert_send([iset, :compare_by_identity?])
+ iset.merge(array)
+ assert_equal(5, iset.size)
+ assert_equal(array.map(&:object_id).sort, iset.map(&:object_id).sort)
+
+ set = Set.new
+ assert_not_send([set, :compare_by_identity?])
+ set.merge(array)
+ assert_equal(3, set.size)
+ assert_equal(array.uniq.sort, set.sort)
+ end
+
+ def test_reset
+ [Set, Class.new(Set)].each { |klass|
+ a = [1, 2]
+ b = [1]
+ set = klass.new([a, b])
+
+ b << 2
+ set.reset
+
+ assert_equal(klass.new([a]), set, klass.name)
+ }
+ end
+end
+
+class TC_Enumerable < Test::Unit::TestCase
+ def test_to_set
+ ary = [2,5,4,3,2,1,3]
+
+ set = ary.to_set
+ assert_instance_of(Set, set)
+ assert_equal([1,2,3,4,5], set.sort)
+
+ set = ary.to_set { |o| o * -2 }
+ assert_instance_of(Set, set)
+ assert_equal([-10,-8,-6,-4,-2], set.sort)
+
+ assert_same set, set.to_set
+ assert_not_same set, set.to_set { |o| o }
+ end
+end
+
+class TC_Set_Builtin < Test::Unit::TestCase
+ private def should_omit?
+ (RUBY_VERSION.scan(/\d+/).map(&:to_i) <=> [3, 2]) < 0 ||
+ !File.exist?(File.expand_path('../prelude.rb', __dir__))
+ end
+
+ def test_Set
+ omit "skipping the test for the builtin Set" if should_omit?
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_nothing_raised do
+ set = Set.new([1, 2])
+ assert_equal('Set', set.class.name)
+ end
+ end;
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_nothing_raised do
+ set = Set[1, 2]
+ assert_equal('Set', set.class.name)
+ end
+ end;
+ end
+
+ def test_to_set
+ omit "skipping the test for the builtin Enumerable#to_set" if should_omit?
+
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ assert_nothing_raised do
+ set = [1, 2].to_set
+ assert_equal('Set', set.class.name)
+ end
+ end;
+ end
+end
diff --git a/test/test_sorted_set.rb b/test/set/test_sorted_set.rb
index f7ad7af299..f7ad7af299 100644
--- a/test/test_sorted_set.rb
+++ b/test/set/test_sorted_set.rb
diff --git a/test/socket/test_addrinfo.rb b/test/socket/test_addrinfo.rb
index bdf1f7649e..c61764d76d 100644
--- a/test/socket/test_addrinfo.rb
+++ b/test/socket/test_addrinfo.rb
@@ -103,7 +103,7 @@ class TestSocketAddrinfo < Test::Unit::TestCase
end
def test_error_message
- e = assert_raise_with_message(SocketError, /getaddrinfo/) do
+ e = assert_raise_with_message(Socket::ResolutionError, /getaddrinfo/) do
Addrinfo.ip("...")
end
m = e.message
@@ -357,7 +357,7 @@ class TestSocketAddrinfo < Test::Unit::TestCase
ai = Addrinfo.unix("/testdir/sock").family_addrinfo("/testdir/sock2")
assert_equal("/testdir/sock2", ai.unix_path)
assert_equal(Socket::SOCK_STREAM, ai.socktype)
- assert_raise(SocketError) { Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("::1", 80) }
+ assert_raise(Socket::ResolutionError) { Addrinfo.tcp("0.0.0.0", 4649).family_addrinfo("::1", 80) }
end
def random_port
@@ -373,8 +373,8 @@ class TestSocketAddrinfo < Test::Unit::TestCase
def errors_addrinuse
errs = [Errno::EADDRINUSE]
- # MinGW fails with "Errno::EACCES: Permission denied - bind(2) for 0.0.0.0:49721"
- errs << Errno::EACCES if /mingw/ =~ RUBY_PLATFORM
+ # Windows fails with "Errno::EACCES: Permission denied - bind(2) for 0.0.0.0:49721"
+ errs << Errno::EACCES if /mingw|mswin/ =~ RUBY_PLATFORM
errs
end
diff --git a/test/socket/test_nonblock.rb b/test/socket/test_nonblock.rb
index d9d1e186b2..5a4688bac3 100644
--- a/test/socket/test_nonblock.rb
+++ b/test/socket/test_nonblock.rb
@@ -307,11 +307,13 @@ class TestSocketNonblock < Test::Unit::TestCase
loop { s1.sendmsg_nonblock(buf) }
end
end
- rescue NotImplementedError, Errno::ENOSYS, Errno::EPROTONOSUPPORT
+ rescue NotImplementedError, Errno::ENOSYS, Errno::EPROTONOSUPPORT, Errno::EPROTOTYPE
omit "UNIXSocket.pair(:SEQPACKET) not implemented on this platform: #{$!}"
end
def test_sendmsg_nonblock_no_exception
+ omit "AF_UNIX + SEQPACKET is not supported on windows" if /mswin|mingw/ =~ RUBY_PLATFORM
+
buf = '*' * 4096
UNIXSocket.pair(:SEQPACKET) do |s1, s2|
n = 0
diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb
index 2c945aa9b9..6a057e866f 100644
--- a/test/socket/test_socket.rb
+++ b/test/socket/test_socket.rb
@@ -91,20 +91,20 @@ class TestSocket < Test::Unit::TestCase
def test_getaddrinfo
# This should not send a DNS query because AF_UNIX.
- assert_raise(SocketError) { Socket.getaddrinfo("www.kame.net", 80, "AF_UNIX") }
+ assert_raise(Socket::ResolutionError) { Socket.getaddrinfo("www.kame.net", 80, "AF_UNIX") }
end
def test_getaddrinfo_raises_no_errors_on_port_argument_of_0 # [ruby-core:29427]
assert_nothing_raised('[ruby-core:29427]'){ Socket.getaddrinfo('localhost', 0, Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
assert_nothing_raised('[ruby-core:29427]'){ Socket.getaddrinfo('localhost', '0', Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
assert_nothing_raised('[ruby-core:29427]'){ Socket.getaddrinfo('localhost', '00', Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
- assert_raise(SocketError, '[ruby-core:29427]'){ Socket.getaddrinfo(nil, nil, Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
+ assert_raise(Socket::ResolutionError, '[ruby-core:29427]'){ Socket.getaddrinfo(nil, nil, Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME) }
assert_nothing_raised('[ruby-core:29427]'){ TCPServer.open('localhost', 0) {} }
end
def test_getnameinfo
- assert_raise(SocketError) { Socket.getnameinfo(["AF_UNIX", 80, "0.0.0.0"]) }
+ assert_raise(Socket::ResolutionError) { Socket.getnameinfo(["AF_UNIX", 80, "0.0.0.0"]) }
assert_raise(ArgumentError) {Socket.getnameinfo(["AF_INET", "http\0", "example.net"])}
assert_raise(ArgumentError) {Socket.getnameinfo(["AF_INET", "http", "example.net\0"])}
end
@@ -340,6 +340,10 @@ class TestSocket < Test::Unit::TestCase
end
def test_udp_server
+ # http://rubyci.s3.amazonaws.com/rhel_zlinux/ruby-master/log/20230312T023302Z.fail.html.gz
+ # Errno::EHOSTUNREACH: No route to host - recvmsg(2)
+ omit if 'rhel_zlinux' == ENV['RUBYCI_NICKNAME']
+
begin
ifaddrs = Socket.getifaddrs
rescue NotImplementedError
@@ -443,13 +447,12 @@ class TestSocket < Test::Unit::TestCase
omit "UDP server is no response: #{$!}"
ensure
if th
- if skipped
- Thread.kill th unless th.join(10)
- else
+ unless skipped
Addrinfo.udp("127.0.0.1", port).connect {|s| s.sendmsg "exit" }
- unless th.join(10)
- Thread.kill th
- th.join(10)
+ end
+ unless th.join(10)
+ th.kill.join(10)
+ unless skipped
raise "thread killed"
end
end
@@ -486,13 +489,14 @@ class TestSocket < Test::Unit::TestCase
end while IO.select([r], nil, nil, 0.1).nil?
n
end
- timeout = (defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? ? 120 : 30) # for --jit-wait
+ timeout = (defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? ? 120 : 30) # for --jit-wait
assert_equal([[s1],[],[]], IO.select([s1], nil, nil, timeout))
msg, _, _, stamp = s1.recvmsg
assert_equal("a", msg)
assert(stamp.cmsg_is?(:SOCKET, type))
w.close # stop th
n = th.value
+ th = nil
n > 1 and
warn "UDP packet loss for #{type} over loopback, #{n} tries needed"
t2 = Time.now.strftime("%Y-%m-%d")
@@ -501,6 +505,10 @@ class TestSocket < Test::Unit::TestCase
t = stamp.timestamp
assert_match(pat, t.strftime("%Y-%m-%d"))
stamp
+ ensure
+ if th and !th.join(10)
+ th.kill.join(10)
+ end
end
end
@@ -583,7 +591,7 @@ class TestSocket < Test::Unit::TestCase
ensure
serv_thread.value.close
server.close
- end
+ end unless RUBY_PLATFORM.include?("freebsd")
def test_connect_timeout
host = "127.0.0.1"
@@ -762,4 +770,251 @@ class TestSocket < Test::Unit::TestCase
s2.close
end
+ def test_resolurion_error_error_code
+ begin
+ Socket.getaddrinfo("example.com", 80, "AF_UNIX")
+ rescue => e
+ assert_include([Socket::EAI_FAMILY, Socket::EAI_FAIL], e.error_code)
+ end
+ end
+
+ def test_tcp_socket_v6_hostname_resolved_earlier
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ begin
+ server = TCPServer.new("::1", 0)
+ rescue Errno::EADDRNOTAVAIL # IPv6 is not supported
+ exit
+ end
+
+ server_thread = Thread.new { server.accept }
+ port = server.addr[1]
+
+ Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
+ case family
+ when Socket::AF_INET6 then [Addrinfo.tcp("::1", port)]
+ when Socket::AF_INET then sleep(10); [Addrinfo.tcp("127.0.0.1", port)]
+ end
+ end
+
+ socket = Socket.tcp("localhost", port)
+ assert_true(socket.remote_address.ipv6?)
+ server_thread.value.close
+ server.close
+ socket.close if socket && !socket.closed?
+ end;
+ end
+
+ def test_tcp_socket_v4_hostname_resolved_earlier
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ server = TCPServer.new("127.0.0.1", 0)
+ port = server.addr[1]
+
+ Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
+ case family
+ when Socket::AF_INET6 then sleep(10); [Addrinfo.tcp("::1", port)]
+ when Socket::AF_INET then [Addrinfo.tcp("127.0.0.1", port)]
+ end
+ end
+
+ server_thread = Thread.new { server.accept }
+ socket = Socket.tcp("localhost", port)
+ assert_true(socket.remote_address.ipv4?)
+ server_thread.value.close
+ server.close
+ socket.close if socket && !socket.closed?
+ end;
+ end
+
+ def test_tcp_socket_v6_hostname_resolved_in_resolution_delay
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ begin
+ server = TCPServer.new("::1", 0)
+ rescue Errno::EADDRNOTAVAIL # IPv6 is not supported
+ exit
+ end
+
+ port = server.addr[1]
+ delay_time = 0.025 # Socket::RESOLUTION_DELAY (private) is 0.05
+
+ Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
+ case family
+ when Socket::AF_INET6 then sleep(delay_time); [Addrinfo.tcp("::1", port)]
+ when Socket::AF_INET then [Addrinfo.tcp("127.0.0.1", port)]
+ end
+ end
+
+ server_thread = Thread.new { server.accept }
+ socket = Socket.tcp("localhost", port)
+ assert_true(socket.remote_address.ipv6?)
+ server_thread.value.close
+ server.close
+ socket.close if socket && !socket.closed?
+ end;
+ end
+
+ def test_tcp_socket_v6_hostname_resolved_earlier_and_v6_server_is_not_listening
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ ipv4_address = "127.0.0.1"
+ ipv4_server = Socket.new(Socket::AF_INET, :STREAM)
+ ipv4_server.bind(Socket.pack_sockaddr_in(0, ipv4_address))
+ port = ipv4_server.connect_address.ip_port
+
+ Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
+ case family
+ when Socket::AF_INET6 then [Addrinfo.tcp("::1", port)]
+ when Socket::AF_INET then sleep(0.001); [Addrinfo.tcp(ipv4_address, port)]
+ end
+ end
+
+ ipv4_server_thread = Thread.new { ipv4_server.listen(1); ipv4_server.accept }
+ socket = Socket.tcp("localhost", port)
+ assert_equal(ipv4_address, socket.remote_address.ip_address)
+
+ accepted, _ = ipv4_server_thread.value
+ accepted.close
+ ipv4_server.close
+ socket.close if socket && !socket.closed?
+ end;
+ end
+
+ def test_tcp_socket_resolv_timeout
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ Addrinfo.define_singleton_method(:getaddrinfo) { |*_| sleep }
+ port = TCPServer.new("localhost", 0).addr[1]
+
+ assert_raise(Errno::ETIMEDOUT) do
+ Socket.tcp("localhost", port, resolv_timeout: 0.01)
+ end
+ end;
+ end
+
+ def test_tcp_socket_resolv_timeout_with_connection_failure
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ server = TCPServer.new("127.0.0.1", 12345)
+ _, port, = server.addr
+
+ Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
+ if family == Socket::AF_INET6
+ sleep
+ else
+ [Addrinfo.tcp("127.0.0.1", port)]
+ end
+ end
+
+ server.close
+
+ assert_raise(Errno::ETIMEDOUT) do
+ Socket.tcp("localhost", port, resolv_timeout: 0.01)
+ end
+ end;
+ end
+
+ def test_tcp_socket_one_hostname_resolution_succeeded_at_least
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ begin
+ server = TCPServer.new("::1", 0)
+ rescue Errno::EADDRNOTAVAIL # IPv6 is not supported
+ exit
+ end
+
+ port = server.addr[1]
+
+ Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
+ case family
+ when Socket::AF_INET6 then [Addrinfo.tcp("::1", port)]
+ when Socket::AF_INET then sleep(0.001); raise SocketError
+ end
+ end
+
+ server_thread = Thread.new { server.accept }
+ socket = nil
+
+ assert_nothing_raised do
+ socket = Socket.tcp("localhost", port)
+ end
+
+ server_thread.value.close
+ server.close
+ socket.close if socket && !socket.closed?
+ end;
+ end
+
+ def test_tcp_socket_all_hostname_resolution_failed
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
+ case family
+ when Socket::AF_INET6 then raise SocketError
+ when Socket::AF_INET then sleep(0.001); raise SocketError, "Last hostname resolution error"
+ end
+ end
+ port = TCPServer.new("localhost", 0).addr[1]
+
+ assert_raise_with_message(SocketError, "Last hostname resolution error") do
+ Socket.tcp("localhost", port)
+ end
+ end;
+ end
+
+ def test_tcp_socket_v6_address_passed
+ opts = %w[-rsocket -W1]
+ assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
+
+ begin;
+ begin
+ server = TCPServer.new("::1", 0)
+ rescue Errno::EADDRNOTAVAIL # IPv6 is not supported
+ exit
+ end
+
+ _, port, = server.addr
+
+ Addrinfo.define_singleton_method(:getaddrinfo) do |*_|
+ [Addrinfo.tcp("::1", port)]
+ end
+
+ server_thread = Thread.new { server.accept }
+ socket = Socket.tcp("::1", port)
+
+ assert_true(socket.remote_address.ipv6?)
+ server_thread.value.close
+ server.close
+ socket.close if socket && !socket.closed?
+ end;
+ end
+
+ def test_tcp_socket_fast_fallback_is_false
+ server = TCPServer.new("127.0.0.1", 0)
+ _, port, = server.addr
+ server_thread = Thread.new { server.accept }
+ socket = Socket.tcp("127.0.0.1", port, fast_fallback: false)
+
+ assert_true(socket.remote_address.ipv4?)
+ server_thread.value.close
+ server.close
+ socket.close if socket && !socket.closed?
+ end
end if defined?(Socket)
diff --git a/test/socket/test_tcp.rb b/test/socket/test_tcp.rb
index 9aa716f7ec..7f9dc53cae 100644
--- a/test/socket/test_tcp.rb
+++ b/test/socket/test_tcp.rb
@@ -70,7 +70,7 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
end
def test_initialize_connect_timeout
- assert_raise(Errno::ETIMEDOUT) do
+ assert_raise(IO::TimeoutError, Errno::ENETUNREACH) do
TCPSocket.new("192.0.2.1", 80, connect_timeout: 0)
end
end
diff --git a/test/socket/test_unix.rb b/test/socket/test_unix.rb
index 8c74d0c939..3e7d85befc 100644
--- a/test/socket/test_unix.rb
+++ b/test/socket/test_unix.rb
@@ -60,6 +60,8 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
assert_not_equal s1.fileno, r.fileno
r.close
end
+ rescue NotImplementedError => error
+ omit error.message
end
def test_fd_passing_n
@@ -150,7 +152,7 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
lock = Thread::Mutex.new
nr = 0
x = 2
- y = 1000
+ y = 400
begin
s1.send_io(nil)
rescue NotImplementedError
@@ -334,62 +336,70 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
end
def test_noname_path
- s1, s2 = UNIXSocket.pair
- assert_equal("", s1.path)
- assert_equal("", s2.path)
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ assert_equal("", s1.path)
+ assert_equal("", s2.path)
+ end
end
def test_noname_addr
- s1, s2 = UNIXSocket.pair
- assert_equal(["AF_UNIX", ""], s1.addr)
- assert_equal(["AF_UNIX", ""], s2.addr)
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ assert_equal(["AF_UNIX", ""], s1.addr)
+ assert_equal(["AF_UNIX", ""], s2.addr)
+ end
end
def test_noname_peeraddr
- s1, s2 = UNIXSocket.pair
- assert_equal(["AF_UNIX", ""], s1.peeraddr)
- assert_equal(["AF_UNIX", ""], s2.peeraddr)
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ assert_equal(["AF_UNIX", ""], s1.peeraddr)
+ assert_equal(["AF_UNIX", ""], s2.peeraddr)
+ end
end
def test_noname_unpack_sockaddr_un
- s1, s2 = UNIXSocket.pair
- n = nil
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getsockname) != ""
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getpeername) != ""
- assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getpeername) != ""
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ n = nil
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getsockname) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s1.getpeername) != ""
+ assert_equal("", Socket.unpack_sockaddr_un(n)) if (n = s2.getpeername) != ""
+ end
end
def test_noname_recvfrom
- s1, s2 = UNIXSocket.pair
- s2.write("a")
- assert_equal(["a", ["AF_UNIX", ""]], s1.recvfrom(10))
- ensure
- s1.close
- s2.close
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit "unnamed pipe is emulated on windows"
+ end
+
+ UNIXSocket.pair do |s1, s2|
+ s2.write("a")
+ assert_equal(["a", ["AF_UNIX", ""]], s1.recvfrom(10))
+ end
end
def test_noname_recv_nonblock
- s1, s2 = UNIXSocket.pair
- s2.write("a")
- IO.select [s1]
- assert_equal("a", s1.recv_nonblock(10))
- ensure
- s1.close
- s2.close
+ UNIXSocket.pair do |s1, s2|
+ s2.write("a")
+ IO.select [s1]
+ assert_equal("a", s1.recv_nonblock(10))
+ end
end
def test_too_long_path
@@ -410,9 +420,10 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
s1.recv_nonblock(10)
fail
rescue => e
- assert(IO::EAGAINWaitReadable === e)
- assert(IO::WaitReadable === e)
+ assert_kind_of(IO::EWOULDBLOCKWaitReadable, e)
+ assert_kind_of(IO::WaitReadable, e)
end
+
s2.send("", 0)
s2.send("haha", 0)
s2.send("", 0)
@@ -429,12 +440,79 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
rv = s1.recv(100, 0, buf)
assert_equal buf.object_id, rv.object_id
assert_equal "BBBBBB", rv
+ rescue Errno::EPROTOTYPE => error
+ omit error.message
+ ensure
+ s1.close if s1
+ s2.close if s2
+ end
+
+ def test_stream_pair
+ s1, s2 = UNIXSocket.pair(Socket::SOCK_STREAM)
+ begin
+ s1.recv_nonblock(10)
+ fail
+ rescue => e
+ assert_kind_of(IO::EWOULDBLOCKWaitReadable, e)
+ assert_kind_of(IO::WaitReadable, e)
+ end
+
+ s2.send("", 0)
+ s2.send("haha", 0)
+ assert_equal("haha", s1.recv(10))
+ assert_raise(IO::EWOULDBLOCKWaitReadable) { s1.recv_nonblock(10) }
+
+ buf = "".dup
+ s2.send("BBBBBB", 0)
+ IO.select([s1])
+ rv = s1.recv(100, 0, buf)
+ assert_equal buf.object_id, rv.object_id
+ assert_equal "BBBBBB", rv
+
+ s2.close
+ assert_nil(s1.recv(10))
+ rescue Errno::EPROTOTYPE => error
+ omit error.message
+ ensure
+ s1.close if s1
+ s2.close if s2
+ end
+
+ def test_seqpacket_pair
+ s1, s2 = UNIXSocket.pair(Socket::SOCK_SEQPACKET)
+ begin
+ s1.recv_nonblock(10)
+ fail
+ rescue => e
+ assert_kind_of(IO::EWOULDBLOCKWaitReadable, e)
+ assert_kind_of(IO::WaitReadable, e)
+ end
+
+ s2.send("haha", 0)
+ assert_equal("haha", s1.recv(10))
+ assert_raise(IO::EWOULDBLOCKWaitReadable) { s1.recv_nonblock(10) }
+
+ buf = "".dup
+ s2.send("BBBBBB", 0)
+ IO.select([s1])
+ rv = s1.recv(100, 0, buf)
+ assert_equal buf.object_id, rv.object_id
+ assert_equal "BBBBBB", rv
+
+ s2.close
+ assert_nil(s1.recv(10))
+ rescue Errno::EPROTOTYPE, Errno::EPROTONOSUPPORT => error
+ omit error.message
ensure
s1.close if s1
s2.close if s2
end
def test_dgram_pair_sendrecvmsg_errno_set
+ if /mswin|mingw/ =~ RUBY_PLATFORM
+ omit("AF_UNIX + SOCK_DGRAM is not supported on windows")
+ end
+
s1, s2 = to_close = UNIXSocket.pair(Socket::SOCK_DGRAM)
pipe = IO.pipe
to_close.concat(pipe)
@@ -457,9 +535,17 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
end
def test_epipe # [ruby-dev:34619]
+ # This is a good example of why reporting the exact `errno` is a terrible
+ # idea for platform abstractions.
+ if RUBY_PLATFORM =~ /mswin|mingw/
+ error = Errno::ESHUTDOWN
+ else
+ error = Errno::EPIPE
+ end
+
UNIXSocket.pair {|s1, s2|
s1.shutdown(Socket::SHUT_WR)
- assert_raise(Errno::EPIPE) { s1.write "a" }
+ assert_raise(error) { s1.write "a" }
assert_equal(nil, s2.read(1))
s2.write "a"
assert_equal("a", s1.read(1))
@@ -493,6 +579,45 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
}
end
+ if /mingw|mswin/ =~ RUBY_PLATFORM
+
+ def test_unix_socket_with_encoding
+ Dir.mktmpdir do |tmpdir|
+ path = "#{tmpdir}/sockäöü".encode("cp850")
+ UNIXServer.open(path) do |serv|
+ assert File.socket?(path)
+ assert File.stat(path).socket?
+ assert File.lstat(path).socket?
+ assert_equal path.encode("utf-8"), serv.path
+ UNIXSocket.open(path) do |s1|
+ s2 = serv.accept
+ s2.close
+ end
+ end
+ end
+ end
+
+ def test_windows_unix_socket_pair_with_umlaut
+ otmp = ENV['TMP']
+ ENV['TMP'] = File.join(Dir.tmpdir, "äöü€")
+ FileUtils.mkdir_p ENV['TMP']
+
+ s1, = UNIXSocket.pair
+ assert !s1.path.empty?
+ assert !File.exist?(s1.path)
+ ensure
+ FileUtils.rm_rf ENV['TMP']
+ ENV['TMP'] = otmp
+ end
+
+ def test_windows_unix_socket_pair_paths
+ s1, s2 = UNIXSocket.pair
+ assert !s1.path.empty?
+ assert s2.path.empty?
+ assert !File.exist?(s1.path)
+ end
+ end
+
def test_initialize
Dir.mktmpdir {|d|
Socket.open(Socket::AF_UNIX, Socket::SOCK_STREAM, 0) {|s|
diff --git a/test/stringio/test_ractor.rb b/test/stringio/test_ractor.rb
index 1c334e2c3f..4a2033bc1f 100644
--- a/test/stringio/test_ractor.rb
+++ b/test/stringio/test_ractor.rb
@@ -11,7 +11,7 @@ class TestStringIOInRactor < Test::Unit::TestCase
require "stringio"
$VERBOSE = nil
r = Ractor.new do
- io = StringIO.new("")
+ io = StringIO.new(+"")
io.puts "abc"
io.truncate(0)
io.puts "def"
diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb
index 34c4748185..e17cd0abb1 100644
--- a/test/stringio/test_stringio.rb
+++ b/test/stringio/test_stringio.rb
@@ -14,14 +14,19 @@ class TestStringIO < Test::Unit::TestCase
include TestEOF::Seek
+ def test_version
+ assert_kind_of(String, StringIO::VERSION)
+ end
+
def test_initialize
assert_kind_of StringIO, StringIO.new
assert_kind_of StringIO, StringIO.new('str')
assert_kind_of StringIO, StringIO.new('str', 'r+')
+ assert_kind_of StringIO, StringIO.new(nil)
assert_raise(ArgumentError) { StringIO.new('', 'x') }
assert_raise(ArgumentError) { StringIO.new('', 'rx') }
assert_raise(ArgumentError) { StringIO.new('', 'rbt') }
- assert_raise(TypeError) { StringIO.new(nil) }
+ assert_raise(TypeError) { StringIO.new(Object) }
o = Object.new
def o.to_str
@@ -36,6 +41,13 @@ class TestStringIO < Test::Unit::TestCase
assert_kind_of StringIO, StringIO.new(o)
end
+ def test_null
+ io = StringIO.new(nil)
+ assert_nil io.gets
+ io.puts "abc"
+ assert_nil io.string
+ end
+
def test_truncate
io = StringIO.new("")
io.puts "abc"
@@ -84,6 +96,14 @@ class TestStringIO < Test::Unit::TestCase
assert_string("", Encoding::UTF_8, StringIO.new("foo").gets(0))
end
+ def test_gets_utf_16
+ stringio = StringIO.new("line1\nline2\nline3\n".encode("utf-16le"))
+ assert_equal("line1\n".encode("utf-16le"), stringio.gets)
+ assert_equal("line2\n".encode("utf-16le"), stringio.gets)
+ assert_equal("line3\n".encode("utf-16le"), stringio.gets)
+ assert_nil(stringio.gets)
+ end
+
def test_gets_chomp
assert_equal(nil, StringIO.new("").gets(chomp: true))
assert_equal("", StringIO.new("\n").gets(chomp: true))
@@ -99,6 +119,8 @@ class TestStringIO < Test::Unit::TestCase
assert_equal("def\n", stringio.gets("", chomp: true))
assert_string("", Encoding::UTF_8, StringIO.new("\n").gets(chomp: true))
+
+ assert_equal("", StringIO.new("ab").gets("ab", chomp: true))
end
def test_gets_chomp_eol
@@ -223,7 +245,7 @@ class TestStringIO < Test::Unit::TestCase
def test_write_integer_overflow
f = StringIO.new
- f.pos = RbConfig::LIMITS["LONG_MAX"]
+ f.pos = StringIO::MAX_LENGTH
assert_raise(ArgumentError) {
f.write("pos + len overflows")
}
@@ -727,6 +749,32 @@ class TestStringIO < Test::Unit::TestCase
assert_equal Encoding::ASCII_8BIT, f.sysread(3).encoding
end
+ def test_pread
+ f = StringIO.new("pread")
+ f.read
+
+ assert_equal "pre".b, f.pread(3, 0)
+ assert_equal "read".b, f.pread(4, 1)
+ assert_equal Encoding::ASCII_8BIT, f.pread(4, 1).encoding
+
+ buf = "".b
+ f.pread(3, 0, buf)
+ assert_equal "pre".b, buf
+ f.pread(4, 1, buf)
+ assert_equal "read".b, buf
+
+ assert_raise(EOFError) { f.pread(1, 5) }
+ assert_raise(ArgumentError) { f.pread(-1, 0) }
+ assert_raise(Errno::EINVAL) { f.pread(3, -1) }
+
+ assert_equal "".b, StringIO.new("").pread(0, 0)
+ assert_equal "".b, StringIO.new("").pread(0, -10)
+
+ buf = "stale".b
+ assert_equal "stale".b, StringIO.new("").pread(0, 0, buf)
+ assert_equal "stale".b, buf
+ end
+
def test_size
f = StringIO.new("1234")
assert_equal(4, f.size)
@@ -859,8 +907,9 @@ class TestStringIO < Test::Unit::TestCase
end
def test_overflow
- return if RbConfig::SIZEOF["void*"] > RbConfig::SIZEOF["long"]
- limit = RbConfig::LIMITS["INTPTR_MAX"] - 0x10
+ intptr_max = RbConfig::LIMITS["INTPTR_MAX"]
+ return if intptr_max > StringIO::MAX_LENGTH
+ limit = intptr_max - 0x10
assert_separately(%w[-rstringio], "#{<<-"begin;"}\n#{<<-"end;"}")
begin;
limit = #{limit}
@@ -913,6 +962,43 @@ class TestStringIO < Test::Unit::TestCase
$VERBOSE = verbose
end
+ def test_coderange_after_overwrite
+ s = StringIO.new("".b)
+
+ s.write("a=b&c=d")
+ s.rewind
+ assert_predicate(s.string, :ascii_only?)
+ s.write "\u{431 43e 433 443 441}"
+ assert_not_predicate(s.string, :ascii_only?)
+
+ s = StringIO.new("\u{3042}")
+ s.rewind
+ assert_not_predicate(s.string, :ascii_only?)
+ s.write('aaaa')
+ assert_predicate(s.string, :ascii_only?)
+ end
+
+ if eval(%{ "test".frozen? && !"test".equal?("test") }) # Ruby 3.4+ chilled strings
+ def test_chilled_string
+ chilled_string = eval(%{""})
+ io = StringIO.new(chilled_string)
+ assert_warning(/literal string will be frozen/) { io << "test" }
+ assert_equal("test", io.string)
+ assert_same(chilled_string, io.string)
+ end
+
+ def test_chilled_string_string_set
+ io = StringIO.new
+ chilled_string = eval(%{""})
+ io.string = chilled_string
+ assert_warning(/literal string will be frozen/) { io << "test" }
+ assert_equal("test", io.string)
+ assert_same(chilled_string, io.string)
+ end
+ end
+
+ private
+
def assert_string(content, encoding, str, mesg = nil)
assert_equal([content, encoding], [str, str.encoding], mesg)
end
diff --git a/test/strscan/test_ractor.rb b/test/strscan/test_ractor.rb
index 480c1ae8a6..a5de7e56ed 100644
--- a/test/strscan/test_ractor.rb
+++ b/test/strscan/test_ractor.rb
@@ -3,7 +3,7 @@ require 'test/unit'
class TestStringScannerRactor < Test::Unit::TestCase
def setup
- pend unless defined? Ractor
+ omit "Ractor not defined" unless defined? Ractor
end
def test_ractor
diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb
index 6e30be1f7d..143cf7197d 100644
--- a/test/strscan/test_stringscanner.rb
+++ b/test/strscan/test_stringscanner.rb
@@ -7,9 +7,30 @@
require 'strscan'
require 'test/unit'
-class TestStringScanner < Test::Unit::TestCase
- def create_string_scanner(string, *args)
- StringScanner.new(string, *args)
+module StringScannerTests
+ def test_peek_byte
+ omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
+ s = create_string_scanner('ab')
+ assert_equal 97, s.peek_byte
+ assert_equal 97, s.scan_byte
+ assert_equal 98, s.peek_byte
+ assert_equal 98, s.scan_byte
+ assert_nil s.peek_byte
+ assert_nil s.scan_byte
+ end
+
+ def test_scan_byte
+ omit("not implemented on TruffleRuby") if RUBY_ENGINE == "truffleruby"
+ s = create_string_scanner('ab')
+ assert_equal 97, s.scan_byte
+ assert_equal 98, s.scan_byte
+ assert_nil s.scan_byte
+
+ str = "\244\242".dup.force_encoding("euc-jp")
+ s = StringScanner.new(str)
+ assert_equal str.getbyte(s.pos), s.scan_byte
+ assert_equal str.getbyte(s.pos), s.scan_byte
+ assert_nil s.scan_byte
end
def test_s_new
@@ -155,8 +176,10 @@ class TestStringScanner < Test::Unit::TestCase
end
def test_string
- s = create_string_scanner('test')
- assert_equal 'test', s.string
+ s = create_string_scanner('test string')
+ assert_equal 'test string', s.string
+ s.scan(/test/)
+ assert_equal 'test string', s.string
s.string = 'a'
assert_equal 'a', s.string
s.scan(/a/)
@@ -207,6 +230,8 @@ class TestStringScanner < Test::Unit::TestCase
end
def test_charpos_not_use_string_methods
+ omit "not supported on TruffleRuby" if RUBY_ENGINE == "truffleruby"
+
string = +'abcädeföghi'
scanner = create_string_scanner(string)
@@ -465,7 +490,10 @@ class TestStringScanner < Test::Unit::TestCase
assert_equal 'foo', s['a']
assert_equal 'bar', s['b']
assert_raise(IndexError) { s['c'] }
- assert_raise_with_message(IndexError, /\u{30c6 30b9 30c8}/) { s["\u{30c6 30b9 30c8}"] }
+ # see https://github.com/jruby/jruby/issues/7644
+ unless RUBY_ENGINE == "jruby" && RbConfig::CONFIG['host_os'] =~ /mswin|win32|mingw/
+ assert_raise_with_message(IndexError, /\u{30c6 30b9 30c8}/) { s["\u{30c6 30b9 30c8}"] }
+ end
end
def test_pre_match
@@ -555,6 +583,16 @@ class TestStringScanner < Test::Unit::TestCase
assert_nil s.matched_size
end
+ def test_empty_encoding_utf8
+ ss = create_string_scanner('')
+ assert_equal(Encoding::UTF_8, ss.rest.encoding)
+ end
+
+ def test_empty_encoding_ascii_8bit
+ ss = create_string_scanner(''.dup.force_encoding("ASCII-8BIT"))
+ assert_equal(Encoding::ASCII_8BIT, ss.rest.encoding)
+ end
+
def test_encoding
ss = create_string_scanner("\xA1\xA2".dup.force_encoding("euc-jp"))
assert_equal(Encoding::EUC_JP, ss.scan(/./e).encoding)
@@ -567,6 +605,8 @@ class TestStringScanner < Test::Unit::TestCase
end
def test_invalid_encoding_string
+ omit "no encoding check on TruffleRuby for scan(String)" if RUBY_ENGINE == "truffleruby"
+
str = "\xA1\xA2".dup.force_encoding("euc-jp")
ss = create_string_scanner(str)
assert_raise(Encoding::CompatibilityError) do
@@ -712,6 +752,8 @@ class TestStringScanner < Test::Unit::TestCase
end
def test_aref_without_regex
+ omit "#[:missing] always raises on TruffleRuby if matched" if RUBY_ENGINE == "truffleruby"
+
s = create_string_scanner('abc')
s.get_byte
assert_nil(s[:c])
@@ -730,8 +772,8 @@ class TestStringScanner < Test::Unit::TestCase
def test_captures
s = create_string_scanner("Timestamp: Fri Dec 12 1975 14:39")
s.scan("Timestamp: ")
- s.scan(/(\w+) (\w+) (\d+) /)
- assert_equal(["Fri", "Dec", "12"], s.captures)
+ s.scan(/(\w+) (\w+) (\d+) (1980)?/)
+ assert_equal(["Fri", "Dec", "12", nil], s.captures)
s.scan(/(\w+) (\w+) (\d+) /)
assert_nil(s.captures)
end
@@ -745,6 +787,42 @@ class TestStringScanner < Test::Unit::TestCase
assert_nil(s.values_at(0, -1, 5, 2))
end
+ def test_scan_aref_repeatedly
+ s = StringScanner.new('test string')
+ assert_equal "test", s.scan(/\w(\w)(\w*)/)
+ assert_equal "test", s[0]
+ assert_equal "e", s[1]
+ assert_equal "st", s[2]
+ assert_nil s.scan(/\w+/)
+ assert_nil s[0]
+ assert_nil s[1]
+ assert_nil s[2]
+ assert_equal " ", s.scan(/\s+/)
+ assert_equal " ", s[0]
+ assert_nil s[1]
+ assert_nil s[2]
+ assert_equal "string", s.scan(/\w(\w)(\w*)/)
+ assert_equal "string", s[0]
+ assert_equal "t", s[1]
+ assert_equal "ring", s[2]
+ end
+
+ def test_named_captures
+ omit("not implemented on TruffleRuby") if ["truffleruby"].include?(RUBY_ENGINE)
+ scan = StringScanner.new("foobarbaz")
+ assert_equal({}, scan.named_captures)
+ assert_equal(9, scan.match?(/(?<f>foo)(?<r>bar)(?<z>baz)/))
+ assert_equal({"f" => "foo", "r" => "bar", "z" => "baz"}, scan.named_captures)
+ end
+end
+
+class TestStringScanner < Test::Unit::TestCase
+ include StringScannerTests
+
+ def create_string_scanner(string, *args)
+ StringScanner.new(string, *args)
+ end
+
def test_fixed_anchor_true
assert_equal(true, StringScanner.new("a", fixed_anchor: true).fixed_anchor?)
end
@@ -759,7 +837,9 @@ class TestStringScanner < Test::Unit::TestCase
end
end
-class TestStringScannerFixedAnchor < TestStringScanner
+class TestStringScannerFixedAnchor < Test::Unit::TestCase
+ include StringScannerTests
+
def create_string_scanner(string, *args)
StringScanner.new(string, fixed_anchor: true)
end
@@ -786,4 +866,12 @@ class TestStringScannerFixedAnchor < TestStringScanner
assert_equal 1, s.skip(/a/)
assert_nil s.skip(/^b/)
end
+
+ # ruby/strscan#86
+ def test_scan_shared_string
+ s = "hellohello"[5..-1]
+ ss = StringScanner.new(s).scan(/hello/)
+
+ assert_equal "hello", ss
+ end
end
diff --git a/test/syslog/test_syslog_logger.rb b/test/syslog/test_syslog_logger.rb
deleted file mode 100644
index d9ffae3901..0000000000
--- a/test/syslog/test_syslog_logger.rb
+++ /dev/null
@@ -1,588 +0,0 @@
-# coding: US-ASCII
-# frozen_string_literal: false
-require 'test/unit'
-require 'tempfile'
-begin
- require 'syslog/logger'
-rescue LoadError
- # skip. see the bottom of this file.
-end
-
-# These tests ensure Syslog::Logger works like Logger
-
-class TestSyslogRootLogger < Test::Unit::TestCase
-
- module MockSyslog
-
- PRIMASK = Syslog::Level.constants.inject(0) { |mask, name| mask | Syslog::Level.const_get(name) }
-
- LEVEL_LABEL_MAP = {
- Syslog::LOG_ALERT => 'ALERT',
- Syslog::LOG_ERR => 'ERR',
- Syslog::LOG_WARNING => 'WARNING',
- Syslog::LOG_NOTICE => 'NOTICE',
- Syslog::LOG_INFO => 'INFO',
- Syslog::LOG_DEBUG => 'DEBUG'
- }
-
- @facility = Syslog::LOG_USER
-
- class << self
-
- attr_reader :facility
- attr_reader :line
- attr_reader :program_name
-
- def log(priority, format, *args)
- level = priority & PRIMASK
- @line = "<#{priority}> #{LEVEL_LABEL_MAP[level]} - #{format % args}"
- end
-
- def open(program_name)
- @program_name = program_name
- end
-
- def reset
- @line = ''
- end
-
- end
- end
-
- Syslog::Logger.syslog = MockSyslog
-
- LEVEL_LABEL_MAP = {
- Logger::DEBUG => 'DEBUG',
- Logger::INFO => 'INFO',
- Logger::WARN => 'WARN',
- Logger::ERROR => 'ERROR',
- Logger::FATAL => 'FATAL',
- Logger::UNKNOWN => 'ANY',
- }
-
- def setup
- @logger = Logger.new(nil)
- end
-
- class Log
- attr_reader :line, :label, :datetime, :pid, :severity, :progname, :msg
- def initialize(line)
- @line = line
- /\A(\w+), \[([^#]*)#(\d+)\]\s+(\w+) -- (\w*): ([\x0-\xff]*)/ =~ @line
- @label, @datetime, @pid, @severity, @progname, @msg = $1, $2, $3, $4, $5, $6
- end
- end
-
- def log_add(severity, msg, progname = nil, &block)
- log(:add, severity, msg, progname, &block)
- end
-
- def log(msg_id, *arg, &block)
- Log.new(log_raw(msg_id, *arg, &block))
- end
-
- def log_raw(msg_id, *arg, &block)
- Tempfile.create(File.basename(__FILE__) + '.log') {|logdev|
- @logger.instance_eval { @logdev = Logger::LogDevice.new(logdev) }
- assert_equal true, @logger.__send__(msg_id, *arg, &block)
- logdev.rewind
- logdev.read
- }
- end
-
- def test_initialize
- assert_equal Logger::DEBUG, @logger.level
- end
-
- def test_custom_formatter
- @logger.formatter = Class.new {
- def call severity, time, progname, msg
- "hi mom!"
- end
- }.new
-
- assert_match(/hi mom!/, log_raw(:fatal, 'fatal level message'))
- end
-
- def test_add
- msg = log_add nil, 'unknown level message' # nil == unknown
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- msg = log_add Logger::FATAL, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- msg = log_add Logger::ERROR, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- msg = log_add Logger::WARN, 'warn level message'
- assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
-
- msg = log_add Logger::INFO, 'info level message'
- assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
-
- msg = log_add Logger::DEBUG, 'debug level message'
- assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
- end
-
- def test_add_level_unknown
- @logger.level = Logger::UNKNOWN
-
- msg = log_add nil, 'unknown level message' # nil == unknown
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- msg = log_add Logger::FATAL, 'fatal level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::ERROR, 'error level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::WARN, 'warn level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::INFO, 'info level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::DEBUG, 'debug level message'
- assert_equal '', msg.line
- end
-
- def test_add_level_fatal
- @logger.level = Logger::FATAL
-
- msg = log_add nil, 'unknown level message' # nil == unknown
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- msg = log_add Logger::FATAL, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- msg = log_add Logger::ERROR, 'error level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::WARN, 'warn level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::INFO, 'info level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::DEBUG, 'debug level message'
- assert_equal '', msg.line
- end
-
- def test_add_level_error
- @logger.level = Logger::ERROR
-
- msg = log_add nil, 'unknown level message' # nil == unknown
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- msg = log_add Logger::FATAL, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- msg = log_add Logger::ERROR, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- msg = log_add Logger::WARN, 'warn level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::INFO, 'info level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::DEBUG, 'debug level message'
- assert_equal '', msg.line
- end
-
- def test_add_level_warn
- @logger.level = Logger::WARN
-
- msg = log_add nil, 'unknown level message' # nil == unknown
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- msg = log_add Logger::FATAL, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- msg = log_add Logger::ERROR, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- msg = log_add Logger::WARN, 'warn level message'
- assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
-
- msg = log_add Logger::INFO, 'info level message'
- assert_equal '', msg.line
-
- msg = log_add Logger::DEBUG, 'debug level message'
- assert_equal '', msg.line
- end
-
- def test_add_level_info
- @logger.level = Logger::INFO
-
- msg = log_add nil, 'unknown level message' # nil == unknown
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- msg = log_add Logger::FATAL, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- msg = log_add Logger::ERROR, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- msg = log_add Logger::WARN, 'warn level message'
- assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
-
- msg = log_add Logger::INFO, 'info level message'
- assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
-
- msg = log_add Logger::DEBUG, 'debug level message'
- assert_equal '', msg.line
- end
-
- def test_add_level_debug
- @logger.level = Logger::DEBUG
-
- msg = log_add nil, 'unknown level message' # nil == unknown
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- msg = log_add Logger::FATAL, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- msg = log_add Logger::ERROR, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- msg = log_add Logger::WARN, 'warn level message'
- assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
-
- msg = log_add Logger::INFO, 'info level message'
- assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
-
- msg = log_add Logger::DEBUG, 'debug level message'
- assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
- end
-
- def test_unknown
- msg = log :unknown, 'unknown level message'
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- @logger.level = Logger::UNKNOWN
- msg = log :unknown, 'unknown level message'
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- @logger.level = Logger::FATAL
- msg = log :unknown, 'unknown level message'
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- @logger.level = Logger::ERROR
- msg = log :unknown, 'unknown level message'
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- @logger.level = Logger::WARN
- msg = log :unknown, 'unknown level message'
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- @logger.level = Logger::INFO
- msg = log :unknown, 'unknown level message'
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
-
- @logger.level = Logger::DEBUG
- msg = log :unknown, 'unknown level message'
- assert_equal LEVEL_LABEL_MAP[Logger::UNKNOWN], msg.severity
- end
-
- def test_fatal
- msg = log :fatal, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- @logger.level = Logger::UNKNOWN
- msg = log :fatal, 'fatal level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::FATAL
- msg = log :fatal, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- @logger.level = Logger::ERROR
- msg = log :fatal, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- @logger.level = Logger::WARN
- msg = log :fatal, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- @logger.level = Logger::INFO
- msg = log :fatal, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
-
- @logger.level = Logger::DEBUG
- msg = log :fatal, 'fatal level message'
- assert_equal LEVEL_LABEL_MAP[Logger::FATAL], msg.severity
- end
-
- def test_fatal_eh
- @logger.level = Logger::FATAL
- assert_equal true, @logger.fatal?
-
- @logger.level = Logger::UNKNOWN
- assert_equal false, @logger.fatal?
- end
-
- def test_error
- msg = log :error, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- @logger.level = Logger::UNKNOWN
- msg = log :error, 'error level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::FATAL
- msg = log :error, 'error level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::ERROR
- msg = log :error, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- @logger.level = Logger::WARN
- msg = log :error, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- @logger.level = Logger::INFO
- msg = log :error, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
-
- @logger.level = Logger::DEBUG
- msg = log :error, 'error level message'
- assert_equal LEVEL_LABEL_MAP[Logger::ERROR], msg.severity
- end
-
- def test_error_eh
- @logger.level = Logger::ERROR
- assert_equal true, @logger.error?
-
- @logger.level = Logger::FATAL
- assert_equal false, @logger.error?
- end
-
- def test_warn
- msg = log :warn, 'warn level message'
- assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
-
- @logger.level = Logger::UNKNOWN
- msg = log :warn, 'warn level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::FATAL
- msg = log :warn, 'warn level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::ERROR
- msg = log :warn, 'warn level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::WARN
- msg = log :warn, 'warn level message'
- assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
-
- @logger.level = Logger::INFO
- msg = log :warn, 'warn level message'
- assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
-
- @logger.level = Logger::DEBUG
- msg = log :warn, 'warn level message'
- assert_equal LEVEL_LABEL_MAP[Logger::WARN], msg.severity
- end
-
- def test_warn_eh
- @logger.level = Logger::WARN
- assert_equal true, @logger.warn?
-
- @logger.level = Logger::ERROR
- assert_equal false, @logger.warn?
- end
-
- def test_info
- msg = log :info, 'info level message'
- assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
-
- @logger.level = Logger::UNKNOWN
- msg = log :info, 'info level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::FATAL
- msg = log :info, 'info level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::ERROR
- msg = log :info, 'info level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::WARN
- msg = log :info, 'info level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::INFO
- msg = log :info, 'info level message'
- assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
-
- @logger.level = Logger::DEBUG
- msg = log :info, 'info level message'
- assert_equal LEVEL_LABEL_MAP[Logger::INFO], msg.severity
- end
-
- def test_info_eh
- @logger.level = Logger::INFO
- assert_equal true, @logger.info?
-
- @logger.level = Logger::WARN
- assert_equal false, @logger.info?
- end
-
- def test_debug
- msg = log :debug, 'debug level message'
- assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
-
- @logger.level = Logger::UNKNOWN
- msg = log :debug, 'debug level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::FATAL
- msg = log :debug, 'debug level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::ERROR
- msg = log :debug, 'debug level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::WARN
- msg = log :debug, 'debug level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::INFO
- msg = log :debug, 'debug level message'
- assert_equal '', msg.line
-
- @logger.level = Logger::DEBUG
- msg = log :debug, 'debug level message'
- assert_equal LEVEL_LABEL_MAP[Logger::DEBUG], msg.severity
- end
-
- def test_debug_eh
- @logger.level = Logger::DEBUG
- assert_equal true, @logger.debug?
-
- @logger.level = Logger::INFO
- assert_equal false, @logger.debug?
- end
-
-end if defined?(Syslog)
-
-class TestSyslogLogger < TestSyslogRootLogger
-
- @facility = Syslog::LOG_USER
-
- def facility
- self.class.instance_variable_get("@facility")
- end
-
- def setup
- super
- @logger = Syslog::Logger.new
- end
-
- SEVERITY_MAP = {}.tap { |map|
- level2severity = Syslog::Logger::LEVEL_MAP.invert
-
- MockSyslog::LEVEL_LABEL_MAP.each { |level, name|
- map[name] = TestSyslogRootLogger::LEVEL_LABEL_MAP[level2severity[level]]
- }
- }
-
- class Log
- attr_reader :line, :label, :datetime, :pid, :severity, :progname, :msg, :priority
- def initialize(line)
- @line = line
- return unless /\A<(\d+)> (\w+) - (.*)\Z/ =~ @line
- priority, severity, @msg = $1, $2, $3
- @severity = SEVERITY_MAP[severity]
- @priority = priority.to_i
- end
- end
-
- def log_add(severity, msg, progname = nil, &block)
- log(:add, severity, msg, progname, &block)
- end
-
- def log(msg_id, *arg, &block)
- Log.new(log_raw(msg_id, *arg, &block))
- end
-
- def log_raw(msg_id, *arg, &block)
- assert_equal true, @logger.__send__(msg_id, *arg, &block)
- msg = MockSyslog.line
- MockSyslog.reset
- return msg
- end
-
- def test_unknown_eh
- @logger.level = Logger::UNKNOWN
- assert_equal true, @logger.unknown?
-
- @logger.level = Logger::UNKNOWN + 1
- assert_equal false, @logger.unknown?
- end
-
- def test_facility
- assert_equal facility, @logger.facility
- end
-
- def test_priority
- msg = log_add nil, 'unknown level message' # nil == unknown
- assert_equal facility|Syslog::LOG_ALERT, msg.priority
-
- msg = log_add Logger::FATAL, 'fatal level message'
- assert_equal facility|Syslog::LOG_ERR, msg.priority
-
- msg = log_add Logger::ERROR, 'error level message'
- assert_equal facility|Syslog::LOG_WARNING, msg.priority
-
- msg = log_add Logger::WARN, 'warn level message'
- assert_equal facility|Syslog::LOG_NOTICE, msg.priority
-
- msg = log_add Logger::INFO, 'info level message'
- assert_equal facility|Syslog::LOG_INFO, msg.priority
-
- msg = log_add Logger::DEBUG, 'debug level message'
- assert_equal facility|Syslog::LOG_DEBUG, msg.priority
- end
-
- class CustomSyslogLogger < Syslog::Logger
- def level
- Logger::INFO
- end
- end
-
- def test_overriding_level
- @logger = CustomSyslogLogger.new
- log = log_add Logger::INFO, 'msg'
- assert_equal 'msg', log.msg
-
- log = log_add Logger::DEBUG, 'msg'
- assert_nil log.msg
- end
-
-end if defined?(Syslog)
-
-
-# Create test class for each available facility
-
-Syslog::Facility.constants.each do |facility_symb|
-
- test_syslog_class = Class.new(TestSyslogLogger) do
-
- @facility = Syslog.const_get(facility_symb)
-
- def setup
- super
- @logger.facility = facility
- end
-
- end
- Object.const_set("TestSyslogLogger_#{facility_symb}", test_syslog_class)
-
-end if defined?(Syslog)
diff --git a/test/test_abbrev.rb b/test/test_abbrev.rb
deleted file mode 100644
index 67287138aa..0000000000
--- a/test/test_abbrev.rb
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-require 'test/unit'
-require 'abbrev'
-
-class TestAbbrev < Test::Unit::TestCase
- def test_abbrev
- words = %w[summer winter win ruby rules]
-
- assert_equal({
- "rub" => "ruby",
- "ruby" => "ruby",
- "rul" => "rules",
- "rule" => "rules",
- "rules" => "rules",
- "s" => "summer",
- "su" => "summer",
- "sum" => "summer",
- "summ" => "summer",
- "summe" => "summer",
- "summer" => "summer",
- "win" => "win",
- "wint" => "winter",
- "winte" => "winter",
- "winter" => "winter",
- }, words.abbrev)
-
- assert_equal({
- "rub" => "ruby",
- "ruby" => "ruby",
- "rul" => "rules",
- "rule" => "rules",
- "rules" => "rules",
- }, words.abbrev('ru'))
-
- assert_equal words.abbrev, Abbrev.abbrev(words)
- assert_equal words.abbrev('ru'), Abbrev.abbrev(words, 'ru')
- end
-
- def test_abbrev_lf
- words = ["abc", "abc\nd", "de"]
-
- assert_equal({
- "abc" => "abc",
- "abc\n" => "abc\nd",
- "abc\nd" => "abc\nd",
- "d" => "de",
- "de" => "de",
- }, words.abbrev)
-
- assert_equal({
- "d" => "de",
- "de" => "de",
- }, words.abbrev('d'))
- end
-end
diff --git a/test/test_extlibs.rb b/test/test_extlibs.rb
index 958c9ff73e..9b6676416c 100644
--- a/test/test_extlibs.rb
+++ b/test/test_extlibs.rb
@@ -34,18 +34,16 @@ class TestExtLibs < Test::Unit::TestCase
end.flatten.compact
excluded << '+' if excluded.empty?
if windows?
- excluded.map! {|i| i == '+' ? ['pty', 'syslog'] : i}
+ excluded.map! {|i| i == '+' ? ['pty'] : i}
excluded.flatten!
else
excluded.map! {|i| i == '+' ? '*win32*' : i}
end
@excluded = excluded
- check_existence "bigdecimal"
check_existence "continuation"
check_existence "coverage"
check_existence "date"
- #check_existence "dbm" # depend on libdbm
check_existence "digest"
check_existence "digest/bubblebabble"
check_existence "digest/md5"
@@ -56,25 +54,20 @@ class TestExtLibs < Test::Unit::TestCase
check_existence "fcntl"
check_existence "fiber"
check_existence "fiddle"
- #check_existence "gdbm" # depend on libgdbm
check_existence "io/console"
check_existence "io/nonblock"
check_existence "io/wait"
check_existence "json"
- check_existence "nkf"
check_existence "objspace"
check_existence "openssl", "this may be false positive, but should assert because rubygems requires this"
check_existence "pathname"
check_existence "psych"
check_existence "pty"
- check_existence "racc/cparse"
check_existence "rbconfig/sizeof"
- #check_existence "readline" # depend on libreadline
check_existence "ripper"
check_existence "socket"
check_existence "stringio"
check_existence "strscan"
- check_existence "syslog"
check_existence "thread"
check_existence "win32ole"
check_existence "zlib", "this may be false positive, but should assert because rubygems requires this"
diff --git a/test/test_forwardable.rb b/test/test_forwardable.rb
index deb0b5d5cf..9ed330058a 100644
--- a/test/test_forwardable.rb
+++ b/test/test_forwardable.rb
@@ -306,7 +306,7 @@ class TestForwardable < Test::Unit::TestCase
def test_basicobject_subclass
bug11616 = '[ruby-core:71176] [Bug #11616]'
- assert_raise_with_message(NameError, /`bar'/, bug11616) {
+ assert_raise_with_message(NameError, /[`']bar'/, bug11616) {
Foo2.new.baz
}
end
diff --git a/test/test_getoptlong.rb b/test/test_getoptlong.rb
deleted file mode 100644
index 0cd370b6c7..0000000000
--- a/test/test_getoptlong.rb
+++ /dev/null
@@ -1,163 +0,0 @@
-require 'test/unit'
-require 'getoptlong'
-
-class TestGetoptLong < Test::Unit::TestCase
-
- def verify(test_argv, expected_remaining_argv, expected_options)
- # Save ARGV and replace it with a test ARGV.
- argv_saved = ARGV.dup
- ARGV.replace(test_argv)
- # Define options.
- opts = GetoptLong.new(
- ['--xxx', '-x', '--aaa', '-a', GetoptLong::REQUIRED_ARGUMENT],
- ['--yyy', '-y', '--bbb', '-b', GetoptLong::OPTIONAL_ARGUMENT],
- ['--zzz', '-z', '--ccc', '-c', GetoptLong::NO_ARGUMENT]
- )
- opts.quiet = true
- # Gather options.
- actual_options = []
- opts.each do |opt, arg|
- actual_options << "#{opt}: #{arg}"
- end
- # Save remaining test ARGV and restore original ARGV.
- actual_remaining_argv = ARGV.dup
- ARGV.replace(argv_saved)
- # Assert.
- assert_equal(expected_remaining_argv, actual_remaining_argv, 'ARGV')
- assert_equal(expected_options, actual_options, 'Options')
- end
-
- def test_no_options
- expected_options = []
- expected_argv = %w[foo bar]
- argv = %w[foo bar]
- verify(argv, expected_argv, expected_options)
- end
-
- def test_required_argument
- expected_options = [
- '--xxx: arg'
- ]
- expected_argv = %w[foo bar]
- options = %w[--xxx --xx --x -x --aaa --aa --a -a]
- options.each do |option|
- argv = ['foo', option, 'arg', 'bar']
- verify(argv, expected_argv, expected_options)
- end
- end
-
- def test_required_argument_missing
- options = %w[--xxx --xx --x -x --aaa --aa --a -a]
- options.each do |option|
- argv = [option]
- e = assert_raise(GetoptLong::MissingArgument) do
- verify(argv, [], [])
- end
- assert_match('requires an argument', e.message)
- end
- end
-
- def test_optional_argument
- expected_options = [
- '--yyy: arg'
- ]
- expected_argv = %w[foo bar]
- options = %w[--yyy --y --y -y --bbb --bb --b -b]
- options.each do |option|
- argv = ['foo', 'bar', option, 'arg']
- verify(argv, expected_argv, expected_options)
- end
- end
-
- def test_optional_argument_missing
- expected_options = [
- '--yyy: '
- ]
- expected_argv = %w[foo bar]
- options = %w[--yyy --y --y -y --bbb --bb --b -b]
- options.each do |option|
- argv = ['foo', 'bar', option]
- verify(argv, expected_argv, expected_options)
- end
- end
-
- def test_no_argument
- expected_options = [
- '--zzz: '
- ]
- expected_argv = %w[foo bar]
- options = %w[--zzz --zz --z -z --ccc --cc --c -c]
- options.each do |option|
- argv = ['foo', option, 'bar']
- verify(argv, expected_argv, expected_options)
- end
- end
-
- def test_new_with_empty_array
- e = assert_raise(ArgumentError) do
- GetoptLong.new([])
- end
- assert_match(/no argument-flag/, e.message)
- end
-
- def test_new_with_bad_array
- e = assert_raise(ArgumentError) do
- GetoptLong.new('foo')
- end
- assert_match(/option list contains non-Array argument/, e.message)
- end
-
- def test_new_with_empty_subarray
- e = assert_raise(ArgumentError) do
- GetoptLong.new([[]])
- end
- assert_match(/no argument-flag/, e.message)
- end
-
- def test_new_with_bad_subarray
- e = assert_raise(ArgumentError) do
- GetoptLong.new([1])
- end
- assert_match(/no option name/, e.message)
- end
-
- def test_new_with_invalid_option
- invalid_options = %w[verbose -verbose -- +]
- invalid_options.each do |invalid_option|
- e = assert_raise(ArgumentError, invalid_option.to_s) do
- arguments = [
- [invalid_option, '-v', GetoptLong::NO_ARGUMENT]
- ]
- GetoptLong.new(*arguments)
- end
- assert_match(/invalid option/, e.message)
- end
- end
-
- def test_new_with_invalid_alias
- invalid_aliases = %w[v - -- +]
- invalid_aliases.each do |invalid_alias|
- e = assert_raise(ArgumentError, invalid_alias.to_s) do
- arguments = [
- ['--verbose', invalid_alias, GetoptLong::NO_ARGUMENT]
- ]
- GetoptLong.new(*arguments)
- end
- assert_match(/invalid option/, e.message)
- end
- end
-
- def test_new_with_invalid_flag
- invalid_flags = ['foo']
- invalid_flags.each do |invalid_flag|
- e = assert_raise(ArgumentError, invalid_flag.to_s) do
- arguments = [
- ['--verbose', '-v', invalid_flag]
- ]
- GetoptLong.new(*arguments)
- end
- assert_match(/no argument-flag/, e.message)
- end
- end
-
-end
diff --git a/test/test_ipaddr.rb b/test/test_ipaddr.rb
index c07ee2a8ee..e95b0d2d7a 100644
--- a/test/test_ipaddr.rb
+++ b/test/test_ipaddr.rb
@@ -133,18 +133,37 @@ class TC_IPAddr < Test::Unit::TestCase
def test_ntop
# IPv4
- assert_equal("192.168.1.1", IPAddr.ntop("\xC0\xA8\x01\x01"))
+ assert_equal("192.168.1.1", IPAddr.ntop("\xC0\xA8\x01\x01".b))
+ assert_equal("10.231.140.171", IPAddr.ntop("\x0A\xE7\x8C\xAB".b))
# IPv6
assert_equal("0000:0000:0000:0000:0000:0000:0000:0001",
- IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"))
+ IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01".b))
+ assert_equal("fe80:0000:0000:0000:f09f:9985:f09f:9986",
+ IPAddr.ntop("\xFE\x80\x00\x00\x00\x00\x00\x00\xF0\x9F\x99\x85\xF0\x9F\x99\x86".b))
# Invalid parameters
+ ## wrong length
assert_raise(IPAddr::AddressFamilyError) {
- IPAddr.ntop("192.168.1.1")
+ IPAddr.ntop("192.168.1.1".b)
}
-
assert_raise(IPAddr::AddressFamilyError) {
- IPAddr.ntop("\xC0\xA8\x01\xFF1")
+ IPAddr.ntop("\xC0\xA8\x01\xFF1".b)
+ }
+ ## UTF-8
+ assert_raise(IPAddr::InvalidAddressError) {
+ IPAddr.ntop("192.168.1.1")
+ }
+ assert_raise(IPAddr::InvalidAddressError) {
+ IPAddr.ntop("\x0A\x0A\x0A\x0A")
+ }
+ assert_raise(IPAddr::InvalidAddressError) {
+ IPAddr.ntop("\x0A\xE7\x8C\xAB")
+ }
+ assert_raise(IPAddr::InvalidAddressError) {
+ IPAddr.ntop("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01")
+ }
+ assert_raise(IPAddr::InvalidAddressError) {
+ IPAddr.ntop("\xFE\x80\x00\x00\x00\x00\x00\x00\xF0\x9F\x99\x85\xF0\x9F\x99\x86")
}
end
@@ -244,6 +263,29 @@ class TC_IPAddr < Test::Unit::TestCase
assert_equal(a.netmask, "255.255.255.0")
end
+ def test_wildcard_mask
+ a = IPAddr.new("192.168.1.2/1")
+ assert_equal(a.wildcard_mask, "127.255.255.255")
+
+ a = IPAddr.new("192.168.1.2/8")
+ assert_equal(a.wildcard_mask, "0.255.255.255")
+
+ a = IPAddr.new("192.168.1.2/16")
+ assert_equal(a.wildcard_mask, "0.0.255.255")
+
+ a = IPAddr.new("192.168.1.2/24")
+ assert_equal(a.wildcard_mask, "0.0.0.255")
+
+ a = IPAddr.new("192.168.1.2/32")
+ assert_equal(a.wildcard_mask, "0.0.0.0")
+
+ a = IPAddr.new("3ffe:505:2::/48")
+ assert_equal(a.wildcard_mask, "0000:0000:0000:ffff:ffff:ffff:ffff:ffff")
+
+ a = IPAddr.new("3ffe:505:2::/128")
+ assert_equal(a.wildcard_mask, "0000:0000:0000:0000:0000:0000:0000:0000")
+ end
+
def test_zone_id
a = IPAddr.new("192.168.1.2")
assert_raise(IPAddr::InvalidAddressError) { a.zone_id = '%ab0' }
@@ -396,6 +438,12 @@ class TC_Operator < Test::Unit::TestCase
assert_equal(true, IPAddr.new('::1').loopback?)
assert_equal(false, IPAddr.new('::').loopback?)
assert_equal(false, IPAddr.new('3ffe:505:2::1').loopback?)
+
+ assert_equal(true, IPAddr.new('::ffff:127.0.0.1').loopback?)
+ assert_equal(true, IPAddr.new('::ffff:127.127.1.1').loopback?)
+ assert_equal(false, IPAddr.new('::ffff:0.0.0.0').loopback?)
+ assert_equal(false, IPAddr.new('::ffff:192.168.2.0').loopback?)
+ assert_equal(false, IPAddr.new('::ffff:255.0.0.0').loopback?)
end
def test_private?
@@ -426,6 +474,26 @@ class TC_Operator < Test::Unit::TestCase
assert_equal(true, IPAddr.new('fc84:8bf7:e905::1').private?)
assert_equal(true, IPAddr.new('fd84:8bf7:e905::1').private?)
assert_equal(false, IPAddr.new('fe84:8bf7:e905::1').private?)
+
+ assert_equal(false, IPAddr.new('::ffff:0.0.0.0').private?)
+ assert_equal(false, IPAddr.new('::ffff:127.0.0.1').private?)
+
+ assert_equal(false, IPAddr.new('::ffff:8.8.8.8').private?)
+ assert_equal(true, IPAddr.new('::ffff:10.0.0.0').private?)
+ assert_equal(true, IPAddr.new('::ffff:10.255.255.255').private?)
+ assert_equal(false, IPAddr.new('::ffff:11.255.1.1').private?)
+
+ assert_equal(false, IPAddr.new('::ffff:172.15.255.255').private?)
+ assert_equal(true, IPAddr.new('::ffff:172.16.0.0').private?)
+ assert_equal(true, IPAddr.new('::ffff:172.31.255.255').private?)
+ assert_equal(false, IPAddr.new('::ffff:172.32.0.0').private?)
+
+ assert_equal(false, IPAddr.new('::ffff:190.168.0.0').private?)
+ assert_equal(true, IPAddr.new('::ffff:192.168.0.0').private?)
+ assert_equal(true, IPAddr.new('::ffff:192.168.255.255').private?)
+ assert_equal(false, IPAddr.new('::ffff:192.169.0.0').private?)
+
+ assert_equal(false, IPAddr.new('::ffff:169.254.0.1').private?)
end
def test_link_local?
@@ -443,6 +511,15 @@ class TC_Operator < Test::Unit::TestCase
assert_equal(false, IPAddr.new('fb84:8bf7:e905::1').link_local?)
assert_equal(true, IPAddr.new('fe80::dead:beef:cafe:1234').link_local?)
+
+ assert_equal(false, IPAddr.new('::ffff:0.0.0.0').link_local?)
+ assert_equal(false, IPAddr.new('::ffff:127.0.0.1').link_local?)
+ assert_equal(false, IPAddr.new('::ffff:10.0.0.0').link_local?)
+ assert_equal(false, IPAddr.new('::ffff:172.16.0.0').link_local?)
+ assert_equal(false, IPAddr.new('::ffff:192.168.0.0').link_local?)
+
+ assert_equal(true, IPAddr.new('::ffff:169.254.1.1').link_local?)
+ assert_equal(true, IPAddr.new('::ffff:169.254.254.255').link_local?)
end
def test_hash
diff --git a/test/test_mutex_m.rb b/test/test_mutex_m.rb
deleted file mode 100644
index e5cfbc8b5f..0000000000
--- a/test/test_mutex_m.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'mutex_m'
-
-class TestMutexM < Test::Unit::TestCase
- def test_cv_wait
- o = Object.new
- o.instance_variable_set(:@foo, nil)
- o.extend(Mutex_m)
- c = Thread::ConditionVariable.new
- t = Thread.start {
- o.synchronize do
- until foo = o.instance_variable_get(:@foo)
- c.wait(o)
- end
- foo
- end
- }
- sleep(0.0001)
- o.synchronize do
- o.instance_variable_set(:@foo, "abc")
- end
- c.signal
- assert_equal "abc", t.value
- end
-
- class KeywordInitializeParent
- def initialize(x:)
- end
- end
-
- class KeywordInitializeChild < KeywordInitializeParent
- include Mutex_m
- def initialize
- super(x: 1)
- end
- end
-
- def test_initialize_with_keyword_arg
- assert KeywordInitializeChild.new
- end
-
- class NoArgInitializeParent
- def initialize
- end
- end
-
- class NoArgInitializeChild < NoArgInitializeParent
- include Mutex_m
- def initialize
- super()
- end
- end
-
- def test_initialize_no_args
- assert NoArgInitializeChild.new
- end
-end
diff --git a/test/test_observer.rb b/test/test_observer.rb
deleted file mode 100644
index 8f8f24b3c5..0000000000
--- a/test/test_observer.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-# frozen_string_literal: true
-require 'test/unit'
-require 'observer'
-
-class TestObserver < Test::Unit::TestCase
- class TestObservable
- include Observable
-
- def notify(*args)
- changed
- notify_observers(*args)
- end
- end
-
- class TestWatcher
- def initialize(observable)
- @notifications = []
- observable.add_observer(self)
- end
-
- attr_reader :notifications
-
- def update(*args)
- @notifications << args
- end
- end
-
- def test_observers
- observable = TestObservable.new
-
- assert_equal(0, observable.count_observers)
-
- watcher1 = TestWatcher.new(observable)
-
- assert_equal(1, observable.count_observers)
-
- observable.notify("test", 123)
-
- watcher2 = TestWatcher.new(observable)
-
- assert_equal(2, observable.count_observers)
-
- observable.notify(42)
-
- assert_equal([["test", 123], [42]], watcher1.notifications)
- assert_equal([[42]], watcher2.notifications)
-
- observable.delete_observer(watcher1)
-
- assert_equal(1, observable.count_observers)
-
- observable.notify(:cats)
-
- assert_equal([["test", 123], [42]], watcher1.notifications)
- assert_equal([[42], [:cats]], watcher2.notifications)
-
- observable.delete_observers
-
- assert_equal(0, observable.count_observers)
-
- observable.notify("nope")
-
- assert_equal([["test", 123], [42]], watcher1.notifications)
- assert_equal([[42], [:cats]], watcher2.notifications)
- end
-end
diff --git a/test/test_open3.rb b/test/test_open3.rb
index a06697a37b..19277c8a66 100644
--- a/test/test_open3.rb
+++ b/test/test_open3.rb
@@ -3,10 +3,6 @@
require 'test/unit'
require 'open3'
-if RUBY_ENGINE == 'ruby'
- require_relative 'lib/jit_support'
-end
-
class TestOpen3 < Test::Unit::TestCase
RUBY = EnvUtil.rubybin
@@ -130,11 +126,7 @@ class TestOpen3 < Test::Unit::TestCase
i.close
STDERR.reopen(old)
assert_equal("zo", o.read)
- if defined?(JITSupport)
- assert_equal("ze", JITSupport.remove_mjit_logs(r.read))
- else
- assert_equal("ze", r.read)
- end
+ assert_equal("ze", r.read)
}
}
}
diff --git a/test/test_pp.rb b/test/test_pp.rb
index 9cef555d79..2fdd5df114 100644
--- a/test/test_pp.rb
+++ b/test/test_pp.rb
@@ -5,15 +5,6 @@ require 'delegate'
require 'test/unit'
require 'ruby2_keywords'
-# Define bind_call for Ruby 2.6 and earlier, to allow testing on JRuby 9.3
-class UnboundMethod
- unless public_method_defined?(:bind_call)
- def bind_call(obj, *args, &block)
- bind(obj).call(*args, &block)
- end
- end
-end
-
module PPTestModule
class PPTest < Test::Unit::TestCase
@@ -37,6 +28,13 @@ class PPTest < Test::Unit::TestCase
end
assert_equal(%(""\n), PP.pp(o, "".dup))
end
+
+ def test_range
+ assert_equal("0..1\n", PP.pp(0..1, "".dup))
+ assert_equal("0...1\n", PP.pp(0...1, "".dup))
+ assert_equal("0...\n", PP.pp(0..., "".dup))
+ assert_equal("...1\n", PP.pp(...1, "".dup))
+ end
end
class HasInspect
@@ -149,7 +147,19 @@ class PPCycleTest < Test::Unit::TestCase
a = S.new(1,2)
a.b = a
assert_equal("#<struct Struct::S a=1, b=#<struct Struct::S:...>>\n", PP.pp(a, ''.dup))
- assert_equal("#{a.inspect}\n", PP.pp(a, ''.dup))
+ assert_equal("#{a.inspect}\n", PP.pp(a, ''.dup)) unless RUBY_ENGINE == "truffleruby"
+ end
+
+ if defined?(Data.define)
+ D = Data.define(:aaa, :bbb)
+ def test_data
+ a = D.new("aaa", "bbb")
+ assert_equal("#<data PPTestModule::PPCycleTest::D\n aaa=\"aaa\",\n bbb=\"bbb\">\n", PP.pp(a, ''.dup, 20))
+ assert_equal("#{a.inspect}\n", PP.pp(a, ''.dup))
+
+ b = Data.define(:a).new(42)
+ assert_equal("#{b.inspect}\n", PP.pp(b, ''.dup))
+ end
end
def test_object
@@ -164,11 +174,12 @@ class PPCycleTest < Test::Unit::TestCase
end
def test_withinspect
+ omit if RUBY_ENGINE == "jruby" or RUBY_ENGINE == "truffleruby"
a = []
a << HasInspect.new(a)
assert_equal("[<inspect:[...]>]\n", PP.pp(a, ''.dup))
assert_equal("#{a.inspect}\n", PP.pp(a, ''.dup))
- end unless RUBY_VERSION < "2.7" # temporary mask to test on JRuby 9.3 (2.6 equivalent)
+ end
def test_share_nil
begin
@@ -188,6 +199,7 @@ class PPSingleLineTest < Test::Unit::TestCase
end
def test_hash_in_array
+ omit if RUBY_ENGINE == "jruby"
assert_equal("[{}]", PP.singleline_pp([->(*a){a.last.clear}.ruby2_keywords.call(a: 1)], ''.dup))
assert_equal("[{}]", PP.singleline_pp([Hash.ruby2_keywords_hash({})], ''.dup))
end
@@ -226,10 +238,36 @@ if defined?(RubyVM)
AST = RubyVM::AbstractSyntaxTree
def test_lasgn_literal
ast = AST.parse("_=1")
- expected = "(SCOPE@1:0-1:3 tbl: [:_] args: nil body: (LASGN@1:0-1:3 :_ (LIT@1:2-1:3 1)))"
+ integer = RUBY_VERSION >= "3.4." ? "INTEGER" : "LIT"
+ expected = "(SCOPE@1:0-1:3 tbl: [:_] args: nil body: (LASGN@1:0-1:3 :_ (#{integer}@1:2-1:3 1)))"
assert_equal(expected, PP.singleline_pp(ast, ''.dup), ast)
end
end
end
+class PPInheritedTest < Test::Unit::TestCase
+ class PPSymbolHash < PP
+ def pp_hash_pair(k, v)
+ case k
+ when Symbol
+ text k.inspect.delete_prefix(":")
+ text ":"
+ group(1) {
+ breakable
+ pp v
+ }
+ else
+ super
+ end
+ end
+ end
+
+ def test_hash_override
+ obj = {k: 1, "": :null, "0": :zero, 100 => :ten}
+ assert_equal <<~EXPECT, PPSymbolHash.pp(obj, "".dup)
+ {k: 1, "": :null, "0": :zero, 100=>:ten}
+ EXPECT
+ end
+end
+
end
diff --git a/test/test_rbconfig.rb b/test/test_rbconfig.rb
index fcbbbd8500..1bbf01b9a6 100644
--- a/test/test_rbconfig.rb
+++ b/test/test_rbconfig.rb
@@ -51,13 +51,4 @@ class TestRbConfig < Test::Unit::TestCase
assert_match(/\$\(sitearch|\$\(rubysitearchprefix\)/, val, "#{key} #{bug7823}")
end
end
-
- if /darwin/ =~ RUBY_PLATFORM
- def test_sdkroot
- assert_separately([{"SDKROOT" => "$(prefix)/SDKRoot"}], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- assert_equal RbConfig::CONFIG["prefix"]+"/SDKRoot", RbConfig::CONFIG["SDKROOT"]
- end;
- end
- end
end
diff --git a/test/test_set.rb b/test/test_set.rb
deleted file mode 100644
index 164dc460a7..0000000000
--- a/test/test_set.rb
+++ /dev/null
@@ -1,879 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'set'
-
-class TC_Set < Test::Unit::TestCase
- class Set2 < Set
- end
-
- def test_aref
- assert_nothing_raised {
- Set[]
- Set[nil]
- Set[1,2,3]
- }
-
- assert_equal(0, Set[].size)
- assert_equal(1, Set[nil].size)
- assert_equal(1, Set[[]].size)
- assert_equal(1, Set[[nil]].size)
-
- set = Set[2,4,6,4]
- assert_equal(Set.new([2,4,6]), set)
- end
-
- def test_s_new
- assert_nothing_raised {
- Set.new()
- Set.new(nil)
- Set.new([])
- Set.new([1,2])
- Set.new('a'..'c')
- }
- assert_raise(ArgumentError) {
- Set.new(false)
- }
- assert_raise(ArgumentError) {
- Set.new(1)
- }
- assert_raise(ArgumentError) {
- Set.new(1,2)
- }
-
- assert_equal(0, Set.new().size)
- assert_equal(0, Set.new(nil).size)
- assert_equal(0, Set.new([]).size)
- assert_equal(1, Set.new([nil]).size)
-
- ary = [2,4,6,4]
- set = Set.new(ary)
- ary.clear
- assert_equal(false, set.empty?)
- assert_equal(3, set.size)
-
- ary = [1,2,3]
-
- s = Set.new(ary) { |o| o * 2 }
- assert_equal([2,4,6], s.sort)
- end
-
- def test_clone
- set1 = Set.new
- set2 = set1.clone
- set1 << 'abc'
- assert_equal(Set.new, set2)
- end
-
- def test_dup
- set1 = Set[1,2]
- set2 = set1.dup
-
- assert_not_same(set1, set2)
-
- assert_equal(set1, set2)
-
- set1.add(3)
-
- assert_not_equal(set1, set2)
- end
-
- def test_size
- assert_equal(0, Set[].size)
- assert_equal(2, Set[1,2].size)
- assert_equal(2, Set[1,2,1].size)
- end
-
- def test_empty?
- assert_equal(true, Set[].empty?)
- assert_equal(false, Set[1, 2].empty?)
- end
-
- def test_clear
- set = Set[1,2]
- ret = set.clear
-
- assert_same(set, ret)
- assert_equal(true, set.empty?)
- end
-
- def test_replace
- set = Set[1,2]
- ret = set.replace('a'..'c')
-
- assert_same(set, ret)
- assert_equal(Set['a','b','c'], set)
-
- set = Set[1,2]
- assert_raise(ArgumentError) {
- set.replace(3)
- }
- assert_equal(Set[1,2], set)
- end
-
- def test_to_a
- set = Set[1,2,3,2]
- ary = set.to_a
-
- assert_equal([1,2,3], ary.sort)
- end
-
- def test_flatten
- # test1
- set1 = Set[
- 1,
- Set[
- 5,
- Set[7,
- Set[0]
- ],
- Set[6,2],
- 1
- ],
- 3,
- Set[3,4]
- ]
-
- set2 = set1.flatten
- set3 = Set.new(0..7)
-
- assert_not_same(set2, set1)
- assert_equal(set3, set2)
-
- # test2; destructive
- orig_set1 = set1
- set1.flatten!
-
- assert_same(orig_set1, set1)
- assert_equal(set3, set1)
-
- # test3; multiple occurrences of a set in an set
- set1 = Set[1, 2]
- set2 = Set[set1, Set[set1, 4], 3]
-
- assert_nothing_raised {
- set2.flatten!
- }
-
- assert_equal(Set.new(1..4), set2)
-
- # test4; recursion
- set2 = Set[]
- set1 = Set[1, set2]
- set2.add(set1)
-
- assert_raise(ArgumentError) {
- set1.flatten!
- }
-
- # test5; miscellaneous
- empty = Set[]
- set = Set[Set[empty, "a"],Set[empty, "b"]]
-
- assert_nothing_raised {
- set.flatten
- }
-
- set1 = empty.merge(Set["no_more", set])
-
- assert_nil(Set.new(0..31).flatten!)
-
- x = Set[Set[],Set[1,2]].flatten!
- y = Set[1,2]
-
- assert_equal(x, y)
- end
-
- def test_include?
- set = Set[1,2,3]
-
- assert_equal(true, set.include?(1))
- assert_equal(true, set.include?(2))
- assert_equal(true, set.include?(3))
- assert_equal(false, set.include?(0))
- assert_equal(false, set.include?(nil))
-
- set = Set["1",nil,"2",nil,"0","1",false]
- assert_equal(true, set.include?(nil))
- assert_equal(true, set.include?(false))
- assert_equal(true, set.include?("1"))
- assert_equal(false, set.include?(0))
- assert_equal(false, set.include?(true))
- end
-
- def test_eqq
- set = Set[1,2,3]
-
- assert_equal(true, set === 1)
- assert_equal(true, set === 2)
- assert_equal(true, set === 3)
- assert_equal(false, set === 0)
- assert_equal(false, set === nil)
-
- set = Set["1",nil,"2",nil,"0","1",false]
- assert_equal(true, set === nil)
- assert_equal(true, set === false)
- assert_equal(true, set === "1")
- assert_equal(false, set === 0)
- assert_equal(false, set === true)
- end
-
- def test_superset?
- set = Set[1,2,3]
-
- assert_raise(ArgumentError) {
- set.superset?()
- }
-
- assert_raise(ArgumentError) {
- set.superset?(2)
- }
-
- assert_raise(ArgumentError) {
- set.superset?([2])
- }
-
- [Set, Set2].each { |klass|
- assert_equal(true, set.superset?(klass[]), klass.name)
- assert_equal(true, set.superset?(klass[1,2]), klass.name)
- assert_equal(true, set.superset?(klass[1,2,3]), klass.name)
- assert_equal(false, set.superset?(klass[1,2,3,4]), klass.name)
- assert_equal(false, set.superset?(klass[1,4]), klass.name)
-
- assert_equal(true, set >= klass[1,2,3], klass.name)
- assert_equal(true, set >= klass[1,2], klass.name)
-
- assert_equal(true, Set[].superset?(klass[]), klass.name)
- }
- end
-
- def test_proper_superset?
- set = Set[1,2,3]
-
- assert_raise(ArgumentError) {
- set.proper_superset?()
- }
-
- assert_raise(ArgumentError) {
- set.proper_superset?(2)
- }
-
- assert_raise(ArgumentError) {
- set.proper_superset?([2])
- }
-
- [Set, Set2].each { |klass|
- assert_equal(true, set.proper_superset?(klass[]), klass.name)
- assert_equal(true, set.proper_superset?(klass[1,2]), klass.name)
- assert_equal(false, set.proper_superset?(klass[1,2,3]), klass.name)
- assert_equal(false, set.proper_superset?(klass[1,2,3,4]), klass.name)
- assert_equal(false, set.proper_superset?(klass[1,4]), klass.name)
-
- assert_equal(false, set > klass[1,2,3], klass.name)
- assert_equal(true, set > klass[1,2], klass.name)
-
- assert_equal(false, Set[].proper_superset?(klass[]), klass.name)
- }
- end
-
- def test_subset?
- set = Set[1,2,3]
-
- assert_raise(ArgumentError) {
- set.subset?()
- }
-
- assert_raise(ArgumentError) {
- set.subset?(2)
- }
-
- assert_raise(ArgumentError) {
- set.subset?([2])
- }
-
- [Set, Set2].each { |klass|
- assert_equal(true, set.subset?(klass[1,2,3,4]), klass.name)
- assert_equal(true, set.subset?(klass[1,2,3]), klass.name)
- assert_equal(false, set.subset?(klass[1,2]), klass.name)
- assert_equal(false, set.subset?(klass[]), klass.name)
-
- assert_equal(true, set <= klass[1,2,3], klass.name)
- assert_equal(true, set <= klass[1,2,3,4], klass.name)
-
- assert_equal(true, Set[].subset?(klass[1]), klass.name)
- assert_equal(true, Set[].subset?(klass[]), klass.name)
- }
- end
-
- def test_proper_subset?
- set = Set[1,2,3]
-
- assert_raise(ArgumentError) {
- set.proper_subset?()
- }
-
- assert_raise(ArgumentError) {
- set.proper_subset?(2)
- }
-
- assert_raise(ArgumentError) {
- set.proper_subset?([2])
- }
-
- [Set, Set2].each { |klass|
- assert_equal(true, set.proper_subset?(klass[1,2,3,4]), klass.name)
- assert_equal(false, set.proper_subset?(klass[1,2,3]), klass.name)
- assert_equal(false, set.proper_subset?(klass[1,2]), klass.name)
- assert_equal(false, set.proper_subset?(klass[]), klass.name)
-
- assert_equal(false, set < klass[1,2,3], klass.name)
- assert_equal(true, set < klass[1,2,3,4], klass.name)
-
- assert_equal(false, Set[].proper_subset?(klass[]), klass.name)
- }
- end
-
- def test_spacecraft_operator
- set = Set[1,2,3]
-
- assert_nil(set <=> 2)
-
- assert_nil(set <=> set.to_a)
-
- [Set, Set2].each { |klass|
- assert_equal(-1, set <=> klass[1,2,3,4], klass.name)
- assert_equal( 0, set <=> klass[3,2,1] , klass.name)
- assert_equal(nil, set <=> klass[1,2,4] , klass.name)
- assert_equal(+1, set <=> klass[2,3] , klass.name)
- assert_equal(+1, set <=> klass[] , klass.name)
-
- assert_equal(0, Set[] <=> klass[], klass.name)
- }
- end
-
- def assert_intersect(expected, set, other)
- case expected
- when true
- assert_send([set, :intersect?, other])
- assert_send([set, :intersect?, other.to_a])
- assert_send([other, :intersect?, set])
- assert_not_send([set, :disjoint?, other])
- assert_not_send([set, :disjoint?, other.to_a])
- assert_not_send([other, :disjoint?, set])
- when false
- assert_not_send([set, :intersect?, other])
- assert_not_send([set, :intersect?, other.to_a])
- assert_not_send([other, :intersect?, set])
- assert_send([set, :disjoint?, other])
- assert_send([set, :disjoint?, other.to_a])
- assert_send([other, :disjoint?, set])
- when Class
- assert_raise(expected) {
- set.intersect?(other)
- }
- assert_raise(expected) {
- set.disjoint?(other)
- }
- else
- raise ArgumentError, "%s: unsupported expected value: %s" % [__method__, expected.inspect]
- end
- end
-
- def test_intersect?
- set = Set[3,4,5]
-
- assert_intersect(ArgumentError, set, 3)
- assert_intersect(true, set, Set[2,4,6])
-
- assert_intersect(true, set, set)
- assert_intersect(true, set, Set[2,4])
- assert_intersect(true, set, Set[5,6,7])
- assert_intersect(true, set, Set[1,2,6,8,4])
-
- assert_intersect(false, set, Set[])
- assert_intersect(false, set, Set[0,2])
- assert_intersect(false, set, Set[0,2,6])
- assert_intersect(false, set, Set[0,2,6,8,10])
-
- # Make sure set hasn't changed
- assert_equal(Set[3,4,5], set)
- end
-
- def test_each
- ary = [1,3,5,7,10,20]
- set = Set.new(ary)
-
- ret = set.each { |o| }
- assert_same(set, ret)
-
- e = set.each
- assert_instance_of(Enumerator, e)
-
- assert_nothing_raised {
- set.each { |o|
- ary.delete(o) or raise "unexpected element: #{o}"
- }
-
- ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
- }
-
- assert_equal(6, e.size)
- set << 42
- assert_equal(7, e.size)
- end
-
- def test_add
- set = Set[1,2,3]
-
- ret = set.add(2)
- assert_same(set, ret)
- assert_equal(Set[1,2,3], set)
-
- ret = set.add?(2)
- assert_nil(ret)
- assert_equal(Set[1,2,3], set)
-
- ret = set.add(4)
- assert_same(set, ret)
- assert_equal(Set[1,2,3,4], set)
-
- ret = set.add?(5)
- assert_same(set, ret)
- assert_equal(Set[1,2,3,4,5], set)
- end
-
- def test_delete
- set = Set[1,2,3]
-
- ret = set.delete(4)
- assert_same(set, ret)
- assert_equal(Set[1,2,3], set)
-
- ret = set.delete?(4)
- assert_nil(ret)
- assert_equal(Set[1,2,3], set)
-
- ret = set.delete(2)
- assert_equal(set, ret)
- assert_equal(Set[1,3], set)
-
- ret = set.delete?(1)
- assert_equal(set, ret)
- assert_equal(Set[3], set)
- end
-
- def test_delete_if
- set = Set.new(1..10)
- ret = set.delete_if { |i| i > 10 }
- assert_same(set, ret)
- assert_equal(Set.new(1..10), set)
-
- set = Set.new(1..10)
- ret = set.delete_if { |i| i % 3 == 0 }
- assert_same(set, ret)
- assert_equal(Set[1,2,4,5,7,8,10], set)
-
- set = Set.new(1..10)
- enum = set.delete_if
- assert_equal(set.size, enum.size)
- assert_same(set, enum.each { |i| i % 3 == 0 })
- assert_equal(Set[1,2,4,5,7,8,10], set)
- end
-
- def test_keep_if
- set = Set.new(1..10)
- ret = set.keep_if { |i| i <= 10 }
- assert_same(set, ret)
- assert_equal(Set.new(1..10), set)
-
- set = Set.new(1..10)
- ret = set.keep_if { |i| i % 3 != 0 }
- assert_same(set, ret)
- assert_equal(Set[1,2,4,5,7,8,10], set)
-
- set = Set.new(1..10)
- enum = set.keep_if
- assert_equal(set.size, enum.size)
- assert_same(set, enum.each { |i| i % 3 != 0 })
- assert_equal(Set[1,2,4,5,7,8,10], set)
- end
-
- def test_collect!
- set = Set[1,2,3,'a','b','c',-1..1,2..4]
-
- ret = set.collect! { |i|
- case i
- when Numeric
- i * 2
- when String
- i.upcase
- else
- nil
- end
- }
-
- assert_same(set, ret)
- assert_equal(Set[2,4,6,'A','B','C',nil], set)
-
- set = Set[1,2,3,'a','b','c',-1..1,2..4]
- enum = set.collect!
-
- assert_equal(set.size, enum.size)
- assert_same(set, enum.each { |i|
- case i
- when Numeric
- i * 2
- when String
- i.upcase
- else
- nil
- end
- })
- assert_equal(Set[2,4,6,'A','B','C',nil], set)
- end
-
- def test_reject!
- set = Set.new(1..10)
-
- ret = set.reject! { |i| i > 10 }
- assert_nil(ret)
- assert_equal(Set.new(1..10), set)
-
- ret = set.reject! { |i| i % 3 == 0 }
- assert_same(set, ret)
- assert_equal(Set[1,2,4,5,7,8,10], set)
-
- set = Set.new(1..10)
- enum = set.reject!
- assert_equal(set.size, enum.size)
- assert_same(set, enum.each { |i| i % 3 == 0 })
- assert_equal(Set[1,2,4,5,7,8,10], set)
- end
-
- def test_select!
- set = Set.new(1..10)
- ret = set.select! { |i| i <= 10 }
- assert_equal(nil, ret)
- assert_equal(Set.new(1..10), set)
-
- set = Set.new(1..10)
- ret = set.select! { |i| i % 3 != 0 }
- assert_same(set, ret)
- assert_equal(Set[1,2,4,5,7,8,10], set)
-
- set = Set.new(1..10)
- enum = set.select!
- assert_equal(set.size, enum.size)
- assert_equal(nil, enum.each { |i| i <= 10 })
- assert_equal(Set.new(1..10), set)
- end
-
- def test_filter!
- set = Set.new(1..10)
- ret = set.filter! { |i| i <= 10 }
- assert_equal(nil, ret)
- assert_equal(Set.new(1..10), set)
-
- set = Set.new(1..10)
- ret = set.filter! { |i| i % 3 != 0 }
- assert_same(set, ret)
- assert_equal(Set[1,2,4,5,7,8,10], set)
-
- set = Set.new(1..10)
- enum = set.filter!
- assert_equal(set.size, enum.size)
- assert_equal(nil, enum.each { |i| i <= 10 })
- assert_equal(Set.new(1..10), set)
- end
-
- def test_merge
- set = Set[1,2,3]
-
- ret = set.merge([2,4,6])
- assert_same(set, ret)
- assert_equal(Set[1,2,3,4,6], set)
- end
-
- def test_subtract
- set = Set[1,2,3]
-
- ret = set.subtract([2,4,6])
- assert_same(set, ret)
- assert_equal(Set[1,3], set)
- end
-
- def test_plus
- set = Set[1,2,3]
-
- ret = set + [2,4,6]
- assert_not_same(set, ret)
- assert_equal(Set[1,2,3,4,6], ret)
- end
-
- def test_minus
- set = Set[1,2,3]
-
- ret = set - [2,4,6]
- assert_not_same(set, ret)
- assert_equal(Set[1,3], ret)
- end
-
- def test_and
- set = Set[1,2,3,4]
-
- ret = set & [2,4,6]
- assert_not_same(set, ret)
- assert_equal(Set[2,4], ret)
- end
-
- def test_xor
- set = Set[1,2,3,4]
- ret = set ^ [2,4,5,5]
- assert_not_same(set, ret)
- assert_equal(Set[1,3,5], ret)
- end
-
- def test_eq
- set1 = Set[2,3,1]
- set2 = Set[1,2,3]
-
- assert_equal(set1, set1)
- assert_equal(set1, set2)
- assert_not_equal(Set[1], [1])
-
- set1 = Class.new(Set)["a", "b"]
- set1.add(set1).reset # Make recursive
- set2 = Set["a", "b", Set["a", "b", set1]]
-
- assert_equal(set1, set2)
-
- assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], "[ruby-dev:26127]")
- end
-
- def test_classify
- set = Set.new(1..10)
- ret = set.classify { |i| i % 3 }
-
- assert_equal(3, ret.size)
- assert_instance_of(Hash, ret)
- ret.each_value { |value| assert_instance_of(Set, value) }
- assert_equal(Set[3,6,9], ret[0])
- assert_equal(Set[1,4,7,10], ret[1])
- assert_equal(Set[2,5,8], ret[2])
-
- set = Set.new(1..10)
- enum = set.classify
-
- assert_equal(set.size, enum.size)
- ret = enum.each { |i| i % 3 }
- assert_equal(3, ret.size)
- assert_instance_of(Hash, ret)
- ret.each_value { |value| assert_instance_of(Set, value) }
- assert_equal(Set[3,6,9], ret[0])
- assert_equal(Set[1,4,7,10], ret[1])
- assert_equal(Set[2,5,8], ret[2])
- end
-
- def test_divide
- set = Set.new(1..10)
- ret = set.divide { |i| i % 3 }
-
- assert_equal(3, ret.size)
- n = 0
- ret.each { |s| n += s.size }
- assert_equal(set.size, n)
- assert_equal(set, ret.flatten)
-
- set = Set[7,10,5,11,1,3,4,9,0]
- ret = set.divide { |a,b| (a - b).abs == 1 }
-
- assert_equal(4, ret.size)
- n = 0
- ret.each { |s| n += s.size }
- assert_equal(set.size, n)
- assert_equal(set, ret.flatten)
- ret.each { |s|
- if s.include?(0)
- assert_equal(Set[0,1], s)
- elsif s.include?(3)
- assert_equal(Set[3,4,5], s)
- elsif s.include?(7)
- assert_equal(Set[7], s)
- elsif s.include?(9)
- assert_equal(Set[9,10,11], s)
- else
- raise "unexpected group: #{s.inspect}"
- end
- }
-
- set = Set.new(1..10)
- enum = set.divide
- ret = enum.each { |i| i % 3 }
-
- assert_equal(set.size, enum.size)
- assert_equal(3, ret.size)
- n = 0
- ret.each { |s| n += s.size }
- assert_equal(set.size, n)
- assert_equal(set, ret.flatten)
- end
-
- def test_freeze
- orig = set = Set[1,2,3]
- assert_equal false, set.frozen?
- set << 4
- assert_same orig, set.freeze
- assert_equal true, set.frozen?
- assert_raise(FrozenError) {
- set << 5
- }
- assert_equal 4, set.size
- end
-
- def test_freeze_dup
- set1 = Set[1,2,3]
- set1.freeze
- set2 = set1.dup
-
- assert_not_predicate set2, :frozen?
- assert_nothing_raised {
- set2.add 4
- }
- end
-
- def test_freeze_clone
- set1 = Set[1,2,3]
- set1.freeze
- set2 = set1.clone
-
- assert_predicate set2, :frozen?
- assert_raise(FrozenError) {
- set2.add 5
- }
- end
-
- def test_freeze_clone_false
- set1 = Set[1,2,3]
- set1.freeze
- set2 = set1.clone(freeze: false)
-
- assert_not_predicate set2, :frozen?
- set2.add 5
- assert_equal Set[1,2,3,5], set2
- assert_equal Set[1,2,3], set1
- end if Kernel.instance_method(:initialize_clone).arity != 1
-
- def test_join
- assert_equal('123', Set[1, 2, 3].join)
- assert_equal('1 & 2 & 3', Set[1, 2, 3].join(' & '))
- end
-
- def test_inspect
- set1 = Set[1, 2]
- assert_equal('#<Set: {1, 2}>', set1.inspect)
-
- set2 = Set[Set[0], 1, 2, set1]
- assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2}>}>', set2.inspect)
-
- set1.add(set2)
- assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2, #<Set: {...}>}>}>', set2.inspect)
- end
-
- def test_to_s
- set1 = Set[1, 2]
- assert_equal('#<Set: {1, 2}>', set1.to_s)
-
- set2 = Set[Set[0], 1, 2, set1]
- assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2}>}>', set2.to_s)
-
- set1.add(set2)
- assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2, #<Set: {...}>}>}>', set2.to_s)
- end
-
- def test_compare_by_identity
- a1, a2 = "a", "a"
- b1, b2 = "b", "b"
- c = "c"
- array = [a1, b1, c, a2, b2]
-
- iset = Set.new.compare_by_identity
- assert_send([iset, :compare_by_identity?])
- iset.merge(array)
- assert_equal(5, iset.size)
- assert_equal(array.map(&:object_id).sort, iset.map(&:object_id).sort)
-
- set = Set.new
- assert_not_send([set, :compare_by_identity?])
- set.merge(array)
- assert_equal(3, set.size)
- assert_equal(array.uniq.sort, set.sort)
- end
-
- def test_reset
- [Set, Class.new(Set)].each { |klass|
- a = [1, 2]
- b = [1]
- set = klass.new([a, b])
-
- b << 2
- set.reset
-
- assert_equal(klass.new([a]), set, klass.name)
- }
- end
-end
-
-class TC_Enumerable < Test::Unit::TestCase
- def test_to_set
- ary = [2,5,4,3,2,1,3]
-
- set = ary.to_set
- assert_instance_of(Set, set)
- assert_equal([1,2,3,4,5], set.sort)
-
- set = ary.to_set { |o| o * -2 }
- assert_instance_of(Set, set)
- assert_equal([-10,-8,-6,-4,-2], set.sort)
-
- assert_same set, set.to_set
- assert_not_same set, set.to_set { |o| o }
- end
-end
-
-class TC_Set_Builtin < Test::Unit::TestCase
- private def should_omit?
- (RUBY_VERSION.scan(/\d+/).map(&:to_i) <=> [3, 2]) < 0 ||
- !File.exist?(File.expand_path('../prelude.rb', __dir__))
- end
-
- def test_Set
- omit "skipping the test for the builtin Set" if should_omit?
-
- assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- assert_nothing_raised do
- set = Set.new([1, 2])
- assert_equal('Set', set.class.name)
- end
- end;
-
- assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- assert_nothing_raised do
- set = Set[1, 2]
- assert_equal('Set', set.class.name)
- end
- end;
- end
-
- def test_to_set
- omit "skipping the test for the builtin Enumerable#to_set" if should_omit?
-
- assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
- begin;
- assert_nothing_raised do
- set = [1, 2].to_set
- assert_equal('Set', set.class.name)
- end
- end;
- end
-end
diff --git a/test/test_singleton.rb b/test/test_singleton.rb
index b3c48bb5f5..e474a0ccc5 100644
--- a/test/test_singleton.rb
+++ b/test/test_singleton.rb
@@ -94,6 +94,23 @@ class TestSingleton < Test::Unit::TestCase
assert_same a, b
end
+ def test_inheritance_creates_separate_singleton
+ a = SingletonTest.instance
+ b = Class.new(SingletonTest).instance
+
+ assert_not_same a, b
+ end
+
+ def test_inheritance_instantiation
+ klass = Class.new do
+ include Singleton
+
+ public_class_method :new
+ end
+
+ assert Class.new(klass).new
+ end
+
def test_class_level_cloning_preserves_singleton_behavior
klass = SingletonTest.clone
@@ -101,4 +118,8 @@ class TestSingleton < Test::Unit::TestCase
b = klass.instance
assert_same a, b
end
+
+ def test_class_level_cloning_creates_separate_singleton
+ assert_not_same SingletonTest.instance, SingletonTest.clone.instance
+ end
end
diff --git a/test/test_syslog.rb b/test/test_syslog.rb
deleted file mode 100644
index 842ae8df49..0000000000
--- a/test/test_syslog.rb
+++ /dev/null
@@ -1,193 +0,0 @@
-# frozen_string_literal: false
-# Please only run this test on machines reasonable for testing.
-# If in doubt, ask your admin.
-
-require 'test/unit'
-
-begin
- require 'syslog'
-rescue LoadError
- # suppress error messages.
-end
-
-class TestSyslog < Test::Unit::TestCase
- def test_new
- assert_raise(NoMethodError) {
- Syslog.new
- }
- end
-
- def test_instance
- sl1 = Syslog.instance
- sl2 = Syslog.open
- sl3 = Syslog.instance
-
- assert_equal(Syslog, sl1)
- assert_equal(Syslog, sl2)
- assert_equal(Syslog, sl3)
- ensure
- Syslog.close if Syslog.opened?
- end
-
- def test_open
- # default parameters
- Syslog.open
-
- assert_equal($0, Syslog.ident)
- assert_equal(Syslog::LOG_PID | Syslog::LOG_CONS, Syslog.options)
- assert_equal(Syslog::LOG_USER, Syslog.facility)
-
- # open without close
- assert_raise(RuntimeError) {
- Syslog.open
- }
-
- Syslog.close
-
- # given parameters
- options = Syslog::LOG_NDELAY | Syslog::LOG_PID
- Syslog.open("foo", options, Syslog::LOG_DAEMON)
-
- assert_equal('foo', Syslog.ident)
- assert_equal(options, Syslog.options)
- assert_equal(Syslog::LOG_DAEMON, Syslog.facility)
-
- Syslog.close
-
- # default parameters again (after close)
- Syslog.open
- Syslog.close
-
- assert_equal(nil, Syslog.ident)
- assert_equal(nil, Syslog.options)
- assert_equal(nil, Syslog.facility)
-
- # block
- param = nil
- Syslog.open { |syslog|
- param = syslog
- }
- assert_equal(Syslog, param)
- ensure
- Syslog.close if Syslog.opened?
- end
-
- def test_opened?
- assert_equal(false, Syslog.opened?)
-
- Syslog.open
- assert_equal(true, Syslog.opened?)
-
- Syslog.close
- assert_equal(false, Syslog.opened?)
-
- Syslog.open {
- assert_equal(true, Syslog.opened?)
- }
-
- assert_equal(false, Syslog.opened?)
- end
-
- def test_close
- assert_raise(RuntimeError) {
- Syslog.close
- }
- end
-
- def test_mask
- assert_equal(nil, Syslog.mask)
-
- Syslog.open
-
- orig = Syslog.mask
-
- Syslog.mask = Syslog.LOG_UPTO(Syslog::LOG_ERR)
- assert_equal(Syslog.LOG_UPTO(Syslog::LOG_ERR), Syslog.mask)
-
- Syslog.mask = Syslog.LOG_MASK(Syslog::LOG_CRIT)
- assert_equal(Syslog.LOG_MASK(Syslog::LOG_CRIT), Syslog.mask)
-
- Syslog.mask = orig
- ensure
- Syslog.close if Syslog.opened?
- end
-
- def syslog_line_regex(ident, message)
- /(?:^| )#{Regexp.quote(ident)}(?:\[([1-9][0-9]*)\])?(?: | ([1-9][0-9]*) - - ||[: ].* )#{Regexp.quote(message)}$/
- end
-
- def test_log
- IO.pipe {|stderr|
- pid = fork {
- stderr[0].close
- STDERR.reopen(stderr[1])
- stderr[1].close
-
- options = Syslog::LOG_PERROR | Syslog::LOG_NDELAY
-
- Syslog.open("syslog_test", options) { |sl|
- sl.log(Syslog::LOG_NOTICE, "test1 - hello, %s!", "world")
- sl.notice("test1 - hello, %s!", "world")
- }
-
- Syslog.open("syslog_test", options | Syslog::LOG_PID) { |sl|
- sl.log(Syslog::LOG_CRIT, "test2 - pid")
- sl.crit("test2 - pid")
- }
- exit!
- }
-
- stderr[1].close
- Process.waitpid(pid)
-
- # LOG_PERROR is not implemented on Cygwin or Solaris. Only test
- # these on systems that define it.
- return unless Syslog.const_defined?(:LOG_PERROR)
- # LOG_PERROR is defined but not supported yet on Android.
- return if RUBY_PLATFORM =~ /android/
-
- 2.times {
- re = syslog_line_regex("syslog_test", "test1 - hello, world!")
- line = stderr[0].gets
- # In AIX, each LOG_PERROR output line has an appended empty line.
- if /aix/ =~ RUBY_PLATFORM && line =~ /^$/
- line = stderr[0].gets
- end
- m = re.match(line)
- assert_not_nil(m)
- if m[1]
- # pid is written regardless of LOG_PID on OS X 10.7+
- assert_equal(pid, m[1].to_i)
- end
- }
-
- 2.times {
- re = syslog_line_regex("syslog_test", "test2 - pid")
- line = stderr[0].gets
- # In AIX, each LOG_PERROR output line has an appended empty line.
- if /aix/ =~ RUBY_PLATFORM && line =~ /^$/
- line = stderr[0].gets
- end
- m = re.match(line)
- assert_not_nil(m)
- output_pid = m[1] || m[2]
- assert_not_nil(output_pid)
- assert_equal(pid, output_pid.to_i)
- }
- }
- end
-
- def test_inspect
- Syslog.open { |sl|
- assert_equal(format('<#%s: opened=true, ident="%s", options=%d, facility=%d, mask=%d>',
- Syslog,
- sl.ident,
- sl.options,
- sl.facility,
- sl.mask),
- sl.inspect)
- }
-
- assert_equal(format('<#%s: opened=false>', Syslog), Syslog.inspect)
- end
-end if defined?(Syslog)
diff --git a/test/test_tempfile.rb b/test/test_tempfile.rb
index 6b087f9207..eddbac5d75 100644
--- a/test/test_tempfile.rb
+++ b/test/test_tempfile.rb
@@ -63,6 +63,22 @@ class TestTempfile < Test::Unit::TestCase
assert_match(/\.txt$/, File.basename(t.path))
end
+ def test_dup
+ t = tempfile
+ t2 = t.dup
+ t2.close
+ assert_equal true, t2.closed?
+ assert_equal false, t.closed?
+ end
+
+ def test_clone
+ t = tempfile
+ t2 = t.clone
+ t2.close
+ assert_equal true, t2.closed?
+ assert_equal false, t.closed?
+ end
+
def test_unlink
t = tempfile("foo")
path = t.path
@@ -209,8 +225,7 @@ puts Tempfile.new('foo').path
def test_tempfile_finalizer_does_not_run_if_unlinked
bug8768 = '[ruby-core:56521] [Bug #8768]'
- args = %w(--disable-gems -rtempfile)
- assert_in_out_err(args, <<-'EOS') do |(filename), (error)|
+ assert_in_out_err(%w(-rtempfile), <<-'EOS') do |(filename), (error)|
tmp = Tempfile.new('foo')
puts tmp.path
tmp.close
@@ -363,6 +378,14 @@ puts Tempfile.new('foo').path
assert_file.not_exist?(path)
end
+ def test_open
+ Tempfile.open {|f|
+ file = f.open
+ assert_kind_of File, file
+ assert_equal f.to_i, file.to_i
+ }
+ end
+
def test_open_traversal_dir
assert_mktmpdir_traversal do |traversal_path|
t = Tempfile.open([traversal_path, 'foo'])
diff --git a/test/test_time.rb b/test/test_time.rb
index b50d8417cf..23e8e104a1 100644
--- a/test/test_time.rb
+++ b/test/test_time.rb
@@ -62,6 +62,15 @@ class TestTimeExtension < Test::Unit::TestCase # :nodoc:
assert_equal(true, t.utc?)
end
+ def test_rfc2822_nonlinear
+ pre = ->(n) {"0 Feb 00 00 :00" + " " * n}
+ assert_linear_performance([100, 500, 5000, 50_000], pre: pre) do |s|
+ assert_raise(ArgumentError) do
+ Time.rfc2822(s)
+ end
+ end
+ end
+
if defined?(Ractor)
def test_rfc2822_ractor
assert_ractor(<<~RUBY, require: 'time')
diff --git a/test/test_timeout.rb b/test/test_timeout.rb
index 76de38949d..e900b10cd7 100644
--- a/test/test_timeout.rb
+++ b/test/test_timeout.rb
@@ -4,12 +4,33 @@ require 'timeout'
class TestTimeout < Test::Unit::TestCase
+ def test_work_is_done_in_same_thread_as_caller
+ assert_equal Thread.current, Timeout.timeout(10){ Thread.current }
+ end
+
+ def test_work_is_done_in_same_fiber_as_caller
+ require 'fiber' # needed for ruby 3.0 and lower
+ assert_equal Fiber.current, Timeout.timeout(10){ Fiber.current }
+ end
+
def test_non_timing_out_code_is_successful
assert_nothing_raised do
assert_equal :ok, Timeout.timeout(1){ :ok }
end
end
+ def test_allows_zero_seconds
+ assert_nothing_raised do
+ assert_equal :ok, Timeout.timeout(0){:ok}
+ end
+ end
+
+ def test_allows_nil_seconds
+ assert_nothing_raised do
+ assert_equal :ok, Timeout.timeout(nil){:ok}
+ end
+ end
+
def test_included
c = Class.new do
include Timeout
@@ -41,25 +62,87 @@ class TestTimeout < Test::Unit::TestCase
end
end
+ def test_nested_timeout
+ a = nil
+ assert_raise(Timeout::Error) do
+ Timeout.timeout(0.1) {
+ Timeout.timeout(1) {
+ nil while true
+ }
+ a = 1
+ }
+ end
+ assert_nil a
+ end
+
+ class MyNewErrorOuter < StandardError; end
+ class MyNewErrorInner < StandardError; end
+
+ # DOES NOT fail with
+ # - raise new(message) if exc.equal?(e)
+ # + raise new(message) if exc.class == e.class
+ def test_nested_timeout_error_identity
+ begin
+ Timeout.timeout(0.1, MyNewErrorOuter) {
+ Timeout.timeout(1, MyNewErrorInner) {
+ nil while true
+ }
+ }
+ rescue => e
+ assert e.class == MyNewErrorOuter
+ end
+ end
+
+ # DOES fail with
+ # - raise new(message) if exc.equal?(e)
+ # + raise new(message) if exc.class == e.class
+ def test_nested_timeout_which_error_bubbles_up
+ raised_exception = nil
+ begin
+ Timeout.timeout(0.1) {
+ Timeout.timeout(1) {
+ raise Timeout::ExitException.new("inner message")
+ }
+ }
+ rescue Exception => e
+ raised_exception = e
+ end
+
+ assert_equal 'inner message', raised_exception.message
+ end
+
def test_cannot_convert_into_time_interval
bug3168 = '[ruby-dev:41010]'
def (n = Object.new).zero?; false; end
assert_raise(TypeError, bug3168) {Timeout.timeout(n) { sleep 0.1 }}
end
- def test_skip_rescue
- bug8730 = '[Bug #8730]'
+ def test_skip_rescue_standarderror
e = nil
- assert_raise_with_message(Timeout::Error, /execution expired/, bug8730) do
+ assert_raise_with_message(Timeout::Error, /execution expired/) do
Timeout.timeout 0.01 do
begin
sleep 3
- rescue Exception => e
+ rescue => e
flunk "should not see any exception but saw #{e.inspect}"
end
end
end
- assert_nil(e, bug8730)
+ end
+
+ def test_raises_exception_internally
+ e = nil
+ assert_raise_with_message(Timeout::Error, /execution expired/) do
+ Timeout.timeout 0.01 do
+ begin
+ sleep 3
+ rescue Exception => exc
+ e = exc
+ raise
+ end
+ end
+ end
+ assert_equal Timeout::ExitException, e.class
end
def test_rescue_exit
@@ -127,11 +210,11 @@ class TestTimeout < Test::Unit::TestCase
bug11344 = '[ruby-dev:49179] [Bug #11344]'
ok = false
assert_raise(Timeout::Error) {
- Thread.handle_interrupt(Timeout::Error => :never) {
+ Thread.handle_interrupt(Timeout::ExitException => :never) {
Timeout.timeout(0.01) {
sleep 0.2
ok = true
- Thread.handle_interrupt(Timeout::Error => :on_blocking) {
+ Thread.handle_interrupt(Timeout::ExitException => :on_blocking) {
sleep 0.2
}
}
@@ -159,4 +242,30 @@ class TestTimeout < Test::Unit::TestCase
assert_equal 'timeout', r.read
r.close
end
+
+ def test_threadgroup
+ assert_separately(%w[-rtimeout], <<-'end;')
+ tg = ThreadGroup.new
+ thr = Thread.new do
+ tg.add(Thread.current)
+ Timeout.timeout(10){}
+ end
+ thr.join
+ assert_equal [].to_s, tg.list.to_s
+ end;
+ end
+
+ # https://github.com/ruby/timeout/issues/24
+ def test_handling_enclosed_threadgroup
+ assert_separately(%w[-rtimeout], <<-'end;')
+ Thread.new {
+ t = Thread.current
+ group = ThreadGroup.new
+ group.add(t)
+ group.enclose
+
+ assert_equal 42, Timeout.timeout(1) { 42 }
+ }.join
+ end;
+ end
end
diff --git a/test/test_tmpdir.rb b/test/test_tmpdir.rb
index 0be2176bd9..054ca15d7a 100644
--- a/test/test_tmpdir.rb
+++ b/test/test_tmpdir.rb
@@ -23,14 +23,14 @@ class TestTmpdir < Test::Unit::TestCase
ENV[e] = tmpdirx
assert_not_equal(tmpdirx, assert_warn('') {Dir.tmpdir})
File.write(tmpdirx, "")
- assert_not_equal(tmpdirx, assert_warn(/not a directory/) {Dir.tmpdir})
+ assert_not_equal(tmpdirx, assert_warn(/\A#{e} is not a directory/) {Dir.tmpdir})
File.unlink(tmpdirx)
ENV[e] = tmpdir
assert_equal(tmpdir, Dir.tmpdir)
File.chmod(0555, tmpdir)
- assert_not_equal(tmpdir, assert_warn(/not writable/) {Dir.tmpdir})
+ assert_not_equal(tmpdir, assert_warn(/\A#{e} is not writable/) {Dir.tmpdir})
File.chmod(0777, tmpdir)
- assert_not_equal(tmpdir, assert_warn(/world-writable/) {Dir.tmpdir})
+ assert_not_equal(tmpdir, assert_warn(/\A#{e} is world-writable/) {Dir.tmpdir})
newdir = Dir.mktmpdir("d", tmpdir) do |dir|
assert_file.directory? dir
assert_equal(tmpdir, File.dirname(dir))
@@ -47,6 +47,18 @@ class TestTmpdir < Test::Unit::TestCase
end
end
+ def test_tmpdir_not_empty_parent
+ Dir.mktmpdir do |tmpdir|
+ envs = %w[TMPDIR TMP TEMP]
+ oldenv = envs.each_with_object({}) {|v, h| h[v] = ENV.delete(v)}
+ ENV[envs[0]] = ""
+ ENV[envs[1]] = tmpdir
+ assert_equal(tmpdir, Dir.tmpdir)
+ ensure
+ ENV.update(oldenv)
+ end
+ end
+
def test_no_homedir
bug7547 = '[ruby-core:50793]'
home, ENV["HOME"] = ENV["HOME"], nil
@@ -103,4 +115,20 @@ class TestTmpdir < Test::Unit::TestCase
end
end
end
+
+ def test_ractor
+ assert_ractor(<<~'end;', require: "tmpdir")
+ r = Ractor.new do
+ Dir.mktmpdir() do |d|
+ Ractor.yield d
+ Ractor.receive
+ end
+ end
+ dir = r.take
+ assert_file.directory? dir
+ r.send true
+ r.take
+ assert_file.not_exist? dir
+ end;
+ end
end
diff --git a/test/test_trick.rb b/test/test_trick.rb
index e37bda2efe..c5c19d079e 100644
--- a/test/test_trick.rb
+++ b/test/test_trick.rb
@@ -1,6 +1,9 @@
+# frozen_string_literal: false
+
require "test/unit"
require "ripper"
require "envutil"
+require "stringio"
# This is a test suite for TRICK entries, joke Ruby program contest.
# The programs are very unusual, and not practical.
@@ -11,24 +14,24 @@ class TestTRICK2013 < Test::Unit::TestCase
def test_kinaba
src = File.join(__dir__, "../sample/trick2013/kinaba/entry.rb")
expected = [*" ".."~"].join("") # all ASCII printables
- assert_in_out_err(["-W0", src], "", [expected])
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src], "", [expected])
assert_equal(expected, File.read(src).chomp.chars.sort.join)
end
def test_mame
src = File.join(__dir__, "../sample/trick2013/mame/entry.rb")
ignore_dsp = "def open(_file, _mode); s = ''; def s.flush; self;end; yield s; end;"
- assert_in_out_err(["-W0"], ignore_dsp + File.read(src), File.read(src).lines(chomp: true), timeout: 60)
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal"], ignore_dsp + File.read(src), File.read(src).lines(chomp: true), timeout: 60)
end
def test_shinh
src = File.join(__dir__, "../sample/trick2013/shinh/entry.rb")
- assert_in_out_err(["-W0", src], "", [])
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src], "", [])
end
def test_yhara
src = File.join(__dir__, "../sample/trick2013/yhara/entry.rb")
- assert_in_out_err(["-W0", src], "", ["JUST ANOTHER RUBY HACKER"])
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src], "", ["JUST ANOTHER RUBY HACKER"])
end
end
@@ -44,7 +47,7 @@ class TestTRICK2015 < Test::Unit::TestCase
end
pi = "3#{ a - b }"
- assert_in_out_err(["-W0", src], "", [pi], timeout: 60)
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src], "", [pi], timeout: 60)
assert_equal(pi[0, 242], Ripper.tokenize(File.read(src)).grep(/\S/).map{|t|t.size%10}.join)
end
@@ -59,7 +62,7 @@ class TestTRICK2015 < Test::Unit::TestCase
s << n.to_s
end
- assert_in_out_err(["-W0", src, "27"], "", s)
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src, "27"], "", s)
end
def test_monae
@@ -77,13 +80,13 @@ class TestTRICK2015 < Test::Unit::TestCase
end
expected = /\A#{ expected.map {|s| "#{ Regexp.quote(s) }\s*\n" }.join }\z/
- assert_in_out_err(["-W0", src], "", expected)
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src], "", expected)
end
def test_eregon
src = File.join(__dir__, "../sample/trick2015/eregon/entry.rb")
- assert_in_out_err(["-W0", src], "", <<END.lines(chomp: true))
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src], "", <<END.lines(chomp: true))
1 9 4 2 3 8 7 6 5
3 7 2 6 5 1 4 8 9
8 5 6 7 4 9 2 3 1
@@ -122,7 +125,7 @@ p cnf 3 5
1 3 0
END
- assert_in_out_err(["-W0", src], inp, ["s SATISFIABLE", "v 1 2 -3"])
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src], inp, ["s SATISFIABLE", "v 1 2 -3"])
end
end
@@ -130,17 +133,17 @@ class TestTRICK2018 < Test::Unit::TestCase
def test_01_kinaba
src = File.join(__dir__, "../sample/trick2018/01-kinaba/entry.rb")
- assert_in_out_err(["-W0", src], "", [])
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", src], "", [])
end
def test_02_mame
src = File.join(__dir__, "../sample/trick2018/02-mame/entry.rb")
ignore_sleep = "def sleep(_); end;"
- assert_in_out_err(["-W0"], ignore_sleep + File.read(src)) do |stdout, _stderr, _status|
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal"], ignore_sleep + File.read(src)) do |stdout, _stderr, _status|
code = stdout.join("\n") + "\n"
expected = code.lines(chomp: true)
- assert_in_out_err(["-W0"], ignore_sleep + code, expected)
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal"], ignore_sleep + code, expected)
end
end
@@ -148,7 +151,7 @@ class TestTRICK2018 < Test::Unit::TestCase
src = File.join(__dir__, "../sample/trick2018/03-tompng/entry.rb")
# only syntax check because it requires chunky_png
- assert_in_out_err(["-W0", "-c", src], "", ["Syntax OK"])
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", "-c", src], "", ["Syntax OK"])
end
def test_04_colin
@@ -171,7 +174,7 @@ class TestTRICK2018 < Test::Unit::TestCase
end
end
END
- assert_in_out_err(["-W0"], code, <<END.lines(chomp: true), encoding: "UTF-8")
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal"], code, <<END.lines(chomp: true), encoding: "UTF-8")
Math
Addition
One plus one equals two.
@@ -186,6 +189,87 @@ END
src = File.join(__dir__, "../sample/trick2018/05-tompng/entry.rb")
# only syntax check because it generates 3D model data
- assert_in_out_err(["-W0", "-c", src], "", ["Syntax OK"])
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", "-c", src], "", ["Syntax OK"])
+ end
+end
+
+class TestTRICK2022 < Test::Unit::TestCase
+ def test_01_tompng
+ src = File.join(__dir__, "../sample/trick2022/01-tompng/entry.rb")
+
+ # only syntax check because it requires matrix
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", "-c", src], "", ["Syntax OK"])
+ end
+
+ def test_02_tompng
+ src = File.join(__dir__, "../sample/trick2022/02-tompng/entry.rb")
+
+ # only syntax check because it works as a web server
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", "-c", src], "", ["Syntax OK"])
+ end
+
+ def test_03_mame
+ src = File.join(__dir__, "../sample/trick2022/03-mame/entry.rb")
+
+ # TODO
+ assert_in_out_err(["-W0", "--disable-frozen-string-literal", "-c", src], "", ["Syntax OK"])
+ end
+end
+
+class TestRubyKaigi2023🥢 < Test::Unit::TestCase
+ CHOPSTICKS = [<<~'0', <<~'1'] # by mame
+ BEGIN{q=:Ruby};p||=:Enjoy;END{puts p,q||2023}
+ 0
+ q=print(q||"/:|}\n")||p&&:@Matsumoto;p=:Kaigi
+ 1
+
+ def test_chopsticks_0
+ assert_in_out_err(%w[-W0], CHOPSTICKS[0], %w[Enjoy Ruby])
+ end
+
+ def test_chopsticks_1
+ assert_in_out_err(%w[-W0], CHOPSTICKS[1], %w[/:|}])
+ end
+
+ def test_chopsticks_0_1
+ assert_in_out_err(%w[-W0], "#{CHOPSTICKS[0]}\n#{CHOPSTICKS[1]}", %w[RubyKaigi @Matsumoto])
+ end
+
+ def test_chopsticks_1_0
+ assert_in_out_err(%w[-W0], "#{CHOPSTICKS[1]}\n#{CHOPSTICKS[0]}", %w[RubyKaigi 2023])
+ end
+end
+
+# https://github.com/mame/all-ruby-quine
+class TestAllRubyQuine < Test::Unit::TestCase
+ def test_all_ruby_quine
+ stdout_bak = $stdout
+ $stdout = StringIO.new
+ verbose_bak = $VERBOSE
+ $VERBOSE = nil
+ src = File.read(File.join(__dir__, "../sample/all-ruby-quine.rb"))
+
+ eval(src)
+
+ out = $stdout.string.lines(chomp: true)
+ $stdout = stdout_bak
+
+ # cheat OCR
+ font = {
+ "-" => 0x7ffffffffffe03fffffffffff, "." => 0x7fffffffffffffffffffc7f8f, "_" => 0x7fffffffffffffffffffff800,
+ "0" => 0x6030e03e07c0f81f03e038603, "1" => 0x70fc1f23fc7f8ff1fe3fc7c01, "2" => 0x4011f1fe3fc7e1f0f87c3f800,
+ "3" => 0x4031e3fe3f8e03fe3fe078c03, "4" => 0x783e0788e318e31c6003f1fe3, "5" => 0x0001fe3fc7f801fe1fe078401,
+ "6" => 0x78083e3fc7f8011e03e038401, "7" => 0x000fe1fc3f0fc3f0fc3f0fc3f, "8" => 0x4011f03e238e038e23e07c401,
+ "9" => 0x4010e03e03c400ff1fe078401, "a" => 0x7fffff00c787f88003e078408, "b" => 0x0ff1fe3fc408701f03e078001,
+ "c" => 0x7fffff8063c0ff1fe3fe3c601, "d" => 0x7f8ff1fe3004781f03e038408,
+ }.invert
+ out = (0...out.first.size / 15).map do |i|
+ font[(3..11).map {|j| out[j][i * 15 + 5, 11] }.join.gsub(/\S/, "#").tr("# ", "10").to_i(2)]
+ end.join
+
+ assert_equal(RUBY_VERSION, out)
+ ensure
+ $stdout = stdout_bak
+ $VERBOSE = verbose_bak
end
end
diff --git a/test/test_unicode_normalize.rb b/test/test_unicode_normalize.rb
index 034d71d808..8789ed92d2 100644
--- a/test/test_unicode_normalize.rb
+++ b/test/test_unicode_normalize.rb
@@ -24,7 +24,7 @@ class TestUnicodeNormalize
NormTest = Struct.new :source, :NFC, :NFD, :NFKC, :NFKD, :line
def self.read_tests
- lines = IO.readlines(expand_filename('NormalizationTest'), encoding: 'utf-8')
+ lines = File.readlines(expand_filename('NormalizationTest'), encoding: 'utf-8')
firstline = lines.shift
define_method "test_0_normalizationtest_firstline" do
assert_include(firstline, "NormalizationTest-#{UNICODE_VERSION}.txt")
diff --git a/test/uri/test_common.rb b/test/uri/test_common.rb
index 038f483a83..1df19e6968 100644
--- a/test/uri/test_common.rb
+++ b/test/uri/test_common.rb
@@ -3,10 +3,7 @@ require 'test/unit'
require 'envutil'
require 'uri'
-module URI
-
-
-class TestCommon < Test::Unit::TestCase
+class URI::TestCommon < Test::Unit::TestCase
def setup
end
@@ -112,6 +109,17 @@ class TestCommon < Test::Unit::TestCase
assert_raise(NoMethodError) { Object.new.URI("http://www.ruby-lang.org/") }
end
+ def test_parse_timeout
+ pre = ->(n) {
+ 'https://example.com/dir/' + 'a' * (n * 100) + '/##.jpg'
+ }
+ assert_linear_performance((1..3).map {|i| 10**i}, rehearsal: 1000, pre: pre) do |uri|
+ assert_raise(URI::InvalidURIError) do
+ URI.parse(uri)
+ end
+ end
+ end
+
def test_encode_www_form_component
assert_equal("%00+%21%22%23%24%25%26%27%28%29*%2B%2C-.%2F09%3A%3B%3C%3D%3E%3F%40" \
"AZ%5B%5C%5D%5E_%60az%7B%7C%7D%7E",
@@ -281,6 +289,3 @@ class TestCommon < Test::Unit::TestCase
private
def s(str) str.force_encoding(Encoding::Windows_31J); end
end
-
-
-end
diff --git a/test/uri/test_ftp.rb b/test/uri/test_ftp.rb
index 0eec984db8..f45bb0667c 100644
--- a/test/uri/test_ftp.rb
+++ b/test/uri/test_ftp.rb
@@ -2,10 +2,7 @@
require 'test/unit'
require 'uri/ftp'
-module URI
-
-
-class TestFTP < Test::Unit::TestCase
+class URI::TestFTP < Test::Unit::TestCase
def setup
end
@@ -29,7 +26,7 @@ class TestFTP < Test::Unit::TestCase
end
def test_parse_invalid
- assert_raise(InvalidURIError){URI.parse('ftp:example')}
+ assert_raise(URI::InvalidURIError) {URI.parse('ftp:example')}
end
def test_paths
@@ -62,6 +59,3 @@ class TestFTP < Test::Unit::TestCase
end
end
end
-
-
-end
diff --git a/test/uri/test_generic.rb b/test/uri/test_generic.rb
index fdb405e396..8209363b82 100644
--- a/test/uri/test_generic.rb
+++ b/test/uri/test_generic.rb
@@ -24,7 +24,19 @@ class URI::TestGeneric < Test::Unit::TestCase
assert_equal "file:///foo", URI("file:///foo").to_s
assert_equal "postgres:///foo", URI("postgres:///foo").to_s
- assert_equal "http:/foo", URI("http:///foo").to_s
+ assert_equal "http:///foo", URI("http:///foo").to_s
+ assert_equal "http:/foo", URI("http:/foo").to_s
+
+ uri = URI('rel_path')
+ assert_equal "rel_path", uri.to_s
+ uri.scheme = 'http'
+ assert_equal "http:rel_path", uri.to_s
+ uri.host = 'h'
+ assert_equal "http://h/rel_path", uri.to_s
+ uri.port = 8080
+ assert_equal "http://h:8080/rel_path", uri.to_s
+ uri.host = nil
+ assert_equal "http::8080/rel_path", uri.to_s
end
def test_parse
@@ -157,6 +169,12 @@ class URI::TestGeneric < Test::Unit::TestCase
assert_equal(nil, url.user)
assert_equal(nil, url.password)
assert_equal(nil, url.userinfo)
+
+ # sec-156615
+ url = URI.parse('http:////example.com')
+ # must be empty string to identify as path-abempty, not path-absolute
+ assert_equal('', url.host)
+ assert_equal('http:////example.com', url.to_s)
end
def test_parse_scheme_with_symbols
@@ -970,6 +988,10 @@ class URI::TestGeneric < Test::Unit::TestCase
end
end
+ def test_split
+ assert_equal [nil, nil, nil, nil, nil, "", nil, nil, nil], URI.split("//")
+ end
+
class CaseInsensitiveEnv
def initialize(h={})
@h = {}
diff --git a/test/uri/test_http.rb b/test/uri/test_http.rb
index 748e90a322..e937b1a26b 100644
--- a/test/uri/test_http.rb
+++ b/test/uri/test_http.rb
@@ -3,10 +3,7 @@ require 'test/unit'
require 'uri/http'
require 'uri/https'
-module URI
-
-
-class TestHTTP < Test::Unit::TestCase
+class URI::TestHTTP < Test::Unit::TestCase
def setup
end
@@ -82,6 +79,3 @@ class TestHTTP < Test::Unit::TestCase
assert_equal('https://a.b.c', URI.parse('https://a.b.c/').origin)
end
end
-
-
-end
diff --git a/test/uri/test_ldap.rb b/test/uri/test_ldap.rb
index 64845e487a..9c4506a357 100644
--- a/test/uri/test_ldap.rb
+++ b/test/uri/test_ldap.rb
@@ -2,10 +2,7 @@
require 'test/unit'
require 'uri/ldap'
-module URI
-
-
-class TestLDAP < Test::Unit::TestCase
+class URI::TestLDAP < Test::Unit::TestCase
def setup
end
@@ -39,7 +36,7 @@ class TestLDAP < Test::Unit::TestCase
# from RFC2255, section 6.
{
'ldap:///o=University%20of%20Michigan,c=US' =>
- ['ldap', nil, URI::LDAP::DEFAULT_PORT,
+ ['ldap', '', URI::LDAP::DEFAULT_PORT,
'o=University%20of%20Michigan,c=US',
nil, nil, nil, nil],
@@ -74,12 +71,12 @@ class TestLDAP < Test::Unit::TestCase
nil, '(int=%5c00%5c00%5c00%5c04)', nil, nil],
'ldap:///??sub??bindname=cn=Manager%2co=Foo' =>
- ['ldap', nil, URI::LDAP::DEFAULT_PORT,
+ ['ldap', '', URI::LDAP::DEFAULT_PORT,
'',
nil, 'sub', nil, 'bindname=cn=Manager%2co=Foo'],
'ldap:///??sub??!bindname=cn=Manager%2co=Foo' =>
- ['ldap', nil, URI::LDAP::DEFAULT_PORT,
+ ['ldap', '', URI::LDAP::DEFAULT_PORT,
'',
nil, 'sub', nil, '!bindname=cn=Manager%2co=Foo'],
}.each do |url2, ary|
@@ -100,6 +97,3 @@ class TestLDAP < Test::Unit::TestCase
assert_raise(URI::InvalidURIError) {URI.parse("ldap:https://example.com")}
end
end
-
-
-end
diff --git a/test/uri/test_parser.rb b/test/uri/test_parser.rb
index f8e9299d09..75c02fe65b 100644
--- a/test/uri/test_parser.rb
+++ b/test/uri/test_parser.rb
@@ -72,4 +72,41 @@ class URI::TestParser < Test::Unit::TestCase
assert_equal("\u3042", p1.unescape('%e3%81%82'.force_encoding(Encoding::US_ASCII)))
assert_equal("\xe3\x83\x90\xe3\x83\x90", p1.unescape("\xe3\x83\x90%e3%83%90"))
end
+
+ def test_split
+ assert_equal(["http", nil, "example.com", nil, nil, "", nil, nil, nil], URI.split("http://example.com"))
+ assert_equal(["http", nil, "[0::0]", nil, nil, "", nil, nil, nil], URI.split("http://[0::0]"))
+ assert_equal([nil, nil, "example.com", nil, nil, "", nil, nil, nil], URI.split("//example.com"))
+ assert_equal([nil, nil, "[0::0]", nil, nil, "", nil, nil, nil], URI.split("//[0::0]"))
+
+ assert_equal(["a", nil, nil, nil, nil, "", nil, nil, nil], URI.split("a:"))
+ assert_raise(URI::InvalidURIError) do
+ URI.parse("::")
+ end
+ assert_raise(URI::InvalidURIError) do
+ URI.parse("foo@example:foo")
+ end
+ end
+
+ def test_rfc2822_parse_relative_uri
+ pre = ->(length) {
+ " " * length + "\0"
+ }
+ parser = URI::RFC2396_Parser.new
+ assert_linear_performance((1..5).map {|i| 10**i}, pre: pre) do |uri|
+ assert_raise(URI::InvalidURIError) do
+ parser.split(uri)
+ end
+ end
+ end
+
+ def test_rfc3986_port_check
+ pre = ->(length) {"\t" * length + "a"}
+ uri = URI.parse("http://my.example.com")
+ assert_linear_performance((1..5).map {|i| 10**i}, pre: pre) do |port|
+ assert_raise(URI::InvalidComponentError) do
+ uri.port = port
+ end
+ end
+ end
end
diff --git a/test/uri/test_ws.rb b/test/uri/test_ws.rb
index 17acb0d9f2..f3918f617c 100644
--- a/test/uri/test_ws.rb
+++ b/test/uri/test_ws.rb
@@ -3,10 +3,7 @@ require 'test/unit'
require 'uri/http'
require 'uri/ws'
-module URI
-
-
-class TestWS < Test::Unit::TestCase
+class URI::TestWS < Test::Unit::TestCase
def setup
end
@@ -66,6 +63,3 @@ class TestWS < Test::Unit::TestCase
end
end
end
-
-
-end
diff --git a/test/uri/test_wss.rb b/test/uri/test_wss.rb
index 2e8b9bc4b7..13a2583059 100644
--- a/test/uri/test_wss.rb
+++ b/test/uri/test_wss.rb
@@ -3,10 +3,7 @@ require 'test/unit'
require 'uri/https'
require 'uri/wss'
-module URI
-
-
-class TestWSS < Test::Unit::TestCase
+class URI::TestWSS < Test::Unit::TestCase
def setup
end
@@ -66,6 +63,3 @@ class TestWSS < Test::Unit::TestCase
end
end
end
-
-
-end
diff --git a/test/win32ole/available_ole.rb b/test/win32ole/available_ole.rb
index ebc9baae66..af397e00b5 100644
--- a/test/win32ole/available_ole.rb
+++ b/test/win32ole/available_ole.rb
@@ -8,7 +8,7 @@ if defined?(WIN32OLE)
module_function
def sysmon_available?
- WIN32OLE_TYPE.new('System Monitor Control', 'SystemMonitor')
+ WIN32OLE::Type.new('System Monitor Control', 'SystemMonitor')
true
rescue
false
@@ -22,18 +22,18 @@ if defined?(WIN32OLE)
end
def msxml_available?
- !WIN32OLE_TYPELIB.typelibs.find { |t| t.name.start_with?('Microsoft XML') }.nil?
+ !WIN32OLE::TypeLib.typelibs.find { |t| t.name.start_with?('Microsoft XML') }.nil?
end
def event_param
method = if msxml_available?
- typelib = WIN32OLE_TYPELIB.typelibs.find { |t| t.name.start_with?('Microsoft XML') }
- ole_type = WIN32OLE_TYPE.new(typelib.name, 'IVBSAXContentHandler')
- WIN32OLE_METHOD.new(ole_type, 'startElement')
+ typelib = WIN32OLE::TypeLib.typelibs.find { |t| t.name.start_with?('Microsoft XML') }
+ ole_type = WIN32OLE::Type.new(typelib.name, 'IVBSAXContentHandler')
+ WIN32OLE::Method.new(ole_type, 'startElement')
elsif ado_available?
typelib = WIN32OLE.new('ADODB.Connection').ole_typelib
- ole_type = WIN32OLE_TYPE.new(typelib.name, 'Connection')
- WIN32OLE_METHOD.new(ole_type, 'WillConnect')
+ ole_type = WIN32OLE::Type.new(typelib.name, 'Connection')
+ WIN32OLE::Method.new(ole_type, 'WillConnect')
end
method && method.params[0]
end
diff --git a/test/win32ole/err_in_callback.rb b/test/win32ole/err_in_callback.rb
index aa6c9c7e3a..baecf780b6 100644
--- a/test/win32ole/err_in_callback.rb
+++ b/test/win32ole/err_in_callback.rb
@@ -2,9 +2,9 @@
require 'win32ole'
db = WIN32OLE.new('ADODB.Connection')
db.connectionString = "Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir=.;"
-ev = WIN32OLE_EVENT.new(db)
+ev = WIN32OLE::Event.new(db)
ev.on_event('WillConnect') {|*args|
foo
}
db.open
-WIN32OLE_EVENT.message_loop
+WIN32OLE::Event.message_loop
diff --git a/test/win32ole/test_err_in_callback.rb b/test/win32ole/test_err_in_callback.rb
index 9ffaf9125f..bea5781bc9 100644
--- a/test/win32ole/test_err_in_callback.rb
+++ b/test/win32ole/test_err_in_callback.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
#
# test Win32OLE avoids cfp consistency error when the exception raised
-# in WIN32OLE_EVENT handler block. [ruby-dev:35450]
+# in WIN32OLE::Event handler block. [ruby-dev:35450]
#
begin
@@ -31,7 +31,7 @@ if defined?(WIN32OLE)
def available_adodb?
begin
WIN32OLE.new('ADODB.Connection')
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
return false
end
return true
diff --git a/test/win32ole/test_folderitem2_invokeverb.rb b/test/win32ole/test_folderitem2_invokeverb.rb
index e11503ca2a..a1c2b2f472 100644
--- a/test/win32ole/test_folderitem2_invokeverb.rb
+++ b/test/win32ole/test_folderitem2_invokeverb.rb
@@ -44,7 +44,7 @@ if defined?(WIN32OLE)
assert_equal(0, links.size)
# Now create shortcut to @dummy_path
- arg = WIN32OLE_VARIANT.new("Link")
+ arg = WIN32OLE::Variant.new("Link")
@fi2.InvokeVerb(arg)
# Now search shortcut to @dummy_path
diff --git a/test/win32ole/test_nil2vtempty.rb b/test/win32ole/test_nil2vtempty.rb
index 49757d61b3..bd86403676 100644
--- a/test/win32ole/test_nil2vtempty.rb
+++ b/test/win32ole/test_nil2vtempty.rb
@@ -28,7 +28,7 @@ if defined?(WIN32OLE)
assert(rs)
assert_equal("_Recordset", rs.ole_type.name)
- rs = con.openSchema(4, [WIN32OLE_VARIANT::Empty, WIN32OLE_VARIANT::Empty, "DUMMY", "TABLE"])
+ rs = con.openSchema(4, [WIN32OLE::Variant::Empty, WIN32OLE::Variant::Empty, "DUMMY", "TABLE"])
assert(rs)
assert_equal("_Recordset", rs.ole_type.name)
end
diff --git a/test/win32ole/test_propertyputref.rb b/test/win32ole/test_propertyputref.rb
index 93edb50835..83418140c2 100644
--- a/test/win32ole/test_propertyputref.rb
+++ b/test/win32ole/test_propertyputref.rb
@@ -11,7 +11,7 @@ if defined?(WIN32OLE)
begin
@sapi = WIN32OLE.new('SAPI.SpVoice')
@sv = @sapi.voice
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
@sapi = nil
end
end
diff --git a/test/win32ole/test_thread.rb b/test/win32ole/test_thread.rb
index cb34693064..b30b2349c5 100644
--- a/test/win32ole/test_thread.rb
+++ b/test/win32ole/test_thread.rb
@@ -14,7 +14,7 @@ if defined?(WIN32OLE)
t = Thread.__send__(meth) {
WIN32OLE.new('Scripting.Dictionary')
}
- assert_nothing_raised(WIN32OLERuntimeError, "[Bug #2618] Thread.#{meth}") {
+ assert_nothing_raised(WIN32OLE::RuntimeError, "[Bug #2618] Thread.#{meth}") {
t.join
}
end
diff --git a/test/win32ole/test_win32ole.rb b/test/win32ole/test_win32ole.rb
index e5f9d35e24..e6347e89b4 100644
--- a/test/win32ole/test_win32ole.rb
+++ b/test/win32ole/test_win32ole.rb
@@ -34,23 +34,23 @@ if defined?(WIN32OLE)
assert_equal(1, @dict2.item("one"))
end
def test_non_exist_property
- assert_raise(WIN32OLERuntimeError) {
+ assert_raise(WIN32OLE::RuntimeError) {
@dict1.unknown_property = 1
}
end
def test_raise_message
- exc = assert_raise(WIN32OLERuntimeError) {
+ exc = assert_raise(WIN32OLE::RuntimeError) {
@dict1.add
}
assert_match(/^\(in OLE method `add': \)/, exc.message) #`
- exc = assert_raise(WIN32OLERuntimeError) {
+ exc = assert_raise(WIN32OLE::RuntimeError) {
@dict1._invoke(1, [], [])
}
assert_match(/^\(in OLE method `<dispatch id:1>': \)/, exc.message) #`
- exc = assert_raise(WIN32OLERuntimeError) {
+ exc = assert_raise(WIN32OLE::RuntimeError) {
@dict1.compareMode = -1
}
assert_match(/^\(in setting property `compareMode': \)/, exc.message) #`
@@ -167,6 +167,11 @@ if defined?(WIN32OLE)
assert_instance_of(WIN32OLE, @dict2)
end
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::RuntimeError, ::WIN32OLERuntimeError)
+ assert_equal(WIN32OLE::QueryInterfaceError, ::WIN32OLEQueryInterfaceError)
+ end
+
def test_s_new_exc
assert_raise(TypeError) {
WIN32OLE.new(1)
@@ -184,7 +189,7 @@ if defined?(WIN32OLE)
def test_s_new_from_clsid
shell = WIN32OLE.new("{13709620-C279-11CE-A49E-444553540000}")
assert_instance_of(WIN32OLE, shell)
- exc = assert_raise(WIN32OLERuntimeError) {
+ exc = assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE.new("{000}")
}
assert_match(/unknown OLE server: `\{000\}'/, exc.message) #`
@@ -335,17 +340,19 @@ if defined?(WIN32OLE)
end
def test_s_codepage_changed
+ omit if RUBY_PLATFORM.match("mswin")
+
cp = WIN32OLE.codepage
fso = WIN32OLE.new("Scripting.FileSystemObject")
fname = fso.getTempName
begin
- obj = WIN32OLE_VARIANT.new([0x3042].pack("U*").force_encoding("UTF-8"))
+ obj = WIN32OLE::Variant.new([0x3042].pack("U*").force_encoding("UTF-8"))
WIN32OLE.codepage = WIN32OLE::CP_UTF8
assert_equal("\xE3\x81\x82".force_encoding("CP65001"), obj.value)
begin
WIN32OLE.codepage = 932 # Windows-31J
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
end
if (WIN32OLE.codepage == 932)
assert_equal("\x82\xA0".force_encoding("CP932"), obj.value)
@@ -353,7 +360,7 @@ if defined?(WIN32OLE)
begin
WIN32OLE.codepage = 20932 # MS EUC-JP
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
end
if (WIN32OLE.codepage == 20932)
assert_equal("\xA4\xA2".force_encoding("CP20932"), obj.value)
@@ -376,7 +383,7 @@ if defined?(WIN32OLE)
# This test fail if codepage 20932 (euc) is not installed.
begin
WIN32OLE.codepage = 20932
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
end
if (WIN32OLE.codepage == 20932)
WIN32OLE.codepage = cp
@@ -403,7 +410,7 @@ if defined?(WIN32OLE)
def test_cp51932
cp = WIN32OLE.codepage
begin
- obj = WIN32OLE_VARIANT.new([0x3042].pack("U*").force_encoding("UTF-8"))
+ obj = WIN32OLE::Variant.new([0x3042].pack("U*").force_encoding("UTF-8"))
begin
WIN32OLE.codepage = 51932
rescue
@@ -424,13 +431,13 @@ if defined?(WIN32OLE)
begin
begin
WIN32OLE.locale = 1041
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_set is skipped(Japanese locale is not installed)")
return
end
assert_equal(1041, WIN32OLE.locale)
WIN32OLE.locale = WIN32OLE::LOCALE_SYSTEM_DEFAULT
- assert_raise(WIN32OLERuntimeError) {
+ assert_raise(WIN32OLE::RuntimeError) {
WIN32OLE.locale = 111
}
assert_equal(WIN32OLE::LOCALE_SYSTEM_DEFAULT, WIN32OLE.locale)
@@ -443,13 +450,13 @@ if defined?(WIN32OLE)
begin
begin
WIN32OLE.locale = 0x0411
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
end
if WIN32OLE.locale == 0x0411
- obj = WIN32OLE_VARIANT.new("\\100,000", WIN32OLE::VARIANT::VT_CY)
+ obj = WIN32OLE::Variant.new("\\100,000", WIN32OLE::VARIANT::VT_CY)
assert_equal("100000", obj.value)
- assert_raise(WIN32OLERuntimeError) {
- obj = WIN32OLE_VARIANT.new("$100.000", WIN32OLE::VARIANT::VT_CY)
+ assert_raise(WIN32OLE::RuntimeError) {
+ obj = WIN32OLE::Variant.new("$100.000", WIN32OLE::VARIANT::VT_CY)
}
else
STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_change is skipped(Japanese locale is not installed)")
@@ -457,10 +464,10 @@ if defined?(WIN32OLE)
begin
WIN32OLE.locale = 1033
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
end
if WIN32OLE.locale == 1033
- obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)
+ obj = WIN32OLE::Variant.new("$100,000", WIN32OLE::VARIANT::VT_CY)
assert_equal("100000", obj.value)
else
STDERR.puts("\n#{__FILE__}:#{__LINE__}:#{self.class.name}.test_s_locale_change is skipped(US English locale is not installed)")
diff --git a/test/win32ole/test_win32ole_event.rb b/test/win32ole/test_win32ole_event.rb
index f02df53be7..d52f8cf9b3 100644
--- a/test/win32ole/test_win32ole_event.rb
+++ b/test/win32ole/test_win32ole_event.rb
@@ -28,17 +28,21 @@ swbemsink_available =
end
end
-if defined?(WIN32OLE_EVENT)
+if defined?(WIN32OLE::Event)
class TestWIN32OLE_EVENT < Test::Unit::TestCase
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::Event, ::WIN32OLE_EVENT)
+ end
+
def test_s_new_exception
assert_raise(TypeError) {
- WIN32OLE_EVENT.new("A")
+ WIN32OLE::Event.new("A")
}
end
def test_s_new_non_exist_event
dict = WIN32OLE.new('Scripting.Dictionary')
assert_raise(RuntimeError) {
- WIN32OLE_EVENT.new(dict)
+ WIN32OLE::Event.new(dict)
}
end
end
@@ -58,7 +62,7 @@ if defined?(WIN32OLE_EVENT)
end
2.times do
- WIN32OLE_EVENT.message_loop
+ WIN32OLE::Event.message_loop
sleep 1
end
@@ -68,7 +72,7 @@ if defined?(WIN32OLE_EVENT)
seconds = EnvUtil.apply_timeout_scale(1)
while tries < 5 && instance_variable_get(watch_ivar) == orig_ivar
$stderr.puts "test_win32ole_event.rb: retrying and sleeping #{seconds}s until #{watch_ivar} is changed from #{orig_ivar.inspect}..."
- WIN32OLE_EVENT.message_loop
+ WIN32OLE::Event.message_loop
sleep(seconds)
tries += 1
seconds *= 2 # sleep at most 31s in total
@@ -86,24 +90,24 @@ if defined?(WIN32OLE_EVENT)
def test_s_new_non_exist_event
assert_raise(RuntimeError) {
- WIN32OLE_EVENT.new(@sws, 'XXXXX')
+ WIN32OLE::Event.new(@sws, 'XXXXX')
}
end
def test_s_new
- obj = WIN32OLE_EVENT.new(@sws, 'ISWbemSinkEvents')
- assert_instance_of(WIN32OLE_EVENT, obj)
- obj = WIN32OLE_EVENT.new(@sws)
- assert_instance_of(WIN32OLE_EVENT, obj)
+ obj = WIN32OLE::Event.new(@sws, 'ISWbemSinkEvents')
+ assert_instance_of(WIN32OLE::Event, obj)
+ obj = WIN32OLE::Event.new(@sws)
+ assert_instance_of(WIN32OLE::Event, obj)
end
def test_s_new_loop
exec_notification_query_async
- ev = WIN32OLE_EVENT.new(@sws)
+ ev = WIN32OLE::Event.new(@sws)
ev.on_event {|*args| default_handler(*args)}
message_loop
10.times do |i|
- WIN32OLE_EVENT.new(@sws)
+ WIN32OLE::Event.new(@sws)
message_loop
GC.start
end
@@ -115,7 +119,7 @@ if defined?(WIN32OLE_EVENT)
def test_on_event
exec_notification_query_async
- ev = WIN32OLE_EVENT.new(@sws, 'ISWbemSinkEvents')
+ ev = WIN32OLE::Event.new(@sws, 'ISWbemSinkEvents')
ev.on_event {|*args| default_handler(*args)}
message_loop(:@event)
assert_match(/OnObjectReady/, @event)
@@ -123,7 +127,7 @@ if defined?(WIN32OLE_EVENT)
def test_on_event_symbol
exec_notification_query_async
- ev = WIN32OLE_EVENT.new(@sws)
+ ev = WIN32OLE::Event.new(@sws)
ev.on_event(:OnObjectReady) {|*args|
handler1
}
@@ -163,7 +167,7 @@ if defined?(WIN32OLE_EVENT)
module ADO
end
def message_loop
- WIN32OLE_EVENT.message_loop
+ WIN32OLE::Event.message_loop
end
def default_handler(event, *args)
@@ -182,7 +186,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_on_event2
- ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev = WIN32OLE::Event.new(@db, 'ConnectionEvents')
ev.on_event('WillConnect') {|*args| handler1}
ev.on_event('WillConnect') {|*args| handler2}
@db.open
@@ -191,7 +195,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_on_event4
- ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev = WIN32OLE::Event.new(@db, 'ConnectionEvents')
ev.on_event{|*args| handler1}
ev.on_event{|*args| handler2}
ev.on_event('WillConnect'){|*args| handler3(*args)}
@@ -202,7 +206,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_on_event5
- ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev = WIN32OLE::Event.new(@db, 'ConnectionEvents')
ev.on_event {|*args| default_handler(*args)}
ev.on_event('WillConnect'){|*args| handler3(*args)}
@db.open
@@ -213,7 +217,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_unadvise
- ev = WIN32OLE_EVENT.new(@db, 'ConnectionEvents')
+ ev = WIN32OLE::Event.new(@db, 'ConnectionEvents')
ev.on_event {|*args| default_handler(*args)}
@db.open
message_loop
@@ -224,16 +228,16 @@ if defined?(WIN32OLE_EVENT)
@db.open
message_loop
assert_equal("", @event);
- assert_raise(WIN32OLERuntimeError) {
+ assert_raise(WIN32OLE::RuntimeError) {
ev.on_event {|*args| default_handler(*args)}
}
end
def test_on_event_with_outargs
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
@db.connectionString = 'XXX' # set illegal connection string
- assert_raise(WIN32OLERuntimeError) {
+ assert_raise(WIN32OLE::RuntimeError) {
@db.open
}
ev.on_event_with_outargs('WillConnect'){|*args|
@@ -245,7 +249,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_on_event_hash_return
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{:return => 1, :ConnectionString => CONNSTR}
}
@@ -255,7 +259,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_on_event_hash_return2
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{:ConnectionString => CONNSTR}
}
@@ -265,7 +269,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_on_event_hash_return3
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{'ConnectionString' => CONNSTR}
}
@@ -275,7 +279,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_on_event_hash_return4
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{'return' => 1, 'ConnectionString' => CONNSTR}
}
@@ -285,7 +289,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_on_event_hash_return5
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){|*args|
{0 => CONNSTR}
}
@@ -295,7 +299,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_off_event
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event{handler1}
ev.off_event
@db.open
@@ -304,7 +308,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_off_event_arg
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){handler1}
ev.off_event('WillConnect')
@db.open
@@ -313,7 +317,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_off_event_arg2
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){handler1}
ev.on_event('ConnectComplete'){handler1}
ev.off_event('WillConnect')
@@ -323,7 +327,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_off_event_sym_arg
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
ev.on_event('WillConnect'){handler1}
ev.off_event(:WillConnect)
@db.open
@@ -382,7 +386,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_handler1
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
h1 = Handler1.new
ev.handler = h1
@db.open
@@ -395,7 +399,7 @@ if defined?(WIN32OLE_EVENT)
end
def test_handler2
- ev = WIN32OLE_EVENT.new(@db)
+ ev = WIN32OLE::Event.new(@db)
h2 = Handler2.new
ev.handler = h2
@db.open
diff --git a/test/win32ole/test_win32ole_method.rb b/test/win32ole/test_win32ole_method.rb
index a0e113e7f0..c84c4027ff 100644
--- a/test/win32ole/test_win32ole_method.rb
+++ b/test/win32ole/test_win32ole_method.rb
@@ -5,42 +5,46 @@ rescue LoadError
end
require "test/unit"
-if defined?(WIN32OLE_METHOD)
+if defined?(WIN32OLE::Method)
class TestWIN32OLE_METHOD < Test::Unit::TestCase
def setup
- ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
- @m_open = WIN32OLE_METHOD.new(ole_type, "open")
- @m_namespace = WIN32OLE_METHOD.new(ole_type, "namespace")
- @m_parent = WIN32OLE_METHOD.new(ole_type, "parent")
- @m_invoke = WIN32OLE_METHOD.new(ole_type, "invoke")
- @m_browse_for_folder = WIN32OLE_METHOD.new(ole_type, "BrowseForFolder")
+ ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Shell")
+ @m_open = WIN32OLE::Method.new(ole_type, "open")
+ @m_namespace = WIN32OLE::Method.new(ole_type, "namespace")
+ @m_parent = WIN32OLE::Method.new(ole_type, "parent")
+ @m_invoke = WIN32OLE::Method.new(ole_type, "invoke")
+ @m_browse_for_folder = WIN32OLE::Method.new(ole_type, "BrowseForFolder")
- ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "File")
- @m_file_name = WIN32OLE_METHOD.new(ole_type, "name")
+ ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "File")
+ @m_file_name = WIN32OLE::Method.new(ole_type, "name")
+ end
+
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::Method, ::WIN32OLE_METHOD)
end
def test_initialize
- ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+ ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Shell")
assert_raise(TypeError) {
- WIN32OLE_METHOD.new(1, 2)
+ WIN32OLE::Method.new(1, 2)
}
assert_raise(ArgumentError) {
- WIN32OLE_METHOD.new("foo")
+ WIN32OLE::Method.new("foo")
}
assert_raise(ArgumentError) {
- WIN32OLE_METHOD.new(ole_type)
+ WIN32OLE::Method.new(ole_type)
}
- assert_raise(WIN32OLERuntimeError) {
- WIN32OLE_METHOD.new(ole_type, "NonExistMethod")
+ assert_raise(WIN32OLE::RuntimeError) {
+ WIN32OLE::Method.new(ole_type, "NonExistMethod")
}
assert_raise(TypeError) {
- WIN32OLE_METHOD.new(ole_type, 1)
+ WIN32OLE::Method.new(ole_type, 1)
}
- method = WIN32OLE_METHOD.new(ole_type, "Open")
- assert_instance_of(WIN32OLE_METHOD, method)
- method = WIN32OLE_METHOD.new(ole_type, "open")
- assert_instance_of(WIN32OLE_METHOD, method)
+ method = WIN32OLE::Method.new(ole_type, "Open")
+ assert_instance_of(WIN32OLE::Method, method)
+ method = WIN32OLE::Method.new(ole_type, "open")
+ assert_instance_of(WIN32OLE::Method, method)
end
def test_name
@@ -119,7 +123,7 @@ if defined?(WIN32OLE_METHOD)
params = @m_browse_for_folder.params
assert_instance_of(Array, params)
assert_equal(4, params.size)
- assert_instance_of(WIN32OLE_PARAM, params[0])
+ assert_instance_of(WIN32OLE::Param, params[0])
end
def test_to_s
@@ -127,7 +131,7 @@ if defined?(WIN32OLE_METHOD)
end
def test_inspect
- assert_equal("#<WIN32OLE_METHOD:NameSpace>", @m_namespace.inspect)
+ assert_equal("#<WIN32OLE::Method:NameSpace>", @m_namespace.inspect)
end
end
diff --git a/test/win32ole/test_win32ole_method_event.rb b/test/win32ole/test_win32ole_method_event.rb
index 7758168872..ab409a1f2d 100644
--- a/test/win32ole/test_win32ole_method_event.rb
+++ b/test/win32ole/test_win32ole_method_event.rb
@@ -5,7 +5,7 @@ end
require 'test/unit'
-if defined?(WIN32OLE_METHOD)
+if defined?(WIN32OLE::Method)
require_relative 'available_ole'
class TestWIN32OLE_METHOD_EVENT < Test::Unit::TestCase
unless AvailableOLE.sysmon_available?
@@ -14,10 +14,10 @@ if defined?(WIN32OLE_METHOD)
end
else
def setup
- ole_type = WIN32OLE_TYPE.new('System Monitor Control', 'SystemMonitor')
- @on_dbl_click = WIN32OLE_METHOD.new(ole_type, 'OnDblClick')
- ole_type = WIN32OLE_TYPE.new('Microsoft Shell Controls And Automation', 'Shell')
- @namespace = WIN32OLE_METHOD.new(ole_type, 'namespace')
+ ole_type = WIN32OLE::Type.new('System Monitor Control', 'SystemMonitor')
+ @on_dbl_click = WIN32OLE::Method.new(ole_type, 'OnDblClick')
+ ole_type = WIN32OLE::Type.new('Microsoft Shell Controls And Automation', 'Shell')
+ @namespace = WIN32OLE::Method.new(ole_type, 'namespace')
end
def test_event?
diff --git a/test/win32ole/test_win32ole_param.rb b/test/win32ole/test_win32ole_param.rb
index 09452d1927..13ca9d0cfb 100644
--- a/test/win32ole/test_win32ole_param.rb
+++ b/test/win32ole/test_win32ole_param.rb
@@ -5,45 +5,49 @@ rescue LoadError
end
require "test/unit"
-if defined?(WIN32OLE_PARAM)
+if defined?(WIN32OLE::Param)
class TestWIN32OLE_PARAM < Test::Unit::TestCase
def setup
- ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellLinkObject")
- m_geticonlocation = WIN32OLE_METHOD.new(ole_type, "GetIconLocation")
+ ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "ShellLinkObject")
+ m_geticonlocation = WIN32OLE::Method.new(ole_type, "GetIconLocation")
@param_pbs = m_geticonlocation.params[0]
- ole_type = WIN32OLE_TYPE.new("Microsoft HTML Object Library", "FontNames")
- m_count = WIN32OLE_METHOD.new(ole_type, "Count")
+ ole_type = WIN32OLE::Type.new("Microsoft HTML Object Library", "FontNames")
+ m_count = WIN32OLE::Method.new(ole_type, "Count")
@param_p = m_count.params[0]
- ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
- m_copyfile = WIN32OLE_METHOD.new(ole_type, "CopyFile")
+ ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "FileSystemObject")
+ m_copyfile = WIN32OLE::Method.new(ole_type, "CopyFile")
@param_source = m_copyfile.params[0]
@param_overwritefiles = m_copyfile.params[2]
- ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "Dictionary")
- m_add = WIN32OLE_METHOD.new(ole_type, "Add")
+ ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "Dictionary")
+ m_add = WIN32OLE::Method.new(ole_type, "Add")
@param_key = m_add.params[0]
end
+ def test_constants_backward_compatibility
+ assert_equal(WIN32OLE::Param, ::WIN32OLE_PARAM)
+ end
+
def test_s_new
assert_raise(ArgumentError) {
- WIN32OLE_PARAM.new("hoge")
+ WIN32OLE::Param.new("hoge")
}
- ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "FileSystemObject")
- m_copyfile = WIN32OLE_METHOD.new(ole_type, "CopyFile")
+ ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "FileSystemObject")
+ m_copyfile = WIN32OLE::Method.new(ole_type, "CopyFile")
assert_raise(IndexError) {
- WIN32OLE_PARAM.new(m_copyfile, 4);
+ WIN32OLE::Param.new(m_copyfile, 4);
}
assert_raise(IndexError) {
- WIN32OLE_PARAM.new(m_copyfile, 0);
+ WIN32OLE::Param.new(m_copyfile, 0);
}
- param = WIN32OLE_PARAM.new(m_copyfile, 3)
+ param = WIN32OLE::Param.new(m_copyfile, 3)
assert_equal("OverWriteFiles", param.name)
- assert_equal(WIN32OLE_PARAM, param.class)
+ assert_equal(WIN32OLE::Param, param.class)
assert_equal(true, param.default)
- assert_equal("#<WIN32OLE_PARAM:OverWriteFiles=true>", param.inspect)
+ assert_equal("#<WIN32OLE::Param:OverWriteFiles=true>", param.inspect)
end
def test_name
@@ -91,8 +95,8 @@ if defined?(WIN32OLE_PARAM)
end
def test_inspect
- assert_equal("#<WIN32OLE_PARAM:Source>", @param_source.inspect)
- assert_equal("#<WIN32OLE_PARAM:OverWriteFiles=true>", @param_overwritefiles.inspect)
+ assert_equal("#<WIN32OLE::Param:Source>", @param_source.inspect)
+ assert_equal("#<WIN32OLE::Param:OverWriteFiles=true>", @param_overwritefiles.inspect)
end
end
end
diff --git a/test/win32ole/test_win32ole_param_event.rb b/test/win32ole/test_win32ole_param_event.rb
index a659a6d0f3..f5a16ead76 100644
--- a/test/win32ole/test_win32ole_param_event.rb
+++ b/test/win32ole/test_win32ole_param_event.rb
@@ -5,7 +5,7 @@ end
require 'test/unit'
-if defined?(WIN32OLE_PARAM)
+if defined?(WIN32OLE::Param)
require_relative 'available_ole'
class TestWIN32OLE_PARAM_EVENT < Test::Unit::TestCase
diff --git a/test/win32ole/test_win32ole_record.rb b/test/win32ole/test_win32ole_record.rb
index 65fd5f6a3c..49205ce53d 100644
--- a/test/win32ole/test_win32ole_record.rb
+++ b/test/win32ole/test_win32ole_record.rb
@@ -65,18 +65,24 @@ End Class
=end
-if defined?(WIN32OLE_RECORD)
+if defined?(WIN32OLE::Record)
+ class TestWIN32OLE_RECORD < Test::Unit::TestCase
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::Record, ::WIN32OLE_RECORD)
+ end
+ end
+
def rbcomtest_exist?
WIN32OLE.new(PROGID_RBCOMTEST)
true
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
false
end
class TestWIN32OLE_RECORD_BY_RBCOMTEST < Test::Unit::TestCase
unless rbcomtest_exist?
def test_dummy_for_skip_message
- omit "#{PROGID_RBCOMTEST} for WIN32OLE_RECORD test is not installed"
+ omit "#{PROGID_RBCOMTEST} for WIN32OLE::Record test is not installed"
end
else
def setup
@@ -84,42 +90,42 @@ if defined?(WIN32OLE_RECORD)
end
def test_s_new_from_win32ole
- rec = WIN32OLE_RECORD.new('Book', @obj)
+ rec = WIN32OLE::Record.new('Book', @obj)
assert(rec)
- assert_instance_of(WIN32OLE_RECORD, rec)
+ assert_instance_of(WIN32OLE::Record, rec)
end
def test_s_new_from_win32ole_typelib
tlib = @obj.ole_typelib
- rec = WIN32OLE_RECORD.new('Book', tlib)
+ rec = WIN32OLE::Record.new('Book', tlib)
assert(rec)
- assert_instance_of(WIN32OLE_RECORD, rec)
+ assert_instance_of(WIN32OLE::Record, rec)
end
def test_s_new_raise
- assert_raise(WIN32OLERuntimeError) {
- WIN32OLE_RECORD.new('NonExistRecordName', @obj)
+ assert_raise(WIN32OLE::RuntimeError) {
+ WIN32OLE::Record.new('NonExistRecordName', @obj)
}
assert_raise(ArgumentError) {
- WIN32OLE_RECORD.new
+ WIN32OLE::Record.new
}
assert_raise(ArgumentError) {
- WIN32OLE_RECORD.new('NonExistRecordName')
+ WIN32OLE::Record.new('NonExistRecordName')
}
end
def test_to_h
- rec = WIN32OLE_RECORD.new('Book', @obj)
+ rec = WIN32OLE::Record.new('Book', @obj)
assert_equal({'title'=>nil, 'cost'=>nil}, rec.to_h)
end
def test_typename
- rec = WIN32OLE_RECORD.new('Book', @obj)
+ rec = WIN32OLE::Record.new('Book', @obj)
assert_equal('Book', rec.typename)
end
def test_method_missing_getter
- rec = WIN32OLE_RECORD.new('Book', @obj)
+ rec = WIN32OLE::Record.new('Book', @obj)
assert_equal(nil, rec.title)
assert_raise(KeyError) {
rec.non_exist_name
@@ -127,14 +133,14 @@ if defined?(WIN32OLE_RECORD)
end
def test_method_missing_setter
- rec = WIN32OLE_RECORD.new('Book', @obj)
+ rec = WIN32OLE::Record.new('Book', @obj)
rec.title = "Ruby Book"
assert_equal("Ruby Book", rec.title)
end
def test_get_record_from_comserver
rec = @obj.getBook
- assert_instance_of(WIN32OLE_RECORD, rec)
+ assert_instance_of(WIN32OLE::Record, rec)
assert_equal("The Ruby Book", rec.title)
assert_equal(20, rec.cost)
end
@@ -143,16 +149,16 @@ if defined?(WIN32OLE_RECORD)
rec = @obj.getBooks
assert_instance_of(Array, rec)
assert_equal(2, rec.size)
- assert_instance_of(WIN32OLE_RECORD, rec[0])
+ assert_instance_of(WIN32OLE::Record, rec[0])
assert_equal("The CRuby Book", rec[0].title)
assert_equal(30, rec[0].cost)
- assert_instance_of(WIN32OLE_RECORD, rec[1])
+ assert_instance_of(WIN32OLE::Record, rec[1])
assert_equal("The JRuby Book", rec[1].title)
assert_equal(40, rec[1].cost)
end
def test_pass_record_parameter
- rec = WIN32OLE_RECORD.new('Book', @obj)
+ rec = WIN32OLE::Record.new('Book', @obj)
rec.title = "Ruby Book"
rec.cost = 60
book = @obj.getVer2BookByValBook(rec)
@@ -161,23 +167,23 @@ if defined?(WIN32OLE_RECORD)
end
def test_pass_variant_parameter_byref
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
@obj.getBookByRefBook(obj)
- assert_instance_of(WIN32OLE_RECORD, obj.value)
+ assert_instance_of(WIN32OLE::Record, obj.value)
book = obj.value
assert_equal("The Ruby Reference Book2", book.title)
assert_equal(44, book.cost)
end
def test_pass_record_parameter_byref
- book = WIN32OLE_RECORD.new('Book', @obj)
+ book = WIN32OLE::Record.new('Book', @obj)
@obj.getBookByRefBook(book)
assert_equal("The Ruby Reference Book2", book.title)
assert_equal(44, book.cost)
end
def test_pass_and_get_record_parameter_byref
- book = WIN32OLE_RECORD.new('Book', @obj)
+ book = WIN32OLE::Record.new('Book', @obj)
book.title = "Ruby Book"
book.cost = 60
@obj.getVer3BookByRefBook(book)
@@ -186,13 +192,13 @@ if defined?(WIN32OLE_RECORD)
end
def test_ole_instance_variable_get
- obj = WIN32OLE_RECORD.new('Book', @obj)
+ obj = WIN32OLE::Record.new('Book', @obj)
assert_equal(nil, obj.ole_instance_variable_get(:title))
assert_equal(nil, obj.ole_instance_variable_get('title'))
end
def test_ole_instance_variable_set
- book = WIN32OLE_RECORD.new('Book', @obj)
+ book = WIN32OLE::Record.new('Book', @obj)
book.ole_instance_variable_set(:title, "Ruby Book")
assert_equal("Ruby Book", book.title)
book.ole_instance_variable_set('title', "Ruby Book2")
@@ -200,8 +206,8 @@ if defined?(WIN32OLE_RECORD)
end
def test_inspect
- book = WIN32OLE_RECORD.new('Book', @obj)
- assert_equal(%q[#<WIN32OLE_RECORD(Book) {"title"=>nil, "cost"=>nil}>], book.inspect)
+ book = WIN32OLE::Record.new('Book', @obj)
+ assert_equal(%q[#<WIN32OLE::Record(Book) {"title"=>nil, "cost"=>nil}>], book.inspect)
end
end
end
diff --git a/test/win32ole/test_win32ole_type.rb b/test/win32ole/test_win32ole_type.rb
index 485b390d5c..9abcd68c9b 100644
--- a/test/win32ole/test_win32ole_type.rb
+++ b/test/win32ole/test_win32ole_type.rb
@@ -5,11 +5,14 @@ rescue LoadError
end
require "test/unit"
-if defined?(WIN32OLE_TYPE)
+if defined?(WIN32OLE::Type)
class TestWIN32OLE_TYPE < Test::Unit::TestCase
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::Type, ::WIN32OLE_TYPE)
+ end
def test_s_progids
- progids = WIN32OLE_TYPE.progids
+ progids = WIN32OLE::Type.progids
assert_instance_of(Array, progids)
assert(progids.size > 0)
assert_instance_of(String, progids[0])
@@ -18,25 +21,25 @@ if defined?(WIN32OLE_TYPE)
def test_initialize
assert_raise(ArgumentError) {
- WIN32OLE_TYPE.new
+ WIN32OLE::Type.new
}
assert_raise(ArgumentError) {
- WIN32OLE_TYPE.new("foo")
+ WIN32OLE::Type.new("foo")
}
assert_raise(TypeError) {
- WIN32OLE_TYPE.new(1, 2)
+ WIN32OLE::Type.new(1, 2)
}
assert_raise(TypeError) {
- WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", 1)
+ WIN32OLE::Type.new("Microsoft Shell Controls And Automation", 1)
}
- assert_raise(WIN32OLERuntimeError) {
- WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "foo")
+ assert_raise(WIN32OLE::RuntimeError) {
+ WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "foo")
}
- assert_raise(WIN32OLERuntimeError) {
- WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Application")
+ assert_raise(WIN32OLE::RuntimeError) {
+ WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Application")
}
- ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
- assert_instance_of(WIN32OLE_TYPE, ole_type)
+ ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Shell")
+ assert_instance_of(WIN32OLE::Type, ole_type)
assert_equal("Shell", ole_type.name)
assert_equal("Class", ole_type.ole_type)
assert_equal("{13709620-C279-11CE-A49E-444553540000}", ole_type.guid)
@@ -53,8 +56,8 @@ if defined?(WIN32OLE_TYPE)
assert_equal([], ole_type.variables)
assert(ole_type.ole_methods.select{|m|/NameSpace/i =~ m.name}.size > 0)
- ole_type2 = WIN32OLE_TYPE.new("{13709620-C279-11CE-A49E-444553540000}", "Shell")
- assert_instance_of(WIN32OLE_TYPE, ole_type)
+ ole_type2 = WIN32OLE::Type.new("{13709620-C279-11CE-A49E-444553540000}", "Shell")
+ assert_instance_of(WIN32OLE::Type, ole_type)
assert_equal(ole_type.name, ole_type2.name)
assert_equal(ole_type.ole_type, ole_type2.ole_type)
assert_equal(ole_type.guid, ole_type2.guid)
@@ -76,7 +79,7 @@ if defined?(WIN32OLE_TYPE)
end
def setup
- @ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "Shell")
+ @ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "Shell")
end
def test_name
@@ -97,7 +100,7 @@ if defined?(WIN32OLE_TYPE)
def test_visible?
assert(@ole_type.visible?)
- ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "IShellDispatch")
+ ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "IShellDispatch")
assert(!ole_type.visible?)
end
@@ -107,13 +110,13 @@ if defined?(WIN32OLE_TYPE)
def test_major_version
assert_equal(0, @ole_type.major_version)
- # ole_type = WIN32OLE_TYPE.new("Microsoft Word 11.0 Object Library", "Documents")
+ # ole_type = WIN32OLE::Type.new("Microsoft Word 11.0 Object Library", "Documents")
# assert_equal(8, ole_type.major_version)
end
def test_minor_version
assert_equal(0, @ole_type.minor_version)
- # ole_type = WIN32OLE_TYPE.new("Microsoft Word 11.0 Object Library", "Documents")
+ # ole_type = WIN32OLE::Type.new("Microsoft Word 11.0 Object Library", "Documents")
# assert_equal(3, ole_type.minor_version)
end
@@ -126,20 +129,20 @@ if defined?(WIN32OLE_TYPE)
end
def test_src_type
- ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "DriveTypeConst")
+ ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "DriveTypeConst")
assert_match(/__MIDL___MIDL_itf_scrrun_/, ole_type.src_type)
assert_equal(nil, @ole_type.src_type)
end
def test_helpfile
assert_equal("", @ole_type.helpfile)
- ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "Folders")
+ ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "Folders")
assert_match(/VBENLR98\.CHM$/i, ole_type.helpfile)
end
def test_helpcontext
assert_equal(0, @ole_type.helpcontext)
- ole_type = WIN32OLE_TYPE.new("Microsoft Scripting Runtime", "Folders")
+ ole_type = WIN32OLE::Type.new("Microsoft Scripting Runtime", "Folders")
assert_equal(2181929, ole_type.helpcontext)
end
@@ -148,25 +151,25 @@ if defined?(WIN32OLE_TYPE)
assert_instance_of(Array, variables)
assert(variables.size == 0)
- ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+ ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
variables = ole_type.variables
assert_instance_of(Array, variables)
assert(variables.size > 0)
- assert_instance_of(WIN32OLE_VARIABLE, variables[0])
+ assert_instance_of(WIN32OLE::Variable, variables[0])
end
def test_ole_methods
methods = @ole_type.ole_methods
assert_instance_of(Array, methods)
assert(methods.size > 0)
- assert_instance_of(WIN32OLE_METHOD, methods[0]);
+ assert_instance_of(WIN32OLE::Method, methods[0]);
assert(methods.collect{|m| m.name}.include?("Application"))
end
def test_ole_typelib
tlib = @ole_type.ole_typelib
- assert_instance_of(WIN32OLE_TYPELIB, tlib)
+ assert_instance_of(WIN32OLE::TypeLib, tlib)
assert_equal("Microsoft Shell Controls And Automation", tlib.name)
end
@@ -178,20 +181,20 @@ if defined?(WIN32OLE_TYPE)
end
def test_inspect
- assert_equal("#<WIN32OLE_TYPE:Shell>", @ole_type.inspect)
+ assert_equal("#<WIN32OLE::Type:Shell>", @ole_type.inspect)
end
- # WIN32OLE_TYPE.typelibs will be obsoleted.
+ # WIN32OLE::Type.typelibs will be obsoleted.
def test_s_typelibs
- tlibs = WIN32OLE_TYPE.typelibs.sort
- tlibs2 = WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}.sort
+ tlibs = WIN32OLE::Type.typelibs.sort
+ tlibs2 = WIN32OLE::TypeLib.typelibs.collect{|t|t.name}.sort
assert_equal(tlibs2, tlibs)
end
- # WIN32OLE_TYPE.ole_classes will be obsoleted.
+ # WIN32OLE::Type.ole_classes will be obsoleted.
def test_s_ole_classes
- ots1 = WIN32OLE_TYPE.ole_classes("Microsoft Shell Controls And Automation")
- ots2 = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation").ole_types
+ ots1 = WIN32OLE::Type.ole_classes("Microsoft Shell Controls And Automation")
+ ots2 = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation").ole_types
otns1 = ots1.collect{|t| t.name}.sort
otns2 = ots2.collect{|t| t.name}.sort
assert_equal(otns2, otns1)
diff --git a/test/win32ole/test_win32ole_type_event.rb b/test/win32ole/test_win32ole_type_event.rb
index ec46245cae..5d1c9fc44c 100644
--- a/test/win32ole/test_win32ole_type_event.rb
+++ b/test/win32ole/test_win32ole_type_event.rb
@@ -6,7 +6,7 @@ end
require 'test/unit'
-if defined?(WIN32OLE_TYPE)
+if defined?(WIN32OLE::Type)
require_relative 'available_ole'
class TestWIN32OLE_TYPE_EVENT < Test::Unit::TestCase
@@ -17,7 +17,7 @@ if defined?(WIN32OLE_TYPE)
else
def setup
- @ole_type = WIN32OLE_TYPE.new('System Monitor Control', 'SystemMonitor')
+ @ole_type = WIN32OLE::Type.new('System Monitor Control', 'SystemMonitor')
end
def test_implemented_ole_types
diff --git a/test/win32ole/test_win32ole_typelib.rb b/test/win32ole/test_win32ole_typelib.rb
index 321c019e53..31d6122756 100644
--- a/test/win32ole/test_win32ole_typelib.rb
+++ b/test/win32ole/test_win32ole_typelib.rb
@@ -5,10 +5,14 @@ rescue LoadError
end
require "test/unit"
-if defined?(WIN32OLE_TYPELIB)
+if defined?(WIN32OLE::TypeLib)
class TestWIN32OLE_TYPELIB < Test::Unit::TestCase
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::TypeLib, ::WIN32OLE_TYPELIB)
+ end
+
def test_s_typelibs
- tlibs = WIN32OLE_TYPELIB.typelibs
+ tlibs = WIN32OLE::TypeLib.typelibs
assert_instance_of(Array, tlibs)
assert(tlibs.size > 0)
tlib = tlibs.find {|t| t.name == "Microsoft Shell Controls And Automation"}
@@ -17,100 +21,100 @@ if defined?(WIN32OLE_TYPELIB)
def test_initialize
assert_raise(ArgumentError) {
- WIN32OLE_TYPELIB.new(1,2,3,4)
+ WIN32OLE::TypeLib.new(1,2,3,4)
}
assert_raise(TypeError) {
- WIN32OLE_TYPELIB.new(100)
+ WIN32OLE::TypeLib.new(100)
}
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
- assert_instance_of(WIN32OLE_TYPELIB, tlib)
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
+ assert_instance_of(WIN32OLE::TypeLib, tlib)
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation", 1.0)
- assert_instance_of(WIN32OLE_TYPELIB, tlib)
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation", 1.0)
+ assert_instance_of(WIN32OLE::TypeLib, tlib)
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation", 1, 0)
- assert_instance_of(WIN32OLE_TYPELIB, tlib)
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation", 1, 0)
+ assert_instance_of(WIN32OLE::TypeLib, tlib)
guid = tlib.guid
- tlib_by_guid = WIN32OLE_TYPELIB.new(guid, 1, 0)
- assert_instance_of(WIN32OLE_TYPELIB, tlib_by_guid)
+ tlib_by_guid = WIN32OLE::TypeLib.new(guid, 1, 0)
+ assert_instance_of(WIN32OLE::TypeLib, tlib_by_guid)
assert_equal("Microsoft Shell Controls And Automation" , tlib_by_guid.name)
path = tlib.path
- tlib_by_path = WIN32OLE_TYPELIB.new(path)
+ tlib_by_path = WIN32OLE::TypeLib.new(path)
assert_equal("Microsoft Shell Controls And Automation" , tlib_by_path.name)
- assert_raise(WIN32OLERuntimeError) {
- WIN32OLE_TYPELIB.new("Non Exist Type Library")
+ assert_raise(WIN32OLE::RuntimeError) {
+ WIN32OLE::TypeLib.new("Non Exist Type Library")
}
end
# #Bug:3907 [ruby-dev:42338]
def test_initialize_with_REG_EXPAND_SZ
- tlib = WIN32OLE_TYPELIB.new("Disk Management Snap-In Object Library")
- assert_instance_of(WIN32OLE_TYPELIB, tlib)
+ tlib = WIN32OLE::TypeLib.new("Disk Management Snap-In Object Library")
+ assert_instance_of(WIN32OLE::TypeLib, tlib)
end
def test_guid
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}", tlib.guid)
end
def test_name
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("Microsoft Shell Controls And Automation", tlib.name)
- tlib = WIN32OLE_TYPELIB.new("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}")
+ tlib = WIN32OLE::TypeLib.new("{50A7E9B0-70EF-11D1-B75A-00A0C90564FE}")
assert_equal("Microsoft Shell Controls And Automation", tlib.name)
end
def test_version
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("1.0", tlib.version)
end
def test_major_version
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal(1, tlib.major_version)
end
def test_minor_version
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal(0, tlib.minor_version)
end
def test_path
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_match(/shell32\.dll$/i, tlib.path)
end
def test_visible?
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert(tlib.visible?)
end
def test_library_name
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("Shell32", tlib.library_name)
end
def test_to_s
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
assert_equal("Microsoft Shell Controls And Automation", tlib.to_s)
end
def test_ole_types
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
ole_types = tlib.ole_types
assert_instance_of(Array, ole_types)
assert(ole_types.size > 0)
- assert_instance_of(WIN32OLE_TYPE, ole_types[0])
+ assert_instance_of(WIN32OLE::Type, ole_types[0])
end
def test_inspect
- tlib = WIN32OLE_TYPELIB.new("Microsoft Shell Controls And Automation")
- assert_equal("#<WIN32OLE_TYPELIB:Microsoft Shell Controls And Automation>", tlib.inspect)
+ tlib = WIN32OLE::TypeLib.new("Microsoft Shell Controls And Automation")
+ assert_equal("#<WIN32OLE::TypeLib:Microsoft Shell Controls And Automation>", tlib.inspect)
end
end
diff --git a/test/win32ole/test_win32ole_variable.rb b/test/win32ole/test_win32ole_variable.rb
index 8af3f987a8..646cf68915 100644
--- a/test/win32ole/test_win32ole_variable.rb
+++ b/test/win32ole/test_win32ole_variable.rb
@@ -5,19 +5,23 @@ rescue LoadError
end
require "test/unit"
-if defined?(WIN32OLE_VARIABLE)
+if defined?(WIN32OLE::Variable)
class TestWIN32OLE_VARIABLE < Test::Unit::TestCase
def setup
- ole_type = WIN32OLE_TYPE.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
+ ole_type = WIN32OLE::Type.new("Microsoft Shell Controls And Automation", "ShellSpecialFolderConstants")
@var1 = ole_type.variables.find {|v| v.name == 'ssfDESKTOP'}
- variables = WIN32OLE_TYPE.new("Microsoft Windows Installer Object Library", "Installer").variables
+ variables = WIN32OLE::Type.new("Microsoft Windows Installer Object Library", "Installer").variables
@var2 = variables.find {|v| v.name == 'UILevel'}
end
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::Variable, ::WIN32OLE_VARIABLE)
+ end
+
def test_initialize
- assert_raise(TypeError) {WIN32OLE_VARIABLE.new}
+ assert_raise(TypeError) {WIN32OLE::Variable.new}
end
def test_name
@@ -58,8 +62,8 @@ if defined?(WIN32OLE_VARIABLE)
end
def test_inspect
- assert_equal("#<WIN32OLE_VARIABLE:ssfDESKTOP=0>", @var1.inspect)
- assert_equal("#<WIN32OLE_VARIABLE:UILevel=nil>", @var2.inspect)
+ assert_equal("#<WIN32OLE::Variable:ssfDESKTOP=0>", @var1.inspect)
+ assert_equal("#<WIN32OLE::Variable:UILevel=nil>", @var2.inspect)
end
end
diff --git a/test/win32ole/test_win32ole_variant.rb b/test/win32ole/test_win32ole_variant.rb
index 1cedf55ef3..13b9a229a5 100644
--- a/test/win32ole/test_win32ole_variant.rb
+++ b/test/win32ole/test_win32ole_variant.rb
@@ -5,7 +5,7 @@ rescue LoadError
end
require "test/unit"
-if defined?(WIN32OLE_VARIANT)
+if defined?(WIN32OLE::Variant)
class TestWIN32OLE_VARIANT < Test::Unit::TestCase
def setup
@@ -17,36 +17,40 @@ if defined?(WIN32OLE_VARIANT)
WIN32OLE.locale = @orglocale
end
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::Variant, ::WIN32OLE_VARIANT)
+ end
+
def test_s_new
- obj = WIN32OLE_VARIANT.new('foo')
- assert_instance_of(WIN32OLE_VARIANT, obj)
+ obj = WIN32OLE::Variant.new('foo')
+ assert_instance_of(WIN32OLE::Variant, obj)
end
def test_s_new_exc
assert_raise(TypeError) {
- WIN32OLE_VARIANT.new(/foo/)
+ WIN32OLE::Variant.new(/foo/)
}
end
def test_s_new_ary
- obj = WIN32OLE_VARIANT.new([1])
- assert_instance_of(WIN32OLE_VARIANT, obj)
+ obj = WIN32OLE::Variant.new([1])
+ assert_instance_of(WIN32OLE::Variant, obj)
assert_raise(TypeError) {
- WIN32OLE_VARIANT.new([/foo/])
+ WIN32OLE::Variant.new([/foo/])
}
end
def test_s_new_no_argument
pat = /wrong number of arguments \(.*\b0\b.* 1\.\.3\)/
assert_raise_with_message(ArgumentError, pat) do
- WIN32OLE_VARIANT.new
+ WIN32OLE::Variant.new
end
end
def test_s_new_one_argument
ex = nil
begin
- WIN32OLE_VARIANT.new('foo')
+ WIN32OLE::Variant.new('foo')
rescue
ex = $!
end
@@ -54,247 +58,247 @@ if defined?(WIN32OLE_VARIANT)
end
def test_s_new_with_nil
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_I2)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_I2)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I2, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_I4)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_I4)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_R4)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_R4)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R4, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_R8)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_R8)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R8, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_CY)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_CY)
assert_equal("0", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_CY, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,30), obj.value)
assert_equal(WIN32OLE::VARIANT::VT_DATE, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_BSTR)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_BSTR)
assert_equal("", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
assert_nil(obj.value)
assert_equal(WIN32OLE::VARIANT::VT_DISPATCH, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_BOOL)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_BOOL)
assert_equal(false, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BOOL, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_VARIANT)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_VARIANT)
assert_nil(obj.value)
assert_equal(WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_I1)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_I1)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I1, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UI1)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UI1)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI1, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UI2)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UI2)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI2, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UI4)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UI4)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI4, obj.vartype)
if defined?(WIN32OLE::VARIANT::VT_I8)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_I8)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_I8)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I8, obj.vartype)
end
if defined?(WIN32OLE::VARIANT::VT_UI8)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UI8)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UI8)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI8, obj.vartype)
end
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_INT)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_INT)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_INT, obj.vartype)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_UINT)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_UINT)
assert_equal(0, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UINT, obj.vartype)
end
def test_s_new_with_non_nil
- obj = WIN32OLE_VARIANT.new(2, WIN32OLE::VARIANT::VT_I2)
+ obj = WIN32OLE::Variant.new(2, WIN32OLE::VARIANT::VT_I2)
assert_equal(2, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I2, obj.vartype)
- obj = WIN32OLE_VARIANT.new(3, WIN32OLE::VARIANT::VT_I4)
+ obj = WIN32OLE::Variant.new(3, WIN32OLE::VARIANT::VT_I4)
assert_equal(3, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
- obj = WIN32OLE_VARIANT.new(4.5, WIN32OLE::VARIANT::VT_R4)
+ obj = WIN32OLE::Variant.new(4.5, WIN32OLE::VARIANT::VT_R4)
assert_equal(4.5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R4, obj.vartype)
- obj = WIN32OLE_VARIANT.new(5.5, WIN32OLE::VARIANT::VT_R8)
+ obj = WIN32OLE::Variant.new(5.5, WIN32OLE::VARIANT::VT_R8)
assert_equal(5.5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R8, obj.vartype)
- obj = WIN32OLE_VARIANT.new(600, WIN32OLE::VARIANT::VT_CY)
+ obj = WIN32OLE::Variant.new(600, WIN32OLE::VARIANT::VT_CY)
assert_equal("600", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_CY, obj.vartype)
- obj = WIN32OLE_VARIANT.new("2001-06-15 12:17:34", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("2001-06-15 12:17:34", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2001,06,15,12,17,34), obj.value)
assert_equal(WIN32OLE::VARIANT::VT_DATE, obj.vartype)
- obj = WIN32OLE_VARIANT.new("foo", WIN32OLE::VARIANT::VT_BSTR)
+ obj = WIN32OLE::Variant.new("foo", WIN32OLE::VARIANT::VT_BSTR)
assert_equal("foo", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
- obj = WIN32OLE_VARIANT.new(true, WIN32OLE::VARIANT::VT_BOOL)
+ obj = WIN32OLE::Variant.new(true, WIN32OLE::VARIANT::VT_BOOL)
assert_equal(true, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BOOL, obj.vartype)
- obj = WIN32OLE_VARIANT.new(2, WIN32OLE::VARIANT::VT_I1)
+ obj = WIN32OLE::Variant.new(2, WIN32OLE::VARIANT::VT_I1)
assert_equal(2, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I1, obj.vartype)
- obj = WIN32OLE_VARIANT.new(3, WIN32OLE::VARIANT::VT_UI1)
+ obj = WIN32OLE::Variant.new(3, WIN32OLE::VARIANT::VT_UI1)
assert_equal(3, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI1, obj.vartype)
- obj = WIN32OLE_VARIANT.new(4, WIN32OLE::VARIANT::VT_UI2)
+ obj = WIN32OLE::Variant.new(4, WIN32OLE::VARIANT::VT_UI2)
assert_equal(4, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI2, obj.vartype)
- obj = WIN32OLE_VARIANT.new(5, WIN32OLE::VARIANT::VT_UI4)
+ obj = WIN32OLE::Variant.new(5, WIN32OLE::VARIANT::VT_UI4)
assert_equal(5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI4, obj.vartype)
if defined?(WIN32OLE::VARIANT::VT_I8)
- obj = WIN32OLE_VARIANT.new(-123456789012345, WIN32OLE::VARIANT::VT_I8)
+ obj = WIN32OLE::Variant.new(-123456789012345, WIN32OLE::VARIANT::VT_I8)
assert_equal(-123456789012345, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I8, obj.vartype)
end
if defined?(WIN32OLE::VARIANT::VT_UI8)
- obj = WIN32OLE_VARIANT.new(123456789012345, WIN32OLE::VARIANT::VT_UI8)
+ obj = WIN32OLE::Variant.new(123456789012345, WIN32OLE::VARIANT::VT_UI8)
assert_equal(123456789012345, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI8, obj.vartype)
end
- obj = WIN32OLE_VARIANT.new(4, WIN32OLE::VARIANT::VT_INT)
+ obj = WIN32OLE::Variant.new(4, WIN32OLE::VARIANT::VT_INT)
assert_equal(4, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_INT, obj.vartype)
- obj = WIN32OLE_VARIANT.new(5, WIN32OLE::VARIANT::VT_UINT)
+ obj = WIN32OLE::Variant.new(5, WIN32OLE::VARIANT::VT_UINT)
assert_equal(5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UINT, obj.vartype)
end
def test_s_new_with_non_nil_byref
- obj = WIN32OLE_VARIANT.new(2, WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(2, WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(2, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(3, WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(3, WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(3, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(4.5, WIN32OLE::VARIANT::VT_R4|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(4.5, WIN32OLE::VARIANT::VT_R4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(4.5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(5.5, WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(5.5, WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(5.5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(600, WIN32OLE::VARIANT::VT_CY|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(600, WIN32OLE::VARIANT::VT_CY|WIN32OLE::VARIANT::VT_BYREF)
assert_equal("600", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_CY|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new("2001-06-15 12:17:34", WIN32OLE::VARIANT::VT_DATE|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new("2001-06-15 12:17:34", WIN32OLE::VARIANT::VT_DATE|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(Time.new(2001,06,15,12,17,34), obj.value)
assert_equal(WIN32OLE::VARIANT::VT_DATE|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new("foo", WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new("foo", WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF)
assert_equal("foo", obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(true, WIN32OLE::VARIANT::VT_BOOL|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(true, WIN32OLE::VARIANT::VT_BOOL|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(true, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_BOOL|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(2, WIN32OLE::VARIANT::VT_I1|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(2, WIN32OLE::VARIANT::VT_I1|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(2, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I1|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(3, WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(3, WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(3, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(4, WIN32OLE::VARIANT::VT_UI2|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(4, WIN32OLE::VARIANT::VT_UI2|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(4, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI2|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(5, WIN32OLE::VARIANT::VT_UI4|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(5, WIN32OLE::VARIANT::VT_UI4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI4|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(4, WIN32OLE::VARIANT::VT_INT|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(4, WIN32OLE::VARIANT::VT_INT|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(4, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_INT|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
- obj = WIN32OLE_VARIANT.new(5, WIN32OLE::VARIANT::VT_UINT|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(5, WIN32OLE::VARIANT::VT_UINT|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(5, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UINT|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
end
def test_s_new_with_i8_byref
- obj = WIN32OLE_VARIANT.new(-123456789012345, WIN32OLE::VARIANT::VT_I8|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(-123456789012345, WIN32OLE::VARIANT::VT_I8|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(-123456789012345, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
end
def test_s_new_with_ui8_byref
- obj = WIN32OLE_VARIANT.new(123456789012345, WIN32OLE::VARIANT::VT_UI8|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(123456789012345, WIN32OLE::VARIANT::VT_UI8|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(123456789012345, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_UI8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
end
def test_value
- obj = WIN32OLE_VARIANT.new('foo')
+ obj = WIN32OLE::Variant.new('foo')
assert_equal('foo', obj.value)
end
def test_s_new_2_argument
- obj = WIN32OLE_VARIANT.new('foo', WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new('foo', WIN32OLE::VARIANT::VT_BSTR|WIN32OLE::VARIANT::VT_BYREF)
assert_equal('foo', obj.value);
end
def test_s_new_2_argument2
- obj = WIN32OLE_VARIANT.new('foo', WIN32OLE::VARIANT::VT_BSTR)
+ obj = WIN32OLE::Variant.new('foo', WIN32OLE::VARIANT::VT_BSTR)
assert_equal('foo', obj.value);
end
def test_s_new_dispatch_array
vt = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH
- obj = WIN32OLE_VARIANT.new(nil, vt)
+ obj = WIN32OLE::Variant.new(nil, vt)
assert_equal(vt, obj.vartype)
assert_nil(obj.value)
vt = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH|WIN32OLE::VARIANT::VT_BYREF
- obj = WIN32OLE_VARIANT.new(nil, vt)
+ obj = WIN32OLE::Variant.new(nil, vt)
assert_equal(vt, obj.vartype)
assert_nil(obj.value)
end
@@ -302,29 +306,29 @@ if defined?(WIN32OLE_VARIANT)
def test_s_new_array
# should not occur stack over flow
ar = (1..500000).to_a.map{|i| [i]}
- ar2 = WIN32OLE_VARIANT.new(ar)
+ ar2 = WIN32OLE::Variant.new(ar)
assert_equal(ar, ar2.value)
end
def test_s_new_vt_record_exc
- # VT_RECORD (= 36) should not be allowed in WIN32OLE_VARIANT#new
+ # VT_RECORD (= 36) should not be allowed in WIN32OLE::Variant#new
assert_raise(ArgumentError) {
- WIN32OLE_VARIANT.new(nil, 36)
+ WIN32OLE::Variant.new(nil, 36)
}
end
def test_s_array
- obj = WIN32OLE_VARIANT.array([2,3], WIN32OLE::VARIANT::VT_I4)
- assert_instance_of(WIN32OLE_VARIANT, obj)
+ obj = WIN32OLE::Variant.array([2,3], WIN32OLE::VARIANT::VT_I4)
+ assert_instance_of(WIN32OLE::Variant, obj)
assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
- obj = WIN32OLE_VARIANT.array([2,3], WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.array([2,3], WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
- obj = WIN32OLE_VARIANT.array([2,3], WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY)
- assert_instance_of(WIN32OLE_VARIANT, obj)
+ obj = WIN32OLE::Variant.array([2,3], WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY)
+ assert_instance_of(WIN32OLE::Variant, obj)
assert_equal(WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_ARRAY, obj.vartype)
assert_equal([[0, 0, 0],[0, 0, 0]], obj.value)
@@ -334,60 +338,60 @@ if defined?(WIN32OLE_VARIANT)
obj[0,1] = "13.2"
assert_equal([[10, 13, 0],[0, 0, 0]], obj.value)
- obj = WIN32OLE_VARIANT.array([3, 2], WIN32OLE::VARIANT::VT_VARIANT)
+ obj = WIN32OLE::Variant.array([3, 2], WIN32OLE::VARIANT::VT_VARIANT)
obj[0,0] = 10
obj[0,1] = "string"
obj[1,0] = 12.735
assert_equal([[10, "string"],[12.735, nil],[nil,nil]], obj.value)
- obj = WIN32OLE_VARIANT.array([2,3], WIN32OLE::VARIANT::VT_DISPATCH)
+ obj = WIN32OLE::Variant.array([2,3], WIN32OLE::VARIANT::VT_DISPATCH)
assert_equal([[nil, nil, nil],[nil,nil,nil]], obj.value)
end
def test_s_array_exc
assert_raise(TypeError) {
- WIN32OLE_VARIANT.array(2, WIN32OLE::VARIANT::VT_I4)
+ WIN32OLE::Variant.array(2, WIN32OLE::VARIANT::VT_I4)
}
end
def test_conversion_num2str
- obj = WIN32OLE_VARIANT.new(124, WIN32OLE::VARIANT::VT_BSTR)
+ obj = WIN32OLE::Variant.new(124, WIN32OLE::VARIANT::VT_BSTR)
assert_equal("124", obj.value);
end
def test_conversion_float2int
- obj = WIN32OLE_VARIANT.new(12.345, WIN32OLE::VARIANT::VT_I4)
+ obj = WIN32OLE::Variant.new(12.345, WIN32OLE::VARIANT::VT_I4)
assert_equal(12, obj.value)
- obj = WIN32OLE_VARIANT.new(12.345, WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(12.345, WIN32OLE::VARIANT::VT_I4|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(12, obj.value)
end
def test_conversion_str2num
- obj = WIN32OLE_VARIANT.new("12.345", WIN32OLE::VARIANT::VT_R8)
+ obj = WIN32OLE::Variant.new("12.345", WIN32OLE::VARIANT::VT_R8)
assert_equal(12.345, obj.value)
end
def test_conversion_ole_variant2ole_variant
- obj = WIN32OLE_VARIANT.new("12.345", WIN32OLE::VARIANT::VT_R4)
- obj = WIN32OLE_VARIANT.new(obj, WIN32OLE::VARIANT::VT_I4)
+ obj = WIN32OLE::Variant.new("12.345", WIN32OLE::VARIANT::VT_R4)
+ obj = WIN32OLE::Variant.new(obj, WIN32OLE::VARIANT::VT_I4)
assert_equal(12, obj.value)
end
def test_conversion_str2date
- obj = WIN32OLE_VARIANT.new("2004-12-24 12:24:45", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("2004-12-24 12:24:45", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2004,12,24,12,24,45), obj.value)
end
def test_conversion_time2date
dt = Time.mktime(2004, 12, 24, 12, 24, 45)
- obj = WIN32OLE_VARIANT.new(dt, WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new(dt, WIN32OLE::VARIANT::VT_DATE)
assert_equal(dt, obj.value)
end
def test_conversion_dbl2date_with_msec
# Date is "2014/8/27 12:34:56.789"
- obj = WIN32OLE_VARIANT.new(41878.524268391200167, WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new(41878.524268391200167, WIN32OLE::VARIANT::VT_DATE)
t = obj.value
assert_equal("2014-08-27 12:34:56", t.strftime('%Y-%m-%d %H:%M:%S'))
assert_in_delta(0.789, t.nsec / 1000000000.0, 0.001)
@@ -396,7 +400,7 @@ if defined?(WIN32OLE_VARIANT)
def test_conversion_time2date_with_msec
t0 = Time.new(2014, 8, 27, 12, 34, 56)
t0 += 0.789
- t1 = WIN32OLE_VARIANT.new(t0).value
+ t1 = WIN32OLE::Variant.new(t0).value
# The t0.nsec is 789000000 and t1.nsec is 789000465
# because of error range by conversion Time between VT_DATE Variant.
@@ -406,7 +410,7 @@ if defined?(WIN32OLE_VARIANT)
t0 = Time.new(2014, 8, 27, 12, 34, 56)
t0 += 0.999999999
- t1 = WIN32OLE_VARIANT.new(t0).value
+ t1 = WIN32OLE::Variant.new(t0).value
msg = "Expected:#{t0.strftime('%Y-%m-%dT%H:%M:%S.%N')} but was:#{t1.strftime('%Y-%m-%dT%H:%M:%S.%N')}"
# The t0 is "2014/08/27 12:34.56.999999999" and
@@ -414,7 +418,7 @@ if defined?(WIN32OLE_VARIANT)
assert_in_delta(t0, t1, 0.001, msg)
t0 = Time.now
- t1 = WIN32OLE_VARIANT.new(t0).value
+ t1 = WIN32OLE::Variant.new(t0).value
msg = "Expected:#{t0.strftime('%Y-%m-%dT%H:%M:%S.%N')} but was:#{t1.strftime('%Y-%m-%dT%H:%M:%S.%N')}"
assert_in_delta(t0, t1, 0.001, msg)
end
@@ -426,110 +430,110 @@ if defined?(WIN32OLE_VARIANT)
# def test_conversion_time_nsec2date
# dt = Time.new(2004, 12,24, 12, 24, 45)
# dt += 0.1
- # obj = WIN32OLE_VARIANT.new(dt, WIN32OLE::VARIANT::VT_DATE)
+ # obj = WIN32OLE::Variant.new(dt, WIN32OLE::VARIANT::VT_DATE)
# assert_equal(dt, obj.value)
# end
def test_conversion_str2cy
begin
WIN32OLE.locale = 0x0411 # set locale Japanese
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
omit("Japanese locale is not installed")
end
if WIN32OLE.locale == 0x0411
- obj = WIN32OLE_VARIANT.new("\\10,000", WIN32OLE::VARIANT::VT_CY)
+ obj = WIN32OLE::Variant.new("\\10,000", WIN32OLE::VARIANT::VT_CY)
assert_equal("10000", obj.value)
end
end
def test_create_vt_array
- obj = WIN32OLE_VARIANT.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8)
+ obj = WIN32OLE::Variant.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8)
assert_equal([1.2, 2.3], obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8, obj.vartype)
- obj = WIN32OLE_VARIANT.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new([1.2, 2.3], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF)
assert_equal([1.2, 2.3], obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_R8|WIN32OLE::VARIANT::VT_BYREF, obj.vartype)
end
def test_create_vt_array2
- obj = WIN32OLE_VARIANT.new([1.2, "a"], WIN32OLE::VARIANT::VT_ARRAY)
+ obj = WIN32OLE::Variant.new([1.2, "a"], WIN32OLE::VARIANT::VT_ARRAY)
assert_equal([1.2, "a"], obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
- obj = WIN32OLE_VARIANT.new([1.2, "a"])
+ obj = WIN32OLE::Variant.new([1.2, "a"])
assert_equal([1.2, "a"], obj.value)
assert_equal(WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_VARIANT, obj.vartype)
end
def test_create_vt_nested_array
- obj = WIN32OLE_VARIANT.new([[1.2, "a", "b"], [3.4, "C", "D"]], WIN32OLE::VARIANT::VT_ARRAY)
+ obj = WIN32OLE::Variant.new([[1.2, "a", "b"], [3.4, "C", "D"]], WIN32OLE::VARIANT::VT_ARRAY)
assert_equal([[1.2, "a", "b"], [3.4, "C", "D"]], obj.value)
- obj = WIN32OLE_VARIANT.new([[1.2, "a", "b"], [3.4, "C", "D"]])
+ obj = WIN32OLE::Variant.new([[1.2, "a", "b"], [3.4, "C", "D"]])
assert_equal([[1.2, "a", "b"], [3.4, "C", "D"]], obj.value)
- obj = WIN32OLE_VARIANT.new([[1.2, "a", "b"], [3.4, "C", "D"], [5.6, "E", "F"]])
+ obj = WIN32OLE::Variant.new([[1.2, "a", "b"], [3.4, "C", "D"], [5.6, "E", "F"]])
assert_equal([[1.2, "a", "b"], [3.4, "C", "D"], [5.6, "E", "F"]], obj.value)
- obj = WIN32OLE_VARIANT.new([[[1.2], [3.4]], [[5.6], [7.8]], [[9.1],[9.2]]])
+ obj = WIN32OLE::Variant.new([[[1.2], [3.4]], [[5.6], [7.8]], [[9.1],[9.2]]])
assert_equal([[[1.2], [3.4]], [[5.6], [7.8]], [[9.1],[9.2]]], obj.value)
end
def test_create_vt_array3
- obj = WIN32OLE_VARIANT.new([])
+ obj = WIN32OLE::Variant.new([])
assert_equal([], obj.value)
- obj = WIN32OLE_VARIANT.new([[]])
+ obj = WIN32OLE::Variant.new([[]])
assert_equal([[]], obj.value)
- obj = WIN32OLE_VARIANT.new([[],[]])
+ obj = WIN32OLE::Variant.new([[],[]])
assert_equal([[],[]], obj.value)
- obj = WIN32OLE_VARIANT.new([], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new([], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
assert_equal([], obj.value)
- obj = WIN32OLE_VARIANT.new([[]], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new([[]], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
assert_equal([[]], obj.value)
- obj = WIN32OLE_VARIANT.new([[],[]], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new([[],[]], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF)
assert_equal([[],[]], obj.value)
end
def test_create_vt_array_nil
vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH|WIN32OLE::VARIANT::VT_BYREF
- obj = WIN32OLE_VARIANT.new(nil, vartype)
+ obj = WIN32OLE::Variant.new(nil, vartype)
assert_nil(obj.value)
assert_equal(vartype, obj.vartype)
vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_DISPATCH
- obj = WIN32OLE_VARIANT.new(nil, vartype)
+ obj = WIN32OLE::Variant.new(nil, vartype)
assert_nil(obj.value)
assert_equal(vartype, obj.vartype)
end
def test_create_vt_array_str
vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BSTR
- obj = WIN32OLE_VARIANT.new(["abc", "123"], vartype)
+ obj = WIN32OLE::Variant.new(["abc", "123"], vartype)
assert_equal(vartype, obj.vartype)
assert_equal(["abc", "123"], obj.value)
vartype = WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_BSTR
- obj = WIN32OLE_VARIANT.new(["abc", "123"], vartype)
+ obj = WIN32OLE::Variant.new(["abc", "123"], vartype)
assert_equal(vartype, obj.vartype)
assert_equal(["abc", "123"], obj.value)
end
def test_create_vt_array_exc
exc = assert_raise(TypeError) {
- WIN32OLE_VARIANT.new("", WIN32OLE::VARIANT::VT_ARRAY)
+ WIN32OLE::Variant.new("", WIN32OLE::VARIANT::VT_ARRAY)
}
assert_match(/wrong argument type String \(expected Array\)/, exc.message)
end
def test_create_vt_array_str2ui1array
- obj = WIN32OLE_VARIANT.new("ABC", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
+ obj = WIN32OLE::Variant.new("ABC", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
assert_equal("ABC", obj.value)
obj.value = "DEF"
@@ -537,10 +541,10 @@ if defined?(WIN32OLE_VARIANT)
obj[0] = 71
assert_equal("GEF", obj.value)
- obj = WIN32OLE_VARIANT.new([65, 0].pack("C*"), WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
+ obj = WIN32OLE::Variant.new([65, 0].pack("C*"), WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
assert_equal([65, 0].pack("C*"), obj.value)
- obj = WIN32OLE_VARIANT.new("abc", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new("abc", WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1|WIN32OLE::VARIANT::VT_BYREF)
assert_equal("abc", obj.value)
obj.value = "DEF"
assert_equal("DEF", obj.value)
@@ -551,19 +555,19 @@ if defined?(WIN32OLE_VARIANT)
end
def test_create_vt_array_int
- obj = WIN32OLE_VARIANT.new([65, 0], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
+ obj = WIN32OLE::Variant.new([65, 0], WIN32OLE::VARIANT::VT_ARRAY|WIN32OLE::VARIANT::VT_UI1)
assert_equal([65, 0].pack("C*"), obj.value)
- obj = WIN32OLE_VARIANT.new([65, 0])
+ obj = WIN32OLE::Variant.new([65, 0])
assert_equal([65, 0], obj.value)
- obj = WIN32OLE_VARIANT.new([65, 0], WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_ARRAY)
+ obj = WIN32OLE::Variant.new([65, 0], WIN32OLE::VARIANT::VT_I2|WIN32OLE::VARIANT::VT_ARRAY)
assert_equal([65, 0], obj.value)
end
def test_vt_array_bracket
- obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
+ obj = WIN32OLE::Variant.new([[1,2,3],[4,5,6]])
assert_equal(1, obj[0,0])
assert_equal(2, obj[0,1])
assert_equal(3, obj[0,2])
@@ -571,10 +575,10 @@ if defined?(WIN32OLE_VARIANT)
assert_equal(5, obj[1,1])
assert_equal(6, obj[1,2])
- assert_raise(WIN32OLERuntimeError) {
+ assert_raise(WIN32OLE::RuntimeError) {
obj[0,4]
}
- assert_raise(WIN32OLERuntimeError) {
+ assert_raise(WIN32OLE::RuntimeError) {
obj[0,-1]
}
assert_raise(ArgumentError) {
@@ -585,10 +589,10 @@ if defined?(WIN32OLE_VARIANT)
obj[1,2] = 8
assert_equal([[7,2,3], [4,5,8]], obj.value)
- assert_raise(WIN32OLERuntimeError) {
+ assert_raise(WIN32OLE::RuntimeError) {
obj[0,4] = 9
}
- assert_raise(WIN32OLERuntimeError) {
+ assert_raise(WIN32OLE::RuntimeError) {
obj[0,-1] = 10
}
assert_raise(ArgumentError) {
@@ -597,60 +601,60 @@ if defined?(WIN32OLE_VARIANT)
end
def test_conversion_vt_date
- obj = WIN32OLE_VARIANT.new(-657434, WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new(-657434, WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(100,1,1), obj.value)
- obj = WIN32OLE_VARIANT.new("1500/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("1500/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1500,12,29,23,59,59), obj.value)
- obj = WIN32OLE_VARIANT.new("1500/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("1500/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1500,12,30), obj.value)
- obj = WIN32OLE_VARIANT.new("1500/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("1500/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1500,12,30,0,0,1), obj.value)
- obj = WIN32OLE_VARIANT.new("1899/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("1899/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,29,23,59,59), obj.value)
- obj = WIN32OLE_VARIANT.new("1899/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("1899/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,30), obj.value)
- obj = WIN32OLE_VARIANT.new("1899/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("1899/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,30,0,0,1), obj.value)
- obj = WIN32OLE_VARIANT.new(0, WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new(0, WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(1899,12,30), obj.value)
- obj = WIN32OLE_VARIANT.new("2008/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("2008/12/29 23:59:59", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2008,12,29,23,59,59), obj.value)
- obj = WIN32OLE_VARIANT.new("2008/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("2008/12/30 00:00:00", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2008,12,30,0,0,0), obj.value)
- obj = WIN32OLE_VARIANT.new("2008/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("2008/12/30 00:00:01", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(2008,12,30,0,0,1), obj.value)
- obj = WIN32OLE_VARIANT.new("9999/12/31 23:59:59", WIN32OLE::VARIANT::VT_DATE)
+ obj = WIN32OLE::Variant.new("9999/12/31 23:59:59", WIN32OLE::VARIANT::VT_DATE)
assert_equal(Time.new(9999,12,31,23,59,59), obj.value)
end
def test_create_nil_dispatch
- var = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
+ var = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_DISPATCH)
assert_nil(var.value)
end
def test_create_variant_byref
- obj = WIN32OLE_VARIANT.new("Str", WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF);
+ obj = WIN32OLE::Variant.new("Str", WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF);
assert_equal("Str", obj.value);
end
def test_vartype
- obj = WIN32OLE_VARIANT.new("Str")
+ obj = WIN32OLE::Variant.new("Str")
assert_equal(WIN32OLE::VARIANT::VT_BSTR, obj.vartype)
end
def test_set_value
- obj = WIN32OLE_VARIANT.new(10)
+ obj = WIN32OLE::Variant.new(10)
obj.value = 12
assert_equal(12, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
@@ -661,57 +665,57 @@ if defined?(WIN32OLE_VARIANT)
assert_equal(11, obj.value)
assert_equal(WIN32OLE::VARIANT::VT_I4, obj.vartype)
- obj = WIN32OLE_VARIANT.new([1,2])
- assert_raise(WIN32OLERuntimeError) {
+ obj = WIN32OLE::Variant.new([1,2])
+ assert_raise(WIN32OLE::RuntimeError) {
obj.value = [3,4]
}
- obj = WIN32OLE_VARIANT.new("2007/01/01", WIN32OLE::VARIANT::VT_DATE)
- assert_raise(WIN32OLERuntimeError) {
+ obj = WIN32OLE::Variant.new("2007/01/01", WIN32OLE::VARIANT::VT_DATE)
+ assert_raise(WIN32OLE::RuntimeError) {
obj.value = "hogehoge"
}
assert_equal(Time.new(2007,1,1), obj.value)
- obj2 = WIN32OLE_VARIANT.new("2006/01/01", WIN32OLE::VARIANT::VT_DATE)
+ obj2 = WIN32OLE::Variant.new("2006/01/01", WIN32OLE::VARIANT::VT_DATE)
obj.value = obj2
assert_equal(Time.new(2006,01,01), obj.value)
end
def test_c_nothing
- assert_nil(WIN32OLE_VARIANT::Nothing.value)
+ assert_nil(WIN32OLE::Variant::Nothing.value)
end
def test_c_empty
- assert_nil(WIN32OLE_VARIANT::Empty.value)
+ assert_nil(WIN32OLE::Variant::Empty.value)
end
def test_c_null
- assert_nil(WIN32OLE_VARIANT::Null.value)
+ assert_nil(WIN32OLE::Variant::Null.value)
end
def test_c_noparam
# DISP_E_PARAMNOTFOUND
- assert_equal(-2147352572, WIN32OLE_VARIANT::NoParam.value)
+ assert_equal(-2147352572, WIN32OLE::Variant::NoParam.value)
end
def test_vt_error_noparam
- v = WIN32OLE_VARIANT.new(-1, WIN32OLE::VARIANT::VT_ERROR)
+ v = WIN32OLE::Variant.new(-1, WIN32OLE::VARIANT::VT_ERROR)
assert_equal(-1, v.value)
fso = WIN32OLE.new("Scripting.FileSystemObject")
- exc = assert_raise(WIN32OLERuntimeError) {
+ exc = assert_raise(WIN32OLE::RuntimeError) {
fso.openTextFile("NonExistingFile", v, false)
}
assert_match(/Type mismatch/i, exc.message)
- exc = assert_raise(WIN32OLERuntimeError) {
- fso.openTextFile("NonExistingFile", WIN32OLE_VARIANT::NoParam, false)
+ exc = assert_raise(WIN32OLE::RuntimeError) {
+ fso.openTextFile("NonExistingFile", WIN32OLE::Variant::NoParam, false)
}
# 800A0035 is 'file not found' error.
assert_match(/800A0035/, exc.message)
# -2147352572 is DISP_E_PARAMNOTFOUND
- v = WIN32OLE_VARIANT.new(-2147352572, WIN32OLE::VARIANT::VT_ERROR)
- exc = assert_raise(WIN32OLERuntimeError) {
- fso.openTextFile("NonExistingFile", WIN32OLE_VARIANT::NoParam, false)
+ v = WIN32OLE::Variant.new(-2147352572, WIN32OLE::VARIANT::VT_ERROR)
+ exc = assert_raise(WIN32OLE::RuntimeError) {
+ fso.openTextFile("NonExistingFile", WIN32OLE::Variant::NoParam, false)
}
# 800A0035 is 'file not found' error code.
assert_match(/800A0035/, exc.message)
diff --git a/test/win32ole/test_win32ole_variant_m.rb b/test/win32ole/test_win32ole_variant_m.rb
index 25ad56cc21..3c2884644c 100644
--- a/test/win32ole/test_win32ole_variant_m.rb
+++ b/test/win32ole/test_win32ole_variant_m.rb
@@ -8,6 +8,11 @@ require "test/unit"
if defined?(WIN32OLE::VARIANT)
class TestWin32OLE_VARIANT_MODULE < Test::Unit::TestCase
include WIN32OLE::VARIANT
+
+ def test_toplevel_constants_backward_compatibility
+ assert_equal(WIN32OLE::VariantType, WIN32OLE::VARIANT)
+ end
+
def test_variant
assert_equal(0, VT_EMPTY)
assert_equal(1, VT_NULL)
diff --git a/test/win32ole/test_win32ole_variant_outarg.rb b/test/win32ole/test_win32ole_variant_outarg.rb
index f50b04aaf5..9301a76aaa 100644
--- a/test/win32ole/test_win32ole_variant_outarg.rb
+++ b/test/win32ole/test_win32ole_variant_outarg.rb
@@ -23,7 +23,7 @@ def ado_csv_installed?
installed
end
-if defined?(WIN32OLE_VARIANT)
+if defined?(WIN32OLE::Variant)
class TestWIN32OLE_VARIANT_OUTARG < Test::Unit::TestCase
module ADO
end
@@ -48,11 +48,11 @@ if defined?(WIN32OLE_VARIANT)
@db.execute(sql, -1)
c = WIN32OLE::ARGV[1]
assert_equal(1, c)
- obj = WIN32OLE_VARIANT.new(nil, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(nil, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(nil, obj.value)
@db.execute(sql , obj)
assert_equal(1, obj.value)
- obj = WIN32OLE_VARIANT.new(-100, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
+ obj = WIN32OLE::Variant.new(-100, WIN32OLE::VARIANT::VT_VARIANT|WIN32OLE::VARIANT::VT_BYREF)
assert_equal(-100, obj.value)
@db.execute(sql, obj)
assert_equal(1, obj.value)
diff --git a/test/win32ole/test_word.rb b/test/win32ole/test_word.rb
index a23757f620..34cfbbc2a4 100644
--- a/test/win32ole/test_word.rb
+++ b/test/win32ole/test_word.rb
@@ -41,7 +41,7 @@ if defined?(WIN32OLE)
def setup
begin
@obj = WIN32OLE.new('Word.Application')
- rescue WIN32OLERuntimeError
+ rescue WIN32OLE::RuntimeError
@obj = nil
end
end
diff --git a/test/yaml/test_store.rb b/test/yaml/test_store.rb
index ef8d3229c1..d389530271 100644
--- a/test/yaml/test_store.rb
+++ b/test/yaml/test_store.rb
@@ -133,7 +133,7 @@ class YAMLStoreTest < Test::Unit::TestCase
def test_yaml_store_files_are_accessed_as_binary_files
bug5311 = '[ruby-core:39503]'
n = 128
- assert_in_out_err(["-Eutf-8:utf-8", "-ryaml/store", "-", @yaml_store_file], <<-SRC, [bug5311], [], bug5311, timeout: 15)
+ assert_in_out_err(["-Eutf-8:utf-8", "-ryaml/store", "-", @yaml_store_file], <<-SRC, [bug5311], [], bug5311, timeout: 60)
@yaml_store = YAML::Store.new(ARGV[0])
(1..#{n}).each do |i|
@yaml_store.transaction {@yaml_store["Key\#{i}"] = "value \#{i}"}
@@ -177,4 +177,4 @@ class YAMLStoreTest < Test::Unit::TestCase
end
assert_equal(indentation_3_yaml, File.read(@yaml_store_file), bug12800)
end
-end
+end if defined?(::YAML::Store)
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index 00a13af95b..502ccceec5 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -506,6 +506,7 @@ if defined? Zlib
end
def test_multithread_deflate
+ pend 'hangs' if RUBY_ENGINE == 'truffleruby'
zd = Zlib::Deflate.new
s = "x" * 10000
@@ -522,6 +523,7 @@ if defined? Zlib
end
def test_multithread_inflate
+ pend 'hangs' if RUBY_ENGINE == 'truffleruby'
zi = Zlib::Inflate.new
s = Zlib.deflate("x" * 10000)
@@ -792,7 +794,7 @@ if defined? Zlib
}
end
- if defined? File::TMPFILE
+ if defined?(File::TMPFILE) and RUBY_ENGINE != 'truffleruby'
def test_path_tmpfile
sio = StringIO.new("".dup, 'w')
gz = Zlib::GzipWriter.new(sio)
@@ -804,10 +806,16 @@ if defined? Zlib
io.rewind
gz0 = Zlib::GzipWriter.new(io)
- assert_raise(NoMethodError) { gz0.path }
-
gz1 = Zlib::GzipReader.new(io)
- assert_raise(NoMethodError) { gz1.path }
+
+ if IO.method_defined?(:path)
+ assert_nil gz0.path
+ assert_nil gz1.path
+ else
+ assert_raise(NoMethodError) { gz0.path }
+ assert_raise(NoMethodError) { gz1.path }
+ end
+
gz0.close
gz1.close
end
@@ -1197,6 +1205,38 @@ if defined? Zlib
}
end
+ # Various methods of Zlib::GzipReader failed when to reading files
+ # just a few bytes larger than GZFILE_READ_SIZE.
+ def test_gzfile_read_size_boundary
+ Tempfile.create("test_zlib_gzip_read_size_boundary") {|t|
+ t.close
+ # NO_COMPRESSION helps with recreating the error condition.
+ # The error happens on compressed files too, but it's harder to reproduce.
+ # For example, ~12750 bytes are needed to trigger the error using __FILE__.
+ # We avoid this because the test file will change over time.
+ Zlib::GzipWriter.open(t.path, Zlib::NO_COMPRESSION) do |gz|
+ gz.print("\n" * 2024) # range from 2024 to 2033 triggers the error
+ gz.flush
+ end
+
+ Zlib::GzipReader.open(t.path) do |f|
+ f.readpartial(1024) until f.eof?
+ assert_raise(EOFError) { f.readpartial(1) }
+ end
+
+ Zlib::GzipReader.open(t.path) do |f|
+ f.readline until f.eof?
+ assert_raise(EOFError) { f.readline }
+ end
+
+ Zlib::GzipReader.open(t.path) do |f|
+ b = f.readbyte until f.eof?
+ f.ungetbyte(b)
+ f.readbyte
+ assert_raise(EOFError) { f.readbyte }
+ end
+ }
+ end
end
class TestZlibGzipWriter < Test::Unit::TestCase
@@ -1451,6 +1491,13 @@ if defined? Zlib
assert_raise(Zlib::GzipFile::Error){ Zlib.gunzip(src) }
end
+ # Zlib.gunzip input is always considered a binary string, regardless of its String#encoding.
+ def test_gunzip_encoding
+ # vvvvvvvv = mtime, but valid UTF-8 string of U+0080
+ src = %w[1f8b0800c28000000003cb48cdc9c9070086a6103605000000].pack("H*").force_encoding('UTF-8')
+ assert_equal 'hello', Zlib.gunzip(src.freeze)
+ end
+
def test_gunzip_no_memory_leak
assert_no_memory_leak(%[-rzlib], "#{<<~"{#"}", "#{<<~'};'}")
d = Zlib.gzip("data")